diff options
author | Esme-Yi <esme.yi@ibm.com> | 2021-08-26 07:17:06 +0000 |
---|---|---|
committer | Esme-Yi <esme.yi@ibm.com> | 2021-08-26 07:17:06 +0000 |
commit | b21ed75e107b10e7b82aa3da87c918214a4f0c0d (patch) | |
tree | 9df5235cf00f395e37d56739b8fb645cd714b73d /llvm/lib/Object/XCOFFObjectFile.cpp | |
parent | d280a76908e841da9e956a113d219e35247272bf (diff) | |
download | llvm-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.cpp | 73 |
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. |