aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/XCOFFObjectFile.cpp
diff options
context:
space:
mode:
authorEsme-Yi <esme.yi@ibm.com>2021-08-26 07:17:06 +0000
committerEsme-Yi <esme.yi@ibm.com>2021-08-26 07:17:06 +0000
commitb21ed75e107b10e7b82aa3da87c918214a4f0c0d (patch)
tree9df5235cf00f395e37d56739b8fb645cd714b73d /llvm/lib/Object/XCOFFObjectFile.cpp
parentd280a76908e841da9e956a113d219e35247272bf (diff)
downloadllvm-b21ed75e107b10e7b82aa3da87c918214a4f0c0d.zip
llvm-b21ed75e107b10e7b82aa3da87c918214a4f0c0d.tar.gz
llvm-b21ed75e107b10e7b82aa3da87c918214a4f0c0d.tar.bz2
[llvm-readobj][XCOFF] Add support for `--needed-libs` option.
Summary: This patch is trying to add support for llvm-readobj --needed-libs option under XCOFF. For XCOFF, the needed libraries can be found from the Import File ID Name Table of the Loader Section. Currently, I am using binary inputs in the test since yaml2obj does not yet support for writing the Loader Section and the import file table. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D106643
Diffstat (limited to 'llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r--llvm/lib/Object/XCOFFObjectFile.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 7ec418c..dfb48e6 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -307,6 +307,38 @@ uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
return Result;
}
+Expected<uintptr_t> XCOFFObjectFile::getLoaderSectionAddress() const {
+ uint64_t OffsetToLoaderSection = 0;
+ uint64_t SizeOfLoaderSection = 0;
+
+ 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;
+ }
+ }
+
+ // No loader section is not an error.
+ if (!SizeOfLoaderSection)
+ return 0;
+
+ uintptr_t LoderSectionStart =
+ reinterpret_cast<uintptr_t>(base() + OffsetToLoaderSection);
+ if (Error E =
+ Binary::checkOffset(Data, LoderSectionStart, SizeOfLoaderSection))
+ return std::move(E);
+ return LoderSectionStart;
+}
+
bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
return false;
}
@@ -794,6 +826,47 @@ XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
return XCOFFStringTable{Size, StringTablePtr};
}
+// 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();
+ if (!LoaderSectionAddrOrError)
+ return LoaderSectionAddrOrError.takeError();
+
+ uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get();
+ if (!LoaderSectionAddr)
+ return StringRef();
+
+ uint64_t OffsetToImportFileTable = 0;
+ uint64_t LengthOfImportFileTable = 0;
+ if (is64Bit()) {
+ const LoaderSectionHeader64 *LoaderSec64 =
+ viewAs<LoaderSectionHeader64>(LoaderSectionAddr);
+ OffsetToImportFileTable = LoaderSec64->OffsetToImpid;
+ LengthOfImportFileTable = LoaderSec64->LengthOfImpidStrTbl;
+ } else {
+ const LoaderSectionHeader32 *LoaderSec32 =
+ viewAs<LoaderSectionHeader32>(LoaderSectionAddr);
+ OffsetToImportFileTable = LoaderSec32->OffsetToImpid;
+ LengthOfImportFileTable = LoaderSec32->LengthOfImpidStrTbl;
+ }
+
+ auto ImportTableOrErr = getObject<char>(
+ Data,
+ reinterpret_cast<void *>(LoaderSectionAddr + OffsetToImportFileTable),
+ LengthOfImportFileTable);
+ if (Error E = ImportTableOrErr.takeError())
+ return std::move(E);
+
+ const char *ImportTablePtr = ImportTableOrErr.get();
+ if (ImportTablePtr[LengthOfImportFileTable - 1] != '\0')
+ return createStringError(
+ object_error::parse_failed,
+ "the import file table must end with a null terminator");
+
+ return StringRef(ImportTablePtr, LengthOfImportFileTable);
+}
+
Expected<std::unique_ptr<XCOFFObjectFile>>
XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
// Can't use std::make_unique because of the private constructor.