aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
authorzhijian <zhijian@ca.ibm.com>2022-09-19 10:55:48 -0400
committerzhijian <zhijian@ca.ibm.com>2022-09-19 10:55:48 -0400
commitdcd5abd4c482d6d5301990078091f1d26dc17872 (patch)
treea8995d9cd62114f0b7c3444f311a6ded201ee1af /llvm/lib/Object/XCOFFObjectFile.cpp
parent924974a3a13b03090d04860f209ce11b3d9d00a6 (diff)
downloadllvm-dcd5abd4c482d6d5301990078091f1d26dc17872.zip
llvm-dcd5abd4c482d6d5301990078091f1d26dc17872.tar.gz
llvm-dcd5abd4c482d6d5301990078091f1d26dc17872.tar.bz2
[AIX] llvm-readobj support a new option --exception-section for xcoff object file.
Summary: llvm-readobj support a new option --exception-section for xcoff object file. https://www.ibm.com/docs/en/aix/7.2?topic=formats-xcoff-object-file-format#XCOFF__iua3i23ajbau Reviewers: James Henderson,Paul Scoropan Differential Revision: https://reviews.llvm.org/D133030
Diffstat (limited to 'llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/XCOFFObjectFile.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index ff39fe1..b1f44f1 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -86,6 +86,9 @@ 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>;
+
uintptr_t
XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
uint32_t Distance) {
@@ -392,6 +395,13 @@ uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
return Result;
}
+uint64_t XCOFFObjectFile::getSectionFileOffsetToRawData(DataRefImpl Sec) const {
+ if (is64Bit())
+ return toSection64(Sec)->FileOffsetToRawData;
+
+ return toSection32(Sec)->FileOffsetToRawData;
+}
+
Expected<uintptr_t> XCOFFObjectFile::getLoaderSectionAddress() const {
uint64_t OffsetToLoaderSection = 0;
uint64_t SizeOfLoaderSection = 0;
@@ -429,6 +439,53 @@ Expected<uintptr_t> XCOFFObjectFile::getLoaderSectionAddress() const {
return LoderSectionStart;
}
+Expected<uintptr_t> XCOFFObjectFile::getSectionFileOffsetToRawData(
+ XCOFF::SectionTypeFlags SectType) const {
+ DataRefImpl DRI = getSectionByType(SectType);
+
+ if (DRI.p == 0) // No section is not an error.
+ return 0;
+
+ 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 SectionStart;
+}
+
bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
return false;
}
@@ -738,6 +795,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) {
+ for (const auto &Sec : Sections)
+ if (Sec.getSectionType() == SectType)
+ return reinterpret_cast<uintptr_t>(&Sec);
+ return 0ul;
+ };
+ 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 +1033,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