diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -295,6 +295,60 @@
 StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
 StringRef getRelocationTypeString(XCOFF::RelocationType Type);
 
+struct TracebackTable {
+  // Byte 1
+  static constexpr uint32_t VersionMask = 0xFF00'0000;
+  static constexpr uint8_t VersionShift = 24;
+
+  // Byte 2
+  static constexpr uint32_t LanguageIdMask = 0x00FF'0000;
+  static constexpr uint8_t LanguageIdShift = 16;
+
+  // Byte 3
+  static constexpr uint32_t GlobaLinkageMask = 0x0000'8000;
+  static constexpr uint32_t IsEprolMask = 0x0000'4000;
+  static constexpr uint32_t HasCodeLenMask = 0x0000'2000;
+  static constexpr uint32_t IntProcMask = 0x0000'1000;
+  static constexpr uint32_t HasCtlMask = 0x0000'0800;
+  static constexpr uint32_t TOCLessMask = 0x0000'0400;
+  static constexpr uint32_t FPPresentMask = 0x0000'0200;
+  static constexpr uint32_t LogAbortMask = 0x0000'0100;
+
+  // Byte 4
+  static constexpr uint32_t IntHandlerMask = 0x0000'0080;
+  static constexpr uint32_t NamePresentMask = 0x0000'0040;
+  static constexpr uint32_t UsedAllocaMask = 0x0000'0020;
+  static constexpr uint32_t ClDisInvMask = 0x0000'001C;
+  static constexpr uint32_t SavesCRMask = 0x0000'0002;
+  static constexpr uint32_t SavesLRMask = 0x0000'0001;
+
+  static constexpr uint8_t ClDisInvShift = 2;
+
+  // Byte 5
+  static constexpr uint32_t StoresBCMask = 0x8000'0000;
+  static constexpr uint32_t FixupMask = 0x4000'0000;
+  static constexpr uint32_t FPSavedMask = 0x3F00'0000;
+  static constexpr uint32_t FPSavedShift = 24;
+
+  // Byte 6
+  static constexpr uint32_t HasVecInfoMask = 0x0080'0000;
+  static constexpr uint32_t Spare4Mask = 0x0040'0000;
+  static constexpr uint32_t GPSavedMask = 0x003F'0000;
+  static constexpr uint32_t GPSavedShift = 16;
+
+  // Byte 7
+  static constexpr uint32_t NumberOfFixedParaMask = 0x0000'FF00;
+  static constexpr uint8_t NumberOfFixedParaShift = 8;
+
+  // Byte 8
+  static constexpr uint32_t NumberOfFPParaMask = 0x0000'00FE;
+  static constexpr uint32_t ParmsOnStackMask = 0x0000'0001;
+  static constexpr uint8_t NumberOfFPParaShift = 01;
+
+  static constexpr uint32_t FixedParaTypeBit = 0x8000'0000;
+  static constexpr uint32_t FloatPointParaTypeBit = 0x4000'0000;
+};
+
 } // end namespace XCOFF
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -391,6 +391,61 @@
   bool isFunction() const;
 };
 
