Skip to content

[obj2yaml] Support CREL #98116

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

Merged
merged 3 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions llvm/test/tools/obj2yaml/ELF/crel-section.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
## Test how we dump SHT_CREL sections.
# RUN: yaml2obj %s -o %t1
# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=YAML

# YAML: - Name: .crel.text
# YAML-NEXT: Type: SHT_CREL
# YAML-NEXT: Link: .symtab
# YAML-NEXT: Info: .text
# YAML-NEXT: Relocations:
# YAML-NEXT: - Offset: 0x1
# YAML-NEXT: Symbol: g1
# YAML-NEXT: Type: R_X86_64_32
# YAML-NEXT: Addend: 1
# YAML-NEXT: - Offset: 0x2
# YAML-NEXT: Symbol: l1
# YAML-NEXT: Type: R_X86_64_64
# YAML-NEXT: Addend: 2
# YAML-NEXT: - Symbol: g1
# YAML-NEXT: Type: R_X86_64_32S
# YAML-NEXT: Addend: -1
# YAML-NEXT: - Offset: 0x4
# YAML-NEXT: Symbol: .text
# YAML-NEXT: Type: R_X86_64_32S
# YAML-NEXT: Addend: -9223372036854775808
# YAML-NEXT: - Name: .crel.dyn
# YAML-NEXT: Type: SHT_CREL
# YAML-NEXT: Relocations: []

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64

Sections:
- Name: .foo
Type: SHT_PROGBITS
Flags: [SHF_ALLOC]
- 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: .crel.dyn
Type: SHT_CREL
Content: 00
## Trigger the .dynsym emission.
DynamicSymbols: []
Symbols:
- Name: unused
Section: .text
Comment on lines +71 to +72
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumb question maybe, but what's the point of this particular symbol?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unused symbol makes symbols referenced by relocations start at higher indexes.
This property is somewhat useful to test llvm-objcopy. It's probably not so useful after decodeCrel has been tested, but I think it does not hurt here...

- Name: .text
Type: STT_SECTION
Section: .text
- Name: l1
- Name: g1
Section: .text
Value: 0x0
Size: 4
Binding: STB_GLOBAL

## Test the behavior when the sh_entsize field is broken.

# RUN: yaml2obj -DTYPE=SHT_RELA --docnum=2 %s -o %t2
# RUN: not obj2yaml %t2 2>&1 | FileCheck %s --check-prefix=ERR1

# ERR1: unable to decode LEB128 at offset 0x00000000: malformed uleb128, extends past end

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Sections:
- Name: .foo
Type: SHT_CREL
55 changes: 35 additions & 20 deletions llvm/tools/obj2yaml/elf2yaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ ELFDumper<ELFT>::dumpSections() {
return [this](const Elf_Shdr *S) { return dumpSymtabShndxSection(S); };
case ELF::SHT_REL:
case ELF::SHT_RELA:
case ELF::SHT_CREL:
return [this](const Elf_Shdr *S) { return dumpRelocSection(S); };
case ELF::SHT_RELR:
return [this](const Elf_Shdr *S) { return dumpRelrSection(S); };
Expand Down Expand Up @@ -1165,27 +1166,41 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
if (Shdr->sh_size != 0)
S->Relocations.emplace();

if (Shdr->sh_type == ELF::SHT_REL) {
auto Rels = Obj.rels(*Shdr);
if (!Rels)
return Rels.takeError();
for (const Elf_Rel &Rel : *Rels) {
ELFYAML::Relocation R;
if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
S->Relocations->push_back(R);
}
std::vector<Elf_Rel> Rels;
std::vector<Elf_Rela> Relas;
if (Shdr->sh_type == ELF::SHT_CREL) {
Expected<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(*Shdr);
if (!ContentOrErr)
return ContentOrErr.takeError();
auto Crel = Obj.decodeCrel(*ContentOrErr);
if (!Crel)
return Crel.takeError();
Rels = std::move(Crel->first);
Relas = std::move(Crel->second);
} else if (Shdr->sh_type == ELF::SHT_REL) {
auto R = Obj.rels(*Shdr);
if (!R)
return R.takeError();
Rels = std::move(*R);
} else {
auto Rels = Obj.relas(*Shdr);
if (!Rels)
return Rels.takeError();
for (const Elf_Rela &Rel : *Rels) {
ELFYAML::Relocation R;
if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
R.Addend = Rel.r_addend;
S->Relocations->push_back(R);
}
auto R = Obj.relas(*Shdr);
if (!R)
return R.takeError();
Relas = std::move(*R);
}

for (const Elf_Rel &Rel : Rels) {
ELFYAML::Relocation R;
if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
S->Relocations->push_back(R);
}
for (const Elf_Rela &Rel : Relas) {
ELFYAML::Relocation R;
if (Error E = dumpRelocation(&Rel, *SymTabOrErr, R))
return std::move(E);
R.Addend = Rel.r_addend;
S->Relocations->push_back(R);
}

return S.release();
Expand Down