LLVM  6.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  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 
157  switch (Machine) {
158  case ELF::EM_ARM:
159  switch (Type) {
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) {
180  }
181  break;
182  default:
183  break;
184  }
185 
186  switch (Type) {
212  default:
213  return "Unknown";
214  }
215 }
216 
217 template <class ELFT>
220  // This function reads relocations in Android's packed relocation format,
221  // which is based on SLEB128 and delta encoding.
222  Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
223  if (!ContentsOrErr)
224  return ContentsOrErr.takeError();
225  const uint8_t *Cur = ContentsOrErr->begin();
226  const uint8_t *End = ContentsOrErr->end();
227  if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
228  Cur[2] != 'S' || Cur[3] != '2')
229  return createError("invalid packed relocation header");
230  Cur += 4;
231 
232  const char *ErrStr = nullptr;
233  auto ReadSLEB = [&]() -> int64_t {
234  if (ErrStr)
235  return 0;
236  unsigned Len;
237  int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
238  Cur += Len;
239  return Result;
240  };
241 
242  uint64_t NumRelocs = ReadSLEB();
243  uint64_t Offset = ReadSLEB();
244  uint64_t Addend = 0;
245 
246  if (ErrStr)
247  return createError(ErrStr);
248 
249  std::vector<Elf_Rela> Relocs;
250  Relocs.reserve(NumRelocs);
251  while (NumRelocs) {
252  uint64_t NumRelocsInGroup = ReadSLEB();
253  if (NumRelocsInGroup > NumRelocs)
254  return createError("relocation group unexpectedly large");
255  NumRelocs -= NumRelocsInGroup;
256 
257  uint64_t GroupFlags = ReadSLEB();
258  bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
259  bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
260  bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
261  bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
262 
263  uint64_t GroupOffsetDelta;
264  if (GroupedByOffsetDelta)
265  GroupOffsetDelta = ReadSLEB();
266 
267  uint64_t GroupRInfo;
268  if (GroupedByInfo)
269  GroupRInfo = ReadSLEB();
270 
271  if (GroupedByAddend && GroupHasAddend)
272  Addend += ReadSLEB();
273 
274  for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
275  Elf_Rela R;
276  Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
277  R.r_offset = Offset;
278  R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
279 
280  if (GroupHasAddend) {
281  if (!GroupedByAddend)
282  Addend += ReadSLEB();
283  R.r_addend = Addend;
284  } else {
285  R.r_addend = 0;
286  }
287 
288  Relocs.push_back(R);
289 
290  if (ErrStr)
291  return createError(ErrStr);
292  }
293 
294  if (ErrStr)
295  return createError(ErrStr);
296  }
297 
298  return Relocs;
299 }
300 
301 template class llvm::object::ELFFile<ELF32LE>;
302 template class llvm::object::ELFFile<ELF32BE>;
303 template class llvm::object::ELFFile<ELF64LE>;
304 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:157
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:219
#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