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