diff options
author | Maryam Benimmar <maryam.benimmar@atos.net> | 2021-08-17 14:22:29 -0400 |
---|---|---|
committer | David Tenty <daltenty@ibm.com> | 2021-08-19 21:56:57 -0400 |
commit | 2cdfd0b2597668d4adc1ea54a7ffdd59e5585279 (patch) | |
tree | a8033b726fd18d2036631f7714d171b15cf88281 /llvm/lib/Object/XCOFFObjectFile.cpp | |
parent | 337bd67d836b7cb7a18fb08df8f3a7902338c7fa (diff) | |
download | llvm-2cdfd0b2597668d4adc1ea54a7ffdd59e5585279.zip llvm-2cdfd0b2597668d4adc1ea54a7ffdd59e5585279.tar.gz llvm-2cdfd0b2597668d4adc1ea54a7ffdd59e5585279.tar.bz2 |
[AIX][XCOFF] 64-bit relocation reading support
Support XCOFFDumper relocation reading support
This patch is part of D103696 partition
Reviewed By: daltenty, Helflym
Differential Revision: https://reviews.llvm.org/D104646
Diffstat (limited to 'llvm/lib/Object/XCOFFObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/XCOFFObjectFile.cpp | 197 |
1 files changed, 137 insertions, 60 deletions
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index 28355b6..7ec418c 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -69,15 +69,18 @@ bool XCOFFSectionHeader<T>::isReservedSectionType() const { return getSectionType() & SectionFlagsReservedMask; } -bool XCOFFRelocation32::isRelocationSigned() const { +template <typename AddressType> +bool XCOFFRelocation<AddressType>::isRelocationSigned() const { return Info & XR_SIGN_INDICATOR_MASK; } -bool XCOFFRelocation32::isFixupIndicated() const { +template <typename AddressType> +bool XCOFFRelocation<AddressType>::isFixupIndicated() const { return Info & XR_FIXUP_INDICATOR_MASK; } -uint8_t XCOFFRelocation32::getRelocatedLength() const { +template <typename AddressType> +uint8_t XCOFFRelocation<AddressType>::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; @@ -146,6 +149,10 @@ const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const { return static_cast<const XCOFFFileHeader64 *>(FileHeader); } +template <typename T> const T *XCOFFObjectFile::sectionHeaderTable() const { + return static_cast<const T *>(SectionHeaderTable); +} + const XCOFFSectionHeader32 * XCOFFObjectFile::sectionHeaderTable32() const { assert(!is64Bit() && "32-bit interface called on 64-bit object file."); @@ -329,61 +336,112 @@ bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const { } relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const { - if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); - const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec); - auto RelocationsOrErr = relocations(*SectionEntPtr); - if (Error E = RelocationsOrErr.takeError()) - return relocation_iterator(RelocationRef()); DataRefImpl Ret; - Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin()); + if (is64Bit()) { + const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec); + auto RelocationsOrErr = + relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr); + if (Error E = RelocationsOrErr.takeError()) { + // TODO: report the error up the stack. + consumeError(std::move(E)); + return relocation_iterator(RelocationRef()); + } + Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin()); + } else { + const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec); + auto RelocationsOrErr = + relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr); + if (Error E = RelocationsOrErr.takeError()) { + // TODO: report the error up the stack. + consumeError(std::move(E)); + return relocation_iterator(RelocationRef()); + } + Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().begin()); + } return relocation_iterator(RelocationRef(Ret, this)); } relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const { - if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); - const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec); - auto RelocationsOrErr = relocations(*SectionEntPtr); - if (Error E = RelocationsOrErr.takeError()) - return relocation_iterator(RelocationRef()); DataRefImpl Ret; - Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end()); + if (is64Bit()) { + const XCOFFSectionHeader64 *SectionEntPtr = toSection64(Sec); + auto RelocationsOrErr = + relocations<XCOFFSectionHeader64, XCOFFRelocation64>(*SectionEntPtr); + if (Error E = RelocationsOrErr.takeError()) { + // TODO: report the error up the stack. + consumeError(std::move(E)); + return relocation_iterator(RelocationRef()); + } + Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end()); + } else { + const XCOFFSectionHeader32 *SectionEntPtr = toSection32(Sec); + auto RelocationsOrErr = + relocations<XCOFFSectionHeader32, XCOFFRelocation32>(*SectionEntPtr); + if (Error E = RelocationsOrErr.takeError()) { + // TODO: report the error up the stack. + consumeError(std::move(E)); + return relocation_iterator(RelocationRef()); + } + Ret.p = reinterpret_cast<uintptr_t>(&*RelocationsOrErr.get().end()); + } return relocation_iterator(RelocationRef(Ret, this)); } void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { - Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1); + if (is64Bit()) + Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation64>(Rel.p) + 1); + else + Rel.p = reinterpret_cast<uintptr_t>(viewAs<XCOFFRelocation32>(Rel.p) + 1); } uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const { - if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); - const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); - const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32(); - const uint32_t RelocAddress = Reloc->VirtualAddress; - const uint16_t NumberOfSections = getNumberOfSections(); - for (uint16_t i = 0; i < NumberOfSections; ++i) { - // Find which section this relocation is belonging to, and get the - // relocation offset relative to the start of the section. - if (Sec32->VirtualAddress <= RelocAddress && - RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) { - return RelocAddress - Sec32->VirtualAddress; + if (is64Bit()) { + const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p); + const XCOFFSectionHeader64 *Sec64 = sectionHeaderTable64(); + const uint64_t RelocAddress = Reloc->VirtualAddress; + const uint16_t NumberOfSections = getNumberOfSections(); + for (uint16_t I = 0; I < NumberOfSections; ++I) { + // Find which section this relocation belongs to, and get the + // relocation offset relative to the start of the section. + if (Sec64->VirtualAddress <= RelocAddress && + RelocAddress < Sec64->VirtualAddress + Sec64->SectionSize) { + return RelocAddress - Sec64->VirtualAddress; + } + ++Sec64; + } + } else { + const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); + const XCOFFSectionHeader32 *Sec32 = sectionHeaderTable32(); + const uint32_t RelocAddress = Reloc->VirtualAddress; + const uint16_t NumberOfSections = getNumberOfSections(); + for (uint16_t I = 0; I < NumberOfSections; ++I) { + // Find which section this relocation belongs to, and get the + // relocation offset relative to the start of the section. + if (Sec32->VirtualAddress <= RelocAddress && + RelocAddress < Sec32->VirtualAddress + Sec32->SectionSize) { + return RelocAddress - Sec32->VirtualAddress; + } + ++Sec32; } - ++Sec32; } return InvalidRelocOffset; } symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { - if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); - const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); - const uint32_t Index = Reloc->SymbolIndex; - - if (Index >= getLogicalNumberOfSymbolTableEntries32()) - return symbol_end(); - + uint32_t Index; + if (is64Bit()) { + const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p); + Index = Reloc->SymbolIndex; + + if (Index >= getNumberOfSymbolTableEntries64()) + return symbol_end(); + } else { + const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); + Index = Reloc->SymbolIndex; + + if (Index >= getLogicalNumberOfSymbolTableEntries32()) + return symbol_end(); + } DataRefImpl SymDRI; SymDRI.p = getSymbolEntryAddressByIndex(Index); return symbol_iterator(SymbolRef(SymDRI, this)); @@ -391,16 +449,20 @@ symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const { if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); + return viewAs<XCOFFRelocation64>(Rel.p)->Type; return viewAs<XCOFFRelocation32>(Rel.p)->Type; } void XCOFFObjectFile::getRelocationTypeName( DataRefImpl Rel, SmallVectorImpl<char> &Result) const { - if (is64Bit()) - report_fatal_error("64-bit support not implemented yet"); - const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); - StringRef Res = XCOFF::getRelocationTypeString(Reloc->Type); + StringRef Res; + if (is64Bit()) { + const XCOFFRelocation64 *Reloc = viewAs<XCOFFRelocation64>(Rel.p); + Res = XCOFF::getRelocationTypeString(Reloc->Type); + } else { + const XCOFFRelocation32 *Reloc = viewAs<XCOFFRelocation32>(Rel.p); + Res = XCOFF::getRelocationTypeString(Reloc->Type); + } Result.append(Res.begin(), Res.end()); } @@ -661,13 +723,16 @@ ArrayRef<XCOFFSectionHeader32> XCOFFObjectFile::sections32() const { // 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; +template <typename T> +Expected<uint32_t> XCOFFObjectFile::getNumberOfRelocationEntries( + const XCOFFSectionHeader<T> &Sec) const { + const T &Section = static_cast<const T &>(Sec); + if (is64Bit()) + return Section.NumberOfRelocations; - if (Sec.NumberOfRelocations < XCOFF::RelocOverflow) - return Sec.NumberOfRelocations; + uint16_t SectionIndex = &Section - sectionHeaderTable<T>() + 1; + if (Section.NumberOfRelocations < XCOFF::RelocOverflow) + return Section.NumberOfRelocations; for (const auto &Sec : sections32()) { if (Sec.Flags == XCOFF::STYP_OVRFLO && Sec.NumberOfRelocations == SectionIndex) @@ -676,27 +741,27 @@ Expected<uint32_t> XCOFFObjectFile::getLogicalNumberOfRelocationEntries( return errorCodeToError(object_error::parse_failed); } -Expected<ArrayRef<XCOFFRelocation32>> -XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const { +template <typename Shdr, typename Reloc> +Expected<ArrayRef<Reloc>> XCOFFObjectFile::relocations(const Shdr &Sec) const { uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader), Sec.FileOffsetToRelocationInfo); - auto NumRelocEntriesOrErr = getLogicalNumberOfRelocationEntries(Sec); + auto NumRelocEntriesOrErr = getNumberOfRelocationEntries(Sec); if (Error E = NumRelocEntriesOrErr.takeError()) return std::move(E); uint32_t NumRelocEntries = NumRelocEntriesOrErr.get(); - - static_assert( - sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32, ""); + static_assert((sizeof(Reloc) == XCOFF::RelocationSerializationSize64 || + sizeof(Reloc) == XCOFF::RelocationSerializationSize32), + "Relocation structure is incorrect"); auto RelocationOrErr = - getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr), - NumRelocEntries * sizeof(XCOFFRelocation32)); + getObject<Reloc>(Data, reinterpret_cast<void *>(RelocAddr), + NumRelocEntries * sizeof(Reloc)); if (Error E = RelocationOrErr.takeError()) return std::move(E); - const XCOFFRelocation32 *StartReloc = RelocationOrErr.get(); + const Reloc *StartReloc = RelocationOrErr.get(); - return ArrayRef<XCOFFRelocation32>(StartReloc, StartReloc + NumRelocEntries); + return ArrayRef<Reloc>(StartReloc, StartReloc + NumRelocEntries); } Expected<XCOFFStringTable> @@ -900,6 +965,18 @@ Expected<StringRef> XCOFFSymbolRef::getName() const { template struct XCOFFSectionHeader<XCOFFSectionHeader32>; template struct XCOFFSectionHeader<XCOFFSectionHeader64>; +template struct XCOFFRelocation<llvm::support::ubig32_t>; +template struct XCOFFRelocation<llvm::support::ubig64_t>; + +template llvm::Expected<llvm::ArrayRef<llvm::object::XCOFFRelocation64>> +llvm::object::XCOFFObjectFile::relocations<llvm::object::XCOFFSectionHeader64, + llvm::object::XCOFFRelocation64>( + llvm::object::XCOFFSectionHeader64 const &) const; +template llvm::Expected<llvm::ArrayRef<llvm::object::XCOFFRelocation32>> +llvm::object::XCOFFObjectFile::relocations<llvm::object::XCOFFSectionHeader32, + llvm::object::XCOFFRelocation32>( + llvm::object::XCOFFSectionHeader32 const &) const; + bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) { if (Bytes.size() < 4) return false; |