ELFObjectFile.cpp revision bfbbe328371772a1b8408066f976a374b379e684
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;
29915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  DenseMap<const Elf_Sym*, Elf_Word> ExtendedSymbolTable;
3004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  /// @brief Map sections to an array of relocation sections that reference
3024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  ///        them sorted by section index.
3034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  RelocMap_t SectionRelocMap;
3044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
3054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  /// @brief Get the relocation section that contains \a Rel.
3064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
3074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return getSection(Rel.w.b);
3084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
309b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
310b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void            validateSymbol(DataRefImpl Symb) const;
3110fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  bool            isRelocationHasAddend(DataRefImpl Rel) const;
3120fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  template<typename T>
3134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const T        *getEntry(uint16_t Section, uint32_t Entry) const;
3144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  template<typename T>
3154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const T        *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
316b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *getSymbol(DataRefImpl Symb) const;
317b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *getSection(DataRefImpl index) const;
318bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  const Elf_Shdr *getSection(uint32_t index) const;
3190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const Elf_Rel  *getRel(DataRefImpl Rel) const;
3200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  const Elf_Rela *getRela(DataRefImpl Rela) const;
321bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  const char     *getString(uint32_t section, uint32_t offset) const;
322b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
3234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  error_code      getSymbolName(const Elf_Sym *Symb, StringRef &Res) const;
324b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
325b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerprotected:
32625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
32725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
328ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const;
32925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
33025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
33125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
33225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
333ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const;
334ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const;
33525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
33625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
33725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
33825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
33925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
34025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
341e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
34225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
34313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
34413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
34507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
34607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                           bool &Result) const;
3474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
3484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
349b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
3500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationNext(DataRefImpl Rel,
3510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                       RelocationRef &Res) const;
3520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationAddress(DataRefImpl Rel,
3530fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                          uint64_t &Res) const;
3540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationSymbol(DataRefImpl Rel,
3550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                         SymbolRef &Res) const;
3560fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationType(DataRefImpl Rel,
3570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                       uint32_t &Res) const;
3584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual error_code getRelocationTypeName(DataRefImpl Rel,
3594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                           SmallVectorImpl<char> &Result) const;
3600fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
3610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                 int64_t &Res) const;
3624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  virtual error_code getRelocationValueString(DataRefImpl Rel,
3634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                           SmallVectorImpl<char> &Result) const;
3640fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
365b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerpublic:
366001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ELFObjectFile(MemoryBuffer *Object, error_code &ec);
367b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator begin_symbols() const;
368b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator end_symbols() const;
369b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator begin_sections() const;
370b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator end_sections() const;
371b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
372b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint8_t getBytesInAddress() const;
373b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef getFileFormatName() const;
374b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual unsigned getArch() const;
37515c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky
376bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  uint64_t getNumSections() const;
377bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  uint64_t getStringTableIndex() const;
37815c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  uint64_t getSymbolTableIndex(const Elf_Sym *symb) const;
379bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  const Elf_Shdr *getSection(const Elf_Sym *symb) const;
380b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
381b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace
382b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
383b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
384b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencervoid ELFObjectFile<target_endianness, is64Bits>
385b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::validateSymbol(DataRefImpl Symb) const {
386b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
3877acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
388b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // FIXME: We really need to do proper error handling in the case of an invalid
389b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        input file. Because we don't use exceptions, I think we'll just pass
390b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        an error object around.
391b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  symb
392b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        && SymbolTableSection
393001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        && symb >= (const Elf_Sym*)(base()
394b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset)
395001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        && symb <  (const Elf_Sym*)(base()
396b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset
397b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_size)))
398b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
399b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Symb must point to a valid symbol!");
400b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
401b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
402b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
40325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
40425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolNext(DataRefImpl Symb,
40525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        SymbolRef &Result) const {
406b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
4077acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
408b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
4097acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  ++Symb.d.a;
410b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Check to see if we are at the end of this symbol table.
4117acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
412b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // We are at the end. If there are other symbol tables, jump to them.
4137acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    ++Symb.d.b;
4147acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    Symb.d.a = 1; // The 0th symbol in ELF is fake.
415b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Otherwise return the terminator.
4167acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    if (Symb.d.b >= SymbolTableSections.size()) {
4177acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer      Symb.d.a = std::numeric_limits<uint32_t>::max();
4187acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer      Symb.d.b = std::numeric_limits<uint32_t>::max();
419b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
420b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
421b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
42225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SymbolRef(Symb, this);
42325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
424b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
425b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
426b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
42725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
42825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolName(DataRefImpl Symb,
42925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        StringRef &Result) const {
430b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
43115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  const Elf_Sym *symb = getSymbol(Symb);
4324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getSymbolName(symb, Result);
433b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
434b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
435b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
43615c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewyckyuint64_t ELFObjectFile<target_endianness, is64Bits>
43715c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky                      ::getSymbolTableIndex(const Elf_Sym *symb) const {
43815c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  if (symb->st_shndx == ELF::SHN_XINDEX)
43915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    return ExtendedSymbolTable.lookup(symb);
44015c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  return symb->st_shndx;
44115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky}
44215c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky
44315c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewyckytemplate<support::endianness target_endianness, bool is64Bits>
444bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
445bfbbe328371772a1b8408066f976a374b379e684Nick LewyckyELFObjectFile<target_endianness, is64Bits>
446bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky                             ::getSection(const Elf_Sym *symb) const {
447bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (symb->st_shndx == ELF::SHN_XINDEX)
448bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    return getSection(ExtendedSymbolTable.lookup(symb));
449bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (symb->st_shndx >= ELF::SHN_LORESERVE)
450bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    return 0;
451bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  return getSection(symb->st_shndx);
452bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky}
453bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky
454bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckytemplate<support::endianness target_endianness, bool is64Bits>
45525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
456ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolOffset(DataRefImpl Symb,
45715c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky                                          uint64_t &Result) const {
458b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
459b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
460b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *Section;
46115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  switch (getSymbolTableIndex(symb)) {
462b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON:
463b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer   // Undefined symbols have no address yet.
46425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::SHN_UNDEF:
46525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
46625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
46725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::SHN_ABS:
46825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = symb->st_value;
46925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
470bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  default: Section = getSection(symb);
471b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
472b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
473b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getType()) {
47425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  case ELF::STT_SECTION:
47525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = Section ? Section->sh_addr : UnknownAddressOrSize;
47625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
477b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_FUNC:
478b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_OBJECT:
479b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_NOTYPE:
48025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = symb->st_value;
48125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
48225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  default:
48325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
48425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
485b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
486b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
487b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
488b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
48925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
490ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolAddress(DataRefImpl Symb,
491ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                           uint64_t &Result) const {
492ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
493ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
494ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Shdr *Section;
49515c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  switch (getSymbolTableIndex(symb)) {
496ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_COMMON: // Fall through.
497ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer   // Undefined symbols have no address yet.
498ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_UNDEF:
499ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
500ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
501ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::SHN_ABS:
502ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(base()+symb->st_value);
503ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
504bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  default: Section = getSection(symb);
505ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
506ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const uint8_t* addr = base();
507ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  if (Section)
508ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    addr += Section->sh_offset;
509ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  switch (symb->getType()) {
510ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_SECTION:
511ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(addr);
512ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
513ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_FUNC: // Fall through.
514ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_OBJECT: // Fall through.
515ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_NOTYPE:
516ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    addr += symb->st_value;
517ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = reinterpret_cast<uintptr_t>(addr);
518ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
519ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  default:
520ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = UnknownAddressOrSize;
521ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
522ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
523ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
524ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
525ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
526ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
52725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolSize(DataRefImpl Symb,
52825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        uint64_t &Result) const {
529b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
530b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
531b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (symb->st_size == 0)
53225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = UnknownAddressOrSize;
53325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = symb->st_size;
53425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
535b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
536b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
537b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
53825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
53925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSymbolNMTypeChar(DataRefImpl Symb,
54025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                              char &Result) const {
541b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
542b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
543bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  const Elf_Shdr *Section = getSection(symb);
544b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
545b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  char ret = '?';
546b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
547b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Section) {
548b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch (Section->sh_type) {
549b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_PROGBITS:
550b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_DYNAMIC:
551b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      switch (Section->sh_flags) {
552b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
553b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 't'; break;
554b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
555b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'd'; break;
556b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case ELF::SHF_ALLOC:
557b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
558b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
559b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'r'; break;
560b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
561b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      break;
562b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_NOBITS: ret = 'b';
563b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
564b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
565b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
566bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  switch (getSymbolTableIndex(symb)) {
567b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_UNDEF:
568b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (ret == '?')
569b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'U';
570b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    break;
571b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_ABS: ret = 'a'; break;
572b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON: ret = 'c'; break;
573b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
574b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
575b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getBinding()) {
576b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
577b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_WEAK:
578bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
579b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'w';
580b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else
581b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (symb->getType() == ELF::STT_OBJECT)
582b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'V';
583b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      else
584b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'W';
585b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
586b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
58725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
58825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    StringRef name;
58925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error_code ec = getSymbolName(Symb, name))
59025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      return ec;
59125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = StringSwitch<char>(name)
592b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      .StartsWith(".debug", 'N')
5930fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      .StartsWith(".note", 'n')
5940fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      .Default('?');
59525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    return object_error::success;
59625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  }
597b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
59825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = ret;
59925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
600b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
601b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
602b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
60325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
604ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::getSymbolType(DataRefImpl Symb,
605ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                        SymbolRef::SymbolType &Result) const {
606ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
607ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
608ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
60915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) {
610ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_External;
611ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    return object_error::success;
612ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
613ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
614ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  switch (symb->getType()) {
615ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_FUNC:
616ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Function;
617ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
618ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  case ELF::STT_OBJECT:
619ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Data;
620ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
621ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  default:
622ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    Result = SymbolRef::ST_Other;
623ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer    break;
624ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  }
625ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
626ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
627ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
628ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
629ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
630ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                        ::isSymbolGlobal(DataRefImpl Symb,
631ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer                                        bool &Result) const {
632ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  validateSymbol(Symb);
633ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  const Elf_Sym  *symb = getSymbol(Symb);
634ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
635ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  Result = symb->getBinding() == ELF::STB_GLOBAL;
636ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer  return object_error::success;
637ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer}
638ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer
639ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
640ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
64125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::isSymbolInternal(DataRefImpl Symb,
64225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                           bool &Result) const {
643b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
644b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
645b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
646b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (  symb->getType() == ELF::STT_FILE
647b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer     || symb->getType() == ELF::STT_SECTION)
64825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = true;
64925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = false;
65025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
651b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
652b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
653b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
65425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
65525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
6567acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
657b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  sec += Header->e_shentsize;
6587acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  Sec.p = reinterpret_cast<intptr_t>(sec);
65925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = SectionRef(Sec, this);
66025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
661b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
662b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
663b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
66425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
66525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionName(DataRefImpl Sec,
66625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         StringRef &Result) const {
6677acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
66825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
66925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
670b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
671b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
672b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
67325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
67425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionAddress(DataRefImpl Sec,
67525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                            uint64_t &Result) const {
6767acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
67725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->sh_addr;
67825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
679b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
680b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
681b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
68225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
68325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionSize(DataRefImpl Sec,
68425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                         uint64_t &Result) const {
6857acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
68625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = sec->sh_size;
68725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
688b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
689b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
690b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
69125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
69225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::getSectionContents(DataRefImpl Sec,
69325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                             StringRef &Result) const {
6947acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
69525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  const char *start = (const char*)base() + sec->sh_offset;
69625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  Result = StringRef(start, sec->sh_size);
69725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
698b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
699b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
700b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
70125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
702e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer                        ::getSectionAlignment(DataRefImpl Sec,
703e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer                                              uint64_t &Result) const {
704e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
705e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  Result = sec->sh_addralign;
706e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer  return object_error::success;
707e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer}
708e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencer
709e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
710e2f2f07be7cf2b55b7e5501291bbcede87e43fd6Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
71125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                        ::isSectionText(DataRefImpl Sec,
71225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                        bool &Result) const {
7137acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
714b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (sec->sh_flags & ELF::SHF_EXECINSTR)
71525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = true;
71625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  else
71725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    Result = false;
71825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  return object_error::success;
719b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
720b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
72113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
72213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
72313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                        ::isSectionData(DataRefImpl Sec,
72413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                                        bool &Result) const {
72513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
72613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
72713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer      && sec->sh_type == ELF::SHT_PROGBITS)
72813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = true;
72913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  else
73013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = false;
73113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
73213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
73313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
73413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
73513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
73613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                        ::isSectionBSS(DataRefImpl Sec,
73713afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer                                       bool &Result) const {
73813afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
73913afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
74013afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer      && sec->sh_type == ELF::SHT_NOBITS)
74113afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = true;
74213afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  else
74313afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer    Result = false;
74413afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer  return object_error::success;
74513afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer}
74613afc5eff2d7370ab486d5039886ab8bbf9039daMichael J. Spencer
747b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
74807ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
74907ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                          ::sectionContainsSymbol(DataRefImpl Sec,
75007ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                  DataRefImpl Symb,
75107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer                                                  bool &Result) const {
75207ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  // FIXME: Unimplemented.
75307ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  Result = false;
75407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer  return object_error::success;
75507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer}
75607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer
7574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
7584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator ELFObjectFile<target_endianness, is64Bits>
7594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                 ::getSectionRelBegin(DataRefImpl Sec) const {
7604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl RelData;
7614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  memset(&RelData, 0, sizeof(RelData));
7624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
7634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
7644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec != 0 && ittr != SectionRelocMap.end()) {
7654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.a = getSection(ittr->second[0])->sh_link;
7664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.b = ittr->second[0];
7674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.c = 0;
7684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
7694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(RelData, this));
7704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
7714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
7734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerrelocation_iterator ELFObjectFile<target_endianness, is64Bits>
7744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                 ::getSectionRelEnd(DataRefImpl Sec) const {
7754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  DataRefImpl RelData;
7764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  memset(&RelData, 0, sizeof(RelData));
7774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
7784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
7794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec != 0 && ittr != SectionRelocMap.end()) {
7804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // Get the index of the last relocation section for this section.
7814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
7824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    const Elf_Shdr *relocsec = getSection(relocsecindex);
7834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.a = relocsec->sh_link;
7844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.b = relocsecindex;
7854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
7864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
7874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return relocation_iterator(RelocationRef(RelData, this));
7884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
7894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
7900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer// Relocations
7910fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
7920fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
7930fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationNext(DataRefImpl Rel,
7940fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                            RelocationRef &Result) const {
7954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  ++Rel.w.c;
7964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *relocsec = getSection(Rel.w.b);
7974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
7984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // We have reached the end of the relocations for this section. See if there
7994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // is another relocation section.
80001a4db3ed4d199da33fa1ce0e1c7b7b9b1c3ccdfMichael J. Spencer    typename RelocMap_t::mapped_type relocseclist =
8014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      SectionRelocMap.lookup(getSection(Rel.w.a));
8024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
8034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // Do a binary search for the current reloc section index (which must be
8044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // present). Then get the next one.
8054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    typename RelocMap_t::mapped_type::const_iterator loc =
8064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
8074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    ++loc;
8084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
8094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
8104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    // to the end iterator.
8114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    if (loc != relocseclist.end()) {
8124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Rel.w.b = *loc;
8134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Rel.w.a = 0;
8140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8160fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Result = RelocationRef(Rel, this);
8170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
8210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
8220fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationSymbol(DataRefImpl Rel,
8230fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                              SymbolRef &Result) const {
8240fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint32_t symbolIdx;
8254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8260fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
8270fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
8280fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
8290fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
8300fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      symbolIdx = getRel(Rel)->getSymbol();
8310fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8320fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8330fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
8340fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      symbolIdx = getRela(Rel)->getSymbol();
8350fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8360fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8370fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8380fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  DataRefImpl SymbolData;
8390fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
8400fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  if (it == SymbolTableSectionsIndexMap.end())
8410fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    report_fatal_error("Relocation symbol table not found!");
8420fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  SymbolData.d.a = symbolIdx;
8430fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  SymbolData.d.b = it->second;
8440fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  Result = SymbolRef(SymbolData, this);
8450fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8460fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8470fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8480fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
8490fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
8500fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationAddress(DataRefImpl Rel,
8510fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                               uint64_t &Result) const {
8520fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  uint64_t offset;
8534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8540fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
8550fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
8560fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
8570fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
8580fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      offset = getRel(Rel)->r_offset;
8590fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8600fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
8620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      offset = getRela(Rel)->r_offset;
8630fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8640fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8650fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8660fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result = offset;
8680fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8690fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8700fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
8720fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
8730fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationType(DataRefImpl Rel,
8740fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                            uint32_t &Result) const {
8754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8760fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
8770fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
8780fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
8790fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
8800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRel(Rel)->getType();
8810fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8820fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8830fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
8840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRela(Rel)->getType();
8850fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      break;
8860fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
8870fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
8880fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return object_error::success;
8890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
8900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
8914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
8924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::enum: res = #enum; break;
8934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
8944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
8954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
8964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getRelocationTypeName(DataRefImpl Rel,
8974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
8984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
8994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint8_t type;
9004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef res;
9014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (sec->sh_type) {
9024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default :
9034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      return object_error::parse_failed;
9044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_REL : {
9054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRel(Rel)->getType();
9064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
9074344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9084344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_RELA : {
9094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRela(Rel)->getType();
9104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
9114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9124344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
9134344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (Header->e_machine) {
9144344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_X86_64:
9154344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
9164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
9174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
9184344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
9194344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
9204344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
9214344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
9224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
9234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
9244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
9254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
9264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
9274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
9284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
9294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
9304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
9314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
9324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
9334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
9344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
9354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
9364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
9374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
9384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
9394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
9404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
9414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
9424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
9434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
9444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
9454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
9464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
9474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
9484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
9494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
9504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
9524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_386:
9534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
9544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
9554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
9564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
9574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
9584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
9594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
9604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
9614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
9624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
9634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
9644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
9654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
9664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
9674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
9684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
9694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
9704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
9714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
9724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
9734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
9744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
9754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
9764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
9774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
9784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
9794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
9804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
9814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
9824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
9834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
9844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
9854344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
9864344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
9874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
9884344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
9894344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
9904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
9914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
9924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
9934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
9944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
9954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
9964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
9974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
9984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
9994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    res = "Unknown";
10004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result.append(res.begin(), res.end());
10024344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
10034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
10044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
10054344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
10064344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
10070fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
10080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramererror_code ELFObjectFile<target_endianness, is64Bits>
10090fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                        ::getRelocationAdditionalInfo(DataRefImpl Rel,
10100fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer                                                      int64_t &Result) const {
10114344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
10120fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  switch (sec->sh_type) {
10130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    default :
10140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      report_fatal_error("Invalid section type in Rel!");
10150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_REL : {
10160fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = 0;
10170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return object_error::success;
10180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
10190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::SHT_RELA : {
10200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      Result = getRela(Rel)->r_addend;
10210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return object_error::success;
10220fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
10230fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  }
10240fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
10250fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
10264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
10274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
10284344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getRelocationValueString(DataRefImpl Rel,
10294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                          SmallVectorImpl<char> &Result) const {
10304344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr *sec = getSection(Rel.w.b);
10314344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint8_t type;
10324344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef res;
10334344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  int64_t addend = 0;
10344344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  uint16_t symbol_index = 0;
10354344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (sec->sh_type) {
10364344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default :
10374344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      return object_error::parse_failed;
10384344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_REL : {
10394344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRel(Rel)->getType();
10404344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      symbol_index = getRel(Rel)->getSymbol();
10414344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      // TODO: Read implicit addend from section data.
10424344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10434344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10444344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::SHT_RELA : {
10454344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      type = getRela(Rel)->getType();
10464344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      symbol_index = getRela(Rel)->getSymbol();
10474344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      addend = getRela(Rel)->r_addend;
10484344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10494344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10504344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10514344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
10524344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  StringRef symname;
10534344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (error_code ec = getSymbolName(symb, symname))
10544344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return ec;
10554344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  switch (Header->e_machine) {
10564344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  case ELF::EM_X86_64:
10574344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    switch (type) {
10584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::R_X86_64_32S:
10594344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = symname;
10604344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10614344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    case ELF::R_X86_64_PC32: {
10624344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        std::string fmtbuf;
10634344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        raw_string_ostream fmt(fmtbuf);
10644344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
10654344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        fmt.flush();
10664344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer        Result.append(fmtbuf.begin(), fmtbuf.end());
10674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      }
10684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      break;
10694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    default:
10704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      res = "Unknown";
10714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    }
10724344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    break;
10734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  default:
10744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    res = "Unknown";
10754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
10764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (Result.empty())
10774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    Result.append(res.begin(), res.end());
10784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
10794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
10800fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
108107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
1082001c9205fca2220480589ec355cb6ec701a37e08Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
1083001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer                                                          , error_code &ec)
1084001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  : ObjectFile(Binary::isELF, Object, ec)
1085b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , SectionHeaderTable(0)
1086b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_shstrtab_sec(0)
1087b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_strtab_sec(0) {
1088001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  Header = reinterpret_cast<const Elf_Ehdr *>(base());
1089b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1090b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Header->e_shoff == 0)
1091b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return;
1092b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1093b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SectionHeaderTable =
1094001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
1095bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
1096b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  (const uint8_t *)SectionHeaderTable + SectionTableSize
1097001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer         <= base() + Data->getBufferSize()))
1098b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1099b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Section table goes past end of file!");
1100b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1101fb05d3d68669859c32bd738f5b5b008e4c4fcf69Nick Lewycky
110215c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  // To find the symbol tables we walk the section table to find SHT_SYMTAB.
110315c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
11044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  const Elf_Shdr* sh = reinterpret_cast<const Elf_Shdr*>(SectionHeaderTable);
1105bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
110615c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) {
110715c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky      if (SymbolTableSectionHeaderIndex)
110815c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky        // FIXME: Proper error handling.
110915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky        report_fatal_error("More than one .symtab_shndx!");
111015c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky      SymbolTableSectionHeaderIndex = sh;
111115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    }
1112b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_SYMTAB) {
11130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
1114b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      SymbolTableSections.push_back(sh);
1115b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
11160fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
11174344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      SectionRelocMap[getSection(sh->sh_link)].push_back(i);
11180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    }
11190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    ++sh;
1120b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1121b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
11224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  // Sort section relocation lists by index.
11234344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
11244344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                     e = SectionRelocMap.end(); i != e; ++i) {
11254344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    std::sort(i->second.begin(), i->second.end());
11264344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
11274344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1128b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Get string table sections.
1129bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  dot_shstrtab_sec = getSection(getStringTableIndex());
1130b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (dot_shstrtab_sec) {
1131b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Verify that the last byte in the string table in a null.
1132001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    if (((const char*)base() + dot_shstrtab_sec->sh_offset)
1133b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        [dot_shstrtab_sec->sh_size - 1] != 0)
1134b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      // FIXME: Proper error handling.
1135b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      report_fatal_error("String table must end with a null terminator!");
1136b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1137b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1138b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Merge this into the above loop.
1139b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
1140bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky                  *e = i + getNumSections() * Header->e_shentsize;
1141b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   i != e; i += Header->e_shentsize) {
1142b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
1143b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_STRTAB) {
1144b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
1145b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (SectionName == ".strtab") {
1146b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        if (dot_strtab_sec != 0)
1147b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          // FIXME: Proper error handling.
1148b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          report_fatal_error("Already found section named .strtab!");
1149b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        dot_strtab_sec = sh;
1150001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer        const char *dot_strtab = (const char*)base() + sh->sh_offset;
1151b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          if (dot_strtab[sh->sh_size - 1] != 0)
1152b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            // FIXME: Proper error handling.
1153b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            report_fatal_error("String table must end with a null terminator!");
1154b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
1155b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1156b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
115715c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky
115815c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  // Build symbol name side-mapping if there is one.
115915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  if (SymbolTableSectionHeaderIndex) {
116015c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
116115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky                                      SymbolTableSectionHeaderIndex->sh_offset);
116215c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    error_code ec;
116315c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    for (symbol_iterator si = begin_symbols(),
116415c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky                         se = end_symbols(); si != se; si.increment(ec)) {
116515c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky      if (ec)
116615c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky        report_fatal_error("Fewer extended symbol table entries than symbols!");
116715c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky      if (*ShndxTable != ELF::SHN_UNDEF)
116815c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky        ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable;
116915c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky      ++ShndxTable;
117015c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky    }
117115c3f727aeff6a80e3f9e7e6b1284748e5f3322aNick Lewycky  }
1172b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1173b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1174b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits>
11764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                             ::begin_symbols() const {
11777acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl SymbolData;
1178b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
1179b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (SymbolTableSections.size() == 0) {
11807acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.a = std::numeric_limits<uint32_t>::max();
11817acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.b = std::numeric_limits<uint32_t>::max();
1182b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  } else {
11837acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
11847acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer    SymbolData.d.b = 0;
1185b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
11867acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(SymbolData, this));
1187b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1188b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1189b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
11904344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits>
11914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                             ::end_symbols() const {
11927acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl SymbolData;
1193b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
11947acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  SymbolData.d.a = std::numeric_limits<uint32_t>::max();
11957acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  SymbolData.d.b = std::numeric_limits<uint32_t>::max();
11967acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return symbol_iterator(SymbolRef(SymbolData, this));
1197b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1198b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1199b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator ELFObjectFile<target_endianness, is64Bits>
12014344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                              ::begin_sections() const {
12027acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
1203539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  memset(&ret, 0, sizeof(DataRefImpl));
1204001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
12057acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
1206b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1207b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1208b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12094344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencersection_iterator ELFObjectFile<target_endianness, is64Bits>
12104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                              ::end_sections() const {
12117acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  DataRefImpl ret;
1212539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher  memset(&ret, 0, sizeof(DataRefImpl));
1213001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  ret.p = reinterpret_cast<intptr_t>(base()
12147acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer                                     + Header->e_shoff
1215bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky                                     + (Header->e_shentsize*getNumSections()));
12167acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return section_iterator(SectionRef(ret, this));
1217b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1218b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1219b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1220b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
12217acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  return is64Bits ? 8 : 4;
1222b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1223b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1224b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1225b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
1226b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getFileFormatName() const {
1227b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_ident[ELF::EI_CLASS]) {
1228b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS32:
1229b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
1230b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
1231b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-i386";
1232b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
1233b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-x86-64";
12340fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    case ELF::EM_ARM:
12350fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer      return "ELF32-arm";
1236b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
1237b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-unknown";
1238b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1239b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS64:
1240b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
1241b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
1242b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-i386";
1243b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
1244b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-x86-64";
1245b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
1246b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-unknown";
1247b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
1248b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
1249b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1250b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid ELFCLASS!");
1251b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1252b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1253b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1254b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1255b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerunsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
1256b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_machine) {
1257b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_386:
1258b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86;
1259b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_X86_64:
1260b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86_64;
12610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  case ELF::EM_ARM:
12620fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer    return Triple::arm;
1263b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
1264b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::UnknownArch;
1265b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1266b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1267b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1268bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckytemplate<support::endianness target_endianness, bool is64Bits>
1269bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckyuint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
1270bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (Header->e_shnum == ELF::SHN_UNDEF)
1271bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    return SectionHeaderTable->sh_size;
1272bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  return Header->e_shnum;
1273bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky}
1274bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky
1275bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckytemplate<support::endianness target_endianness, bool is64Bits>
1276bfbbe328371772a1b8408066f976a374b379e684Nick Lewyckyuint64_t
1277bfbbe328371772a1b8408066f976a374b379e684Nick LewyckyELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
1278bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (Header->e_shnum == ELF::SHN_UNDEF) {
1279bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
1280bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky      return SectionHeaderTable->sh_link;
1281bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    if (Header->e_shstrndx >= getNumSections())
1282bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky      return 0;
1283bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  }
1284bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  return Header->e_shstrndx;
1285bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky}
1286bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky
12874344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1288b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12890fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<typename T>
12900fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerinline const T *
12914344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
12924344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                                     uint32_t Entry) const {
12934344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<T>(getSection(Section), Entry);
12944344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
12954344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
12964344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
12974344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<typename T>
12984344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencerinline const T *
12994344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. SpencerELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section,
13004344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                                     uint32_t Entry) const {
13010fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer  return reinterpret_cast<const T *>(
1302001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer           base()
13034344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer           + Section->sh_offset
13044344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer           + (Entry * Section->sh_entsize));
13050fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
13060fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
13070fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
13080fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
13090fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
13104344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
13110fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
13120fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
13130fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
13140fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
13150fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
13164344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
13170fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
13180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
13190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramertemplate<support::endianness target_endianness, bool is64Bits>
13200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela *
13210fcab076f0358890e2f1b213f4303c780e05d99dBenjamin KramerELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const {
13224344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
1323b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1324b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1325b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1326b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1327b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
13287acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer  const Elf_Shdr *sec = getSection(Symb.d.b);
13294344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
1330b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1331b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid symbol table section!");
1332b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return sec;
1333b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1334b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1335b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1336b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
1337bfbbe328371772a1b8408066f976a374b379e684Nick LewyckyELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const {
1338bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (index == 0)
1339b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return 0;
1340bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  if (!SectionHeaderTable || index >= getNumSections())
1341b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1342b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid section index!");
1343b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1344b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return reinterpret_cast<const Elf_Shdr *>(
1345b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         reinterpret_cast<const char *>(SectionHeaderTable)
1346b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         + (index * Header->e_shentsize));
1347b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1348b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1349b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1350b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
1351bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky                         ::getString(uint32_t section,
1352b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
1353b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return getString(getSection(section), offset);
1354b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1355b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1356b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
1357b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
1358b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                         ::getString(const Elf_Shdr *section,
1359b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
1360b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
1361b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (offset >= section->sh_size)
1362b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1363001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    report_fatal_error("Symbol name offset outside of string table!");
1364001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  return (const char *)base() + section->sh_offset + offset;
1365b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1366b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
13674344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
13684344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencererror_code ELFObjectFile<target_endianness, is64Bits>
13694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                        ::getSymbolName(const Elf_Sym *symb,
13704344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer                                        StringRef &Result) const {
13714344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  if (symb->st_name == 0) {
1372bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky    const Elf_Shdr *section = getSection(symb);
13734344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    if (!section)
13744344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Result = "";
13754344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    else
13764344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer      Result = getString(dot_shstrtab_sec, section->sh_name);
13774344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer    return object_error::success;
13784344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  }
13794344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
13804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  // Use the default symbol table name section.
13814344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  Result = getString(dot_strtab_sec, symb->st_name);
13824344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer  return object_error::success;
13834344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer}
13844344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
1385b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// EI_CLASS, EI_DATA.
1386b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstatic std::pair<unsigned char, unsigned char>
1387b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencergetElfArchType(MemoryBuffer *Object) {
1388b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Object->getBufferSize() < ELF::EI_NIDENT)
1389b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
1390b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
1391b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
1392b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
1393b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1394b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace llvm {
1395b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1396b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
1397b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
1398001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer    error_code ec;
1399b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
1400001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::little, false>(Object, ec);
1401b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
1402001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::big, false>(Object, ec);
1403b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
1404001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::little, true>(Object, ec);
1405b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
1406001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer      return new ELFObjectFile<support::big, true>(Object, ec);
1407b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
1408b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Not an ELF object file!");
1409b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
1410b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
1411b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm
1412