+class XCOFFTracebackTable {
+  const uint8_t *TBPtr;
+  const uint64_t Size;
+  Optional<std::string> ParaType;
+  Optional<uint32_t> CodeLen;
+  Optional<uint32_t> HandMask;
+  Optional<uint32_t> CtlInfo;
+  Optional<uint16_t> FunctionNameLen;
+  Optional<StringRef> FunctionName;
+  Optional<uint8_t> AllocaRegister;
+
+public:
+  static Expected<XCOFFTracebackTable> create(const uint8_t *Ptr, uint64_t S);
+  XCOFFTracebackTable(const uint8_t *Ptr, uint64_t S, Error &Err);
+
+  uint8_t getVersion();
+  uint8_t getLanguageID();
+
+  bool isGlobalLinkage();
+  bool isEprol();
+  bool hasFunctionCodeLen();
+  bool isInternalProcedure();
+  bool hasCtl();
+  bool isTOCLess();
+  bool isFloatPointPresent();
+  bool isLogAbort();
+
+  bool isInterruptHandler();
+  bool isFuncNamePresent();
+  bool usedAlloca();
+  uint8_t getClDisInv();
+  bool doesCRSaved();
+  bool doesLRSaved();
+
+  bool doesBackChainStore();
+  uint8_t getNumOfFPRsSaved();
+
+  bool hasVecInfo();
+  uint8_t getNumofGPRsSaved();
+
+  uint8_t getNumberOfFixedPara();
+
+  uint8_t getNumberOfFPPara();
+  bool isParaOnStack();
+
+  Optional<std::string> getParaType() { return ParaType; }
+  Optional<uint32_t> getCodeLen() { return CodeLen; }
+  Optional<uint32_t> getHandMask() { return HandMask; }
+  Optional<uint32_t> getCtlInfo() { return CtlInfo; }
+  Optional<uint16_t> getFunctionNameLen() { return FunctionNameLen; }
+  Optional<StringRef> getFunctionName() { return FunctionName; }
+  Optional<uint8_t> getAllocaRegister() { return AllocaRegister; }
+};
+
+bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
 } // namespace object
 } // namespace llvm
 
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -12,10 +12,14 @@
 
 #include "llvm/Object/XCOFFObjectFile.h"
 #include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Support/DataExtractor.h"
 #include <cstddef>
 #include <cstring>
 
 namespace llvm {
+
+using namespace XCOFF;
+
 namespace object {
 
 static const uint8_t FunctionSym = 0x20;
@@ -834,5 +838,170 @@
 template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
 template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
 
+bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
+  assert(Bytes.size() == 4 && "Traceback table started with 4 bytes zero.");
+  return support::endian::read32be(Bytes.data()) == 0;
+}
+
+static std::string parseParaType(uint32_t Value, unsigned int ParaNum) {
+  std::string ParaType;
+  for (unsigned I = 0; I < ParaNum; ++I) {
+    if (I != 0)
+      ParaType += ", ";
+    if ((Value & TracebackTable::FixedParaTypeBit) == 0) {
+      // Fixed parameter type.
+      ParaType += "i";
+      Value <<= 1;
+      continue;
+    } else {
+      if ((Value & TracebackTable::FloatPointParaTypeBit) == 0)
+        // Float parameter type.
+        ParaType += "f";
+      else
+        // Double parameter type.
+        ParaType += "d";
+
+      Value <<= 2;
+      continue;
+    }
+  }
+  return ParaType;
+}
+
+Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
+                                                          const uint64_t S) {
+  Error Err = Error::success();
+  XCOFFTracebackTable TBT(Ptr, S, Err);
+  if (Err)
+    return std::move(Err);
+  return std::move(TBT);
+}
+
+XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, const uint64_t S,
+                                         Error &Err)
+    : TBPtr(Ptr), Size(S) {
+  ErrorAsOutParameter EAO(&Err);
+  DataExtractor DE(ArrayRef<uint8_t>(Ptr, S), false, 4);
+  uint64_t offset_ptr = 0;
+
+  DE.getU64(&offset_ptr, &Err);
+
+  unsigned int ParaNum = getNumberOfFixedPara() + getNumberOfFPPara();
+
+  if (!Err && ParaNum)
+    ParaType = parseParaType(DE.getU32(&offset_ptr, &Err), ParaNum);
+
+  if (!Err && hasFunctionCodeLen())
+    CodeLen = DE.getU32(&offset_ptr, &Err);
+
+  if (!Err && isInterruptHandler())
+    HandMask = DE.getU32(&offset_ptr, &Err);
+
+  if (!Err && hasCtl())
+    CtlInfo = DE.getU32(&offset_ptr, &Err);
+
+  if (!Err && isFuncNamePresent()) {
+    uint16_t Len = DE.getU16(&offset_ptr, &Err);
+    if (!Err)
+      FunctionName = DE.getBytes(&offset_ptr, Len, &Err);
+    FunctionNameLen = Len;
+  }
+
+  if (!Err && usedAlloca())
+    AllocaRegister = DE.getU8(&offset_ptr, &Err);
+}
+
+#define GETBITWITHMASK(P, X)                                                   \
+  (support::endian::read32be(TBPtr + P) & TracebackTable::X)
+#define GETBITWITHMASKSHIFT(P, X, S)                                           \
+  (support::endian::read32be(TBPtr + P) & TracebackTable::X) >>                \
+      TracebackTable::S
+
+uint8_t XCOFFTracebackTable::getVersion() {
+  return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
+}
+
+uint8_t XCOFFTracebackTable::getLanguageID() {
+  return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
+}
+
+bool XCOFFTracebackTable::isGlobalLinkage() {
+  return GETBITWITHMASK(0, GlobaLinkageMask);
+}
+
+bool XCOFFTracebackTable::isEprol() { return GETBITWITHMASK(0, IsEprolMask); }
+
+bool XCOFFTracebackTable::hasFunctionCodeLen() {
+  return GETBITWITHMASK(0, HasCodeLenMask);
+}
+
+bool XCOFFTracebackTable::isInternalProcedure() {
+  return GETBITWITHMASK(0, IntProcMask);
+}
+
+bool XCOFFTracebackTable::hasCtl() { return GETBITWITHMASK(0, HasCtlMask); }
+
+bool XCOFFTracebackTable::isTOCLess() { return GETBITWITHMASK(0, TOCLessMask); }
+
+bool XCOFFTracebackTable::isFloatPointPresent() {
+  return GETBITWITHMASK(0, FPPresentMask);
+}
+
+bool XCOFFTracebackTable::isLogAbort() {
+  return GETBITWITHMASK(0, LogAbortMask);
+}
+
+bool XCOFFTracebackTable::isInterruptHandler() {
+  return GETBITWITHMASK(0, IntHandlerMask);
+}
+
+bool XCOFFTracebackTable::isFuncNamePresent() {
+  return GETBITWITHMASK(0, NamePresentMask);
+}
+
+bool XCOFFTracebackTable::usedAlloca() {
+  return GETBITWITHMASK(0, UsedAllocaMask);
+}
+
+uint8_t XCOFFTracebackTable::getClDisInv() {
+  return GETBITWITHMASKSHIFT(0, ClDisInvMask, ClDisInvShift);
+}
+
+bool XCOFFTracebackTable::doesCRSaved() {
+  return GETBITWITHMASK(0, SavesCRMask);
+}
+
+bool XCOFFTracebackTable::doesLRSaved() {
+  return GETBITWITHMASK(0, SavesLRMask);
+}
+
+bool XCOFFTracebackTable::doesBackChainStore() {
+  return GETBITWITHMASK(4, StoresBCMask);
+}
+
+uint8_t XCOFFTracebackTable::getNumOfFPRsSaved() {
+  return GETBITWITHMASKSHIFT(4, FPSavedMask, FPSavedShift);
+}
+
+bool XCOFFTracebackTable::hasVecInfo() {
+  return GETBITWITHMASK(4, HasVecInfoMask);
+}
+
+uint8_t XCOFFTracebackTable::getNumofGPRsSaved() {
+  return GETBITWITHMASKSHIFT(4, GPSavedMask, GPSavedShift);
+}
+
+uint8_t XCOFFTracebackTable::getNumberOfFixedPara() {
+  return GETBITWITHMASKSHIFT(4, NumberOfFixedParaMask, NumberOfFixedParaShift);
+}
+
+uint8_t XCOFFTracebackTable::getNumberOfFPPara() {
+  return GETBITWITHMASKSHIFT(4, NumberOfFPParaMask, NumberOfFPParaShift);
+}
+
+bool XCOFFTracebackTable::isParaOnStack() {
+  return GETBITWITHMASK(4, ParmsOnStackMask);
+}
+
 } // namespace object
 } // namespace llvm
