Skip to content

Commit 46d11e3

Browse files
author
Georgii Rymar
committed
[yaml2obj/obj2yaml] - Add support for SHT_RELR sections.
The encoded sequence of Elf*_Relr entries in a SHT_RELR section looks like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] i.e. start with an address, followed by any number of bitmaps. The address entry encodes 1 relocation. The subsequent bitmap entries encode up to 63(31) relocations each, at subsequent offsets following the last address entry. More information is here: https://github.com/llvm-mirror/llvm/blob/master/lib/Object/ELF.cpp#L272 This patch adds a support for these sections. Differential revision: https://reviews.llvm.org/D71872
1 parent cbe681b commit 46d11e3

File tree

6 files changed

+401
-7
lines changed

6 files changed

+401
-7
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct Chunk {
138138
Group,
139139
RawContent,
140140
Relocation,
141+
Relr,
141142
NoBits,
142143
Note,
143144
Hash,
@@ -440,6 +441,17 @@ struct RelocationSection : Section {
440441
}
441442
};
442443

444+
struct RelrSection : Section {
445+
Optional<std::vector<llvm::yaml::Hex64>> Entries;
446+
Optional<yaml::BinaryRef> Content;
447+
448+
RelrSection() : Section(ChunkKind::Relr) {}
449+
450+
static bool classof(const Chunk *S) {
451+
return S->Kind == ChunkKind::Relr;
452+
}
453+
};
454+
443455
struct SymtabShndxSection : Section {
444456
std::vector<uint32_t> Entries;
445457

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ template <class ELFT> class ELFState {
110110
typedef typename ELFT::Rela Elf_Rela;
111111
typedef typename ELFT::Relr Elf_Relr;
112112
typedef typename ELFT::Dyn Elf_Dyn;
113+
typedef typename ELFT::uint uintX_t;
113114

114115
enum class SymtabType { Static, Dynamic };
115116

@@ -165,6 +166,9 @@ template <class ELFT> class ELFState {
165166
void writeSectionContent(Elf_Shdr &SHeader,
166167
const ELFYAML::RelocationSection &Section,
167168
ContiguousBlobAccumulator &CBA);
169+
void writeSectionContent(Elf_Shdr &SHeader,
170+
const ELFYAML::RelrSection &Section,
171+
ContiguousBlobAccumulator &CBA);
168172
void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
169173
ContiguousBlobAccumulator &CBA);
170174
void writeSectionContent(Elf_Shdr &SHeader,
@@ -454,6 +458,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
454458
writeSectionContent(SHeader, *S, CBA);
455459
} else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
456460
writeSectionContent(SHeader, *S, CBA);
461+
} else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) {
462+
writeSectionContent(SHeader, *S, CBA);
457463
} else if (auto S = dyn_cast<ELFYAML::Group>(Sec)) {
458464
writeSectionContent(SHeader, *S, CBA);
459465
} else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) {
@@ -770,10 +776,6 @@ void ELFState<ELFT>::writeSectionContent(
770776

771777
if (Section.EntSize)
772778
SHeader.sh_entsize = *Section.EntSize;
773-
else if (Section.Type == llvm::ELF::SHT_RELR)
774-
SHeader.sh_entsize = sizeof(Elf_Relr);
775-
else
776-
SHeader.sh_entsize = 0;
777779

778780
if (Section.Info)
779781
SHeader.sh_info = *Section.Info;
@@ -827,6 +829,30 @@ void ELFState<ELFT>::writeSectionContent(
827829
}
828830
}
829831

832+
template <class ELFT>
833+
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
834+
const ELFYAML::RelrSection &Section,
835+
ContiguousBlobAccumulator &CBA) {
836+
raw_ostream &OS =
837+
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
838+
SHeader.sh_entsize =
839+
Section.EntSize ? uint64_t(*Section.EntSize) : sizeof(Elf_Relr);
840+
841+
if (Section.Content) {
842+
SHeader.sh_size = writeContent(OS, Section.Content, None);
843+
return;
844+
}
845+
846+
for (llvm::yaml::Hex64 E : *Section.Entries) {
847+
if (!ELFT::Is64Bits && E > UINT32_MAX)
848+
reportError(Section.Name + ": the value is too large for 32-bits: 0x" +
849+
Twine::utohexstr(E));
850+
support::endian::write<uintX_t>(OS, E, ELFT::TargetEndianness);
851+
}
852+
853+
SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();
854+
}
855+
830856
template <class ELFT>
831857
void ELFState<ELFT>::writeSectionContent(
832858
Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
@@ -889,7 +915,6 @@ template <class ELFT>
889915
void ELFState<ELFT>::writeSectionContent(
890916
Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,
891917
ContiguousBlobAccumulator &CBA) {
892-
using uintX_t = typename ELFT::uint;
893918
raw_ostream &OS =
894919
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
895920

@@ -1115,8 +1140,6 @@ template <class ELFT>
11151140
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
11161141
const ELFYAML::DynamicSection &Section,
11171142
ContiguousBlobAccumulator &CBA) {
1118-
typedef typename ELFT::uint uintX_t;
1119-
11201143
assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
11211144
"Section type is not SHT_DYNAMIC");
11221145

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,12 @@ static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
11011101
IO.mapOptional("Relocations", Section.Relocations);
11021102
}
11031103

