ELFObjectFile.cpp revision 4344b1ef9b3721a5ebc2e024f753772a1e4ddd92
1b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
3b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//                     The LLVM Compiler Infrastructure
4b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
5b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// This file is distributed under the University of Illinois Open Source
6b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// License. See LICENSE.TXT for details.
7b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
8b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===----------------------------------------------------------------------===//
9b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
10b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// This file defines the ELFObjectFile class.
11b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
12b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===----------------------------------------------------------------------===//
13b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
14b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/ADT/SmallVector.h"
15b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/ADT/StringSwitch.h"
16b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/ADT/Triple.h"
170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer#include "llvm/ADT/DenseMap.h"
18b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Object/ObjectFile.h"
19b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/ELF.h"
20b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/Endian.h"
21b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/ErrorHandling.h"
22b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/MemoryBuffer.h"
234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#include "llvm/Support/raw_ostream.h"
244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#include <algorithm>
25b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include <limits>
26b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include <utility>
27b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
28b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerusing namespace llvm;
29b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerusing namespace object;
30b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
31b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
32b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
33b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
34b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelperCommon {
35b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
36b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint16_t, target_endianness, support::aligned> Elf_Half;
37b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
38b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Word;
39b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
40b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <int32_t, target_endianness, support::aligned> Elf_Sword;
41b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
42b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Xword;
43b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
44b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <int64_t, target_endianness, support::aligned> Elf_Sxword;
45b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
46b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
47b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
48b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
49b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
50b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper;
51b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
52b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer/// ELF 32bit types.
53b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
54b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper<target_endianness, false>
55b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  : ELFDataTypeTypedefHelperCommon<target_endianness> {
56b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
57b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Addr;
58b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
59b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Off;
60b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
61b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
62b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer/// ELF 64bit types.
63b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
64b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper<target_endianness, true>
65b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  : ELFDataTypeTypedefHelperCommon<target_endianness>{
66b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
67b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Addr;
68b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
69b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Off;
70b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
71b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
72b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
73b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// I really don't like doing this, but the alternative is copypasta.
74b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
75b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
76b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
77b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
78b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
79b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
80b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
81b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
82b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
83b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
84b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
85b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
86b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
87b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
88b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
89b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
90b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Section header.
91b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
92b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
93b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base;
94b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
95b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
96b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base<target_endianness, false> {
97b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
98b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_name;     // Section name (index into string table)
99b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_type;     // Section type (SHT_*)
100b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_flags;    // Section flags (SHF_*)
101b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr sh_addr;     // Address where section is to be loaded
102b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Off  sh_offset;   // File offset of section data, in bytes
103b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_size;     // Size of section, in bytes
104b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_link;     // Section type-specific header table index link
105b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_info;     // Section type-specific extra information
106b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_addralign;// Section address alignment
107b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_entsize;  // Size of records contained within the section
108b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
109b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
110b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
111b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base<target_endianness, true> {
112b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
113b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_name;     // Section name (index into string table)
114b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_type;     // Section type (SHT_*)
115b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_flags;    // Section flags (SHF_*)
116b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr  sh_addr;     // Address where section is to be loaded
117b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Off   sh_offset;   // File offset of section data, in bytes
118b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_size;     // Size of section, in bytes
119b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_link;     // Section type-specific header table index link
120b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_info;     // Section type-specific extra information
121b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_addralign;// Section address alignment
122b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_entsize;  // Size of records contained within the section
123b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
124b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
125b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
126b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
127b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
128b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
129b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
130b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  /// @brief Get the number of entities this section contains if it has any.
131b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned getEntityCount() const {
132b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh_entsize == 0)
133b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return 0;
1347acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    return sh_size / sh_entsize;
135b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
136b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
137b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
138b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
139b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
140b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
141b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base;
142b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
143b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
144b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base<target_endianness, false> {
145b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
146b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_name;  // Symbol name (index into string table)
147b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr      st_value; // Value or address associated with the symbol
148b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_size;  // Size of the symbol
149b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_info;  // Symbol's type and binding attributes
150b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_other; // Must be zero; reserved
151b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Half      st_shndx; // Which section (header table index) it's defined in
152b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
153b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
154b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
155b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base<target_endianness, true> {
156b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
157b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_name;  // Symbol name (index into string table)
158b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_info;  // Symbol's type and binding attributes
159b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_other; // Must be zero; reserved
160b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Half      st_shndx; // Which section (header table index) it's defined in
161b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr      st_value; // Value or address associated with the symbol
162b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword     st_size;  // Size of the symbol
163b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
164b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
165b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
166b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
167b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
168b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
169b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // These accessors and mutators correspond to the ELF32_ST_BIND,
170b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
171b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char getBinding() const { return st_info >> 4; }
172b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char getType() const { return st_info & 0x0f; }
173b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
174b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
175b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setBindingAndType(unsigned char b, unsigned char t) {
176b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    st_info = (b << 4) + (t & 0x0f);
177b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
178b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
179b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
180b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
181b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
1820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits, bool isRela>
1830fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Base;
1840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
1850fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness>
1860fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Base<target_endianness, false, false> {
1870fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
1880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
1890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Word      r_info;  // Symbol table index and type of relocation to apply
1900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
1910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
1920fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness>
1930fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Base<target_endianness, true, false> {
1940fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
1950fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
1960fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Xword     r_info;   // Symbol table index and type of relocation to apply
1970fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
1980fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
1990fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness>
2000fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Base<target_endianness, false, true> {
2010fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
2020fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
2030fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Word      r_info;   // Symbol table index and type of relocation to apply
2040fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Sword     r_addend; // Compute value for relocatable field by adding this
2050fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
2060fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2070fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness>
2080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Base<target_endianness, true, true> {
2090fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
2100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Addr      r_offset; // Location (file byte offset, or program virtual addr)
2110fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Xword     r_info;   // Symbol table index and type of relocation to apply
2120fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Elf_Sxword    r_addend; // Compute value for relocatable field by adding this.
2130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
2140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits, bool isRela>
2160fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Impl;
2170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool isRela>
2190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Impl<target_endianness, true, isRela>
2200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer       : Elf_Rel_Base<target_endianness, true, isRela> {
2210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  using Elf_Rel_Base<target_endianness, true, isRela>::r_info;
2220fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
2230fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2240fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
2250fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  // and ELF64_R_INFO macros defined in the ELF specification:
2260fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint64_t getSymbol() const { return (r_info >> 32); }
2270fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  unsigned char getType() const {
2280fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    return (unsigned char) (r_info & 0xffffffffL);
2290fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
2300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); }
2310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
2320fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setSymbolAndType(uint64_t s, unsigned char t) {
2330fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    r_info = (s << 32) + (t&0xffffffffL);
2340fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
2350fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
2360fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2370fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool isRela>
2380fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerstruct Elf_Rel_Impl<target_endianness, false, isRela>
2390fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer       : Elf_Rel_Base<target_endianness, false, isRela> {
2400fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  using Elf_Rel_Base<target_endianness, false, isRela>::r_info;
2410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
2420fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
2440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  // and ELF32_R_INFO macros defined in the ELF specification:
2450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint32_t getSymbol() const { return (r_info >> 8); }
2460fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
2470fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
2480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
2490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  void setSymbolAndType(uint32_t s, unsigned char t) {
2500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    r_info = (s << 8) + t;
2510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
2520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer};
2530fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
2550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
2560fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramernamespace {
257b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
258b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerclass ELFObjectFile : public ObjectFile {
259b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
260b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
261b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
262b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
2630fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
2640fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
265b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
266b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  struct Elf_Ehdr {
267b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
268b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_type;     // Type of file (see ET_*)
269b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_machine;  // Required architecture for this file (see EM_*)
270b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Word e_version;  // Must be equal to 1
271b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Addr e_entry;    // Address to jump to in order to start program
272b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Off  e_phoff;    // Program header table's file offset, in bytes
273b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Off  e_shoff;    // Section header table's file offset, in bytes
274b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Word e_flags;    // Processor-specific flags
275b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_ehsize;   // Size of ELF header, in bytes
276b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_phentsize;// Size of an entry in the program header table
277b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_phnum;    // Number of entries in the program header table
278b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shentsize;// Size of an entry in the section header table
279b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shnum;    // Number of entries in the section header table
280b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shstrndx; // Section header table index of section name
281b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                  // string table
282b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    bool checkMagic() const {
283b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
284b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
285b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
286b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
287b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  };
288b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
2890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  typedef SmallVector<const Elf_Shdr*, 1> Sections_t;
2900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  typedef DenseMap<unsigned, unsigned> IndexMap_t;
2914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
292b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
293b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Ehdr *Header;
294b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *SectionHeaderTable;
295b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
296b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
2970fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Sections_t SymbolTableSections;
2980fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  IndexMap_t SymbolTableSectionsIndexMap;
2994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  /// @brief Map sections to an array of relocation sections that reference
3014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  ///        them sorted by section index.
3024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  RelocMap_t SectionRelocMap;
3034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  /// @brief Get the relocation section that contains \a Rel.
3054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
3064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return getSection(Rel.w.b);
3074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
308b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
309b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void            validateSymbol(DataRefImpl Symb) const;
3100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  bool            isRelocationHasAddend(DataRefImpl Rel) const;
3110fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  template<typename T>
3124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const T        *getEntry(uint16_t Section, uint32_t Entry) const;
3134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  template<typename T>
3144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const T        *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
315b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *getSymbol(DataRefImpl Symb) const;
316b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *getSection(DataRefImpl index) const;
317b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *getSection(uint16_t index) const;
3180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const Elf_Rel  *getRel(DataRefImpl Rel) const;
3190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const Elf_Rela *getRela(DataRefImpl Rela) const;
320b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char     *getString(uint16_t section, uint32_t offset) const;
321b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
3224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  error_code      getSymbolName(const Elf_Sym *Symb, StringRef &Res) const;
323b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
324b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerprotected:
32525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
32625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
327ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const;
32825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
32925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
33025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
33125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
332ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const;
333ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const;
33425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
33525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
33625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
33725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
33825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
33925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
34025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
34113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
34213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
34307ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
34407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                           bool &Result) const;
3454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
3464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
347b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
3480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationNext(DataRefImpl Rel,
3490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                       RelocationRef &Res) const;
3500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationAddress(DataRefImpl Rel,
3510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                          uint64_t &Res) const;
3520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationSymbol(DataRefImpl Rel,
3530fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                         SymbolRef &Res) const;
3540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationType(DataRefImpl Rel,
3550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                       uint32_t &Res) const;
3564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual error_code getRelocationTypeName(DataRefImpl Rel,
3574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                           SmallVectorImpl<char> &Result) const;
3580fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
3590fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                 int64_t &Res) const;
3604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual error_code getRelocationValueString(DataRefImpl Rel,
3614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                           SmallVectorImpl<char> &Result) const;
3620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
363b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerpublic:
364001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ELFObjectFile(MemoryBuffer *Object, error_code &ec);
365b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator begin_symbols() const;
366b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator end_symbols() const;
367b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator begin_sections() const;
368b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator end_sections() const;
369b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
370b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint8_t getBytesInAddress() const;
371b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef getFileFormatName() const;
372b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual unsigned getArch() const;
373b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
374b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace
375b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
376b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
377b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencervoid ELFObjectFile<target_endianness, is64Bits>
378b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::validateSymbol(DataRefImpl Symb) const {
379b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
3807acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
381b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // FIXME: We really need to do proper error handling in the case of an invalid
382b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        input file. Because we don't use exceptions, I think we'll just pass
383b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        an error object around.
384b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  symb
385b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        && SymbolTableSection
386001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        && symb >= (const Elf_Sym*)(base()
387b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset)
388001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        && symb <  (const Elf_Sym*)(base()
389b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset
390b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_size)))
391b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
392b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Symb must point to a valid symbol!");
393b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
394b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
395b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
39625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
39725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolNext(DataRefImpl Symb,
39825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        SymbolRef &Result) const {
399b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
4007acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
401b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
4027acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ++Symb.d.a;
403b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Check to see if we are at the end of this symbol table.
4047acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
405b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // We are at the end. If there are other symbol tables, jump to them.
4067acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    ++Symb.d.b;
4077acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    Symb.d.a = 1; // The 0th symbol in ELF is fake.
408b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Otherwise return the terminator.
4097acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    if (Symb.d.b >= SymbolTableSections.size()) {
4107acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer      Symb.d.a = std::numeric_limits<uint32_t>::max();
4117acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer      Symb.d.b = std::numeric_limits<uint32_t>::max();
412b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
413b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
414b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
41525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SymbolRef(Symb, this);
41625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
417b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
418b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
419b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
42025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
42125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolName(DataRefImpl Symb,
42225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        StringRef &Result) const {
423b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
424b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
4254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getSymbolName(symb, Result);
426b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
427b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
428b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
42925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
430ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolOffset(DataRefImpl Symb,
43125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                           uint64_t &Result) const {
432b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
433b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
434b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *Section;
435b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->st_shndx) {
436b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON:
437b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer   // Undefined symbols have no address yet.
43825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::SHN_UNDEF:
43925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
44025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
44125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::SHN_ABS:
44225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = symb->st_value;
44325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
444b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default: Section = getSection(symb->st_shndx);
445b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
446b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
447b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getType()) {
44825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::STT_SECTION:
44925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = Section ? Section->sh_addr : UnknownAddressOrSize;
45025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
451b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_FUNC:
452b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_OBJECT:
453b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_NOTYPE:
45425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = symb->st_value;
45525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
45625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  default:
45725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
45825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
459b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
460b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
461b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
462b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
46325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
464ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolAddress(DataRefImpl Symb,
465ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                           uint64_t &Result) const {
466ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
467ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
468ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Shdr *Section;
469ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  switch (symb->st_shndx) {
470ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_COMMON: // Fall through.
471ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer   // Undefined symbols have no address yet.
472ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_UNDEF:
473ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
474ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
475ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_ABS:
476ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(base()+symb->st_value);
477ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
478ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  default: Section = getSection(symb->st_shndx);
479ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
480ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const uint8_t* addr = base();
481ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (Section)
482ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    addr += Section->sh_offset;
483ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  switch (symb->getType()) {
484ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_SECTION:
485ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(addr);
486ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
487ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_FUNC: // Fall through.
488ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_OBJECT: // Fall through.
489ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_NOTYPE:
490ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    addr += symb->st_value;
491ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(addr);
492ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
493ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  default:
494ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
495ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
496ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
497ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
498ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
499ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
500ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
50125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolSize(DataRefImpl Symb,
50225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        uint64_t &Result) const {
503b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
504b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
505b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (symb->st_size == 0)
50625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
50725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = symb->st_size;
50825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
509b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
510b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
511b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
51225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
51325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolNMTypeChar(DataRefImpl Symb,
51425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                              char &Result) const {
515b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
516b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
517b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *Section = getSection(symb->st_shndx);
518b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
519b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  char ret = '?';
520b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
521b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Section) {
522b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch (Section->sh_type) {
523b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_PROGBITS:
524b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_DYNAMIC:
525b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      switch (Section->sh_flags) {
526b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
527b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 't'; break;
528b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
529b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'd'; break;
530b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case ELF::SHF_ALLOC:
531b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
532b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
533b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'r'; break;
534b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
535b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      break;
536b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_NOBITS: ret = 'b';
537b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
538b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
539b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
540b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->st_shndx) {
541b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_UNDEF:
542b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (ret == '?')
543b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'U';
544b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    break;
545b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_ABS: ret = 'a'; break;
546b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON: ret = 'c'; break;
547b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
548b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
549b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getBinding()) {
550b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
551b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_WEAK:
552b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (symb->st_shndx == ELF::SHN_UNDEF)
553b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'w';
554b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else
555b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (symb->getType() == ELF::STT_OBJECT)
556b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'V';
557b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      else
558b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'W';
559b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
560b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
56125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
56225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    StringRef name;
56325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error_code ec = getSymbolName(Symb, name))
56425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      return ec;
56525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = StringSwitch<char>(name)
566b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      .StartsWith(".debug", 'N')
5670fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      .StartsWith(".note", 'n')
5680fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      .Default('?');
56925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
57025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
571b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
57225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = ret;
57325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
574b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
575b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
576b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
57725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
578ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolType(DataRefImpl Symb,
579ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                        SymbolRef::SymbolType &Result) const {
580ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
581ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
582ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
583ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (symb->st_shndx == ELF::SHN_UNDEF) {
584ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_External;
585ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
586ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
587ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
588ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  switch (symb->getType()) {
589ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_FUNC:
590ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Function;
591ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
592ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_OBJECT:
593ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Data;
594ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
595ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  default:
596ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Other;
597ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
598ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
599ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
600ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
601ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
602ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
603ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
604ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::isSymbolGlobal(DataRefImpl Symb,
605ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                        bool &Result) const {
606ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
607ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
608ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
609ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  Result = symb->getBinding() == ELF::STB_GLOBAL;
610ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
611ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
612ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
613ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
614ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
61525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::isSymbolInternal(DataRefImpl Symb,
61625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                           bool &Result) const {
617b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
618b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
619b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
620b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (  symb->getType() == ELF::STT_FILE
621b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer     || symb->getType() == ELF::STT_SECTION)
62225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = true;
62325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = false;
62425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
625b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
626b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
627b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
62825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
62925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
6307acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
631b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  sec += Header->e_shentsize;
6327acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  Sec.p = reinterpret_cast<intptr_t>(sec);
63325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SectionRef(Sec, this);
63425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
635b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
636b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
637b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
63825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
63925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionName(DataRefImpl Sec,
64025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         StringRef &Result) const {
6417acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
64225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
64325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
644b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
645b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
646b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
64725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
64825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionAddress(DataRefImpl Sec,
64925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                            uint64_t &Result) const {
6507acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
65125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->sh_addr;
65225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
653b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
654b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
655b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
65625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
65725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionSize(DataRefImpl Sec,
65825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         uint64_t &Result) const {
6597acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
66025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->sh_size;
66125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
662b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
663b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
664b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
66525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
66625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionContents(DataRefImpl Sec,
66725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                             StringRef &Result) const {
6687acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
66925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const char *start = (const char*)base() + sec->sh_offset;
67025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = StringRef(start, sec->sh_size);
67125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
672b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
673b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
674b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
67525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
67625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::isSectionText(DataRefImpl Sec,
67725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        bool &Result) const {
6787acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
679b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (sec->sh_flags & ELF::SHF_EXECINSTR)
68025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = true;
68125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else
68225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = false;
68325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
684b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
685b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
68613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
68713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
68813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                        ::isSectionData(DataRefImpl Sec,
68913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                                        bool &Result) const {
69013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
69113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
69213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer      && sec->sh_type == ELF::SHT_PROGBITS)
69313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = true;
69413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  else
69513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = false;
69613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
69713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
69813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
69913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
70013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
70113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                        ::isSectionBSS(DataRefImpl Sec,
70213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                                       bool &Result) const {
70313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
70413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
70513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer      && sec->sh_type == ELF::SHT_NOBITS)
70613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = true;
70713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  else
70813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = false;
70913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
71013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
71113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
712b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
71307ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
71407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                          ::sectionContainsSymbol(DataRefImpl Sec,
71507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                  DataRefImpl Symb,
71607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                  bool &Result) const {
71707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  // FIXME: Unimplemented.
71807ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  Result = false;
71907ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  return object_error::success;
72007ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer}
72107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer
7224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
7234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator ELFObjectFile<target_endianness, is64Bits>
7244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                 ::getSectionRelBegin(DataRefImpl Sec) const {
7254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl RelData;
7264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  memset(&RelData, 0, sizeof(RelData));
7274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
7284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
7294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec != 0 && ittr != SectionRelocMap.end()) {
7304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.a = getSection(ittr->second[0])->sh_link;
7314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.b = ittr->second[0];
7324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.c = 0;
7334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
7344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(RelData, this));
7354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
7364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
7384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator ELFObjectFile<target_endianness, is64Bits>
7394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                 ::getSectionRelEnd(DataRefImpl Sec) const {
7404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl RelData;
7414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  memset(&RelData, 0, sizeof(RelData));
7424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
7434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
7444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec != 0 && ittr != SectionRelocMap.end()) {
7454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // Get the index of the last relocation section for this section.
7464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
7474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    const Elf_Shdr *relocsec = getSection(relocsecindex);
7484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.a = relocsec->sh_link;
7494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.b = relocsecindex;
7504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
7514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
7524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(RelData, this));
7534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
7544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer// Relocations
7560fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
7570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
7580fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationNext(DataRefImpl Rel,
7590fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                            RelocationRef &Result) const {
7604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  ++Rel.w.c;
7614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *relocsec = getSection(Rel.w.b);
7624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
7634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // We have reached the end of the relocations for this section. See if there
7644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // is another relocation section.
7654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    typename RelocMap_t::mapped_type &relocseclist =
7664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      SectionRelocMap.lookup(getSection(Rel.w.a));
7674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // Do a binary search for the current reloc section index (which must be
7694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // present). Then get the next one.
7704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    typename RelocMap_t::mapped_type::const_iterator loc =
7714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
7724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ++loc;
7734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
7754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // to the end iterator.
7764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    if (loc != relocseclist.end()) {
7774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Rel.w.b = *loc;
7784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Rel.w.a = 0;
7790fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
7800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
7810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Result = RelocationRef(Rel, this);
7820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
7830fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
7840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
7850fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
7860fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
7870fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationSymbol(DataRefImpl Rel,
7880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                              SymbolRef &Result) const {
7890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint32_t symbolIdx;
7904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
7910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
7920fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
7930fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
7940fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
7950fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      symbolIdx = getRel(Rel)->getSymbol();
7960fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
7970fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
7980fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
7990fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      symbolIdx = getRela(Rel)->getSymbol();
8000fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8010fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8020fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8030fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  DataRefImpl SymbolData;
8040fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
8050fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  if (it == SymbolTableSectionsIndexMap.end())
8060fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    report_fatal_error("Relocation symbol table not found!");
8070fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  SymbolData.d.a = symbolIdx;
8080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  SymbolData.d.b = it->second;
8090fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Result = SymbolRef(SymbolData, this);
8100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8110fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8120fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
8140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
8150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationAddress(DataRefImpl Rel,
8160fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                               uint64_t &Result) const {
8170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint64_t offset;
8184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
8200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
8210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
8220fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
8230fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      offset = getRel(Rel)->r_offset;
8240fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8250fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8260fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
8270fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      offset = getRela(Rel)->r_offset;
8280fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8290fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result = offset;
8330fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8340fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8350fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8360fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
8370fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
8380fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationType(DataRefImpl Rel,
8390fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                            uint32_t &Result) const {
8404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
8420fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
8430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
8440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
8450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRel(Rel)->getType();
8460fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8470fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
8490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRela(Rel)->getType();
8500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8530fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
8574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::enum: res = #enum; break;
8584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
8594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
8604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
8614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getRelocationTypeName(DataRefImpl Rel,
8624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
8634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint8_t type;
8654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef res;
8664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (sec->sh_type) {
8674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default :
8684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      return object_error::parse_failed;
8694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_REL : {
8704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRel(Rel)->getType();
8714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
8724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
8734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_RELA : {
8744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRela(Rel)->getType();
8754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
8764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
8774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
8784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (Header->e_machine) {
8794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_X86_64:
8804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
8814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
8824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
8834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
8844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
8854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
8864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
8874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
8884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
8894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
8904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
8914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
8924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
8934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
8944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
8954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
8964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
8974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
8984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
8994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
9004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
9014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
9024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
9034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
9044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
9054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
9064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
9074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
9084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
9094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
9104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
9114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
9124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
9134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
9144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
9154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
9174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_386:
9184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
9194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
9204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
9214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
9224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
9234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
9244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
9254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
9264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
9274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
9284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
9294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
9304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
9314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
9324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
9334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
9344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
9354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
9364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
9374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
9384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
9394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
9404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
9414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
9424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
9434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
9444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
9454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
9464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
9474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
9484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
9494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
9504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
9514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
9524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
9534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
9544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
9554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
9564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
9574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
9584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
9594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
9604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
9614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
9634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
9644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    res = "Unknown";
9654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
9664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result.append(res.begin(), res.end());
9674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
9684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
9694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
9704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
9714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
9720fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
9730fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
9740fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationAdditionalInfo(DataRefImpl Rel,
9750fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                      int64_t &Result) const {
9764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
9770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
9780fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
9790fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
9800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
9810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = 0;
9820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return object_error::success;
9830fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
9840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
9850fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRela(Rel)->r_addend;
9860fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return object_error::success;
9870fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
9880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
9890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
9900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
9914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
9924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
9934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getRelocationValueString(DataRefImpl Rel,
9944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
9954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
9964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint8_t type;
9974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef res;
9984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  int64_t addend = 0;
9994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint16_t symbol_index = 0;
10004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (sec->sh_type) {
10014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default :
10024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      return object_error::parse_failed;
10034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_REL : {
10044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRel(Rel)->getType();
10054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      symbol_index = getRel(Rel)->getSymbol();
10064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      // TODO: Read implicit addend from section data.
10074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_RELA : {
10104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRela(Rel)->getType();
10114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      symbol_index = getRela(Rel)->getSymbol();
10124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      addend = getRela(Rel)->r_addend;
10134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
10174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef symname;
10184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (error_code ec = getSymbolName(symb, symname))
10194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return ec;
10204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (Header->e_machine) {
10214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_X86_64:
10224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
10234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::R_X86_64_32S:
10244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = symname;
10254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::R_X86_64_PC32: {
10274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        std::string fmtbuf;
10284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        raw_string_ostream fmt(fmtbuf);
10294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
10304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        fmt.flush();
10314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        Result.append(fmtbuf.begin(), fmtbuf.end());
10324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      }
10334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
10354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
10364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
10384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
10394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    res = "Unknown";
10404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (Result.empty())
10424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    Result.append(res.begin(), res.end());
10434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
10444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
10450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
104607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
1047001c9205fca2220480589ec355cb6ec701a37e08Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
1048001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer                                                          , error_code &ec)
1049001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  : ObjectFile(Binary::isELF, Object, ec)
1050b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , SectionHeaderTable(0)
1051b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_shstrtab_sec(0)
1052b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_strtab_sec(0) {
1053001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  Header = reinterpret_cast<const Elf_Ehdr *>(base());
1054b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1055b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Header->e_shoff == 0)
1056b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return;
1057b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1058b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SectionHeaderTable =
1059001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
1060b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
1061b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  (const uint8_t *)SectionHeaderTable + SectionTableSize
1062001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer         <= base() + Data->getBufferSize()))
1063b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1064b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Section table goes past end of file!");
1065b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1066b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1067b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // To find the symbol tables we walk the section table to find SHT_STMTAB.
10684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr* sh = reinterpret_cast<const Elf_Shdr*>(SectionHeaderTable);
10690fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  for (unsigned i = 0; i < Header->e_shnum; ++i) {
1070b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_SYMTAB) {
10710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
1072b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      SymbolTableSections.push_back(sh);
1073b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
10740fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
10754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      SectionRelocMap[getSection(sh->sh_link)].push_back(i);
10760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
10770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    ++sh;
1078b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1079b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
10804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  // Sort section relocation lists by index.
10814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
10824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                     e = SectionRelocMap.end(); i != e; ++i) {
10834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    std::sort(i->second.begin(), i->second.end());
10844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1086b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Get string table sections.
1087b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  dot_shstrtab_sec = getSection(Header->e_shstrndx);
1088b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (dot_shstrtab_sec) {
1089b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Verify that the last byte in the string table in a null.
1090001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    if (((const char*)base() + dot_shstrtab_sec->sh_offset)
1091b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        [dot_shstrtab_sec->sh_size - 1] != 0)
1092b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      // FIXME: Proper error handling.
1093b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      report_fatal_error("String table must end with a null terminator!");
1094b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1095b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1096b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Merge this into the above loop.
1097b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
1098b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  *e = i + Header->e_shnum * Header->e_shentsize;
1099b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   i != e; i += Header->e_shentsize) {
1100b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
1101b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_STRTAB) {
1102b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
1103b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (SectionName == ".strtab") {
1104b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        if (dot_strtab_sec != 0)
1105b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          // FIXME: Proper error handling.
1106b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          report_fatal_error("Already found section named .strtab!");
1107b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        dot_strtab_sec = sh;
1108001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        const char *dot_strtab = (const char*)base() + sh->sh_offset;
1109b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          if (dot_strtab[sh->sh_size - 1] != 0)
1110b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            // FIXME: Proper error handling.
1111b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            report_fatal_error("String table must end with a null terminator!");
1112b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
1113b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1114b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1115b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1116b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1117b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits>
11194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                             ::begin_symbols() const {
11207acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl SymbolData;
1121b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
1122b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (SymbolTableSections.size() == 0) {
11237acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.a = std::numeric_limits<uint32_t>::max();
11247acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1125b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  } else {
11267acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
11277acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.b = 0;
1128b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
11297acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(SymbolData, this));
1130b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1131b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1132b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits>
11344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                             ::end_symbols() const {
11357acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl SymbolData;
1136b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
11377acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  SymbolData.d.a = std::numeric_limits<uint32_t>::max();
11387acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  SymbolData.d.b = std::numeric_limits<uint32_t>::max();
11397acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(SymbolData, this));
1140b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1141b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1142b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator ELFObjectFile<target_endianness, is64Bits>
11444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                              ::begin_sections() const {
11457acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
1146539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  memset(&ret, 0, sizeof(DataRefImpl));
1147001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
11487acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
1149b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1150b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1151b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator ELFObjectFile<target_endianness, is64Bits>
11534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                              ::end_sections() const {
11547acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
1155539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  memset(&ret, 0, sizeof(DataRefImpl));
1156001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(base()
11577acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer                                     + Header->e_shoff
11587acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer                                     + (Header->e_shentsize * Header->e_shnum));
11597acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
1160b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1161b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1162b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1163b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
11647acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return is64Bits ? 8 : 4;
1165b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1166b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1167b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1168b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
1169b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getFileFormatName() const {
1170b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_ident[ELF::EI_CLASS]) {
1171b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS32:
1172b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
1173b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
1174b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-i386";
1175b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
1176b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-x86-64";
11770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::EM_ARM:
11780fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return "ELF32-arm";
1179b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
1180b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-unknown";
1181b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1182b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS64:
1183b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
1184b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
1185b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-i386";
1186b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
1187b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-x86-64";
1188b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
1189b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-unknown";
1190b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1191b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
1192b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1193b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid ELFCLASS!");
1194b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1195b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1196b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1197b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1198b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerunsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
1199b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_machine) {
1200b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_386:
1201b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86;
1202b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_X86_64:
1203b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86_64;
12040fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  case ELF::EM_ARM:
12050fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    return Triple::arm;
1206b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
1207b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::UnknownArch;
1208b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1209b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1210b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
12114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1212b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<typename T>
12140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerinline const T *
12154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
12164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                                     uint32_t Entry) const {
12174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<T>(getSection(Section), Entry);
12184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
12194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
12204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<typename T>
12224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerinline const T *
12234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section,
12244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                                     uint32_t Entry) const {
12250fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return reinterpret_cast<const T *>(
1226001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer           base()
12274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer           + Section->sh_offset
12284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer           + (Entry * Section->sh_entsize));
12290fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
12300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
12310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
12320fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
12330fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
12344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
12350fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
12360fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
12370fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
12380fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
12390fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
12404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
12410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
12420fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
12430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
12440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
12450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
12464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
1247b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1248b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1249b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1250b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1251b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
12527acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = getSection(Symb.d.b);
12534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
1254b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1255b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid symbol table section!");
1256b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return sec;
1257b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1258b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1259b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1260b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1261b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const {
1262b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (index == 0 || index >= ELF::SHN_LORESERVE)
1263b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return 0;
1264b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!SectionHeaderTable || index >= Header->e_shnum)
1265b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1266b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid section index!");
1267b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1268b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return reinterpret_cast<const Elf_Shdr *>(
1269b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         reinterpret_cast<const char *>(SectionHeaderTable)
1270b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         + (index * Header->e_shentsize));
1271b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1272b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1273b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1274b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
1275b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                         ::getString(uint16_t section,
1276b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
1277b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return getString(getSection(section), offset);
1278b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1279b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1280b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1281b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
1282b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                         ::getString(const Elf_Shdr *section,
1283b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
1284b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
1285b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (offset >= section->sh_size)
1286b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1287001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    report_fatal_error("Symbol name offset outside of string table!");
1288001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  return (const char *)base() + section->sh_offset + offset;
1289b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1290b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
12914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
12934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getSymbolName(const Elf_Sym *symb,
12944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                        StringRef &Result) const {
12954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (symb->st_name == 0) {
12964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    const Elf_Shdr *section = getSection(symb->st_shndx);
12974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    if (!section)
12984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Result = "";
12994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    else
13004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Result = getString(dot_shstrtab_sec, section->sh_name);
13014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return object_error::success;
13024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
13034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
13044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  // Use the default symbol table name section.
13054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result = getString(dot_strtab_sec, symb->st_name);
13064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
13074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
13084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1309b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// EI_CLASS, EI_DATA.
1310b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstatic std::pair<unsigned char, unsigned char>
1311b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencergetElfArchType(MemoryBuffer *Object) {
1312b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Object->getBufferSize() < ELF::EI_NIDENT)
1313b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
1314b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
1315b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
1316b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1317b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1318b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace llvm {
1319b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1320b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
1321b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
1322001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    error_code ec;
1323b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
1324001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::little, false>(Object, ec);
1325b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
1326001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::big, false>(Object, ec);
1327b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
1328001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::little, true>(Object, ec);
1329b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
1330001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::big, true>(Object, ec);
1331b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1332b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Not an ELF object file!");
1333b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1334b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1335b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm
1336