[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/smithp35 approved this pull request. LGTM too, thanks for the updates. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/jh7370 approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -1117,9 +1155,11 @@ void ELFObjectFile::getRelocationTypeName( template Expected ELFObjectFile::getRelocationAddend(DataRefImpl Rel) const { - if (getRelSection(Rel)->sh_type != ELF::SHT_RELA) -return createError("Section is not SHT_RELA"); - return (int64_t)getRela(Rel)->r_addend; + if (getRelSection(Rel)->sh_type == ELF::SHT_RELA) +return (int64_t)getRela(Rel)->r_addend; + if (getRelSection(Rel)->sh_type == ELF::SHT_CREL) +return (int64_t)getCrel(Rel).r_addend; + return createError("Section is not SHT_RELA"); MaskRay wrote: Error message adjusted. I think this line is dynamically unreachable. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -1117,9 +1155,11 @@ void ELFObjectFile::getRelocationTypeName( template Expected ELFObjectFile::getRelocationAddend(DataRefImpl Rel) const { - if (getRelSection(Rel)->sh_type != ELF::SHT_RELA) -return createError("Section is not SHT_RELA"); - return (int64_t)getRela(Rel)->r_addend; + if (getRelSection(Rel)->sh_type == ELF::SHT_RELA) +return (int64_t)getRela(Rel)->r_addend; + if (getRelSection(Rel)->sh_type == ELF::SHT_CREL) +return (int64_t)getCrel(Rel).r_addend; + return createError("Section is not SHT_RELA"); jh7370 wrote: I'm not sure this error quite makes sense anymore. Probably needs to say something about addends. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -207,6 +209,43 @@ bool isSectionInSegment(const typename ELFT::Phdr , checkSectionVMA(Phdr, Sec); } +template +Error decodeCrel(ArrayRef Content, + function_ref HdrHandler, MaskRay wrote: thx for the suggestion. adopted https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -207,6 +209,43 @@ bool isSectionInSegment(const typename ELFT::Phdr , checkSectionVMA(Phdr, Sec); } +template MaskRay wrote: thx for the suggestion. adopted https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -207,6 +209,43 @@ bool isSectionInSegment(const typename ELFT::Phdr , checkSectionVMA(Phdr, Sec); } +template +Error decodeCrel(ArrayRef Content, + function_ref HdrHandler, smithp35 wrote: could be worth ``` uint64_t /* relocation count */, bool /* explicit addends */ ``` https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -207,6 +209,43 @@ bool isSectionInSegment(const typename ELFT::Phdr , checkSectionVMA(Phdr, Sec); } +template smithp35 wrote: Thanks for lifting this out. Possibly worth a comment describing HdrHandler and EntryHandler. For example: ``` // The HdrHandler is called once with the number of relocations and whether the relocations have addends. // The EntryHandler is called once per decoded relocation. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/smithp35 commented: Thanks for the updates. Only a couple of small suggestions. Will be out of office till Monday next week. I'm fine with others approving. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/smithp35 edited https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -0,0 +1,213 @@ +# RUN: yaml2obj --docnum=1 %s -o %t +# RUN: llvm-objdump -r %t | FileCheck %s --strict-whitespace --match-full-lines + +# CHECK:RELOCATION RECORDS FOR [.text]: +# CHECK-NEXT:OFFSET TYPE VALUE +# CHECK-NEXT:0001 R_X86_64_32 g1+0x1 +# CHECK-NEXT:0002 R_X86_64_64 l1+0x2 +# CHECK-NEXT: R_X86_64_32S g1-0x1 +# CHECK-NEXT:0004 R_X86_64_32S .text-0x8000 +#CHECK-EMPTY: +# CHECK-NEXT:RELOCATION RECORDS FOR [nonalloc]: +# CHECK-NEXT:OFFSET TYPE VALUE +# CHECK-NEXT:0010 R_X86_64_64 g1+0x1 +# CHECK-NEXT:0020 R_X86_64_64 g2+0x2 +# CHECK-NEXT:0030 R_X86_64_64 *ABS* +# CHECK-NOT:{{.}} + +--- !ELF +FileHeader: !FileHeader + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + +Sections: +- Name: .text + Type: SHT_PROGBITS + Content: "" + Flags: [SHF_ALLOC] +- Name: .crel.text + Type: SHT_CREL + Info: .text + Link: .symtab + Relocations: +- Offset: 0x1 + Symbol: g1 + Type: R_X86_64_32 + Addend: 1 +- Offset: 0x2 + Symbol: l1 + Type: R_X86_64_64 + Addend: 2 +- Offset: 0x0 + Symbol: g1 + Type: R_X86_64_32S + Addend: 0x +- Offset: 0x4 + Symbol: .text + Type: R_X86_64_32S + Addend: 0x8000 +- Name: nonalloc + Type: SHT_PROGBITS + Size: 0x30 +- Name: .crelnonalloc + Type: SHT_CREL + Info: nonalloc + Link: .symtab + Relocations: +- Offset: 0x10 + Symbol: g1 + Type: R_X86_64_64 + Addend: 1 +- Offset: 0x20 + Symbol: g2 + Type: R_X86_64_64 + Addend: 2 +- Offset: 0x30 + Symbol: 0 + Type: R_X86_64_64 + +Symbols: + - Name: .text +Type: STT_SECTION +Section: .text + - Name:l1 + - Name:g1 +Section: .text +Value: 0x0 +Size:4 +Binding: STB_GLOBAL + - Name:g2 +Binding: STB_GLOBAL + +## Check relocation formatting on ELFCLASS32 as well. +# RUN: yaml2obj --docnum=2 %s > %t2 +# RUN: llvm-objdump -r %t2 | FileCheck %s --check-prefix=ELF32 --strict-whitespace --match-full-lines + +# ELF32:RELOCATION RECORDS FOR [.text]: +# ELF32-NEXT:OFFSET TYPE VALUE +# ELF32-NEXT:0008 R_ARM_REL32 l1+0x1 +# ELF32-NEXT:0004 R_ARM_ABS32 g1 + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data:ELFDATA2MSB + Type:ET_REL + Machine: EM_ARM +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 0x10 +- Name: .crel.text + Type: SHT_CREL + Info: .text + Link: .symtab + Relocations: +- Offset: 0x8 + Symbol: l1 + Type: R_ARM_REL32 + Addend: 1 +- Offset: 0x4 + Symbol: g1 + Type: R_ARM_ABS32 +Symbols: + - Name:l1 + - Name:g1 +Binding: STB_GLOBAL + +## Check CREL with implicit addends. +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: llvm-objdump -r %t3 | FileCheck %s --check-prefix=IMPLICIT --strict-whitespace --match-full-lines +# IMPLICIT:RELOCATION RECORDS FOR [.data]: +# IMPLICIT-NEXT:OFFSET TYPE VALUE +# IMPLICIT-NEXT:001f R_X86_64_32 g1 +# IMPLICIT-NEXT:003f R_X86_64_64 g1 +# IMPLICIT-NEXT: R_X86_64_32S l1 +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name:.text +Type:SHT_PROGBITS + - Name:.data +Type:SHT_PROGBITS + - Name:.crel.data +Type:SHT_CREL +Flags: [ SHF_INFO_LINK ] +Link:.symtab +Info:.data +Content: 187f030a82017787feff077f0a +Symbols: + - Name:.text +Type:STT_SECTION +Section: .text + - Name:l1 +Section: .text + - Name:g1 +Section: .text +Binding: STB_GLOBAL + +## Test errors. +# RUN: yaml2obj --docnum=4 %s -o %t.err +# RUN: llvm-objdump -r %t.err 2>&1 | FileCheck %s --check-prefix=ERR -DFILE=%t.err + +# ERR:RELOCATION RECORDS FOR [.data]: +# ERR-NEXT:OFFSET TYPE VALUE +# ERR-NEXT:warning: '[[FILE]]': unable to decode LEB128 at offset 0x: malformed uleb128, extends past end +# ERR-NOT:{{.}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name:.text +Type:SHT_PROGBITS + - Name:.data +Type:SHT_PROGBITS + - Name:.crel.data +Type:SHT_CREL +Flags: [] +Link:.symtab +Info:.data +Symbols: + - Name:.text +Type:STT_SECTION +Section: .text + +# RUN: yaml2obj --docnum=5 %s -o %t.err2 +# RUN: llvm-objdump -r %t.err2 2>&1 | FileCheck %s --check-prefix=ERR2
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -1453,6 +1525,15 @@ template bool ELFObjectFile::isRelocatableObject() const { return EF.getHeader().e_type == ELF::ET_REL; } +template +StringRef ELFObjectFile::getCrelError(DataRefImpl Sec) const { + uintptr_t SHT = reinterpret_cast(cantFail(EF.sections()).begin()); + auto I = (Sec.p - SHT) / EF.getHeader().e_shentsize; + if (I < CrelErrs.size()) +return CrelErrs[I]; + return ""; MaskRay wrote: I have changed `mutable SmallVector CrelErrs;` so that it is only non-empty when there is a decoder problem. This is now needed. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay edited https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -2687,6 +2687,15 @@ void Dumper::printRelocations() { << "VALUE\n"; for (SectionRef Section : P.second) { + // CREL requires decoding and has its specific errors. + if (O.isELF() && ELFSectionRef(Section).getType() == ELF::SHT_CREL) { +const ELFObjectFileBase *ELF = cast(); +StringRef Err = ELF->getCrelError(Section); +if (!Err.empty()) { + reportUniqueWarning(Err); MaskRay wrote: Adopted `getCrelDecodeProblem`. > My expectation for a decode error would be that we report it, but continue as > best we can. I would expect a non-zero error code though. Please ignore if > this isn't llvm-objdump practice. llvm-readobj tries to continue execution and report warnings. While a lot of code in llvm-objdump reports errors, there have been efforts to migrate to warnings: https://reviews.llvm.org/D154754 https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/smithp35 commented: I agree with jh7370 that it would be good to extract the decoding logic, it seems like each tool needs some way of passing in a way to step through the data, return the decoded data, and a way of storing errors. It is possible that this will end up being more code than just inlining the algorithm, however I'm hoping that this additional code is simpler and less error prone than copying the logic. May be worth a try to see what it looks like. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -2687,6 +2687,15 @@ void Dumper::printRelocations() { << "VALUE\n"; for (SectionRef Section : P.second) { + // CREL requires decoding and has its specific errors. smithp35 wrote: I recommend ``` // CREL sections require decoding, each section may have its own specific errors. ``` https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/smithp35 edited https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -1453,6 +1525,15 @@ template bool ELFObjectFile::isRelocatableObject() const { return EF.getHeader().e_type == ELF::ET_REL; } +template +StringRef ELFObjectFile::getCrelError(DataRefImpl Sec) const { + uintptr_t SHT = reinterpret_cast(cantFail(EF.sections()).begin()); + auto I = (Sec.p - SHT) / EF.getHeader().e_shentsize; + if (I < CrelErrs.size()) +return CrelErrs[I]; + return ""; smithp35 wrote: Wouldn't this be an error (or perhaps internal error) for an out of bounds access? https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -292,6 +295,11 @@ template class ELFObjectFile : public ELFObjectFileBase { const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section. const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section. + // Hold CREL relocations for SectionRef::relocations(). + mutable SmallVector, 0> Crels; + // Hold CREL decoding errors. + mutable SmallVector CrelErrs; smithp35 wrote: I expect that most objects would have no decoding errors, yet it looks like we're allocating a potentially large (intermediate ELF file as output of LTO for example) amount of empty strings. An alternative could be an unordered_map of section indexes to strings. This would also look a bit cleaner than just checking if the string is empty for no errors. I don't have a strong opinion though. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -2687,6 +2687,15 @@ void Dumper::printRelocations() { << "VALUE\n"; for (SectionRef Section : P.second) { + // CREL requires decoding and has its specific errors. + if (O.isELF() && ELFSectionRef(Section).getType() == ELF::SHT_CREL) { +const ELFObjectFileBase *ELF = cast(); +StringRef Err = ELF->getCrelError(Section); +if (!Err.empty()) { + reportUniqueWarning(Err); smithp35 wrote: If we are giving a warning rather than an error, then perhaps we should use something like `getCrelDecodeProblem` Just looks a bit strange recording errors, but then only reporting a warning. My expectation for a decode error would be that we report it, but continue as best we can. I would expect a non-zero error code though. Please ignore if this isn't llvm-objdump practice. https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
@@ -1022,6 +1033,47 @@ ELFObjectFile::section_rel_begin(DataRefImpl Sec) const { uintptr_t SHT = reinterpret_cast((*SectionsOrErr).begin()); RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize; RelData.d.b = 0; + if (reinterpret_cast(Sec.p)->sh_type == ELF::SHT_CREL) { +if (RelData.d.a + 1 > Crels.size()) { + Crels.resize(RelData.d.a + 1); + CrelErrs.resize(RelData.d.a + 1); +} +if (Crels[RelData.d.a].empty()) { + // Decode SHT_CREL. See ELFFile::decodeCrel. + ArrayRef Content = cantFail(getSectionContents(Sec)); + DataExtractor Data(Content, ELFT::Endianness == endianness::little, + sizeof(typename ELFT::Addr)); + DataExtractor::Cursor Cur(0); + const uint64_t Hdr = Data.getULEB128(Cur); + const size_t Count = Hdr / 8; + const size_t FlagBits = Hdr & ELF::CREL_HDR_ADDEND ? 3 : 2; + const size_t Shift = Hdr % ELF::CREL_HDR_ADDEND; + uintX_t Offset = 0, Addend = 0; + uint32_t Symidx = 0, Type = 0; + for (size_t i = 0; i != Count; ++i) { jh7370 wrote: It really doesn't feel right that this whole algorithm is duplicated from the version in ELF.cpp. Surely they can be folded together into shared code somewhere? https://github.com/llvm/llvm-project/pull/97382 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
llvmbot wrote: @llvm/pr-subscribers-llvm-binary-utilities Author: Fangrui Song (MaskRay) Changes The decoder code is similar to that for llvm-readelf -r (#91280). Because the section representation of LLVMObject (`SectionRef`) is 64-bit, insufficient to hold all decoder states, `section_rel_begin` is modified to decode CREL eagerly and hold the decoded relocations inside ELFObjectFileELFT. The test is adapted from llvm/test/tools/llvm-readobj/ELF/crel.test. --- Full diff: https://github.com/llvm/llvm-project/pull/97382.diff 6 Files Affected: - (modified) llvm/include/llvm/Object/ELFObjectFile.h (+87-6) - (modified) llvm/lib/Object/ELFObjectFile.cpp (+11) - (added) llvm/test/tools/llvm-objdump/ELF/crel.test (+213) - (modified) llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test (+4) - (modified) llvm/tools/llvm-objdump/ELFDump.cpp (+5-1) - (modified) llvm/tools/llvm-objdump/llvm-objdump.cpp (+9) ``diff diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 8cc09e7fd7d55..665d848d5b607 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -29,6 +29,7 @@ #include "llvm/Support/ELFAttributes.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/TargetParser/SubtargetFeature.h" @@ -122,6 +123,8 @@ class ELFObjectFileBase : public ObjectFile { Expected> readBBAddrMap(std::optional TextSectionIndex = std::nullopt, std::vector *PGOAnalyses = nullptr) const; + + StringRef getCrelError(SectionRef Sec) const; }; class ELFSectionRef : public SectionRef { @@ -292,6 +295,11 @@ template class ELFObjectFile : public ELFObjectFileBase { const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section. const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section. + // Hold CREL relocations for SectionRef::relocations(). + mutable SmallVector, 0> Crels; + // Hold CREL decoding errors. + mutable SmallVector CrelErrs; + Error initContent() override; void moveSymbolNext(DataRefImpl ) const override; @@ -446,6 +454,7 @@ template class ELFObjectFile : public ELFObjectFileBase { const Elf_Rel *getRel(DataRefImpl Rel) const; const Elf_Rela *getRela(DataRefImpl Rela) const; + Elf_Crel getCrel(DataRefImpl Crel) const; Expected getSymbol(DataRefImpl Sym) const { return EF.template getEntry(Sym.d.a, Sym.d.b); @@ -499,6 +508,8 @@ template class ELFObjectFile : public ELFObjectFileBase { bool isRelocatableObject() const override; void createFakeSections() { EF.createFakeSections(); } + + StringRef getCrelError(DataRefImpl Sec) const; }; using ELF32LEObjectFile = ELFObjectFile; @@ -1022,6 +1033,47 @@ ELFObjectFile::section_rel_begin(DataRefImpl Sec) const { uintptr_t SHT = reinterpret_cast((*SectionsOrErr).begin()); RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize; RelData.d.b = 0; + if (reinterpret_cast(Sec.p)->sh_type == ELF::SHT_CREL) { +if (RelData.d.a + 1 > Crels.size()) { + Crels.resize(RelData.d.a + 1); + CrelErrs.resize(RelData.d.a + 1); +} +if (Crels[RelData.d.a].empty()) { + // Decode SHT_CREL. See ELFFile::decodeCrel. + ArrayRef Content = cantFail(getSectionContents(Sec)); + DataExtractor Data(Content, ELFT::Endianness == endianness::little, + sizeof(typename ELFT::Addr)); + DataExtractor::Cursor Cur(0); + const uint64_t Hdr = Data.getULEB128(Cur); + const size_t Count = Hdr / 8; + const size_t FlagBits = Hdr & ELF::CREL_HDR_ADDEND ? 3 : 2; + const size_t Shift = Hdr % ELF::CREL_HDR_ADDEND; + uintX_t Offset = 0, Addend = 0; + uint32_t Symidx = 0, Type = 0; + for (size_t i = 0; i != Count; ++i) { +const uint8_t B = Data.getU8(Cur); +Offset += B >> FlagBits; +if (B >= 0x80) + Offset += + (Data.getULEB128(Cur) << (7 - FlagBits)) - (0x80 >> FlagBits); +if (B & 1) + Symidx += Data.getSLEB128(Cur); +if (B & 2) + Type += Data.getSLEB128(Cur); +if (B & 4 && FlagBits == 3) + Addend += Data.getSLEB128(Cur); +if (!Cur) + break; +Crels[RelData.d.a].push_back( +Elf_Crel{Offset << Shift, uint32_t(Symidx), Type, + std::make_signed_t(Addend)}); + } + if (!Cur) { +Crels[RelData.d.a].assign(1, Elf_Crel{0, 0, 0, 0}); +CrelErrs[RelData.d.a] = toString(Cur.takeError()); + } +} + } return relocation_iterator(RelocationRef(RelData, this)); } @@ -1030,9 +1082,13 @@ relocation_iterator ELFObjectFile::section_rel_end(DataRefImpl Sec) const { const Elf_Shdr *S = reinterpret_cast(Sec.p); relocation_iterator Begin = section_rel_begin(Sec); +
[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/97382 The decoder code is similar to that for llvm-readelf -r (#91280). Because the section representation of LLVMObject (`SectionRef`) is 64-bit, insufficient to hold all decoder states, `section_rel_begin` is modified to decode CREL eagerly and hold the decoded relocations inside ELFObjectFile. The test is adapted from llvm/test/tools/llvm-readobj/ELF/crel.test. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits