Mercurial > hg > CbC > CbC_llvm
comparison lib/Object/ELF.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- ELF.cpp - ELF object file implementation ---------------------------===// | 1 //===- ELF.cpp - ELF object file implementation ---------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
10 #include "llvm/Object/ELF.h" | 9 #include "llvm/Object/ELF.h" |
11 #include "llvm/BinaryFormat/ELF.h" | 10 #include "llvm/BinaryFormat/ELF.h" |
123 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" | 122 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def" |
124 default: | 123 default: |
125 break; | 124 break; |
126 } | 125 } |
127 break; | 126 break; |
128 case ELF::EM_WEBASSEMBLY: | |
129 switch (Type) { | |
130 #include "llvm/BinaryFormat/ELFRelocs/WebAssembly.def" | |
131 default: | |
132 break; | |
133 } | |
134 break; | |
135 case ELF::EM_AMDGPU: | 127 case ELF::EM_AMDGPU: |
136 switch (Type) { | 128 switch (Type) { |
137 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" | 129 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" |
138 default: | 130 default: |
139 break; | 131 break; |
144 #include "llvm/BinaryFormat/ELFRelocs/BPF.def" | 136 #include "llvm/BinaryFormat/ELFRelocs/BPF.def" |
145 default: | 137 default: |
146 break; | 138 break; |
147 } | 139 } |
148 break; | 140 break; |
141 case ELF::EM_MSP430: | |
142 switch (Type) { | |
143 #include "llvm/BinaryFormat/ELFRelocs/MSP430.def" | |
144 default: | |
145 break; | |
146 } | |
147 break; | |
149 default: | 148 default: |
150 break; | 149 break; |
151 } | 150 } |
152 return "Unknown"; | 151 return "Unknown"; |
153 } | 152 } |
154 | 153 |
155 #undef ELF_RELOC | 154 #undef ELF_RELOC |
155 | |
156 uint32_t llvm::object::getELFRelativeRelocationType(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_AMDGPU: | |
191 break; | |
192 case ELF::EM_BPF: | |
193 break; | |
194 default: | |
195 break; | |
196 } | |
197 return 0; | |
198 } | |
156 | 199 |
157 StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { | 200 StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { |
158 switch (Machine) { | 201 switch (Machine) { |
159 case ELF::EM_ARM: | 202 case ELF::EM_ARM: |
160 switch (Type) { | 203 switch (Type) { |
174 case ELF::EM_MIPS: | 217 case ELF::EM_MIPS: |
175 case ELF::EM_MIPS_RS3_LE: | 218 case ELF::EM_MIPS_RS3_LE: |
176 switch (Type) { | 219 switch (Type) { |
177 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO); | 220 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO); |
178 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); | 221 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); |
222 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF); | |
179 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); | 223 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); |
180 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF); | |
181 } | 224 } |
182 break; | 225 break; |
183 default: | 226 default: |
184 break; | 227 break; |
185 } | 228 } |
200 STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY); | 243 STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY); |
201 STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY); | 244 STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY); |
202 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY); | 245 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY); |
203 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP); | 246 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP); |
204 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX); | 247 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX); |
248 STRINGIFY_ENUM_CASE(ELF, SHT_RELR); | |
205 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL); | 249 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL); |
206 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA); | 250 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA); |
251 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR); | |
207 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB); | 252 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB); |
208 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS); | 253 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS); |
254 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE); | |
255 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG); | |
256 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES); | |
257 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART); | |
209 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); | 258 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); |
210 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); | 259 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); |
211 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); | 260 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); |
212 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed); | 261 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed); |
213 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym); | 262 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym); |
214 default: | 263 default: |
215 return "Unknown"; | 264 return "Unknown"; |
216 } | 265 } |
266 } | |
267 | |
268 template <class ELFT> | |
269 Expected<std::vector<typename ELFT::Rela>> | |
270 ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const { | |
271 // This function decodes the contents of an SHT_RELR packed relocation | |
272 // section. | |
273 // | |
274 // Proposal for adding SHT_RELR sections to generic-abi is here: | |
275 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg | |
276 // | |
277 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks | |
278 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ] | |
279 // | |
280 // i.e. start with an address, followed by any number of bitmaps. The address | |
281 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63 | |
282 // relocations each, at subsequent offsets following the last address entry. | |
283 // | |
284 // The bitmap entries must have 1 in the least significant bit. The assumption | |
285 // here is that an address cannot have 1 in lsb. Odd addresses are not | |
286 // supported. | |
287 // | |
288 // Excluding the least significant bit in the bitmap, each non-zero bit in | |
289 // the bitmap represents a relocation to be applied to a corresponding machine | |
290 // word that follows the base address word. The second least significant bit | |
291 // represents the machine word immediately following the initial address, and | |
292 // each bit that follows represents the next word, in linear order. As such, | |
293 // a single bitmap can encode up to 31 relocations in a 32-bit object, and | |
294 // 63 relocations in a 64-bit object. | |
295 // | |
296 // This encoding has a couple of interesting properties: | |
297 // 1. Looking at any entry, it is clear whether it's an address or a bitmap: | |
298 // even means address, odd means bitmap. | |
299 // 2. Just a simple list of addresses is a valid encoding. | |
300 | |
301 Elf_Rela Rela; | |
302 Rela.r_info = 0; | |
303 Rela.r_addend = 0; | |
304 Rela.setType(getRelativeRelocationType(), false); | |
305 std::vector<Elf_Rela> Relocs; | |
306 | |
307 // Word type: uint32_t for Elf32, and uint64_t for Elf64. | |
308 typedef typename ELFT::uint Word; | |
309 | |
310 // Word size in number of bytes. | |
311 const size_t WordSize = sizeof(Word); | |
312 | |
313 // Number of bits used for the relocation offsets bitmap. | |
314 // These many relative relocations can be encoded in a single entry. | |
315 const size_t NBits = 8*WordSize - 1; | |
316 | |
317 Word Base = 0; | |
318 for (const Elf_Relr &R : relrs) { | |
319 Word Entry = R; | |
320 if ((Entry&1) == 0) { | |
321 // Even entry: encodes the offset for next relocation. | |
322 Rela.r_offset = Entry; | |
323 Relocs.push_back(Rela); | |
324 // Set base offset for subsequent bitmap entries. | |
325 Base = Entry + WordSize; | |
326 continue; | |
327 } | |
328 | |
329 // Odd entry: encodes bitmap for relocations starting at base. | |
330 Word Offset = Base; | |
331 while (Entry != 0) { | |
332 Entry >>= 1; | |
333 if ((Entry&1) != 0) { | |
334 Rela.r_offset = Offset; | |
335 Relocs.push_back(Rela); | |
336 } | |
337 Offset += WordSize; | |
338 } | |
339 | |
340 // Advance base offset by NBits words. | |
341 Base += NBits * WordSize; | |
342 } | |
343 | |
344 return Relocs; | |
217 } | 345 } |
218 | 346 |
219 template <class ELFT> | 347 template <class ELFT> |
220 Expected<std::vector<typename ELFT::Rela>> | 348 Expected<std::vector<typename ELFT::Rela>> |
221 ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const { | 349 ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const { |
271 GroupRInfo = ReadSLEB(); | 399 GroupRInfo = ReadSLEB(); |
272 | 400 |
273 if (GroupedByAddend && GroupHasAddend) | 401 if (GroupedByAddend && GroupHasAddend) |
274 Addend += ReadSLEB(); | 402 Addend += ReadSLEB(); |
275 | 403 |
404 if (!GroupHasAddend) | |
405 Addend = 0; | |
406 | |
276 for (uint64_t I = 0; I != NumRelocsInGroup; ++I) { | 407 for (uint64_t I = 0; I != NumRelocsInGroup; ++I) { |
277 Elf_Rela R; | 408 Elf_Rela R; |
278 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB(); | 409 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB(); |
279 R.r_offset = Offset; | 410 R.r_offset = Offset; |
280 R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB(); | 411 R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB(); |
281 | 412 if (GroupHasAddend && !GroupedByAddend) |
282 if (GroupHasAddend) { | 413 Addend += ReadSLEB(); |
283 if (!GroupedByAddend) | 414 R.r_addend = Addend; |
284 Addend += ReadSLEB(); | |
285 R.r_addend = Addend; | |
286 } else { | |
287 R.r_addend = 0; | |
288 } | |
289 | |
290 Relocs.push_back(R); | 415 Relocs.push_back(R); |
291 | 416 |
292 if (ErrStr) | 417 if (ErrStr) |
293 return createError(ErrStr); | 418 return createError(ErrStr); |
294 } | 419 } |
296 if (ErrStr) | 421 if (ErrStr) |
297 return createError(ErrStr); | 422 return createError(ErrStr); |
298 } | 423 } |
299 | 424 |
300 return Relocs; | 425 return Relocs; |
426 } | |
427 | |
428 template <class ELFT> | |
429 std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch, | |
430 uint64_t Type) const { | |
431 #define DYNAMIC_STRINGIFY_ENUM(tag, value) \ | |
432 case value: \ | |
433 return #tag; | |
434 | |
435 #define DYNAMIC_TAG(n, v) | |
436 switch (Arch) { | |
437 case ELF::EM_AARCH64: | |
438 switch (Type) { | |
439 #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) | |
440 #include "llvm/BinaryFormat/DynamicTags.def" | |
441 #undef AARCH64_DYNAMIC_TAG | |
442 } | |
443 break; | |
444 | |
445 case ELF::EM_HEXAGON: | |
446 switch (Type) { | |
447 #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) | |
448 #include "llvm/BinaryFormat/DynamicTags.def" | |
449 #undef HEXAGON_DYNAMIC_TAG | |
450 } | |
451 break; | |
452 | |
453 case ELF::EM_MIPS: | |
454 switch (Type) { | |
455 #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) | |
456 #include "llvm/BinaryFormat/DynamicTags.def" | |
457 #undef MIPS_DYNAMIC_TAG | |
458 } | |
459 break; | |
460 | |
461 case ELF::EM_PPC64: | |
462 switch (Type) { | |
463 #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) | |
464 #include "llvm/BinaryFormat/DynamicTags.def" | |
465 #undef PPC64_DYNAMIC_TAG | |
466 } | |
467 break; | |
468 } | |
469 #undef DYNAMIC_TAG | |
470 switch (Type) { | |
471 // Now handle all dynamic tags except the architecture specific ones | |
472 #define AARCH64_DYNAMIC_TAG(name, value) | |
473 #define MIPS_DYNAMIC_TAG(name, value) | |
474 #define HEXAGON_DYNAMIC_TAG(name, value) | |
475 #define PPC64_DYNAMIC_TAG(name, value) | |
476 // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc. | |
477 #define DYNAMIC_TAG_MARKER(name, value) | |
478 #define DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value) | |
479 #include "llvm/BinaryFormat/DynamicTags.def" | |
480 #undef DYNAMIC_TAG | |
481 #undef AARCH64_DYNAMIC_TAG | |
482 #undef MIPS_DYNAMIC_TAG | |
483 #undef HEXAGON_DYNAMIC_TAG | |
484 #undef PPC64_DYNAMIC_TAG | |
485 #undef DYNAMIC_TAG_MARKER | |
486 #undef DYNAMIC_STRINGIFY_ENUM | |
487 default: | |
488 return "<unknown:>0x" + utohexstr(Type, true); | |
489 } | |
490 } | |
491 | |
492 template <class ELFT> | |
493 std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const { | |
494 return getDynamicTagAsString(getHeader()->e_machine, Type); | |
495 } | |
496 | |
497 template <class ELFT> | |
498 Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const { | |
499 ArrayRef<Elf_Dyn> Dyn; | |
500 size_t DynSecSize = 0; | |
501 | |
502 auto ProgramHeadersOrError = program_headers(); | |
503 if (!ProgramHeadersOrError) | |
504 return ProgramHeadersOrError.takeError(); | |
505 | |
506 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) { | |
507 if (Phdr.p_type == ELF::PT_DYNAMIC) { | |
508 Dyn = makeArrayRef( | |
509 reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset), | |
510 Phdr.p_filesz / sizeof(Elf_Dyn)); | |
511 DynSecSize = Phdr.p_filesz; | |
512 break; | |
513 } | |
514 } | |
515 | |
516 // If we can't find the dynamic section in the program headers, we just fall | |
517 // back on the sections. | |
518 if (Dyn.empty()) { | |
519 auto SectionsOrError = sections(); | |
520 if (!SectionsOrError) | |
521 return SectionsOrError.takeError(); | |
522 | |
523 for (const Elf_Shdr &Sec : *SectionsOrError) { | |
524 if (Sec.sh_type == ELF::SHT_DYNAMIC) { | |
525 Expected<ArrayRef<Elf_Dyn>> DynOrError = | |
526 getSectionContentsAsArray<Elf_Dyn>(&Sec); | |
527 if (!DynOrError) | |
528 return DynOrError.takeError(); | |
529 Dyn = *DynOrError; | |
530 DynSecSize = Sec.sh_size; | |
531 break; | |
532 } | |
533 } | |
534 | |
535 if (!Dyn.data()) | |
536 return ArrayRef<Elf_Dyn>(); | |
537 } | |
538 | |
539 if (Dyn.empty()) | |
540 // TODO: this error is untested. | |
541 return createError("invalid empty dynamic section"); | |
542 | |
543 if (DynSecSize % sizeof(Elf_Dyn) != 0) | |
544 // TODO: this error is untested. | |
545 return createError("malformed dynamic section"); | |
546 | |
547 if (Dyn.back().d_tag != ELF::DT_NULL) | |
548 // TODO: this error is untested. | |
549 return createError("dynamic sections must be DT_NULL terminated"); | |
550 | |
551 return Dyn; | |
552 } | |
553 | |
554 template <class ELFT> | |
555 Expected<const uint8_t *> ELFFile<ELFT>::toMappedAddr(uint64_t VAddr) const { | |
556 auto ProgramHeadersOrError = program_headers(); | |
557 if (!ProgramHeadersOrError) | |
558 return ProgramHeadersOrError.takeError(); | |
559 | |
560 llvm::SmallVector<Elf_Phdr *, 4> LoadSegments; | |
561 | |
562 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) | |
563 if (Phdr.p_type == ELF::PT_LOAD) | |
564 LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr)); | |
565 | |
566 const Elf_Phdr *const *I = | |
567 std::upper_bound(LoadSegments.begin(), LoadSegments.end(), VAddr, | |
568 [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) { | |
569 return VAddr < Phdr->p_vaddr; | |
570 }); | |
571 | |
572 if (I == LoadSegments.begin()) | |
573 return createError("virtual address is not in any segment: 0x" + | |
574 Twine::utohexstr(VAddr)); | |
575 --I; | |
576 const Elf_Phdr &Phdr = **I; | |
577 uint64_t Delta = VAddr - Phdr.p_vaddr; | |
578 if (Delta >= Phdr.p_filesz) | |
579 return createError("virtual address is not in any segment: 0x" + | |
580 Twine::utohexstr(VAddr)); | |
581 return base() + Phdr.p_offset + Delta; | |
301 } | 582 } |
302 | 583 |
303 template class llvm::object::ELFFile<ELF32LE>; | 584 template class llvm::object::ELFFile<ELF32LE>; |
304 template class llvm::object::ELFFile<ELF32BE>; | 585 template class llvm::object::ELFFile<ELF32BE>; |
305 template class llvm::object::ELFFile<ELF64LE>; | 586 template class llvm::object::ELFFile<ELF64LE>; |