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.cpp282
1 files changed, 39 insertions, 243 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index f98cd69a0d37..602b7357986a 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -11,14 +11,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/XCOFFObjectFile.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include <cstddef>
#include <cstring>
namespace llvm {
namespace object {
-enum { FUNCTION_SYM = 0x20, SYM_TYPE_MASK = 0x07, RELOC_OVERFLOW = 65535 };
-
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
template <typename T>
@@ -39,40 +42,10 @@ template <typename T> static const T *viewAs(uintptr_t in) {
return reinterpret_cast<const T *>(in);
}
-static StringRef generateXCOFFFixedNameStringRef(const char *Name) {
- auto NulCharPtr =
- static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
+static StringRef generateStringRef(const char *Name, uint64_t Size) {
+ auto NulCharPtr = static_cast<const char *>(memchr(Name, '\0', Size));
return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
- : StringRef(Name, XCOFF::NameSize);
-}
-
-template <typename T> StringRef XCOFFSectionHeader<T>::getName() const {
- const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
- return generateXCOFFFixedNameStringRef(DerivedXCOFFSectionHeader.Name);
-}
-
-template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
- const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
- return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
-}
-
-template <typename T>
-bool XCOFFSectionHeader<T>::isReservedSectionType() const {
- return getSectionType() & SectionFlagsReservedMask;
-}
-
-bool XCOFFRelocation32::isRelocationSigned() const {
- return Info & XR_SIGN_INDICATOR_MASK;
-}
-
-bool XCOFFRelocation32::isFixupIndicated() const {
- return Info & XR_FIXUP_INDICATOR_MASK;
-}
-
-uint8_t XCOFFRelocation32::getRelocatedLength() const {
- // The relocation encodes the bit length being relocated minus 1. Add back
- // the 1 to get the actual length being relocated.
- return (Info & XR_BIASED_LENGTH_MASK) + 1;
+ : StringRef(Name, Size);
}
void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
@@ -110,9 +83,6 @@ XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
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;
}
@@ -142,19 +112,23 @@ XCOFFObjectFile::sectionHeaderTable64() const {
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
SymEntPtr += SymEntPtr->NumberOfAuxEntries + 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));
-#endif
Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
}
-Expected<StringRef>
-XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
- // The byte offset is relative to the start of the string table.
- // A byte offset value of 0 is a null or zero-length symbol
+Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
+ const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+
+ if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+ return generateStringRef(SymEntPtr->SymbolName, XCOFF::SymbolNameSize);
+
+ // 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");
+
+ uint32_t Offset = SymEntPtr->NameInStrTbl.Offset;
+ // The byte offset is relative to the start of the string table
+ // or .debug section. A byte offset value of 0 is a null or zero-length symbol
// name. A byte offset in the range 1 to 3 (inclusive) points into the length
// field; as a soft-error recovery mechanism, we treat such cases as having an
// offset of 0.
@@ -164,39 +138,17 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
if (StringTable.Data != nullptr && StringTable.Size > Offset)
return (StringTable.Data + Offset);
- return make_error<GenericBinaryError>("Bad offset for string table entry",
+ return make_error<GenericBinaryError>("Symbol Name parse failed",
object_error::parse_failed);
}
-Expected<StringRef>
-XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
- if (CFileEntPtr->NameInStrTbl.Magic !=
- XCOFFSymbolEntry::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);
-}
-
Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ uint64_t Result = 0;
+ llvm_unreachable("Not yet implemented!");
+ return Result;
}
uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
return toSymbolEntry(Symb)->Value;
}
@@ -233,7 +185,7 @@ void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
}
Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
- return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
+ return generateStringRef(getSectionNameInternal(Sec), XCOFF::SectionNameSize);
}
uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
@@ -265,21 +217,7 @@ uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
Expected<ArrayRef<uint8_t>>
XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
- if (isSectionVirtual(Sec))
- return ArrayRef<uint8_t>();
-
- uint64_t OffsetToRaw;
- if (is64Bit())
- OffsetToRaw = toSection64(Sec)->FileOffsetToRawData;
- else
- OffsetToRaw = toSection32(Sec)->FileOffsetToRawData;
-
- const uint8_t * ContentStart = base() + OffsetToRaw;
- uint64_t SectionSize = getSectionSize(Sec);
- if (checkOffset(Data, uintptr_t(ContentStart), SectionSize))
- return make_error<BinaryError>();
-
- return makeArrayRef(ContentStart,SectionSize);
+ llvm_unreachable("Not yet implemented!");
}
uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
@@ -309,8 +247,9 @@ bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
}
bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
- return is64Bit() ? toSection64(Sec)->FileOffsetToRawData == 0
- : toSection32(Sec)->FileOffsetToRawData == 0;
+ bool Result = false;
+ llvm_unreachable("Not yet implemented!");
+ return Result;
}
relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
@@ -396,6 +335,7 @@ Triple::ArchType XCOFFObjectFile::getArch() const {
}
SubtargetFeatures XCOFFObjectFile::getFeatures() const {
+ llvm_unreachable("Not yet implemented!");
return SubtargetFeatures();
}
@@ -453,8 +393,8 @@ XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
default:
Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
if (SecRef)
- return generateXCOFFFixedNameStringRef(
- getSectionNameInternal(SecRef.get()));
+ return generateStringRef(getSectionNameInternal(SecRef.get()),
+ XCOFF::SectionNameSize);
return SecRef.takeError();
}
}
@@ -502,48 +442,6 @@ uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
return fileHeader64()->NumberOfSymTableEntries;
}
-uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
- uint32_t NumberOfSymTableEntries =
- is64Bit() ? getNumberOfSymbolTableEntries64()
- : getLogicalNumberOfSymbolTableEntries32();
- return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
- XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
-}
-
-void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
- if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
- report_fatal_error("Symbol table entry is outside of symbol table.");
-
- if (SymbolEntPtr >= getEndOfSymbolTableAddress())
- report_fatal_error("Symbol table entry is outside of symbol table.");
-
- ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
- reinterpret_cast<const char *>(SymbolTblPtr);
-
- if (Offset % XCOFF::SymbolTableEntrySize != 0)
- report_fatal_error(
- "Symbol table entry position is not valid inside of symbol table.");
-}
-
-uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
- return (reinterpret_cast<const char *>(SymbolEntPtr) -
- reinterpret_cast<const char *>(SymbolTblPtr)) /
- XCOFF::SymbolTableEntrySize;
-}
-
-Expected<StringRef>
-XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
- if (is64Bit())
- report_fatal_error("64-bit symbol table support not implemented yet.");
-
- if (Index >= getLogicalNumberOfSymbolTableEntries32())
- return errorCodeToError(object_error::invalid_symbol_index);
-
- DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
- return getSymbolName(SymDRI);
-}
-
uint16_t XCOFFObjectFile::getFlags() const {
return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
}
@@ -579,46 +477,6 @@ ArrayRef<XCOFFSectionHeader32> XCOFFObjectFile::sections32() const {
TablePtr + getNumberOfSections());
}
-// In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
-// section header contains the actual count of relocation entries in the s_paddr
-// field. STYP_OVRFLO headers contain the section index of their corresponding
-// sections as their raw "NumberOfRelocations" field value.
-Expected<uint32_t> XCOFFObjectFile::getLogicalNumberOfRelocationEntries(
- const XCOFFSectionHeader32 &Sec) const {
-
- uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1;
-
- if (Sec.NumberOfRelocations < RELOC_OVERFLOW)
- return Sec.NumberOfRelocations;
- for (const auto &Sec : sections32()) {
- if (Sec.Flags == XCOFF::STYP_OVRFLO &&
- Sec.NumberOfRelocations == SectionIndex)
- return Sec.PhysicalAddress;
- }
- return errorCodeToError(object_error::parse_failed);
-}
-
-Expected<ArrayRef<XCOFFRelocation32>>
-XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const {
- uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
- Sec.FileOffsetToRelocationInfo);
- auto NumRelocEntriesOrErr = getLogicalNumberOfRelocationEntries(Sec);
- if (Error E = NumRelocEntriesOrErr.takeError())
- return std::move(E);
-
- uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
-
- auto RelocationOrErr =
- getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
- NumRelocEntries * sizeof(XCOFFRelocation32));
- if (Error E = RelocationOrErr.takeError())
- return std::move(E);
-
- const XCOFFRelocation32 *StartReloc = RelocationOrErr.get();
-
- return ArrayRef<XCOFFRelocation32>(StartReloc, StartReloc + NumRelocEntries);
-}
-
Expected<XCOFFStringTable>
XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
// If there is a string table, then the buffer must contain at least 4 bytes
@@ -649,7 +507,7 @@ XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
Expected<std::unique_ptr<XCOFFObjectFile>>
XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
- // Can't use std::make_unique because of the private constructor.
+ // Can't use make_unique because of the private constructor.
std::unique_ptr<XCOFFObjectFile> Obj;
Obj.reset(new XCOFFObjectFile(Type, MBR));
@@ -714,75 +572,13 @@ ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
return XCOFFObjectFile::create(FileType, MemBufRef);
}
-XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
-}
-
-uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
-}
-
-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.");
-
- // In XCOFF32, the csect auxilliary entry is always the last auxiliary
- // entry for the symbol.
- uintptr_t AuxAddr = getWithOffset(
- SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
-
-#ifndef NDEBUG
- OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
-#endif
-
- return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
-}
-
-uint16_t XCOFFSymbolRef::getType() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
-}
-
-int16_t XCOFFSymbolRef::getSectionNumber() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+StringRef XCOFFSectionHeader32::getName() const {
+ return generateStringRef(Name, XCOFF::SectionNameSize);
}
-bool XCOFFSymbolRef::hasCsectAuxEnt() 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.");
-
- if (getType() & FUNCTION_SYM)
- return true;
-
- if (!hasCsectAuxEnt())
- return false;
-
- const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
-
- // A function definition should be a label definition.
- if ((CsectAuxEnt->SymbolAlignmentAndType & SYM_TYPE_MASK) != XCOFF::XTY_LD)
- return false;
-
- if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
- return false;
-
- int16_t SectNum = getSectionNumber();
- Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
- if (!SI)
- return false;
-
- return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+StringRef XCOFFSectionHeader64::getName() const {
+ return generateStringRef(Name, XCOFF::SectionNameSize);
}
-// Explictly instantiate template classes.
-template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
-template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
-
} // namespace object
} // namespace llvm