xref: /llvm-project-15.0.7/llvm/lib/Object/ELF.cpp (revision 1524e67f)
1 //===- ELF.cpp - ELF object file implementation ---------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Object/ELF.h"
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/Support/LEB128.h"
13 
14 using namespace llvm;
15 using namespace object;
16 
17 #define STRINGIFY_ENUM_CASE(ns, name)                                          \
18   case ns::name:                                                               \
19     return #name;
20 
21 #define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
22 
23 StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
24                                                  uint32_t Type) {
25   switch (Machine) {
26   case ELF::EM_X86_64:
27     switch (Type) {
28 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
29     default:
30       break;
31     }
32     break;
33   case ELF::EM_386:
34   case ELF::EM_IAMCU:
35     switch (Type) {
36 #include "llvm/BinaryFormat/ELFRelocs/i386.def"
37     default:
38       break;
39     }
40     break;
41   case ELF::EM_MIPS:
42     switch (Type) {
43 #include "llvm/BinaryFormat/ELFRelocs/Mips.def"
44     default:
45       break;
46     }
47     break;
48   case ELF::EM_AARCH64:
49     switch (Type) {
50 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
51     default:
52       break;
53     }
54     break;
55   case ELF::EM_ARM:
56     switch (Type) {
57 #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
58     default:
59       break;
60     }
61     break;
62   case ELF::EM_ARC_COMPACT:
63   case ELF::EM_ARC_COMPACT2:
64     switch (Type) {
65 #include "llvm/BinaryFormat/ELFRelocs/ARC.def"
66     default:
67       break;
68     }
69     break;
70   case ELF::EM_AVR:
71     switch (Type) {
72 #include "llvm/BinaryFormat/ELFRelocs/AVR.def"
73     default:
74       break;
75     }
76     break;
77   case ELF::EM_HEXAGON:
78     switch (Type) {
79 #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
80     default:
81       break;
82     }
83     break;
84   case ELF::EM_LANAI:
85     switch (Type) {
86 #include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
87     default:
88       break;
89     }
90     break;
91   case ELF::EM_PPC:
92     switch (Type) {
93 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
94     default:
95       break;
96     }
97     break;
98   case ELF::EM_PPC64:
99     switch (Type) {
100 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
101     default:
102       break;
103     }
104     break;
105   case ELF::EM_RISCV:
106     switch (Type) {
107 #include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
108     default:
109       break;
110     }
111     break;
112   case ELF::EM_S390:
113     switch (Type) {
114 #include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
115     default:
116       break;
117     }
118     break;
119   case ELF::EM_SPARC:
120   case ELF::EM_SPARC32PLUS:
121   case ELF::EM_SPARCV9:
122     switch (Type) {
123 #include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
124     default:
125       break;
126     }
127     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:
136     switch (Type) {
137 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
138     default:
139       break;
140     }
141   case ELF::EM_BPF:
142     switch (Type) {
143 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
144     default:
145       break;
146     }
147     break;
148   default:
149     break;
150   }
151   return "Unknown";
152 }
153 
154 #undef ELF_RELOC
155 
156 StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
157   switch (Machine) {
158   case ELF::EM_ARM:
159     switch (Type) {
160       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
161       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
162       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
163       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
164       STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
165     }
166     break;
167   case ELF::EM_HEXAGON:
168     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
169     break;
170   case ELF::EM_X86_64:
171     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
172     break;
173   case ELF::EM_MIPS:
174   case ELF::EM_MIPS_RS3_LE:
175     switch (Type) {
176       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
177       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
178       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
179       STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
180     }
181     break;
182   default:
183     break;
184   }
185 
186   switch (Type) {
187     STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
188     STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
189     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
190     STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
191     STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
192     STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
193     STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
194     STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
195     STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
196     STRINGIFY_ENUM_CASE(ELF, SHT_REL);
197     STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
198     STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
199     STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
200     STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
201     STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
202     STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
203     STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
204     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
205     STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
206     STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
207     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
208     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
209     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
210     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
211     STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
212   default:
213     return "Unknown";
214   }
215 }
216 
217 template <class ELFT>
218 Expected<uint32_t>
219 ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
220                                ArrayRef<Elf_Word> ShndxTable) const {
221   uint32_t Index = Sym->st_shndx;
222   if (Index == ELF::SHN_XINDEX) {
223     auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
224         Sym, Syms.begin(), ShndxTable);
225     if (!ErrorOrIndex)
226       return ErrorOrIndex.takeError();
227     return *ErrorOrIndex;
228   }
229   if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
230     return 0;
231   return Index;
232 }
233 
234 template <class ELFT>
235 Expected<const typename ELFT::Shdr *>
236 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
237                           ArrayRef<Elf_Word> ShndxTable) const {
238   auto SymsOrErr = symbols(SymTab);
239   if (!SymsOrErr)
240     return SymsOrErr.takeError();
241   return getSection(Sym, *SymsOrErr, ShndxTable);
242 }
243 
244 template <class ELFT>
245 Expected<const typename ELFT::Shdr *>
246 ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
247                           ArrayRef<Elf_Word> ShndxTable) const {
248   auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
249   if (!IndexOrErr)
250     return IndexOrErr.takeError();
251   uint32_t Index = *IndexOrErr;
252   if (Index == 0)
253     return nullptr;
254   return getSection(Index);
255 }
256 
257 template <class ELFT>
258 Expected<const typename ELFT::Sym *>
259 ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
260   auto SymtabOrErr = symbols(Sec);
261   if (!SymtabOrErr)
262     return SymtabOrErr.takeError();
263   return object::getSymbol<ELFT>(*SymtabOrErr, Index);
264 }
265 
266 template <class ELFT>
267 Expected<ArrayRef<uint8_t>>
268 ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
269   return getSectionContentsAsArray<uint8_t>(Sec);
270 }
271 
272 template <class ELFT>
273 StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
274   return getELFRelocationTypeName(getHeader()->e_machine, Type);
275 }
276 
277 template <class ELFT>
278 void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
279                                           SmallVectorImpl<char> &Result) const {
280   if (!isMipsELF64()) {
281     StringRef Name = getRelocationTypeName(Type);
282     Result.append(Name.begin(), Name.end());
283   } else {
284     // The Mips N64 ABI allows up to three operations to be specified per
285     // relocation record. Unfortunately there's no easy way to test for the
286     // presence of N64 ELFs as they have no special flag that identifies them
287     // as being N64. We can safely assume at the moment that all Mips
288     // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
289     // information to disambiguate between old vs new ABIs.
290     uint8_t Type1 = (Type >> 0) & 0xFF;
291     uint8_t Type2 = (Type >> 8) & 0xFF;
292     uint8_t Type3 = (Type >> 16) & 0xFF;
293 
294     // Concat all three relocation type names.
295     StringRef Name = getRelocationTypeName(Type1);
296     Result.append(Name.begin(), Name.end());
297 
298     Name = getRelocationTypeName(Type2);
299     Result.append(1, '/');
300     Result.append(Name.begin(), Name.end());
301 
302     Name = getRelocationTypeName(Type3);
303     Result.append(1, '/');
304     Result.append(Name.begin(), Name.end());
305   }
306 }
307 
308 template <class ELFT>
309 Expected<const typename ELFT::Sym *>
310 ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
311                                    const Elf_Shdr *SymTab) const {
312   uint32_t Index = Rel->getSymbol(isMips64EL());
313   if (Index == 0)
314     return nullptr;
315   return getEntry<Elf_Sym>(SymTab, Index);
316 }
317 
318 template <class ELFT>
319 Expected<StringRef>
320 ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
321   uint32_t Index = getHeader()->e_shstrndx;
322   if (Index == ELF::SHN_XINDEX)
323     Index = Sections[0].sh_link;
324 
325   if (!Index) // no section string table.
326     return "";
327   if (Index >= Sections.size())
328     return createError("invalid section index");
329   return getStringTable(&Sections[Index]);
330 }
331 
332 template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
333 
334 template <class ELFT>
335 Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
336   if (sizeof(Elf_Ehdr) > Object.size())
337     return createError("Invalid buffer");
338   return ELFFile(Object);
339 }
340 
341 template <class ELFT>
342 Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
343   const uintX_t SectionTableOffset = getHeader()->e_shoff;
344   if (SectionTableOffset == 0)
345     return ArrayRef<Elf_Shdr>();
346 
347   if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
348     return createError(
349         "invalid section header entry size (e_shentsize) in ELF header");
350 
351   const uint64_t FileSize = Buf.size();
352 
353   if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
354     return createError("section header table goes past the end of the file");
355 
356   // Invalid address alignment of section headers
357   if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
358     return createError("invalid alignment of section headers");
359 
360   const Elf_Shdr *First =
361       reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
362 
363   uintX_t NumSections = getHeader()->e_shnum;
364   if (NumSections == 0)
365     NumSections = First->sh_size;
366 
367   if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
368     return createError("section table goes past the end of file");
369 
370   const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
371 
372   // Section table goes past end of file!
373   if (SectionTableOffset + SectionTableSize > FileSize)
374     return createError("section table goes past the end of file");
375 
376   return makeArrayRef(First, NumSections);
377 }
378 
379 template <class ELFT>
380 Expected<const typename ELFT::Shdr *>
381 ELFFile<ELFT>::getSection(uint32_t Index) const {
382   auto TableOrErr = sections();
383   if (!TableOrErr)
384     return TableOrErr.takeError();
385   return object::getSection<ELFT>(*TableOrErr, Index);
386 }
387 
388 template <class ELFT>
389 Expected<StringRef>
390 ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
391   if (Section->sh_type != ELF::SHT_STRTAB)
392     return createError("invalid sh_type for string table, expected SHT_STRTAB");
393   auto V = getSectionContentsAsArray<char>(Section);
394   if (!V)
395     return V.takeError();
396   ArrayRef<char> Data = *V;
397   if (Data.empty())
398     return createError("empty string table");
399   if (Data.back() != '\0')
400     return createError("string table non-null terminated");
401   return StringRef(Data.begin(), Data.size());
402 }
403 
404 template <class ELFT>
405 Expected<ArrayRef<typename ELFT::Word>>
406 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
407   auto SectionsOrErr = sections();
408   if (!SectionsOrErr)
409     return SectionsOrErr.takeError();
410   return getSHNDXTable(Section, *SectionsOrErr);
411 }
412 
413 template <class ELFT>
414 Expected<ArrayRef<typename ELFT::Word>>
415 ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
416                              Elf_Shdr_Range Sections) const {
417   assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
418   auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
419   if (!VOrErr)
420     return VOrErr.takeError();
421   ArrayRef<Elf_Word> V = *VOrErr;
422   auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
423   if (!SymTableOrErr)
424     return SymTableOrErr.takeError();
425   const Elf_Shdr &SymTable = **SymTableOrErr;
426   if (SymTable.sh_type != ELF::SHT_SYMTAB &&
427       SymTable.sh_type != ELF::SHT_DYNSYM)
428     return createError("invalid sh_type");
429   if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
430     return createError("invalid section contents size");
431   return V;
432 }
433 
434 template <class ELFT>
435 Expected<StringRef>
436 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
437   auto SectionsOrErr = sections();
438   if (!SectionsOrErr)
439     return SectionsOrErr.takeError();
440   return getStringTableForSymtab(Sec, *SectionsOrErr);
441 }
442 
443 template <class ELFT>
444 Expected<StringRef>
445 ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
446                                        Elf_Shdr_Range Sections) const {
447 
448   if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
449     return createError(
450         "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
451   auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
452   if (!SectionOrErr)
453     return SectionOrErr.takeError();
454   return getStringTable(*SectionOrErr);
455 }
456 
457 template <class ELFT>
458 Expected<StringRef>
459 ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
460   auto SectionsOrErr = sections();
461   if (!SectionsOrErr)
462     return SectionsOrErr.takeError();
463   auto Table = getSectionStringTable(*SectionsOrErr);
464   if (!Table)
465     return Table.takeError();
466   return getSectionName(Section, *Table);
467 }
468 
469 template <class ELFT>
470 Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
471                                                   StringRef DotShstrtab) const {
472   uint32_t Offset = Section->sh_name;
473   if (Offset == 0)
474     return StringRef();
475   if (Offset >= DotShstrtab.size())
476     return createError("invalid string offset");
477   return StringRef(DotShstrtab.data() + Offset);
478 }
479 
480 template <class ELFT>
481 Expected<std::vector<typename ELFT::Rela>>
482 ELFFile<ELFT>::android_relas(const Elf_Shdr *Sec) const {
483   // This function reads relocations in Android's packed relocation format,
484   // which is based on SLEB128 and delta encoding.
485   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
486   if (!ContentsOrErr)
487     return ContentsOrErr.takeError();
488   const uint8_t *Cur = ContentsOrErr->begin();
489   const uint8_t *End = ContentsOrErr->end();
490   if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
491       Cur[2] != 'S' || Cur[3] != '2')
492     return createError("invalid packed relocation header");
493   Cur += 4;
494 
495   const char *ErrStr = nullptr;
496   auto ReadSLEB = [&]() -> int64_t {
497     if (ErrStr)
498       return 0;
499     unsigned Len;
500     int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
501     Cur += Len;
502     return Result;
503   };
504 
505   uint64_t NumRelocs = ReadSLEB();
506   uint64_t Offset = ReadSLEB();
507   uint64_t Addend = 0;
508 
509   if (ErrStr)
510     return createError(ErrStr);
511 
512   std::vector<Elf_Rela> Relocs;
513   Relocs.reserve(NumRelocs);
514   while (NumRelocs) {
515     uint64_t NumRelocsInGroup = ReadSLEB();
516     if (NumRelocsInGroup > NumRelocs)
517       return createError("relocation group unexpectedly large");
518     NumRelocs -= NumRelocsInGroup;
519 
520     uint64_t GroupFlags = ReadSLEB();
521     bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
522     bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
523     bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
524     bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
525 
526     uint64_t GroupOffsetDelta;
527     if (GroupedByOffsetDelta)
528       GroupOffsetDelta = ReadSLEB();
529 
530     uint64_t GroupRInfo;
531     if (GroupedByInfo)
532       GroupRInfo = ReadSLEB();
533 
534     if (GroupedByAddend && GroupHasAddend)
535       Addend += ReadSLEB();
536 
537     for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
538       Elf_Rela R;
539       Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
540       R.r_offset = Offset;
541       R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
542 
543       if (GroupHasAddend) {
544         if (!GroupedByAddend)
545           Addend += ReadSLEB();
546         R.r_addend = Addend;
547       } else {
548         R.r_addend = 0;
549       }
550 
551       Relocs.push_back(R);
552 
553       if (ErrStr)
554         return createError(ErrStr);
555     }
556 
557     if (ErrStr)
558       return createError(ErrStr);
559   }
560 
561   return Relocs;
562 }
563 
564 template class llvm::object::ELFFile<ELF32LE>;
565 template class llvm::object::ELFFile<ELF32BE>;
566 template class llvm::object::ELFFile<ELF64LE>;
567 template class llvm::object::ELFFile<ELF64BE>;
568