LLVM  7.0.0svn
ELF.cpp
Go to the documentation of this file.
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 
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;
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_AMDGPU:
129  switch (Type) {
130 #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
131  default:
132  break;
133  }
134  break;
135  case ELF::EM_BPF:
136  switch (Type) {
137 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
138  default:
139  break;
140  }
141  break;
142  default:
143  break;
144  }
145  return "Unknown";
146 }
147 
148 #undef ELF_RELOC
149 
151  switch (Machine) {
152  case ELF::EM_X86_64:
153  return ELF::R_X86_64_RELATIVE;
154  case ELF::EM_386:
155  case ELF::EM_IAMCU:
156  return ELF::R_386_RELATIVE;
157  case ELF::EM_MIPS:
158  break;
159  case ELF::EM_AARCH64:
160  return ELF::R_AARCH64_RELATIVE;
161  case ELF::EM_ARM:
162  return ELF::R_ARM_RELATIVE;
163  case ELF::EM_ARC_COMPACT:
165  return ELF::R_ARC_RELATIVE;
166  case ELF::EM_AVR:
167  break;
168  case ELF::EM_HEXAGON:
169  return ELF::R_HEX_RELATIVE;
170  case ELF::EM_LANAI:
171  break;
172  case ELF::EM_PPC:
173  break;
174  case ELF::EM_PPC64:
175  return ELF::R_PPC64_RELATIVE;
176  case ELF::EM_RISCV:
177  return ELF::R_RISCV_RELATIVE;
178  case ELF::EM_S390:
179  return ELF::R_390_RELATIVE;
180  case ELF::EM_SPARC:
181  case ELF::EM_SPARC32PLUS:
182  case ELF::EM_SPARCV9:
183  return ELF::R_SPARC_RELATIVE;
184  case ELF::EM_AMDGPU:
185  break;
186  case ELF::EM_BPF:
187  break;
188  default:
189  break;
190  }
191  return 0;
192 }
193 
195  switch (Machine) {
196  case ELF::EM_ARM:
197  switch (Type) {
203  }
204  break;
205  case ELF::EM_HEXAGON:
206  switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
207  break;
208  case ELF::EM_X86_64:
209  switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
210  break;
211  case ELF::EM_MIPS:
212  case ELF::EM_MIPS_RS3_LE:
213  switch (Type) {
218  }
219  break;
220  default:
221  break;
222  }
223 
224  switch (Type) {
255  default:
256  return "Unknown";
257  }
258 }
259 
260 template <class ELFT>
263  // This function decodes the contents of an SHT_RELR packed relocation
264  // section.
265  //
266  // Proposal for adding SHT_RELR sections to generic-abi is here:
267  // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
268  //
269  // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
270  // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
271  //
272  // i.e. start with an address, followed by any number of bitmaps. The address
273  // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
274  // relocations each, at subsequent offsets following the last address entry.
275  //
276  // The bitmap entries must have 1 in the least significant bit. The assumption
277  // here is that an address cannot have 1 in lsb. Odd addresses are not
278  // supported.
279  //
280  // Excluding the least significant bit in the bitmap, each non-zero bit in
281  // the bitmap represents a relocation to be applied to a corresponding machine
282  // word that follows the base address word. The second least significant bit
283  // represents the machine word immediately following the initial address, and
284  // each bit that follows represents the next word, in linear order. As such,
285  // a single bitmap can encode up to 31 relocations in a 32-bit object, and
286  // 63 relocations in a 64-bit object.
287  //
288  // This encoding has a couple of interesting properties:
289  // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
290  // even means address, odd means bitmap.
291  // 2. Just a simple list of addresses is a valid encoding.
292 
293  Elf_Rela Rela;
294  Rela.r_info = 0;
295  Rela.r_addend = 0;
296  Rela.setType(getRelrRelocationType(), false);
297  std::vector<Elf_Rela> Relocs;
298 
299  // Word type: uint32_t for Elf32, and uint64_t for Elf64.
300  typedef typename ELFT::uint Word;
301 
302  // Word size in number of bytes.
303  const size_t WordSize = sizeof(Word);
304 
305  // Number of bits used for the relocation offsets bitmap.
306  // These many relative relocations can be encoded in a single entry.
307  const size_t NBits = 8*WordSize - 1;
308 
309  Word Base = 0;
310  for (const Elf_Relr &R : relrs) {
311  Word Entry = R;
312  if ((Entry&1) == 0) {
313  // Even entry: encodes the offset for next relocation.
314  Rela.r_offset = Entry;
315  Relocs.push_back(Rela);
316  // Set base offset for subsequent bitmap entries.
317  Base = Entry + WordSize;
318  continue;
319  }
320 
321  // Odd entry: encodes bitmap for relocations starting at base.
322  Word Offset = Base;
323  while (Entry != 0) {
324  Entry >>= 1;
325  if ((Entry&1) != 0) {
326  Rela.r_offset = Offset;
327  Relocs.push_back(Rela);
328  }
329  Offset += WordSize;
330  }
331 
332  // Advance base offset by NBits words.
333  Base += NBits * WordSize;
334  }
335 
336  return Relocs;
337 }
338 
339 template <class ELFT>
342  // This function reads relocations in Android's packed relocation format,
343  // which is based on SLEB128 and delta encoding.
344  Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
345  if (!ContentsOrErr)
346  return ContentsOrErr.takeError();
347  const uint8_t *Cur = ContentsOrErr->begin();
348  const uint8_t *End = ContentsOrErr->end();
349  if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
350  Cur[2] != 'S' || Cur[3] != '2')
351  return createError("invalid packed relocation header");
352  Cur += 4;
353 
354  const char *ErrStr = nullptr;
355  auto ReadSLEB = [&]() -> int64_t {
356  if (ErrStr)
357  return 0;
358  unsigned Len;
359  int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
360  Cur += Len;
361  return Result;
362  };
363 
364  uint64_t NumRelocs = ReadSLEB();
365  uint64_t Offset = ReadSLEB();
366  uint64_t Addend = 0;
367 
368  if (ErrStr)
369  return createError(ErrStr);
370 
371  std::vector<Elf_Rela> Relocs;
372  Relocs.reserve(NumRelocs);
373  while (NumRelocs) {
374  uint64_t NumRelocsInGroup = ReadSLEB();
375  if (NumRelocsInGroup > NumRelocs)
376  return createError("relocation group unexpectedly large");
377  NumRelocs -= NumRelocsInGroup;
378 
379  uint64_t GroupFlags = ReadSLEB();
380  bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
381  bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
382  bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
383  bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
384 
385  uint64_t GroupOffsetDelta;
386  if (GroupedByOffsetDelta)
387  GroupOffsetDelta = ReadSLEB();
388 
389  uint64_t GroupRInfo;
390  if (GroupedByInfo)
391  GroupRInfo = ReadSLEB();
392 
393  if (GroupedByAddend && GroupHasAddend)
394  Addend += ReadSLEB();
395 
396  for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
397  Elf_Rela R;
398  Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
399  R.r_offset = Offset;
400  R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
401 
402  if (GroupHasAddend) {
403  if (!GroupedByAddend)
404  Addend += ReadSLEB();
405  R.r_addend = Addend;
406  } else {
407  R.r_addend = 0;
408  }
409 
410  Relocs.push_back(R);
411 
412  if (ErrStr)
413  return createError(ErrStr);
414  }
415 
416  if (ErrStr)
417  return createError(ErrStr);
418  }
419 
420  return Relocs;
421 }
422 
423 template class llvm::object::ELFFile<ELF32LE>;
424 template class llvm::object::ELFFile<ELF32BE>;
425 template class llvm::object::ELFFile<ELF64LE>;
426 template class llvm::object::ELFFile<ELF64BE>;
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
uint32_t getELFRelrRelocationType(uint32_t Machine)
Definition: ELF.cpp:150
static Error createError(StringRef Err)
Definition: ELF.h:48
Expected< std::vector< Elf_Rela > > decode_relrs(Elf_Relr_Range relrs) const
Definition: ELF.cpp:262
Error takeError()
Take ownership of the stored error.
Definition: Error.h:545
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:162
support::ulittle32_t Word
Definition: IRSymtab.h:51
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
typename ELFT::Relr Elf_Relr
Definition: ELF.h:64
COFF::MachineTypes Machine
Definition: COFFYAML.cpp:363
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
typename ELFT::RelrRange Elf_Relr_Range
Definition: ELF.h:80
typename ELFT::Rela Elf_Rela
Definition: ELF.h:63
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:23
#define STRINGIFY_ENUM_CASE(ns, name)
Definition: ELF.cpp:17
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr *Sec) const
Definition: ELF.cpp:341
#define I(x, y, z)
Definition: MD5.cpp:58
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
typename ELFT::Shdr Elf_Shdr
Definition: ELF.h:58