1104+
static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) {
1105+
commonSectionMapping(IO, Section);
1106+
IO.mapOptional("Entries", Section.Entries);
1107+
IO.mapOptional("Content", Section.Content);
1108+
}
1109+
11041110
static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
11051111
commonSectionMapping(IO, Group);
11061112
IO.mapOptional("Info", Group.Signature);
@@ -1200,6 +1206,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
12001206
Section.reset(new ELFYAML::RelocationSection());
12011207
sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
12021208
break;
1209+
case ELF::SHT_RELR:
1210+
if (!IO.outputting())
1211+
Section.reset(new ELFYAML::RelrSection());
1212+
sectionMapping(IO, *cast<ELFYAML::RelrSection>(Section.get()));
1213+
break;
12031214
case ELF::SHT_GROUP:
12041215
if (!IO.outputting())
12051216
Section.reset(new ELFYAML::Group());
@@ -1441,6 +1452,12 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
14411452
return {};
14421453
}
14431454

1455+
if (const auto *RS = dyn_cast<ELFYAML::RelrSection>(C.get())) {
1456+
if (RS->Entries && RS->Content)
1457+
return "\"Entries\" and \"Content\" can't be used together";
1458+
return {};
1459+
}
1460+
14441461
return {};
14451462
}
14461463

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
## Test how we dump SHT_RELR sections for 32 and 64-bit targets.
2+
3+
## Test we use the "Entries" property when it is possible do
4+
## dump values correctly.
5+
6+
# RUN: yaml2obj --docnum=1 %s -o %t.64le
7+
# RUN: obj2yaml %t.64le | FileCheck %s --check-prefix=ELF64LE
8+
# RUN: yaml2obj --docnum=2 %s -o %t.32le
9+
# RUN: obj2yaml %t.32le | FileCheck %s --check-prefix=ELF32LE
10+
# RUN: yaml2obj --docnum=3 %s -o %t.64be
11+
# RUN: obj2yaml %t.64be | FileCheck %s --check-prefix=ELF64BE
12+
# RUN: yaml2obj --docnum=4 %s -o %t.32be
13+
# RUN: obj2yaml %t.32be | FileCheck %s --check-prefix=ELF32BE
14+
15+
# ELF64LE: Sections:
16+
# ELF64LE-NEXT: - Name: .relr.dyn
17+
# ELF64LE-NEXT: Type: SHT_RELR
18+
# ELF64LE-NEXT: EntSize: 0x0000000000000008
19+
# ELF64LE-NEXT: Entries: [ 0x8877665544332211 ]
20+
21+
# ELF32LE: Sections:
22+
# ELF32LE-NEXT: - Name: .relr.dyn
23+
# ELF32LE-NEXT: Type: SHT_RELR
24+
# ELF32LE-NEXT: EntSize: 0x0000000000000004
25+
# ELF32LE-NEXT: Entries: [ 0x0000000044332211, 0x0000000088776655 ]
26+
27+
# ELF64BE: Sections:
28+
# ELF64BE-NEXT: - Name: .relr.dyn
29+
# ELF64BE-NEXT: Type: SHT_RELR
30+
# ELF64BE-NEXT: EntSize: 0x0000000000000008
31+
# ELF64BE-NEXT: Entries: [ 0x1122334455667788 ]
32+
33+
# ELF32BE: Sections:
34+
# ELF32BE-NEXT: - Name: .relr.dyn
35+
# ELF32BE-NEXT: Type: SHT_RELR
36+
# ELF32BE-NEXT: EntSize: 0x0000000000000004
37+
# ELF32BE-NEXT: Entries: [ 0x0000000011223344, 0x0000000055667788 ]
38+
39+
--- !ELF
40+
FileHeader:
41+
Class: ELFCLASS64
42+
Data: ELFDATA2LSB
43+
Type: ET_DYN
44+
Machine: EM_X86_64
45+
Sections:
46+
- Name: .relr.dyn
47+
Type: SHT_RELR
48+
Content: "1122334455667788"
49+
50+
--- !ELF
51+
FileHeader:
52+
Class: ELFCLASS32
53+
Data: ELFDATA2LSB
54+
Type: ET_DYN
55+
Machine: EM_386
56+
Sections:
57+
- Name: .relr.dyn
58+
Type: SHT_RELR
59+
Content: "1122334455667788"
60+
61+
--- !ELF
62+
FileHeader:
63+
Class: ELFCLASS64
64+
Data: ELFDATA2MSB
65+
Type: ET_DYN
66+
Machine: EM_X86_64
67+
Sections:
68+
- Name: .relr.dyn
69+
Type: SHT_RELR
70+
Content: "1122334455667788"
71+
72+
--- !ELF
73+
FileHeader:
74+
Class: ELFCLASS32
75+
Data: ELFDATA2MSB
76+
Type: ET_DYN
77+
Machine: EM_386
78+
Sections:
79+
- Name: .relr.dyn
80+
Type: SHT_RELR
81+
Content: "1122334455667788"
82+
83+
## Test we use the "Content" property when a SHT_RELR section is truncated.
84+
85+
# RUN: yaml2obj --docnum=5 %s -o %t.content
86+
# RUN: obj2yaml %t.content | FileCheck %s --check-prefix=CONTENT
87+
88+
# CONTENT: - Name: .relr.dyn
89+
# CONTENT-NEXT: Type: SHT_RELR
90+
# CONTENT-NEXT: EntSize: 0x0000000000000008
91+
# CONTENT-NEXT: Content: '11223344556677'
92+
93+
--- !ELF
94+
FileHeader:
95+
Class: ELFCLASS64
96+
Data: ELFDATA2MSB
97+
Type: ET_DYN
98+
Machine: EM_X86_64
99+
Sections:
100+
- Name: .relr.dyn
101+
Type: SHT_RELR
102+
Content: "11223344556677"

0 commit comments

Comments
 (0)