ELF.h revision 2d70e263c2b508bf4641273dd89a23149f6f6164
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" 212d70e263c2b508bf4641273dd89a23149f6f6164David Meyer#include "llvm/ADT/PointerIntPair.h" 22f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Object/ObjectFile.h" 23f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/Casting.h" 24f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/ELF.h" 25f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/Endian.h" 26f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/ErrorHandling.h" 27f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/MemoryBuffer.h" 28f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Support/raw_ostream.h" 29f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <algorithm> 30f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <limits> 31f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include <utility> 32f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 33f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace llvm { 34f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace object { 35f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 36f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Templates to choose Elf_Addr and Elf_Off depending on is64Bits. 37f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 38f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelperCommon { 39f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 40f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint16_t, target_endianness, support::aligned> Elf_Half; 41f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 42f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint32_t, target_endianness, support::aligned> Elf_Word; 43f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 44f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <int32_t, target_endianness, support::aligned> Elf_Sword; 45f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 46f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <uint64_t, target_endianness, support::aligned> Elf_Xword; 47f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 48f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <int64_t, target_endianness, support::aligned> Elf_Sxword; 49f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 50f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 51f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 52f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper; 53f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 54f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky/// ELF 32bit types. 55f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 56f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper<target_endianness, false> 57f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : ELFDataTypeTypedefHelperCommon<target_endianness> { 58f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef uint32_t value_type; 59f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 60f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Addr; 61f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 62f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Off; 63f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 64f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 65f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky/// ELF 64bit types. 66f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 67f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct ELFDataTypeTypedefHelper<target_endianness, true> 68f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : ELFDataTypeTypedefHelperCommon<target_endianness>{ 69f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef uint64_t value_type; 70f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 71f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Addr; 72f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef support::detail::packed_endian_specific_integral 73f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky <value_type, target_endianness, support::aligned> Elf_Off; 74f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 75f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 76f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// I really don't like doing this, but the alternative is copypasta. 77f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#define LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) \ 78f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 79f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Addr Elf_Addr; \ 80f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 81f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Off Elf_Off; \ 82f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 83f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Half Elf_Half; \ 84f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 85f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Word Elf_Word; \ 86f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 87f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sword Elf_Sword; \ 88f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 89f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Xword Elf_Xword; \ 90f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytypedef typename \ 91f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFDataTypeTypedefHelper<target_endianness, is64Bits>::Elf_Sxword Elf_Sxword; 92f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 93f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Section header. 94f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 95f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base; 96f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 97f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 98f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base<target_endianness, false> { 99f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 100f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_name; // Section name (index into string table) 101f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_type; // Section type (SHT_*) 102f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_flags; // Section flags (SHF_*) 103f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr sh_addr; // Address where section is to be loaded 104f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off sh_offset; // File offset of section data, in bytes 105f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_size; // Size of section, in bytes 106f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_link; // Section type-specific header table index link 107f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_info; // Section type-specific extra information 108f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_addralign;// Section address alignment 109f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_entsize; // Size of records contained within the section 110f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 111f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 112f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 113f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Base<target_endianness, true> { 114f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 115f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_name; // Section name (index into string table) 116f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_type; // Section type (SHT_*) 117f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_flags; // Section flags (SHF_*) 118f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr sh_addr; // Address where section is to be loaded 119f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off sh_offset; // File offset of section data, in bytes 120f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_size; // Size of section, in bytes 121f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_link; // Section type-specific header table index link 122f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word sh_info; // Section type-specific extra information 123f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_addralign;// Section address alignment 124f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword sh_entsize; // Size of records contained within the section 125f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 126f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 127f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 128f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Shdr_Impl : Elf_Shdr_Base<target_endianness, is64Bits> { 129f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Shdr_Base<target_endianness, is64Bits>::sh_entsize; 130f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Shdr_Base<target_endianness, is64Bits>::sh_size; 131f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 132f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Get the number of entities this section contains if it has any. 133f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned getEntityCount() const { 134f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh_entsize == 0) 135f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 136f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return sh_size / sh_entsize; 137f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 138f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 139f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 140f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 141f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base; 142f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 143f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 144f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base<target_endianness, false> { 145f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 146f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_name; // Symbol name (index into string table) 147f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr st_value; // Value or address associated with the symbol 148f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_size; // Size of the symbol 149f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_info; // Symbol's type and binding attributes 150f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_other; // Must be zero; reserved 151f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half st_shndx; // Which section (header table index) it's defined in 152f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 153f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 154f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 155f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Base<target_endianness, true> { 156f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 157f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word st_name; // Symbol name (index into string table) 158f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_info; // Symbol's type and binding attributes 159f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char st_other; // Must be zero; reserved 160f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half st_shndx; // Which section (header table index) it's defined in 161f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr st_value; // Value or address associated with the symbol 162f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword st_size; // Size of the symbol 163f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 164f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 165f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 166f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Sym_Impl : Elf_Sym_Base<target_endianness, is64Bits> { 167f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Sym_Base<target_endianness, is64Bits>::st_info; 168f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 169f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF32_ST_BIND, 170f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: 171f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getBinding() const { return st_info >> 4; } 172f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { return st_info & 0x0f; } 173f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 174f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 175f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setBindingAndType(unsigned char b, unsigned char t) { 176f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky st_info = (b << 4) + (t & 0x0f); 177f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 178f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 179f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1802d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section 1812d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// (.gnu.version). This structure is identical for ELF32 and ELF64. 1822d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 1832d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Versym_Impl { 1842d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 1852d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) 1862d70e263c2b508bf4641273dd89a23149f6f6164David Meyer}; 1872d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 1882d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 1892d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Verdaux_Impl; 1902d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 1912d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section 1922d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// (.gnu.version_d). This structure is identical for ELF32 and ELF64. 1932d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 1942d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Verdef_Impl { 1952d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 1962d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; 1972d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) 1982d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) 1992d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vd_ndx; // Version index, used in .gnu.version entries 2002d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vd_cnt; // Number of Verdaux entries 2012d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vd_hash; // Hash of name 2022d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) 2032d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) 2042d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2052d70e263c2b508bf4641273dd89a23149f6f6164David Meyer /// Get the first Verdaux entry for this Verdef. 2062d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Verdaux *getAux() const { 2072d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux); 2082d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 2092d70e263c2b508bf4641273dd89a23149f6f6164David Meyer}; 2102d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2112d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Verdaux: This is the structure of auxilary data in the SHT_GNU_verdef 2122d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. 2132d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 2142d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Verdaux_Impl { 2152d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 2162d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vda_name; // Version name (offset in string table) 2172d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) 2182d70e263c2b508bf4641273dd89a23149f6f6164David Meyer}; 2192d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2202d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed 2212d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 2222d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 2232d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Verneed_Impl { 2242d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 2252d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) 2262d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vn_cnt; // Number of associated Vernaux entries 2272d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vn_file; // Library name (string table offset) 2282d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) 2292d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vn_next; // Offset to next Verneed entry (in bytes) 2302d70e263c2b508bf4641273dd89a23149f6f6164David Meyer}; 2312d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2322d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed 2332d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 2342d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 2352d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstruct Elf_Vernaux_Impl { 2362d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 2372d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vna_hash; // Hash of dependency name 2382d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) 2392d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Half vna_other; // Version index, used in .gnu.version entries 2402d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vna_name; // Dependency name 2412d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) 2422d70e263c2b508bf4641273dd89a23149f6f6164David Meyer}; 2432d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2442d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic 2452d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// table section (.dynamic) look like. 2465c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 2475c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerstruct Elf_Dyn_Base; 2485c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2495c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness> 2505c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerstruct Elf_Dyn_Base<target_endianness, false> { 2515c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, false) 2525c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Sword d_tag; 2535c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer union { 2545c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Word d_val; 2555c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Addr d_ptr; 2565c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } d_un; 2575c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}; 2585c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2595c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness> 2605c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerstruct Elf_Dyn_Base<target_endianness, true> { 2615c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer LLVM_ELF_IMPORT_TYPES(target_endianness, true) 2625c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Sxword d_tag; 2635c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer union { 2645c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Xword d_val; 2655c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Elf_Addr d_ptr; 2665c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } d_un; 2675c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}; 2685c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2692d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters. 2705c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 2715c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerstruct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> { 2725c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag; 2735c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer using Elf_Dyn_Base<target_endianness, is64Bits>::d_un; 2745c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer int64_t getTag() const { return d_tag; } 2755c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer uint64_t getVal() const { return d_un.d_val; } 2765c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer uint64_t getPtr() const { return d_un.ptr; } 2775c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}; 2785c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2795c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 2805c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerclass ELFObjectFile; 2815c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2825c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// DynRefImpl: Reference to an entry in the dynamic table 2835c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// This is an ELF-specific interface. 2845c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 2855c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerclass DynRefImpl { 2865c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; 2875c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer typedef ELFObjectFile<target_endianness, is64Bits> OwningType; 2885c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2895c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DataRefImpl DynPimpl; 2905c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer const OwningType *OwningObject; 2915c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2925c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerpublic: 2935c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynRefImpl() : OwningObject(NULL) { 2945c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer std::memset(&DynPimpl, 0, sizeof(DynPimpl)); 2955c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 2965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2975c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynRefImpl(DataRefImpl DynP, const OwningType *Owner); 2985c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 2995c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer bool operator==(const DynRefImpl &Other) const; 3005c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer bool operator <(const DynRefImpl &Other) const; 3015c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 3025c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer error_code getNext(DynRefImpl &Result) const; 3035c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer int64_t getTag() const; 3045c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer uint64_t getVal() const; 3055c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer uint64_t getPtr() const; 3065c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 3075c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DataRefImpl getRawDataRefImpl() const; 3085c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer}; 3095c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 3105c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer// Elf_Rel: Elf Relocation 311f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits, bool isRela> 312f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base; 313f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 314f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 315f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, false, false> { 316f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 317f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 318f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word r_info; // Symbol table index and type of relocation to apply 319f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 320f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 321f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 322f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, true, false> { 323f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 324f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 325f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword r_info; // Symbol table index and type of relocation to apply 326f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 327f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 328f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 329f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, false, true> { 330f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 331f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 332f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word r_info; // Symbol table index and type of relocation to apply 333f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Sword r_addend; // Compute value for relocatable field by adding this 334f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 335f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 336f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness> 337f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Base<target_endianness, true, true> { 338f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 339f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 340f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Xword r_info; // Symbol table index and type of relocation to apply 341f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Sxword r_addend; // Compute value for relocatable field by adding this. 342f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 343f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 344f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits, bool isRela> 345f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl; 346f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 347f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool isRela> 348f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl<target_endianness, true, isRela> 349f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : Elf_Rel_Base<target_endianness, true, isRela> { 350f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Rel_Base<target_endianness, true, isRela>::r_info; 351f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, true) 352f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 353f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, 354f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // and ELF64_R_INFO macros defined in the ELF specification: 355f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getSymbol() const { return (r_info >> 32); } 356f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { 357f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (unsigned char) (r_info & 0xffffffffL); 358f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 359f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); } 360f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 361f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbolAndType(uint64_t s, unsigned char t) { 362f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky r_info = (s << 32) + (t&0xffffffffL); 363f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 364f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 365f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 366f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool isRela> 367f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskystruct Elf_Rel_Impl<target_endianness, false, isRela> 368f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky : Elf_Rel_Base<target_endianness, false, isRela> { 369f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky using Elf_Rel_Base<target_endianness, false, isRela>::r_info; 370f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, false) 371f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 372f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, 373f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // and ELF32_R_INFO macros defined in the ELF specification: 374f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t getSymbol() const { return (r_info >> 8); } 375f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); } 376f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 377f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 378f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void setSymbolAndType(uint32_t s, unsigned char t) { 379f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky r_info = (s << 8) + t; 380f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 381f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 382f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 383f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 384f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 385f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyclass ELFObjectFile : public ObjectFile { 386f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits) 387f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 388f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr; 389f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym; 3905c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn; 391f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel; 392f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela; 3932d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Verdef_Impl<target_endianness, is64Bits> Elf_Verdef; 3942d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Verdaux_Impl<target_endianness, is64Bits> Elf_Verdaux; 3952d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Verneed_Impl<target_endianness, is64Bits> Elf_Verneed; 3962d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Vernaux_Impl<target_endianness, is64Bits> Elf_Vernaux; 3972d70e263c2b508bf4641273dd89a23149f6f6164David Meyer typedef Elf_Versym_Impl<target_endianness, is64Bits> Elf_Versym; 3985c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer typedef DynRefImpl<target_endianness, is64Bits> DynRef; 3995c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer typedef content_iterator<DynRef> dyn_iterator; 400f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 401f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 402f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky struct Elf_Ehdr { 403f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes 404f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_type; // Type of file (see ET_*) 405f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_machine; // Required architecture for this file (see EM_*) 406f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word e_version; // Must be equal to 1 407f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Addr e_entry; // Address to jump to in order to start program 408f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off e_phoff; // Program header table's file offset, in bytes 409f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Off e_shoff; // Section header table's file offset, in bytes 410f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Word e_flags; // Processor-specific flags 411f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_ehsize; // Size of ELF header, in bytes 412f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_phentsize;// Size of an entry in the program header table 413f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_phnum; // Number of entries in the program header table 414f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shentsize;// Size of an entry in the section header table 415f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shnum; // Number of entries in the section header table 416f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Elf_Half e_shstrndx; // Section header table index of section name 417f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // string table 418f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool checkMagic() const { 419f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 420f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 421f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } 422f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } 423f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky }; 424f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // This flag is used for classof, to distinguish ELFObjectFile from 425f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // its subclass. If more subclasses will be created, this flag will 426f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // have to become an enum. 427f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isDyldELFObject; 428f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 429f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprivate: 430f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef SmallVector<const Elf_Shdr*, 1> Sections_t; 431f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef DenseMap<unsigned, unsigned> IndexMap_t; 432f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t; 433f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 434f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Ehdr *Header; 435f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SectionHeaderTable; 436f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *dot_shstrtab_sec; // Section header string table. 437f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *dot_strtab_sec; // Symbol header string table. 438dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table. 4392d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 4402d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // SymbolTableSections[0] always points to the dynamic string table section 4412d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // header, or NULL if there is no dynamic string table. 442f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sections_t SymbolTableSections; 443f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky IndexMap_t SymbolTableSectionsIndexMap; 444f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable; 445f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 4462d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Shdr *dot_dynamic_sec; // .dynamic 4472d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Shdr *dot_gnu_version_sec; // .gnu.version 4482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r 4492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d 4502d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 45197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer // Pointer to SONAME entry in dynamic string table 45297f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer // This is set the first time getLoadName is called. 45397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer mutable const char *dt_soname; 4545c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 4552d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Records for each version index the corresponding Verdef or Vernaux entry. 4562d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // This is filled the first time LoadVersionMap() is called. 4572d70e263c2b508bf4641273dd89a23149f6f6164David Meyer class VersionMapEntry : public PointerIntPair<const void*, 1> { 4582d70e263c2b508bf4641273dd89a23149f6f6164David Meyer public: 4592d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // If the integer is 0, this is an Elf_Verdef*. 4602d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // If the integer is 1, this is an Elf_Vernaux*. 4612d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } 4622d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMapEntry(const Elf_Verdef *verdef) 4632d70e263c2b508bf4641273dd89a23149f6f6164David Meyer : PointerIntPair<const void*, 1>(verdef, 0) { } 4642d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMapEntry(const Elf_Vernaux *vernaux) 4652d70e263c2b508bf4641273dd89a23149f6f6164David Meyer : PointerIntPair<const void*, 1>(vernaux, 1) { } 4662d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool isNull() const { return getPointer() == NULL; } 4672d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool isVerdef() const { return !isNull() && getInt() == 0; } 4682d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool isVernaux() const { return !isNull() && getInt() == 1; } 4692d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Verdef *getVerdef() const { 4702d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL; 4712d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 4722d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Vernaux *getVernaux() const { 4732d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL; 4742d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 4752d70e263c2b508bf4641273dd89a23149f6f6164David Meyer }; 4762d70e263c2b508bf4641273dd89a23149f6f6164David Meyer mutable SmallVector<VersionMapEntry, 16> VersionMap; 4772d70e263c2b508bf4641273dd89a23149f6f6164David Meyer void LoadVersionDefs(const Elf_Shdr *sec) const; 4782d70e263c2b508bf4641273dd89a23149f6f6164David Meyer void LoadVersionNeeds(const Elf_Shdr *ec) const; 4792d70e263c2b508bf4641273dd89a23149f6f6164David Meyer void LoadVersionMap() const; 4802d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 481f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Map sections to an array of relocation sections that reference 482f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// them sorted by section index. 483f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocMap_t SectionRelocMap; 484f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 485f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky /// @brief Get the relocation section that contains \a Rel. 486f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 487f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(Rel.w.b); 488f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 489f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 490f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isRelocationHasAddend(DataRefImpl Rel) const; 491f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky template<typename T> 492f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const T *getEntry(uint16_t Section, uint32_t Entry) const; 493f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky template<typename T> 494f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; 495f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(DataRefImpl index) const; 496f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(uint32_t index) const; 497f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Rel *getRel(DataRefImpl Rel) const; 498f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Rela *getRela(DataRefImpl Rela) const; 499f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *getString(uint32_t section, uint32_t offset) const; 500f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *getString(const Elf_Shdr *section, uint32_t offset) const; 501dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer error_code getSymbolName(const Elf_Shdr *section, 502dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Sym *Symb, 503dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer StringRef &Res) const; 5042d70e263c2b508bf4641273dd89a23149f6f6164David Meyer error_code getSymbolVersion(const Elf_Shdr *section, 5052d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Sym *Symb, 5062d70e263c2b508bf4641273dd89a23149f6f6164David Meyer StringRef &Version, 5072d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool &IsDefault) const; 508dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer void VerifyStrTab(const Elf_Shdr *sh) const; 509f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 510f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 511f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private? 512f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky void validateSymbol(DataRefImpl Symb) const; 513f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 5145c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerpublic: 5155c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer const Elf_Dyn *getDyn(DataRefImpl DynData) const; 5162d70e263c2b508bf4641273dd89a23149f6f6164David Meyer error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, 5172d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool &IsDefault) const; 518f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyprotected: 519f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 520f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 521f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 522f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 523f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 524f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; 525c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 526f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; 527f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSymbolSection(DataRefImpl Symb, 528f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky section_iterator &Res) const; 529f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 5305c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer friend class DynRefImpl<target_endianness, is64Bits>; 5315c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const; 5325c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 5335c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; 5345c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; 5355c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 536f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 537f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 538f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 539f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 540f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 541f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 542f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 543f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 544f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 545f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 546f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const; 547f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; 548f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; 549f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 550f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationNext(DataRefImpl Rel, 551f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocationRef &Res) const; 552f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationAddress(DataRefImpl Rel, 553f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 554f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationOffset(DataRefImpl Rel, 555f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 556f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationSymbol(DataRefImpl Rel, 557f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Res) const; 558f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationType(DataRefImpl Rel, 559f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Res) const; 560f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationTypeName(DataRefImpl Rel, 561f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const; 562f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, 563f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t &Res) const; 564f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual error_code getRelocationValueString(DataRefImpl Rel, 565f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const; 566f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 567f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskypublic: 568f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELFObjectFile(MemoryBuffer *Object, error_code &ec); 569f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual symbol_iterator begin_symbols() const; 570f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual symbol_iterator end_symbols() const; 5715c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 572dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer virtual symbol_iterator begin_dynamic_symbols() const; 573dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer virtual symbol_iterator end_dynamic_symbols() const; 5745c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 575f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual section_iterator begin_sections() const; 576f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual section_iterator end_sections() const; 577f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 5785c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual library_iterator begin_libraries_needed() const; 5795c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual library_iterator end_libraries_needed() const; 5805c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 5815c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual dyn_iterator begin_dynamic_table() const; 5825c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer virtual dyn_iterator end_dynamic_table() const; 5835c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 584f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual uint8_t getBytesInAddress() const; 585f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual StringRef getFileFormatName() const; 5862d70e263c2b508bf4641273dd89a23149f6f6164David Meyer virtual StringRef getObjectType() const { return "ELF"; } 587f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky virtual unsigned getArch() const; 58897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer virtual StringRef getLoadName() const; 589f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 590f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getNumSections() const; 591f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t getStringTableIndex() const; 592f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; 593f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *getSection(const Elf_Sym *symb) const; 594f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 595f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Methods for type inquiry through isa, cast, and dyn_cast 596f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool isDyldType() const { return isDyldELFObject; } 597f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky static inline bool classof(const Binary *v) { 5986f9489a86f33624f9ff5388411d12359ce9cef20David Meyer return v->getType() == getELFType(target_endianness == support::little, 5996f9489a86f33624f9ff5388411d12359ce9cef20David Meyer is64Bits); 600f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 601f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky static inline bool classof(const ELFObjectFile *v) { return true; } 602f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky}; 603f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 6042d70e263c2b508bf4641273dd89a23149f6f6164David Meyer// Iterate through the version definitions, and place each Elf_Verdef 6052d70e263c2b508bf4641273dd89a23149f6f6164David Meyer// in the VersionMap according to its index. 6062d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 6072d70e263c2b508bf4641273dd89a23149f6f6164David Meyervoid ELFObjectFile<target_endianness, is64Bits>:: 6082d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LoadVersionDefs(const Elf_Shdr *sec) const { 6092d70e263c2b508bf4641273dd89a23149f6f6164David Meyer unsigned vd_size = sec->sh_size; // Size of section in bytes 6102d70e263c2b508bf4641273dd89a23149f6f6164David Meyer unsigned vd_count = sec->sh_info; // Number of Verdef entries 6112d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *sec_start = (const char*)base() + sec->sh_offset; 6122d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *sec_end = sec_start + vd_size; 6132d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // The first Verdef entry is at the start of the section. 6142d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *p = sec_start; 6152d70e263c2b508bf4641273dd89a23149f6f6164David Meyer for (unsigned i = 0; i < vd_count; i++) { 6162d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (p + sizeof(Elf_Verdef) > sec_end) 6172d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Section ended unexpectedly while scanning " 6182d70e263c2b508bf4641273dd89a23149f6f6164David Meyer "version definitions."); 6192d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p); 6202d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (vd->vd_version != ELF::VER_DEF_CURRENT) 6212d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Unexpected verdef version"); 6222d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; 6232d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (index >= VersionMap.size()) 6242d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap.resize(index+1); 6252d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap[index] = VersionMapEntry(vd); 6262d70e263c2b508bf4641273dd89a23149f6f6164David Meyer p += vd->vd_next; 6272d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 6282d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 6292d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6302d70e263c2b508bf4641273dd89a23149f6f6164David Meyer// Iterate through the versions needed section, and place each Elf_Vernaux 6312d70e263c2b508bf4641273dd89a23149f6f6164David Meyer// in the VersionMap according to its index. 6322d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 6332d70e263c2b508bf4641273dd89a23149f6f6164David Meyervoid ELFObjectFile<target_endianness, is64Bits>:: 6342d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LoadVersionNeeds(const Elf_Shdr *sec) const { 6352d70e263c2b508bf4641273dd89a23149f6f6164David Meyer unsigned vn_size = sec->sh_size; // Size of section in bytes 6362d70e263c2b508bf4641273dd89a23149f6f6164David Meyer unsigned vn_count = sec->sh_info; // Number of Verneed entries 6372d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *sec_start = (const char*)base() + sec->sh_offset; 6382d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *sec_end = sec_start + vn_size; 6392d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // The first Verneed entry is at the start of the section. 6402d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *p = sec_start; 6412d70e263c2b508bf4641273dd89a23149f6f6164David Meyer for (unsigned i = 0; i < vn_count; i++) { 6422d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (p + sizeof(Elf_Verneed) > sec_end) 6432d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Section ended unexpectedly while scanning " 6442d70e263c2b508bf4641273dd89a23149f6f6164David Meyer "version needed records."); 6452d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p); 6462d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (vn->vn_version != ELF::VER_NEED_CURRENT) 6472d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Unexpected verneed version"); 6482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Iterate through the Vernaux entries 6492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *paux = p + vn->vn_aux; 6502d70e263c2b508bf4641273dd89a23149f6f6164David Meyer for (unsigned j = 0; j < vn->vn_cnt; j++) { 6512d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (paux + sizeof(Elf_Vernaux) > sec_end) 6522d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Section ended unexpected while scanning auxiliary " 6532d70e263c2b508bf4641273dd89a23149f6f6164David Meyer "version needed records."); 6542d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux); 6552d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t index = vna->vna_other & ELF::VERSYM_VERSION; 6562d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (index >= VersionMap.size()) 6572d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap.resize(index+1); 6582d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap[index] = VersionMapEntry(vna); 6592d70e263c2b508bf4641273dd89a23149f6f6164David Meyer paux += vna->vna_next; 6602d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 6612d70e263c2b508bf4641273dd89a23149f6f6164David Meyer p += vn->vn_next; 6622d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 6632d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 6642d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6652d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 6662d70e263c2b508bf4641273dd89a23149f6f6164David Meyervoid ELFObjectFile<target_endianness, is64Bits>::LoadVersionMap() const { 6672d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // If there is no dynamic symtab or version table, there is nothing to do. 6682d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL) 6692d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return; 6702d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6712d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Has the VersionMap already been loaded? 6722d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (VersionMap.size() > 0) 6732d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return; 6742d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6752d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // The first two version indexes are reserved. 6762d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Index 0 is LOCAL, index 1 is GLOBAL. 6772d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap.push_back(VersionMapEntry()); 6782d70e263c2b508bf4641273dd89a23149f6f6164David Meyer VersionMap.push_back(VersionMapEntry()); 6792d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6802d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_d_sec) 6812d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LoadVersionDefs(dot_gnu_version_d_sec); 6822d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 6832d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_r_sec) 6842d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LoadVersionNeeds(dot_gnu_version_r_sec); 6852d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 6862d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 687f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 688f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyvoid ELFObjectFile<target_endianness, is64Bits> 689f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::validateSymbol(DataRefImpl Symb) const { 690f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 691f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 692f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: We really need to do proper error handling in the case of an invalid 693f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // input file. Because we don't use exceptions, I think we'll just pass 694f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // an error object around. 695f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!( symb 696f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && SymbolTableSection 697f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && symb >= (const Elf_Sym*)(base() 698f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_offset) 699f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && symb < (const Elf_Sym*)(base() 700f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_offset 701f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + SymbolTableSection->sh_size))) 702f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 703f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Symb must point to a valid symbol!"); 704f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 705f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 706f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 707f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 708f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolNext(DataRefImpl Symb, 709f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Result) const { 710f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 711f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b]; 712f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 713f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++Symb.d.a; 714f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Check to see if we are at the end of this symbol table. 715f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Symb.d.a >= SymbolTableSection->getEntityCount()) { 716f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // We are at the end. If there are other symbol tables, jump to them. 717dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // If the symbol table is .dynsym, we are iterating dynamic symbols, 718dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // and there is only one table of these. 719dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (Symb.d.b != 0) { 720dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ++Symb.d.b; 721dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Symb.d.a = 1; // The 0th symbol in ELF is fake. 722dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 723f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Otherwise return the terminator. 724dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) { 725f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Symb.d.a = std::numeric_limits<uint32_t>::max(); 726f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Symb.d.b = std::numeric_limits<uint32_t>::max(); 727f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 728f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 729f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 730f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef(Symb, this); 731f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 732f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 733f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 734f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 735f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 736f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolName(DataRefImpl Symb, 737f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 738f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 739f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 740dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result); 741f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 742f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 743f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 7442d70e263c2b508bf4641273dd89a23149f6f6164David Meyererror_code ELFObjectFile<target_endianness, is64Bits> 7452d70e263c2b508bf4641273dd89a23149f6f6164David Meyer ::getSymbolVersion(SymbolRef SymRef, 7462d70e263c2b508bf4641273dd89a23149f6f6164David Meyer StringRef &Version, 7472d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool &IsDefault) const { 7482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer DataRefImpl Symb = SymRef.getRawDataRefImpl(); 7492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer validateSymbol(Symb); 7502d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Sym *symb = getSymbol(Symb); 7512d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return getSymbolVersion(SymbolTableSections[Symb.d.b], symb, 7522d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version, IsDefault); 7532d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 7542d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 7552d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 756f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELF::Elf64_Word ELFObjectFile<target_endianness, is64Bits> 757f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolTableIndex(const Elf_Sym *symb) const { 758f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx == ELF::SHN_XINDEX) 759f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ExtendedSymbolTable.lookup(symb); 760f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symb->st_shndx; 761f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 762f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 763f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 764f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 765f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits> 766f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSection(const Elf_Sym *symb) const { 767f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx == ELF::SHN_XINDEX) 768f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(ExtendedSymbolTable.lookup(symb)); 769f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_shndx >= ELF::SHN_LORESERVE) 770f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 771f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getSection(symb->st_shndx); 772f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 773f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 774f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 775f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 776f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolFileOffset(DataRefImpl Symb, 777f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 778f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 779f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 780f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section; 781f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 782f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: 783f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Unintialized symbols have no offset in the object file 784f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 785f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 786f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 787f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: 788f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value; 789f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 790f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: Section = getSection(symb); 791f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 792f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 793f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 794f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 795f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = Section ? Section->sh_addr : UnknownAddressOrSize; 796f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 797f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 798f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 799f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_NOTYPE: 800f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value + 801f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky (Section ? Section->sh_offset : 0); 802f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 803f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 804f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 805f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 806f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 807f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 808f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 809f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 810f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 811f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolAddress(DataRefImpl Symb, 812f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 813f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 814f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 815f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section; 816f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 817f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: 818f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 819f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 820f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 821f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: 822f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value; 823f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 824f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: Section = getSection(symb); 825f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 826f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 827f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 828f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 829f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = Section ? Section->sh_addr : UnknownAddressOrSize; 830f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 831f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 832f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 833f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_NOTYPE: 834f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_value + (Section ? Section->sh_addr : 0); 835f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 836f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 837f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 838f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 839f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 840f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 841f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 842f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 843f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 844f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolSize(DataRefImpl Symb, 845f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 846f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 847f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 848f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_size == 0) 849f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = UnknownAddressOrSize; 850f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = symb->st_size; 851f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 852f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 853f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 854f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 855f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 856f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolNMTypeChar(DataRefImpl Symb, 857f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky char &Result) const { 858f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 859f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 860f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *Section = getSection(symb); 861f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 862f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky char ret = '?'; 863f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 864f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Section) { 865f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Section->sh_type) { 866f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_PROGBITS: 867f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_DYNAMIC: 868f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Section->sh_flags) { 869f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 870f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 't'; break; 871f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 872f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'd'; break; 873f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHF_ALLOC: 874f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 875f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 876f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'r'; break; 877f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 878f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 879f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_NOBITS: ret = 'b'; 880f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 881f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 882f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 883f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (getSymbolTableIndex(symb)) { 884f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_UNDEF: 885f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ret == '?') 886f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'U'; 887f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 888f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_ABS: ret = 'a'; break; 889f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHN_COMMON: ret = 'c'; break; 890f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 891f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 892f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getBinding()) { 893f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STB_GLOBAL: ret = ::toupper(ret); break; 894f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STB_WEAK: 895f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 896f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'w'; 897f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 898f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->getType() == ELF::STT_OBJECT) 899f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'V'; 900f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 901f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret = 'W'; 902f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 903f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 904f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ret == '?' && symb->getType() == ELF::STT_SECTION) { 905f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef name; 906f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (error_code ec = getSymbolName(Symb, name)) 907f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ec; 908f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringSwitch<char>(name) 909f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .StartsWith(".debug", 'N') 910f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .StartsWith(".note", 'n') 911f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky .Default('?'); 912f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 913f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 914f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 915f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = ret; 916f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 917f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 918f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 919f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 920f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 921f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolType(DataRefImpl Symb, 922f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef::Type &Result) const { 923f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 924f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 925f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 926f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (symb->getType()) { 9272c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_NOTYPE: 9282c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result = SymbolRef::ST_Unknown; 9292c67727046234ad9702ab5acb72700b5ac99a676David Meyer break; 930f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_SECTION: 931f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Debug; 932f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 933f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FILE: 934f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_File; 935f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 936f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_FUNC: 937f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Function; 938f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 939f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::STT_OBJECT: 9402c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_COMMON: 9412c67727046234ad9702ab5acb72700b5ac99a676David Meyer case ELF::STT_TLS: 942f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Data; 943f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 944f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 945f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef::ST_Other; 946f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 947f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 948f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 949f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 950f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 951f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 952f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 953c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer ::getSymbolFlags(DataRefImpl Symb, 954c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer uint32_t &Result) const { 955f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 956f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 957f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 958c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result = SymbolRef::SF_None; 959f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 960c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getBinding() != ELF::STB_LOCAL) 961c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Global; 962f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 963c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getBinding() == ELF::STB_WEAK) 964c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Weak; 965c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 966c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->st_shndx == ELF::SHN_ABS) 967c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_Absolute; 968c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer 969c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer if (symb->getType() == ELF::STT_FILE || 970c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer symb->getType() == ELF::STT_SECTION) 971c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer Result |= SymbolRef::SF_FormatSpecific; 972f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 9732c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) 9742c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_Undefined; 9752c67727046234ad9702ab5acb72700b5ac99a676David Meyer 9762c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (symb->getType() == ELF::STT_COMMON || 9772c67727046234ad9702ab5acb72700b5ac99a676David Meyer getSymbolTableIndex(symb) == ELF::SHN_COMMON) 9782c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_Common; 9792c67727046234ad9702ab5acb72700b5ac99a676David Meyer 9802c67727046234ad9702ab5acb72700b5ac99a676David Meyer if (symb->getType() == ELF::STT_TLS) 9812c67727046234ad9702ab5acb72700b5ac99a676David Meyer Result |= SymbolRef::SF_ThreadLocal; 9822c67727046234ad9702ab5acb72700b5ac99a676David Meyer 983f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 984f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 985f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 986f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 987f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 988f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSymbolSection(DataRefImpl Symb, 989f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky section_iterator &Res) const { 990f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky validateSymbol(Symb); 991f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getSymbol(Symb); 992f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(symb); 993f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!sec) 994f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Res = end_sections(); 995f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else { 996f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl Sec; 997f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sec.p = reinterpret_cast<intptr_t>(sec); 998f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Res = section_iterator(SectionRef(Sec, this)); 999f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1000f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1001f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1002f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1003f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1004f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1005f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const { 1006f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p); 1007f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky sec += Header->e_shentsize; 1008f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Sec.p = reinterpret_cast<intptr_t>(sec); 1009f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SectionRef(Sec, this); 1010f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1011f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1012f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1013f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1014f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1015f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionName(DataRefImpl Sec, 1016f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 1017f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1018f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name)); 1019f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1020f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1021f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1022f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1023f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1024f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionAddress(DataRefImpl Sec, 1025f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1026f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1027f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_addr; 1028f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1029f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1030f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1031f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1032f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1033f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionSize(DataRefImpl Sec, 1034f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1035f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1036f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_size; 1037f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1038f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1039f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1040f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1041f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1042f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionContents(DataRefImpl Sec, 1043f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 1044f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1045f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const char *start = (const char*)base() + sec->sh_offset; 1046f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = StringRef(start, sec->sh_size); 1047f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1048f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1049f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1050f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1051f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1052f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionAlignment(DataRefImpl Sec, 1053f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1054f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1055f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = sec->sh_addralign; 1056f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1057f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1058f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1059f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1060f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1061f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionText(DataRefImpl Sec, 1062f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 1063f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1064f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & ELF::SHF_EXECINSTR) 1065f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 1066f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 1067f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 1068f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1069f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1070f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1071f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1072f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1073f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionData(DataRefImpl Sec, 1074f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 1075f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1076f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 1077f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && sec->sh_type == ELF::SHT_PROGBITS) 1078f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 1079f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 1080f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 1081f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1082f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1083f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1084f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1085f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1086f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::isSectionBSS(DataRefImpl Sec, 1087f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 1088f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1089f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) 1090f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky && sec->sh_type == ELF::SHT_NOBITS) 1091f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = true; 1092f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 1093f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 1094f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1095f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1096f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1097f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1098f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1099f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::sectionContainsSymbol(DataRefImpl Sec, 1100f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl Symb, 1101f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky bool &Result) const { 1102f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Unimplemented. 1103f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = false; 1104f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1105f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1106f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1107f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1108f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyrelocation_iterator ELFObjectFile<target_endianness, is64Bits> 1109f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionRelBegin(DataRefImpl Sec) const { 1110f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl RelData; 1111f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&RelData, 0, sizeof(RelData)); 1112f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1113f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 1114f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec != 0 && ittr != SectionRelocMap.end()) { 1115f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.a = getSection(ittr->second[0])->sh_info; 1116f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.b = ittr->second[0]; 1117f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.c = 0; 1118f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1119f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return relocation_iterator(RelocationRef(RelData, this)); 1120f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1121f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1122f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1123f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyrelocation_iterator ELFObjectFile<target_endianness, is64Bits> 1124f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getSectionRelEnd(DataRefImpl Sec) const { 1125f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl RelData; 1126f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&RelData, 0, sizeof(RelData)); 1127f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); 1128f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); 1129f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec != 0 && ittr != SectionRelocMap.end()) { 1130f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Get the index of the last relocation section for this section. 1131f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; 1132f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *relocsec = getSection(relocsecindex); 1133f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.a = relocsec->sh_info; 1134f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.b = relocsecindex; 1135f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; 1136f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1137f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return relocation_iterator(RelocationRef(RelData, this)); 1138f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1139f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1140f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Relocations 1141f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1142f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1143f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationNext(DataRefImpl Rel, 1144f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky RelocationRef &Result) const { 1145f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++Rel.w.c; 1146f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *relocsec = getSection(Rel.w.b); 1147f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { 1148f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // We have reached the end of the relocations for this section. See if there 1149f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // is another relocation section. 1150f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::mapped_type relocseclist = 1151f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionRelocMap.lookup(getSection(Rel.w.a)); 1152f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1153f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Do a binary search for the current reloc section index (which must be 1154f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // present). Then get the next one. 1155f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky typename RelocMap_t::mapped_type::const_iterator loc = 1156f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b); 1157f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++loc; 1158f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1159f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel 1160f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // to the end iterator. 1161f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (loc != relocseclist.end()) { 1162f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Rel.w.b = *loc; 1163f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Rel.w.a = 0; 1164f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1165f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1166f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = RelocationRef(Rel, this); 1167f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1168f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1169f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1170f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1171f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1172f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationSymbol(DataRefImpl Rel, 1173f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolRef &Result) const { 1174f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t symbolIdx; 1175f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1176f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1177f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1178f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1179f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1180f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbolIdx = getRel(Rel)->getSymbol(); 1181f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1182f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1183f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1184f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbolIdx = getRela(Rel)->getSymbol(); 1185f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1186f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1187f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1188f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 1189f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link); 1190f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (it == SymbolTableSectionsIndexMap.end()) 1191f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Relocation symbol table not found!"); 1192f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = symbolIdx; 1193f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = it->second; 1194f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = SymbolRef(SymbolData, this); 1195f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1196f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1197f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1198f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1199f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1200f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationAddress(DataRefImpl Rel, 1201f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1202f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t offset; 1203f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1204f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1205f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1206f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1207f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1208f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRel(Rel)->r_offset; 1209f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1210f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1211f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1212f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRela(Rel)->r_offset; 1213f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1214f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1215f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1216f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1217f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = offset; 1218f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1219f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1220f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1221f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1222f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1223f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationOffset(DataRefImpl Rel, 1224f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1225f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t offset; 1226f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1227f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1228f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1229f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1230f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1231f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRel(Rel)->r_offset; 1232f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1233f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1234f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1235f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky offset = getRela(Rel)->r_offset; 1236f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1237f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1238f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1239f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1240f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = offset - sec->sh_addr; 1241f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1242f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1243f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1244f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1245f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1246f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationType(DataRefImpl Rel, 1247f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint64_t &Result) const { 1248f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1249f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1250f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1251f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1252f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1253f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRel(Rel)->getType(); 1254f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1255f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1256f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1257f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRela(Rel)->getType(); 1258f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1259f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1260f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1261f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1262f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1263f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1264f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ 1265f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::enum: res = #enum; break; 1266f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1267f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1268f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1269f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationTypeName(DataRefImpl Rel, 1270f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const { 1271f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1272f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint8_t type; 1273f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef res; 1274f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1275f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1276f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::parse_failed; 1277f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1278f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRel(Rel)->getType(); 1279f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1280f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1281f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1282f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRela(Rel)->getType(); 1283f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1284f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1285f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1286f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Header->e_machine) { 1287f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1288f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 1289f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); 1290f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); 1291f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); 1292f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); 1293f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); 1294f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); 1295f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); 1296f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); 1297f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); 1298f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); 1299f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32); 1300f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S); 1301f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16); 1302f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16); 1303f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8); 1304f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8); 1305f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64); 1306f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); 1307f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); 1308f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); 1309f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); 1310f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); 1311f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); 1312f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); 1313f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); 1314f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); 1315f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); 1316f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); 1317f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); 1318f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); 1319f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); 1320f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); 1321f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1322f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1323f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1324f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1325f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1326f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 1327f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); 1328f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); 1329f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); 1330f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); 1331f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); 1332f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); 1333f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); 1334f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); 1335f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); 1336f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); 1337f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC); 1338f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT); 1339f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF); 1340f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE); 1341f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE); 1342f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE); 1343f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD); 1344f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM); 1345f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16); 1346f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16); 1347f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8); 1348f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8); 1349f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32); 1350f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH); 1351f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL); 1352f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP); 1353f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32); 1354f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH); 1355f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL); 1356f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP); 1357f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); 1358f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); 1359f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); 1360f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); 1361f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); 1362f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); 1363f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); 1364f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); 1365f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); 1366f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); 1367f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1368f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1369f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1370f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1371f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1372f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1373f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1374f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(res.begin(), res.end()); 1375f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1376f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1377f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1378f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME 1379f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1380f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1381f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1382f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationAdditionalInfo(DataRefImpl Rel, 1383f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t &Result) const { 1384f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1385f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1386f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1387f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section type in Rel!"); 1388f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1389f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = 0; 1390f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1391f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1392f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1393f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getRela(Rel)->r_addend; 1394f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1395f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1396f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1397f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1398f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1399f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1400f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1401f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getRelocationValueString(DataRefImpl Rel, 1402f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SmallVectorImpl<char> &Result) const { 1403f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Rel.w.b); 1404f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint8_t type; 1405f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef res; 1406f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky int64_t addend = 0; 1407f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint16_t symbol_index = 0; 1408f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (sec->sh_type) { 1409f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default : 1410f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::parse_failed; 1411f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_REL : { 1412f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRel(Rel)->getType(); 1413f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbol_index = getRel(Rel)->getSymbol(); 1414f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // TODO: Read implicit addend from section data. 1415f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1416f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1417f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::SHT_RELA : { 1418f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky type = getRela(Rel)->getType(); 1419f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky symbol_index = getRela(Rel)->getSymbol(); 1420f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky addend = getRela(Rel)->r_addend; 1421f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1422f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1423f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1424f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index); 1425f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef symname; 1426dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname)) 1427f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return ec; 1428f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (Header->e_machine) { 1429f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1430f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch (type) { 1431f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::R_X86_64_32S: 1432f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = symname; 1433f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1434f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::R_X86_64_PC32: { 1435f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::string fmtbuf; 1436f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky raw_string_ostream fmt(fmtbuf); 1437f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky fmt << symname << (addend < 0 ? "" : "+") << addend << "-P"; 1438f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky fmt.flush(); 1439f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(fmtbuf.begin(), fmtbuf.end()); 1440f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1441f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1442f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1443f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1444f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1445f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky break; 1446f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1447f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky res = "Unknown"; 1448f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1449f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Result.empty()) 1450f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result.append(res.begin(), res.end()); 1451f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 1452f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1453f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1454dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer// Verify that the last byte in the string table in a null. 1455dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1456dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencervoid ELFObjectFile<target_endianness, is64Bits> 1457dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::VerifyStrTab(const Elf_Shdr *sh) const { 1458dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const char *strtab = (const char*)base() + sh->sh_offset; 1459dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (strtab[sh->sh_size - 1] != 0) 1460dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1461dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("String table must end with a null terminator!"); 1462dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1463dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1464f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1465f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object 1466f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , error_code &ec) 14676f9489a86f33624f9ff5388411d12359ce9cef20David Meyer : ObjectFile(getELFType(target_endianness == support::little, is64Bits), 14686f9489a86f33624f9ff5388411d12359ce9cef20David Meyer Object, ec) 1469f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , isDyldELFObject(false) 1470f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , SectionHeaderTable(0) 1471f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky , dot_shstrtab_sec(0) 1472dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer , dot_strtab_sec(0) 14735c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer , dot_dynstr_sec(0) 147497f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer , dot_dynamic_sec(0) 14752d70e263c2b508bf4641273dd89a23149f6f6164David Meyer , dot_gnu_version_sec(0) 14762d70e263c2b508bf4641273dd89a23149f6f6164David Meyer , dot_gnu_version_r_sec(0) 14772d70e263c2b508bf4641273dd89a23149f6f6164David Meyer , dot_gnu_version_d_sec(0) 14782d70e263c2b508bf4641273dd89a23149f6f6164David Meyer , dt_soname(0) 14792d70e263c2b508bf4641273dd89a23149f6f6164David Meyer { 1480f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1481f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t FileSize = Data->getBufferSize(); 1482f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1483f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sizeof(Elf_Ehdr) > FileSize) 1484f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1485f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("File too short!"); 1486f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1487f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Header = reinterpret_cast<const Elf_Ehdr *>(base()); 1488f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1489f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shoff == 0) 1490f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return; 1491f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1492f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t SectionTableOffset = Header->e_shoff; 1493f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1494f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) 1495f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1496f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Section header table goes past end of file!"); 1497f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1498f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // The getNumSections() call below depends on SectionHeaderTable being set. 1499f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionHeaderTable = 1500f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); 1501f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; 1502f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1503f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionTableOffset + SectionTableSize > FileSize) 1504f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1505f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Section table goes past end of file!"); 1506f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1507f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // To find the symbol tables we walk the section table to find SHT_SYMTAB. 1508f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr* SymbolTableSectionHeaderIndex = 0; 1509f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr* sh = SectionHeaderTable; 1510dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1511dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Reserve SymbolTableSections[0] for .dynsym 1512dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSections.push_back(NULL); 1513dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1514f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (uint64_t i = 0, e = getNumSections(); i != e; ++i) { 15152d70e263c2b508bf4641273dd89a23149f6f6164David Meyer switch (sh->sh_type) { 15162d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_SYMTAB_SHNDX: { 1517f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SymbolTableSectionHeaderIndex) 1518f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1519f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("More than one .symtab_shndx!"); 1520f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionHeaderIndex = sh; 15212d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 1522f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 15232d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_SYMTAB: { 1524f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionsIndexMap[i] = SymbolTableSections.size(); 1525f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSections.push_back(sh); 15262d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 1527f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 15282d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_DYNSYM: { 1529dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections[0] != NULL) 1530dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1531dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("More than one .dynsym!"); 1532dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSectionsIndexMap[i] = 0; 1533dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolTableSections[0] = sh; 15342d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 1535dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 15362d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_REL: 15372d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_RELA: { 1538f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SectionRelocMap[getSection(sh->sh_info)].push_back(i); 15392d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 1540f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 15412d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_DYNAMIC: { 15425c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (dot_dynamic_sec != NULL) 15435c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // FIXME: Proper error handling. 15445c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("More than one .dynamic!"); 15455c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dot_dynamic_sec = sh; 15462d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 15472d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 15482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_GNU_versym: { 15492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_sec != NULL) 15502d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // FIXME: Proper error handling. 15512d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("More than one .gnu.version section!"); 15522d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dot_gnu_version_sec = sh; 15532d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 15542d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 15552d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_GNU_verdef: { 15562d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_d_sec != NULL) 15572d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // FIXME: Proper error handling. 15582d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("More than one .gnu.version_d section!"); 15592d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dot_gnu_version_d_sec = sh; 15602d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 15612d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 15622d70e263c2b508bf4641273dd89a23149f6f6164David Meyer case ELF::SHT_GNU_verneed: { 15632d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_r_sec != NULL) 15642d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // FIXME: Proper error handling. 15652d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("More than one .gnu.version_r section!"); 15662d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dot_gnu_version_r_sec = sh; 15672d70e263c2b508bf4641273dd89a23149f6f6164David Meyer break; 15682d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 15695c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 1570f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++sh; 1571f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1572f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1573f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Sort section relocation lists by index. 1574f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (typename RelocMap_t::iterator i = SectionRelocMap.begin(), 1575f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky e = SectionRelocMap.end(); i != e; ++i) { 1576f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky std::sort(i->second.begin(), i->second.end()); 1577f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1578f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1579f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Get string table sections. 1580f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky dot_shstrtab_sec = getSection(getStringTableIndex()); 1581f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (dot_shstrtab_sec) { 1582f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Verify that the last byte in the string table in a null. 1583dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_shstrtab_sec); 1584f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1585f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1586f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Merge this into the above loop. 1587f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable), 1588f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky *e = i + getNumSections() * Header->e_shentsize; 1589f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky i != e; i += Header->e_shentsize) { 1590f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i); 1591f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sh->sh_type == ELF::SHT_STRTAB) { 1592f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name)); 1593f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SectionName == ".strtab") { 1594f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (dot_strtab_sec != 0) 1595f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1596f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Already found section named .strtab!"); 1597f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky dot_strtab_sec = sh; 1598dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_strtab_sec); 1599dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else if (SectionName == ".dynstr") { 1600dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (dot_dynstr_sec != 0) 1601dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // FIXME: Proper error handling. 1602dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer report_fatal_error("Already found section named .dynstr!"); 1603dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer dot_dynstr_sec = sh; 1604dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer VerifyStrTab(dot_dynstr_sec); 1605f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1606f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1607f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1608f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1609f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // Build symbol name side-mapping if there is one. 1610f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (SymbolTableSectionHeaderIndex) { 1611f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() + 1612f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolTableSectionHeaderIndex->sh_offset); 1613f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky error_code ec; 1614f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky for (symbol_iterator si = begin_symbols(), 1615f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky se = end_symbols(); si != se; si.increment(ec)) { 1616f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (ec) 1617f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Fewer extended symbol table entries than symbols!"); 1618f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (*ShndxTable != ELF::SHN_UNDEF) 1619f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable; 1620f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ++ShndxTable; 1621f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1622f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1623f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1624f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1625f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1626f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1627f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::begin_symbols() const { 1628f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 1629f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&SymbolData, 0, sizeof(SymbolData)); 1630dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections.size() <= 1) { 1631f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1632f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1633f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } else { 1634f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 1635dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = 1; // The 0th table is .dynsym 1636f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1637f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symbol_iterator(SymbolRef(SymbolData, this)); 1638f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1639f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1640f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1641f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1642f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::end_symbols() const { 1643f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl SymbolData; 1644f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&SymbolData, 0, sizeof(SymbolData)); 1645f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1646f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1647f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return symbol_iterator(SymbolRef(SymbolData, this)); 1648f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1649f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1650f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1651dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1652dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::begin_dynamic_symbols() const { 1653dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer DataRefImpl SymbolData; 1654dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer memset(&SymbolData, 0, sizeof(SymbolData)); 1655dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (SymbolTableSections[0] == NULL) { 1656dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1657dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1658dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else { 1659dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = 1; // The 0th symbol in ELF is fake. 1660dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = 0; // The 0th table is .dynsym 1661dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 1662dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return symbol_iterator(SymbolRef(SymbolData, this)); 1663dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1664dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1665dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1666dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencersymbol_iterator ELFObjectFile<target_endianness, is64Bits> 1667dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::end_dynamic_symbols() const { 1668dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer DataRefImpl SymbolData; 1669dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer memset(&SymbolData, 0, sizeof(SymbolData)); 1670dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.a = std::numeric_limits<uint32_t>::max(); 1671dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer SymbolData.d.b = std::numeric_limits<uint32_t>::max(); 1672dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer return symbol_iterator(SymbolRef(SymbolData, this)); 1673dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer} 1674dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer 1675dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencertemplate<support::endianness target_endianness, bool is64Bits> 1676f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysection_iterator ELFObjectFile<target_endianness, is64Bits> 1677f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::begin_sections() const { 1678f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl ret; 1679f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&ret, 0, sizeof(DataRefImpl)); 1680f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff); 1681f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return section_iterator(SectionRef(ret, this)); 1682f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1683f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1684f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1685f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskysection_iterator ELFObjectFile<target_endianness, is64Bits> 1686f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::end_sections() const { 1687f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky DataRefImpl ret; 1688f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky memset(&ret, 0, sizeof(DataRefImpl)); 1689f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ret.p = reinterpret_cast<intptr_t>(base() 1690f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + Header->e_shoff 1691f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (Header->e_shentsize*getNumSections())); 1692f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return section_iterator(SectionRef(ret, this)); 1693f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1694f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1695f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 16965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertypename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator 16975c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid MeyerELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const { 16985c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DataRefImpl DynData; 16995c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer memset(&DynData, 0, sizeof(DynData)); 17005c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) { 17015c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynData.d.a = std::numeric_limits<uint32_t>::max(); 17025c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } else { 17035c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynData.d.a = 0; 17045c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 17055c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return dyn_iterator(DynRef(DynData, this)); 17065c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 17075c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17085c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 17095c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertypename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator 17105c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid MeyerELFObjectFile<target_endianness, is64Bits> 17115c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::end_dynamic_table() const { 17125c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DataRefImpl DynData; 17135c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer memset(&DynData, 0, sizeof(DynData)); 17145c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynData.d.a = std::numeric_limits<uint32_t>::max(); 17155c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return dyn_iterator(DynRef(DynData, this)); 17165c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 17175c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17185c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 17195c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code ELFObjectFile<target_endianness, is64Bits> 17205c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getDynNext(DataRefImpl DynData, 17215c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynRef &Result) const { 17225c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ++DynData.d.a; 17235c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17245c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Check to see if we are at the end of .dynamic 17255c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) { 17265c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // We are at the end. Return the terminator. 17275c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer DynData.d.a = std::numeric_limits<uint32_t>::max(); 17285c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 17295c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17305c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Result = DynRef(DynData, this); 17315c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return object_error::success; 17325c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 17335c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17345c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 173597f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid MeyerStringRef 173697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid MeyerELFObjectFile<target_endianness, is64Bits>::getLoadName() const { 173797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer if (!dt_soname) { 173897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer // Find the DT_SONAME entry 173997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer dyn_iterator it = begin_dynamic_table(); 174097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer dyn_iterator ie = end_dynamic_table(); 174197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer error_code ec; 174297f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer while (it != ie) { 174397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer if (it->getTag() == ELF::DT_SONAME) 174497f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer break; 174597f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer it.increment(ec); 174697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer if (ec) 174797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer report_fatal_error("dynamic table iteration failed"); 174897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer } 174997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer if (it != ie) { 175097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer if (dot_dynstr_sec == NULL) 175197f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer report_fatal_error("Dynamic string table is missing"); 175297f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer dt_soname = getString(dot_dynstr_sec, it->getVal()); 175397f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer } else { 175497f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer dt_soname = ""; 175597f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer } 175697f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer } 175797f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer return dt_soname; 175897f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer} 175997f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyer 176097f7787bfb56ad31fe20ec0bb9c3c9f3253d14fbDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 17615c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator ELFObjectFile<target_endianness, is64Bits> 17625c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::begin_libraries_needed() const { 17635c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Find the first DT_NEEDED entry 17645c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator i = begin_dynamic_table(); 17655c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator e = end_dynamic_table(); 17665c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer error_code ec; 17675c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer while (i != e) { 17685c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (i->getTag() == ELF::DT_NEEDED) 17695c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer break; 17705c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer i.increment(ec); 17715c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (ec) 17725c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("dynamic table iteration failed"); 17735c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 17745c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Use the same DataRefImpl format as DynRef. 17755c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return library_iterator(LibraryRef(i->getRawDataRefImpl(), this)); 17765c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 17775c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17785c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 17795c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code ELFObjectFile<target_endianness, is64Bits> 17805c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getLibraryNext(DataRefImpl Data, 17815c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer LibraryRef &Result) const { 17825c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Use the same DataRefImpl format as DynRef. 17835c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator i = dyn_iterator(DynRef(Data, this)); 17845c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator e = end_dynamic_table(); 17855c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17865c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Skip the current dynamic table entry. 17875c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer error_code ec; 17885c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (i != e) { 17895c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer i.increment(ec); 17905c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: proper error handling 17915c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (ec) 17925c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("dynamic table iteration failed"); 17935c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 17945c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 17955c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Find the next DT_NEEDED entry. 17965c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer while (i != e) { 17975c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (i->getTag() == ELF::DT_NEEDED) 17985c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer break; 17995c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer i.increment(ec); 18005c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (ec) 18015c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("dynamic table iteration failed"); 18025c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer } 18035c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Result = LibraryRef(i->getRawDataRefImpl(), this); 18045c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return object_error::success; 18055c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 18065c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18075c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 18085c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyererror_code ELFObjectFile<target_endianness, is64Bits> 18095c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getLibraryPath(DataRefImpl Data, StringRef &Res) const { 18105c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator i = dyn_iterator(DynRef(Data, this)); 18115c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (i == end_dynamic_table()) 18125c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("getLibraryPath() called on iterator end"); 18135c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18145c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (i->getTag() != ELF::DT_NEEDED) 18155c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Invalid library_iterator"); 18165c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18175c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // This uses .dynstr to lookup the name of the DT_NEEDED entry. 18185c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // THis works as long as DT_STRTAB == .dynstr. This is true most of 18195c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // the time, but the specification allows exceptions. 18205c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // TODO: This should really use DT_STRTAB instead. Doing this requires 18215c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // reading the program headers. 18225c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer if (dot_dynstr_sec == NULL) 18235c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer report_fatal_error("Dynamic string table is missing"); 18245c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer Res = getString(dot_dynstr_sec, i->getVal()); 18255c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return object_error::success; 18265c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 18275c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18285c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 18295c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerlibrary_iterator ELFObjectFile<target_endianness, is64Bits> 18305c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::end_libraries_needed() const { 18315c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer dyn_iterator e = end_dynamic_table(); 18325c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer // Use the same DataRefImpl format as DynRef. 18335c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return library_iterator(LibraryRef(e->getRawDataRefImpl(), this)); 18345c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 18355c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 18365c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 1837f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const { 1838f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return is64Bits ? 8 : 4; 1839f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1840f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1841f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1842f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyStringRef ELFObjectFile<target_endianness, is64Bits> 1843f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getFileFormatName() const { 1844f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_ident[ELF::EI_CLASS]) { 1845f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::ELFCLASS32: 1846f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1847f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1848f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-i386"; 1849f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1850f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-x86-64"; 1851f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_ARM: 1852f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-arm"; 1853f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1854f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF32-unknown"; 1855f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1856f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::ELFCLASS64: 1857f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1858f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1859f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-i386"; 1860f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1861f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-x86-64"; 1862f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1863f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return "ELF64-unknown"; 1864f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1865f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1866f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1867f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid ELFCLASS!"); 1868f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1869f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1870f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1871f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1872f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyunsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const { 1873f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky switch(Header->e_machine) { 1874f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_386: 1875f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::x86; 1876f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_X86_64: 1877f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::x86_64; 1878f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky case ELF::EM_ARM: 1879f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::arm; 1880f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky default: 1881f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Triple::UnknownArch; 1882f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1883f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1884f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1885f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1886f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const { 1887f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(Header && "Header not initialized!"); 1888f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shnum == ELF::SHN_UNDEF) { 1889f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(SectionHeaderTable && "SectionHeaderTable not initialized!"); 1890f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return SectionHeaderTable->sh_size; 1891f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1892f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Header->e_shnum; 1893f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1894f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1895f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1896f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyuint64_t 1897f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const { 1898f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shnum == ELF::SHN_UNDEF) { 1899f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shstrndx == ELF::SHN_HIRESERVE) 1900f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return SectionHeaderTable->sh_link; 1901f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Header->e_shstrndx >= getNumSections()) 1902f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 1903f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 1904f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return Header->e_shstrndx; 1905f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1906f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1907f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1908f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1909f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<typename T> 1910f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyinline const T * 1911f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section, 1912f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t Entry) const { 1913f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<T>(getSection(Section), Entry); 1914f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1915f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1916f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1917f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<typename T> 1918f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyinline const T * 1919f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getEntry(const Elf_Shdr * Section, 1920f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky uint32_t Entry) const { 1921f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return reinterpret_cast<const T *>( 1922f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky base() 1923f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + Section->sh_offset 1924f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (Entry * Section->sh_entsize)); 1925f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1926f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1927f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1928f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym * 1929f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const { 1930f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a); 1931f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1932f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1933f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 19345c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Dyn * 19355c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid MeyerELFObjectFile<target_endianness, is64Bits>::getDyn(DataRefImpl DynData) const { 19365c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a); 19375c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 19385c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 19395c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 1940f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel * 1941f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const { 1942f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c); 1943f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1944f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1945f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1946f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rela * 1947f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getRela(DataRefImpl Rela) const { 1948f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c); 1949f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1950f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1951f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1952f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 1953f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSection(DataRefImpl Symb) const { 1954f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *sec = getSection(Symb.d.b); 1955f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) 1956f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1957f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid symbol table section!"); 1958f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return sec; 1959f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1960f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1961f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1962f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst typename ELFObjectFile<target_endianness, is64Bits>::Elf_Shdr * 1963f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyELFObjectFile<target_endianness, is64Bits>::getSection(uint32_t index) const { 1964f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (index == 0) 1965f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return 0; 1966f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!SectionHeaderTable || index >= getNumSections()) 1967f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1968f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Invalid section index!"); 1969f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1970f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return reinterpret_cast<const Elf_Shdr *>( 1971f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky reinterpret_cast<const char *>(SectionHeaderTable) 1972f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky + (index * Header->e_shentsize)); 1973f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1974f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1975f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1976f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst char *ELFObjectFile<target_endianness, is64Bits> 1977f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getString(uint32_t section, 1978f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf32_Word offset) const { 1979f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return getString(getSection(section), offset); 1980f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1981f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1982f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1983f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyconst char *ELFObjectFile<target_endianness, is64Bits> 1984f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ::getString(const Elf_Shdr *section, 1985f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky ELF::Elf32_Word offset) const { 1986f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); 1987f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (offset >= section->sh_size) 1988f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky // FIXME: Proper error handling. 1989f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky report_fatal_error("Symbol name offset outside of string table!"); 1990f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return (const char *)base() + section->sh_offset + offset; 1991f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 1992f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 1993f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskytemplate<support::endianness target_endianness, bool is64Bits> 1994f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyerror_code ELFObjectFile<target_endianness, is64Bits> 1995dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer ::getSymbolName(const Elf_Shdr *section, 1996dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer const Elf_Sym *symb, 1997f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky StringRef &Result) const { 1998f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (symb->st_name == 0) { 1999f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky const Elf_Shdr *section = getSection(symb); 2000f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (!section) 2001f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = ""; 2002f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else 2003f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky Result = getString(dot_shstrtab_sec, section->sh_name); 2004f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 2005f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky } 2006f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 2007dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (section == SymbolTableSections[0]) { 2008dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Symbol is in .dynsym, use .dynstr string table 2009dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Result = getString(dot_dynstr_sec, symb->st_name); 2010dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } else { 2011dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer // Use the default symbol table name section. 2012dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer Result = getString(dot_strtab_sec, symb->st_name); 2013dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 2014f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky return object_error::success; 2015f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 2016f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 20175c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 20182d70e263c2b508bf4641273dd89a23149f6f6164David Meyererror_code ELFObjectFile<target_endianness, is64Bits> 20192d70e263c2b508bf4641273dd89a23149f6f6164David Meyer ::getSymbolVersion(const Elf_Shdr *section, 20202d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Sym *symb, 20212d70e263c2b508bf4641273dd89a23149f6f6164David Meyer StringRef &Version, 20222d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool &IsDefault) const { 20232d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Handle non-dynamic symbols. 20242d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (section != SymbolTableSections[0]) { 20252d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Non-dynamic symbols can have versions in their names 20262d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // A name of the form 'foo@V1' indicates version 'V1', non-default. 20272d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // A name of the form 'foo@@V2' indicates version 'V2', default version. 20282d70e263c2b508bf4641273dd89a23149f6f6164David Meyer StringRef Name; 20292d70e263c2b508bf4641273dd89a23149f6f6164David Meyer error_code ec = getSymbolName(section, symb, Name); 20302d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (ec != object_error::success) 20312d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return ec; 20322d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t atpos = Name.find('@'); 20332d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (atpos == StringRef::npos) { 20342d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version = ""; 20352d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = false; 20362d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return object_error::success; 20372d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20382d70e263c2b508bf4641273dd89a23149f6f6164David Meyer ++atpos; 20392d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (atpos < Name.size() && Name[atpos] == '@') { 20402d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = true; 20412d70e263c2b508bf4641273dd89a23149f6f6164David Meyer ++atpos; 20422d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } else { 20432d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = false; 20442d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20452d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version = Name.substr(atpos); 20462d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return object_error::success; 20472d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // This is a dynamic symbol. Look in the GNU symbol version table. 20502d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (dot_gnu_version_sec == NULL) { 20512d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // No version table. 20522d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version = ""; 20532d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = false; 20542d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return object_error::success; 20552d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20562d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20572d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Determine the position in the symbol table of this entry. 20582d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const char *sec_start = (const char*)base() + section->sh_offset; 20592d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t entry_index = ((const char*)symb - sec_start)/section->sh_entsize; 20602d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20612d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Get the corresponding version index entry 20622d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); 20632d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; 20642d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20652d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Special markers for unversioned symbols. 20662d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (version_index == ELF::VER_NDX_LOCAL || 20672d70e263c2b508bf4641273dd89a23149f6f6164David Meyer version_index == ELF::VER_NDX_GLOBAL) { 20682d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version = ""; 20692d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = false; 20702d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return object_error::success; 20712d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20722d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20732d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Lookup this symbol in the version table 20742d70e263c2b508bf4641273dd89a23149f6f6164David Meyer LoadVersionMap(); 20752d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) 20762d70e263c2b508bf4641273dd89a23149f6f6164David Meyer report_fatal_error("Symbol has version index without corresponding " 20772d70e263c2b508bf4641273dd89a23149f6f6164David Meyer "define or reference entry"); 20782d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const VersionMapEntry &entry = VersionMap[version_index]; 20792d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20802d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Get the version name string 20812d70e263c2b508bf4641273dd89a23149f6f6164David Meyer size_t name_offset; 20822d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (entry.isVerdef()) { 20832d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // The first Verdaux entry holds the name. 20842d70e263c2b508bf4641273dd89a23149f6f6164David Meyer name_offset = entry.getVerdef()->getAux()->vda_name; 20852d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } else { 20862d70e263c2b508bf4641273dd89a23149f6f6164David Meyer name_offset = entry.getVernaux()->vna_name; 20872d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20882d70e263c2b508bf4641273dd89a23149f6f6164David Meyer Version = getString(dot_dynstr_sec, name_offset); 20892d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20902d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Set IsDefault 20912d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (entry.isVerdef()) { 20922d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); 20932d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } else { 20942d70e263c2b508bf4641273dd89a23149f6f6164David Meyer IsDefault = false; 20952d70e263c2b508bf4641273dd89a23149f6f6164David Meyer } 20962d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 20972d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return object_error::success; 20982d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 20992d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 21002d70e263c2b508bf4641273dd89a23149f6f6164David Meyertemplate<support::endianness target_endianness, bool is64Bits> 21015c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline DynRefImpl<target_endianness, is64Bits> 21025c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner) 21035c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer : DynPimpl(DynP) 21045c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer , OwningObject(Owner) {} 21055c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21065c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21075c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline bool DynRefImpl<target_endianness, is64Bits> 21085c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::operator==(const DynRefImpl &Other) const { 21095c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return DynPimpl == Other.DynPimpl; 21105c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21115c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21125c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21135c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline bool DynRefImpl<target_endianness, is64Bits> 21145c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::operator <(const DynRefImpl &Other) const { 21155c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return DynPimpl < Other.DynPimpl; 21165c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21175c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21185c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21195c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline error_code DynRefImpl<target_endianness, is64Bits> 21205c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getNext(DynRefImpl &Result) const { 21215c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return OwningObject->getDynNext(DynPimpl, Result); 21225c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21235c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21245c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21255c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline int64_t DynRefImpl<target_endianness, is64Bits> 21265c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getTag() const { 21275c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return OwningObject->getDyn(DynPimpl)->d_tag; 21285c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21295c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21305c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21315c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline uint64_t DynRefImpl<target_endianness, is64Bits> 21325c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getVal() const { 21335c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return OwningObject->getDyn(DynPimpl)->d_un.d_val; 21345c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21355c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21365c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21375c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline uint64_t DynRefImpl<target_endianness, is64Bits> 21385c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getPtr() const { 21395c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return OwningObject->getDyn(DynPimpl)->d_un.d_ptr; 21405c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21415c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21425c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyertemplate<support::endianness target_endianness, bool is64Bits> 21435c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyerinline DataRefImpl DynRefImpl<target_endianness, is64Bits> 21445c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer ::getRawDataRefImpl() const { 21455c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer return DynPimpl; 21465c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer} 21475c2b4ea73c8f48bb5f96c86fe437385b8fb3dcdaDavid Meyer 21482d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// This is a generic interface for retrieving GNU symbol version 21492d70e263c2b508bf4641273dd89a23149f6f6164David Meyer/// information from an ELFObjectFile. 21502d70e263c2b508bf4641273dd89a23149f6f6164David Meyerstatic inline error_code GetELFSymbolVersion(const ObjectFile *Obj, 21512d70e263c2b508bf4641273dd89a23149f6f6164David Meyer const SymbolRef &Sym, 21522d70e263c2b508bf4641273dd89a23149f6f6164David Meyer StringRef &Version, 21532d70e263c2b508bf4641273dd89a23149f6f6164David Meyer bool &IsDefault) { 21542d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Little-endian 32-bit 21552d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (const ELFObjectFile<support::little, false> *ELFObj = 21562d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dyn_cast<ELFObjectFile<support::little, false> >(Obj)) 21572d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 21582d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 21592d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Big-endian 32-bit 21602d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (const ELFObjectFile<support::big, false> *ELFObj = 21612d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dyn_cast<ELFObjectFile<support::big, false> >(Obj)) 21622d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 21632d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 21642d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Little-endian 64-bit 21652d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (const ELFObjectFile<support::little, true> *ELFObj = 21662d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dyn_cast<ELFObjectFile<support::little, true> >(Obj)) 21672d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 21682d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 21692d70e263c2b508bf4641273dd89a23149f6f6164David Meyer // Big-endian 64-bit 21702d70e263c2b508bf4641273dd89a23149f6f6164David Meyer if (const ELFObjectFile<support::big, true> *ELFObj = 21712d70e263c2b508bf4641273dd89a23149f6f6164David Meyer dyn_cast<ELFObjectFile<support::big, true> >(Obj)) 21722d70e263c2b508bf4641273dd89a23149f6f6164David Meyer return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 21732d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 21742d70e263c2b508bf4641273dd89a23149f6f6164David Meyer llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); 21752d70e263c2b508bf4641273dd89a23149f6f6164David Meyer} 21762d70e263c2b508bf4641273dd89a23149f6f6164David Meyer 2177f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 2178f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky} 2179f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky 2180f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#endif 2181