aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-04-14 21:41:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-06-22 18:20:56 +0000
commitbdd1243df58e60e85101c09001d9812a789b6bc4 (patch)
treea1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
parent781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff)
parente3b557809604d036af6e00c60f012c2025b59a5e (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp156
1 files changed, 123 insertions, 33 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
index ff39fe1794c0..68baefcd6eaa 100644
--- a/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -86,6 +86,37 @@ uint8_t XCOFFRelocation<AddressType>::getRelocatedLength() const {
return (Info & XR_BIASED_LENGTH_MASK) + 1;
}
+template struct ExceptionSectionEntry<support::ubig32_t>;
+template struct ExceptionSectionEntry<support::ubig64_t>;
+
+template <typename T>
+Expected<StringRef> getLoaderSecSymNameInStrTbl(const T *LoaderSecHeader,
+ uint64_t Offset) {
+ if (LoaderSecHeader->LengthOfStrTbl > Offset)
+ return (reinterpret_cast<const char *>(LoaderSecHeader) +
+ LoaderSecHeader->OffsetToStrTbl + Offset);
+
+ return createError("entry with offset 0x" + Twine::utohexstr(Offset) +
+ " in the loader section's string table with size 0x" +
+ Twine::utohexstr(LoaderSecHeader->LengthOfStrTbl) +
+ " is invalid");
+}
+
+Expected<StringRef> LoaderSectionSymbolEntry32::getSymbolName(
+ const LoaderSectionHeader32 *LoaderSecHeader32) const {
+ const NameOffsetInStrTbl *NameInStrTbl =
+ reinterpret_cast<const NameOffsetInStrTbl *>(SymbolName);
+ if (NameInStrTbl->IsNameInStrTbl != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
+ return generateXCOFFFixedNameStringRef(SymbolName);
+
+ return getLoaderSecSymNameInStrTbl(LoaderSecHeader32, NameInStrTbl->Offset);
+}
+
+Expected<StringRef> LoaderSectionSymbolEntry64::getSymbolName(
+ const LoaderSectionHeader64 *LoaderSecHeader64) const {
+ return getLoaderSecSymNameInStrTbl(LoaderSecHeader64, Offset);
+}
+
uintptr_t
XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
uint32_t Distance) {
@@ -383,7 +414,7 @@ XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
Twine::utohexstr(OffsetToRaw) + " and size 0x" +
Twine::utohexstr(SectionSize) + " goes past the end of the file");
- return makeArrayRef(ContentStart,SectionSize);
+ return ArrayRef(ContentStart, SectionSize);
}
uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
@@ -392,41 +423,58 @@ uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
return Result;
}
-Expected<uintptr_t> XCOFFObjectFile::getLoaderSectionAddress() const {
- uint64_t OffsetToLoaderSection = 0;
- uint64_t SizeOfLoaderSection = 0;
+uint64_t XCOFFObjectFile::getSectionFileOffsetToRawData(DataRefImpl Sec) const {
+ if (is64Bit())
+ return toSection64(Sec)->FileOffsetToRawData;
- if (is64Bit()) {
- for (const auto &Sec64 : sections64())
- if (Sec64.getSectionType() == XCOFF::STYP_LOADER) {
- OffsetToLoaderSection = Sec64.FileOffsetToRawData;
- SizeOfLoaderSection = Sec64.SectionSize;
- break;
- }
- } else {
- for (const auto &Sec32 : sections32())
- if (Sec32.getSectionType() == XCOFF::STYP_LOADER) {
- OffsetToLoaderSection = Sec32.FileOffsetToRawData;
- SizeOfLoaderSection = Sec32.SectionSize;
- break;
- }
- }
+ return toSection32(Sec)->FileOffsetToRawData;
+}
+
+Expected<uintptr_t> XCOFFObjectFile::getSectionFileOffsetToRawData(
+ XCOFF::SectionTypeFlags SectType) const {
+ DataRefImpl DRI = getSectionByType(SectType);
- // No loader section is not an error.
- if (!SizeOfLoaderSection)
+ if (DRI.p == 0) // No section is not an error.
return 0;
- uintptr_t LoderSectionStart =
- reinterpret_cast<uintptr_t>(base() + OffsetToLoaderSection);
- if (Error E =
- Binary::checkOffset(Data, LoderSectionStart, SizeOfLoaderSection))
- return createError(toString(std::move(E)) +
- ": loader section with offset 0x" +
- Twine::utohexstr(OffsetToLoaderSection) +
- " and size 0x" + Twine::utohexstr(SizeOfLoaderSection) +
+ uint64_t SectionOffset = getSectionFileOffsetToRawData(DRI);
+ uint64_t SizeOfSection = getSectionSize(DRI);
+
+ uintptr_t SectionStart = reinterpret_cast<uintptr_t>(base() + SectionOffset);
+ if (Error E = Binary::checkOffset(Data, SectionStart, SizeOfSection)) {
+ SmallString<32> UnknownType;
+ Twine(("<Unknown:") + Twine::utohexstr(SectType) + ">")
+ .toVector(UnknownType);
+ const char *SectionName = UnknownType.c_str();
+
+ switch (SectType) {
+#define ECASE(Value, String) \
+ case XCOFF::Value: \
+ SectionName = String; \
+ break
+
+ ECASE(STYP_PAD, "pad");
+ ECASE(STYP_DWARF, "dwarf");
+ ECASE(STYP_TEXT, "text");
+ ECASE(STYP_DATA, "data");
+ ECASE(STYP_BSS, "bss");
+ ECASE(STYP_EXCEPT, "expect");
+ ECASE(STYP_INFO, "info");
+ ECASE(STYP_TDATA, "tdata");
+ ECASE(STYP_TBSS, "tbss");
+ ECASE(STYP_LOADER, "loader");
+ ECASE(STYP_DEBUG, "debug");
+ ECASE(STYP_TYPCHK, "typchk");
+ ECASE(STYP_OVRFLO, "ovrflo");
+#undef ECASE
+ }
+ return createError(toString(std::move(E)) + ": " + SectionName +
+ " section with offset 0x" +
+ Twine::utohexstr(SectionOffset) + " and size 0x" +
+ Twine::utohexstr(SizeOfSection) +
" goes past the end of the file");
-
- return LoderSectionStart;
+ }
+ return SectionStart;
}
bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
@@ -664,7 +712,7 @@ Triple::ArchType XCOFFObjectFile::getArch() const {
return is64Bit() ? Triple::ppc64 : Triple::ppc;
}
-SubtargetFeatures XCOFFObjectFile::getFeatures() const {
+Expected<SubtargetFeatures> XCOFFObjectFile::getFeatures() const {
return SubtargetFeatures();
}
@@ -738,6 +786,22 @@ Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
return DRI;
}
+DataRefImpl
+XCOFFObjectFile::getSectionByType(XCOFF::SectionTypeFlags SectType) const {
+ DataRefImpl DRI;
+ auto GetSectionAddr = [&](const auto &Sections) -> uintptr_t {
+ for (const auto &Sec : Sections)
+ if (Sec.getSectionType() == SectType)
+ return reinterpret_cast<uintptr_t>(&Sec);
+ return uintptr_t(0);
+ };
+ if (is64Bit())
+ DRI.p = GetSectionAddr(sections64());
+ else
+ DRI.p = GetSectionAddr(sections32());
+ return DRI;
+}
+
Expected<StringRef>
XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
const int16_t SectionNum = SymEntPtr.getSectionNumber();
@@ -960,6 +1024,31 @@ Expected<ArrayRef<Reloc>> XCOFFObjectFile::relocations(const Shdr &Sec) const {
return ArrayRef<Reloc>(StartReloc, StartReloc + NumRelocEntries);
}
+template <typename ExceptEnt>
+Expected<ArrayRef<ExceptEnt>> XCOFFObjectFile::getExceptionEntries() const {
+ assert((is64Bit() && sizeof(ExceptEnt) == sizeof(ExceptionSectionEntry64)) ||
+ (!is64Bit() && sizeof(ExceptEnt) == sizeof(ExceptionSectionEntry32)));
+
+ Expected<uintptr_t> ExceptionSectOrErr =
+ getSectionFileOffsetToRawData(XCOFF::STYP_EXCEPT);
+ if (!ExceptionSectOrErr)
+ return ExceptionSectOrErr.takeError();
+
+ DataRefImpl DRI = getSectionByType(XCOFF::STYP_EXCEPT);
+ if (DRI.p == 0)
+ return ArrayRef<ExceptEnt>();
+
+ ExceptEnt *ExceptEntStart =
+ reinterpret_cast<ExceptEnt *>(*ExceptionSectOrErr);
+ return ArrayRef<ExceptEnt>(
+ ExceptEntStart, ExceptEntStart + getSectionSize(DRI) / sizeof(ExceptEnt));
+}
+
+template Expected<ArrayRef<ExceptionSectionEntry32>>
+XCOFFObjectFile::getExceptionEntries() const;
+template Expected<ArrayRef<ExceptionSectionEntry64>>
+XCOFFObjectFile::getExceptionEntries() const;
+
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
@@ -997,7 +1086,8 @@ XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
// This function returns the import file table. Each entry in the import file
// table consists of: "path_name\0base_name\0archive_member_name\0".
Expected<StringRef> XCOFFObjectFile::getImportFileTable() const {
- Expected<uintptr_t> LoaderSectionAddrOrError = getLoaderSectionAddress();
+ Expected<uintptr_t> LoaderSectionAddrOrError =
+ getSectionFileOffsetToRawData(XCOFF::STYP_LOADER);
if (!LoaderSectionAddrOrError)
return LoaderSectionAddrOrError.takeError();