llvm.org GIT mirror llvm / eefdbb4
[llvm-readobj] Add experimental support for SHT_RELR sections This change adds experimental support for SHT_RELR sections, proposed here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg Definitions for the new ELF section type and dynamic array tags, as well as the encoding used in the new section are all under discussion and are subject to change. Use with caution! Author: rahulchaudhry Differential Revision: https://reviews.llvm.org/D47919 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335922 91177308-0d34-0410-b5e6-96231b3b80d8 Jake Ehrlich 1 year, 2 months ago
13 changed file(s) with 471 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
6464
6565 DYNAMIC_TAG(SYMTAB_SHNDX, 34) // Address of the SHT_SYMTAB_SHNDX section.
6666
67 // Experimental support for SHT_RELR sections. For details, see proposal
68 // at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
69 DYNAMIC_TAG(RELRSZ, 35) // Size of Relr relocation table.
70 DYNAMIC_TAG(RELR, 36) // Address of relocation table (Relr entries).
71 DYNAMIC_TAG(RELRENT, 37) // Size of a Relr relocation entry.
72
6773 DYNAMIC_TAG_MARKER(LOOS, 0x60000000) // Start of environment specific tags.
6874 DYNAMIC_TAG_MARKER(HIOS, 0x6FFFFFFF) // End of environment specific tags.
6975 DYNAMIC_TAG_MARKER(LOPROC, 0x70000000) // Start of processor specific tags.
7581 DYNAMIC_TAG(ANDROID_RELSZ, 0x60000010)
7682 DYNAMIC_TAG(ANDROID_RELA, 0x60000011)
7783 DYNAMIC_TAG(ANDROID_RELASZ, 0x60000012)
84
85 // Android's experimental support for SHT_RELR sections.
86 // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#253
87 DYNAMIC_TAG(ANDROID_RELR, 0x6FFFE000) // Address of relocation table (Relr entries).
88 DYNAMIC_TAG(ANDROID_RELRSZ, 0x6FFFE001) // Size of Relr relocation table.
89 DYNAMIC_TAG(ANDROID_RELRENT, 0x6FFFE003) // Size of a Relr relocation entry.
7890
7991 DYNAMIC_TAG(GNU_HASH, 0x6FFFFEF5) // Reference to the GNU hash table.
8092 DYNAMIC_TAG(TLSDESC_PLT, 0x6FFFFEF6) // Location of PLT entry for TLS
795795 SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
796796 SHT_GROUP = 17, // Section group.
797797 SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
798 // Experimental support for SHT_RELR sections. For details, see proposal
799 // at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
800 SHT_RELR = 19, // Relocation entries; only offsets.
798801 SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
799802 // Android packed relocation section types.
800803 // https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37
803806 SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
804807 SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
805808 SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
809 // Android's experimental support for SHT_RELR sections.
810 // https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
811 SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
806812 SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
807813 SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
808814 SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
10661072 }
10671073 };
10681074
1075 // Relocation entry without explicit addend or info (relative relocations only).
1076 typedef Elf32_Word Elf32_Relr; // offset/bitmap for relative relocations
1077
10691078 // Relocation entry, without explicit addend.
10701079 struct Elf64_Rel {
10711080 Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
10981107 r_info = ((Elf64_Xword)s << 32) + (t & 0xffffffffL);
10991108 }
11001109 };
1110
1111 // Relocation entry without explicit addend or info (relative relocations only).
1112 typedef Elf64_Xword Elf64_Relr; // offset/bitmap for relative relocations
11011113
11021114 // Program header for ELF32.
11031115 struct Elf32_Phdr {
3131 namespace object {
3232
3333 StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
34 uint32_t getELFRelrRelocationType(uint32_t Machine);
3435 StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
3536
3637 // Subclasses of ELFFile may need this for template instantiation
5960 using Elf_Phdr = typename ELFT::Phdr;
6061 using Elf_Rel = typename ELFT::Rel;
6162 using Elf_Rela = typename ELFT::Rela;
63 using Elf_Relr = typename ELFT::Relr;
6264 using Elf_Verdef = typename ELFT::Verdef;
6365 using Elf_Verdaux = typename ELFT::Verdaux;
6466 using Elf_Verneed = typename ELFT::Verneed;
7476 using Elf_Sym_Range = typename ELFT::SymRange;
7577 using Elf_Rel_Range = typename ELFT::RelRange;
7678 using Elf_Rela_Range = typename ELFT::RelaRange;
79 using Elf_Relr_Range = typename ELFT::RelrRange;
7780 using Elf_Phdr_Range = typename ELFT::PhdrRange;
7881
7982 const uint8_t *base() const {
109112 StringRef getRelocationTypeName(uint32_t Type) const;
110113 void getRelocationTypeName(uint32_t Type,
111114 SmallVectorImpl &Result) const;
115 uint32_t getRelrRelocationType() const;
112116
113117 /// Get the symbol for a given relocation.
114118 Expected getRelocationSymbol(const Elf_Rel *Rel,
141145 Expected rels(const Elf_Shdr *Sec) const {
142146 return getSectionContentsAsArray(Sec);
143147 }
148
149 Expected relrs(const Elf_Shdr *Sec) const {
150 return getSectionContentsAsArray(Sec);
151 }
152
153 Expected> decode_relrs(Elf_Relr_Range relrs) const;
144154
145155 Expected> android_relas(const Elf_Shdr *Sec) const;
146156
394404 Result.append(1, '/');
395405 Result.append(Name.begin(), Name.end());
396406 }
407 }
408
409 template
410 uint32_t ELFFile::getRelrRelocationType() const {
411 return getELFRelrRelocationType(getHeader()->e_machine);
397412 }
398413
399414 template
6161 using Phdr = Elf_Phdr_Impl>;
6262 using Rel = Elf_Rel_Impl, false>;
6363 using Rela = Elf_Rel_Impl, true>;
64 using Relr = packed;
6465 using Verdef = Elf_Verdef_Impl>;
6566 using Verdaux = Elf_Verdaux_Impl>;
6667 using Verneed = Elf_Verneed_Impl>;
7879 using SymRange = ArrayRef;
7980 using RelRange = ArrayRef;
8081 using RelaRange = ArrayRef;
82 using RelrRange = ArrayRef;
8183 using PhdrRange = ArrayRef;
8284
8385 using Half = packed;
152152 }
153153
154154 #undef ELF_RELOC
155
156 uint32_t llvm::object::getELFRelrRelocationType(uint32_t Machine) {
157 switch (Machine) {
158 case ELF::EM_X86_64:
159 return ELF::R_X86_64_RELATIVE;
160 case ELF::EM_386:
161 case ELF::EM_IAMCU:
162 return ELF::R_386_RELATIVE;
163 case ELF::EM_MIPS:
164 break;
165 case ELF::EM_AARCH64:
166 return ELF::R_AARCH64_RELATIVE;
167 case ELF::EM_ARM:
168 return ELF::R_ARM_RELATIVE;
169 case ELF::EM_ARC_COMPACT:
170 case ELF::EM_ARC_COMPACT2:
171 return ELF::R_ARC_RELATIVE;
172 case ELF::EM_AVR:
173 break;
174 case ELF::EM_HEXAGON:
175 return ELF::R_HEX_RELATIVE;
176 case ELF::EM_LANAI:
177 break;
178 case ELF::EM_PPC:
179 break;
180 case ELF::EM_PPC64:
181 return ELF::R_PPC64_RELATIVE;
182 case ELF::EM_RISCV:
183 return ELF::R_RISCV_RELATIVE;
184 case ELF::EM_S390:
185 return ELF::R_390_RELATIVE;
186 case ELF::EM_SPARC:
187 case ELF::EM_SPARC32PLUS:
188 case ELF::EM_SPARCV9:
189 return ELF::R_SPARC_RELATIVE;
190 case ELF::EM_WEBASSEMBLY:
191 break;
192 case ELF::EM_AMDGPU:
193 break;
194 case ELF::EM_BPF:
195 break;
196 default:
197 break;
198 }
199 return 0;
200 }
155201
156202 StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
157203 switch (Machine) {
201247 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
202248 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
203249 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
250 STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
204251 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
205252 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
253 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
206254 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
207255 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
208256 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
214262 default:
215263 return "Unknown";
216264 }
265 }
266
267 template
268 Expected>
269 ELFFile::decode_relrs(Elf_Relr_Range relrs) const {
270 // This function decodes the contents of an SHT_RELR packed relocation
271 // section.
272 //
273 // Proposal for adding SHT_RELR sections to generic-abi is here:
274 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
275 //
276 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
277 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
278 //
279 // i.e. start with an address, followed by any number of bitmaps. The address
280 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
281 // relocations each, at subsequent offsets following the last address entry.
282 //
283 // The bitmap entries must have 1 in the least significant bit. The assumption
284 // here is that an address cannot have 1 in lsb. Odd addresses are not
285 // supported.
286 //
287 // Excluding the least significant bit in the bitmap, each non-zero bit in
288 // the bitmap represents a relocation to be applied to a corresponding machine
289 // word that follows the base address word. The second least significant bit
290 // represents the machine word immediately following the initial address, and
291 // each bit that follows represents the next word, in linear order. As such,
292 // a single bitmap can encode up to 31 relocations in a 32-bit object, and
293 // 63 relocations in a 64-bit object.
294 //
295 // This encoding has a couple of interesting properties:
296 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
297 // even means address, odd means bitmap.
298 // 2. Just a simple list of addresses is a valid encoding.
299
300 Elf_Rela Rela;
301 Rela.r_info = 0;
302 Rela.r_addend = 0;
303 Rela.setType(getRelrRelocationType(), false);
304 std::vector Relocs;
305
306 // Word type: uint32_t for Elf32, and uint64_t for Elf64.
307 typedef typename ELFT::uint Word;
308
309 // Word size in number of bytes.
310 const size_t WordSize = sizeof(Word);
311
312 // Number of bits used for the relocation offsets bitmap.
313 // These many relative relocations can be encoded in a single entry.
314 const size_t NBits = 8*WordSize - 1;
315
316 Word Base = 0;
317 for (const Elf_Relr &R : relrs) {
318 Word Entry = R;
319 if ((Entry&1) == 0) {
320 // Even entry: encodes the offset for next relocation.
321 Rela.r_offset = Entry;
322 Relocs.push_back(Rela);
323 // Set base offset for subsequent bitmap entries.
324 Base = Entry + WordSize;
325 continue;
326 }
327
328 // Odd entry: encodes bitmap for relocations starting at base.
329 Word Offset = Base;
330 while (Entry != 0) {
331 Entry >>= 1;
332 if ((Entry&1) != 0) {
333 Rela.r_offset = Offset;
334 Relocs.push_back(Rela);
335 }
336 Offset += WordSize;
337 }
338
339 // Advance base offset by NBits words.
340 Base += NBits * WordSize;
341 }
342
343 return Relocs;
217344 }
218345
219346 template
435435 ECase(SHT_PREINIT_ARRAY);
436436 ECase(SHT_GROUP);
437437 ECase(SHT_SYMTAB_SHNDX);
438 ECase(SHT_RELR);
438439 ECase(SHT_LOOS);
439440 ECase(SHT_ANDROID_REL);
440441 ECase(SHT_ANDROID_RELA);
442 ECase(SHT_ANDROID_RELR);
441443 ECase(SHT_LLVM_ODRTAB);
442444 ECase(SHT_LLVM_LINKER_OPTIONS);
443445 ECase(SHT_LLVM_CALL_GRAPH_PROFILE);
0 .quad 0x0000000000010d60 // Initial offset
1 .quad 0x0000000000000103 // Continuation bitmap
2 .quad 0x0000000000020000 // New offset
3 .quad 0x00000000000f0501 // Continuation bitmap
4 .quad 0x000a700550400009 // Continuation bitmap
0 .long 0x00010d60 // Initial offset
1 .long 0x00000103 // Continuation bitmap
2 .long 0x00020000 // New offset
3 .long 0x000f0501 // Continuation bitmap
4 .long 0x50400009 // Continuation bitmap
0 # The binary blobs in this file were created like this:
1 # llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu Inputs/elf-relr-relocs1.s -o - | obj2yaml | grep Content:
2
3 # RUN: yaml2obj -docnum 1 %s \
4 # RUN: | llvm-readobj -elf-output-style=LLVM -relocations -raw-relr - \
5 # RUN: | FileCheck --check-prefix=RAW-LLVM1 %s
6 # RAW-LLVM1: Section (1) .relr.dyn {
7 # RAW-LLVM1-NEXT: 0x10D60
8 # RAW-LLVM1-NEXT: 0x103
9 # RAW-LLVM1-NEXT: 0x20000
10 # RAW-LLVM1-NEXT: 0xF0501
11 # RAW-LLVM1-NEXT: 0xA700550400009
12 # RAW-LLVM1-NEXT: }
13
14 # RUN: yaml2obj -docnum 1 %s \
15 # RUN: | llvm-readobj -elf-output-style=LLVM -relocations - \
16 # RUN: | FileCheck --check-prefix=LLVM1 %s
17 # LLVM1: Section (1) .relr.dyn {
18 # LLVM1-NEXT: 0x10D60 R_X86_64_RELATIVE - 0x0
19 # LLVM1-NEXT: 0x10D68 R_X86_64_RELATIVE - 0x0
20 # LLVM1-NEXT: 0x10DA0 R_X86_64_RELATIVE - 0x0
21 # LLVM1-NEXT: 0x20000 R_X86_64_RELATIVE - 0x0
22 # LLVM1-NEXT: 0x20040 R_X86_64_RELATIVE - 0x0
23 # LLVM1-NEXT: 0x20050 R_X86_64_RELATIVE - 0x0
24 # LLVM1-NEXT: 0x20080 R_X86_64_RELATIVE - 0x0
25 # LLVM1-NEXT: 0x20088 R_X86_64_RELATIVE - 0x0
26 # LLVM1-NEXT: 0x20090 R_X86_64_RELATIVE - 0x0
27 # LLVM1-NEXT: 0x20098 R_X86_64_RELATIVE - 0x0
28 # LLVM1-NEXT: 0x20210 R_X86_64_RELATIVE - 0x0
29 # LLVM1-NEXT: 0x202A8 R_X86_64_RELATIVE - 0x0
30 # LLVM1-NEXT: 0x202D8 R_X86_64_RELATIVE - 0x0
31 # LLVM1-NEXT: 0x202E8 R_X86_64_RELATIVE - 0x0
32 # LLVM1-NEXT: 0x202F8 R_X86_64_RELATIVE - 0x0
33 # LLVM1-NEXT: 0x20308 R_X86_64_RELATIVE - 0x0
34 # LLVM1-NEXT: 0x20358 R_X86_64_RELATIVE - 0x0
35 # LLVM1-NEXT: 0x20360 R_X86_64_RELATIVE - 0x0
36 # LLVM1-NEXT: 0x20368 R_X86_64_RELATIVE - 0x0
37 # LLVM1-NEXT: 0x20380 R_X86_64_RELATIVE - 0x0
38 # LLVM1-NEXT: 0x20390 R_X86_64_RELATIVE - 0x0
39 # LLVM1-NEXT: }
40
41 # RUN: yaml2obj -docnum 1 %s \
42 # RUN: | llvm-readobj -elf-output-style=GNU -relocations -raw-relr - \
43 # RUN: | FileCheck --check-prefix=RAW-GNU1 %s
44 # RAW-GNU1: Relocation section '.relr.dyn' at offset 0x180 contains 5 entries:
45 # RAW-GNU1: 0000000000010d60
46 # RAW-GNU1-NEXT: 0000000000000103
47 # RAW-GNU1-NEXT: 0000000000020000
48 # RAW-GNU1-NEXT: 00000000000f0501
49 # RAW-GNU1-NEXT: 000a700550400009
50
51 # RUN: yaml2obj -docnum 1 %s \
52 # RUN: | llvm-readobj -elf-output-style=GNU -relocations - \
53 # RUN: | FileCheck --check-prefix=GNU1 %s
54 # GNU1: Relocation section '.relr.dyn' at offset 0x180 contains 21 entries:
55 # GNU1: 0000000000010d60 0000000000000008 R_X86_64_RELATIVE
56 # GNU1-NEXT: 0000000000010d68 0000000000000008 R_X86_64_RELATIVE
57 # GNU1-NEXT: 0000000000010da0 0000000000000008 R_X86_64_RELATIVE
58 # GNU1-NEXT: 0000000000020000 0000000000000008 R_X86_64_RELATIVE
59 # GNU1-NEXT: 0000000000020040 0000000000000008 R_X86_64_RELATIVE
60 # GNU1-NEXT: 0000000000020050 0000000000000008 R_X86_64_RELATIVE
61 # GNU1-NEXT: 0000000000020080 0000000000000008 R_X86_64_RELATIVE
62 # GNU1-NEXT: 0000000000020088 0000000000000008 R_X86_64_RELATIVE
63 # GNU1-NEXT: 0000000000020090 0000000000000008 R_X86_64_RELATIVE
64 # GNU1-NEXT: 0000000000020098 0000000000000008 R_X86_64_RELATIVE
65 # GNU1-NEXT: 0000000000020210 0000000000000008 R_X86_64_RELATIVE
66 # GNU1-NEXT: 00000000000202a8 0000000000000008 R_X86_64_RELATIVE
67 # GNU1-NEXT: 00000000000202d8 0000000000000008 R_X86_64_RELATIVE
68 # GNU1-NEXT: 00000000000202e8 0000000000000008 R_X86_64_RELATIVE
69 # GNU1-NEXT: 00000000000202f8 0000000000000008 R_X86_64_RELATIVE
70 # GNU1-NEXT: 0000000000020308 0000000000000008 R_X86_64_RELATIVE
71 # GNU1-NEXT: 0000000000020358 0000000000000008 R_X86_64_RELATIVE
72 # GNU1-NEXT: 0000000000020360 0000000000000008 R_X86_64_RELATIVE
73 # GNU1-NEXT: 0000000000020368 0000000000000008 R_X86_64_RELATIVE
74 # GNU1-NEXT: 0000000000020380 0000000000000008 R_X86_64_RELATIVE
75 # GNU1-NEXT: 0000000000020390 0000000000000008 R_X86_64_RELATIVE
76
77 # elf-relr-relocs1.s
78 --- !ELF
79 FileHeader:
80 Class: ELFCLASS64
81 Data: ELFDATA2LSB
82 Type: ET_DYN
83 Machine: EM_X86_64
84 Entry: 0x0000000000001000
85 Sections:
86 - Name: .relr.dyn
87 Type: SHT_RELR
88 Flags: [ SHF_ALLOC ]
89 Address: 0x00000000000001C8
90 Link: .symtab
91 AddressAlign: 0x0000000000000001
92 Content: 600D0100000000000301000000000000000002000000000001050F00000000000900405005700A00
93 ...
94
95 # RUN: yaml2obj -docnum 2 %s \
96 # RUN: | llvm-readobj -elf-output-style=LLVM -relocations -raw-relr - \
97 # RUN: | FileCheck --check-prefix=RAW-LLVM2 %s
98 # RAW-LLVM2: Section (1) .relr.dyn {
99 # RAW-LLVM2-NEXT: 0x10D60
100 # RAW-LLVM2-NEXT: 0x103
101 # RAW-LLVM2-NEXT: 0x20000
102 # RAW-LLVM2-NEXT: 0xF0501
103 # RAW-LLVM2-NEXT: 0x50400009
104 # RAW-LLVM2-NEXT: }
105
106 # RUN: yaml2obj -docnum 2 %s \
107 # RUN: | llvm-readobj -elf-output-style=LLVM -relocations - \
108 # RUN: | FileCheck --check-prefix=LLVM2 %s
109 # LLVM2: Section (1) .relr.dyn {
110 # LLVM2-NEXT: 0x10D60 R_386_RELATIVE - 0x0
111 # LLVM2-NEXT: 0x10D64 R_386_RELATIVE - 0x0
112 # LLVM2-NEXT: 0x10D80 R_386_RELATIVE - 0x0
113 # LLVM2-NEXT: 0x20000 R_386_RELATIVE - 0x0
114 # LLVM2-NEXT: 0x20020 R_386_RELATIVE - 0x0
115 # LLVM2-NEXT: 0x20028 R_386_RELATIVE - 0x0
116 # LLVM2-NEXT: 0x20040 R_386_RELATIVE - 0x0
117 # LLVM2-NEXT: 0x20044 R_386_RELATIVE - 0x0
118 # LLVM2-NEXT: 0x20048 R_386_RELATIVE - 0x0
119 # LLVM2-NEXT: 0x2004C R_386_RELATIVE - 0x0
120 # LLVM2-NEXT: 0x20088 R_386_RELATIVE - 0x0
121 # LLVM2-NEXT: 0x200D4 R_386_RELATIVE - 0x0
122 # LLVM2-NEXT: 0x200EC R_386_RELATIVE - 0x0
123 # LLVM2-NEXT: 0x200F4 R_386_RELATIVE - 0x0
124 # LLVM2-NEXT: }
125
126 # RUN: yaml2obj -docnum 2 %s \
127 # RUN: | llvm-readobj -elf-output-style=GNU -relocations -raw-relr - \
128 # RUN: | FileCheck --check-prefix=RAW-GNU2 %s
129 # RAW-GNU2: Relocation section '.relr.dyn' at offset 0xfc contains 5 entries:
130 # RAW-GNU2: 00010d60
131 # RAW-GNU2-NEXT: 00000103
132 # RAW-GNU2-NEXT: 00020000
133 # RAW-GNU2-NEXT: 000f0501
134 # RAW-GNU2-NEXT: 50400009
135
136 # RUN: yaml2obj -docnum 2 %s \
137 # RUN: | llvm-readobj -elf-output-style=GNU -relocations - \
138 # RUN: | FileCheck --check-prefix=GNU2 %s
139 # GNU2: Relocation section '.relr.dyn' at offset 0xfc contains 14 entries:
140 # GNU2: 00010d60 00000008 R_386_RELATIVE
141 # GNU2-NEXT: 00010d64 00000008 R_386_RELATIVE
142 # GNU2-NEXT: 00010d80 00000008 R_386_RELATIVE
143 # GNU2-NEXT: 00020000 00000008 R_386_RELATIVE
144 # GNU2-NEXT: 00020020 00000008 R_386_RELATIVE
145 # GNU2-NEXT: 00020028 00000008 R_386_RELATIVE
146 # GNU2-NEXT: 00020040 00000008 R_386_RELATIVE
147 # GNU2-NEXT: 00020044 00000008 R_386_RELATIVE
148 # GNU2-NEXT: 00020048 00000008 R_386_RELATIVE
149 # GNU2-NEXT: 0002004c 00000008 R_386_RELATIVE
150 # GNU2-NEXT: 00020088 00000008 R_386_RELATIVE
151 # GNU2-NEXT: 000200d4 00000008 R_386_RELATIVE
152 # GNU2-NEXT: 000200ec 00000008 R_386_RELATIVE
153 # GNU2-NEXT: 000200f4 00000008 R_386_RELATIVE
154
155 # elf-relr-relocs2.s
156 --- !ELF
157 FileHeader:
158 Class: ELFCLASS32
159 Data: ELFDATA2LSB
160 Type: ET_DYN
161 Machine: EM_386
162 Entry: 0x00001000
163 Sections:
164 - Name: .relr.dyn
165 Type: SHT_RELR
166 Flags: [ SHF_ALLOC ]
167 Address: 0x000001C8
168 Link: .symtab
169 AddressAlign: 0x00000001
170 Content: 600D0100030100000000020001050F0009004050
171 ...
8484 using Elf_Dyn_Range = typename ELFT::DynRange; \
8585 using Elf_Rel = typename ELFT::Rel; \
8686 using Elf_Rela = typename ELFT::Rela; \
87 using Elf_Relr = typename ELFT::Relr; \
8788 using Elf_Rel_Range = typename ELFT::RelRange; \
8889 using Elf_Rela_Range = typename ELFT::RelaRange; \
90 using Elf_Relr_Range = typename ELFT::RelrRange; \
8991 using Elf_Phdr = typename ELFT::Phdr; \
9092 using Elf_Half = typename ELFT::Half; \
9193 using Elf_Ehdr = typename ELFT::Ehdr; \
205207 const ELFO *Obj;
206208 DynRegionInfo DynRelRegion;
207209 DynRegionInfo DynRelaRegion;
210 DynRegionInfo DynRelrRegion;
208211 DynRegionInfo DynPLTRelRegion;
209212 DynRegionInfo DynSymRegion;
210213 DynRegionInfo DynamicTable;
256259
257260 Elf_Rel_Range dyn_rels() const;
258261 Elf_Rela_Range dyn_relas() const;
262 Elf_Relr_Range dyn_relrs() const;
259263 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable,
260264 bool IsDynamic) const;
261265 void getSectionNameIndex(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
270274 StringRef getDynamicStringTable() const { return DynamicStringTable; }
271275 const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
272276 const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; }
277 const DynRegionInfo &getDynRelrRegion() const { return DynRelrRegion; }
273278 const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; }
274279 const Elf_Hash *getHashTable() const { return HashTable; }
275280 const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; }
391396 }
392397 void printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, uint32_t Sym,
393398 StringRef StrTable, uint32_t Bucket);
399 void printRelocHeader(unsigned SType);
394400 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
395401 const Elf_Rela &R, bool IsRela);
396402 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
14911497 case ELF::DT_RELENT:
14921498 DynRelRegion.EntSize = Dyn.getVal();
14931499 break;
1500 case ELF::DT_RELR:
1501 case ELF::DT_ANDROID_RELR:
1502 DynRelrRegion.Addr = toMappedAddr(Dyn.getPtr());
1503 break;
1504 case ELF::DT_RELRSZ:
1505 case ELF::DT_ANDROID_RELRSZ:
1506 DynRelrRegion.Size = Dyn.getVal();
1507 break;
1508 case ELF::DT_RELRENT:
1509 case ELF::DT_ANDROID_RELRENT:
1510 DynRelrRegion.EntSize = Dyn.getVal();
1511 break;
14941512 case ELF::DT_PLTREL:
14951513 if (Dyn.getVal() == DT_REL)
14961514 DynPLTRelRegion.EntSize = sizeof(Elf_Rel);
15221540 template
15231541 typename ELFDumper::Elf_Rela_Range ELFDumper::dyn_relas() const {
15241542 return DynRelaRegion.getAsArrayRef();
1543 }
1544
1545 template
1546 typename ELFDumper::Elf_Relr_Range ELFDumper::dyn_relrs() const {
1547 return DynRelrRegion.getAsArrayRef();
15251548 }
15261549
15271550 template
25812604 const Elf_Rela &R, bool IsRela) {
25822605 std::string Offset, Info, Addend, Value;
25832606 SmallString<32> RelocName;
2584 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
25852607 StringRef TargetName;
25862608 const Elf_Sym *Sym = nullptr;
25872609 unsigned Width = ELFT::Is64Bits ? 16 : 8;
25972619 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable()));
25982620 TargetName = unwrapOrError(Obj->getSectionName(Sec));
25992621 } else if (Sym) {
2622 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab));
26002623 TargetName = unwrapOrError(Sym->getName(StrTable));
26012624 }
26022625
26282651 OS << "\n";
26292652 }
26302653
2631 static inline void printRelocHeader(raw_ostream &OS, bool Is64, bool IsRela) {
2632 if (Is64)
2633 OS << " Offset Info Type"
2654 template void GNUStyle::printRelocHeader(unsigned SType) {
2655 bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA;
2656 bool IsRelr = SType == ELF::SHT_RELR || SType == ELF::SHT_ANDROID_RELR;
2657 if (ELFT::Is64Bits)
2658 OS << " ";
2659 else
2660 OS << " ";
2661 if (IsRelr && opts::RawRelr)
2662 OS << "Data ";
2663 else
2664 OS << "Offset";
2665 if (ELFT::Is64Bits)
2666 OS << " Info Type"
26342667 << " Symbol's Value Symbol's Name";
26352668 else
2636 OS << " Offset Info Type Sym. Value "
2637 << "Symbol's Name";
2669 OS << " Info Type Sym. Value Symbol's Name";
26382670 if (IsRela)
2639 OS << (IsRela ? " + Addend" : "");
2671 OS << " + Addend";
26402672 OS << "\n";
26412673 }
26422674
26432675 template void GNUStyle::printRelocations(const ELFO *Obj) {
26442676 bool HasRelocSections = false;
26452677 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
2646 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
2678 if (Sec.sh_type != ELF::SHT_REL &&
2679 Sec.sh_type != ELF::SHT_RELA &&
2680 Sec.sh_type != ELF::SHT_RELR &&
26472681 Sec.sh_type != ELF::SHT_ANDROID_REL &&
2648 Sec.sh_type != ELF::SHT_ANDROID_RELA)
2682 Sec.sh_type != ELF::SHT_ANDROID_RELA &&
2683 Sec.sh_type != ELF::SHT_ANDROID_RELR)
26492684 continue;
26502685 HasRelocSections = true;
26512686 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
26582693 AndroidRelas = unwrapOrError(Obj->android_relas(&Sec));
26592694 Entries = AndroidRelas.size();
26602695 }
2696 std::vector RelrRelas;
2697 if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
2698 Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
2699 // .relr.dyn relative relocation section needs to be unpacked first
2700 // to get the actual number of entries.
2701 Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(&Sec));
2702 RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
2703 Entries = RelrRelas.size();
2704 }
26612705 uintX_t Offset = Sec.sh_offset;
26622706 OS << "\nRelocation section '" << Name << "' at offset 0x"
26632707 << to_hexString(Offset, false) << " contains " << Entries
26642708 << " entries:\n";
2665 printRelocHeader(OS, ELFT::Is64Bits,
2666 Sec.sh_type == ELF::SHT_RELA ||
2667 Sec.sh_type == ELF::SHT_ANDROID_RELA);
2709 printRelocHeader(Sec.sh_type);
26682710 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link));
26692711 switch (Sec.sh_type) {
26702712 case ELF::SHT_REL:
26792721 case ELF::SHT_RELA:
26802722 for (const auto &R : unwrapOrError(Obj->relas(&Sec)))
26812723 printRelocation(Obj, SymTab, R, true);
2724 break;
2725 case ELF::SHT_RELR:
2726 case ELF::SHT_ANDROID_RELR:
2727 if (opts::RawRelr)
2728 for (const auto &R : unwrapOrError(Obj->relrs(&Sec)))
2729 OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8))
2730 << "\n";
2731 else
2732 for (const auto &R : RelrRelas)
2733 printRelocation(Obj, SymTab, R, false);
26822734 break;
26832735 case ELF::SHT_ANDROID_REL:
26842736 case ELF::SHT_ANDROID_RELA:
27612813 return "GROUP";
27622814 case SHT_SYMTAB_SHNDX:
27632815 return "SYMTAB SECTION INDICES";
2816 case SHT_RELR:
2817 case SHT_ANDROID_RELR:
2818 return "RELR";
27642819 case SHT_LLVM_ODRTAB:
27652820 return "LLVM_ODRTAB";
27662821 case SHT_LLVM_LINKER_OPTIONS:
32993354 void GNUStyle::printDynamicRelocations(const ELFO *Obj) {
33003355 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
33013356 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
3357 const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
33023358 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
33033359 if (DynRelaRegion.Size > 0) {
33043360 OS << "\n'RELA' relocation section at offset "
33053361 << format_hex(reinterpret_cast(DynRelaRegion.Addr) -
33063362 Obj->base(),
33073363 1) << " contains " << DynRelaRegion.Size << " bytes:\n";
3308 printRelocHeader(OS, ELFT::Is64Bits, true);
3364 printRelocHeader(ELF::SHT_RELA);
33093365 for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
33103366 printDynamicRelocation(Obj, Rela, true);
33113367 }
33143370 << format_hex(reinterpret_cast(DynRelRegion.Addr) -
33153371 Obj->base(),
33163372 1) << " contains " << DynRelRegion.Size << " bytes:\n";
3317 printRelocHeader(OS, ELFT::Is64Bits, false);
3373 printRelocHeader(ELF::SHT_REL);
33183374 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
33193375 Elf_Rela Rela;
33203376 Rela.r_offset = Rel.r_offset;
33233379 printDynamicRelocation(Obj, Rela, false);
33243380 }
33253381 }
3382 if (DynRelrRegion.Size > 0) {
3383 OS << "\n'RELR' relocation section at offset "
3384 << format_hex(reinterpret_cast(DynRelrRegion.Addr) -
3385 Obj->base(),
3386 1) << " contains " << DynRelrRegion.Size << " bytes:\n";
3387 printRelocHeader(ELF::SHT_REL);
3388 Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
3389 std::vector RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
3390 for (const Elf_Rela &Rela : RelrRelas) {
3391 printDynamicRelocation(Obj, Rela, false);
3392 }
3393 }
33263394 if (DynPLTRelRegion.Size) {
33273395 OS << "\n'PLT' relocation section at offset "
33283396 << format_hex(reinterpret_cast(DynPLTRelRegion.Addr) -
33303398 1) << " contains " << DynPLTRelRegion.Size << " bytes:\n";
33313399 }
33323400 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
3333 printRelocHeader(OS, ELFT::Is64Bits, true);
3401 printRelocHeader(ELF::SHT_RELA);
33343402 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef())
33353403 printDynamicRelocation(Obj, Rela, true);
33363404 } else {
3337 printRelocHeader(OS, ELFT::Is64Bits, false);
3405 printRelocHeader(ELF::SHT_REL);
33383406 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) {
33393407 Elf_Rela Rela;
33403408 Rela.r_offset = Rel.r_offset;
39554023 for (const Elf_Shdr &Sec : unwrapOrError(Obj->sections())) {
39564024 ++SectionNumber;
39574025
3958 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA &&
4026 if (Sec.sh_type != ELF::SHT_REL &&
4027 Sec.sh_type != ELF::SHT_RELA &&
4028 Sec.sh_type != ELF::SHT_RELR &&
39594029 Sec.sh_type != ELF::SHT_ANDROID_REL &&
3960 Sec.sh_type != ELF::SHT_ANDROID_RELA)
4030 Sec.sh_type != ELF::SHT_ANDROID_RELA &&
4031 Sec.sh_type != ELF::SHT_ANDROID_RELR)
39614032 continue;
39624033
39634034 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
39904061 for (const Elf_Rela &R : unwrapOrError(Obj->relas(Sec)))
39914062 printRelocation(Obj, R, SymTab);
39924063 break;
4064 case ELF::SHT_RELR:
4065 case ELF::SHT_ANDROID_RELR: {
4066 Elf_Relr_Range Relrs = unwrapOrError(Obj->relrs(Sec));
4067 if (opts::RawRelr) {
4068 for (const Elf_Relr &R : Relrs)
4069 W.startLine() << W.hex(R) << "\n";
4070 } else {
4071 std::vector RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
4072 for (const Elf_Rela &R : RelrRelas)
4073 printRelocation(Obj, R, SymTab);
4074 }
4075 break;
4076 }
39934077 case ELF::SHT_ANDROID_REL:
39944078 case ELF::SHT_ANDROID_RELA:
39954079 for (const Elf_Rela &R : unwrapOrError(Obj->android_relas(Sec)))
41704254 void LLVMStyle::printDynamicRelocations(const ELFO *Obj) {
41714255 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion();
41724256 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
4257 const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
41734258 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
41744259 if (DynRelRegion.Size && DynRelaRegion.Size)
41754260 report_fatal_error("There are both REL and RELA dynamic relocations");
41864271 Rela.r_addend = 0;
41874272 printDynamicRelocation(Obj, Rela);
41884273 }
4274 if (DynRelrRegion.Size > 0) {
4275 Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
4276 std::vector RelrRelas = unwrapOrError(Obj->decode_relrs(Relrs));
4277 for (const Elf_Rela &Rela : RelrRelas)
4278 printDynamicRelocation(Obj, Rela);
4279 }
41894280 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
41904281 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef())
41914282 printDynamicRelocation(Obj, Rela);
162162 // -expand-relocs
163163 cl::opt ExpandRelocs("expand-relocs",
164164 cl::desc("Expand each shown relocation to multiple lines"));
165
166 // -raw-relr
167 cl::opt RawRelr("raw-relr",
168 cl::desc("Do not decode relocations in SHT_RELR section, display raw contents"));
165169
166170 // -codeview
167171 cl::opt CodeView("codeview",
5959 extern llvm::cl::opt DynamicSymbols;
6060 extern llvm::cl::opt UnwindInfo;
6161 extern llvm::cl::opt ExpandRelocs;
62 extern llvm::cl::opt RawRelr;
6263 extern llvm::cl::opt CodeView;
6364 extern llvm::cl::opt CodeViewSubsectionBytes;
6465 extern llvm::cl::opt ARMAttributes;
113113 typedef typename ELFT::Sym Elf_Sym;
114114 typedef typename ELFT::Rel Elf_Rel;
115115 typedef typename ELFT::Rela Elf_Rela;
116 typedef typename ELFT::Relr Elf_Relr;
116117
117118 enum class SymtabType { Static, Dynamic };
118119
458459 Section.Content.writeAsBinary(OS);
459460 for (auto i = Section.Content.binary_size(); i < Section.Size; ++i)
460461 OS.write(0);
461 SHeader.sh_entsize = 0;
462 if (Section.Type == llvm::ELF::SHT_RELR)
463 SHeader.sh_entsize = sizeof(Elf_Relr);
464 else
465 SHeader.sh_entsize = 0;
462466 SHeader.sh_size = Section.Size;
463467 }
464468