1234285Sdim//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim//
10234285Sdim// This file declares the ELFObjectFile template class.
11234285Sdim//
12234285Sdim//===----------------------------------------------------------------------===//
13234285Sdim
14234285Sdim#ifndef LLVM_OBJECT_ELF_H
15234285Sdim#define LLVM_OBJECT_ELF_H
16234285Sdim
17249423Sdim#include "llvm/ADT/DenseMap.h"
18249423Sdim#include "llvm/ADT/PointerIntPair.h"
19234285Sdim#include "llvm/ADT/SmallVector.h"
20234285Sdim#include "llvm/ADT/StringSwitch.h"
21234285Sdim#include "llvm/ADT/Triple.h"
22234285Sdim#include "llvm/Object/ObjectFile.h"
23234285Sdim#include "llvm/Support/Casting.h"
24234285Sdim#include "llvm/Support/ELF.h"
25234285Sdim#include "llvm/Support/Endian.h"
26234285Sdim#include "llvm/Support/ErrorHandling.h"
27234285Sdim#include "llvm/Support/MemoryBuffer.h"
28234285Sdim#include "llvm/Support/raw_ostream.h"
29234285Sdim#include <algorithm>
30234285Sdim#include <limits>
31234285Sdim#include <utility>
32234285Sdim
33234285Sdimnamespace llvm {
34234285Sdimnamespace object {
35234285Sdim
36249423Sdimusing support::endianness;
37249423Sdim
38249423Sdimtemplate<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
39249423Sdimstruct ELFType {
40249423Sdim  static const endianness TargetEndianness = target_endianness;
41249423Sdim  static const std::size_t MaxAlignment = max_alignment;
42249423Sdim  static const bool Is64Bits = is64Bits;
43249423Sdim};
44249423Sdim
45249423Sdimtemplate<typename T, int max_align>
46249423Sdimstruct MaximumAlignment {
47249423Sdim  enum {value = AlignOf<T>::Alignment > max_align ? max_align
48249423Sdim                                                  : AlignOf<T>::Alignment};
49249423Sdim};
50249423Sdim
51234982Sdim// Subclasses of ELFObjectFile may need this for template instantiation
52234982Sdiminline std::pair<unsigned char, unsigned char>
53234982SdimgetElfArchType(MemoryBuffer *Object) {
54234982Sdim  if (Object->getBufferSize() < ELF::EI_NIDENT)
55234982Sdim    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
56234982Sdim  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
57234982Sdim                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
58234982Sdim}
59234982Sdim
60234285Sdim// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
61249423Sdimtemplate<endianness target_endianness, std::size_t max_alignment>
62234285Sdimstruct ELFDataTypeTypedefHelperCommon {
63234285Sdim  typedef support::detail::packed_endian_specific_integral
64249423Sdim    <uint16_t, target_endianness,
65249423Sdim     MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half;
66234285Sdim  typedef support::detail::packed_endian_specific_integral
67249423Sdim    <uint32_t, target_endianness,
68249423Sdim     MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word;
69234285Sdim  typedef support::detail::packed_endian_specific_integral
70249423Sdim    <int32_t, target_endianness,
71249423Sdim     MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword;
72234285Sdim  typedef support::detail::packed_endian_specific_integral
73249423Sdim    <uint64_t, target_endianness,
74249423Sdim     MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword;
75234285Sdim  typedef support::detail::packed_endian_specific_integral
76249423Sdim    <int64_t, target_endianness,
77249423Sdim     MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
78234285Sdim};
79234285Sdim
80249423Sdimtemplate<class ELFT>
81234285Sdimstruct ELFDataTypeTypedefHelper;
82234285Sdim
83234285Sdim/// ELF 32bit types.
84251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
85251662Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> >
86249423Sdim  : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
87234285Sdim  typedef uint32_t value_type;
88234285Sdim  typedef support::detail::packed_endian_specific_integral
89249423Sdim    <value_type, TargetEndianness,
90249423Sdim     MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
91234285Sdim  typedef support::detail::packed_endian_specific_integral
92249423Sdim    <value_type, TargetEndianness,
93249423Sdim     MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
94234285Sdim};
95234285Sdim
96234285Sdim/// ELF 64bit types.
97251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
98251662Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> >
99249423Sdim  : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
100234285Sdim  typedef uint64_t value_type;
101234285Sdim  typedef support::detail::packed_endian_specific_integral
102249423Sdim    <value_type, TargetEndianness,
103249423Sdim     MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
104234285Sdim  typedef support::detail::packed_endian_specific_integral
105249423Sdim    <value_type, TargetEndianness,
106249423Sdim     MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
107234285Sdim};
108234285Sdim
109234285Sdim// I really don't like doing this, but the alternative is copypasta.
110251662Sdim#define LLVM_ELF_IMPORT_TYPES(E, M, W)                                         \
111251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Addr Elf_Addr; \
112251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Off Elf_Off;   \
113251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Half Elf_Half; \
114251662Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Word Elf_Word; \
115251662Sdimtypedef typename                                                               \
116251662Sdim  ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sword Elf_Sword;              \
117251662Sdimtypedef typename                                                               \
118251662Sdim  ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Xword Elf_Xword;              \
119251662Sdimtypedef typename                                                               \
120251662Sdim  ELFDataTypeTypedefHelper<ELFType<E,M,W> >::Elf_Sxword Elf_Sxword;
121234285Sdim
122251662Sdim#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)                                       \
123251662Sdim  LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment,            \
124251662Sdim  ELFT::Is64Bits)
125249423Sdim
126251662Sdim// Section header.
127249423Sdimtemplate<class ELFT>
128234285Sdimstruct Elf_Shdr_Base;
129234285Sdim
130251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
131251662Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > {
132251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
133234285Sdim  Elf_Word sh_name;     // Section name (index into string table)
134234285Sdim  Elf_Word sh_type;     // Section type (SHT_*)
135234285Sdim  Elf_Word sh_flags;    // Section flags (SHF_*)
136234285Sdim  Elf_Addr sh_addr;     // Address where section is to be loaded
137234285Sdim  Elf_Off  sh_offset;   // File offset of section data, in bytes
138234285Sdim  Elf_Word sh_size;     // Size of section, in bytes
139234285Sdim  Elf_Word sh_link;     // Section type-specific header table index link
140234285Sdim  Elf_Word sh_info;     // Section type-specific extra information
141234285Sdim  Elf_Word sh_addralign;// Section address alignment
142234285Sdim  Elf_Word sh_entsize;  // Size of records contained within the section
143234285Sdim};
144234285Sdim
145251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
146251662Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > {
147251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
148234285Sdim  Elf_Word  sh_name;     // Section name (index into string table)
149234285Sdim  Elf_Word  sh_type;     // Section type (SHT_*)
150234285Sdim  Elf_Xword sh_flags;    // Section flags (SHF_*)
151234285Sdim  Elf_Addr  sh_addr;     // Address where section is to be loaded
152234285Sdim  Elf_Off   sh_offset;   // File offset of section data, in bytes
153234285Sdim  Elf_Xword sh_size;     // Size of section, in bytes
154234285Sdim  Elf_Word  sh_link;     // Section type-specific header table index link
155234285Sdim  Elf_Word  sh_info;     // Section type-specific extra information
156234285Sdim  Elf_Xword sh_addralign;// Section address alignment
157234285Sdim  Elf_Xword sh_entsize;  // Size of records contained within the section
158234285Sdim};
159234285Sdim
160249423Sdimtemplate<class ELFT>
161249423Sdimstruct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
162249423Sdim  using Elf_Shdr_Base<ELFT>::sh_entsize;
163249423Sdim  using Elf_Shdr_Base<ELFT>::sh_size;
164234285Sdim
165234285Sdim  /// @brief Get the number of entities this section contains if it has any.
166234285Sdim  unsigned getEntityCount() const {
167234285Sdim    if (sh_entsize == 0)
168234285Sdim      return 0;
169234285Sdim    return sh_size / sh_entsize;
170234285Sdim  }
171234285Sdim};
172234285Sdim
173249423Sdimtemplate<class ELFT>
174234285Sdimstruct Elf_Sym_Base;
175234285Sdim
176251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
177251662Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > {
178251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
179234285Sdim  Elf_Word      st_name;  // Symbol name (index into string table)
180234285Sdim  Elf_Addr      st_value; // Value or address associated with the symbol
181234285Sdim  Elf_Word      st_size;  // Size of the symbol
182234285Sdim  unsigned char st_info;  // Symbol's type and binding attributes
183234285Sdim  unsigned char st_other; // Must be zero; reserved
184234285Sdim  Elf_Half      st_shndx; // Which section (header table index) it's defined in
185234285Sdim};
186234285Sdim
187251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
188251662Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > {
189251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
190234285Sdim  Elf_Word      st_name;  // Symbol name (index into string table)
191234285Sdim  unsigned char st_info;  // Symbol's type and binding attributes
192234285Sdim  unsigned char st_other; // Must be zero; reserved
193234285Sdim  Elf_Half      st_shndx; // Which section (header table index) it's defined in
194234285Sdim  Elf_Addr      st_value; // Value or address associated with the symbol
195234285Sdim  Elf_Xword     st_size;  // Size of the symbol
196234285Sdim};
197234285Sdim
198249423Sdimtemplate<class ELFT>
199249423Sdimstruct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
200249423Sdim  using Elf_Sym_Base<ELFT>::st_info;
201234285Sdim
202234285Sdim  // These accessors and mutators correspond to the ELF32_ST_BIND,
203234285Sdim  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
204234285Sdim  unsigned char getBinding() const { return st_info >> 4; }
205234285Sdim  unsigned char getType() const { return st_info & 0x0f; }
206234285Sdim  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
207234285Sdim  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
208234285Sdim  void setBindingAndType(unsigned char b, unsigned char t) {
209234285Sdim    st_info = (b << 4) + (t & 0x0f);
210234285Sdim  }
211234285Sdim};
212234285Sdim
213234285Sdim/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
214234285Sdim/// (.gnu.version). This structure is identical for ELF32 and ELF64.
215249423Sdimtemplate<class ELFT>
216234285Sdimstruct Elf_Versym_Impl {
217251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
218234285Sdim  Elf_Half vs_index;   // Version index with flags (e.g. VERSYM_HIDDEN)
219234285Sdim};
220234285Sdim
221249423Sdimtemplate<class ELFT>
222234285Sdimstruct Elf_Verdaux_Impl;
223234285Sdim
224234285Sdim/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
225234285Sdim/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
226249423Sdimtemplate<class ELFT>
227234285Sdimstruct Elf_Verdef_Impl {
228251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
229249423Sdim  typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
230234285Sdim  Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
231234285Sdim  Elf_Half vd_flags;   // Bitwise flags (VER_DEF_*)
232234285Sdim  Elf_Half vd_ndx;     // Version index, used in .gnu.version entries
233234285Sdim  Elf_Half vd_cnt;     // Number of Verdaux entries
234234285Sdim  Elf_Word vd_hash;    // Hash of name
235234285Sdim  Elf_Word vd_aux;     // Offset to the first Verdaux entry (in bytes)
236234285Sdim  Elf_Word vd_next;    // Offset to the next Verdef entry (in bytes)
237234285Sdim
238234285Sdim  /// Get the first Verdaux entry for this Verdef.
239234285Sdim  const Elf_Verdaux *getAux() const {
240234285Sdim    return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux);
241234285Sdim  }
242234285Sdim};
243234285Sdim
244239462Sdim/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
245234285Sdim/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
246249423Sdimtemplate<class ELFT>
247234285Sdimstruct Elf_Verdaux_Impl {
248251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
249234285Sdim  Elf_Word vda_name; // Version name (offset in string table)
250234285Sdim  Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
251234285Sdim};
252234285Sdim
253234285Sdim/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
254234285Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
255249423Sdimtemplate<class ELFT>
256234285Sdimstruct Elf_Verneed_Impl {
257251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
258234285Sdim  Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
259234285Sdim  Elf_Half vn_cnt;     // Number of associated Vernaux entries
260234285Sdim  Elf_Word vn_file;    // Library name (string table offset)
261234285Sdim  Elf_Word vn_aux;     // Offset to first Vernaux entry (in bytes)
262234285Sdim  Elf_Word vn_next;    // Offset to next Verneed entry (in bytes)
263234285Sdim};
264234285Sdim
265234285Sdim/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
266234285Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
267249423Sdimtemplate<class ELFT>
268234285Sdimstruct Elf_Vernaux_Impl {
269251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
270234285Sdim  Elf_Word vna_hash;  // Hash of dependency name
271234285Sdim  Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
272234285Sdim  Elf_Half vna_other; // Version index, used in .gnu.version entries
273234285Sdim  Elf_Word vna_name;  // Dependency name
274234285Sdim  Elf_Word vna_next;  // Offset to next Vernaux entry (in bytes)
275234285Sdim};
276234285Sdim
277234285Sdim/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
278234285Sdim///               table section (.dynamic) look like.
279249423Sdimtemplate<class ELFT>
280234285Sdimstruct Elf_Dyn_Base;
281234285Sdim
282251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
283251662Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > {
284251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
285234285Sdim  Elf_Sword d_tag;
286234285Sdim  union {
287234285Sdim    Elf_Word d_val;
288234285Sdim    Elf_Addr d_ptr;
289234285Sdim  } d_un;
290234285Sdim};
291234285Sdim
292251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
293251662Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > {
294251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
295234285Sdim  Elf_Sxword d_tag;
296234285Sdim  union {
297234285Sdim    Elf_Xword d_val;
298234285Sdim    Elf_Addr d_ptr;
299234285Sdim  } d_un;
300234285Sdim};
301234285Sdim
302234285Sdim/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
303249423Sdimtemplate<class ELFT>
304249423Sdimstruct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
305249423Sdim  using Elf_Dyn_Base<ELFT>::d_tag;
306249423Sdim  using Elf_Dyn_Base<ELFT>::d_un;
307234285Sdim  int64_t getTag() const { return d_tag; }
308234285Sdim  uint64_t getVal() const { return d_un.d_val; }
309234285Sdim  uint64_t getPtr() const { return d_un.ptr; }
310234285Sdim};
311234285Sdim
312234285Sdim// Elf_Rel: Elf Relocation
313249423Sdimtemplate<class ELFT, bool isRela>
314234285Sdimstruct Elf_Rel_Base;
315234285Sdim
316251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
317251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> {
318251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
319234285Sdim  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
320234285Sdim  Elf_Word      r_info;  // Symbol table index and type of relocation to apply
321249423Sdim
322249423Sdim  uint32_t getRInfo(bool isMips64EL) const {
323249423Sdim    assert(!isMips64EL);
324249423Sdim    return r_info;
325249423Sdim  }
326249423Sdim  void setRInfo(uint32_t R) {
327249423Sdim    r_info = R;
328249423Sdim  }
329234285Sdim};
330234285Sdim
331251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
332251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> {
333251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
334234285Sdim  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
335234285Sdim  Elf_Xword     r_info;   // Symbol table index and type of relocation to apply
336249423Sdim
337249423Sdim  uint64_t getRInfo(bool isMips64EL) const {
338249423Sdim    uint64_t t = r_info;
339249423Sdim    if (!isMips64EL)
340249423Sdim      return t;
341249423Sdim    // Mip64 little endian has a "special" encoding of r_info. Instead of one
342249423Sdim    // 64 bit little endian number, it is a little ending 32 bit number followed
343249423Sdim    // by a 32 bit big endian number.
344249423Sdim    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
345249423Sdim      ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
346249423Sdim    return r_info;
347249423Sdim  }
348249423Sdim  void setRInfo(uint64_t R) {
349249423Sdim    // FIXME: Add mips64el support.
350249423Sdim    r_info = R;
351249423Sdim  }
352234285Sdim};
353234285Sdim
354251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
355251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> {
356251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
357234285Sdim  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
358234285Sdim  Elf_Word      r_info;   // Symbol table index and type of relocation to apply
359234285Sdim  Elf_Sword     r_addend; // Compute value for relocatable field by adding this
360249423Sdim
361249423Sdim  uint32_t getRInfo(bool isMips64EL) const {
362249423Sdim    assert(!isMips64EL);
363249423Sdim    return r_info;
364249423Sdim  }
365249423Sdim  void setRInfo(uint32_t R) {
366249423Sdim    r_info = R;
367249423Sdim  }
368234285Sdim};
369234285Sdim
370251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
371251662Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> {
372251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
373234285Sdim  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
374234285Sdim  Elf_Xword     r_info;   // Symbol table index and type of relocation to apply
375234285Sdim  Elf_Sxword    r_addend; // Compute value for relocatable field by adding this.
376249423Sdim
377249423Sdim  uint64_t getRInfo(bool isMips64EL) const {
378249423Sdim    // Mip64 little endian has a "special" encoding of r_info. Instead of one
379249423Sdim    // 64 bit little endian number, it is a little ending 32 bit number followed
380249423Sdim    // by a 32 bit big endian number.
381249423Sdim    uint64_t t = r_info;
382249423Sdim    if (!isMips64EL)
383249423Sdim      return t;
384249423Sdim    return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
385249423Sdim      ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
386249423Sdim  }
387249423Sdim  void setRInfo(uint64_t R) {
388249423Sdim    // FIXME: Add mips64el support.
389249423Sdim    r_info = R;
390249423Sdim  }
391234285Sdim};
392234285Sdim
393249423Sdimtemplate<class ELFT, bool isRela>
394234285Sdimstruct Elf_Rel_Impl;
395234285Sdim
396251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
397251662Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, isRela>
398251662Sdim       : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, isRela> {
399251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
400234285Sdim
401234285Sdim  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
402234285Sdim  // and ELF64_R_INFO macros defined in the ELF specification:
403249423Sdim  uint32_t getSymbol(bool isMips64EL) const {
404249423Sdim    return (uint32_t) (this->getRInfo(isMips64EL) >> 32);
405234285Sdim  }
406249423Sdim  uint32_t getType(bool isMips64EL) const {
407249423Sdim    return (uint32_t) (this->getRInfo(isMips64EL) & 0xffffffffL);
408234285Sdim  }
409249423Sdim  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
410249423Sdim  void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); }
411249423Sdim  void setSymbolAndType(uint32_t s, uint32_t t) {
412249423Sdim    this->setRInfo(((uint64_t)s << 32) + (t&0xffffffffL));
413249423Sdim  }
414234285Sdim};
415234285Sdim
416251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
417251662Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, isRela>
418251662Sdim       : Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, isRela> {
419251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
420234285Sdim
421234285Sdim  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
422234285Sdim  // and ELF32_R_INFO macros defined in the ELF specification:
423249423Sdim  uint32_t getSymbol(bool isMips64EL) const {
424249423Sdim    return this->getRInfo(isMips64EL) >> 8;
425249423Sdim  }
426249423Sdim  unsigned char getType(bool isMips64EL) const {
427249423Sdim    return (unsigned char) (this->getRInfo(isMips64EL) & 0x0ff);
428249423Sdim  }
429234285Sdim  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
430234285Sdim  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
431234285Sdim  void setSymbolAndType(uint32_t s, unsigned char t) {
432249423Sdim    this->setRInfo((s << 8) + t);
433234285Sdim  }
434234285Sdim};
435234285Sdim
436249423Sdimtemplate<class ELFT>
437243830Sdimstruct Elf_Ehdr_Impl {
438251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
439243830Sdim  unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
440243830Sdim  Elf_Half e_type;     // Type of file (see ET_*)
441243830Sdim  Elf_Half e_machine;  // Required architecture for this file (see EM_*)
442243830Sdim  Elf_Word e_version;  // Must be equal to 1
443243830Sdim  Elf_Addr e_entry;    // Address to jump to in order to start program
444243830Sdim  Elf_Off  e_phoff;    // Program header table's file offset, in bytes
445243830Sdim  Elf_Off  e_shoff;    // Section header table's file offset, in bytes
446243830Sdim  Elf_Word e_flags;    // Processor-specific flags
447243830Sdim  Elf_Half e_ehsize;   // Size of ELF header, in bytes
448243830Sdim  Elf_Half e_phentsize;// Size of an entry in the program header table
449243830Sdim  Elf_Half e_phnum;    // Number of entries in the program header table
450243830Sdim  Elf_Half e_shentsize;// Size of an entry in the section header table
451243830Sdim  Elf_Half e_shnum;    // Number of entries in the section header table
452243830Sdim  Elf_Half e_shstrndx; // Section header table index of section name
453243830Sdim                                 // string table
454243830Sdim  bool checkMagic() const {
455243830Sdim    return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
456243830Sdim  }
457243830Sdim   unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
458243830Sdim   unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
459243830Sdim};
460234285Sdim
461249423Sdimtemplate<class ELFT>
462249423Sdimstruct Elf_Phdr_Impl;
463243830Sdim
464251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
465251662Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > {
466251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false)
467243830Sdim  Elf_Word p_type;   // Type of segment
468243830Sdim  Elf_Off  p_offset; // FileOffset where segment is located, in bytes
469249423Sdim  Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
470243830Sdim  Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
471243830Sdim  Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
472243830Sdim  Elf_Word p_memsz;  // Num. of bytes in mem image of segment (may be zero)
473243830Sdim  Elf_Word p_flags;  // Segment flags
474243830Sdim  Elf_Word p_align;  // Segment alignment constraint
475243830Sdim};
476243830Sdim
477251662Sdimtemplate<endianness TargetEndianness, std::size_t MaxAlign>
478251662Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > {
479251662Sdim  LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true)
480243830Sdim  Elf_Word p_type;   // Type of segment
481243830Sdim  Elf_Word p_flags;  // Segment flags
482243830Sdim  Elf_Off  p_offset; // FileOffset where segment is located, in bytes
483249423Sdim  Elf_Addr p_vaddr;  // Virtual Address of beginning of segment
484243830Sdim  Elf_Addr p_paddr;  // Physical address of beginning of segment (OS-specific)
485249423Sdim  Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
486249423Sdim  Elf_Xword p_memsz;  // Num. of bytes in mem image of segment (may be zero)
487249423Sdim  Elf_Xword p_align;  // Segment alignment constraint
488243830Sdim};
489243830Sdim
490249423Sdimtemplate<class ELFT>
491234285Sdimclass ELFObjectFile : public ObjectFile {
492251662Sdim  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
493234285Sdim
494243830Sdimpublic:
495249423Sdim  /// \brief Iterate over constant sized entities.
496249423Sdim  template<class EntT>
497249423Sdim  class ELFEntityIterator {
498243830Sdim  public:
499249423Sdim    typedef ptrdiff_t difference_type;
500249423Sdim    typedef EntT value_type;
501249423Sdim    typedef std::random_access_iterator_tag iterator_category;
502243830Sdim    typedef value_type &reference;
503243830Sdim    typedef value_type *pointer;
504243830Sdim
505243830Sdim    /// \brief Default construct iterator.
506249423Sdim    ELFEntityIterator() : EntitySize(0), Current(0) {}
507249423Sdim    ELFEntityIterator(uint64_t EntSize, const char *Start)
508249423Sdim      : EntitySize(EntSize)
509243830Sdim      , Current(Start) {}
510243830Sdim
511243830Sdim    reference operator *() {
512243830Sdim      assert(Current && "Attempted to dereference an invalid iterator!");
513249423Sdim      return *reinterpret_cast<pointer>(Current);
514243830Sdim    }
515243830Sdim
516243830Sdim    pointer operator ->() {
517243830Sdim      assert(Current && "Attempted to dereference an invalid iterator!");
518249423Sdim      return reinterpret_cast<pointer>(Current);
519243830Sdim    }
520243830Sdim
521249423Sdim    bool operator ==(const ELFEntityIterator &Other) {
522249423Sdim      return Current == Other.Current;
523243830Sdim    }
524243830Sdim
525249423Sdim    bool operator !=(const ELFEntityIterator &Other) {
526243830Sdim      return !(*this == Other);
527243830Sdim    }
528243830Sdim
529249423Sdim    ELFEntityIterator &operator ++() {
530243830Sdim      assert(Current && "Attempted to increment an invalid iterator!");
531249423Sdim      Current += EntitySize;
532243830Sdim      return *this;
533243830Sdim    }
534243830Sdim
535249423Sdim    ELFEntityIterator operator ++(int) {
536249423Sdim      ELFEntityIterator Tmp = *this;
537243830Sdim      ++*this;
538243830Sdim      return Tmp;
539243830Sdim    }
540243830Sdim
541249423Sdim    ELFEntityIterator &operator =(const ELFEntityIterator &Other) {
542249423Sdim      EntitySize = Other.EntitySize;
543249423Sdim      Current = Other.Current;
544249423Sdim      return *this;
545249423Sdim    }
546249423Sdim
547249423Sdim    difference_type operator -(const ELFEntityIterator &Other) const {
548249423Sdim      assert(EntitySize == Other.EntitySize &&
549249423Sdim             "Subtracting iterators of different EntitiySize!");
550249423Sdim      return (Current - Other.Current) / EntitySize;
551249423Sdim    }
552249423Sdim
553249423Sdim    const char *get() const { return Current; }
554249423Sdim
555243830Sdim  private:
556249423Sdim    uint64_t EntitySize;
557243830Sdim    const char *Current;
558243830Sdim  };
559243830Sdim
560249423Sdim  typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
561249423Sdim  typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
562249423Sdim  typedef Elf_Sym_Impl<ELFT> Elf_Sym;
563249423Sdim  typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
564249423Sdim  typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
565249423Sdim  typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
566249423Sdim  typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
567249423Sdim  typedef Elf_Verdef_Impl<ELFT> Elf_Verdef;
568249423Sdim  typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
569249423Sdim  typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
570249423Sdim  typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
571249423Sdim  typedef Elf_Versym_Impl<ELFT> Elf_Versym;
572249423Sdim  typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_iterator;
573249423Sdim  typedef ELFEntityIterator<const Elf_Sym> Elf_Sym_iterator;
574249423Sdim  typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
575249423Sdim  typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
576249423Sdim
577249423Sdimprotected:
578249423Sdim  // This flag is used for classof, to distinguish ELFObjectFile from
579249423Sdim  // its subclass. If more subclasses will be created, this flag will
580249423Sdim  // have to become an enum.
581249423Sdim  bool isDyldELFObject;
582249423Sdim
583243830Sdimprivate:
584249423Sdim  typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
585249423Sdim  typedef DenseMap<unsigned, unsigned> IndexMap_t;
586249423Sdim  typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
587249423Sdim
588249423Sdim  const Elf_Ehdr *Header;
589249423Sdim  const Elf_Shdr *SectionHeaderTable;
590249423Sdim  const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
591249423Sdim  const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
592249423Sdim  const Elf_Shdr *dot_dynstr_sec;   // Dynamic symbol string table.
593249423Sdim
594249423Sdim  // SymbolTableSections[0] always points to the dynamic string table section
595249423Sdim  // header, or NULL if there is no dynamic string table.
596249423Sdim  Sections_t SymbolTableSections;
597249423Sdim  IndexMap_t SymbolTableSectionsIndexMap;
598249423Sdim  DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
599249423Sdim
600249423Sdim  const Elf_Shdr *dot_dynamic_sec;       // .dynamic
601249423Sdim  const Elf_Shdr *dot_gnu_version_sec;   // .gnu.version
602249423Sdim  const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
603249423Sdim  const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
604249423Sdim
605249423Sdim  // Pointer to SONAME entry in dynamic string table
606249423Sdim  // This is set the first time getLoadName is called.
607249423Sdim  mutable const char *dt_soname;
608249423Sdim
609249423Sdimprivate:
610251662Sdim  uint64_t getROffset(DataRefImpl Rel) const;
611251662Sdim
612234285Sdim  // Records for each version index the corresponding Verdef or Vernaux entry.
613234285Sdim  // This is filled the first time LoadVersionMap() is called.
614234285Sdim  class VersionMapEntry : public PointerIntPair<const void*, 1> {
615234285Sdim    public:
616234285Sdim    // If the integer is 0, this is an Elf_Verdef*.
617234285Sdim    // If the integer is 1, this is an Elf_Vernaux*.
618234285Sdim    VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { }
619234285Sdim    VersionMapEntry(const Elf_Verdef *verdef)
620234285Sdim        : PointerIntPair<const void*, 1>(verdef, 0) { }
621234285Sdim    VersionMapEntry(const Elf_Vernaux *vernaux)
622234285Sdim        : PointerIntPair<const void*, 1>(vernaux, 1) { }
623234285Sdim    bool isNull() const { return getPointer() == NULL; }
624234285Sdim    bool isVerdef() const { return !isNull() && getInt() == 0; }
625234285Sdim    bool isVernaux() const { return !isNull() && getInt() == 1; }
626234285Sdim    const Elf_Verdef *getVerdef() const {
627234285Sdim      return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL;
628234285Sdim    }
629234285Sdim    const Elf_Vernaux *getVernaux() const {
630234285Sdim      return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL;
631234285Sdim    }
632234285Sdim  };
633234285Sdim  mutable SmallVector<VersionMapEntry, 16> VersionMap;
634234285Sdim  void LoadVersionDefs(const Elf_Shdr *sec) const;
635234285Sdim  void LoadVersionNeeds(const Elf_Shdr *ec) const;
636234285Sdim  void LoadVersionMap() const;
637234285Sdim
638234285Sdim  /// @brief Map sections to an array of relocation sections that reference
639234285Sdim  ///        them sorted by section index.
640234285Sdim  RelocMap_t SectionRelocMap;
641234285Sdim
642234285Sdim  /// @brief Get the relocation section that contains \a Rel.
643234285Sdim  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
644234285Sdim    return getSection(Rel.w.b);
645234285Sdim  }
646234285Sdim
647249423Sdimpublic:
648234285Sdim  bool            isRelocationHasAddend(DataRefImpl Rel) const;
649234285Sdim  template<typename T>
650234285Sdim  const T        *getEntry(uint16_t Section, uint32_t Entry) const;
651234285Sdim  template<typename T>
652234285Sdim  const T        *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
653234285Sdim  const Elf_Shdr *getSection(DataRefImpl index) const;
654234285Sdim  const Elf_Shdr *getSection(uint32_t index) const;
655234285Sdim  const Elf_Rel  *getRel(DataRefImpl Rel) const;
656234285Sdim  const Elf_Rela *getRela(DataRefImpl Rela) const;
657234285Sdim  const char     *getString(uint32_t section, uint32_t offset) const;
658234285Sdim  const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
659234285Sdim  error_code      getSymbolVersion(const Elf_Shdr *section,
660234285Sdim                                   const Elf_Sym *Symb,
661234285Sdim                                   StringRef &Version,
662234285Sdim                                   bool &IsDefault) const;
663234285Sdim  void VerifyStrTab(const Elf_Shdr *sh) const;
664234285Sdim
665234285Sdimprotected:
666234285Sdim  const Elf_Sym  *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
667234285Sdim  void            validateSymbol(DataRefImpl Symb) const;
668251662Sdim  StringRef       getRelocationTypeName(uint32_t Type) const;
669234285Sdim
670234285Sdimpublic:
671239462Sdim  error_code      getSymbolName(const Elf_Shdr *section,
672239462Sdim                                const Elf_Sym *Symb,
673239462Sdim                                StringRef &Res) const;
674239462Sdim  error_code      getSectionName(const Elf_Shdr *section,
675239462Sdim                                 StringRef &Res) const;
676234285Sdim  const Elf_Dyn  *getDyn(DataRefImpl DynData) const;
677234285Sdim  error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
678234285Sdim                              bool &IsDefault) const;
679249423Sdim  uint64_t getSymbolIndex(const Elf_Sym *sym) const;
680234285Sdimprotected:
681234285Sdim  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
682234285Sdim  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
683234285Sdim  virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
684234285Sdim  virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
685251662Sdim  virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
686234285Sdim  virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
687234285Sdim  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
688234285Sdim  virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
689234285Sdim  virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
690234285Sdim  virtual error_code getSymbolSection(DataRefImpl Symb,
691234285Sdim                                      section_iterator &Res) const;
692243830Sdim  virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
693234285Sdim
694234285Sdim  virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
695234285Sdim  virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
696234285Sdim
697234285Sdim  virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
698234285Sdim  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
699234285Sdim  virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
700234285Sdim  virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
701234285Sdim  virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
702234285Sdim  virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
703234285Sdim  virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
704234285Sdim  virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
705234285Sdim  virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
706234285Sdim  virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
707234285Sdim                                                   bool &Res) const;
708234285Sdim  virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
709234285Sdim  virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
710243830Sdim  virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
711234285Sdim  virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
712234285Sdim                                           bool &Result) const;
713234285Sdim  virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
714234285Sdim  virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
715234285Sdim
716234285Sdim  virtual error_code getRelocationNext(DataRefImpl Rel,
717234285Sdim                                       RelocationRef &Res) const;
718234285Sdim  virtual error_code getRelocationAddress(DataRefImpl Rel,
719234285Sdim                                          uint64_t &Res) const;
720234285Sdim  virtual error_code getRelocationOffset(DataRefImpl Rel,
721234285Sdim                                         uint64_t &Res) const;
722234285Sdim  virtual error_code getRelocationSymbol(DataRefImpl Rel,
723234285Sdim                                         SymbolRef &Res) const;
724234285Sdim  virtual error_code getRelocationType(DataRefImpl Rel,
725234285Sdim                                       uint64_t &Res) const;
726234285Sdim  virtual error_code getRelocationTypeName(DataRefImpl Rel,
727234285Sdim                                           SmallVectorImpl<char> &Result) const;
728234285Sdim  virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
729234285Sdim                                                 int64_t &Res) const;
730234285Sdim  virtual error_code getRelocationValueString(DataRefImpl Rel,
731234285Sdim                                           SmallVectorImpl<char> &Result) const;
732234285Sdim
733234285Sdimpublic:
734234285Sdim  ELFObjectFile(MemoryBuffer *Object, error_code &ec);
735249423Sdim
736249423Sdim  bool isMips64EL() const {
737249423Sdim    return Header->e_machine == ELF::EM_MIPS &&
738249423Sdim      Header->getFileClass() == ELF::ELFCLASS64 &&
739249423Sdim      Header->getDataEncoding() == ELF::ELFDATA2LSB;
740249423Sdim  }
741249423Sdim
742234285Sdim  virtual symbol_iterator begin_symbols() const;
743234285Sdim  virtual symbol_iterator end_symbols() const;
744234285Sdim
745234285Sdim  virtual symbol_iterator begin_dynamic_symbols() const;
746234285Sdim  virtual symbol_iterator end_dynamic_symbols() const;
747234285Sdim
748234285Sdim  virtual section_iterator begin_sections() const;
749234285Sdim  virtual section_iterator end_sections() const;
750234285Sdim
751234285Sdim  virtual library_iterator begin_libraries_needed() const;
752234285Sdim  virtual library_iterator end_libraries_needed() const;
753234285Sdim
754249423Sdim  const Elf_Shdr *getDynamicSymbolTableSectionHeader() const {
755249423Sdim    return SymbolTableSections[0];
756249423Sdim  }
757234285Sdim
758249423Sdim  const Elf_Shdr *getDynamicStringTableSectionHeader() const {
759249423Sdim    return dot_dynstr_sec;
760249423Sdim  }
761243830Sdim
762249423Sdim  Elf_Dyn_iterator begin_dynamic_table() const;
763249423Sdim  /// \param NULLEnd use one past the first DT_NULL entry as the end instead of
764249423Sdim  /// the section size.
765249423Sdim  Elf_Dyn_iterator end_dynamic_table(bool NULLEnd = false) const;
766249423Sdim
767249423Sdim  Elf_Sym_iterator begin_elf_dynamic_symbols() const {
768249423Sdim    const Elf_Shdr *DynSymtab = SymbolTableSections[0];
769249423Sdim    if (DynSymtab)
770249423Sdim      return Elf_Sym_iterator(DynSymtab->sh_entsize,
771249423Sdim                              (const char *)base() + DynSymtab->sh_offset);
772249423Sdim    return Elf_Sym_iterator(0, 0);
773243830Sdim  }
774243830Sdim
775249423Sdim  Elf_Sym_iterator end_elf_dynamic_symbols() const {
776249423Sdim    const Elf_Shdr *DynSymtab = SymbolTableSections[0];
777249423Sdim    if (DynSymtab)
778249423Sdim      return Elf_Sym_iterator(DynSymtab->sh_entsize, (const char *)base() +
779249423Sdim                              DynSymtab->sh_offset + DynSymtab->sh_size);
780249423Sdim    return Elf_Sym_iterator(0, 0);
781249423Sdim  }
782249423Sdim
783249423Sdim  Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const {
784249423Sdim    return Elf_Rela_Iter(sec->sh_entsize,
785249423Sdim                         (const char *)(base() + sec->sh_offset));
786249423Sdim  }
787249423Sdim
788249423Sdim  Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const {
789249423Sdim    return Elf_Rela_Iter(sec->sh_entsize, (const char *)
790243830Sdim                         (base() + sec->sh_offset + sec->sh_size));
791243830Sdim  }
792243830Sdim
793249423Sdim  Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const {
794249423Sdim    return Elf_Rel_Iter(sec->sh_entsize,
795249423Sdim                        (const char *)(base() + sec->sh_offset));
796243830Sdim  }
797243830Sdim
798249423Sdim  Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const {
799249423Sdim    return Elf_Rel_Iter(sec->sh_entsize, (const char *)
800243830Sdim                        (base() + sec->sh_offset + sec->sh_size));
801243830Sdim  }
802243830Sdim
803249423Sdim  /// \brief Iterate over program header table.
804249423Sdim  typedef ELFEntityIterator<const Elf_Phdr> Elf_Phdr_Iter;
805249423Sdim
806249423Sdim  Elf_Phdr_Iter begin_program_headers() const {
807249423Sdim    return Elf_Phdr_Iter(Header->e_phentsize,
808249423Sdim                         (const char*)base() + Header->e_phoff);
809249423Sdim  }
810249423Sdim
811249423Sdim  Elf_Phdr_Iter end_program_headers() const {
812249423Sdim    return Elf_Phdr_Iter(Header->e_phentsize,
813249423Sdim                         (const char*)base() +
814249423Sdim                           Header->e_phoff +
815249423Sdim                           (Header->e_phnum * Header->e_phentsize));
816249423Sdim  }
817249423Sdim
818234285Sdim  virtual uint8_t getBytesInAddress() const;
819234285Sdim  virtual StringRef getFileFormatName() const;
820234285Sdim  virtual StringRef getObjectType() const { return "ELF"; }
821234285Sdim  virtual unsigned getArch() const;
822234285Sdim  virtual StringRef getLoadName() const;
823239462Sdim  virtual error_code getSectionContents(const Elf_Shdr *sec,
824239462Sdim                                        StringRef &Res) const;
825234285Sdim
826234285Sdim  uint64_t getNumSections() const;
827234285Sdim  uint64_t getStringTableIndex() const;
828234285Sdim  ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
829249423Sdim  const Elf_Ehdr *getElfHeader() const;
830234285Sdim  const Elf_Shdr *getSection(const Elf_Sym *symb) const;
831239462Sdim  const Elf_Shdr *getElfSection(section_iterator &It) const;
832239462Sdim  const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
833243830Sdim  const Elf_Sym *getElfSymbol(uint32_t index) const;
834234285Sdim
835234285Sdim  // Methods for type inquiry through isa, cast, and dyn_cast
836234285Sdim  bool isDyldType() const { return isDyldELFObject; }
837234285Sdim  static inline bool classof(const Binary *v) {
838249423Sdim    return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
839249423Sdim                                      ELFT::Is64Bits);
840234285Sdim  }
841234285Sdim};
842234285Sdim
843234285Sdim// Iterate through the version definitions, and place each Elf_Verdef
844234285Sdim// in the VersionMap according to its index.
845249423Sdimtemplate<class ELFT>
846249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
847234285Sdim  unsigned vd_size = sec->sh_size; // Size of section in bytes
848234285Sdim  unsigned vd_count = sec->sh_info; // Number of Verdef entries
849234285Sdim  const char *sec_start = (const char*)base() + sec->sh_offset;
850234285Sdim  const char *sec_end = sec_start + vd_size;
851234285Sdim  // The first Verdef entry is at the start of the section.
852234285Sdim  const char *p = sec_start;
853234285Sdim  for (unsigned i = 0; i < vd_count; i++) {
854234285Sdim    if (p + sizeof(Elf_Verdef) > sec_end)
855234285Sdim      report_fatal_error("Section ended unexpectedly while scanning "
856234285Sdim                         "version definitions.");
857234285Sdim    const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
858234285Sdim    if (vd->vd_version != ELF::VER_DEF_CURRENT)
859234285Sdim      report_fatal_error("Unexpected verdef version");
860234285Sdim    size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
861234285Sdim    if (index >= VersionMap.size())
862234285Sdim      VersionMap.resize(index+1);
863234285Sdim    VersionMap[index] = VersionMapEntry(vd);
864234285Sdim    p += vd->vd_next;
865234285Sdim  }
866234285Sdim}
867234285Sdim
868234285Sdim// Iterate through the versions needed section, and place each Elf_Vernaux
869234285Sdim// in the VersionMap according to its index.
870249423Sdimtemplate<class ELFT>
871249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
872234285Sdim  unsigned vn_size = sec->sh_size; // Size of section in bytes
873234285Sdim  unsigned vn_count = sec->sh_info; // Number of Verneed entries
874234285Sdim  const char *sec_start = (const char*)base() + sec->sh_offset;
875234285Sdim  const char *sec_end = sec_start + vn_size;
876234285Sdim  // The first Verneed entry is at the start of the section.
877234285Sdim  const char *p = sec_start;
878234285Sdim  for (unsigned i = 0; i < vn_count; i++) {
879234285Sdim    if (p + sizeof(Elf_Verneed) > sec_end)
880234285Sdim      report_fatal_error("Section ended unexpectedly while scanning "
881234285Sdim                         "version needed records.");
882234285Sdim    const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
883234285Sdim    if (vn->vn_version != ELF::VER_NEED_CURRENT)
884234285Sdim      report_fatal_error("Unexpected verneed version");
885234285Sdim    // Iterate through the Vernaux entries
886234285Sdim    const char *paux = p + vn->vn_aux;
887234285Sdim    for (unsigned j = 0; j < vn->vn_cnt; j++) {
888234285Sdim      if (paux + sizeof(Elf_Vernaux) > sec_end)
889234285Sdim        report_fatal_error("Section ended unexpected while scanning auxiliary "
890234285Sdim                           "version needed records.");
891234285Sdim      const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
892234285Sdim      size_t index = vna->vna_other & ELF::VERSYM_VERSION;
893234285Sdim      if (index >= VersionMap.size())
894234285Sdim        VersionMap.resize(index+1);
895234285Sdim      VersionMap[index] = VersionMapEntry(vna);
896234285Sdim      paux += vna->vna_next;
897234285Sdim    }
898234285Sdim    p += vn->vn_next;
899234285Sdim  }
900234285Sdim}
901234285Sdim
902249423Sdimtemplate<class ELFT>
903249423Sdimvoid ELFObjectFile<ELFT>::LoadVersionMap() const {
904234285Sdim  // If there is no dynamic symtab or version table, there is nothing to do.
905234285Sdim  if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL)
906234285Sdim    return;
907234285Sdim
908234285Sdim  // Has the VersionMap already been loaded?
909234285Sdim  if (VersionMap.size() > 0)
910234285Sdim    return;
911234285Sdim
912234285Sdim  // The first two version indexes are reserved.
913234285Sdim  // Index 0 is LOCAL, index 1 is GLOBAL.
914234285Sdim  VersionMap.push_back(VersionMapEntry());
915234285Sdim  VersionMap.push_back(VersionMapEntry());
916234285Sdim
917234285Sdim  if (dot_gnu_version_d_sec)
918234285Sdim    LoadVersionDefs(dot_gnu_version_d_sec);
919234285Sdim
920234285Sdim  if (dot_gnu_version_r_sec)
921234285Sdim    LoadVersionNeeds(dot_gnu_version_r_sec);
922234285Sdim}
923234285Sdim
924249423Sdimtemplate<class ELFT>
925249423Sdimvoid ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const {
926249423Sdim#ifndef NDEBUG
927234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
928234285Sdim  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
929234285Sdim  // FIXME: We really need to do proper error handling in the case of an invalid
930234285Sdim  //        input file. Because we don't use exceptions, I think we'll just pass
931234285Sdim  //        an error object around.
932234285Sdim  if (!(  symb
933234285Sdim        && SymbolTableSection
934234285Sdim        && symb >= (const Elf_Sym*)(base()
935234285Sdim                   + SymbolTableSection->sh_offset)
936234285Sdim        && symb <  (const Elf_Sym*)(base()
937234285Sdim                   + SymbolTableSection->sh_offset
938234285Sdim                   + SymbolTableSection->sh_size)))
939234285Sdim    // FIXME: Proper error handling.
940234285Sdim    report_fatal_error("Symb must point to a valid symbol!");
941249423Sdim#endif
942234285Sdim}
943234285Sdim
944249423Sdimtemplate<class ELFT>
945249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb,
946249423Sdim                                              SymbolRef &Result) const {
947234285Sdim  validateSymbol(Symb);
948234285Sdim  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
949234285Sdim
950234285Sdim  ++Symb.d.a;
951234285Sdim  // Check to see if we are at the end of this symbol table.
952234285Sdim  if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
953234285Sdim    // We are at the end. If there are other symbol tables, jump to them.
954234285Sdim    // If the symbol table is .dynsym, we are iterating dynamic symbols,
955234285Sdim    // and there is only one table of these.
956234285Sdim    if (Symb.d.b != 0) {
957234285Sdim      ++Symb.d.b;
958234285Sdim      Symb.d.a = 1; // The 0th symbol in ELF is fake.
959234285Sdim    }
960234285Sdim    // Otherwise return the terminator.
961234285Sdim    if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) {
962234285Sdim      Symb.d.a = std::numeric_limits<uint32_t>::max();
963234285Sdim      Symb.d.b = std::numeric_limits<uint32_t>::max();
964234285Sdim    }
965234285Sdim  }
966234285Sdim
967234285Sdim  Result = SymbolRef(Symb, this);
968234285Sdim  return object_error::success;
969234285Sdim}
970234285Sdim
971249423Sdimtemplate<class ELFT>
972249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
973249423Sdim                                              StringRef &Result) const {
974234285Sdim  validateSymbol(Symb);
975234285Sdim  const Elf_Sym *symb = getSymbol(Symb);
976234285Sdim  return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
977234285Sdim}
978234285Sdim
979249423Sdimtemplate<class ELFT>
980249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
981249423Sdim                                                 StringRef &Version,
982249423Sdim                                                 bool &IsDefault) const {
983234285Sdim  DataRefImpl Symb = SymRef.getRawDataRefImpl();
984234285Sdim  validateSymbol(Symb);
985234285Sdim  const Elf_Sym *symb = getSymbol(Symb);
986234285Sdim  return getSymbolVersion(SymbolTableSections[Symb.d.b], symb,
987234285Sdim                          Version, IsDefault);
988234285Sdim}
989234285Sdim
990249423Sdimtemplate<class ELFT>
991249423SdimELF::Elf64_Word ELFObjectFile<ELFT>
992249423Sdim                             ::getSymbolTableIndex(const Elf_Sym *symb) const {
993234285Sdim  if (symb->st_shndx == ELF::SHN_XINDEX)
994234285Sdim    return ExtendedSymbolTable.lookup(symb);
995234285Sdim  return symb->st_shndx;
996234285Sdim}
997234285Sdim
998249423Sdimtemplate<class ELFT>
999249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr *
1000249423SdimELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const {
1001234285Sdim  if (symb->st_shndx == ELF::SHN_XINDEX)
1002234285Sdim    return getSection(ExtendedSymbolTable.lookup(symb));
1003234285Sdim  if (symb->st_shndx >= ELF::SHN_LORESERVE)
1004234285Sdim    return 0;
1005234285Sdim  return getSection(symb->st_shndx);
1006234285Sdim}
1007234285Sdim
1008249423Sdimtemplate<class ELFT>
1009249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Ehdr *
1010249423SdimELFObjectFile<ELFT>::getElfHeader() const {
1011249423Sdim  return Header;
1012249423Sdim}
1013249423Sdim
1014249423Sdimtemplate<class ELFT>
1015249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr *
1016249423SdimELFObjectFile<ELFT>::getElfSection(section_iterator &It) const {
1017239462Sdim  llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
1018239462Sdim  return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p);
1019239462Sdim}
1020239462Sdim
1021249423Sdimtemplate<class ELFT>
1022249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym *
1023249423SdimELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const {
1024239462Sdim  return getSymbol(It->getRawDataRefImpl());
1025239462Sdim}
1026239462Sdim
1027249423Sdimtemplate<class ELFT>
1028249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym *
1029249423SdimELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const {
1030243830Sdim  DataRefImpl SymbolData;
1031243830Sdim  SymbolData.d.a = index;
1032243830Sdim  SymbolData.d.b = 1;
1033243830Sdim  return getSymbol(SymbolData);
1034243830Sdim}
1035243830Sdim
1036249423Sdimtemplate<class ELFT>
1037249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
1038249423Sdim                                                    uint64_t &Result) const {
1039234285Sdim  validateSymbol(Symb);
1040234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1041234285Sdim  const Elf_Shdr *Section;
1042234285Sdim  switch (getSymbolTableIndex(symb)) {
1043234285Sdim  case ELF::SHN_COMMON:
1044234285Sdim   // Unintialized symbols have no offset in the object file
1045234285Sdim  case ELF::SHN_UNDEF:
1046234285Sdim    Result = UnknownAddressOrSize;
1047234285Sdim    return object_error::success;
1048234285Sdim  case ELF::SHN_ABS:
1049234285Sdim    Result = symb->st_value;
1050234285Sdim    return object_error::success;
1051234285Sdim  default: Section = getSection(symb);
1052234285Sdim  }
1053234285Sdim
1054234285Sdim  switch (symb->getType()) {
1055234285Sdim  case ELF::STT_SECTION:
1056249423Sdim    Result = Section ? Section->sh_offset : UnknownAddressOrSize;
1057234285Sdim    return object_error::success;
1058234285Sdim  case ELF::STT_FUNC:
1059234285Sdim  case ELF::STT_OBJECT:
1060234285Sdim  case ELF::STT_NOTYPE:
1061234285Sdim    Result = symb->st_value +
1062234285Sdim             (Section ? Section->sh_offset : 0);
1063234285Sdim    return object_error::success;
1064234285Sdim  default:
1065234285Sdim    Result = UnknownAddressOrSize;
1066234285Sdim    return object_error::success;
1067234285Sdim  }
1068234285Sdim}
1069234285Sdim
1070249423Sdimtemplate<class ELFT>
1071249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
1072249423Sdim                                                 uint64_t &Result) const {
1073234285Sdim  validateSymbol(Symb);
1074234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1075234285Sdim  const Elf_Shdr *Section;
1076234285Sdim  switch (getSymbolTableIndex(symb)) {
1077234285Sdim  case ELF::SHN_COMMON:
1078234285Sdim  case ELF::SHN_UNDEF:
1079234285Sdim    Result = UnknownAddressOrSize;
1080234285Sdim    return object_error::success;
1081234285Sdim  case ELF::SHN_ABS:
1082234285Sdim    Result = symb->st_value;
1083234285Sdim    return object_error::success;
1084234285Sdim  default: Section = getSection(symb);
1085234285Sdim  }
1086234285Sdim
1087234285Sdim  switch (symb->getType()) {
1088234285Sdim  case ELF::STT_SECTION:
1089234285Sdim    Result = Section ? Section->sh_addr : UnknownAddressOrSize;
1090234285Sdim    return object_error::success;
1091234285Sdim  case ELF::STT_FUNC:
1092234285Sdim  case ELF::STT_OBJECT:
1093234285Sdim  case ELF::STT_NOTYPE:
1094243830Sdim    bool IsRelocatable;
1095243830Sdim    switch(Header->e_type) {
1096243830Sdim    case ELF::ET_EXEC:
1097243830Sdim    case ELF::ET_DYN:
1098243830Sdim      IsRelocatable = false;
1099243830Sdim      break;
1100243830Sdim    default:
1101243830Sdim      IsRelocatable = true;
1102243830Sdim    }
1103243830Sdim    Result = symb->st_value;
1104249423Sdim
1105249423Sdim    // Clear the ARM/Thumb indicator flag.
1106249423Sdim    if (Header->e_machine == ELF::EM_ARM)
1107249423Sdim      Result &= ~1;
1108249423Sdim
1109243830Sdim    if (IsRelocatable && Section != 0)
1110243830Sdim      Result += Section->sh_addr;
1111234285Sdim    return object_error::success;
1112234285Sdim  default:
1113234285Sdim    Result = UnknownAddressOrSize;
1114234285Sdim    return object_error::success;
1115234285Sdim  }
1116234285Sdim}
1117234285Sdim
1118249423Sdimtemplate<class ELFT>
1119251662Sdimerror_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb,
1120251662Sdim                                                   uint32_t &Res) const {
1121251662Sdim  uint32_t flags;
1122251662Sdim  getSymbolFlags(Symb, flags);
1123251662Sdim  if (flags & SymbolRef::SF_Common) {
1124251662Sdim    uint64_t Value;
1125251662Sdim    getSymbolValue(Symb, Value);
1126251662Sdim    Res = Value;
1127251662Sdim  } else {
1128251662Sdim    Res = 0;
1129251662Sdim  }
1130251662Sdim  return object_error::success;
1131251662Sdim}
1132251662Sdim
1133251662Sdimtemplate<class ELFT>
1134249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
1135249423Sdim                                              uint64_t &Result) const {
1136234285Sdim  validateSymbol(Symb);
1137234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1138234285Sdim  if (symb->st_size == 0)
1139234285Sdim    Result = UnknownAddressOrSize;
1140234285Sdim  Result = symb->st_size;
1141234285Sdim  return object_error::success;
1142234285Sdim}
1143234285Sdim
1144249423Sdimtemplate<class ELFT>
1145249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb,
1146249423Sdim                                                    char &Result) const {
1147234285Sdim  validateSymbol(Symb);
1148234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1149234285Sdim  const Elf_Shdr *Section = getSection(symb);
1150234285Sdim
1151234285Sdim  char ret = '?';
1152234285Sdim
1153234285Sdim  if (Section) {
1154234285Sdim    switch (Section->sh_type) {
1155234285Sdim    case ELF::SHT_PROGBITS:
1156234285Sdim    case ELF::SHT_DYNAMIC:
1157234285Sdim      switch (Section->sh_flags) {
1158234285Sdim      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
1159234285Sdim        ret = 't'; break;
1160234285Sdim      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
1161234285Sdim        ret = 'd'; break;
1162234285Sdim      case ELF::SHF_ALLOC:
1163234285Sdim      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
1164234285Sdim      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
1165234285Sdim        ret = 'r'; break;
1166234285Sdim      }
1167234285Sdim      break;
1168234285Sdim    case ELF::SHT_NOBITS: ret = 'b';
1169234285Sdim    }
1170234285Sdim  }
1171234285Sdim
1172234285Sdim  switch (getSymbolTableIndex(symb)) {
1173234285Sdim  case ELF::SHN_UNDEF:
1174234285Sdim    if (ret == '?')
1175234285Sdim      ret = 'U';
1176234285Sdim    break;
1177234285Sdim  case ELF::SHN_ABS: ret = 'a'; break;
1178234285Sdim  case ELF::SHN_COMMON: ret = 'c'; break;
1179234285Sdim  }
1180234285Sdim
1181234285Sdim  switch (symb->getBinding()) {
1182234285Sdim  case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
1183234285Sdim  case ELF::STB_WEAK:
1184234285Sdim    if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
1185234285Sdim      ret = 'w';
1186234285Sdim    else
1187234285Sdim      if (symb->getType() == ELF::STT_OBJECT)
1188234285Sdim        ret = 'V';
1189234285Sdim      else
1190234285Sdim        ret = 'W';
1191234285Sdim  }
1192234285Sdim
1193234285Sdim  if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
1194234285Sdim    StringRef name;
1195234285Sdim    if (error_code ec = getSymbolName(Symb, name))
1196234285Sdim      return ec;
1197234285Sdim    Result = StringSwitch<char>(name)
1198234285Sdim      .StartsWith(".debug", 'N')
1199234285Sdim      .StartsWith(".note", 'n')
1200234285Sdim      .Default('?');
1201234285Sdim    return object_error::success;
1202234285Sdim  }
1203234285Sdim
1204234285Sdim  Result = ret;
1205234285Sdim  return object_error::success;
1206234285Sdim}
1207234285Sdim
1208249423Sdimtemplate<class ELFT>
1209249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
1210249423Sdim                                              SymbolRef::Type &Result) const {
1211234285Sdim  validateSymbol(Symb);
1212234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1213234285Sdim
1214234285Sdim  switch (symb->getType()) {
1215234285Sdim  case ELF::STT_NOTYPE:
1216234285Sdim    Result = SymbolRef::ST_Unknown;
1217234285Sdim    break;
1218234285Sdim  case ELF::STT_SECTION:
1219234285Sdim    Result = SymbolRef::ST_Debug;
1220234285Sdim    break;
1221234285Sdim  case ELF::STT_FILE:
1222234285Sdim    Result = SymbolRef::ST_File;
1223234285Sdim    break;
1224234285Sdim  case ELF::STT_FUNC:
1225234285Sdim    Result = SymbolRef::ST_Function;
1226234285Sdim    break;
1227234285Sdim  case ELF::STT_OBJECT:
1228234285Sdim  case ELF::STT_COMMON:
1229234285Sdim  case ELF::STT_TLS:
1230234285Sdim    Result = SymbolRef::ST_Data;
1231234285Sdim    break;
1232234285Sdim  default:
1233234285Sdim    Result = SymbolRef::ST_Other;
1234234285Sdim    break;
1235234285Sdim  }
1236234285Sdim  return object_error::success;
1237234285Sdim}
1238234285Sdim
1239249423Sdimtemplate<class ELFT>
1240249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
1241249423Sdim                                               uint32_t &Result) const {
1242234285Sdim  validateSymbol(Symb);
1243234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1244234285Sdim
1245234285Sdim  Result = SymbolRef::SF_None;
1246234285Sdim
1247234285Sdim  if (symb->getBinding() != ELF::STB_LOCAL)
1248234285Sdim    Result |= SymbolRef::SF_Global;
1249234285Sdim
1250234285Sdim  if (symb->getBinding() == ELF::STB_WEAK)
1251234285Sdim    Result |= SymbolRef::SF_Weak;
1252234285Sdim
1253234285Sdim  if (symb->st_shndx == ELF::SHN_ABS)
1254234285Sdim    Result |= SymbolRef::SF_Absolute;
1255234285Sdim
1256234285Sdim  if (symb->getType() == ELF::STT_FILE ||
1257234285Sdim      symb->getType() == ELF::STT_SECTION)
1258234285Sdim    Result |= SymbolRef::SF_FormatSpecific;
1259234285Sdim
1260234285Sdim  if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
1261234285Sdim    Result |= SymbolRef::SF_Undefined;
1262234285Sdim
1263234285Sdim  if (symb->getType() == ELF::STT_COMMON ||
1264234285Sdim      getSymbolTableIndex(symb) == ELF::SHN_COMMON)
1265234285Sdim    Result |= SymbolRef::SF_Common;
1266234285Sdim
1267234285Sdim  if (symb->getType() == ELF::STT_TLS)
1268234285Sdim    Result |= SymbolRef::SF_ThreadLocal;
1269234285Sdim
1270234285Sdim  return object_error::success;
1271234285Sdim}
1272234285Sdim
1273249423Sdimtemplate<class ELFT>
1274249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
1275249423Sdim                                                 section_iterator &Res) const {
1276234285Sdim  validateSymbol(Symb);
1277234285Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1278234285Sdim  const Elf_Shdr *sec = getSection(symb);
1279234285Sdim  if (!sec)
1280234285Sdim    Res = end_sections();
1281234285Sdim  else {
1282234285Sdim    DataRefImpl Sec;
1283234285Sdim    Sec.p = reinterpret_cast<intptr_t>(sec);
1284234285Sdim    Res = section_iterator(SectionRef(Sec, this));
1285234285Sdim  }
1286234285Sdim  return object_error::success;
1287234285Sdim}
1288234285Sdim
1289249423Sdimtemplate<class ELFT>
1290249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb,
1291249423Sdim                                               uint64_t &Val) const {
1292243830Sdim  validateSymbol(Symb);
1293243830Sdim  const Elf_Sym *symb = getSymbol(Symb);
1294243830Sdim  Val = symb->st_value;
1295243830Sdim  return object_error::success;
1296243830Sdim}
1297243830Sdim
1298249423Sdimtemplate<class ELFT>
1299249423Sdimerror_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec,
1300249423Sdim                                               SectionRef &Result) const {
1301234285Sdim  const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
1302234285Sdim  sec += Header->e_shentsize;
1303234285Sdim  Sec.p = reinterpret_cast<intptr_t>(sec);
1304234285Sdim  Result = SectionRef(Sec, this);
1305234285Sdim  return object_error::success;
1306234285Sdim}
1307234285Sdim
1308249423Sdimtemplate<class ELFT>
1309249423Sdimerror_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
1310249423Sdim                                               StringRef &Result) const {
1311234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1312234285Sdim  Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
1313234285Sdim  return object_error::success;
1314234285Sdim}
1315234285Sdim
1316249423Sdimtemplate<class ELFT>
1317249423Sdimerror_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
1318249423Sdim                                                  uint64_t &Result) const {
1319234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1320234285Sdim  Result = sec->sh_addr;
1321234285Sdim  return object_error::success;
1322234285Sdim}
1323234285Sdim
1324249423Sdimtemplate<class ELFT>
1325249423Sdimerror_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
1326249423Sdim                                               uint64_t &Result) const {
1327234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1328234285Sdim  Result = sec->sh_size;
1329234285Sdim  return object_error::success;
1330234285Sdim}
1331234285Sdim
1332249423Sdimtemplate<class ELFT>
1333249423Sdimerror_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
1334249423Sdim                                                   StringRef &Result) const {
1335234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1336234285Sdim  const char *start = (const char*)base() + sec->sh_offset;
1337234285Sdim  Result = StringRef(start, sec->sh_size);
1338234285Sdim  return object_error::success;
1339234285Sdim}
1340234285Sdim
1341249423Sdimtemplate<class ELFT>
1342249423Sdimerror_code ELFObjectFile<ELFT>::getSectionContents(const Elf_Shdr *Sec,
1343249423Sdim                                                   StringRef &Result) const {
1344239462Sdim  const char *start = (const char*)base() + Sec->sh_offset;
1345239462Sdim  Result = StringRef(start, Sec->sh_size);
1346239462Sdim  return object_error::success;
1347239462Sdim}
1348239462Sdim
1349249423Sdimtemplate<class ELFT>
1350249423Sdimerror_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
1351249423Sdim                                                    uint64_t &Result) const {
1352234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1353234285Sdim  Result = sec->sh_addralign;
1354234285Sdim  return object_error::success;
1355234285Sdim}
1356234285Sdim
1357249423Sdimtemplate<class ELFT>
1358249423Sdimerror_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
1359249423Sdim                                              bool &Result) const {
1360234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1361234285Sdim  if (sec->sh_flags & ELF::SHF_EXECINSTR)
1362234285Sdim    Result = true;
1363234285Sdim  else
1364234285Sdim    Result = false;
1365234285Sdim  return object_error::success;
1366234285Sdim}
1367234285Sdim
1368249423Sdimtemplate<class ELFT>
1369249423Sdimerror_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
1370249423Sdim                                              bool &Result) const {
1371234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1372234285Sdim  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
1373234285Sdim      && sec->sh_type == ELF::SHT_PROGBITS)
1374234285Sdim    Result = true;
1375234285Sdim  else
1376234285Sdim    Result = false;
1377234285Sdim  return object_error::success;
1378234285Sdim}
1379234285Sdim
1380249423Sdimtemplate<class ELFT>
1381249423Sdimerror_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
1382249423Sdim                                             bool &Result) const {
1383234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1384234285Sdim  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
1385234285Sdim      && sec->sh_type == ELF::SHT_NOBITS)
1386234285Sdim    Result = true;
1387234285Sdim  else
1388234285Sdim    Result = false;
1389234285Sdim  return object_error::success;
1390234285Sdim}
1391234285Sdim
1392249423Sdimtemplate<class ELFT>
1393249423Sdimerror_code ELFObjectFile<ELFT>::isSectionRequiredForExecution(
1394249423Sdim    DataRefImpl Sec, bool &Result) const {
1395234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1396234285Sdim  if (sec->sh_flags & ELF::SHF_ALLOC)
1397234285Sdim    Result = true;
1398234285Sdim  else
1399234285Sdim    Result = false;
1400234285Sdim  return object_error::success;
1401234285Sdim}
1402234285Sdim
1403249423Sdimtemplate<class ELFT>
1404249423Sdimerror_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
1405249423Sdim                                                 bool &Result) const {
1406234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1407234285Sdim  if (sec->sh_type == ELF::SHT_NOBITS)
1408234285Sdim    Result = true;
1409234285Sdim  else
1410234285Sdim    Result = false;
1411234285Sdim  return object_error::success;
1412234285Sdim}
1413234285Sdim
1414249423Sdimtemplate<class ELFT>
1415249423Sdimerror_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
1416249423Sdim                                                  bool &Result) const {
1417234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1418234285Sdim  // For ELF, all zero-init sections are virtual (that is, they occupy no space
1419234285Sdim  //   in the object image) and vice versa.
1420249423Sdim  Result = sec->sh_type == ELF::SHT_NOBITS;
1421234285Sdim  return object_error::success;
1422234285Sdim}
1423234285Sdim
1424249423Sdimtemplate<class ELFT>
1425249423Sdimerror_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
1426249423Sdim                                                      bool &Result) const {
1427243830Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1428243830Sdim  if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR)
1429243830Sdim    Result = false;
1430243830Sdim  else
1431243830Sdim    Result = true;
1432243830Sdim  return object_error::success;
1433243830Sdim}
1434243830Sdim
1435249423Sdimtemplate<class ELFT>
1436249423Sdimerror_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
1437249423Sdim                                                      DataRefImpl Symb,
1438249423Sdim                                                      bool &Result) const {
1439249423Sdim  validateSymbol(Symb);
1440249423Sdim
1441249423Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1442249423Sdim  const Elf_Sym  *symb = getSymbol(Symb);
1443249423Sdim
1444249423Sdim  unsigned shndx = symb->st_shndx;
1445249423Sdim  bool Reserved = shndx >= ELF::SHN_LORESERVE
1446249423Sdim               && shndx <= ELF::SHN_HIRESERVE;
1447249423Sdim
1448249423Sdim  Result = !Reserved && (sec == getSection(symb->st_shndx));
1449234285Sdim  return object_error::success;
1450234285Sdim}
1451234285Sdim
1452249423Sdimtemplate<class ELFT>
1453249423Sdimrelocation_iterator
1454249423SdimELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const {
1455234285Sdim  DataRefImpl RelData;
1456234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1457234285Sdim  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
1458234285Sdim  if (sec != 0 && ittr != SectionRelocMap.end()) {
1459234285Sdim    RelData.w.a = getSection(ittr->second[0])->sh_info;
1460234285Sdim    RelData.w.b = ittr->second[0];
1461234285Sdim    RelData.w.c = 0;
1462234285Sdim  }
1463234285Sdim  return relocation_iterator(RelocationRef(RelData, this));
1464234285Sdim}
1465234285Sdim
1466249423Sdimtemplate<class ELFT>
1467249423Sdimrelocation_iterator
1468249423SdimELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const {
1469234285Sdim  DataRefImpl RelData;
1470234285Sdim  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
1471234285Sdim  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
1472234285Sdim  if (sec != 0 && ittr != SectionRelocMap.end()) {
1473234285Sdim    // Get the index of the last relocation section for this section.
1474234285Sdim    std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
1475234285Sdim    const Elf_Shdr *relocsec = getSection(relocsecindex);
1476234285Sdim    RelData.w.a = relocsec->sh_info;
1477234285Sdim    RelData.w.b = relocsecindex;
1478234285Sdim    RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
1479234285Sdim  }
1480234285Sdim  return relocation_iterator(RelocationRef(RelData, this));
1481234285Sdim}
1482234285Sdim
1483234285Sdim// Relocations
1484249423Sdimtemplate<class ELFT>
1485249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
1486249423Sdim                                                  RelocationRef &Result) const {
1487234285Sdim  ++Rel.w.c;
1488234285Sdim  const Elf_Shdr *relocsec = getSection(Rel.w.b);
1489234285Sdim  if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
1490234285Sdim    // We have reached the end of the relocations for this section. See if there
1491234285Sdim    // is another relocation section.
1492234285Sdim    typename RelocMap_t::mapped_type relocseclist =
1493234285Sdim      SectionRelocMap.lookup(getSection(Rel.w.a));
1494234285Sdim
1495234285Sdim    // Do a binary search for the current reloc section index (which must be
1496234285Sdim    // present). Then get the next one.
1497234285Sdim    typename RelocMap_t::mapped_type::const_iterator loc =
1498234285Sdim      std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
1499234285Sdim    ++loc;
1500234285Sdim
1501234285Sdim    // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
1502234285Sdim    // to the end iterator.
1503234285Sdim    if (loc != relocseclist.end()) {
1504234285Sdim      Rel.w.b = *loc;
1505234285Sdim      Rel.w.a = 0;
1506234285Sdim    }
1507234285Sdim  }
1508234285Sdim  Result = RelocationRef(Rel, this);
1509234285Sdim  return object_error::success;
1510234285Sdim}
1511234285Sdim
1512249423Sdimtemplate<class ELFT>
1513249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
1514249423Sdim                                                    SymbolRef &Result) const {
1515234285Sdim  uint32_t symbolIdx;
1516234285Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
1517234285Sdim  switch (sec->sh_type) {
1518234285Sdim    default :
1519234285Sdim      report_fatal_error("Invalid section type in Rel!");
1520234285Sdim    case ELF::SHT_REL : {
1521249423Sdim      symbolIdx = getRel(Rel)->getSymbol(isMips64EL());
1522234285Sdim      break;
1523234285Sdim    }
1524234285Sdim    case ELF::SHT_RELA : {
1525249423Sdim      symbolIdx = getRela(Rel)->getSymbol(isMips64EL());
1526234285Sdim      break;
1527234285Sdim    }
1528234285Sdim  }
1529234285Sdim  DataRefImpl SymbolData;
1530234285Sdim  IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
1531234285Sdim  if (it == SymbolTableSectionsIndexMap.end())
1532234285Sdim    report_fatal_error("Relocation symbol table not found!");
1533234285Sdim  SymbolData.d.a = symbolIdx;
1534234285Sdim  SymbolData.d.b = it->second;
1535234285Sdim  Result = SymbolRef(SymbolData, this);
1536234285Sdim  return object_error::success;
1537234285Sdim}
1538234285Sdim
1539249423Sdimtemplate<class ELFT>
1540249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
1541249423Sdim                                                     uint64_t &Result) const {
1542251662Sdim  assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) &&
1543251662Sdim         "Only executable and shared objects files have addresses");
1544251662Sdim  Result = getROffset(Rel);
1545234285Sdim  return object_error::success;
1546234285Sdim}
1547234285Sdim
1548249423Sdimtemplate<class ELFT>
1549249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
1550249423Sdim                                                    uint64_t &Result) const {
1551251662Sdim  assert(Header->e_type == ELF::ET_REL &&
1552251662Sdim         "Only relocatable object files have relocation offsets");
1553251662Sdim  Result = getROffset(Rel);
1554251662Sdim  return object_error::success;
1555251662Sdim}
1556251662Sdim
1557251662Sdimtemplate<class ELFT>
1558251662Sdimuint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
1559234285Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
1560234285Sdim  switch (sec->sh_type) {
1561251662Sdim  default:
1562251662Sdim    report_fatal_error("Invalid section type in Rel!");
1563251662Sdim  case ELF::SHT_REL:
1564251662Sdim    return getRel(Rel)->r_offset;
1565251662Sdim  case ELF::SHT_RELA:
1566251662Sdim    return getRela(Rel)->r_offset;
1567234285Sdim  }
1568234285Sdim}
1569234285Sdim
1570249423Sdimtemplate<class ELFT>
1571249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
1572249423Sdim                                                  uint64_t &Result) const {
1573234285Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
1574234285Sdim  switch (sec->sh_type) {
1575234285Sdim    default :
1576234285Sdim      report_fatal_error("Invalid section type in Rel!");
1577234285Sdim    case ELF::SHT_REL : {
1578249423Sdim      Result = getRel(Rel)->getType(isMips64EL());
1579234285Sdim      break;
1580234285Sdim    }
1581234285Sdim    case ELF::SHT_RELA : {
1582249423Sdim      Result = getRela(Rel)->getType(isMips64EL());
1583234285Sdim      break;
1584234285Sdim    }
1585234285Sdim  }
1586234285Sdim  return object_error::success;
1587234285Sdim}
1588234285Sdim
1589234285Sdim#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
1590251662Sdim  case ELF::enum: Res = #enum; break;
1591234285Sdim
1592249423Sdimtemplate<class ELFT>
1593251662SdimStringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
1594251662Sdim  StringRef Res = "Unknown";
1595234285Sdim  switch (Header->e_machine) {
1596234285Sdim  case ELF::EM_X86_64:
1597251662Sdim    switch (Type) {
1598234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
1599234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
1600234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
1601234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
1602234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
1603234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
1604234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
1605234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
1606234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
1607234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
1608234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
1609234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
1610234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
1611234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
1612234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
1613234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
1614234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
1615234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
1616234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
1617234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
1618234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
1619234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
1620234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
1621234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
1622234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
1623234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
1624234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
1625251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT64);
1626251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL64);
1627251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC64);
1628251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPLT64);
1629251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLTOFF64);
1630234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
1631234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
1632234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
1633234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
1634234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
1635251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_IRELATIVE);
1636251662Sdim    default: break;
1637234285Sdim    }
1638234285Sdim    break;
1639234285Sdim  case ELF::EM_386:
1640251662Sdim    switch (Type) {
1641234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
1642234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
1643234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
1644234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
1645234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
1646234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
1647234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
1648234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
1649234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
1650234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
1651234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
1652234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
1653234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
1654234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
1655234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
1656234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
1657234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
1658234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
1659234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
1660234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
1661234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
1662234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
1663234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
1664234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
1665234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
1666234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
1667234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
1668234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
1669234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
1670234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
1671234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
1672234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
1673234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
1674234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
1675234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
1676234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
1677234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
1678234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
1679234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
1680234285Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
1681251662Sdim    default: break;
1682234285Sdim    }
1683234285Sdim    break;
1684249423Sdim  case ELF::EM_MIPS:
1685251662Sdim    switch (Type) {
1686249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NONE);
1687249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_16);
1688249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_32);
1689249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL32);
1690249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_26);
1691249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HI16);
1692249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LO16);
1693249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL16);
1694249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_LITERAL);
1695249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT16);
1696249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16);
1697249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16);
1698249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32);
1699249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5);
1700249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6);
1701249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64);
1702249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_DISP);
1703249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_PAGE);
1704249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_OFST);
1705249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_HI16);
1706249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GOT_LO16);
1707249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SUB);
1708249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_A);
1709249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_INSERT_B);
1710249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_DELETE);
1711249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHER);
1712249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_HIGHEST);
1713249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_HI16);
1714249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL_LO16);
1715249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SCN_DISP);
1716249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_REL16);
1717249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_ADD_IMMEDIATE);
1718249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PJUMP);
1719249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_RELGOT);
1720249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JALR);
1721249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD32);
1722249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL32);
1723249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPMOD64);
1724249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL64);
1725249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GD);
1726249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_LDM);
1727249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_HI16);
1728249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_DTPREL_LO16);
1729249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_GOTTPREL);
1730249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL32);
1731249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL64);
1732249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16);
1733249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16);
1734249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT);
1735249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY);
1736249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT);
1737251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM);
1738251662Sdim    default: break;
1739249423Sdim    }
1740249423Sdim    break;
1741249423Sdim  case ELF::EM_AARCH64:
1742251662Sdim    switch (Type) {
1743249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE);
1744249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64);
1745249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32);
1746249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS16);
1747249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL64);
1748249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL32);
1749249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL16);
1750249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0);
1751249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0_NC);
1752249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1);
1753249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1_NC);
1754249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2);
1755249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2_NC);
1756249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G3);
1757249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G0);
1758249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G1);
1759249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G2);
1760249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD_PREL_LO19);
1761249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_LO21);
1762249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_PG_HI21);
1763249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADD_ABS_LO12_NC);
1764249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST8_ABS_LO12_NC);
1765249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TSTBR14);
1766249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CONDBR19);
1767249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_JUMP26);
1768249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CALL26);
1769249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST16_ABS_LO12_NC);
1770249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST32_ABS_LO12_NC);
1771249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST64_ABS_LO12_NC);
1772249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST128_ABS_LO12_NC);
1773249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_GOT_PAGE);
1774249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD64_GOT_LO12_NC);
1775249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G2);
1776249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1);
1777249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC);
1778249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0);
1779249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC);
1780249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_HI12);
1781249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12);
1782249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC);
1783249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12);
1784249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC);
1785249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12);
1786249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC);
1787249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12);
1788249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC);
1789249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12);
1790249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC);
1791249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
1792249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
1793249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
1794249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
1795249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
1796249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G2);
1797249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1);
1798249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC);
1799249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0);
1800249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC);
1801249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_HI12);
1802249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12);
1803249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC);
1804249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12);
1805249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC);
1806249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12);
1807249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC);
1808249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12);
1809249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC);
1810249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12);
1811249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC);
1812249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADR_PAGE);
1813249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC);
1814249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC);
1815249423Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL);
1816251662Sdim    default: break;
1817249423Sdim    }
1818249423Sdim    break;
1819243830Sdim  case ELF::EM_ARM:
1820251662Sdim    switch (Type) {
1821243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE);
1822243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PC24);
1823243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32);
1824243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32);
1825243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G0);
1826243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS16);
1827243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS12);
1828243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ABS5);
1829243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS8);
1830243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL32);
1831243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_CALL);
1832243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC8);
1833243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BREL_ADJ);
1834243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESC);
1835243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_SWI8);
1836243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_XPC25);
1837243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_XPC22);
1838243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPMOD32);
1839243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DTPOFF32);
1840243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_TPOFF32);
1841243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_COPY);
1842243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GLOB_DAT);
1843243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP_SLOT);
1844243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_RELATIVE);
1845243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF32);
1846243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_PREL);
1847243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL);
1848243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32);
1849243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_CALL);
1850243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_JUMP24);
1851243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP24);
1852243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_BASE_ABS);
1853243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_7_0);
1854243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_15_8);
1855243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PCREL_23_15);
1856243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SBREL_11_0_NC);
1857243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_19_12_NC);
1858243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SBREL_27_20_CK);
1859243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET1);
1860243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_SBREL31);
1861243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_V4BX);
1862243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TARGET2);
1863243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PREL31);
1864243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_ABS_NC);
1865243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_ABS);
1866243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_PREL_NC);
1867243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_PREL);
1868243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_ABS_NC);
1869243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_ABS);
1870243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_PREL_NC);
1871243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_PREL);
1872243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP19);
1873243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP6);
1874243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_ALU_PREL_11_0);
1875243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_PC12);
1876243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ABS32_NOI);
1877243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_REL32_NOI);
1878243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0_NC);
1879243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G0);
1880243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1_NC);
1881243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G1);
1882243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_PC_G2);
1883243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G1);
1884243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_PC_G2);
1885243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G0);
1886243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G1);
1887243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_PC_G2);
1888243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G0);
1889243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G1);
1890243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_PC_G2);
1891243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0_NC);
1892243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G0);
1893243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1_NC);
1894243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G1);
1895243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ALU_SB_G2);
1896243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G0);
1897243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G1);
1898243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDR_SB_G2);
1899243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G0);
1900243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G1);
1901243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDRS_SB_G2);
1902243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G0);
1903243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G1);
1904243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_LDC_SB_G2);
1905243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL_NC);
1906243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVT_BREL);
1907243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_MOVW_BREL);
1908243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL_NC);
1909243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVT_BREL);
1910243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_MOVW_BREL);
1911243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GOTDESC);
1912243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_CALL);
1913243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_DESCSEQ);
1914243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_CALL);
1915243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PLT32_ABS);
1916243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_ABS);
1917243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_PREL);
1918243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOT_BREL12);
1919243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTOFF12);
1920243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GOTRELAX);
1921243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTENTRY);
1922243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_GNU_VTINHERIT);
1923243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP11);
1924243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_JUMP8);
1925243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_GD32);
1926243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDM32);
1927243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO32);
1928243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE32);
1929243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE32);
1930243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LDO12);
1931243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_LE12);
1932243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_TLS_IE12GP);
1933243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_0);
1934243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_1);
1935243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_2);
1936243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_3);
1937243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_4);
1938243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_5);
1939243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_6);
1940243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_7);
1941243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_8);
1942243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_9);
1943243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_10);
1944243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_11);
1945243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_12);
1946243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_13);
1947243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_14);
1948243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_PRIVATE_15);
1949243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_ME_TOO);
1950243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ16);
1951243830Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_THM_TLS_DESCSEQ32);
1952251662Sdim    default: break;
1953243830Sdim    }
1954243830Sdim    break;
1955239462Sdim  case ELF::EM_HEXAGON:
1956251662Sdim    switch (Type) {
1957239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_NONE);
1958239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL);
1959239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL);
1960239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL);
1961239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_LO16);
1962239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HI16);
1963239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32);
1964239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16);
1965239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8);
1966239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_0);
1967239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_1);
1968239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_2);
1969239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GPREL16_3);
1970239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_HL16);
1971239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL);
1972239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL);
1973239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B32_PCREL_X);
1974239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_6_X);
1975239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B22_PCREL_X);
1976239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B15_PCREL_X);
1977239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B13_PCREL_X);
1978239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B9_PCREL_X);
1979239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_B7_PCREL_X);
1980239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_16_X);
1981239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_12_X);
1982239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_11_X);
1983239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_10_X);
1984239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_9_X);
1985239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_8_X);
1986239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_7_X);
1987239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_X);
1988239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_32_PCREL);
1989239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_COPY);
1990239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GLOB_DAT);
1991239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_JMP_SLOT);
1992239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_RELATIVE);
1993239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_PLT_B22_PCREL);
1994239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_LO16);
1995239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_HI16);
1996239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32);
1997239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_LO16);
1998239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_HI16);
1999239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32);
2000239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16);
2001239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPMOD_32);
2002239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_LO16);
2003239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_HI16);
2004239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32);
2005239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16);
2006239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_PLT_B22_PCREL);
2007239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_LO16);
2008239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_HI16);
2009239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32);
2010239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16);
2011239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_LO16);
2012239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_HI16);
2013239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32);
2014239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_LO16);
2015239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_HI16);
2016239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32);
2017239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16);
2018239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_LO16);
2019239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_HI16);
2020239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32);
2021239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16);
2022239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_6_PCREL_X);
2023239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_32_6_X);
2024239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_16_X);
2025239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOTREL_11_X);
2026239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_32_6_X);
2027239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_16_X);
2028239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GOT_11_X);
2029239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_32_6_X);
2030239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_16_X);
2031239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_DTPREL_11_X);
2032239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_32_6_X);
2033239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_16_X);
2034239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_GD_GOT_11_X);
2035239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_32_6_X);
2036239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_16_X);
2037239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_32_6_X);
2038239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_16_X);
2039239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_IE_GOT_11_X);
2040239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_32_6_X);
2041239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_16_X);
2042239462Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_HEX_TPREL_11_X);
2043251662Sdim    default: break;
2044239462Sdim    }
2045239462Sdim    break;
2046251662Sdim  case ELF::EM_PPC:
2047251662Sdim    switch (Type) {
2048251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_NONE);
2049251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR32);
2050251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR24);
2051251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16);
2052251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_LO);
2053251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HI);
2054251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR16_HA);
2055251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14);
2056251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRTAKEN);
2057251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_ADDR14_BRNTAKEN);
2058251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL24);
2059251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14);
2060251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN);
2061251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN);
2062251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32);
2063251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO);
2064251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA);
2065251662Sdim    default: break;
2066251662Sdim    }
2067251662Sdim    break;
2068251662Sdim  case ELF::EM_PPC64:
2069251662Sdim    switch (Type) {
2070251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_NONE);
2071251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR32);
2072251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO);
2073251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HI);
2074251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR14);
2075251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL24);
2076251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32);
2077251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64);
2078251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER);
2079251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST);
2080251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64);
2081251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16);
2082251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO);
2083251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA);
2084251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC);
2085251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS);
2086251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS);
2087251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS);
2088251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS);
2089251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS);
2090251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO);
2091251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA);
2092251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO);
2093251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA);
2094251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO);
2095251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA);
2096251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO);
2097251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA);
2098251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS);
2099251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA);
2100251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD);
2101251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD);
2102251662Sdim    default: break;
2103251662Sdim    }
2104251662Sdim    break;
2105251662Sdim  case ELF::EM_S390:
2106251662Sdim    switch (Type) {
2107251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_NONE);
2108251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_8);
2109251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_12);
2110251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_16);
2111251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_32);
2112251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32);
2113251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT12);
2114251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT32);
2115251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32);
2116251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_COPY);
2117251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GLOB_DAT);
2118251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_JMP_SLOT);
2119251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_RELATIVE);
2120251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF);
2121251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPC);
2122251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT16);
2123251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16);
2124251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC16DBL);
2125251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT16DBL);
2126251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC32DBL);
2127251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT32DBL);
2128251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPCDBL);
2129251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_64);
2130251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PC64);
2131251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT64);
2132251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLT64);
2133251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTENT);
2134251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF16);
2135251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTOFF64);
2136251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT12);
2137251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT16);
2138251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT32);
2139251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT64);
2140251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLTENT);
2141251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF16);
2142251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF32);
2143251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_PLTOFF64);
2144251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LOAD);
2145251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GDCALL);
2146251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDCALL);
2147251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD32);
2148251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GD64);
2149251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE12);
2150251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE32);
2151251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE64);
2152251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM32);
2153251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDM64);
2154251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE32);
2155251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IE64);
2156251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_IEENT);
2157251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE32);
2158251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LE64);
2159251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO32);
2160251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_LDO64);
2161251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPMOD);
2162251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_DTPOFF);
2163251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_TPOFF);
2164251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_20);
2165251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOT20);
2166251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_GOTPLT20);
2167251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_TLS_GOTIE20);
2168251662Sdim      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_390_IRELATIVE);
2169251662Sdim    default: break;
2170251662Sdim    }
2171251662Sdim    break;
2172251662Sdim  default: break;
2173234285Sdim  }
2174251662Sdim  return Res;
2175234285Sdim}
2176234285Sdim
2177234285Sdim#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
2178234285Sdim
2179249423Sdimtemplate<class ELFT>
2180251662Sdimerror_code ELFObjectFile<ELFT>::getRelocationTypeName(
2181251662Sdim    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2182251662Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
2183251662Sdim  uint32_t type;
2184251662Sdim  switch (sec->sh_type) {
2185251662Sdim    default :
2186251662Sdim      return object_error::parse_failed;
2187251662Sdim    case ELF::SHT_REL : {
2188251662Sdim      type = getRel(Rel)->getType(isMips64EL());
2189251662Sdim      break;
2190251662Sdim    }
2191251662Sdim    case ELF::SHT_RELA : {
2192251662Sdim      type = getRela(Rel)->getType(isMips64EL());
2193251662Sdim      break;
2194251662Sdim    }
2195251662Sdim  }
2196251662Sdim
2197251662Sdim  if (!isMips64EL()) {
2198251662Sdim    StringRef Name = getRelocationTypeName(type);
2199251662Sdim    Result.append(Name.begin(), Name.end());
2200251662Sdim  } else {
2201251662Sdim    uint8_t Type1 = (type >>  0) & 0xFF;
2202251662Sdim    uint8_t Type2 = (type >>  8) & 0xFF;
2203251662Sdim    uint8_t Type3 = (type >> 16) & 0xFF;
2204251662Sdim
2205251662Sdim    // Concat all three relocation type names.
2206251662Sdim    StringRef Name = getRelocationTypeName(Type1);
2207251662Sdim    Result.append(Name.begin(), Name.end());
2208251662Sdim
2209251662Sdim    Name = getRelocationTypeName(Type2);
2210251662Sdim    Result.append(1, '/');
2211251662Sdim    Result.append(Name.begin(), Name.end());
2212251662Sdim
2213251662Sdim    Name = getRelocationTypeName(Type3);
2214251662Sdim    Result.append(1, '/');
2215251662Sdim    Result.append(Name.begin(), Name.end());
2216251662Sdim  }
2217251662Sdim
2218251662Sdim  return object_error::success;
2219251662Sdim}
2220251662Sdim
2221251662Sdimtemplate<class ELFT>
2222249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo(
2223249423Sdim    DataRefImpl Rel, int64_t &Result) const {
2224234285Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
2225234285Sdim  switch (sec->sh_type) {
2226234285Sdim    default :
2227234285Sdim      report_fatal_error("Invalid section type in Rel!");
2228234285Sdim    case ELF::SHT_REL : {
2229234285Sdim      Result = 0;
2230234285Sdim      return object_error::success;
2231234285Sdim    }
2232234285Sdim    case ELF::SHT_RELA : {
2233234285Sdim      Result = getRela(Rel)->r_addend;
2234234285Sdim      return object_error::success;
2235234285Sdim    }
2236234285Sdim  }
2237234285Sdim}
2238234285Sdim
2239249423Sdimtemplate<class ELFT>
2240249423Sdimerror_code ELFObjectFile<ELFT>::getRelocationValueString(
2241249423Sdim    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
2242234285Sdim  const Elf_Shdr *sec = getSection(Rel.w.b);
2243234285Sdim  uint8_t type;
2244234285Sdim  StringRef res;
2245234285Sdim  int64_t addend = 0;
2246234285Sdim  uint16_t symbol_index = 0;
2247234285Sdim  switch (sec->sh_type) {
2248243830Sdim    default:
2249234285Sdim      return object_error::parse_failed;
2250243830Sdim    case ELF::SHT_REL: {
2251249423Sdim      type = getRel(Rel)->getType(isMips64EL());
2252249423Sdim      symbol_index = getRel(Rel)->getSymbol(isMips64EL());
2253234285Sdim      // TODO: Read implicit addend from section data.
2254234285Sdim      break;
2255234285Sdim    }
2256243830Sdim    case ELF::SHT_RELA: {
2257249423Sdim      type = getRela(Rel)->getType(isMips64EL());
2258249423Sdim      symbol_index = getRela(Rel)->getSymbol(isMips64EL());
2259234285Sdim      addend = getRela(Rel)->r_addend;
2260234285Sdim      break;
2261234285Sdim    }
2262234285Sdim  }
2263234285Sdim  const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
2264234285Sdim  StringRef symname;
2265234285Sdim  if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname))
2266234285Sdim    return ec;
2267234285Sdim  switch (Header->e_machine) {
2268234285Sdim  case ELF::EM_X86_64:
2269234285Sdim    switch (type) {
2270243830Sdim    case ELF::R_X86_64_PC8:
2271243830Sdim    case ELF::R_X86_64_PC16:
2272234285Sdim    case ELF::R_X86_64_PC32: {
2273234285Sdim        std::string fmtbuf;
2274234285Sdim        raw_string_ostream fmt(fmtbuf);
2275234285Sdim        fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
2276234285Sdim        fmt.flush();
2277234285Sdim        Result.append(fmtbuf.begin(), fmtbuf.end());
2278234285Sdim      }
2279234285Sdim      break;
2280243830Sdim    case ELF::R_X86_64_8:
2281243830Sdim    case ELF::R_X86_64_16:
2282243830Sdim    case ELF::R_X86_64_32:
2283243830Sdim    case ELF::R_X86_64_32S:
2284243830Sdim    case ELF::R_X86_64_64: {
2285243830Sdim        std::string fmtbuf;
2286243830Sdim        raw_string_ostream fmt(fmtbuf);
2287243830Sdim        fmt << symname << (addend < 0 ? "" : "+") << addend;
2288243830Sdim        fmt.flush();
2289243830Sdim        Result.append(fmtbuf.begin(), fmtbuf.end());
2290243830Sdim      }
2291243830Sdim      break;
2292234285Sdim    default:
2293234285Sdim      res = "Unknown";
2294234285Sdim    }
2295234285Sdim    break;
2296249423Sdim  case ELF::EM_AARCH64:
2297243830Sdim  case ELF::EM_ARM:
2298239462Sdim  case ELF::EM_HEXAGON:
2299239462Sdim    res = symname;
2300239462Sdim    break;
2301234285Sdim  default:
2302234285Sdim    res = "Unknown";
2303234285Sdim  }
2304234285Sdim  if (Result.empty())
2305234285Sdim    Result.append(res.begin(), res.end());
2306234285Sdim  return object_error::success;
2307234285Sdim}
2308234285Sdim
2309234285Sdim// Verify that the last byte in the string table in a null.
2310249423Sdimtemplate<class ELFT>
2311249423Sdimvoid ELFObjectFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
2312234285Sdim  const char *strtab = (const char*)base() + sh->sh_offset;
2313234285Sdim  if (strtab[sh->sh_size - 1] != 0)
2314234285Sdim    // FIXME: Proper error handling.
2315234285Sdim    report_fatal_error("String table must end with a null terminator!");
2316234285Sdim}
2317234285Sdim
2318249423Sdimtemplate<class ELFT>
2319249423SdimELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
2320249423Sdim  : ObjectFile(getELFType(
2321249423Sdim      static_cast<endianness>(ELFT::TargetEndianness) == support::little,
2322249423Sdim      ELFT::Is64Bits),
2323251662Sdim      Object)
2324234285Sdim  , isDyldELFObject(false)
2325234285Sdim  , SectionHeaderTable(0)
2326234285Sdim  , dot_shstrtab_sec(0)
2327234285Sdim  , dot_strtab_sec(0)
2328234285Sdim  , dot_dynstr_sec(0)
2329234285Sdim  , dot_dynamic_sec(0)
2330234285Sdim  , dot_gnu_version_sec(0)
2331234285Sdim  , dot_gnu_version_r_sec(0)
2332234285Sdim  , dot_gnu_version_d_sec(0)
2333234285Sdim  , dt_soname(0)
2334234285Sdim {
2335234285Sdim
2336234285Sdim  const uint64_t FileSize = Data->getBufferSize();
2337234285Sdim
2338234285Sdim  if (sizeof(Elf_Ehdr) > FileSize)
2339234285Sdim    // FIXME: Proper error handling.
2340234285Sdim    report_fatal_error("File too short!");
2341234285Sdim
2342234285Sdim  Header = reinterpret_cast<const Elf_Ehdr *>(base());
2343234285Sdim
2344234285Sdim  if (Header->e_shoff == 0)
2345234285Sdim    return;
2346234285Sdim
2347234285Sdim  const uint64_t SectionTableOffset = Header->e_shoff;
2348234285Sdim
2349234285Sdim  if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
2350234285Sdim    // FIXME: Proper error handling.
2351234285Sdim    report_fatal_error("Section header table goes past end of file!");
2352234285Sdim
2353234285Sdim  // The getNumSections() call below depends on SectionHeaderTable being set.
2354234285Sdim  SectionHeaderTable =
2355234285Sdim    reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
2356234285Sdim  const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
2357234285Sdim
2358234285Sdim  if (SectionTableOffset + SectionTableSize > FileSize)
2359234285Sdim    // FIXME: Proper error handling.
2360234285Sdim    report_fatal_error("Section table goes past end of file!");
2361234285Sdim
2362234285Sdim  // To find the symbol tables we walk the section table to find SHT_SYMTAB.
2363234285Sdim  const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
2364234285Sdim  const Elf_Shdr* sh = SectionHeaderTable;
2365234285Sdim
2366234285Sdim  // Reserve SymbolTableSections[0] for .dynsym
2367234285Sdim  SymbolTableSections.push_back(NULL);
2368234285Sdim
2369234285Sdim  for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
2370234285Sdim    switch (sh->sh_type) {
2371234285Sdim    case ELF::SHT_SYMTAB_SHNDX: {
2372234285Sdim      if (SymbolTableSectionHeaderIndex)
2373234285Sdim        // FIXME: Proper error handling.
2374234285Sdim        report_fatal_error("More than one .symtab_shndx!");
2375234285Sdim      SymbolTableSectionHeaderIndex = sh;
2376234285Sdim      break;
2377234285Sdim    }
2378234285Sdim    case ELF::SHT_SYMTAB: {
2379234285Sdim      SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
2380234285Sdim      SymbolTableSections.push_back(sh);
2381234285Sdim      break;
2382234285Sdim    }
2383234285Sdim    case ELF::SHT_DYNSYM: {
2384234285Sdim      if (SymbolTableSections[0] != NULL)
2385234285Sdim        // FIXME: Proper error handling.
2386234285Sdim        report_fatal_error("More than one .dynsym!");
2387234285Sdim      SymbolTableSectionsIndexMap[i] = 0;
2388234285Sdim      SymbolTableSections[0] = sh;
2389234285Sdim      break;
2390234285Sdim    }
2391234285Sdim    case ELF::SHT_REL:
2392234285Sdim    case ELF::SHT_RELA: {
2393234285Sdim      SectionRelocMap[getSection(sh->sh_info)].push_back(i);
2394234285Sdim      break;
2395234285Sdim    }
2396234285Sdim    case ELF::SHT_DYNAMIC: {
2397234285Sdim      if (dot_dynamic_sec != NULL)
2398234285Sdim        // FIXME: Proper error handling.
2399234285Sdim        report_fatal_error("More than one .dynamic!");
2400234285Sdim      dot_dynamic_sec = sh;
2401234285Sdim      break;
2402234285Sdim    }
2403234285Sdim    case ELF::SHT_GNU_versym: {
2404234285Sdim      if (dot_gnu_version_sec != NULL)
2405234285Sdim        // FIXME: Proper error handling.
2406234285Sdim        report_fatal_error("More than one .gnu.version section!");
2407234285Sdim      dot_gnu_version_sec = sh;
2408234285Sdim      break;
2409234285Sdim    }
2410234285Sdim    case ELF::SHT_GNU_verdef: {
2411234285Sdim      if (dot_gnu_version_d_sec != NULL)
2412234285Sdim        // FIXME: Proper error handling.
2413234285Sdim        report_fatal_error("More than one .gnu.version_d section!");
2414234285Sdim      dot_gnu_version_d_sec = sh;
2415234285Sdim      break;
2416234285Sdim    }
2417234285Sdim    case ELF::SHT_GNU_verneed: {
2418234285Sdim      if (dot_gnu_version_r_sec != NULL)
2419234285Sdim        // FIXME: Proper error handling.
2420234285Sdim        report_fatal_error("More than one .gnu.version_r section!");
2421234285Sdim      dot_gnu_version_r_sec = sh;
2422234285Sdim      break;
2423234285Sdim    }
2424234285Sdim    }
2425234285Sdim    ++sh;
2426234285Sdim  }
2427234285Sdim
2428234285Sdim  // Sort section relocation lists by index.
2429234285Sdim  for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
2430234285Sdim                                     e = SectionRelocMap.end(); i != e; ++i) {
2431234285Sdim    std::sort(i->second.begin(), i->second.end());
2432234285Sdim  }
2433234285Sdim
2434234285Sdim  // Get string table sections.
2435234285Sdim  dot_shstrtab_sec = getSection(getStringTableIndex());
2436234285Sdim  if (dot_shstrtab_sec) {
2437234285Sdim    // Verify that the last byte in the string table in a null.
2438234285Sdim    VerifyStrTab(dot_shstrtab_sec);
2439234285Sdim  }
2440234285Sdim
2441234285Sdim  // Merge this into the above loop.
2442234285Sdim  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
2443234285Sdim                  *e = i + getNumSections() * Header->e_shentsize;
2444234285Sdim                   i != e; i += Header->e_shentsize) {
2445234285Sdim    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
2446234285Sdim    if (sh->sh_type == ELF::SHT_STRTAB) {
2447234285Sdim      StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
2448234285Sdim      if (SectionName == ".strtab") {
2449234285Sdim        if (dot_strtab_sec != 0)
2450234285Sdim          // FIXME: Proper error handling.
2451234285Sdim          report_fatal_error("Already found section named .strtab!");
2452234285Sdim        dot_strtab_sec = sh;
2453234285Sdim        VerifyStrTab(dot_strtab_sec);
2454234285Sdim      } else if (SectionName == ".dynstr") {
2455234285Sdim        if (dot_dynstr_sec != 0)
2456234285Sdim          // FIXME: Proper error handling.
2457234285Sdim          report_fatal_error("Already found section named .dynstr!");
2458234285Sdim        dot_dynstr_sec = sh;
2459234285Sdim        VerifyStrTab(dot_dynstr_sec);
2460234285Sdim      }
2461234285Sdim    }
2462234285Sdim  }
2463234285Sdim
2464234285Sdim  // Build symbol name side-mapping if there is one.
2465234285Sdim  if (SymbolTableSectionHeaderIndex) {
2466234285Sdim    const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
2467234285Sdim                                      SymbolTableSectionHeaderIndex->sh_offset);
2468234285Sdim    error_code ec;
2469234285Sdim    for (symbol_iterator si = begin_symbols(),
2470234285Sdim                         se = end_symbols(); si != se; si.increment(ec)) {
2471234285Sdim      if (ec)
2472234285Sdim        report_fatal_error("Fewer extended symbol table entries than symbols!");
2473234285Sdim      if (*ShndxTable != ELF::SHN_UNDEF)
2474234285Sdim        ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable;
2475234285Sdim      ++ShndxTable;
2476234285Sdim    }
2477234285Sdim  }
2478234285Sdim}
2479234285Sdim
2480249423Sdim// Get the symbol table index in the symtab section given a symbol
2481249423Sdimtemplate<class ELFT>
2482249423Sdimuint64_t ELFObjectFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const {
2483249423Sdim  assert(SymbolTableSections.size() == 1 && "Only one symbol table supported!");
2484249423Sdim  const Elf_Shdr *SymTab = *SymbolTableSections.begin();
2485249423Sdim  uintptr_t SymLoc = uintptr_t(Sym);
2486249423Sdim  uintptr_t SymTabLoc = uintptr_t(base() + SymTab->sh_offset);
2487249423Sdim  assert(SymLoc > SymTabLoc && "Symbol not in symbol table!");
2488249423Sdim  uint64_t SymOffset = SymLoc - SymTabLoc;
2489249423Sdim  assert(SymOffset % SymTab->sh_entsize == 0 &&
2490249423Sdim         "Symbol not multiple of symbol size!");
2491249423Sdim  return SymOffset / SymTab->sh_entsize;
2492249423Sdim}
2493249423Sdim
2494249423Sdimtemplate<class ELFT>
2495249423Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_symbols() const {
2496234285Sdim  DataRefImpl SymbolData;
2497234285Sdim  if (SymbolTableSections.size() <= 1) {
2498234285Sdim    SymbolData.d.a = std::numeric_limits<uint32_t>::max();
2499234285Sdim    SymbolData.d.b = std::numeric_limits<uint32_t>::max();
2500234285Sdim  } else {
2501234285Sdim    SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
2502234285Sdim    SymbolData.d.b = 1; // The 0th table is .dynsym
2503234285Sdim  }
2504234285Sdim  return symbol_iterator(SymbolRef(SymbolData, this));
2505234285Sdim}
2506234285Sdim
2507249423Sdimtemplate<class ELFT>
2508249423Sdimsymbol_iterator ELFObjectFile<ELFT>::end_symbols() const {
2509234285Sdim  DataRefImpl SymbolData;
2510234285Sdim  SymbolData.d.a = std::numeric_limits<uint32_t>::max();
2511234285Sdim  SymbolData.d.b = std::numeric_limits<uint32_t>::max();
2512234285Sdim  return symbol_iterator(SymbolRef(SymbolData, this));
2513234285Sdim}
2514234285Sdim
2515249423Sdimtemplate<class ELFT>
2516249423Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const {
2517234285Sdim  DataRefImpl SymbolData;
2518234285Sdim  if (SymbolTableSections[0] == NULL) {
2519234285Sdim    SymbolData.d.a = std::numeric_limits<uint32_t>::max();
2520234285Sdim    SymbolData.d.b = std::numeric_limits<uint32_t>::max();
2521234285Sdim  } else {
2522234285Sdim    SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
2523234285Sdim    SymbolData.d.b = 0; // The 0th table is .dynsym
2524234285Sdim  }
2525234285Sdim  return symbol_iterator(SymbolRef(SymbolData, this));
2526234285Sdim}
2527234285Sdim
2528249423Sdimtemplate<class ELFT>
2529249423Sdimsymbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const {
2530234285Sdim  DataRefImpl SymbolData;
2531234285Sdim  SymbolData.d.a = std::numeric_limits<uint32_t>::max();
2532234285Sdim  SymbolData.d.b = std::numeric_limits<uint32_t>::max();
2533234285Sdim  return symbol_iterator(SymbolRef(SymbolData, this));
2534234285Sdim}
2535234285Sdim
2536249423Sdimtemplate<class ELFT>
2537249423Sdimsection_iterator ELFObjectFile<ELFT>::begin_sections() const {
2538234285Sdim  DataRefImpl ret;
2539234285Sdim  ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
2540234285Sdim  return section_iterator(SectionRef(ret, this));
2541234285Sdim}
2542234285Sdim
2543249423Sdimtemplate<class ELFT>
2544249423Sdimsection_iterator ELFObjectFile<ELFT>::end_sections() const {
2545234285Sdim  DataRefImpl ret;
2546234285Sdim  ret.p = reinterpret_cast<intptr_t>(base()
2547234285Sdim                                     + Header->e_shoff
2548234285Sdim                                     + (Header->e_shentsize*getNumSections()));
2549234285Sdim  return section_iterator(SectionRef(ret, this));
2550234285Sdim}
2551234285Sdim
2552249423Sdimtemplate<class ELFT>
2553249423Sdimtypename ELFObjectFile<ELFT>::Elf_Dyn_iterator
2554249423SdimELFObjectFile<ELFT>::begin_dynamic_table() const {
2555249423Sdim  if (dot_dynamic_sec)
2556249423Sdim    return Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
2557249423Sdim                            (const char *)base() + dot_dynamic_sec->sh_offset);
2558249423Sdim  return Elf_Dyn_iterator(0, 0);
2559234285Sdim}
2560234285Sdim
2561249423Sdimtemplate<class ELFT>
2562249423Sdimtypename ELFObjectFile<ELFT>::Elf_Dyn_iterator
2563249423SdimELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
2564249423Sdim  if (dot_dynamic_sec) {
2565249423Sdim    Elf_Dyn_iterator Ret(dot_dynamic_sec->sh_entsize,
2566249423Sdim                         (const char *)base() + dot_dynamic_sec->sh_offset +
2567249423Sdim                         dot_dynamic_sec->sh_size);
2568234285Sdim
2569249423Sdim    if (NULLEnd) {
2570249423Sdim      Elf_Dyn_iterator Start = begin_dynamic_table();
2571249423Sdim      while (Start != Ret && Start->getTag() != ELF::DT_NULL)
2572249423Sdim        ++Start;
2573234285Sdim
2574249423Sdim      // Include the DT_NULL.
2575249423Sdim      if (Start != Ret)
2576249423Sdim        ++Start;
2577249423Sdim      Ret = Start;
2578249423Sdim    }
2579249423Sdim    return Ret;
2580234285Sdim  }
2581249423Sdim  return Elf_Dyn_iterator(0, 0);
2582234285Sdim}
2583234285Sdim
2584249423Sdimtemplate<class ELFT>
2585249423SdimStringRef ELFObjectFile<ELFT>::getLoadName() const {
2586234285Sdim  if (!dt_soname) {
2587234285Sdim    // Find the DT_SONAME entry
2588249423Sdim    Elf_Dyn_iterator it = begin_dynamic_table();
2589249423Sdim    Elf_Dyn_iterator ie = end_dynamic_table();
2590249423Sdim    while (it != ie && it->getTag() != ELF::DT_SONAME)
2591249423Sdim      ++it;
2592249423Sdim
2593234285Sdim    if (it != ie) {
2594234285Sdim      if (dot_dynstr_sec == NULL)
2595234285Sdim        report_fatal_error("Dynamic string table is missing");
2596234285Sdim      dt_soname = getString(dot_dynstr_sec, it->getVal());
2597234285Sdim    } else {
2598234285Sdim      dt_soname = "";
2599234285Sdim    }
2600234285Sdim  }
2601234285Sdim  return dt_soname;
2602234285Sdim}
2603234285Sdim
2604249423Sdimtemplate<class ELFT>
2605249423Sdimlibrary_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
2606234285Sdim  // Find the first DT_NEEDED entry
2607249423Sdim  Elf_Dyn_iterator i = begin_dynamic_table();
2608249423Sdim  Elf_Dyn_iterator e = end_dynamic_table();
2609249423Sdim  while (i != e && i->getTag() != ELF::DT_NEEDED)
2610249423Sdim    ++i;
2611249423Sdim
2612249423Sdim  DataRefImpl DRI;
2613249423Sdim  DRI.p = reinterpret_cast<uintptr_t>(i.get());
2614249423Sdim  return library_iterator(LibraryRef(DRI, this));
2615234285Sdim}
2616234285Sdim
2617249423Sdimtemplate<class ELFT>
2618249423Sdimerror_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
2619249423Sdim                                               LibraryRef &Result) const {
2620234285Sdim  // Use the same DataRefImpl format as DynRef.
2621249423Sdim  Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
2622249423Sdim                                        reinterpret_cast<const char *>(Data.p));
2623249423Sdim  Elf_Dyn_iterator e = end_dynamic_table();
2624234285Sdim
2625249423Sdim  // Skip the current dynamic table entry and find the next DT_NEEDED entry.
2626249423Sdim  do
2627249423Sdim    ++i;
2628249423Sdim  while (i != e && i->getTag() != ELF::DT_NEEDED);
2629234285Sdim
2630249423Sdim  DataRefImpl DRI;
2631249423Sdim  DRI.p = reinterpret_cast<uintptr_t>(i.get());
2632249423Sdim  Result = LibraryRef(DRI, this);
2633234285Sdim  return object_error::success;
2634234285Sdim}
2635234285Sdim
2636249423Sdimtemplate<class ELFT>
2637249423Sdimerror_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
2638249423Sdim                                               StringRef &Res) const {
2639249423Sdim  Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
2640249423Sdim                                        reinterpret_cast<const char *>(Data.p));
2641234285Sdim  if (i == end_dynamic_table())
2642234285Sdim    report_fatal_error("getLibraryPath() called on iterator end");
2643234285Sdim
2644234285Sdim  if (i->getTag() != ELF::DT_NEEDED)
2645234285Sdim    report_fatal_error("Invalid library_iterator");
2646234285Sdim
2647234285Sdim  // This uses .dynstr to lookup the name of the DT_NEEDED entry.
2648234285Sdim  // THis works as long as DT_STRTAB == .dynstr. This is true most of
2649234285Sdim  // the time, but the specification allows exceptions.
2650234285Sdim  // TODO: This should really use DT_STRTAB instead. Doing this requires
2651234285Sdim  // reading the program headers.
2652234285Sdim  if (dot_dynstr_sec == NULL)
2653234285Sdim    report_fatal_error("Dynamic string table is missing");
2654234285Sdim  Res = getString(dot_dynstr_sec, i->getVal());
2655234285Sdim  return object_error::success;
2656234285Sdim}
2657234285Sdim
2658249423Sdimtemplate<class ELFT>
2659249423Sdimlibrary_iterator ELFObjectFile<ELFT>::end_libraries_needed() const {
2660249423Sdim  Elf_Dyn_iterator e = end_dynamic_table();
2661249423Sdim  DataRefImpl DRI;
2662249423Sdim  DRI.p = reinterpret_cast<uintptr_t>(e.get());
2663249423Sdim  return library_iterator(LibraryRef(DRI, this));
2664234285Sdim}
2665234285Sdim
2666249423Sdimtemplate<class ELFT>
2667249423Sdimuint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
2668249423Sdim  return ELFT::Is64Bits ? 8 : 4;
2669234285Sdim}
2670234285Sdim
2671249423Sdimtemplate<class ELFT>
2672249423SdimStringRef ELFObjectFile<ELFT>::getFileFormatName() const {
2673234285Sdim  switch(Header->e_ident[ELF::EI_CLASS]) {
2674234285Sdim  case ELF::ELFCLASS32:
2675234285Sdim    switch(Header->e_machine) {
2676234285Sdim    case ELF::EM_386:
2677234285Sdim      return "ELF32-i386";
2678234285Sdim    case ELF::EM_X86_64:
2679234285Sdim      return "ELF32-x86-64";
2680234285Sdim    case ELF::EM_ARM:
2681234285Sdim      return "ELF32-arm";
2682239462Sdim    case ELF::EM_HEXAGON:
2683239462Sdim      return "ELF32-hexagon";
2684249423Sdim    case ELF::EM_MIPS:
2685249423Sdim      return "ELF32-mips";
2686234285Sdim    default:
2687234285Sdim      return "ELF32-unknown";
2688234285Sdim    }
2689234285Sdim  case ELF::ELFCLASS64:
2690234285Sdim    switch(Header->e_machine) {
2691234285Sdim    case ELF::EM_386:
2692234285Sdim      return "ELF64-i386";
2693234285Sdim    case ELF::EM_X86_64:
2694234285Sdim      return "ELF64-x86-64";
2695249423Sdim    case ELF::EM_AARCH64:
2696249423Sdim      return "ELF64-aarch64";
2697243830Sdim    case ELF::EM_PPC64:
2698243830Sdim      return "ELF64-ppc64";
2699251662Sdim    case ELF::EM_S390:
2700251662Sdim      return "ELF64-s390";
2701234285Sdim    default:
2702234285Sdim      return "ELF64-unknown";
2703234285Sdim    }
2704234285Sdim  default:
2705234285Sdim    // FIXME: Proper error handling.
2706234285Sdim    report_fatal_error("Invalid ELFCLASS!");
2707234285Sdim  }
2708234285Sdim}
2709234285Sdim
2710249423Sdimtemplate<class ELFT>
2711249423Sdimunsigned ELFObjectFile<ELFT>::getArch() const {
2712234285Sdim  switch(Header->e_machine) {
2713234285Sdim  case ELF::EM_386:
2714234285Sdim    return Triple::x86;
2715234285Sdim  case ELF::EM_X86_64:
2716234285Sdim    return Triple::x86_64;
2717249423Sdim  case ELF::EM_AARCH64:
2718249423Sdim    return Triple::aarch64;
2719234285Sdim  case ELF::EM_ARM:
2720234285Sdim    return Triple::arm;
2721239462Sdim  case ELF::EM_HEXAGON:
2722239462Sdim    return Triple::hexagon;
2723243830Sdim  case ELF::EM_MIPS:
2724249423Sdim    return (ELFT::TargetEndianness == support::little) ?
2725243830Sdim           Triple::mipsel : Triple::mips;
2726243830Sdim  case ELF::EM_PPC64:
2727243830Sdim    return Triple::ppc64;
2728251662Sdim  case ELF::EM_S390:
2729251662Sdim    return Triple::systemz;
2730234285Sdim  default:
2731234285Sdim    return Triple::UnknownArch;
2732234285Sdim  }
2733234285Sdim}
2734234285Sdim
2735249423Sdimtemplate<class ELFT>
2736249423Sdimuint64_t ELFObjectFile<ELFT>::getNumSections() const {
2737234285Sdim  assert(Header && "Header not initialized!");
2738234285Sdim  if (Header->e_shnum == ELF::SHN_UNDEF) {
2739234285Sdim    assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
2740234285Sdim    return SectionHeaderTable->sh_size;
2741234285Sdim  }
2742234285Sdim  return Header->e_shnum;
2743234285Sdim}
2744234285Sdim
2745249423Sdimtemplate<class ELFT>
2746234285Sdimuint64_t
2747249423SdimELFObjectFile<ELFT>::getStringTableIndex() const {
2748234285Sdim  if (Header->e_shnum == ELF::SHN_UNDEF) {
2749234285Sdim    if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
2750234285Sdim      return SectionHeaderTable->sh_link;
2751234285Sdim    if (Header->e_shstrndx >= getNumSections())
2752234285Sdim      return 0;
2753234285Sdim  }
2754234285Sdim  return Header->e_shstrndx;
2755234285Sdim}
2756234285Sdim
2757249423Sdimtemplate<class ELFT>
2758234285Sdimtemplate<typename T>
2759234285Sdiminline const T *
2760249423SdimELFObjectFile<ELFT>::getEntry(uint16_t Section, uint32_t Entry) const {
2761234285Sdim  return getEntry<T>(getSection(Section), Entry);
2762234285Sdim}
2763234285Sdim
2764249423Sdimtemplate<class ELFT>
2765234285Sdimtemplate<typename T>
2766234285Sdiminline const T *
2767249423SdimELFObjectFile<ELFT>::getEntry(const Elf_Shdr * Section, uint32_t Entry) const {
2768234285Sdim  return reinterpret_cast<const T *>(
2769234285Sdim           base()
2770234285Sdim           + Section->sh_offset
2771234285Sdim           + (Entry * Section->sh_entsize));
2772234285Sdim}
2773234285Sdim
2774249423Sdimtemplate<class ELFT>
2775249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Sym *
2776249423SdimELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
2777234285Sdim  return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
2778234285Sdim}
2779234285Sdim
2780249423Sdimtemplate<class ELFT>
2781249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Rel *
2782249423SdimELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
2783234285Sdim  return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
2784234285Sdim}
2785234285Sdim
2786249423Sdimtemplate<class ELFT>
2787249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Rela *
2788249423SdimELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
2789234285Sdim  return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
2790234285Sdim}
2791234285Sdim
2792249423Sdimtemplate<class ELFT>
2793249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr *
2794249423SdimELFObjectFile<ELFT>::getSection(DataRefImpl Symb) const {
2795234285Sdim  const Elf_Shdr *sec = getSection(Symb.d.b);
2796234285Sdim  if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
2797234285Sdim    // FIXME: Proper error handling.
2798234285Sdim    report_fatal_error("Invalid symbol table section!");
2799234285Sdim  return sec;
2800234285Sdim}
2801234285Sdim
2802249423Sdimtemplate<class ELFT>
2803249423Sdimconst typename ELFObjectFile<ELFT>::Elf_Shdr *
2804249423SdimELFObjectFile<ELFT>::getSection(uint32_t index) const {
2805234285Sdim  if (index == 0)
2806234285Sdim    return 0;
2807234285Sdim  if (!SectionHeaderTable || index >= getNumSections())
2808234285Sdim    // FIXME: Proper error handling.
2809234285Sdim    report_fatal_error("Invalid section index!");
2810234285Sdim
2811234285Sdim  return reinterpret_cast<const Elf_Shdr *>(
2812234285Sdim         reinterpret_cast<const char *>(SectionHeaderTable)
2813234285Sdim         + (index * Header->e_shentsize));
2814234285Sdim}
2815234285Sdim
2816249423Sdimtemplate<class ELFT>
2817249423Sdimconst char *ELFObjectFile<ELFT>::getString(uint32_t section,
2818249423Sdim                                           ELF::Elf32_Word offset) const {
2819234285Sdim  return getString(getSection(section), offset);
2820234285Sdim}
2821234285Sdim
2822249423Sdimtemplate<class ELFT>
2823249423Sdimconst char *ELFObjectFile<ELFT>::getString(const Elf_Shdr *section,
2824249423Sdim                                           ELF::Elf32_Word offset) const {
2825234285Sdim  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
2826234285Sdim  if (offset >= section->sh_size)
2827234285Sdim    // FIXME: Proper error handling.
2828234285Sdim    report_fatal_error("Symbol name offset outside of string table!");
2829234285Sdim  return (const char *)base() + section->sh_offset + offset;
2830234285Sdim}
2831234285Sdim
2832249423Sdimtemplate<class ELFT>
2833249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolName(const Elf_Shdr *section,
2834249423Sdim                                              const Elf_Sym *symb,
2835249423Sdim                                              StringRef &Result) const {
2836234285Sdim  if (symb->st_name == 0) {
2837234285Sdim    const Elf_Shdr *section = getSection(symb);
2838234285Sdim    if (!section)
2839234285Sdim      Result = "";
2840234285Sdim    else
2841234285Sdim      Result = getString(dot_shstrtab_sec, section->sh_name);
2842234285Sdim    return object_error::success;
2843234285Sdim  }
2844234285Sdim
2845234285Sdim  if (section == SymbolTableSections[0]) {
2846234285Sdim    // Symbol is in .dynsym, use .dynstr string table
2847234285Sdim    Result = getString(dot_dynstr_sec, symb->st_name);
2848234285Sdim  } else {
2849234285Sdim    // Use the default symbol table name section.
2850234285Sdim    Result = getString(dot_strtab_sec, symb->st_name);
2851234285Sdim  }
2852234285Sdim  return object_error::success;
2853234285Sdim}
2854234285Sdim
2855249423Sdimtemplate<class ELFT>
2856249423Sdimerror_code ELFObjectFile<ELFT>::getSectionName(const Elf_Shdr *section,
2857249423Sdim                                               StringRef &Result) const {
2858239462Sdim  Result = StringRef(getString(dot_shstrtab_sec, section->sh_name));
2859239462Sdim  return object_error::success;
2860239462Sdim}
2861239462Sdim
2862249423Sdimtemplate<class ELFT>
2863249423Sdimerror_code ELFObjectFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
2864249423Sdim                                                 const Elf_Sym *symb,
2865249423Sdim                                                 StringRef &Version,
2866249423Sdim                                                 bool &IsDefault) const {
2867234285Sdim  // Handle non-dynamic symbols.
2868234285Sdim  if (section != SymbolTableSections[0]) {
2869234285Sdim    // Non-dynamic symbols can have versions in their names
2870234285Sdim    // A name of the form 'foo@V1' indicates version 'V1', non-default.
2871234285Sdim    // A name of the form 'foo@@V2' indicates version 'V2', default version.
2872234285Sdim    StringRef Name;
2873234285Sdim    error_code ec = getSymbolName(section, symb, Name);
2874234285Sdim    if (ec != object_error::success)
2875234285Sdim      return ec;
2876234285Sdim    size_t atpos = Name.find('@');
2877234285Sdim    if (atpos == StringRef::npos) {
2878234285Sdim      Version = "";
2879234285Sdim      IsDefault = false;
2880234285Sdim      return object_error::success;
2881234285Sdim    }
2882234285Sdim    ++atpos;
2883234285Sdim    if (atpos < Name.size() && Name[atpos] == '@') {
2884234285Sdim      IsDefault = true;
2885234285Sdim      ++atpos;
2886234285Sdim    } else {
2887234285Sdim      IsDefault = false;
2888234285Sdim    }
2889234285Sdim    Version = Name.substr(atpos);
2890234285Sdim    return object_error::success;
2891234285Sdim  }
2892234285Sdim
2893234285Sdim  // This is a dynamic symbol. Look in the GNU symbol version table.
2894234285Sdim  if (dot_gnu_version_sec == NULL) {
2895234285Sdim    // No version table.
2896234285Sdim    Version = "";
2897234285Sdim    IsDefault = false;
2898234285Sdim    return object_error::success;
2899234285Sdim  }
2900234285Sdim
2901234285Sdim  // Determine the position in the symbol table of this entry.
2902234285Sdim  const char *sec_start = (const char*)base() + section->sh_offset;
2903234285Sdim  size_t entry_index = ((const char*)symb - sec_start)/section->sh_entsize;
2904234285Sdim
2905234285Sdim  // Get the corresponding version index entry
2906234285Sdim  const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
2907234285Sdim  size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
2908234285Sdim
2909234285Sdim  // Special markers for unversioned symbols.
2910234285Sdim  if (version_index == ELF::VER_NDX_LOCAL ||
2911234285Sdim      version_index == ELF::VER_NDX_GLOBAL) {
2912234285Sdim    Version = "";
2913234285Sdim    IsDefault = false;
2914234285Sdim    return object_error::success;
2915234285Sdim  }
2916234285Sdim
2917234285Sdim  // Lookup this symbol in the version table
2918234285Sdim  LoadVersionMap();
2919234285Sdim  if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
2920234285Sdim    report_fatal_error("Symbol has version index without corresponding "
2921234285Sdim                       "define or reference entry");
2922234285Sdim  const VersionMapEntry &entry = VersionMap[version_index];
2923234285Sdim
2924234285Sdim  // Get the version name string
2925234285Sdim  size_t name_offset;
2926234285Sdim  if (entry.isVerdef()) {
2927234285Sdim    // The first Verdaux entry holds the name.
2928234285Sdim    name_offset = entry.getVerdef()->getAux()->vda_name;
2929234285Sdim  } else {
2930234285Sdim    name_offset = entry.getVernaux()->vna_name;
2931234285Sdim  }
2932234285Sdim  Version = getString(dot_dynstr_sec, name_offset);
2933234285Sdim
2934234285Sdim  // Set IsDefault
2935234285Sdim  if (entry.isVerdef()) {
2936234285Sdim    IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
2937234285Sdim  } else {
2938234285Sdim    IsDefault = false;
2939234285Sdim  }
2940234285Sdim
2941234285Sdim  return object_error::success;
2942234285Sdim}
2943234285Sdim
2944234285Sdim/// This is a generic interface for retrieving GNU symbol version
2945234285Sdim/// information from an ELFObjectFile.
2946234285Sdimstatic inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
2947234285Sdim                                             const SymbolRef &Sym,
2948234285Sdim                                             StringRef &Version,
2949234285Sdim                                             bool &IsDefault) {
2950234285Sdim  // Little-endian 32-bit
2951249423Sdim  if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj =
2952249423Sdim          dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj))
2953234285Sdim    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
2954234285Sdim
2955234285Sdim  // Big-endian 32-bit
2956249423Sdim  if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj =
2957249423Sdim          dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj))
2958234285Sdim    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
2959234285Sdim
2960234285Sdim  // Little-endian 64-bit
2961249423Sdim  if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj =
2962249423Sdim          dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj))
2963234285Sdim    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
2964234285Sdim
2965234285Sdim  // Big-endian 64-bit
2966249423Sdim  if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj =
2967249423Sdim          dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj))
2968234285Sdim    return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
2969234285Sdim
2970234285Sdim  llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
2971234285Sdim}
2972234285Sdim
2973249423Sdim/// This function returns the hash value for a symbol in the .dynsym section
2974249423Sdim/// Name of the API remains consistent as specified in the libelf
2975249423Sdim/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
2976249423Sdimstatic inline unsigned elf_hash(StringRef &symbolName) {
2977249423Sdim  unsigned h = 0, g;
2978249423Sdim  for (unsigned i = 0, j = symbolName.size(); i < j; i++) {
2979249423Sdim    h = (h << 4) + symbolName[i];
2980249423Sdim    g = h & 0xf0000000L;
2981249423Sdim    if (g != 0)
2982249423Sdim      h ^= g >> 24;
2983249423Sdim    h &= ~g;
2984249423Sdim  }
2985249423Sdim  return h;
2986234285Sdim}
2987249423Sdim
2988234285Sdim}
2989249423Sdim}
2990234285Sdim
2991234285Sdim#endif
2992