Home | History | Annotate | Line # | Download | only in Object
      1 //===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file defines the XCOFFObjectFile class.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #include "llvm/Object/XCOFFObjectFile.h"
     14 #include "llvm/ADT/StringSwitch.h"
     15 #include "llvm/MC/SubtargetFeature.h"
     16 #include "llvm/Support/DataExtractor.h"
     17 #include <cstddef>
     18 #include <cstring>
     19 
     20 namespace llvm {
     21 
     22 using namespace XCOFF;
     23 
     24 namespace object {
     25 
     26 static const uint8_t FunctionSym = 0x20;
     27 static const uint8_t SymTypeMask = 0x07;
     28 static const uint16_t NoRelMask = 0x0001;
     29 
     30 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
     31 // 'M'. Returns a pointer to the underlying object on success.
     32 template <typename T>
     33 static Expected<const T *> getObject(MemoryBufferRef M, const void *Ptr,
     34                                      const uint64_t Size = sizeof(T)) {
     35   uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);
     36   if (Error E = Binary::checkOffset(M, Addr, Size))
     37     return std::move(E);
     38   return reinterpret_cast<const T *>(Addr);
     39 }
     40 
     41 static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset) {
     42   return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base) +
     43                                      Offset);
     44 }
     45 
     46 template <typename T> static const T *viewAs(uintptr_t in) {
     47   return reinterpret_cast<const T *>(in);
     48 }
     49 
     50 static StringRef generateXCOFFFixedNameStringRef(const char *Name) {
     51   auto NulCharPtr =
     52       static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
     53   return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
     54                     : StringRef(Name, XCOFF::NameSize);
     55 }
     56 
     57 template <typename T> StringRef XCOFFSectionHeader<T>::getName() const {
     58   const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
     59   return generateXCOFFFixedNameStringRef(DerivedXCOFFSectionHeader.Name);
     60 }
     61 
     62 template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
     63   const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
     64   return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
     65 }
     66 
     67 template <typename T>
     68 bool XCOFFSectionHeader<T>::isReservedSectionType() const {
     69   return getSectionType() & SectionFlagsReservedMask;
     70 }
     71 
     72 bool XCOFFRelocation32::isRelocationSigned() const {
     73   return Info & XR_SIGN_INDICATOR_MASK;
     74 }
     75 
     76 bool XCOFFRelocation32::isFixupIndicated() const {
     77   return Info & XR_FIXUP_INDICATOR_MASK;
     78 }
     79 
     80 uint8_t XCOFFRelocation32::getRelocatedLength() const {
     81   // The relocation encodes the bit length being relocated minus 1. Add back
     82   // the 1 to get the actual length being relocated.
     83   return (Info & XR_BIASED_LENGTH_MASK) + 1;
     84 }
     85 
     86 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
     87                                           uintptr_t TableAddress) const {
     88   if (Addr < TableAddress)
     89     report_fatal_error("Section header outside of section header table.");
     90 
     91   uintptr_t Offset = Addr - TableAddress;
     92   if (Offset >= getSectionHeaderSize() * getNumberOfSections())
     93     report_fatal_error("Section header outside of section header table.");
     94 
     95   if (Offset % getSectionHeaderSize() != 0)
     96     report_fatal_error(
     97         "Section header pointer does not point to a valid section header.");
     98 }
     99 
    100 const XCOFFSectionHeader32 *
    101 XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
    102   assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
    103 #ifndef NDEBUG
    104   checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
    105 #endif
    106   return viewAs<XCOFFSectionHeader32>(Ref.p);
    107 }
    108 
    109 const XCOFFSectionHeader64 *
    110 XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
    111   assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
    112 #ifndef NDEBUG
    113   checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
    114 #endif
    115   return viewAs<XCOFFSectionHeader64>(Ref.p);
    116 }
    117 
    118 const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
    119   assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
    120   assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
    121 #ifndef NDEBUG
    122   checkSymbolEntryPointer(Ref.p);
    123 #endif
    124   auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
    125   return SymEntPtr;
    126 }
    127 
    128 const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
    129   assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
    130   return static_cast<const XCOFFFileHeader32 *>(FileHeader);
    131 }
    132 
    133 const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const {
    134   assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
    135   return static_cast<const XCOFFFileHeader64 *>(FileHeader);
    136 }
    137 
    138 const XCOFFSectionHeader32 *
    139 XCOFFObjectFile::sectionHeaderTable32() const {
    140   assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
    141   return static_cast<const XCOFFSectionHeader32 *>(SectionHeaderTable);
    142 }
    143 
    144 const XCOFFSectionHeader64 *
    145 XCOFFObjectFile::sectionHeaderTable64() const {
    146   assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
    147   return static_cast<const XCOFFSectionHeader64 *>(SectionHeaderTable);
    148 }
    149 
    150 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
    151   const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
    152   SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
    153 #ifndef NDEBUG
    154   // This function is used by basic_symbol_iterator, which allows to
    155   // point to the end-of-symbol-table address.
    156   if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
    157     checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
    158 #endif
    159   Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
    160 }
    161 
    162 Expected<StringRef>
    163 XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
    164   // The byte offset is relative to the start of the string table.
    165   // A byte offset value of 0 is a null or zero-length symbol
    166   // name. A byte offset in the range 1 to 3 (inclusive) points into the length
    167   // field; as a soft-error recovery mechanism, we treat such cases as having an
    168   // offset of 0.
    169   if (Offset < 4)
    170     return StringRef(nullptr, 0);
    171 
    172   if (StringTable.Data != nullptr && StringTable.Size > Offset)
    173     return (StringTable.Data + Offset);
    174 
    175   return make_error<GenericBinaryError>("Bad offset for string table entry",
    176                                         object_error::parse_failed);
    177 }
    178 
    179 Expected<StringRef>
    180 XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
    181   if (CFileEntPtr->NameInStrTbl.Magic !=
    182       XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
    183     return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
    184   return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
    185 }
    186 
    187 Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
    188   const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
    189 
    190   // A storage class value with the high-order bit on indicates that the name is
    191   // a symbolic debugger stabstring.
    192   if (SymEntPtr->StorageClass & 0x80)
    193     return StringRef("Unimplemented Debug Name");
    194 
    195   if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
    196     return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
    197 
    198   return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
    199 }
    200 
    201 Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
    202   assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
    203   return toSymbolEntry(Symb)->Value;
    204 }
    205 
    206 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
    207   assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
    208   return toSymbolEntry(Symb)->Value;
    209 }
    210 
    211 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
    212   uint64_t Result = 0;
    213   llvm_unreachable("Not yet implemented!");
    214   return Result;
    215 }
    216 
    217 Expected<SymbolRef::Type>
    218 XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
    219   llvm_unreachable("Not yet implemented!");
    220   return SymbolRef::ST_Other;
    221 }
    222 
    223 Expected<section_iterator>
    224 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
    225   const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
    226   int16_t SectNum = SymEntPtr->SectionNumber;
    227 
    228   if (isReservedSectionNumber(SectNum))
    229     return section_end();
    230 
    231   Expected<DataRefImpl> ExpSec = getSectionByNum(SectNum);
    232   if (!ExpSec)
    233     return ExpSec.takeError();
    234 
    235   return section_iterator(SectionRef(ExpSec.get(), this));
    236 }
    237 
    238 void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
    239   const char *Ptr = reinterpret_cast<const char *>(Sec.p);
    240   Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize());
    241 }
    242 
    243 Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
    244   return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
    245 }
    246 
    247 uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
    248   // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
    249   // with MSVC.
    250   if (is64Bit())
    251     return toSection64(Sec)->VirtualAddress;
    252 
    253   return toSection32(Sec)->VirtualAddress;
    254 }
    255 
    256 uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
    257   // Section numbers in XCOFF are numbered beginning at 1. A section number of
    258   // zero is used to indicate that a symbol is being imported or is undefined.
    259   if (is64Bit())
    260     return toSection64(Sec) - sectionHeaderTable64() + 1;
    261   else
    262     return toSection32(Sec) - sectionHeaderTable32() + 1;
    263 }
    264 
    265 uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
    266   // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
    267   // with MSVC.
    268   if (is64Bit())
    269     return toSection64(Sec)->SectionSize;
    270 
    271   return toSection32(Sec)->SectionSize;
    272 }
    273 
    274 Expected<ArrayRef<uint8_t>>
    275 XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
    276   if (isSectionVirtual(Sec))
    277     return ArrayRef<uint8_t>();
    278 
    279   uint64_t OffsetToRaw;
    280   if (is64Bit())
    281     OffsetToRaw = toSection64(Sec)->FileOffsetToRawData;
    282   else
    283     OffsetToRaw = toSection32(Sec)->FileOffsetToRawData;
    284 
    285   const uint8_t * ContentStart = base() + OffsetToRaw;
    286   uint64_t SectionSize = getSectionSize(Sec);
    287   if (checkOffset(Data, reinterpret_cast<uintptr_t>(ContentStart), SectionSize))
    288     return make_error<BinaryError>();
    289 
    290   return makeArrayRef(ContentStart,SectionSize);
    291 }
    292 
    293 uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
    294   uint64_t Result = 0;
    295   llvm_unreachable("Not yet implemented!");
    296   return Result;
    297 }
    298 
    299 bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
    300   return false;
    301 }
    302 
    303 bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
    304   return getSectionFlags(Sec) & XCOFF::STYP_TEXT;
    305 }
    306 
    307 bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
    308   uint32_t Flags = getSectionFlags(Sec);
    309   return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
    310 }
    311 
    312 bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
    313   uint32_t Flags = getSectionFlags(Sec);
    314   return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
    315 }
    316 
    317 bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
    318   return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
    319                    : toSection32(Sec)->FileOffsetToRawData == 0;
    320 }
    321 
    322 relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
    323   if (is64Bit())
    324     report_fatal_error("64-bit support not implemented yet");
    325   const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
    326   auto RelocationsOrErr = relocations(*SectionEntPtr);
    327   if (Error E = RelocationsOrErr.takeError())
    328     return relocation_iterator(RelocationRef());
    329   DataRefImpl Ret;
    330   Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin());
    331   return relocation_iterator(RelocationRef(Ret, this));
    332 }
    333 
    334 relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
    335   if (is64Bit())
    336     report_fatal_error("64-bit support not implemented yet");
    337   const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec);
    338   auto RelocationsOrErr = relocations(*SectionEntPtr);
    339   if (Error E = RelocationsOrErr.takeError())
    340     return relocation_iterator(RelocationRef());
    341   DataRefImpl Ret;
    342   Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end());
    343   return relocation_iterator(RelocationRef(Ret, this));
    344 }
    345 
    346 void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
    347   Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1);
    348 }
    349 
    350 uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
    351   if (is64Bit())
    352     report_fatal_error("64-bit support not implemented yet");
    353   const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    354   const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32();
    355   const uint32_t RelocAddress = Reloc->VirtualAddress;
    356   const uint16_t NumberOfSections = getNumberOfSections();
    357   for (uint16_t i = 0; i < NumberOfSections; ++i) {
    358     // Find which section this relocation is belonging to, and get the
    359     // relocation offset relative to the start of the section.
    360     if (Sec32->VirtualAddress <= RelocAddress &&
    361         RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) {
    362       return RelocAddress - Sec32->VirtualAddress;
    363     }
    364     ++Sec32;
    365   }
    366   return InvalidRelocOffset;
    367 }
    368 
    369 symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
    370   if (is64Bit())
    371     report_fatal_error("64-bit support not implemented yet");
    372   const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    373   const uint32_t Index = Reloc->SymbolIndex;
    374 
    375   if (Index >= getLogicalNumberOfSymbolTableEntries32())
    376     return symbol_end();
    377 
    378   DataRefImpl SymDRI;
    379   SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
    380   return symbol_iterator(SymbolRef(SymDRI, this));
    381 }
    382 
    383 uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
    384   if (is64Bit())
    385     report_fatal_error("64-bit support not implemented yet");
    386   return viewAs<XCOFFRelocation32>(Rel.p)->Type;
    387 }
    388 
    389 void XCOFFObjectFile::getRelocationTypeName(
    390     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
    391   if (is64Bit())
    392     report_fatal_error("64-bit support not implemented yet");
    393   const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p);
    394   StringRef Res = XCOFF::getRelocationTypeString(Reloc->Type);
    395   Result.append(Res.begin(), Res.end());
    396 }
    397 
    398 Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
    399   uint32_t Result = 0;
    400   llvm_unreachable("Not yet implemented!");
    401   return Result;
    402 }
    403 
    404 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
    405   if (is64Bit())
    406     report_fatal_error("64-bit support not implemented yet");
    407   DataRefImpl SymDRI;
    408   SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
    409   return basic_symbol_iterator(SymbolRef(SymDRI, this));
    410 }
    411 
    412 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
    413   if (is64Bit())
    414     report_fatal_error("64-bit support not implemented yet");
    415   DataRefImpl SymDRI;
    416   SymDRI.p = reinterpret_cast<uintptr_t>(
    417       SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
    418   return basic_symbol_iterator(SymbolRef(SymDRI, this));
    419 }
    420 
    421 section_iterator XCOFFObjectFile::section_begin() const {
    422   DataRefImpl DRI;
    423   DRI.p = getSectionHeaderTableAddress();
    424   return section_iterator(SectionRef(DRI, this));
    425 }
    426 
    427 section_iterator XCOFFObjectFile::section_end() const {
    428   DataRefImpl DRI;
    429   DRI.p = getWithOffset(getSectionHeaderTableAddress(),
    430                         getNumberOfSections() * getSectionHeaderSize());
    431   return section_iterator(SectionRef(DRI, this));
    432 }
    433 
    434 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
    435 
    436 StringRef XCOFFObjectFile::getFileFormatName() const {
    437   return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
    438 }
    439 
    440 Triple::ArchType XCOFFObjectFile::getArch() const {
    441   return is64Bit() ? Triple::ppc64 : Triple::ppc;
    442 }
    443 
    444 SubtargetFeatures XCOFFObjectFile::getFeatures() const {
    445   return SubtargetFeatures();
    446 }
    447 
    448 bool XCOFFObjectFile::isRelocatableObject() const {
    449   if (is64Bit())
    450     report_fatal_error("64-bit support not implemented yet");
    451   return !(fileHeader32()->Flags & NoRelMask);
    452 }
    453 
    454 Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
    455   // TODO FIXME Should get from auxiliary_header->o_entry when support for the
    456   // auxiliary_header is added.
    457   return 0;
    458 }
    459 
    460 StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
    461   return StringSwitch<StringRef>(Name)
    462       .Case("dwinfo", "debug_info")
    463       .Case("dwline", "debug_line")
    464       .Case("dwpbnms", "debug_pubnames")
    465       .Case("dwpbtyp", "debug_pubtypes")
    466       .Case("dwarnge", "debug_aranges")
    467       .Case("dwabrev", "debug_abbrev")
    468       .Case("dwstr", "debug_str")
    469       .Case("dwrnges", "debug_ranges")
    470       .Case("dwloc", "debug_loc")
    471       .Case("dwframe", "debug_frame")
    472       .Case("dwmac", "debug_macinfo")
    473       .Default(Name);
    474 }
    475 
    476 size_t XCOFFObjectFile::getFileHeaderSize() const {
    477   return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
    478 }
    479 
    480 size_t XCOFFObjectFile::getSectionHeaderSize() const {
    481   return is64Bit() ? sizeof(XCOFFSectionHeader64) :
    482                      sizeof(XCOFFSectionHeader32);
    483 }
    484 
    485 bool XCOFFObjectFile::is64Bit() const {
    486   return Binary::ID_XCOFF64 == getType();
    487 }
    488 
    489 uint16_t XCOFFObjectFile::getMagic() const {
    490   return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
    491 }
    492 
    493 Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
    494   if (Num <= 0 || Num > getNumberOfSections())
    495     return errorCodeToError(object_error::invalid_section_index);
    496 
    497   DataRefImpl DRI;
    498   DRI.p = getWithOffset(getSectionHeaderTableAddress(),
    499                         getSectionHeaderSize() * (Num - 1));
    500   return DRI;
    501 }
    502 
    503 Expected<StringRef>
    504 XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
    505   assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
    506   int16_t SectionNum = SymEntPtr->SectionNumber;
    507 
    508   switch (SectionNum) {
    509   case XCOFF::N_DEBUG:
    510     return "N_DEBUG";
    511   case XCOFF::N_ABS:
    512     return "N_ABS";
    513   case XCOFF::N_UNDEF:
    514     return "N_UNDEF";
    515   default:
    516     Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
    517     if (SecRef)
    518       return generateXCOFFFixedNameStringRef(
    519           getSectionNameInternal(SecRef.get()));
    520     return SecRef.takeError();
    521   }
    522 }
    523 
    524 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
    525   return (SectionNumber <= 0 && SectionNumber >= -2);
    526 }
    527 
    528 uint16_t XCOFFObjectFile::getNumberOfSections() const {
    529   return is64Bit() ? fileHeader64()->NumberOfSections
    530                    : fileHeader32()->NumberOfSections;
    531 }
    532 
    533 int32_t XCOFFObjectFile::getTimeStamp() const {
    534   return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
    535 }
    536 
    537 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
    538   return is64Bit() ? fileHeader64()->AuxHeaderSize
    539                    : fileHeader32()->AuxHeaderSize;
    540 }
    541 
    542 uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
    543   return fileHeader32()->SymbolTableOffset;
    544 }
    545 
    546 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
    547   // As far as symbol table size is concerned, if this field is negative it is
    548   // to be treated as a 0. However since this field is also used for printing we
    549   // don't want to truncate any negative values.
    550   return fileHeader32()->NumberOfSymTableEntries;
    551 }
    552 
    553 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
    554   return (fileHeader32()->NumberOfSymTableEntries >= 0
    555               ? fileHeader32()->NumberOfSymTableEntries
    556               : 0);
    557 }
    558 
    559 uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
    560   return fileHeader64()->SymbolTableOffset;
    561 }
    562 
    563 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
    564   return fileHeader64()->NumberOfSymTableEntries;
    565 }
    566 
    567 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
    568   uint32_t NumberOfSymTableEntries =
    569       is64Bit() ? getNumberOfSymbolTableEntries64()
    570                 : getLogicalNumberOfSymbolTableEntries32();
    571   return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
    572                        XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
    573 }
    574 
    575 void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
    576   if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
    577     report_fatal_error("Symbol table entry is outside of symbol table.");
    578 
    579   if (SymbolEntPtr >= getEndOfSymbolTableAddress())
    580     report_fatal_error("Symbol table entry is outside of symbol table.");
    581 
    582   ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
    583                      reinterpret_cast<const char *>(SymbolTblPtr);
    584 
    585   if (Offset % XCOFF::SymbolTableEntrySize != 0)
    586     report_fatal_error(
    587         "Symbol table entry position is not valid inside of symbol table.");
    588 }
    589 
    590 uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
    591   return (reinterpret_cast<const char *>(SymbolEntPtr) -
    592           reinterpret_cast<const char *>(SymbolTblPtr)) /
    593          XCOFF::SymbolTableEntrySize;
    594 }
    595 
    596 Expected<StringRef>
    597 XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
    598   if (is64Bit())
    599     report_fatal_error("64-bit symbol table support not implemented yet.");
    600 
    601   if (Index >= getLogicalNumberOfSymbolTableEntries32())
    602     return errorCodeToError(object_error::invalid_symbol_index);
    603 
    604   DataRefImpl SymDRI;
    605   SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
    606   return getSymbolName(SymDRI);
    607 }
    608 
    609 uint16_t XCOFFObjectFile::getFlags() const {
    610   return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
    611 }
    612 
    613 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
    614   return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
    615 }
    616 
    617 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
    618   return reinterpret_cast<uintptr_t>(SectionHeaderTable);
    619 }
    620 
    621 int32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec) const {
    622   return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
    623 }
    624 
    625 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
    626     : ObjectFile(Type, Object) {
    627   assert(Type == Binary::ID_XCOFF32 || Type == Binary::ID_XCOFF64);
    628 }
    629 
    630 ArrayRef<XCOFFSectionHeader64> XCOFFObjectFile::sections64() const {
    631   assert(is64Bit() && "64-bit interface called for non 64-bit file.");
    632   const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
    633   return ArrayRef<XCOFFSectionHeader64>(TablePtr,
    634                                         TablePtr + getNumberOfSections());
    635 }
    636 
    637 ArrayRef<XCOFFSectionHeader32> XCOFFObjectFile::sections32() const {
    638   assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
    639   const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
    640   return ArrayRef<XCOFFSectionHeader32>(TablePtr,
    641                                         TablePtr + getNumberOfSections());
    642 }
    643 
    644 // In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
    645 // section header contains the actual count of relocation entries in the s_paddr
    646 // field. STYP_OVRFLO headers contain the section index of their corresponding
    647 // sections as their raw "NumberOfRelocations" field value.
    648 Expected<uint32_t> XCOFFObjectFile::getLogicalNumberOfRelocationEntries(
    649     const XCOFFSectionHeader32 &Sec) const {
    650 
    651   uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1;
    652 
    653   if (Sec.NumberOfRelocations < XCOFF::RelocOverflow)
    654     return Sec.NumberOfRelocations;
    655   for (const auto &Sec : sections32()) {
    656     if (Sec.Flags == XCOFF::STYP_OVRFLO &&
    657         Sec.NumberOfRelocations == SectionIndex)
    658       return Sec.PhysicalAddress;
    659   }
    660   return errorCodeToError(object_error::parse_failed);
    661 }
    662 
    663 Expected<ArrayRef<XCOFFRelocation32>>
    664 XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const {
    665   uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
    666                                       Sec.FileOffsetToRelocationInfo);
    667   auto NumRelocEntriesOrErr = getLogicalNumberOfRelocationEntries(Sec);
    668   if (Error E = NumRelocEntriesOrErr.takeError())
    669     return std::move(E);
    670 
    671   uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
    672 
    673   static_assert(
    674       sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32, "");
    675   auto RelocationOrErr =
    676       getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
    677                                    NumRelocEntries * sizeof(XCOFFRelocation32));
    678   if (Error E = RelocationOrErr.takeError())
    679     return std::move(E);
    680 
    681   const XCOFFRelocation32 *StartReloc = RelocationOrErr.get();
    682 
    683   return ArrayRef<XCOFFRelocation32>(StartReloc, StartReloc + NumRelocEntries);
    684 }
    685 
    686 Expected<XCOFFStringTable>
    687 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
    688   // If there is a string table, then the buffer must contain at least 4 bytes
    689   // for the string table's size. Not having a string table is not an error.
    690   if (Error E = Binary::checkOffset(
    691           Obj->Data, reinterpret_cast<uintptr_t>(Obj->base() + Offset), 4)) {
    692     consumeError(std::move(E));
    693     return XCOFFStringTable{0, nullptr};
    694   }
    695 
    696   // Read the size out of the buffer.
    697   uint32_t Size = support::endian::read32be(Obj->base() + Offset);
    698 
    699   // If the size is less then 4, then the string table is just a size and no
    700   // string data.
    701   if (Size <= 4)
    702     return XCOFFStringTable{4, nullptr};
    703 
    704   auto StringTableOrErr =
    705       getObject<char>(Obj->Data, Obj->base() + Offset, Size);
    706   if (Error E = StringTableOrErr.takeError())
    707     return std::move(E);
    708 
    709   const char *StringTablePtr = StringTableOrErr.get();
    710   if (StringTablePtr[Size - 1] != '\0')
    711     return errorCodeToError(object_error::string_table_non_null_end);
    712 
    713   return XCOFFStringTable{Size, StringTablePtr};
    714 }
    715 
    716 Expected<std::unique_ptr<XCOFFObjectFile>>
    717 XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
    718   // Can't use std::make_unique because of the private constructor.
    719   std::unique_ptr<XCOFFObjectFile> Obj;
    720   Obj.reset(new XCOFFObjectFile(Type, MBR));
    721 
    722   uint64_t CurOffset = 0;
    723   const auto *Base = Obj->base();
    724   MemoryBufferRef Data = Obj->Data;
    725 
    726   // Parse file header.
    727   auto FileHeaderOrErr =
    728       getObject<void>(Data, Base + CurOffset, Obj->getFileHeaderSize());
    729   if (Error E = FileHeaderOrErr.takeError())
    730     return std::move(E);
    731   Obj->FileHeader = FileHeaderOrErr.get();
    732 
    733   CurOffset += Obj->getFileHeaderSize();
    734   // TODO FIXME we don't have support for an optional header yet, so just skip
    735   // past it.
    736   CurOffset += Obj->getOptionalHeaderSize();
    737 
    738   // Parse the section header table if it is present.
    739   if (Obj->getNumberOfSections()) {
    740     auto SecHeadersOrErr = getObject<void>(Data, Base + CurOffset,
    741                                            Obj->getNumberOfSections() *
    742                                                Obj->getSectionHeaderSize());
    743     if (Error E = SecHeadersOrErr.takeError())
    744       return std::move(E);
    745     Obj->SectionHeaderTable = SecHeadersOrErr.get();
    746   }
    747 
    748   // 64-bit object supports only file header and section headers for now.
    749   if (Obj->is64Bit())
    750     return std::move(Obj);
    751 
    752   // If there is no symbol table we are done parsing the memory buffer.
    753   if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
    754     return std::move(Obj);
    755 
    756   // Parse symbol table.
    757   CurOffset = Obj->fileHeader32()->SymbolTableOffset;
    758   uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
    759                              Obj->getLogicalNumberOfSymbolTableEntries32();
    760   auto SymTableOrErr =
    761       getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
    762   if (Error E = SymTableOrErr.takeError())
    763     return std::move(E);
    764   Obj->SymbolTblPtr = SymTableOrErr.get();
    765   CurOffset += SymbolTableSize;
    766 
    767   // Parse String table.
    768   Expected<XCOFFStringTable> StringTableOrErr =
    769       parseStringTable(Obj.get(), CurOffset);
    770   if (Error E = StringTableOrErr.takeError())
    771     return std::move(E);
    772   Obj->StringTable = StringTableOrErr.get();
    773 
    774   return std::move(Obj);
    775 }
    776 
    777 Expected<std::unique_ptr<ObjectFile>>
    778 ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
    779                                   unsigned FileType) {
    780   return XCOFFObjectFile::create(FileType, MemBufRef);
    781 }
    782 
    783 XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
    784   return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
    785 }
    786 
    787 uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
    788   return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
    789 }
    790 
    791 // TODO: The function needs to return an error if there is no csect auxiliary
    792 // entry.
    793 const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
    794   assert(!OwningObjectPtr->is64Bit() &&
    795          "32-bit interface called on 64-bit object file.");
    796   assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
    797 
    798   // In XCOFF32, the csect auxilliary entry is always the last auxiliary
    799   // entry for the symbol.
    800   uintptr_t AuxAddr = getWithOffset(
    801       SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
    802 
    803 #ifndef NDEBUG
    804   OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
    805 #endif
    806 
    807   return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
    808 }
    809 
    810 uint16_t XCOFFSymbolRef::getType() const {
    811   return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
    812 }
    813 
    814 int16_t XCOFFSymbolRef::getSectionNumber() const {
    815   return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
    816 }
    817 
    818 // TODO: The function name needs to be changed to express the purpose of the
    819 // function.
    820 bool XCOFFSymbolRef::hasCsectAuxEnt() const {
    821   XCOFF::StorageClass SC = getStorageClass();
    822   return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
    823           SC == XCOFF::C_HIDEXT);
    824 }
    825 
    826 bool XCOFFSymbolRef::isFunction() const {
    827   if (OwningObjectPtr->is64Bit())
    828     report_fatal_error("64-bit support is unimplemented yet.");
    829 
    830   if (getType() & FunctionSym)
    831     return true;
    832 
    833   if (!hasCsectAuxEnt())
    834     return false;
    835 
    836   const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
    837 
    838   // A function definition should be a label definition.
    839   if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
    840     return false;
    841 
    842   if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
    843     return false;
    844 
    845   int16_t SectNum = getSectionNumber();
    846   Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
    847   if (!SI)
    848     return false;
    849 
    850   return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
    851 }
    852 
    853 // Explictly instantiate template classes.
    854 template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
    855 template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
    856 
    857 bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
    858   if (Bytes.size() < 4)
    859     return false;
    860 
    861   return support::endian::read32be(Bytes.data()) == 0;
    862 }
    863 
    864 TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
    865   const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
    866   Data = support::endian::read16be(Ptr);
    867   VecParmsInfo = support::endian::read32be(Ptr + 2);
    868 }
    869 
    870 #define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
    871 #define GETVALUEWITHMASKSHIFT(X, S)                                            \
    872   ((Data & (TracebackTable::X)) >> (TracebackTable::S))
    873 uint8_t TBVectorExt::getNumberOfVRSaved() const {
    874   return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
    875 }
    876 
    877 bool TBVectorExt::isVRSavedOnStack() const {
    878   return GETVALUEWITHMASK(IsVRSavedOnStackMask);
    879 }
    880 
    881 bool TBVectorExt::hasVarArgs() const {
    882   return GETVALUEWITHMASK(HasVarArgsMask);
    883 }
    884 uint8_t TBVectorExt::getNumberOfVectorParms() const {
    885   return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
    886                                NumberOfVectorParmsShift);
    887 }
    888 
    889 bool TBVectorExt::hasVMXInstruction() const {
    890   return GETVALUEWITHMASK(HasVMXInstructionMask);
    891 }
    892 #undef GETVALUEWITHMASK
    893 #undef GETVALUEWITHMASKSHIFT
    894 
    895 SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
    896   SmallString<32> ParmsType;
    897   uint32_t Value = VecParmsInfo;
    898   for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
    899     if (I != 0)
    900       ParmsType += ", ";
    901     switch (Value & TracebackTable::ParmTypeMask) {
    902     case TracebackTable::ParmTypeIsVectorCharBit:
    903       ParmsType += "vc";
    904       break;
    905 
    906     case TracebackTable::ParmTypeIsVectorShortBit:
    907       ParmsType += "vs";
    908       break;
    909 
    910     case TracebackTable::ParmTypeIsVectorIntBit:
    911       ParmsType += "vi";
    912       break;
    913 
    914     case TracebackTable::ParmTypeIsVectorFloatBit:
    915       ParmsType += "vf";
    916       break;
    917     }
    918     Value <<= 2;
    919   }
    920   return ParmsType;
    921 }
    922 
    923 static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
    924                                                  unsigned int ParmsNum) {
    925   SmallString<32> ParmsType;
    926   unsigned I = 0;
    927   bool Begin = false;
    928   while (I < ParmsNum || Value) {
    929     if (Begin)
    930       ParmsType += ", ";
    931     else
    932       Begin = true;
    933 
    934     switch (Value & TracebackTable::ParmTypeMask) {
    935     case TracebackTable::ParmTypeIsFixedBits:
    936       ParmsType += "i";
    937       ++I;
    938       break;
    939     case TracebackTable::ParmTypeIsVectorBits:
    940       ParmsType += "v";
    941       break;
    942     case TracebackTable::ParmTypeIsFloatingBits:
    943       ParmsType += "f";
    944       ++I;
    945       break;
    946     case TracebackTable::ParmTypeIsDoubleBits:
    947       ParmsType += "d";
    948       ++I;
    949       break;
    950     default:
    951       assert(false && "Unrecognized bits in ParmsType.");
    952     }
    953     Value <<= 2;
    954   }
    955   assert(I == ParmsNum &&
    956          "The total parameters number of fixed-point or floating-point "
    957          "parameters not equal to the number in the parameter type!");
    958   return ParmsType;
    959 }
    960 
    961 Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
    962                                                           uint64_t &Size) {
    963   Error Err = Error::success();
    964   XCOFFTracebackTable TBT(Ptr, Size, Err);
    965   if (Err)
    966     return std::move(Err);
    967   return TBT;
    968 }
    969 
    970 XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
    971                                          Error &Err)
    972     : TBPtr(Ptr) {
    973   ErrorAsOutParameter EAO(&Err);
    974   DataExtractor DE(ArrayRef<uint8_t>(Ptr, Size), /*IsLittleEndian=*/false,
    975                    /*AddressSize=*/0);
    976   DataExtractor::Cursor Cur(/*Offset=*/0);
    977 
    978   // Skip 8 bytes of mandatory fields.
    979   DE.getU64(Cur);
    980 
    981   // Begin to parse optional fields.
    982   if (Cur) {
    983     unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
    984 
    985     // As long as there are no "fixed-point" or floating-point parameters, this
    986     // field remains not present even when hasVectorInfo gives true and
    987     // indicates the presence of vector parameters.
    988     if (ParmNum > 0) {
    989       uint32_t ParamsTypeValue = DE.getU32(Cur);
    990       if (Cur)
    991         ParmsType = hasVectorInfo()
    992                         ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
    993                         : parseParmsType(ParamsTypeValue, ParmNum);
    994     }
    995   }
    996 
    997   if (Cur && hasTraceBackTableOffset())
    998     TraceBackTableOffset = DE.getU32(Cur);
    999 
   1000   if (Cur && isInterruptHandler())
   1001     HandlerMask = DE.getU32(Cur);
   1002 
   1003   if (Cur && hasControlledStorage()) {
   1004     NumOfCtlAnchors = DE.getU32(Cur);
   1005     if (Cur && NumOfCtlAnchors) {
   1006       SmallVector<uint32_t, 8> Disp;
   1007       Disp.reserve(NumOfCtlAnchors.getValue());
   1008       for (uint32_t I = 0; I < NumOfCtlAnchors && Cur; ++I)
   1009         Disp.push_back(DE.getU32(Cur));
   1010       if (Cur)
   1011         ControlledStorageInfoDisp = std::move(Disp);
   1012     }
   1013   }
   1014 
   1015   if (Cur && isFuncNamePresent()) {
   1016     uint16_t FunctionNameLen = DE.getU16(Cur);
   1017     if (Cur)
   1018       FunctionName = DE.getBytes(Cur, FunctionNameLen);
   1019   }
   1020 
   1021   if (Cur && isAllocaUsed())
   1022     AllocaRegister = DE.getU8(Cur);
   1023 
   1024   if (Cur && hasVectorInfo()) {
   1025     StringRef VectorExtRef = DE.getBytes(Cur, 6);
   1026     if (Cur)
   1027       VecExt = TBVectorExt(VectorExtRef);
   1028   }
   1029 
   1030   if (Cur && hasExtensionTable())
   1031     ExtensionTable = DE.getU8(Cur);
   1032 
   1033   if (!Cur)
   1034     Err = Cur.takeError();
   1035   Size = Cur.tell();
   1036 }
   1037 
   1038 #define GETBITWITHMASK(P, X)                                                   \
   1039   (support::endian::read32be(TBPtr + (P)) & (TracebackTable::X))
   1040 #define GETBITWITHMASKSHIFT(P, X, S)                                           \
   1041   ((support::endian::read32be(TBPtr + (P)) & (TracebackTable::X)) >>           \
   1042    (TracebackTable::S))
   1043 
   1044 uint8_t XCOFFTracebackTable::getVersion() const {
   1045   return GETBITWITHMASKSHIFT(0, VersionMask, VersionShift);
   1046 }
   1047 
   1048 uint8_t XCOFFTracebackTable::getLanguageID() const {
   1049   return GETBITWITHMASKSHIFT(0, LanguageIdMask, LanguageIdShift);
   1050 }
   1051 
   1052 bool XCOFFTracebackTable::isGlobalLinkage() const {
   1053   return GETBITWITHMASK(0, IsGlobaLinkageMask);
   1054 }
   1055 
   1056 bool XCOFFTracebackTable::isOutOfLineEpilogOrPrologue() const {
   1057   return GETBITWITHMASK(0, IsOutOfLineEpilogOrPrologueMask);
   1058 }
   1059 
   1060 bool XCOFFTracebackTable::hasTraceBackTableOffset() const {
   1061   return GETBITWITHMASK(0, HasTraceBackTableOffsetMask);
   1062 }
   1063 
   1064 bool XCOFFTracebackTable::isInternalProcedure() const {
   1065   return GETBITWITHMASK(0, IsInternalProcedureMask);
   1066 }
   1067 
   1068 bool XCOFFTracebackTable::hasControlledStorage() const {
   1069   return GETBITWITHMASK(0, HasControlledStorageMask);
   1070 }
   1071 
   1072 bool XCOFFTracebackTable::isTOCless() const {
   1073   return GETBITWITHMASK(0, IsTOClessMask);
   1074 }
   1075 
   1076 bool XCOFFTracebackTable::isFloatingPointPresent() const {
   1077   return GETBITWITHMASK(0, IsFloatingPointPresentMask);
   1078 }
   1079 
   1080 bool XCOFFTracebackTable::isFloatingPointOperationLogOrAbortEnabled() const {
   1081   return GETBITWITHMASK(0, IsFloatingPointOperationLogOrAbortEnabledMask);
   1082 }
   1083 
   1084 bool XCOFFTracebackTable::isInterruptHandler() const {
   1085   return GETBITWITHMASK(0, IsInterruptHandlerMask);
   1086 }
   1087 
   1088 bool XCOFFTracebackTable::isFuncNamePresent() const {
   1089   return GETBITWITHMASK(0, IsFunctionNamePresentMask);
   1090 }
   1091 
   1092 bool XCOFFTracebackTable::isAllocaUsed() const {
   1093   return GETBITWITHMASK(0, IsAllocaUsedMask);
   1094 }
   1095 
   1096 uint8_t XCOFFTracebackTable::getOnConditionDirective() const {
   1097   return GETBITWITHMASKSHIFT(0, OnConditionDirectiveMask,
   1098                              OnConditionDirectiveShift);
   1099 }
   1100 
   1101 bool XCOFFTracebackTable::isCRSaved() const {
   1102   return GETBITWITHMASK(0, IsCRSavedMask);
   1103 }
   1104 
   1105 bool XCOFFTracebackTable::isLRSaved() const {
   1106   return GETBITWITHMASK(0, IsLRSavedMask);
   1107 }
   1108 
   1109 bool XCOFFTracebackTable::isBackChainStored() const {
   1110   return GETBITWITHMASK(4, IsBackChainStoredMask);
   1111 }
   1112 
   1113 bool XCOFFTracebackTable::isFixup() const {
   1114   return GETBITWITHMASK(4, IsFixupMask);
   1115 }
   1116 
   1117 uint8_t XCOFFTracebackTable::getNumOfFPRsSaved() const {
   1118   return GETBITWITHMASKSHIFT(4, FPRSavedMask, FPRSavedShift);
   1119 }
   1120 
   1121 bool XCOFFTracebackTable::hasExtensionTable() const {
   1122   return GETBITWITHMASK(4, HasExtensionTableMask);
   1123 }
   1124 
   1125 bool XCOFFTracebackTable::hasVectorInfo() const {
   1126   return GETBITWITHMASK(4, HasVectorInfoMask);
   1127 }
   1128 
   1129 uint8_t XCOFFTracebackTable::getNumOfGPRsSaved() const {
   1130   return GETBITWITHMASKSHIFT(4, GPRSavedMask, GPRSavedShift);
   1131 }
   1132 
   1133 uint8_t XCOFFTracebackTable::getNumberOfFixedParms() const {
   1134   return GETBITWITHMASKSHIFT(4, NumberOfFixedParmsMask,
   1135                              NumberOfFixedParmsShift);
   1136 }
   1137 
   1138 uint8_t XCOFFTracebackTable::getNumberOfFPParms() const {
   1139   return GETBITWITHMASKSHIFT(4, NumberOfFloatingPointParmsMask,
   1140                              NumberOfFloatingPointParmsShift);
   1141 }
   1142 
   1143 bool XCOFFTracebackTable::hasParmsOnStack() const {
   1144   return GETBITWITHMASK(4, HasParmsOnStackMask);
   1145 }
   1146 
   1147 #undef GETBITWITHMASK
   1148 #undef GETBITWITHMASKSHIFT
   1149 } // namespace object
   1150 } // namespace llvm
   1151