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_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  break;
142  case ELF::EM_BPF:
143  switch (Type) {
144 #include "llvm/BinaryFormat/ELFRelocs/BPF.def"
145  default:
146  break;
147  }
148  break;
149  default:
150  break;
151  }
152  return "Unknown";
153 }
154 
155 #undef ELF_RELOC
156 
158  switch (Machine) {
159  case ELF::EM_ARM:
160  switch (Type) {
166  }
167  break;
168  case ELF::EM_HEXAGON:
169  switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
170  break;
171  case ELF::EM_X86_64:
172  switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
173  break;
174  case ELF::EM_MIPS:
175  case ELF::EM_MIPS_RS3_LE:
176  switch (Type) {
181  }
182  break;
183  default:
184  break;
185  }
186 
187  switch (Type) {
213  default:
214  return "Unknown";
215  }
216 }
217 
218 template <class ELFT>
221  // This function reads relocations in Android's packed relocation format,
222  // which is based on SLEB128 and delta encoding.
223  Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
224  if (!ContentsOrErr)
225  return ContentsOrErr.takeError();
226  const uint8_t *Cur = ContentsOrErr->begin();
227  const uint8_t *End = ContentsOrErr->end();
228  if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
229  Cur[2] != 'S' || Cur[3] != '2')
230  return createError("invalid packed relocation header");
231  Cur += 4;
232 
233  const char *ErrStr = nullptr;
234  auto ReadSLEB = [&]() -> int64_t {
235  if (ErrStr)
236  return 0;
237  unsigned Len;
238  int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
239  Cur += Len;
240  return Result;
241  };
242 
243  uint64_t NumRelocs = ReadSLEB();
244  uint64_t Offset = ReadSLEB();
245  uint64_t Addend = 0;
246 
247  if (ErrStr)
248  return createError(ErrStr);
249 
250  std::vector<Elf_Rela> Relocs;
251  Relocs.reserve(NumRelocs);
252  while (NumRelocs) {
253  uint64_t NumRelocsInGroup = ReadSLEB();
254  if (NumRelocsInGroup > NumRelocs)
255  return createError("relocation group unexpectedly large");
256  NumRelocs -= NumRelocsInGroup;
257 
258  uint64_t GroupFlags = ReadSLEB();
259  bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
260  bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
261  bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
262  bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
263 
264  uint64_t GroupOffsetDelta;
265  if (GroupedByOffsetDelta)
266  GroupOffsetDelta = ReadSLEB();
267 
268  uint64_t GroupRInfo;
269  if (GroupedByInfo)
270  GroupRInfo = ReadSLEB();
271 
272  if (GroupedByAddend && GroupHasAddend)
273  Addend += ReadSLEB();
274 
275  for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
276  Elf_Rela R;
277  Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
278  R.r_offset = Offset;
279  R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
280 
281  if (GroupHasAddend) {
282  if (!GroupedByAddend)
283  Addend += ReadSLEB();
284  R.r_addend = Addend;
285  } else {
286  R.r_addend = 0;
287  }
288 
289  Relocs.push_back(R);
290 
291  if (ErrStr)
292  return createError(ErrStr);
293  }
294 
295  if (ErrStr)
296  return createError(ErrStr);
297  }
298 
299  return Relocs;
300 }
301 
302 template class llvm::object::ELFFile<ELF32LE>;
303 template class llvm::object::ELFFile<ELF32BE>;
304 template class llvm::object::ELFFile<ELF64LE>;
305 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)
static Error createError(StringRef Err)
Definition: ELF.h:47
Error takeError()
Take ownership of the stored error.
Definition: Error.h:537
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
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
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
static const unsigned End
typename ELFT::Rela Elf_Rela
Definition: ELF.h:62
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:220
#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:57