ELF.h revision 2c67727046234ad9702ab5acb72700b5ac99a676
1f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===// 2f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// 3f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// The LLVM Compiler Infrastructure 4f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// 5f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// This file is distributed under the University of Illinois Open Source 6f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// License. See LICENSE.TXT for details. 7f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// 8f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky//===----------------------------------------------------------------------===// 9f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// 10f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// This file declares the ELFObjectFile template class. 11f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// 12f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky//===----------------------------------------------------------------------===// 13f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 14f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#ifndef LLVM_OBJECT_ELF_H 15f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#define LLVM_OBJECT_ELF_H 16f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 17f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/ADT/SmallVector.h" 18f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/ADT/StringSwitch.h" 19f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/ADT/Triple.h" 20f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/ADT/DenseMap.h" 21f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Object/ObjectFile.h" 22f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/Casting.h" 23f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/ELF.h" 24f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/Endian.h" 25f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/ErrorHandling.h" 26f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/MemoryBuffer.h" 27f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/raw_ostream.h" 28f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <algorithm> 29f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <limits> 30f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <utility> 31f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 32f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace llvm { 33f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace object { 34f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 35f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Templates to choose Elf_Addr and Elf_Off depending on is64Bits. 36f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 37f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelperCommon { 38f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 39f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint16_t, target_endianness, support::aligned> Elf_Half; 40f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 41f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint32_t, target_endianness, support::aligned> Elf_Word; 42f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 43f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <int32_t, target_endianness, support::aligned> Elf_Sword; 44f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 45f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint64_t, target_endianness, support::aligned> Elf_Xword; 46f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 47f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <int64_t, target_endianness, support::aligned> Elf_Sxword; 48f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 49f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 50f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 51f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper; 52f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 53f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky/// ELF 32bit types. 54f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 55f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper<target_endianness, false> 56f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : ELFDataTypeTypedefHelperCommon<target_endianness> { 57f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef uint32_t value_type; 58f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 59f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Addr; 60f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 61f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Off; 62f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 63f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 64f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky/// ELF 64bit types. 65f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 66f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper<target_endianness, true> 67f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : ELFDataTypeTypedefHelperCommon<target_endianness>{ 68f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef uint64_t value_type; 69f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 70f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Addr; 71f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 72f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Off; 73f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 74f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 75f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// I really don't like doing this, but the alternative is copypasta. 76f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \ 77f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 78f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \ 79f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 80f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \ 81f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 82f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \ 83f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 84f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \ 85f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 86f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \ 87f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 88f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \ 89f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 90f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword; 91f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 92f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Section header. 93f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 94f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base; 95f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 96f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 97f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base<target_endianness, false> { 98f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 99f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_name; // Section name (index into string table) 100f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_type; // Section type (SHT_*) 101f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_flags; // Section flags (SHF_*) 102f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr sh_addr; // Address where section is to be loaded 103f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off sh_offset; // File offset of section data, in bytes 104f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_size; // Size of section, in bytes 105f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_link; // Section type-specific header table index link 106f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_info; // Section type-specific extra information 107f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_addralign;// Section address alignment 108f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_entsize; // Size of records contained within the section 109f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 110f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 111f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 112f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base<target_endianness, true> { 113f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 114f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_name; // Section name (index into string table) 115f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_type; // Section type (SHT_*) 116f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_flags; // Section flags (SHF_*) 117f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr sh_addr; // Address where section is to be loaded 118f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off sh_offset; // File offset of section data, in bytes 119f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_size; // Size of section, in bytes 120f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_link; // Section type-specific header table index link 121f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_info; // Section type-specific extra information 122f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_addralign;// Section address alignment 123f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_entsize; // Size of records contained within the section 124f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 125f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 126f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 127f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { 128f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize; 129f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size; 130f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 131f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Get the number of entities this section contains if it has any. 132f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned getEntityCount() const { 133f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh_entsize == 0) 134f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 135f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return sh_size / sh_entsize; 136f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 137f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 138f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 139f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 140f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base; 141f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 142f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 143f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base<target_endianness, false> { 144f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 145f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_name; // Symbol name (index into string table) 146f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr st_value; // Value or address associated with the symbol 147f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_size; // Size of the symbol 148f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_info; // Symbol's type and binding attributes 149f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_other; // Must be zero; reserved 150f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half st_shndx; // Which section (header table index) it's defined in 151f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 152f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 153f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 154f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base<target_endianness, true> { 155f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 156f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_name; // Symbol name (index into string table) 157f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_info; // Symbol's type and binding attributes 158f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_other; // Must be zero; reserved 159f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half st_shndx; // Which section (header table index) it's defined in 160f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr st_value; // Value or address associated with the symbol 161f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword st_size; // Size of the symbol 162f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 163f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 164f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 165f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { 166f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Sym_Base<target_endianness, is64Bits>::st_info; 167f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 168f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF32_ST_BIND, 169f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: 170f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getBinding() const { return st_info >> 4; } 171f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { return st_info & 0x0f; } 172f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 173f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 174f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setBindingAndType(unsigned char b, unsigned char t) { 175f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky st_info = (b << 4) + (t & 0x0f); 176f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 177f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 178f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 179f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits, bool isRela> 180f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base; 181f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 182f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 183f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, false, false> { 184f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 185f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 186f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word r_info; // Symbol table index and type of relocation to apply 187f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 188f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 189f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 190f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, true, false> { 191f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 192f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 193f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword r_info; // Symbol table index and type of relocation to apply 194f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 195f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 196f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 197f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, false, true> { 198f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 199f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 200f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word r_info; // Symbol table index and type of relocation to apply 201f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Sword r_addend; // Compute value for relocatable field by adding this 202f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 203f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 204f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 205f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, true, true> { 206f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 207f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 208f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword r_info; // Symbol table index and type of relocation to apply 209f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Sxword r_addend; // Compute value for relocatable field by adding this. 210f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 211f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 212f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits, bool isRela> 213f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl; 214f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 215f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool isRela> 216f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl<target_endianness, true, isRela> 217f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : Elf_Rel_Base<target_endianness, true, isRela> { 218f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Rel_Base<target_endianness, true, isRela>::r_info; 219f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 220f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 221f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, 222f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // and ELF64_R_INFO macros defined in the ELF specification: 223f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getSymbol() const { return (r_info >> 32); } 224f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { 225f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (unsigned char) (r_info & 0xffffffffL); 226f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 227f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); } 228f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 229f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbolAndType(uint64_t s, unsigned char t) { 230f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky r_info = (s << 32) + (t&0xffffffffL); 231f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 232f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 233f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 234f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool isRela> 235f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl<target_endianness, false, isRela> 236f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : Elf_Rel_Base<target_endianness, false, isRela> { 237f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Rel_Base<target_endianness, false, isRela>::r_info; 238f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 239f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 240f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, 241f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // and ELF32_R_INFO macros defined in the ELF specification: 242f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t getSymbol() const { return (r_info >> 8); } 243f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); } 244f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 245f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 246f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbolAndType(uint32_t s, unsigned char t) { 247f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky r_info = (s << 8) + t; 248f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 249f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 250f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 251f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 252f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 253f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyclass ELFObjectFile : public ObjectFile { 254f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 255f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 256f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; 257f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; 258f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; 259f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; 260f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 261f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 262f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky struct Elf_Ehdr { 263f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes 264f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_type; // Type of file (see ET_*) 265f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_machine; // Required architecture for this file (see EM_*) 266f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word e_version; // Must be equal to 1 267f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr e_entry; // Address to jump to in order to start program 268f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off e_phoff; // Program header table's file offset, in bytes 269f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off e_shoff; // Section header table's file offset, in bytes 270f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word e_flags; // Processor-specific flags 271f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_ehsize; // Size of ELF header, in bytes 272f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_phentsize;// Size of an entry in the program header table 273f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_phnum; // Number of entries in the program header table 274f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shentsize;// Size of an entry in the section header table 275f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shnum; // Number of entries in the section header table 276f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shstrndx; // Section header table index of section name 277f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // string table 278f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool checkMagic() const { 279f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 280f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 281f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } 282f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } 283f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky }; 284f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // This flag is used for classof, to distinguish ELFObjectFile from 285f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // its subclass. If more subclasses will be created, this flag will 286f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // have to become an enum. 287f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isDyldELFObject; 288f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 289f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprivate: 290f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef SmallVector<const Elf_Shdr*, 1> Sections_t; 291f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef DenseMap<unsigned, unsigned> IndexMap_t; 292f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; 293f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 294f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Ehdr *Header; 295f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SectionHeaderTable; 296f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *dot_shstrtab_sec; // Section header string table. 297f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *dot_strtab_sec; // Symbol header string table. 298dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. 299f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sections_t SymbolTableSections; 300f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky IndexMap_t SymbolTableSectionsIndexMap; 301f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; 302f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 303f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Map sections to an array of relocation sections that reference 304f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// them sorted by section index. 305f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocMap_t SectionRelocMap; 306f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 307f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Get the relocation section that contains \a Rel. 308f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 309f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(Rel.w.b); 310f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 311f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 312f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isRelocationHasAddend(DataRefImpl Rel) const; 313f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky template<typename T> 314f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const T *getEntry(uint16_t Section, uint32_t Entry) const; 315f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky template<typename T> 316f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; 317f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(DataRefImpl index) const; 318f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(uint32_t index) const; 319f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Rel *getRel(DataRefImpl Rel) const; 320f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Rela *getRela(DataRefImpl Rela) const; 321f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *getString(uint32_t section, uint32_t offset) const; 322f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *getString(const Elf_Shdr *section, uint32_t offset) const; 323dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer error_code getSymbolName(const Elf_Shdr *section, 324dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Sym *Symb, 325dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer StringRef &Res) const; 326dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer void VerifyStrTab(const Elf_Shdr *sh) const; 327f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 328f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 329f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private? 330f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void validateSymbol(DataRefImpl Symb) const; 331f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 332f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 333f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 334f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 335f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 336f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 337f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 338f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; 339c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 340f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; 341f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolSection(DataRefImpl Symb, 342f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky section_iterator &Res) const; 343f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 344f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 345f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 346f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 347f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 348f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 349f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 350f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 351f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 352f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 353f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 354f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const; 355f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; 356f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; 357f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 358f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationNext(DataRefImpl Rel, 359f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocationRef &Res) const; 360f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationAddress(DataRefImpl Rel, 361f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 362f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationOffset(DataRefImpl Rel, 363f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 364f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationSymbol(DataRefImpl Rel, 365f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Res) const; 366f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationType(DataRefImpl Rel, 367f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 368f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationTypeName(DataRefImpl Rel, 369f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const; 370f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, 371f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t &Res) const; 372f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationValueString(DataRefImpl Rel, 373f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const; 374f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 375f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskypublic: 376f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFObjectFile(MemoryBuffer *Object, error_code &ec); 377f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual symbol_iterator begin_symbols() const; 378f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual symbol_iterator end_symbols() const; 379dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer virtual symbol_iterator begin_dynamic_symbols() const; 380dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer virtual symbol_iterator end_dynamic_symbols() const; 381f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual section_iterator begin_sections() const; 382f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual section_iterator end_sections() const; 383f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 384f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual uint8_t getBytesInAddress() const; 385f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual StringRef getFileFormatName() const; 386f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual unsigned getArch() const; 387f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 388f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getNumSections() const; 389f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getStringTableIndex() const; 390f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; 391f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(const Elf_Sym *symb) const; 392f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 393f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Methods for type inquiry through isa, cast, and dyn_cast 394f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isDyldType() const { return isDyldELFObject; } 395f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky static inline bool classof(const Binary *v) { 396f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return v->getType() == Binary::isELF; 397f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 398f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky static inline bool classof(const ELFObjectFile *v) { return true; } 399f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 400f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 401f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 402f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyvoid ELFObjectFile<target_endianness, is64Bits> 403f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::validateSymbol(DataRefImpl Symb) const { 404f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 405f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 406f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: We really need to do proper error handling in the case of an invalid 407f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // input file. Because we don't use exceptions, I think we'll just pass 408f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // an error object around. 409f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!( symb 410f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && SymbolTableSection 411f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && symb >= (const Elf_Sym*)(base() 412f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_offset) 413f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && symb < (const Elf_Sym*)(base() 414f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_offset 415f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_size))) 416f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 417f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Symb must point to a valid symbol!"); 418f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 419f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 420f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 421f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 422f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolNext(DataRefImpl Symb, 423f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Result) const { 424f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 425f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 426f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 427f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++Symb.d.a; 428f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Check to see if we are at the end of this symbol table. 429f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Symb.d.a >= SymbolTableSection->getEntityCount()) { 430f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // We are at the end. If there are other symbol tables, jump to them. 431dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // If the symbol table is .dynsym, we are iterating dynamic symbols, 432dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // and there is only one table of these. 433dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (Symb.d.b != 0) { 434dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ++Symb.d.b; 435dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Symb.d.a = 1; // The 0th symbol in ELF is fake. 436dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 437f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Otherwise return the terminator. 438dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) { 439f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Symb.d.a = std::numeric_limits<uint32_t>::max(); 440f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Symb.d.b = std::numeric_limits<uint32_t>::max(); 441f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 442f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 443f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 444f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef(Symb, this); 445f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 446f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 447f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 448f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 449f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 450f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolName(DataRefImpl Symb, 451f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 452f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 453f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 454dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); 455f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 456f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 457f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 458f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits> 459f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolTableIndex(const Elf_Sym *symb) const { 460f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx == ELF::SHN_XINDEX) 461f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ExtendedSymbolTable.lookup(symb); 462f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symb->st_shndx; 463f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 464f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 465f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 466f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 467f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits> 468f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSection(const Elf_Sym *symb) const { 469f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx == ELF::SHN_XINDEX) 470f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(ExtendedSymbolTable.lookup(symb)); 471f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx >= ELF::SHN_LORESERVE) 472f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 473f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(symb->st_shndx); 474f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 475f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 476f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 477f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 478f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolFileOffset(DataRefImpl Symb, 479f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 480f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 481f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 482f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section; 483f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 484f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: 485f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Unintialized symbols have no offset in the object file 486f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 487f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 488f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 489f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: 490f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value; 491f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 492f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: Section = getSection(symb); 493f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 494f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 495f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 496f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 497f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = Section ? Section->sh_addr : UnknownAddressOrSize; 498f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 499f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 500f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 501f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_NOTYPE: 502f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value + 503f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky (Section ? Section->sh_offset : 0); 504f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 505f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 506f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 507f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 508f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 509f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 510f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 511f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 512f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 513f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolAddress(DataRefImpl Symb, 514f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 515f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 516f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 517f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section; 518f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 519f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: 520f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 521f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 522f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 523f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: 524f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value; 525f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 526f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: Section = getSection(symb); 527f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 528f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 529f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 530f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 531f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = Section ? Section->sh_addr : UnknownAddressOrSize; 532f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 533f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 534f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 535f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_NOTYPE: 536f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value + (Section ? Section->sh_addr : 0); 537f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 538f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 539f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 540f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 541f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 542f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 543f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 544f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 545f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 546f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolSize(DataRefImpl Symb, 547f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 548f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 549f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 550f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_size == 0) 551f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 552f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_size; 553f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 554f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 555f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 556f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 557f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 558f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolNMTypeChar(DataRefImpl Symb, 559f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky char &Result) const { 560f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 561f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 562f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section = getSection(symb); 563f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 564f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky char ret = '?'; 565f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 566f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Section) { 567f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Section->sh_type) { 568f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_PROGBITS: 569f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_DYNAMIC: 570f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Section->sh_flags) { 571f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 572f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 't'; break; 573f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 574f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'd'; break; 575f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHF_ALLOC: 576f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 577f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 578f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'r'; break; 579f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 580f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 581f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_NOBITS: ret = 'b'; 582f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 583f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 584f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 585f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 586f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 587f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ret == '?') 588f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'U'; 589f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 590f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: ret = 'a'; break; 591f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: ret = 'c'; break; 592f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 593f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 594f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getBinding()) { 595f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STB_GLOBAL: ret = ::toupper(ret); break; 596f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STB_WEAK: 597f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 598f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'w'; 599f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 600f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->getType() == ELF::STT_OBJECT) 601f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'V'; 602f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 603f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'W'; 604f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 605f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 606f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ret == '?' && symb->getType() == ELF::STT_SECTION) { 607f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef name; 608f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (error_code ec = getSymbolName(Symb, name)) 609f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ec; 610f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringSwitch<char>(name) 611f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .StartsWith(".debug", 'N') 612f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .StartsWith(".note", 'n') 613f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .Default('?'); 614f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 615f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 616f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 617f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = ret; 618f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 619f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 620f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 621f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 622f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 623f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolType(DataRefImpl Symb, 624f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef::Type &Result) const { 625f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 626f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 627f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 628f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 6292c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_NOTYPE: 6302c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result = SymbolRef::ST_Unknown; 6312c67727046234ad9702ab5acb72700b5ac99a676David Meyer break; 632f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 633f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Debug; 634f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 635f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FILE: 636f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_File; 637f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 638f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 639f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Function; 640f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 641f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 6422c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_COMMON: 6432c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_TLS: 644f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Data; 645f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 646f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 647f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Other; 648f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 649f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 650f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 651f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 652f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 653f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 654f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 655c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer ::getSymbolFlags(DataRefImpl Symb, 656c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer uint32_t &Result) const { 657f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 658f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 659f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 660c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result = SymbolRef::SF_None; 661f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 662c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getBinding() != ELF::STB_LOCAL) 663c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Global; 664f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 665c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getBinding() == ELF::STB_WEAK) 666c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Weak; 667c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 668c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->st_shndx == ELF::SHN_ABS) 669c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Absolute; 670c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 671c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getType() == ELF::STT_FILE || 672c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer symb->getType() == ELF::STT_SECTION) 673c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_FormatSpecific; 674f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 6752c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 6762c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_Undefined; 6772c67727046234ad9702ab5acb72700b5ac99a676David Meyer 6782c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (symb->getType() == ELF::STT_COMMON || 6792c67727046234ad9702ab5acb72700b5ac99a676David Meyer getSymbolTableIndex(symb) == ELF::SHN_COMMON) 6802c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_Common; 6812c67727046234ad9702ab5acb72700b5ac99a676David Meyer 6822c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (symb->getType() == ELF::STT_TLS) 6832c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_ThreadLocal; 6842c67727046234ad9702ab5acb72700b5ac99a676David Meyer 685f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 686f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 687f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 688f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 689f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 690f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolSection(DataRefImpl Symb, 691f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky section_iterator &Res) const { 692f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 693f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 694f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(symb); 695f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!sec) 696f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Res = end_sections(); 697f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else { 698f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl Sec; 699f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sec.p = reinterpret_cast<intptr_t>(sec); 700f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Res = section_iterator(SectionRef(Sec, this)); 701f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 702f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 703f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 704f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 705f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 706f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 707f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const { 708f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); 709f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky sec += Header->e_shentsize; 710f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sec.p = reinterpret_cast<intptr_t>(sec); 711f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SectionRef(Sec, this); 712f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 713f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 714f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 715f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 716f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 717f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionName(DataRefImpl Sec, 718f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 719f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 720f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); 721f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 722f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 723f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 724f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 725f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 726f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionAddress(DataRefImpl Sec, 727f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 728f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 729f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_addr; 730f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 731f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 732f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 733f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 734f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 735f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionSize(DataRefImpl Sec, 736f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 737f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 738f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_size; 739f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 740f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 741f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 742f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 743f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 744f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionContents(DataRefImpl Sec, 745f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 746f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 747f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *start = (const char*)base() + sec->sh_offset; 748f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringRef(start, sec->sh_size); 749f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 750f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 751f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 752f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 753f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 754f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionAlignment(DataRefImpl Sec, 755f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 756f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 757f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_addralign; 758f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 759f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 760f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 761f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 762f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 763f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionText(DataRefImpl Sec, 764f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 765f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 766f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & ELF::SHF_EXECINSTR) 767f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 768f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 769f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 770f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 771f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 772f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 773f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 774f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 775f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionData(DataRefImpl Sec, 776f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 777f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 778f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 779f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && sec->sh_type == ELF::SHT_PROGBITS) 780f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 781f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 782f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 783f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 784f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 785f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 786f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 787f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 788f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionBSS(DataRefImpl Sec, 789f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 790f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 791f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 792f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && sec->sh_type == ELF::SHT_NOBITS) 793f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 794f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 795f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 796f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 797f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 798f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 799f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 800f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 801f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::sectionContainsSymbol(DataRefImpl Sec, 802f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl Symb, 803f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 804f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Unimplemented. 805f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 806f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 807f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 808f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 809f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 810f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyrelocation_iterator ELFObjectFile<target_endianness, is64Bits> 811f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionRelBegin(DataRefImpl Sec) const { 812f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl RelData; 813f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&RelData, 0, sizeof(RelData)); 814f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 815f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 816f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec != 0 && ittr != SectionRelocMap.end()) { 817f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.a = getSection(ittr->second[0])->sh_info; 818f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.b = ittr->second[0]; 819f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.c = 0; 820f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 821f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return relocation_iterator(RelocationRef(RelData, this)); 822f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 823f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 824f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 825f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyrelocation_iterator ELFObjectFile<target_endianness, is64Bits> 826f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionRelEnd(DataRefImpl Sec) const { 827f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl RelData; 828f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&RelData, 0, sizeof(RelData)); 829f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 830f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 831f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec != 0 && ittr != SectionRelocMap.end()) { 832f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Get the index of the last relocation section for this section. 833f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; 834f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *relocsec = getSection(relocsecindex); 835f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.a = relocsec->sh_info; 836f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.b = relocsecindex; 837f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; 838f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 839f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return relocation_iterator(RelocationRef(RelData, this)); 840f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 841f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 842f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Relocations 843f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 844f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 845f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationNext(DataRefImpl Rel, 846f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocationRef &Result) const { 847f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++Rel.w.c; 848f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *relocsec = getSection(Rel.w.b); 849f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { 850f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // We have reached the end of the relocations for this section. See if there 851f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // is another relocation section. 852f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::mapped_type relocseclist = 853f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionRelocMap.lookup(getSection(Rel.w.a)); 854f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 855f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Do a binary search for the current reloc section index (which must be 856f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // present). Then get the next one. 857f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::mapped_type::const_iterator loc = 858f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b); 859f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++loc; 860f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 861f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel 862f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // to the end iterator. 863f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (loc != relocseclist.end()) { 864f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Rel.w.b = *loc; 865f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Rel.w.a = 0; 866f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 867f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 868f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = RelocationRef(Rel, this); 869f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 870f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 871f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 872f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 873f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 874f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationSymbol(DataRefImpl Rel, 875f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Result) const { 876f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t symbolIdx; 877f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 878f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 879f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 880f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 881f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 882f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbolIdx = getRel(Rel)->getSymbol(); 883f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 884f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 885f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 886f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbolIdx = getRela(Rel)->getSymbol(); 887f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 888f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 889f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 890f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 891f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link); 892f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (it == SymbolTableSectionsIndexMap.end()) 893f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Relocation symbol table not found!"); 894f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = symbolIdx; 895f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = it->second; 896f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef(SymbolData, this); 897f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 898f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 899f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 900f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 901f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 902f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationAddress(DataRefImpl Rel, 903f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 904f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t offset; 905f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 906f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 907f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 908f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 909f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 910f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRel(Rel)->r_offset; 911f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 912f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 913f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 914f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRela(Rel)->r_offset; 915f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 916f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 917f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 918f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 919f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = offset; 920f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 921f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 922f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 923f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 924f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 925f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationOffset(DataRefImpl Rel, 926f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 927f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t offset; 928f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 929f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 930f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 931f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 932f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 933f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRel(Rel)->r_offset; 934f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 935f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 936f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 937f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRela(Rel)->r_offset; 938f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 939f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 940f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 941f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 942f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = offset - sec->sh_addr; 943f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 944f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 945f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 946f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 947f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 948f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationType(DataRefImpl Rel, 949f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 950f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 951f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 952f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 953f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 954f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 955f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRel(Rel)->getType(); 956f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 957f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 958f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 959f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRela(Rel)->getType(); 960f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 961f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 962f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 963f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 964f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 965f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 966f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ 967f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::enum: res = #enum; break; 968f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 969f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 970f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 971f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationTypeName(DataRefImpl Rel, 972f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const { 973f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 974f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint8_t type; 975f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef res; 976f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 977f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 978f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::parse_failed; 979f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 980f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRel(Rel)->getType(); 981f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 982f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 983f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 984f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRela(Rel)->getType(); 985f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 986f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 987f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 988f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Header->e_machine) { 989f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 990f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 991f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); 992f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); 993f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); 994f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); 995f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); 996f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); 997f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); 998f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); 999f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); 1000f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); 1001f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32); 1002f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S); 1003f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16); 1004f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16); 1005f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8); 1006f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8); 1007f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64); 1008f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); 1009f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); 1010f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); 1011f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); 1012f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); 1013f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); 1014f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); 1015f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); 1016f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); 1017f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); 1018f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); 1019f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); 1020f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); 1021f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); 1022f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); 1023f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1024f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1025f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1026f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1027f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1028f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 1029f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); 1030f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); 1031f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); 1032f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); 1033f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); 1034f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); 1035f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); 1036f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); 1037f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); 1038f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); 1039f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC); 1040f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT); 1041f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF); 1042f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE); 1043f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE); 1044f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE); 1045f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD); 1046f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM); 1047f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16); 1048f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16); 1049f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8); 1050f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8); 1051f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32); 1052f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH); 1053f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL); 1054f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP); 1055f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32); 1056f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH); 1057f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL); 1058f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP); 1059f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); 1060f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); 1061f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); 1062f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); 1063f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); 1064f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); 1065f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); 1066f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); 1067f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); 1068f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); 1069f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1070f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1071f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1072f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1073f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1074f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1075f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1076f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(res.begin(), res.end()); 1077f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1078f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1079f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1080f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME 1081f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1082f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1083f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1084f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationAdditionalInfo(DataRefImpl Rel, 1085f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t &Result) const { 1086f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1087f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1088f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1089f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1090f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1091f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = 0; 1092f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1093f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1094f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1095f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRela(Rel)->r_addend; 1096f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1097f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1098f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1099f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1100f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1101f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1102f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1103f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationValueString(DataRefImpl Rel, 1104f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const { 1105f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1106f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint8_t type; 1107f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef res; 1108f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t addend = 0; 1109f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint16_t symbol_index = 0; 1110f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1111f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1112f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::parse_failed; 1113f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1114f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRel(Rel)->getType(); 1115f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbol_index = getRel(Rel)->getSymbol(); 1116f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // TODO: Read implicit addend from section data. 1117f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1118f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1119f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1120f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRela(Rel)->getType(); 1121f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbol_index = getRela(Rel)->getSymbol(); 1122f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky addend = getRela(Rel)->r_addend; 1123f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1124f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1125f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1126f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index); 1127f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef symname; 1128dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname)) 1129f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ec; 1130f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Header->e_machine) { 1131f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1132f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 1133f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::R_X86_64_32S: 1134f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = symname; 1135f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1136f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::R_X86_64_PC32: { 1137f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::string fmtbuf; 1138f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky raw_string_ostream fmt(fmtbuf); 1139f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky fmt << symname << (addend < 0 ? "" : "+") << addend << "-P"; 1140f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky fmt.flush(); 1141f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(fmtbuf.begin(), fmtbuf.end()); 1142f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1143f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1144f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1145f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1146f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1147f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1148f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1149f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1150f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1151f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Result.empty()) 1152f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(res.begin(), res.end()); 1153f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1154f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1155f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1156dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer// Verify that the last byte in the string table in a null. 1157dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1158dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencervoid ELFObjectFile<target_endianness, is64Bits> 1159dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::VerifyStrTab(const Elf_Shdr *sh) const { 1160dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const char *strtab = (const char*)base() + sh->sh_offset; 1161dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (strtab[sh->sh_size - 1] != 0) 1162dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1163dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("String table must end with a null terminator!"); 1164dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1165dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1166f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1167f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object 1168f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , error_code &ec) 1169f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : ObjectFile(Binary::isELF, Object, ec) 1170f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , isDyldELFObject(false) 1171f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , SectionHeaderTable(0) 1172f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , dot_shstrtab_sec(0) 1173dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer , dot_strtab_sec(0) 1174dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer , dot_dynstr_sec(0) { 1175f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1176f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t FileSize = Data->getBufferSize(); 1177f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1178f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sizeof(Elf_Ehdr) > FileSize) 1179f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1180f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("File too short!"); 1181f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1182f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Header = reinterpret_cast<const Elf_Ehdr *>(base()); 1183f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1184f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shoff == 0) 1185f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return; 1186f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1187f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t SectionTableOffset = Header->e_shoff; 1188f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1189f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) 1190f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1191f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Section header table goes past end of file!"); 1192f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1193f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // The getNumSections() call below depends on SectionHeaderTable being set. 1194f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionHeaderTable = 1195f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); 1196f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; 1197f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1198f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionTableOffset + SectionTableSize > FileSize) 1199f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1200f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Section table goes past end of file!"); 1201f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1202f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // To find the symbol tables we walk the section table to find SHT_SYMTAB. 1203f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr* SymbolTableSectionHeaderIndex = 0; 1204f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr* sh = SectionHeaderTable; 1205dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1206dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Reserve SymbolTableSections[0] for .dynsym 1207dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSections.push_back(NULL); 1208dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1209f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (uint64_t i = 0, e = getNumSections(); i != e; ++i) { 1210f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) { 1211f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SymbolTableSectionHeaderIndex) 1212f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1213f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("More than one .symtab_shndx!"); 1214f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionHeaderIndex = sh; 1215f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1216f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh->sh_type == ELF::SHT_SYMTAB) { 1217f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionsIndexMap[i] = SymbolTableSections.size(); 1218f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSections.push_back(sh); 1219f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1220dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (sh->sh_type == ELF::SHT_DYNSYM) { 1221dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections[0] != NULL) 1222dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1223dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("More than one .dynsym!"); 1224dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSectionsIndexMap[i] = 0; 1225dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSections[0] = sh; 1226dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 1227f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) { 1228f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionRelocMap[getSection(sh->sh_info)].push_back(i); 1229f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1230f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++sh; 1231f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1232f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1233f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Sort section relocation lists by index. 1234f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (typename RelocMap_t::iterator i = SectionRelocMap.begin(), 1235f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky e = SectionRelocMap.end(); i != e; ++i) { 1236f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::sort(i->second.begin(), i->second.end()); 1237f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1238f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1239f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Get string table sections. 1240f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky dot_shstrtab_sec = getSection(getStringTableIndex()); 1241f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (dot_shstrtab_sec) { 1242f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Verify that the last byte in the string table in a null. 1243dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_shstrtab_sec); 1244f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1245f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1246f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Merge this into the above loop. 1247f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable), 1248f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky *e = i + getNumSections() * Header->e_shentsize; 1249f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky i != e; i += Header->e_shentsize) { 1250f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i); 1251f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh->sh_type == ELF::SHT_STRTAB) { 1252f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name)); 1253f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionName == ".strtab") { 1254f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (dot_strtab_sec != 0) 1255f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1256f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Already found section named .strtab!"); 1257f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky dot_strtab_sec = sh; 1258dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_strtab_sec); 1259dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else if (SectionName == ".dynstr") { 1260dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (dot_dynstr_sec != 0) 1261dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1262dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("Already found section named .dynstr!"); 1263dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer dot_dynstr_sec = sh; 1264dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_dynstr_sec); 1265f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1266f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1267f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1268f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1269f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Build symbol name side-mapping if there is one. 1270f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SymbolTableSectionHeaderIndex) { 1271f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + 1272f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionHeaderIndex->sh_offset); 1273f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky error_code ec; 1274f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (symbol_iterator si = begin_symbols(), 1275f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky se = end_symbols(); si != se; si.increment(ec)) { 1276f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ec) 1277f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Fewer extended symbol table entries than symbols!"); 1278f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (*ShndxTable != ELF::SHN_UNDEF) 1279f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable; 1280f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++ShndxTable; 1281f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1282f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1283f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1284f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1285f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1286f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1287f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::begin_symbols() const { 1288f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 1289f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&SymbolData, 0, sizeof(SymbolData)); 1290dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections.size() <= 1) { 1291f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1292f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1293f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } else { 1294f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 1295dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = 1; // The 0th table is .dynsym 1296f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1297f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symbol_iterator(SymbolRef(SymbolData, this)); 1298f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1299f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1300f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1301f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1302f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::end_symbols() const { 1303f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 1304f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&SymbolData, 0, sizeof(SymbolData)); 1305f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1306f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1307f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symbol_iterator(SymbolRef(SymbolData, this)); 1308f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1309f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1310f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1311dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1312dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::begin_dynamic_symbols() const { 1313dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer DataRefImpl SymbolData; 1314dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer memset(&SymbolData, 0, sizeof(SymbolData)); 1315dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections[0] == NULL) { 1316dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1317dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1318dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else { 1319dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 1320dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = 0; // The 0th table is .dynsym 1321dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 1322dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return symbol_iterator(SymbolRef(SymbolData, this)); 1323dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1324dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1325dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1326dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1327dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::end_dynamic_symbols() const { 1328dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer DataRefImpl SymbolData; 1329dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer memset(&SymbolData, 0, sizeof(SymbolData)); 1330dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1331dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1332dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return symbol_iterator(SymbolRef(SymbolData, this)); 1333dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1334dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1335dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1336f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysection_iterator ELFObjectFile<target_endianness, is64Bits> 1337f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::begin_sections() const { 1338f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl ret; 1339f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&ret, 0, sizeof(DataRefImpl)); 1340f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); 1341f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return section_iterator(SectionRef(ret, this)); 1342f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1343f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1344f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1345f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysection_iterator ELFObjectFile<target_endianness, is64Bits> 1346f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::end_sections() const { 1347f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl ret; 1348f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&ret, 0, sizeof(DataRefImpl)); 1349f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret.p = reinterpret_cast<intptr_t>(base() 1350f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + Header->e_shoff 1351f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (Header->e_shentsize*getNumSections())); 1352f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return section_iterator(SectionRef(ret, this)); 1353f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1354f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1355f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1356f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const { 1357f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return is64Bits ? 8 : 4; 1358f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1359f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1360f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1361f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyStringRef ELFObjectFile<target_endianness, is64Bits> 1362f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getFileFormatName() const { 1363f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_ident[ELF::EI_CLASS]) { 1364f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::ELFCLASS32: 1365f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1366f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1367f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-i386"; 1368f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1369f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-x86-64"; 1370f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_ARM: 1371f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-arm"; 1372f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1373f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-unknown"; 1374f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1375f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::ELFCLASS64: 1376f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1377f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1378f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-i386"; 1379f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1380f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-x86-64"; 1381f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1382f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-unknown"; 1383f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1384f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1385f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1386f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid ELFCLASS!"); 1387f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1388f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1389f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1390f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1391f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyunsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { 1392f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1393f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1394f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::x86; 1395f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1396f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::x86_64; 1397f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_ARM: 1398f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::arm; 1399f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1400f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::UnknownArch; 1401f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1402f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1403f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1404f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1405f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const { 1406f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(Header && "Header not initialized!"); 1407f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shnum == ELF::SHN_UNDEF) { 1408f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 1409f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return SectionHeaderTable->sh_size; 1410f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1411f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Header->e_shnum; 1412f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1413f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1414f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1415f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint64_t 1416f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const { 1417f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shnum == ELF::SHN_UNDEF) { 1418f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shstrndx == ELF::SHN_HIRESERVE) 1419f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return SectionHeaderTable->sh_link; 1420f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shstrndx >= getNumSections()) 1421f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 1422f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1423f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Header->e_shstrndx; 1424f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1425f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1426f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1427f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1428f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<typename T> 1429f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyinline const T * 1430f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section, 1431f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t Entry) const { 1432f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<T>(getSection(Section), Entry); 1433f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1434f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1435f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1436f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<typename T> 1437f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyinline const T * 1438f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section, 1439f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t Entry) const { 1440f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return reinterpret_cast<const T *>( 1441f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky base() 1442f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + Section->sh_offset 1443f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (Entry * Section->sh_entsize)); 1444f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1445f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1446f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1447f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * 1448f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const { 1449f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); 1450f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1451f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1452f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1453f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel * 1454f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const { 1455f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); 1456f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1457f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1458f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1459f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela * 1460f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const { 1461f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); 1462f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1463f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1464f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1465f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 1466f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const { 1467f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Symb.d.b); 1468f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) 1469f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1470f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid symbol table section!"); 1471f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return sec; 1472f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1473f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1474f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1475f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 1476f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const { 1477f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (index == 0) 1478f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 1479f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!SectionHeaderTable || index >= getNumSections()) 1480f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1481f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section index!"); 1482f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1483f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return reinterpret_cast<const Elf_Shdr *>( 1484f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky reinterpret_cast<const char *>(SectionHeaderTable) 1485f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (index * Header->e_shentsize)); 1486f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1487f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1488f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1489f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst char *ELFObjectFile<target_endianness, is64Bits> 1490f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getString(uint32_t section, 1491f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf32_Word offset) const { 1492f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getString(getSection(section), offset); 1493f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1494f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1495f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1496f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst char *ELFObjectFile<target_endianness, is64Bits> 1497f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getString(const Elf_Shdr *section, 1498f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf32_Word offset) const { 1499f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); 1500f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (offset >= section->sh_size) 1501f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1502f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Symbol name offset outside of string table!"); 1503f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (const char *)base() + section->sh_offset + offset; 1504f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1505f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1506f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1507f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1508dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::getSymbolName(const Elf_Shdr *section, 1509dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Sym *symb, 1510f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 1511f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_name == 0) { 1512f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *section = getSection(symb); 1513f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!section) 1514f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = ""; 1515f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 1516f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getString(dot_shstrtab_sec, section->sh_name); 1517f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1518f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1519f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1520dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (section == SymbolTableSections[0]) { 1521dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Symbol is in .dynsym, use .dynstr string table 1522dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Result = getString(dot_dynstr_sec, symb->st_name); 1523dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else { 1524dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Use the default symbol table name section. 1525dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Result = getString(dot_strtab_sec, symb->st_name); 1526dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 1527f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1528f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1529f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1530f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1531f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1532f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1533f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#endif 1534