[llvm-branch-commits] [llvm-objdump] -r: support CREL (PR #97382)

2024-07-08 Thread Peter Smith via llvm-branch-commits

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)

2024-07-08 Thread James Henderson via llvm-branch-commits

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)

2024-07-05 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-05 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-05 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-05 Thread James Henderson via llvm-branch-commits


@@ -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)

2024-07-03 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-03 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-03 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-03 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-03 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-03 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-03 Thread Peter Smith via llvm-branch-commits

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)

2024-07-03 Thread Peter Smith via llvm-branch-commits

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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits

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)

2024-07-02 Thread Fangrui Song via llvm-branch-commits


@@ -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)

2024-07-02 Thread Peter Smith via llvm-branch-commits

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)

2024-07-02 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-02 Thread Peter Smith via llvm-branch-commits

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)

2024-07-02 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-02 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-02 Thread Peter Smith via llvm-branch-commits


@@ -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)

2024-07-02 Thread James Henderson via llvm-branch-commits


@@ -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)

2024-07-01 Thread via llvm-branch-commits

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)

2024-07-01 Thread Fangrui Song via llvm-branch-commits

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