aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp418
1 files changed, 224 insertions, 194 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index a16a458168d4..53447d0c97b2 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/DataExtractor.h"
#include <cstddef>
@@ -23,8 +24,8 @@ using namespace XCOFF;
namespace object {
static const uint8_t FunctionSym = 0x20;
-static const uint8_t SymTypeMask = 0x07;
static const uint16_t NoRelMask = 0x0001;
+static const size_t SymbolAuxTypeOffset = 17;
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
@@ -82,6 +83,19 @@ uint8_t XCOFFRelocation32::getRelocatedLength() const {
return (Info & XR_BIASED_LENGTH_MASK) + 1;
}
+uintptr_t
+XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+ uint32_t Distance) {
+ return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
+}
+
+const XCOFF::SymbolAuxType *
+XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
+ assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
+ return viewAs<XCOFF::SymbolAuxType>(
+ getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
+}
+
void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
uintptr_t TableAddress) const {
if (Addr < TableAddress)
@@ -114,14 +128,12 @@ XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
return viewAs<XCOFFSectionHeader64>(Ref.p);
}
-const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
+XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
#ifndef NDEBUG
checkSymbolEntryPointer(Ref.p);
#endif
- auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
- return SymEntPtr;
+ return XCOFFSymbolRef(Ref, this);
}
const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
@@ -147,15 +159,15 @@ XCOFFObjectFile::sectionHeaderTable64() const {
}
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+ uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
+ Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
#ifndef NDEBUG
// This function is used by basic_symbol_iterator, which allows to
// point to the end-of-symbol-table address.
- if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
- checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
+ if (NextSymbolAddr != getEndOfSymbolTableAddress())
+ checkSymbolEntryPointer(NextSymbolAddr);
#endif
- Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
+ Symb.p = NextSymbolAddr;
}
Expected<StringRef>
@@ -175,36 +187,27 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
object_error::parse_failed);
}
+StringRef XCOFFObjectFile::getStringTable() const {
+ return StringRef(StringTable.Data, StringTable.Size);
+}
+
Expected<StringRef>
XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
- if (CFileEntPtr->NameInStrTbl.Magic !=
- XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+ if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
}
Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-
- // A storage class value with the high-order bit on indicates that the name is
- // a symbolic debugger stabstring.
- if (SymEntPtr->StorageClass & 0x80)
- return StringRef("Unimplemented Debug Name");
-
- if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
- return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
-
- return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
+ return toSymbolRef(Symb).getName();
}
Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -215,14 +218,13 @@ uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
Expected<SymbolRef::Type>
XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
- llvm_unreachable("Not yet implemented!");
+ // TODO: Return the correct symbol type.
return SymbolRef::ST_Other;
}
Expected<section_iterator>
XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- int16_t SectNum = SymEntPtr->SectionNumber;
+ const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();
if (isReservedSectionNumber(SectNum))
return section_end();
@@ -296,9 +298,7 @@ uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
}
bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
- bool Result = false;
- llvm_unreachable("Not yet implemented!");
- return Result;
+ return false;
}
bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
@@ -315,6 +315,11 @@ bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
}
+bool XCOFFObjectFile::isDebugSection(DataRefImpl Sec) const {
+ uint32_t Flags = getSectionFlags(Sec);
+ return Flags & (XCOFF::STYP_DEBUG | XCOFF::STYP_DWARF);
+}
+
bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
: toSection32(Sec)->FileOffsetToRawData == 0;
@@ -377,7 +382,7 @@ symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_end();
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -398,24 +403,20 @@ void XCOFFObjectFile::getRelocationTypeName(
Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
uint32_t Result = 0;
- llvm_unreachable("Not yet implemented!");
+ // TODO: Return correct symbol flags.
return Result;
}
basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(
- SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
+ const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
+ SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -448,7 +449,7 @@ SubtargetFeatures XCOFFObjectFile::getFeatures() const {
bool XCOFFObjectFile::isRelocatableObject() const {
if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
+ return !(fileHeader64()->Flags & NoRelMask);
return !(fileHeader32()->Flags & NoRelMask);
}
@@ -458,6 +459,22 @@ Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
return 0;
}
+StringRef XCOFFObjectFile::mapDebugSectionName(StringRef Name) const {
+ return StringSwitch<StringRef>(Name)
+ .Case("dwinfo", "debug_info")
+ .Case("dwline", "debug_line")
+ .Case("dwpbnms", "debug_pubnames")
+ .Case("dwpbtyp", "debug_pubtypes")
+ .Case("dwarnge", "debug_aranges")
+ .Case("dwabrev", "debug_abbrev")
+ .Case("dwstr", "debug_str")
+ .Case("dwrnges", "debug_ranges")
+ .Case("dwloc", "debug_loc")
+ .Case("dwframe", "debug_frame")
+ .Case("dwmac", "debug_macinfo")
+ .Default(Name);
+}
+
size_t XCOFFObjectFile::getFileHeaderSize() const {
return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
}
@@ -486,9 +503,8 @@ Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
}
Expected<StringRef>
-XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- int16_t SectionNum = SymEntPtr->SectionNumber;
+XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
+ const int16_t SectionNum = SymEntPtr.getSectionNumber();
switch (SectionNum) {
case XCOFF::N_DEBUG:
@@ -506,6 +522,11 @@ XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
}
}
+unsigned XCOFFObjectFile::getSymbolSectionID(SymbolRef Sym) const {
+ XCOFFSymbolRef XCOFFSymRef(Sym.getRawDataRefImpl(), this);
+ return XCOFFSymRef.getSectionNumber();
+}
+
bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
return (SectionNumber <= 0 && SectionNumber >= -2);
}
@@ -549,10 +570,13 @@ uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
return fileHeader64()->NumberOfSymTableEntries;
}
+uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
+ return is64Bit() ? getNumberOfSymbolTableEntries64()
+ : getLogicalNumberOfSymbolTableEntries32();
+}
+
uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
- uint32_t NumberOfSymTableEntries =
- is64Bit() ? getNumberOfSymbolTableEntries64()
- : getLogicalNumberOfSymbolTableEntries32();
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
}
@@ -578,16 +602,20 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
XCOFF::SymbolTableEntrySize;
}
+uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
+ return getAdvancedSymbolEntryAddress(
+ reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
+}
+
Expected<StringRef>
XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
- if (is64Bit())
- report_fatal_error("64-bit symbol table support not implemented yet.");
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
- if (Index >= getLogicalNumberOfSymbolTableEntries32())
+ if (Index >= NumberOfSymTableEntries)
return errorCodeToError(object_error::invalid_symbol_index);
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return getSymbolName(SymDRI);
}
@@ -730,20 +758,21 @@ XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
Obj->SectionHeaderTable = SecHeadersOrErr.get();
}
- // 64-bit object supports only file header and section headers for now.
- if (Obj->is64Bit())
- return std::move(Obj);
+ const uint32_t NumberOfSymbolTableEntries =
+ Obj->getNumberOfSymbolTableEntries();
// If there is no symbol table we are done parsing the memory buffer.
- if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
+ if (NumberOfSymbolTableEntries == 0)
return std::move(Obj);
// Parse symbol table.
- CurOffset = Obj->fileHeader32()->SymbolTableOffset;
- uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
- Obj->getLogicalNumberOfSymbolTableEntries32();
+ CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
+ : Obj->getSymbolTableOffset32();
+ const uint64_t SymbolTableSize =
+ static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
+ NumberOfSymbolTableEntries;
auto SymTableOrErr =
- getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
+ getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
if (Error E = SymTableOrErr.takeError())
return std::move(E);
Obj->SymbolTblPtr = SymTableOrErr.get();
@@ -765,74 +794,103 @@ ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
return XCOFFObjectFile::create(FileType, MemBufRef);
}
-XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
-}
+bool XCOFFSymbolRef::isFunction() const {
+ if (!isCsectSymbol())
+ return false;
-uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
-}
+ if (getSymbolType() & FunctionSym)
+ return true;
-// TODO: The function needs to return an error if there is no csect auxiliary
-// entry.
-const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
- assert(!OwningObjectPtr->is64Bit() &&
- "32-bit interface called on 64-bit object file.");
- assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
+ Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
+ if (!ExpCsectAuxEnt)
+ return false;
- // In XCOFF32, the csect auxilliary entry is always the last auxiliary
- // entry for the symbol.
- uintptr_t AuxAddr = getWithOffset(
- SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
+ const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
-#ifndef NDEBUG
- OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
-#endif
+ // A function definition should be a label definition.
+ // FIXME: This is not necessarily the case when -ffunction-sections is
+ // enabled.
+ if (!CsectAuxRef.isLabel())
+ return false;
- return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
-}
+ if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
+ return false;
-uint16_t XCOFFSymbolRef::getType() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
-}
+ const int16_t SectNum = getSectionNumber();
+ Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
+ if (!SI) {
+ // If we could not get the section, then this symbol should not be
+ // a function. So consume the error and return `false` to move on.
+ consumeError(SI.takeError());
+ return false;
+ }
-int16_t XCOFFSymbolRef::getSectionNumber() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+ return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
}
-// TODO: The function name needs to be changed to express the purpose of the
-// function.
-bool XCOFFSymbolRef::hasCsectAuxEnt() const {
+bool XCOFFSymbolRef::isCsectSymbol() const {
XCOFF::StorageClass SC = getStorageClass();
return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
SC == XCOFF::C_HIDEXT);
}
-bool XCOFFSymbolRef::isFunction() const {
- if (OwningObjectPtr->is64Bit())
- report_fatal_error("64-bit support is unimplemented yet.");
+Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
+ assert(isCsectSymbol() &&
+ "Calling csect symbol interface with a non-csect symbol.");
- if (getType() & FunctionSym)
- return true;
+ uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
- if (!hasCsectAuxEnt())
- return false;
+ Expected<StringRef> NameOrErr = getName();
+ if (auto Err = NameOrErr.takeError())
+ return std::move(Err);
- const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
+ if (!NumberOfAuxEntries) {
+ return createStringError(object_error::parse_failed,
+ "csect symbol \"" + *NameOrErr +
+ "\" contains no auxiliary entry");
+ }
- // A function definition should be a label definition.
- if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
- return false;
+ if (!OwningObjectPtr->is64Bit()) {
+ // In XCOFF32, the csect auxilliary entry is always the last auxiliary
+ // entry for the symbol.
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), NumberOfAuxEntries);
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
+ }
- if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
- return false;
+ // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
+ // We need to iterate through all the auxiliary entries to find it.
+ for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), Index);
+ if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
+ XCOFF::SymbolAuxType::AUX_CSECT) {
+#ifndef NDEBUG
+ OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
+#endif
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
+ }
+ }
- int16_t SectNum = getSectionNumber();
- Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
- if (!SI)
- return false;
+ return createStringError(
+ object_error::parse_failed,
+ "a csect auxiliary entry is not found for symbol \"" + *NameOrErr + "\"");
+}
- return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+Expected<StringRef> XCOFFSymbolRef::getName() const {
+ // A storage class value with the high-order bit on indicates that the name is
+ // a symbolic debugger stabstring.
+ if (getStorageClass() & 0x80)
+ return StringRef("Unimplemented Debug Name");
+
+ if (Entry32) {
+ if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
+ return generateXCOFFFixedNameStringRef(Entry32->SymbolName);
+
+ return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
+ }
+
+ return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
}
// Explictly instantiate template classes.
@@ -846,15 +904,34 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
return support::endian::read32be(Bytes.data()) == 0;
}
-TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
+#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
+#define GETVALUEWITHMASKSHIFT(X, S) \
+ ((Data & (TracebackTable::X)) >> (TracebackTable::S))
+
+Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
+ Error Err = Error::success();
+ TBVectorExt TBTVecExt(TBvectorStrRef, Err);
+ if (Err)
+ return std::move(Err);
+ return TBTVecExt;
+}
+
+TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
Data = support::endian::read16be(Ptr);
- VecParmsInfo = support::endian::read32be(Ptr + 2);
+ uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
+ unsigned ParmsNum =
+ GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
+
+ ErrorAsOutParameter EAO(&Err);
+ Expected<SmallString<32>> VecParmsTypeOrError =
+ parseVectorParmsType(VecParmsTypeValue, ParmsNum);
+ if (!VecParmsTypeOrError)
+ Err = VecParmsTypeOrError.takeError();
+ else
+ VecParmsInfo = VecParmsTypeOrError.get();
}
-#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
-#define GETVALUEWITHMASKSHIFT(X, S) \
- ((Data & (TracebackTable::X)) >> (TracebackTable::S))
uint8_t TBVectorExt::getNumberOfVRSaved() const {
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
}
@@ -866,6 +943,7 @@ bool TBVectorExt::isVRSavedOnStack() const {
bool TBVectorExt::hasVarArgs() const {
return GETVALUEWITHMASK(HasVarArgsMask);
}
+
uint8_t TBVectorExt::getNumberOfVectorParms() const {
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
NumberOfVectorParmsShift);
@@ -877,72 +955,6 @@ bool TBVectorExt::hasVMXInstruction() const {
#undef GETVALUEWITHMASK
#undef GETVALUEWITHMASKSHIFT
-SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
- SmallString<32> ParmsType;
- uint32_t Value = VecParmsInfo;
- for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
- if (I != 0)
- ParmsType += ", ";
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsVectorCharBit:
- ParmsType += "vc";
- break;
-
- case TracebackTable::ParmTypeIsVectorShortBit:
- ParmsType += "vs";
- break;
-
- case TracebackTable::ParmTypeIsVectorIntBit:
- ParmsType += "vi";
- break;
-
- case TracebackTable::ParmTypeIsVectorFloatBit:
- ParmsType += "vf";
- break;
- }
- Value <<= 2;
- }
- return ParmsType;
-}
-
-static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
- unsigned int ParmsNum) {
- SmallString<32> ParmsType;
- unsigned I = 0;
- bool Begin = false;
- while (I < ParmsNum || Value) {
- if (Begin)
- ParmsType += ", ";
- else
- Begin = true;
-
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsFixedBits:
- ParmsType += "i";
- ++I;
- break;
- case TracebackTable::ParmTypeIsVectorBits:
- ParmsType += "v";
- break;
- case TracebackTable::ParmTypeIsFloatingBits:
- ParmsType += "f";
- ++I;
- break;
- case TracebackTable::ParmTypeIsDoubleBits:
- ParmsType += "d";
- ++I;
- break;
- default:
- assert(false && "Unrecognized bits in ParmsType.");
- }
- Value <<= 2;
- }
- assert(I == ParmsNum &&
- "The total parameters number of fixed-point or floating-point "
- "parameters not equal to the number in the parameter type!");
- return ParmsType;
-}
-
Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
uint64_t &Size) {
Error Err = Error::success();
@@ -963,21 +975,13 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
// Skip 8 bytes of mandatory fields.
DE.getU64(Cur);
+ unsigned FixedParmsNum = getNumberOfFixedParms();
+ unsigned FloatingParmsNum = getNumberOfFPParms();
+ uint32_t ParamsTypeValue = 0;
+
// Begin to parse optional fields.
- if (Cur) {
- unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
-
- // As long as there are no "fixed-point" or floating-point parameters, this
- // field remains not present even when hasVectorInfo gives true and
- // indicates the presence of vector parameters.
- if (ParmNum > 0) {
- uint32_t ParamsTypeValue = DE.getU32(Cur);
- if (Cur)
- ParmsType = hasVectorInfo()
- ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
- : parseParmsType(ParamsTypeValue, ParmNum);
- }
- }
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
+ ParamsTypeValue = DE.getU32(Cur);
if (Cur && hasTraceBackTableOffset())
TraceBackTableOffset = DE.getU32(Cur);
@@ -1006,10 +1010,35 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (Cur && isAllocaUsed())
AllocaRegister = DE.getU8(Cur);
+ unsigned VectorParmsNum = 0;
if (Cur && hasVectorInfo()) {
StringRef VectorExtRef = DE.getBytes(Cur, 6);
- if (Cur)
- VecExt = TBVectorExt(VectorExtRef);
+ if (Cur) {
+ Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
+ if (!TBVecExtOrErr) {
+ Err = TBVecExtOrErr.takeError();
+ return;
+ }
+ VecExt = TBVecExtOrErr.get();
+ VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
+ }
+ }
+
+ // As long as there is no fixed-point or floating-point parameter, this
+ // field remains not present even when hasVectorInfo gives true and
+ // indicates the presence of vector parameters.
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
+ Expected<SmallString<32>> ParmsTypeOrError =
+ hasVectorInfo()
+ ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
+ FloatingParmsNum, VectorParmsNum)
+ : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
+
+ if (!ParmsTypeOrError) {
+ Err = ParmsTypeOrError.takeError();
+ return;
+ }
+ ParmsType = ParmsTypeOrError.get();
}
if (Cur && hasExtensionTable())
@@ -1017,6 +1046,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (!Cur)
Err = Cur.takeError();
+
Size = Cur.tell();
}