-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[llvm-objdump] -r: support CREL #97382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Created using spr 1.3.5-bogner [skip ci]
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-llvm-binary-utilities Author: Fangrui Song (MaskRay) ChangesThe decoder code is similar to that for llvm-readelf -r (#91280). Because the section representation of LLVMObject ( 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:
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<std::vector<BBAddrMap>>
readBBAddrMap(std::optional<unsigned> TextSectionIndex = std::nullopt,
std::vector<PGOAnalysisMap> *PGOAnalyses = nullptr) const;
+
+ StringRef getCrelError(SectionRef Sec) const;
};
class ELFSectionRef : public SectionRef {
@@ -292,6 +295,11 @@ template <class ELFT> 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<SmallVector<Elf_Crel, 0>, 0> Crels;
+ // Hold CREL decoding errors.
+ mutable SmallVector<std::string, 0> CrelErrs;
+
Error initContent() override;
void moveSymbolNext(DataRefImpl &Symb) const override;
@@ -446,6 +454,7 @@ template <class ELFT> 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<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
@@ -499,6 +508,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
bool isRelocatableObject() const override;
void createFakeSections() { EF.createFakeSections(); }
+
+ StringRef getCrelError(DataRefImpl Sec) const;
};
using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
@@ -1022,6 +1033,47 @@ ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize;
RelData.d.b = 0;
+ if (reinterpret_cast<const Elf_Shdr *>(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<ELFT>::decodeCrel.
+ ArrayRef<uint8_t> 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<typename ELFT::uint>(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<ELFT>::section_rel_end(DataRefImpl Sec) const {
const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
relocation_iterator Begin = section_rel_begin(Sec);
+ DataRefImpl RelData = Begin->getRawDataRefImpl();
+ if (S->sh_type == ELF::SHT_CREL) {
+ RelData.d.b = Crels[RelData.d.a].size();
+ return relocation_iterator(RelocationRef(RelData, this));
+ }
if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
return Begin;
- DataRefImpl RelData = Begin->getRawDataRefImpl();
const Elf_Shdr *RelSec = getRelSection(RelData);
// Error check sh_link here so that getRelocationSymbol can just use it.
@@ -1050,7 +1106,7 @@ Expected<section_iterator>
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
const Elf_Shdr *EShdr = getSection(Sec);
uintX_t Type = EShdr->sh_type;
- if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
+ if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA && Type != ELF::SHT_CREL)
return section_end();
Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
@@ -1070,7 +1126,9 @@ symbol_iterator
ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
uint32_t symbolIdx;
const Elf_Shdr *sec = getRelSection(Rel);
- if (sec->sh_type == ELF::SHT_REL)
+ if (sec->sh_type == ELF::SHT_CREL)
+ symbolIdx = getCrel(Rel).r_symidx;
+ else if (sec->sh_type == ELF::SHT_REL)
symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
else
symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
@@ -1087,6 +1145,8 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_CREL)
+ return getCrel(Rel).r_offset;
if (sec->sh_type == ELF::SHT_REL)
return getRel(Rel)->r_offset;
@@ -1096,6 +1156,8 @@ uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_CREL)
+ return getCrel(Rel).r_type;
if (sec->sh_type == ELF::SHT_REL)
return getRel(Rel)->getType(EF.isMips64EL());
else
@@ -1117,9 +1179,11 @@ void ELFObjectFile<ELFT>::getRelocationTypeName(
template <class ELFT>
Expected<int64_t>
ELFObjectFile<ELFT>::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");
}
template <class ELFT>
@@ -1142,6 +1206,14 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
return *Ret;
}
+template <class ELFT>
+typename ELFObjectFile<ELFT>::Elf_Crel
+ELFObjectFile<ELFT>::getCrel(DataRefImpl Crel) const {
+ assert(getRelSection(Crel)->sh_type == ELF::SHT_CREL);
+ assert(Crel.d.a < Crels.size());
+ return Crels[Crel.d.a][Crel.d.b];
+}
+
template <class ELFT>
Expected<ELFObjectFile<ELFT>>
ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
@@ -1453,6 +1525,15 @@ template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
return EF.getHeader().e_type == ELF::ET_REL;
}
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getCrelError(DataRefImpl Sec) const {
+ uintptr_t SHT = reinterpret_cast<uintptr_t>(cantFail(EF.sections()).begin());
+ auto I = (Sec.p - SHT) / EF.getHeader().e_shentsize;
+ if (I < CrelErrs.size())
+ return CrelErrs[I];
+ return "";
+}
+
} // end namespace object
} // end namespace llvm
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index cbc55a145e0e6..3da7da759a145 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -1013,3 +1013,14 @@ Expected<std::vector<BBAddrMap>> ELFObjectFileBase::readBBAddrMap(
return readBBAddrMapImpl(cast<ELF64BEObjectFile>(this)->getELFFile(),
TextSectionIndex, PGOAnalyses);
}
+
+StringRef ELFObjectFileBase::getCrelError(SectionRef Sec) const {
+ auto Data = Sec.getRawDataRefImpl();
+ if (const auto *Obj = dyn_cast<ELF32LEObjectFile>(this))
+ return Obj->getCrelError(Data);
+ if (const auto *Obj = dyn_cast<ELF32BEObjectFile>(this))
+ return Obj->getCrelError(Data);
+ if (const auto *Obj = dyn_cast<ELF64LEObjectFile>(this))
+ return Obj->getCrelError(Data);
+ return cast<ELF64BEObjectFile>(this)->getCrelError(Data);
+}
diff --git a/llvm/test/tools/llvm-objdump/ELF/crel.test b/llvm/test/tools/llvm-objdump/ELF/crel.test
new file mode 100644
index 0000000000000..7eb435e232ae4
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/crel.test
@@ -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:0000000000000001 R_X86_64_32 g1+0x1
+# CHECK-NEXT:0000000000000002 R_X86_64_64 l1+0x2
+# CHECK-NEXT:0000000000000000 R_X86_64_32S g1-0x1
+# CHECK-NEXT:0000000000000004 R_X86_64_32S .text-0x8000000000000000
+#CHECK-EMPTY:
+# CHECK-NEXT:RELOCATION RECORDS FOR [nonalloc]:
+# CHECK-NEXT:OFFSET TYPE VALUE
+# CHECK-NEXT:0000000000000010 R_X86_64_64 g1+0x1
+# CHECK-NEXT:0000000000000020 R_X86_64_64 g2+0x2
+# CHECK-NEXT:0000000000000030 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: "0000000000000000"
+ 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: 0xffffffffffffffff
+ - Offset: 0x4
+ Symbol: .text
+ Type: R_X86_64_32S
+ Addend: 0x8000000000000000
+- 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:00000008 R_ARM_REL32 l1+0x1
+# ELF32-NEXT:00000004 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:000000000000001f R_X86_64_32 g1
+# IMPLICIT-NEXT:000000000000003f R_X86_64_64 g1
+# IMPLICIT-NEXT:0000000000000000 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: 187f030a82017787feffffffffffffff077f0a
+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 0x00000000: 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 -DFILE=%t.err2
+
+# ERR2:RELOCATION RECORDS FOR [.data]:
+# ERR2-NEXT:OFFSET TYPE VALUE
+# ERR2-NEXT:warning: '[[FILE]]': unexpected end of data at offset 0x1 while reading [0x1, 0x2)
+# ERR-NOT:{{.}}
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2MSB
+ Type: ET_REL
+ Machine: EM_ARM
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ - Name: .data
+ Type: SHT_PROGBITS
+ - Name: .crel.data
+ Type: SHT_CREL
+ Flags: []
+ Link: .symtab
+ Info: .data
+ Content: 08
+Symbols:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
diff --git a/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test
index cce0712e8fa0d..a6bd09ce3fa24 100644
--- a/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test
+++ b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-relocs.test
@@ -6,6 +6,10 @@
# RUN: llvm-objdump 1.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
# RUN: llvm-objdump 1.o -r --disassemble-symbols=x2,x4 | FileCheck %s --check-prefix=CHECK2
+# RUN: llvm-mc -filetype=obj -triple=x86_64 -crel 1.s -o 1leb.o
+# RUN: llvm-objdump 1leb.o -d -r | FileCheck %s --implicit-check-not="RELOCATION RECORDS"
+# RUN: llvm-objdump 1leb.o -r --disassemble-symbols=x2,x4 | FileCheck %s --check-prefix=CHECK2
+
#--- 1.s
# CHECK: 0000000000000000 <x1>:
# CHECK-NEXT: 0: e8 00 00 00 00 callq 0x5 <x1+0x5>
diff --git a/llvm/tools/llvm-objdump/ELFDump.cpp b/llvm/tools/llvm-objdump/ELFDump.cpp
index 8c184fc1fbb66..5ac13495662fa 100644
--- a/llvm/tools/llvm-objdump/ELFDump.cpp
+++ b/llvm/tools/llvm-objdump/ELFDump.cpp
@@ -104,7 +104,11 @@ static Error getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
// In SHT_REL case we would need to read the addend from section data.
// GNU objdump does not do that and we just follow for simplicity atm.
bool Undef = false;
- if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
+ if ((*SecOrErr)->sh_type == ELF::SHT_CREL) {
+ auto ERela = Obj->getCrel(Rel);
+ Addend = ERela.r_addend;
+ Undef = ERela.getSymbol(false) == 0;
+ } else if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
const typename ELFT::Rela *ERela = Obj->getRela(Rel);
Addend = ERela->r_addend;
Undef = ERela->getSymbol(false) == 0;
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 6249be4f332b7..792a27f8d3d3d 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -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<const ELFObjectFileBase>(&O);
+ StringRef Err = ELF->getCrelError(Section);
+ if (!Err.empty()) {
+ reportUniqueWarning(Err);
+ continue;
+ }
+ }
for (const RelocationRef &Reloc : Section.relocations()) {
uint64_t Address = Reloc.getOffset();
SmallString<32> RelocName;
|
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@@ -2687,6 +2687,15 @@ void Dumper::printRelocations() { | |||
<< "VALUE\n"; | |||
|
|||
for (SectionRef Section : P.second) { | |||
// CREL requires decoding and has its specific errors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend
// CREL sections require decoding, each section may have its own specific errors.
Created using spr 1.3.5-bogner [skip ci]
Created using spr 1.3.5-bogner
# ERR2:RELOCATION RECORDS FOR [.data]: | ||
# ERR2-NEXT:OFFSET TYPE VALUE | ||
# ERR2-NEXT:warning: '[[FILE]]': unexpected end of data at offset 0x1 while reading [0x1, 0x2) | ||
# ERR-NOT:{{.}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change this to # ERR2-NOT:{{.}}
in the next update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
llvm/include/llvm/Object/ELF.h
Outdated
@@ -207,6 +209,43 @@ bool isSectionInSegment(const typename ELFT::Phdr &Phdr, | |||
checkSectionVMA<ELFT>(Phdr, Sec); | |||
} | |||
|
|||
template <bool Is64> | |||
Error decodeCrel(ArrayRef<uint8_t> Content, | |||
function_ref<void(uint64_t, bool)> HdrHandler, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be worth
uint64_t /* relocation count */, bool /* explicit addends */
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thx for the suggestion. adopted
Created using spr 1.3.5-bogner [skip ci]
Created using spr 1.3.5-bogner
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"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this error quite makes sense anymore. Probably needs to say something about addends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error message adjusted. I think this line is dynamically unreachable.
Created using spr 1.3.5-bogner [skip ci]
Created using spr 1.3.5-bogner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too, thanks for the updates.
Extract the llvm-readelf decoder to
decodeCrel
(#91280) and reuse itfor llvm-objdump.
Because the section representation of LLVMObject (
SectionRef
) is64-bit, insufficient to hold all decoder states,
section_rel_begin
ismodified to decode CREL eagerly and hold the decoded relocations inside
ELFObjectFile.
The test is adapted from llvm/test/tools/llvm-readobj/ELF/crel.test.