diff --git a/llvm/unittests/Object/CMakeLists.txt b/llvm/unittests/Object/CMakeLists.txt
--- a/llvm/unittests/Object/CMakeLists.txt
+++ b/llvm/unittests/Object/CMakeLists.txt
@@ -12,6 +12,7 @@
   ObjectFileTest.cpp
   SymbolSizeTest.cpp
   SymbolicFileTest.cpp
+  XCOFFObjectFileTest.cpp
   )
 
 target_link_libraries(ObjectTests PRIVATE LLVMTestingSupport)
diff --git a/llvm/unittests/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
new file mode 100644
--- /dev/null
+++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
@@ -0,0 +1,118 @@
+//===- XCOFFObjectFileTest.cpp - Tests for XCOFFObjectFile ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/XCOFFObjectFile.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+TEST(XCOFFObjectFileTest, doesXCOFFTracebackTableBegin) {
+  EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0}));
+
+  EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0, 1}));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPItest) {
+  uint8_t V[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01, 0x05, 0x58, 0x00,
+                 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
+                 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
+
+  Expected<XCOFFTracebackTable> TTOrErr =
+      XCOFFTracebackTable::create(V, sizeof(V));
+
+  ASSERT_TRUE(!!TTOrErr) << "Parse error";
+
+  XCOFFTracebackTable TT = TTOrErr.get();
+
+  EXPECT_EQ(TT.getVersion(), 0);
+
+  EXPECT_EQ(TT.getLanguageID(), 0);
+
+  EXPECT_FALSE(TT.isGlobalLinkage());
+  EXPECT_FALSE(TT.isEprol());
+  EXPECT_TRUE(TT.hasFunctionCodeLen());
+  EXPECT_FALSE(TT.isInternalProcedure());
+  EXPECT_FALSE(TT.hasCtl());
+  EXPECT_FALSE(TT.isTOCLess());
+  EXPECT_TRUE(TT.isFloatPointPresent());
+  EXPECT_FALSE(TT.isLogAbort());
+
+  EXPECT_FALSE(TT.isInterruptHandler());
+  EXPECT_TRUE(TT.isFuncNamePresent());
+  EXPECT_FALSE(TT.usedAlloca());
+  EXPECT_EQ(TT.usedAlloca(), 0);
+  EXPECT_FALSE(TT.doesCRSaved());
+  EXPECT_FALSE(TT.doesLRSaved());
+
+  EXPECT_TRUE(TT.doesBackChainStore());
+  EXPECT_EQ(TT.getNumOfFPRsSaved(), 0);
+
+  EXPECT_FALSE(TT.hasVecInfo());
+  EXPECT_EQ(TT.getNumofGPRsSaved(), 0);
+
+  EXPECT_EQ(TT.getNumberOfFixedPara(), 1);
+
+  EXPECT_EQ(TT.getNumberOfFPPara(), 2);
+  EXPECT_TRUE(TT.isParaOnStack());
+
+  EXPECT_TRUE(TT.getParaType());
+  EXPECT_STREQ(TT.getParaType().getValue().data(), "i, f, d");
+
+  EXPECT_EQ(TT.getCodeLen().getValue(), 64u);
+
+  EXPECT_FALSE(TT.getHandMask());
+  EXPECT_FALSE(TT.getCtlInfo());
+
+  EXPECT_TRUE(TT.getFunctionNameLen());
+  EXPECT_EQ(TT.getFunctionNameLen().getValue(), 7);
+  EXPECT_TRUE(TT.getFunctionName());
+  EXPECT_STREQ(TT.getFunctionName().getValue().data(), "add_all");
+
+  EXPECT_FALSE(TT.getAllocaRegister());
+
+  uint8_t V1[] = {0x01, 0x02, 0xA2, 0x40, 0x80, 0x00, 0x02, 0x07, 0x2B, 0x00,
+                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
+                  0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
+
+  Expected<XCOFFTracebackTable> TTOrErr1 =
+      XCOFFTracebackTable::create(V1, sizeof(V1));
+  ASSERT_TRUE(!!TTOrErr1) << "Parse error";
+  XCOFFTracebackTable TT1 = TTOrErr1.get();
+  EXPECT_EQ(TT1.getVersion(), 1);
+  EXPECT_EQ(TT1.getLanguageID(), 2);
+
+  EXPECT_TRUE(TT1.isGlobalLinkage());
+  EXPECT_EQ(TT1.getNumberOfFixedPara(), 2);
+
+  EXPECT_EQ(TT1.getNumberOfFPPara(), 3);
+
+  EXPECT_TRUE(TT1.getParaType());
+  EXPECT_STREQ(TT1.getParaType().getValue().data(), "i, i, f, f, d");
+
+  V1[8] = 0xAC;
+  Expected<XCOFFTracebackTable> TTOrErr2 =
+      XCOFFTracebackTable::create(V1, sizeof(V1));
+  ASSERT_TRUE(!!TTOrErr2) << "Parse error";
+  XCOFFTracebackTable TT2 = TTOrErr2.get();
+  EXPECT_STREQ(TT2.getParaType().getValue().data(), "f, f, d, i, i");
+
+  V1[8] = 0xD4;
+  Expected<XCOFFTracebackTable> TTOrErr3 =
+      XCOFFTracebackTable::create(V1, sizeof(V1));
+  ASSERT_TRUE(!!TTOrErr3) << "Parse error";
+  XCOFFTracebackTable TT3 = TTOrErr3.get();
+  EXPECT_STREQ(TT3.getParaType().getValue().data(), "d, i, f, f, i");
+
+  V1[6] = 0x01;
+  Expected<XCOFFTracebackTable> TTOrErr4 =
+      XCOFFTracebackTable::create(V1, sizeof(V1));
+  ASSERT_TRUE(!!TTOrErr4) << "Parse error";
+  XCOFFTracebackTable TT4 = TTOrErr4.get();
+  EXPECT_STREQ(TT4.getParaType().getValue().data(), "d, i, f, f");
+}