ELFObjectFile.cpp revision b84551a14f1c96942eb82408652e633543b0961e
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"
17b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Object/ObjectFile.h"
18b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/ELF.h"
19b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/Endian.h"
20b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/ErrorHandling.h"
21b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include "llvm/Support/MemoryBuffer.h"
22b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include <limits>
23b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#include <utility>
24b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
25b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerusing namespace llvm;
26b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerusing namespace object;
27b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
28b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
29b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
30b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
31b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelperCommon {
32b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
33b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint16_t, target_endianness, support::aligned> Elf_Half;
34b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
35b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Word;
36b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
37b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <int32_t, target_endianness, support::aligned> Elf_Sword;
38b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
39b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Xword;
40b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
41b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <int64_t, target_endianness, support::aligned> Elf_Sxword;
42b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
43b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
44b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
45b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
46b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
47b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper;
48b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
49b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer/// ELF 32bit types.
50b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
51b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper<target_endianness, false>
52b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  : ELFDataTypeTypedefHelperCommon<target_endianness> {
53b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
54b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Addr;
55b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
56b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint32_t, target_endianness, support::aligned> Elf_Off;
57b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
58b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
59b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer/// ELF 64bit types.
60b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
61b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataTypeTypedefHelper<target_endianness, true>
62b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  : ELFDataTypeTypedefHelperCommon<target_endianness>{
63b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
64b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Addr;
65b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef support::detail::packed_endian_specific_integral
66b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    <uint64_t, target_endianness, support::aligned> Elf_Off;
67b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
68b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
69b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
70b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// I really don't like doing this, but the alternative is copypasta.
71b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \
72b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
73b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \
74b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
75b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \
76b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
77b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \
78b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
79b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \
80b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
81b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \
82b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
83b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \
84b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertypedef typename \
85b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword;
86b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
87b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Section header.
88b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
89b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
90b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base;
91b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
92b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
93b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base<target_endianness, false> {
94b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
95b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_name;     // Section name (index into string table)
96b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_type;     // Section type (SHT_*)
97b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_flags;    // Section flags (SHF_*)
98b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr sh_addr;     // Address where section is to be loaded
99b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Off  sh_offset;   // File offset of section data, in bytes
100b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_size;     // Size of section, in bytes
101b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_link;     // Section type-specific header table index link
102b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_info;     // Section type-specific extra information
103b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_addralign;// Section address alignment
104b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word sh_entsize;  // Size of records contained within the section
105b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
106b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
107b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
108b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Base<target_endianness, true> {
109b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
110b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_name;     // Section name (index into string table)
111b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_type;     // Section type (SHT_*)
112b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_flags;    // Section flags (SHF_*)
113b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr  sh_addr;     // Address where section is to be loaded
114b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Off   sh_offset;   // File offset of section data, in bytes
115b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_size;     // Size of section, in bytes
116b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_link;     // Section type-specific header table index link
117b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word  sh_info;     // Section type-specific extra information
118b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_addralign;// Section address alignment
119b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword sh_entsize;  // Size of records contained within the section
120b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
121b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
122b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
123b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> {
124b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize;
125b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size;
126b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
127b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  /// @brief Get the number of entities this section contains if it has any.
128b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned getEntityCount() const {
129b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh_entsize == 0)
130b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return 0;
131b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else
132b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return sh_size / sh_entsize;
133b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
134b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
135b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
136b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
137b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
138b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
139b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base;
140b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
141b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
142b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base<target_endianness, false> {
143b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
144b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_name;  // Symbol name (index into string table)
145b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr      st_value; // Value or address associated with the symbol
146b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_size;  // Size of the symbol
147b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_info;  // Symbol's type and binding attributes
148b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_other; // Must be zero; reserved
149b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Half      st_shndx; // Which section (header table index) it's defined in
150b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
151b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
152b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness>
153b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Base<target_endianness, true> {
154b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
155b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Word      st_name;  // Symbol name (index into string table)
156b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_info;  // Symbol's type and binding attributes
157b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char st_other; // Must be zero; reserved
158b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Half      st_shndx; // Which section (header table index) it's defined in
159b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Addr      st_value; // Value or address associated with the symbol
160b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Elf_Xword     st_size;  // Size of the symbol
161b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
162b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
163b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
164b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> {
165b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  using Elf_Sym_Base<target_endianness, is64Bits>::st_info;
166b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
167b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // These accessors and mutators correspond to the ELF32_ST_BIND,
168b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
169b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char getBinding() const { return st_info >> 4; }
170b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  unsigned char getType() const { return st_info & 0x0f; }
171b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
172b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
173b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void setBindingAndType(unsigned char b, unsigned char t) {
174b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    st_info = (b << 4) + (t & 0x0f);
175b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
176b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
177b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
178b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
179b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
180b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstruct ELFDataRefImpl {
181b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  uint32_t SymbolIndex;
182b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  uint16_t SymbolTableSectionIndex;
183b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  uint16_t Unused;
184b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
185b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
186b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
187b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace {
188b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
189b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerclass ELFObjectFile : public ObjectFile {
190b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
191b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
192b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
193b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
194b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
195b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  struct Elf_Ehdr {
196b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
197b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_type;     // Type of file (see ET_*)
198b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_machine;  // Required architecture for this file (see EM_*)
199b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Word e_version;  // Must be equal to 1
200b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Addr e_entry;    // Address to jump to in order to start program
201b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Off  e_phoff;    // Program header table's file offset, in bytes
202b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Off  e_shoff;    // Section header table's file offset, in bytes
203b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Word e_flags;    // Processor-specific flags
204b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_ehsize;   // Size of ELF header, in bytes
205b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_phentsize;// Size of an entry in the program header table
206b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_phnum;    // Number of entries in the program header table
207b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shentsize;// Size of an entry in the section header table
208b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shnum;    // Number of entries in the section header table
209b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    Elf_Half e_shstrndx; // Section header table index of section name
210b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                  // string table
211b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    bool checkMagic() const {
212b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
213b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
214b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
215b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
216b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  };
217b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
218b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  typedef SmallVector<const Elf_Shdr*, 1> SymbolTableSections_t;
219b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
220b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Ehdr *Header;
221b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *SectionHeaderTable;
222b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
223b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *dot_strtab_sec;   // Symbol header string table.
224b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SymbolTableSections_t SymbolTableSections;
225b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
226b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  void            validateSymbol(DataRefImpl Symb) const;
227b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *getSymbol(DataRefImpl Symb) const;
228b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *getSection(DataRefImpl index) const;
229b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *getSection(uint16_t index) const;
230b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char     *getString(uint16_t section, uint32_t offset) const;
231b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char     *getString(const Elf_Shdr *section, uint32_t offset) const;
232b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
233b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerprotected:
234b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual SymbolRef getSymbolNext(DataRefImpl Symb) const;
235b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef getSymbolName(DataRefImpl Symb) const;
236b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint64_t  getSymbolAddress(DataRefImpl Symb) const;
237b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint64_t  getSymbolSize(DataRefImpl Symb) const;
238b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual char      getSymbolNMTypeChar(DataRefImpl Symb) const;
239b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual bool      isSymbolInternal(DataRefImpl Symb) const;
240b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
241b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual SectionRef getSectionNext(DataRefImpl Sec) const;
242b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef  getSectionName(DataRefImpl Sec) const;
243b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint64_t   getSectionAddress(DataRefImpl Sec) const;
244b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint64_t   getSectionSize(DataRefImpl Sec) const;
245b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef  getSectionContents(DataRefImpl Sec) const;
246b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual bool       isSectionText(DataRefImpl Sec) const;
247b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
248b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerpublic:
249b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFObjectFile(MemoryBuffer *Object);
250b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator begin_symbols() const;
251b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual symbol_iterator end_symbols() const;
252b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator begin_sections() const;
253b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual section_iterator end_sections() const;
254b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
255b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual uint8_t getBytesInAddress() const;
256b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual StringRef getFileFormatName() const;
257b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  virtual unsigned getArch() const;
258b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer};
259b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace
260b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
261b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
262b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencervoid ELFObjectFile<target_endianness, is64Bits>
263b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::validateSymbol(DataRefImpl Symb) const {
264b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb);
265b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
266b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *SymbolTableSection =
267b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolTableSections[SymbolData.SymbolTableSectionIndex];
268b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // FIXME: We really need to do proper error handling in the case of an invalid
269b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        input file. Because we don't use exceptions, I think we'll just pass
270b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  //        an error object around.
271b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  symb
272b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        && SymbolTableSection
273b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        && symb >= (const Elf_Sym*)(base
274b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset)
275b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        && symb <  (const Elf_Sym*)(base
276b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_offset
277b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   + SymbolTableSection->sh_size)))
278b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
279b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Symb must point to a valid symbol!");
280b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
281b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
282b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
283b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerSymbolRef ELFObjectFile<target_endianness, is64Bits>
284b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getSymbolNext(DataRefImpl Symb) const {
285b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
286b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataRefImpl &SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb);
287b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *SymbolTableSection =
288b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolTableSections[SymbolData.SymbolTableSectionIndex];
289b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
290b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ++SymbolData.SymbolIndex;
291b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Check to see if we are at the end of this symbol table.
292b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (SymbolData.SymbolIndex >= SymbolTableSection->getEntityCount()) {
293b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // We are at the end. If there are other symbol tables, jump to them.
294b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    ++SymbolData.SymbolTableSectionIndex;
295b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolData.SymbolIndex = 1; // The 0th symbol in ELF is fake.
296b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Otherwise return the terminator.
297b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (SymbolData.SymbolTableSectionIndex >= SymbolTableSections.size()) {
298b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max();
299b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max();
300b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
301b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
302b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
303b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return SymbolRef(Symb, this);
304b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
305b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
306b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
307b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
308b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getSymbolName(DataRefImpl Symb) const {
309b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
310b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
311b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (symb->st_name == 0) {
312b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    const Elf_Shdr *section = getSection(symb->st_shndx);
313b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (!section)
314b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "";
315b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return getString(dot_shstrtab_sec, section->sh_name);
316b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
317b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
318b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Use the default symbol table name section.
319b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return getString(dot_strtab_sec, symb->st_name);
320b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
321b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
322b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
323b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint64_t ELFObjectFile<target_endianness, is64Bits>
324b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                      ::getSymbolAddress(DataRefImpl Symb) const {
325b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
326b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
327b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *Section;
328b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->st_shndx) {
329b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON:
330b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer   // Undefined symbols have no address yet.
331b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_UNDEF: return UnknownAddressOrSize;
332b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_ABS: return symb->st_value;
333b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default: Section = getSection(symb->st_shndx);
334b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
335b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
336b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getType()) {
337b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_SECTION: return Section ? Section->sh_addr
338b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                        : UnknownAddressOrSize;
339b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_FUNC:
340b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_OBJECT:
341b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STT_NOTYPE:
342b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return symb->st_value;
343b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default: return UnknownAddressOrSize;
344b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
345b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
346b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
347b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
348b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint64_t ELFObjectFile<target_endianness, is64Bits>
349b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                      ::getSymbolSize(DataRefImpl Symb) const {
350b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
351b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
352b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (symb->st_size == 0)
353b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return UnknownAddressOrSize;
354b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return symb->st_size;
355b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
356b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
357b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
358b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerchar ELFObjectFile<target_endianness, is64Bits>
359b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::getSymbolNMTypeChar(DataRefImpl Symb) const {
360b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
361b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
362b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *Section = getSection(symb->st_shndx);
363b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
364b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  char ret = '?';
365b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
366b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Section) {
367b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch (Section->sh_type) {
368b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_PROGBITS:
369b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_DYNAMIC:
370b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      switch (Section->sh_flags) {
371b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
372b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 't'; break;
373b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
374b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'd'; break;
375b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case ELF::SHF_ALLOC:
376b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
377b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
378b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'r'; break;
379b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
380b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      break;
381b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::SHT_NOBITS: ret = 'b';
382b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
383b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
384b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
385b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->st_shndx) {
386b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_UNDEF:
387b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (ret == '?')
388b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'U';
389b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    break;
390b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_ABS: ret = 'a'; break;
391b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::SHN_COMMON: ret = 'c'; break;
392b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
393b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
394b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch (symb->getBinding()) {
395b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
396b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::STB_WEAK:
397b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (symb->st_shndx == ELF::SHN_UNDEF)
398b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      ret = 'w';
399b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else
400b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (symb->getType() == ELF::STT_OBJECT)
401b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'V';
402b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      else
403b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        ret = 'W';
404b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
405b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
406b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (ret == '?' && symb->getType() == ELF::STT_SECTION)
407b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return StringSwitch<char>(getSymbolName(Symb))
408b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      .StartsWith(".debug", 'N')
409b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      .StartsWith(".note", 'n');
410b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
411b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return ret;
412b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
413b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
414b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
415b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerbool ELFObjectFile<target_endianness, is64Bits>
416b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::isSymbolInternal(DataRefImpl Symb) const {
417b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  validateSymbol(Symb);
418b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Sym  *symb = getSymbol(Symb);
419b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
420b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (  symb->getType() == ELF::STT_FILE
421b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer     || symb->getType() == ELF::STT_SECTION)
422b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return true;
423b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return false;
424b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
425b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
426b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
427b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerSectionRef ELFObjectFile<target_endianness, is64Bits>
428b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                        ::getSectionNext(DataRefImpl Sec) const {
429b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const uint8_t *sec = *reinterpret_cast<const uint8_t **>(&Sec);
430b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  sec += Header->e_shentsize;
431b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return SectionRef(DataRefImpl(sec), this);
432b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
433b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
434b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
435b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
436b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getSectionName(DataRefImpl Sec) const {
437b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
438b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    *reinterpret_cast<const Elf_Shdr **>(&Sec);
439b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return StringRef(getString(dot_shstrtab_sec, sec->sh_name));
440b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
441b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
442b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
443b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint64_t ELFObjectFile<target_endianness, is64Bits>
444b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                      ::getSectionAddress(DataRefImpl Sec) const {
445b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
446b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    *reinterpret_cast<const Elf_Shdr **>(&Sec);
447b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return sec->sh_addr;
448b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
449b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
450b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
451b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint64_t ELFObjectFile<target_endianness, is64Bits>
452b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                      ::getSectionSize(DataRefImpl Sec) const {
453b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
454b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    *reinterpret_cast<const Elf_Shdr **>(&Sec);
455b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return sec->sh_size;
456b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
457b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
458b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
459b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
460b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getSectionContents(DataRefImpl Sec) const {
461b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
462b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    *reinterpret_cast<const Elf_Shdr **>(&Sec);
463b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const char *start = (char*)base + sec->sh_offset;
464b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return StringRef(start, sec->sh_size);
465b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
466b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
467b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
468b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerbool ELFObjectFile<target_endianness, is64Bits>
469b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  ::isSectionText(DataRefImpl Sec) const {
470b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
471b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    *reinterpret_cast<const Elf_Shdr **>(&Sec);
472b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (sec->sh_flags & ELF::SHF_EXECINSTR)
473b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return true;
474b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return false;
475b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
476b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
477b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
478b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object)
479b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  : ObjectFile(Object)
480b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , SectionHeaderTable(0)
481b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_shstrtab_sec(0)
482b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  , dot_strtab_sec(0) {
483b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  Header = reinterpret_cast<const Elf_Ehdr *>(base);
484b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
485b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Header->e_shoff == 0)
486b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return;
487b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
488b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SectionHeaderTable =
489b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    reinterpret_cast<const Elf_Shdr *>(base + Header->e_shoff);
490b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
491b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!(  (const uint8_t *)SectionHeaderTable + SectionTableSize
492b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         <= base + MapFile->getBufferSize()))
493b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
494b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Section table goes past end of file!");
495b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
496b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
497b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // To find the symbol tables we walk the section table to find SHT_STMTAB.
498b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
499b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  *e = i + Header->e_shnum * Header->e_shentsize;
500b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   i != e; i += Header->e_shentsize) {
501b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
502b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_SYMTAB) {
503b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      SymbolTableSections.push_back(sh);
504b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
505b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
506b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
507b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Get string table sections.
508b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  dot_shstrtab_sec = getSection(Header->e_shstrndx);
509b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (dot_shstrtab_sec) {
510b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // Verify that the last byte in the string table in a null.
511b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (((const char*)base + dot_shstrtab_sec->sh_offset)
512b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        [dot_shstrtab_sec->sh_size - 1] != 0)
513b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      // FIXME: Proper error handling.
514b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      report_fatal_error("String table must end with a null terminator!");
515b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
516b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
517b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  // Merge this into the above loop.
518b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
519b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                  *e = i + Header->e_shnum * Header->e_shentsize;
520b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                   i != e; i += Header->e_shentsize) {
521b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
522b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (sh->sh_type == ELF::SHT_STRTAB) {
523b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
524b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      if (SectionName == ".strtab") {
525b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        if (dot_strtab_sec != 0)
526b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          // FIXME: Proper error handling.
527b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          report_fatal_error("Already found section named .strtab!");
528b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        dot_strtab_sec = sh;
529b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer        const char *dot_strtab = (const char*)base + sh->sh_offset;
530b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer          if (dot_strtab[sh->sh_size - 1] != 0)
531b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            // FIXME: Proper error handling.
532b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer            report_fatal_error("String table must end with a null terminator!");
533b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      }
534b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
535b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
536b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
537b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
538b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
539b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
540b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                         ::begin_symbols() const {
541b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataRefImpl SymbolData;
542b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
543b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (SymbolTableSections.size() == 0) {
544b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max();
545b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max();
546b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  } else {
547b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolData.SymbolIndex = 1; // The 0th symbol in ELF is fake.
548b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolData.SymbolTableSectionIndex = 0;
549b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
550b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return symbol_iterator(
551b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolRef(DataRefImpl(*reinterpret_cast<DataRefImpl*>(&SymbolData)), this));
552b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
553b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
554b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
555b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerObjectFile::symbol_iterator ELFObjectFile<target_endianness, is64Bits>
556b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                         ::end_symbols() const {
557b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ELFDataRefImpl SymbolData;
558b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  memset(&SymbolData, 0, sizeof(SymbolData));
559b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SymbolData.SymbolIndex = std::numeric_limits<uint32_t>::max();
560b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  SymbolData.SymbolTableSectionIndex = std::numeric_limits<uint32_t>::max();
561b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return symbol_iterator(
562b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolRef(DataRefImpl(*reinterpret_cast<DataRefImpl*>(&SymbolData)), this));
563b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
564b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
565b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
566b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
567b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                          ::begin_sections() const {
568b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return section_iterator(
569b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SectionRef(DataRefImpl(base + Header->e_shoff), this));
570b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
571b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
572b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
573b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
574b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                          ::end_sections() const {
575b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return section_iterator(
576b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SectionRef(DataRefImpl(base
577b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                           + Header->e_shoff
578b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                           + (Header->e_shentsize * Header->e_shnum)), this));
579b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
580b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
581b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
582b84551a14f1c96942eb82408652e633543b0961eMichael J. Spenceruint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
583b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return 4;
584b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
585b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
586b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
587b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerStringRef ELFObjectFile<target_endianness, is64Bits>
588b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       ::getFileFormatName() const {
589b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_ident[ELF::EI_CLASS]) {
590b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS32:
591b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
592b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
593b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-i386";
594b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
595b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-x86-64";
596b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
597b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF32-unknown";
598b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
599b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::ELFCLASS64:
600b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    switch(Header->e_machine) {
601b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_386:
602b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-i386";
603b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    case ELF::EM_X86_64:
604b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-x86-64";
605b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    default:
606b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return "ELF64-unknown";
607b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    }
608b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
609b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
610b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid ELFCLASS!");
611b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
612b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
613b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
614b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
615b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerunsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
616b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  switch(Header->e_machine) {
617b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_386:
618b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86;
619b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  case ELF::EM_X86_64:
620b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::x86_64;
621b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  default:
622b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return Triple::UnknownArch;
623b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
624b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
625b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
626b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
627b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
628b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
629b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb);
630b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec =
631b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    SymbolTableSections[SymbolData.SymbolTableSectionIndex];
632b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return reinterpret_cast<const Elf_Sym *>(
633b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer           base
634b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer           + sec->sh_offset
635b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer           + (SymbolData.SymbolIndex * sec->sh_entsize));
636b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
637b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
638b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
639b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
640b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const {
641b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const ELFDataRefImpl SymbolData = *reinterpret_cast<ELFDataRefImpl *>(&Symb);
642b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  const Elf_Shdr *sec = getSection(SymbolData.SymbolTableSectionIndex);
643b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (sec->sh_type != ELF::SHT_SYMTAB)
644b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
645b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid symbol table section!");
646b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return sec;
647b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
648b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
649b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
650b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr *
651b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencerELFObjectFile<target_endianness, is64Bits>::getSection(uint16_t index) const {
652b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (index == 0 || index >= ELF::SHN_LORESERVE)
653b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return 0;
654b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (!SectionHeaderTable || index >= Header->e_shnum)
655b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
656b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Invalid section index!");
657b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
658b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return reinterpret_cast<const Elf_Shdr *>(
659b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         reinterpret_cast<const char *>(SectionHeaderTable)
660b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer         + (index * Header->e_shentsize));
661b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
662b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
663b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
664b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
665b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                         ::getString(uint16_t section,
666b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
667b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return getString(getSection(section), offset);
668b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
669b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
670b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits>
671b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerconst char *ELFObjectFile<target_endianness, is64Bits>
672b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                         ::getString(const Elf_Shdr *section,
673b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                                     ELF::Elf32_Word offset) const {
674b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
675b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (offset >= section->sh_size)
676b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
677b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Sybol name offset outside of string table!");
678b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return (const char *)base + section->sh_offset + offset;
679b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
680b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
681b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// EI_CLASS, EI_DATA.
682b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencerstatic std::pair<unsigned char, unsigned char>
683b84551a14f1c96942eb82408652e633543b0961eMichael J. SpencergetElfArchType(MemoryBuffer *Object) {
684b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  if (Object->getBufferSize() < ELF::EI_NIDENT)
685b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
686b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
687b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer                       , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
688b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer}
689b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
690b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencernamespace llvm {
691b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
692b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
693b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
694b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
695b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return new ELFObjectFile<support::little, false>(Object);
696b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
697b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return new ELFObjectFile<support::big, false>(Object);
698b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
699b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return new ELFObjectFile<support::little, true>(Object);
700b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
701b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer      return new ELFObjectFile<support::big, true>(Object);
702b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    // FIXME: Proper error handling.
703b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer    report_fatal_error("Not an ELF object file!");
704b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer  }
705b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
706b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm
707