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