1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 3*7fd79137SRobert Mustacchi Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. 4*7fd79137SRobert Mustacchi Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved. 5*7fd79137SRobert Mustacchi Portions Copyright 2009-2010 David Anderson. All rights reserved. 6*7fd79137SRobert Mustacchi Portions Copyright 2009-2010 Novell Inc. All rights reserved. 7*7fd79137SRobert Mustacchi 8*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 9*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 10*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 11*7fd79137SRobert Mustacchi 12*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 13*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 14*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15*7fd79137SRobert Mustacchi 16*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 17*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 18*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 19*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 20*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 21*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 22*7fd79137SRobert Mustacchi 23*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 24*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 25*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 26*7fd79137SRobert Mustacchi USA. 27*7fd79137SRobert Mustacchi 28*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 29*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 30*7fd79137SRobert Mustacchi 31*7fd79137SRobert Mustacchi http://www.sgi.com 32*7fd79137SRobert Mustacchi 33*7fd79137SRobert Mustacchi For further information regarding this notice, see: 34*7fd79137SRobert Mustacchi 35*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi */ 38*7fd79137SRobert Mustacchi 39*7fd79137SRobert Mustacchi #include "config.h" 40*7fd79137SRobert Mustacchi #include "dwarf_incl.h" 41*7fd79137SRobert Mustacchi #include "dwarf_elf_access.h" 42*7fd79137SRobert Mustacchi 43*7fd79137SRobert Mustacchi #ifdef HAVE_ELF_H 44*7fd79137SRobert Mustacchi #include <elf.h> 45*7fd79137SRobert Mustacchi #endif 46*7fd79137SRobert Mustacchi #ifdef HAVE_LIBELF_H 47*7fd79137SRobert Mustacchi #include <libelf.h> 48*7fd79137SRobert Mustacchi #else 49*7fd79137SRobert Mustacchi #ifdef HAVE_LIBELF_LIBELF_H 50*7fd79137SRobert Mustacchi #include <libelf/libelf.h> 51*7fd79137SRobert Mustacchi #endif 52*7fd79137SRobert Mustacchi #endif 53*7fd79137SRobert Mustacchi 54*7fd79137SRobert Mustacchi #include <stdio.h> 55*7fd79137SRobert Mustacchi #include <sys/stat.h> 56*7fd79137SRobert Mustacchi #include <sys/types.h> 57*7fd79137SRobert Mustacchi #include <string.h> 58*7fd79137SRobert Mustacchi #include <stdlib.h> 59*7fd79137SRobert Mustacchi 60*7fd79137SRobert Mustacchi #define FALSE 0 61*7fd79137SRobert Mustacchi #define TRUE 1 62*7fd79137SRobert Mustacchi 63*7fd79137SRobert Mustacchi #ifndef EM_MIPS 64*7fd79137SRobert Mustacchi /* This is the standard elf value EM_MIPS. */ 65*7fd79137SRobert Mustacchi #define EM_MIPS 8 66*7fd79137SRobert Mustacchi #endif 67*7fd79137SRobert Mustacchi 68*7fd79137SRobert Mustacchi 69*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETEHDR 70*7fd79137SRobert Mustacchi extern Elf64_Ehdr *elf64_getehdr(Elf *); 71*7fd79137SRobert Mustacchi #endif 72*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETSHDR 73*7fd79137SRobert Mustacchi extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); 74*7fd79137SRobert Mustacchi #endif 75*7fd79137SRobert Mustacchi #ifdef WORDS_BIGENDIAN 76*7fd79137SRobert Mustacchi #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ 77*7fd79137SRobert Mustacchi { \ 78*7fd79137SRobert Mustacchi dbg->de_copy_word(dest, \ 79*7fd79137SRobert Mustacchi ((char *)source) +srclength-len_out, \ 80*7fd79137SRobert Mustacchi len_out) ; \ 81*7fd79137SRobert Mustacchi } 82*7fd79137SRobert Mustacchi 83*7fd79137SRobert Mustacchi 84*7fd79137SRobert Mustacchi #else /* LITTLE ENDIAN */ 85*7fd79137SRobert Mustacchi 86*7fd79137SRobert Mustacchi #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ 87*7fd79137SRobert Mustacchi { \ 88*7fd79137SRobert Mustacchi dbg->de_copy_word( (dest) , \ 89*7fd79137SRobert Mustacchi ((char *)source) , \ 90*7fd79137SRobert Mustacchi len_out) ; \ 91*7fd79137SRobert Mustacchi } 92*7fd79137SRobert Mustacchi #endif 93*7fd79137SRobert Mustacchi 94*7fd79137SRobert Mustacchi 95*7fd79137SRobert Mustacchi 96*7fd79137SRobert Mustacchi typedef struct { 97*7fd79137SRobert Mustacchi dwarf_elf_handle elf; 98*7fd79137SRobert Mustacchi int is_64bit; 99*7fd79137SRobert Mustacchi Dwarf_Small length_size; 100*7fd79137SRobert Mustacchi Dwarf_Small pointer_size; 101*7fd79137SRobert Mustacchi Dwarf_Unsigned section_count; 102*7fd79137SRobert Mustacchi Dwarf_Endianness endianness; 103*7fd79137SRobert Mustacchi Dwarf_Small machine; 104*7fd79137SRobert Mustacchi int libdwarf_owns_elf; 105*7fd79137SRobert Mustacchi Elf32_Ehdr *ehdr32; 106*7fd79137SRobert Mustacchi 107*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETEHDR 108*7fd79137SRobert Mustacchi Elf64_Ehdr *ehdr64; 109*7fd79137SRobert Mustacchi #endif 110*7fd79137SRobert Mustacchi /* Elf symtab and its strtab. Initialized at first 111*7fd79137SRobert Mustacchi call to do relocations, the actual data is in the Dwarf_Debug 112*7fd79137SRobert Mustacchi struct, not allocated locally here. */ 113*7fd79137SRobert Mustacchi struct Dwarf_Section_s *symtab; 114*7fd79137SRobert Mustacchi struct Dwarf_Section_s *strtab; 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi } dwarf_elf_object_access_internals_t; 117*7fd79137SRobert Mustacchi 118*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela { 119*7fd79137SRobert Mustacchi Dwarf_ufixed64 r_offset; 120*7fd79137SRobert Mustacchi /*Dwarf_ufixed64 r_info; */ 121*7fd79137SRobert Mustacchi Dwarf_ufixed64 r_type; 122*7fd79137SRobert Mustacchi Dwarf_ufixed64 r_symidx; 123*7fd79137SRobert Mustacchi Dwarf_ufixed64 r_addend; 124*7fd79137SRobert Mustacchi }; 125*7fd79137SRobert Mustacchi 126*7fd79137SRobert Mustacchi 127*7fd79137SRobert Mustacchi static int dwarf_elf_object_access_load_section(void* obj_in, 128*7fd79137SRobert Mustacchi Dwarf_Half section_index, 129*7fd79137SRobert Mustacchi Dwarf_Small** section_data, 130*7fd79137SRobert Mustacchi int* error); 131*7fd79137SRobert Mustacchi 132*7fd79137SRobert Mustacchi /* 133*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_init() 134*7fd79137SRobert Mustacchi */ 135*7fd79137SRobert Mustacchi static int 136*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_init(void* obj_in, 137*7fd79137SRobert Mustacchi dwarf_elf_handle elf, 138*7fd79137SRobert Mustacchi int* error) 139*7fd79137SRobert Mustacchi { 140*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 141*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 142*7fd79137SRobert Mustacchi char *ehdr_ident = 0; 143*7fd79137SRobert Mustacchi Dwarf_Half machine = 0; 144*7fd79137SRobert Mustacchi obj->elf = elf; 145*7fd79137SRobert Mustacchi 146*7fd79137SRobert Mustacchi if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { 147*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_GETIDENT_ERROR; 148*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 149*7fd79137SRobert Mustacchi } 150*7fd79137SRobert Mustacchi 151*7fd79137SRobert Mustacchi obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); 152*7fd79137SRobert Mustacchi 153*7fd79137SRobert Mustacchi 154*7fd79137SRobert Mustacchi if(ehdr_ident[EI_DATA] == ELFDATA2LSB){ 155*7fd79137SRobert Mustacchi obj->endianness = DW_OBJECT_LSB; 156*7fd79137SRobert Mustacchi } 157*7fd79137SRobert Mustacchi else if(ehdr_ident[EI_DATA] == ELFDATA2MSB){ 158*7fd79137SRobert Mustacchi obj->endianness = DW_OBJECT_MSB; 159*7fd79137SRobert Mustacchi } 160*7fd79137SRobert Mustacchi 161*7fd79137SRobert Mustacchi if (obj->is_64bit) { 162*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETEHDR 163*7fd79137SRobert Mustacchi obj->ehdr64 = elf64_getehdr(elf); 164*7fd79137SRobert Mustacchi if (obj->ehdr64 == NULL) { 165*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_GETEHDR_ERROR; 166*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 167*7fd79137SRobert Mustacchi } 168*7fd79137SRobert Mustacchi obj->section_count = obj->ehdr64->e_shnum; 169*7fd79137SRobert Mustacchi machine = obj->ehdr64->e_machine; 170*7fd79137SRobert Mustacchi obj->machine = machine; 171*7fd79137SRobert Mustacchi #else 172*7fd79137SRobert Mustacchi *error = DW_DLE_NO_ELF64_SUPPORT; 173*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 174*7fd79137SRobert Mustacchi #endif 175*7fd79137SRobert Mustacchi } 176*7fd79137SRobert Mustacchi else { 177*7fd79137SRobert Mustacchi obj->ehdr32 = elf32_getehdr(elf); 178*7fd79137SRobert Mustacchi if (obj->ehdr32 == NULL) { 179*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_GETEHDR_ERROR; 180*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 181*7fd79137SRobert Mustacchi } 182*7fd79137SRobert Mustacchi obj->section_count = obj->ehdr32->e_shnum; 183*7fd79137SRobert Mustacchi machine = obj->ehdr32->e_machine; 184*7fd79137SRobert Mustacchi obj->machine = machine; 185*7fd79137SRobert Mustacchi } 186*7fd79137SRobert Mustacchi 187*7fd79137SRobert Mustacchi /* The following length_size is Not Too Significant. Only used 188*7fd79137SRobert Mustacchi one calculation, and an approximate one at that. */ 189*7fd79137SRobert Mustacchi obj->length_size = obj->is_64bit ? 8 : 4; 190*7fd79137SRobert Mustacchi obj->pointer_size = obj->is_64bit ? 8 : 4; 191*7fd79137SRobert Mustacchi 192*7fd79137SRobert Mustacchi if (obj->is_64bit && machine != EM_MIPS) { 193*7fd79137SRobert Mustacchi /* MIPS/IRIX makes pointer size and length size 8 for -64. 194*7fd79137SRobert Mustacchi Other platforms make length 4 always. */ 195*7fd79137SRobert Mustacchi /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus 196*7fd79137SRobert Mustacchi tools, and the dwarfv2.1 64bit extension setting. 197*7fd79137SRobert Mustacchi This is not the same as the size-of-an-offset, which 198*7fd79137SRobert Mustacchi is 4 in 32bit dwarf and 8 in 64bit dwarf. */ 199*7fd79137SRobert Mustacchi obj->length_size = 4; 200*7fd79137SRobert Mustacchi } 201*7fd79137SRobert Mustacchi return DW_DLV_OK; 202*7fd79137SRobert Mustacchi } 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi /* 205*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_byte_order 206*7fd79137SRobert Mustacchi */ 207*7fd79137SRobert Mustacchi static 208*7fd79137SRobert Mustacchi Dwarf_Endianness 209*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_byte_order(void* obj_in) 210*7fd79137SRobert Mustacchi { 211*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 212*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 213*7fd79137SRobert Mustacchi return obj->endianness; 214*7fd79137SRobert Mustacchi } 215*7fd79137SRobert Mustacchi 216*7fd79137SRobert Mustacchi /* 217*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section_count() 218*7fd79137SRobert Mustacchi */ 219*7fd79137SRobert Mustacchi static 220*7fd79137SRobert Mustacchi Dwarf_Unsigned 221*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section_count(void * obj_in) 222*7fd79137SRobert Mustacchi { 223*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 224*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 225*7fd79137SRobert Mustacchi return obj->section_count; 226*7fd79137SRobert Mustacchi } 227*7fd79137SRobert Mustacchi 228*7fd79137SRobert Mustacchi 229*7fd79137SRobert Mustacchi /* 230*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section() 231*7fd79137SRobert Mustacchi */ 232*7fd79137SRobert Mustacchi static 233*7fd79137SRobert Mustacchi int 234*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section_info( 235*7fd79137SRobert Mustacchi void* obj_in, 236*7fd79137SRobert Mustacchi Dwarf_Half section_index, 237*7fd79137SRobert Mustacchi Dwarf_Obj_Access_Section* ret_scn, 238*7fd79137SRobert Mustacchi int* error) 239*7fd79137SRobert Mustacchi { 240*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 241*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 242*7fd79137SRobert Mustacchi 243*7fd79137SRobert Mustacchi Elf32_Shdr *shdr32 = 0; 244*7fd79137SRobert Mustacchi 245*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETSHDR 246*7fd79137SRobert Mustacchi Elf64_Shdr *shdr64 = 0; 247*7fd79137SRobert Mustacchi #endif 248*7fd79137SRobert Mustacchi Elf_Scn *scn = 0; 249*7fd79137SRobert Mustacchi 250*7fd79137SRobert Mustacchi 251*7fd79137SRobert Mustacchi scn = elf_getscn(obj->elf, section_index); 252*7fd79137SRobert Mustacchi if (scn == NULL) { 253*7fd79137SRobert Mustacchi *error = DW_DLE_MDE; 254*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 255*7fd79137SRobert Mustacchi } 256*7fd79137SRobert Mustacchi if (obj->is_64bit) { 257*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_GETSHDR 258*7fd79137SRobert Mustacchi shdr64 = elf64_getshdr(scn); 259*7fd79137SRobert Mustacchi if (shdr64 == NULL) { 260*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_GETSHDR_ERROR; 261*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 262*7fd79137SRobert Mustacchi } 263*7fd79137SRobert Mustacchi 264*7fd79137SRobert Mustacchi ret_scn->size = shdr64->sh_size; 265*7fd79137SRobert Mustacchi ret_scn->addr = shdr64->sh_addr; 266*7fd79137SRobert Mustacchi ret_scn->link = shdr64->sh_link; 267*7fd79137SRobert Mustacchi 268*7fd79137SRobert Mustacchi ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx, 269*7fd79137SRobert Mustacchi shdr64->sh_name); 270*7fd79137SRobert Mustacchi if(ret_scn->name == NULL) { 271*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_STRPTR_ERROR; 272*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 273*7fd79137SRobert Mustacchi } 274*7fd79137SRobert Mustacchi return DW_DLV_OK; 275*7fd79137SRobert Mustacchi #else 276*7fd79137SRobert Mustacchi *error = DW_DLE_MISSING_ELF64_SUPPORT; 277*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 278*7fd79137SRobert Mustacchi #endif /* HAVE_ELF64_GETSHDR */ 279*7fd79137SRobert Mustacchi } 280*7fd79137SRobert Mustacchi if ((shdr32 = elf32_getshdr(scn)) == NULL) { 281*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_GETSHDR_ERROR; 282*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 283*7fd79137SRobert Mustacchi } 284*7fd79137SRobert Mustacchi 285*7fd79137SRobert Mustacchi ret_scn->size = shdr32->sh_size; 286*7fd79137SRobert Mustacchi ret_scn->addr = shdr32->sh_addr; 287*7fd79137SRobert Mustacchi ret_scn->link = shdr32->sh_link; 288*7fd79137SRobert Mustacchi 289*7fd79137SRobert Mustacchi ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx, 290*7fd79137SRobert Mustacchi shdr32->sh_name); 291*7fd79137SRobert Mustacchi if (ret_scn->name == NULL) { 292*7fd79137SRobert Mustacchi *error = DW_DLE_ELF_STRPTR_ERROR; 293*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 294*7fd79137SRobert Mustacchi } 295*7fd79137SRobert Mustacchi return DW_DLV_OK; 296*7fd79137SRobert Mustacchi } 297*7fd79137SRobert Mustacchi 298*7fd79137SRobert Mustacchi /* 299*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_length_size 300*7fd79137SRobert Mustacchi */ 301*7fd79137SRobert Mustacchi static 302*7fd79137SRobert Mustacchi Dwarf_Small 303*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_length_size(void* obj_in) 304*7fd79137SRobert Mustacchi { 305*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 306*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 307*7fd79137SRobert Mustacchi return obj->length_size; 308*7fd79137SRobert Mustacchi } 309*7fd79137SRobert Mustacchi 310*7fd79137SRobert Mustacchi /* 311*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_pointer_size 312*7fd79137SRobert Mustacchi */ 313*7fd79137SRobert Mustacchi static 314*7fd79137SRobert Mustacchi Dwarf_Small 315*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_pointer_size(void* obj_in) 316*7fd79137SRobert Mustacchi { 317*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 318*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 319*7fd79137SRobert Mustacchi return obj->pointer_size; 320*7fd79137SRobert Mustacchi } 321*7fd79137SRobert Mustacchi 322*7fd79137SRobert Mustacchi #define MATCH_REL_SEC(i_,s_,r_) \ 323*7fd79137SRobert Mustacchi if(i_ == s_.dss_index) { \ 324*7fd79137SRobert Mustacchi *r_ = &s_; \ 325*7fd79137SRobert Mustacchi return DW_DLV_OK; \ 326*7fd79137SRobert Mustacchi } 327*7fd79137SRobert Mustacchi 328*7fd79137SRobert Mustacchi static int 329*7fd79137SRobert Mustacchi find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, 330*7fd79137SRobert Mustacchi struct Dwarf_Section_s **relocatablesec, int *error) 331*7fd79137SRobert Mustacchi { 332*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); 333*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); 334*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); 335*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); 336*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); 337*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); 338*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec); 339*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); 340*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec); 341*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec); 342*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec); 343*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec); 344*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec); 345*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); 346*7fd79137SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); 347*7fd79137SRobert Mustacchi /* dbg-> de_debug_str,syms); */ 348*7fd79137SRobert Mustacchi /* de_elf_symtab,syms); */ 349*7fd79137SRobert Mustacchi /* de_elf_strtab,syms); */ 350*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_MISMATCH; 351*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 352*7fd79137SRobert Mustacchi 353*7fd79137SRobert Mustacchi } 354*7fd79137SRobert Mustacchi #undef MATCH_REL_SEC 355*7fd79137SRobert Mustacchi 356*7fd79137SRobert Mustacchi static void 357*7fd79137SRobert Mustacchi get_rela_elf32(Dwarf_Small *data, unsigned int i, 358*7fd79137SRobert Mustacchi int endianness, 359*7fd79137SRobert Mustacchi int machine, struct Dwarf_Elf_Rela *relap) 360*7fd79137SRobert Mustacchi { 361*7fd79137SRobert Mustacchi Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela))); 362*7fd79137SRobert Mustacchi relap->r_offset = relp->r_offset; 363*7fd79137SRobert Mustacchi /* 364*7fd79137SRobert Mustacchi relap->r_info = relp->r_info; 365*7fd79137SRobert Mustacchi */ 366*7fd79137SRobert Mustacchi relap->r_type = ELF32_R_TYPE(relp->r_info); 367*7fd79137SRobert Mustacchi relap->r_symidx = ELF32_R_SYM(relp->r_info); 368*7fd79137SRobert Mustacchi relap->r_addend = relp->r_addend; 369*7fd79137SRobert Mustacchi } 370*7fd79137SRobert Mustacchi 371*7fd79137SRobert Mustacchi static void 372*7fd79137SRobert Mustacchi get_rela_elf64(Dwarf_Small *data, unsigned int i, 373*7fd79137SRobert Mustacchi int endianness, 374*7fd79137SRobert Mustacchi int machine,struct Dwarf_Elf_Rela *relap) 375*7fd79137SRobert Mustacchi { 376*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_RELA 377*7fd79137SRobert Mustacchi Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela))); 378*7fd79137SRobert Mustacchi relap->r_offset = relp->r_offset; 379*7fd79137SRobert Mustacchi /* 380*7fd79137SRobert Mustacchi relap->r_info = relp->r_info; 381*7fd79137SRobert Mustacchi */ 382*7fd79137SRobert Mustacchi if(machine == EM_MIPS && endianness == DW_OBJECT_LSB ) { 383*7fd79137SRobert Mustacchi /* This is really wierd. Treat this very specially. 384*7fd79137SRobert Mustacchi The Elf64 LE MIPS object used for 385*7fd79137SRobert Mustacchi testing (that has rela) wants the 386*7fd79137SRobert Mustacchi values as sym ssym type3 type2 type, treating 387*7fd79137SRobert Mustacchi each value as independent value. But libelf xlate 388*7fd79137SRobert Mustacchi treats it as something else so we fudge here. 389*7fd79137SRobert Mustacchi It is unclear 390*7fd79137SRobert Mustacchi how to precisely characterize where these relocations 391*7fd79137SRobert Mustacchi were used. 392*7fd79137SRobert Mustacchi SGI MIPS on IRIX never used .rela relocations. 393*7fd79137SRobert Mustacchi The BE 64bit elf MIPS test object with rela uses traditional 394*7fd79137SRobert Mustacchi elf relocation layouts, not this special case. */ 395*7fd79137SRobert Mustacchi #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff) 396*7fd79137SRobert Mustacchi #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff) 397*7fd79137SRobert Mustacchi /* We ignore the special TYPE2 and TYPE3, they should be 398*7fd79137SRobert Mustacchi value R_MIPS_NONE in rela. */ 399*7fd79137SRobert Mustacchi relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info); 400*7fd79137SRobert Mustacchi relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info); 401*7fd79137SRobert Mustacchi #undef MIPS64SYM 402*7fd79137SRobert Mustacchi #undef MIPS64TYPE 403*7fd79137SRobert Mustacchi } else 404*7fd79137SRobert Mustacchi { 405*7fd79137SRobert Mustacchi relap->r_type = ELF64_R_TYPE(relp->r_info); 406*7fd79137SRobert Mustacchi relap->r_symidx = ELF64_R_SYM(relp->r_info); 407*7fd79137SRobert Mustacchi } 408*7fd79137SRobert Mustacchi relap->r_addend = relp->r_addend; 409*7fd79137SRobert Mustacchi #endif 410*7fd79137SRobert Mustacchi } 411*7fd79137SRobert Mustacchi 412*7fd79137SRobert Mustacchi static void 413*7fd79137SRobert Mustacchi get_relocations_array(Dwarf_Bool is_64bit, 414*7fd79137SRobert Mustacchi int endianness, 415*7fd79137SRobert Mustacchi int machine, 416*7fd79137SRobert Mustacchi Dwarf_Small *data, 417*7fd79137SRobert Mustacchi unsigned int num_relocations, 418*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela *relap) 419*7fd79137SRobert Mustacchi { 420*7fd79137SRobert Mustacchi unsigned int i = 0; 421*7fd79137SRobert Mustacchi void (*get_relocations)(Dwarf_Small *data, unsigned int i, 422*7fd79137SRobert Mustacchi int endianness, 423*7fd79137SRobert Mustacchi int machine, 424*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela *relap); 425*7fd79137SRobert Mustacchi 426*7fd79137SRobert Mustacchi /* Handle 32/64 bit issue 427*7fd79137SRobert Mustacchi */ 428*7fd79137SRobert Mustacchi if (is_64bit) { 429*7fd79137SRobert Mustacchi get_relocations = get_rela_elf64; 430*7fd79137SRobert Mustacchi } else { 431*7fd79137SRobert Mustacchi get_relocations = get_rela_elf32; 432*7fd79137SRobert Mustacchi } 433*7fd79137SRobert Mustacchi 434*7fd79137SRobert Mustacchi for (i=0; i < num_relocations; i++) { 435*7fd79137SRobert Mustacchi get_relocations(data, i,endianness,machine, &(relap[i])); 436*7fd79137SRobert Mustacchi } 437*7fd79137SRobert Mustacchi 438*7fd79137SRobert Mustacchi } 439*7fd79137SRobert Mustacchi 440*7fd79137SRobert Mustacchi static int 441*7fd79137SRobert Mustacchi get_relocation_entries(Dwarf_Bool is_64bit, 442*7fd79137SRobert Mustacchi int endianness, 443*7fd79137SRobert Mustacchi int machine, 444*7fd79137SRobert Mustacchi Dwarf_Small *relocation_section, 445*7fd79137SRobert Mustacchi Dwarf_Unsigned relocation_section_size, 446*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela **relas, 447*7fd79137SRobert Mustacchi unsigned int *nrelas, 448*7fd79137SRobert Mustacchi int *error) 449*7fd79137SRobert Mustacchi { 450*7fd79137SRobert Mustacchi unsigned int relocation_size = 0; 451*7fd79137SRobert Mustacchi 452*7fd79137SRobert Mustacchi if (is_64bit) { 453*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_RELA 454*7fd79137SRobert Mustacchi relocation_size = sizeof(Elf64_Rela); 455*7fd79137SRobert Mustacchi #else 456*7fd79137SRobert Mustacchi *error = DW_DLE_MISSING_ELF64_SUPPORT; 457*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 458*7fd79137SRobert Mustacchi #endif 459*7fd79137SRobert Mustacchi } else { 460*7fd79137SRobert Mustacchi relocation_size = sizeof(Elf32_Rela); 461*7fd79137SRobert Mustacchi } 462*7fd79137SRobert Mustacchi 463*7fd79137SRobert Mustacchi if (relocation_section == NULL) { 464*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_PTR_NULL; 465*7fd79137SRobert Mustacchi return(DW_DLV_ERROR); 466*7fd79137SRobert Mustacchi } 467*7fd79137SRobert Mustacchi 468*7fd79137SRobert Mustacchi if ((relocation_section_size != 0)) { 469*7fd79137SRobert Mustacchi size_t bytescount = 0; 470*7fd79137SRobert Mustacchi if(relocation_section_size%relocation_size) { 471*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_LENGTH_ODD; 472*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 473*7fd79137SRobert Mustacchi } 474*7fd79137SRobert Mustacchi *nrelas = relocation_section_size/relocation_size; 475*7fd79137SRobert Mustacchi bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela); 476*7fd79137SRobert Mustacchi *relas = malloc(bytescount); 477*7fd79137SRobert Mustacchi if (!*relas) { 478*7fd79137SRobert Mustacchi *error = DW_DLE_MAF; 479*7fd79137SRobert Mustacchi return(DW_DLV_ERROR); 480*7fd79137SRobert Mustacchi } 481*7fd79137SRobert Mustacchi memset(*relas,0,bytescount); 482*7fd79137SRobert Mustacchi get_relocations_array(is_64bit,endianness,machine, relocation_section, 483*7fd79137SRobert Mustacchi *nrelas, *relas); 484*7fd79137SRobert Mustacchi } 485*7fd79137SRobert Mustacchi return(DW_DLV_OK); 486*7fd79137SRobert Mustacchi } 487*7fd79137SRobert Mustacchi 488*7fd79137SRobert Mustacchi static Dwarf_Bool 489*7fd79137SRobert Mustacchi is_32bit_abs_reloc(unsigned int type, Dwarf_Half machine) 490*7fd79137SRobert Mustacchi { 491*7fd79137SRobert Mustacchi Dwarf_Bool r = 0; 492*7fd79137SRobert Mustacchi switch (machine) { 493*7fd79137SRobert Mustacchi #if defined(EM_MIPS) && defined (R_MIPS_32) 494*7fd79137SRobert Mustacchi case EM_MIPS: 495*7fd79137SRobert Mustacchi r = (type == R_MIPS_32); 496*7fd79137SRobert Mustacchi break; 497*7fd79137SRobert Mustacchi #endif 498*7fd79137SRobert Mustacchi #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32) 499*7fd79137SRobert Mustacchi case EM_SPARC32PLUS: 500*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA32); 501*7fd79137SRobert Mustacchi break; 502*7fd79137SRobert Mustacchi #endif 503*7fd79137SRobert Mustacchi #if defined(EM_SPARCV9) && defined (R_SPARC_UA32) 504*7fd79137SRobert Mustacchi case EM_SPARCV9: 505*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA32); 506*7fd79137SRobert Mustacchi break; 507*7fd79137SRobert Mustacchi #endif 508*7fd79137SRobert Mustacchi #if defined(EM_SPARC) && defined (R_SPARC_UA32) 509*7fd79137SRobert Mustacchi case EM_SPARC: 510*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA32); 511*7fd79137SRobert Mustacchi break; 512*7fd79137SRobert Mustacchi #endif 513*7fd79137SRobert Mustacchi #if defined(EM_386) && defined (R_386_32) 514*7fd79137SRobert Mustacchi case EM_386: 515*7fd79137SRobert Mustacchi r = (type == R_386_32); 516*7fd79137SRobert Mustacchi break; 517*7fd79137SRobert Mustacchi #endif 518*7fd79137SRobert Mustacchi #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) 519*7fd79137SRobert Mustacchi case EM_IA_64: 520*7fd79137SRobert Mustacchi r = (type == R_IA64_SECREL32LSB); 521*7fd79137SRobert Mustacchi break; 522*7fd79137SRobert Mustacchi #endif 523*7fd79137SRobert Mustacchi #if defined(EM_PPC64) && defined (R_PPC64_ADDR32) 524*7fd79137SRobert Mustacchi case EM_PPC64: 525*7fd79137SRobert Mustacchi r = (type == R_PPC64_ADDR32); 526*7fd79137SRobert Mustacchi break; 527*7fd79137SRobert Mustacchi #endif 528*7fd79137SRobert Mustacchi #if defined(EM_PPC) && defined (R_PPC_ADDR32) 529*7fd79137SRobert Mustacchi case EM_PPC: 530*7fd79137SRobert Mustacchi r = (type == R_PPC_ADDR32); 531*7fd79137SRobert Mustacchi break; 532*7fd79137SRobert Mustacchi #endif 533*7fd79137SRobert Mustacchi #if defined(EM_S390) && defined (R_390_32) 534*7fd79137SRobert Mustacchi case EM_S390: 535*7fd79137SRobert Mustacchi r = (type == R_390_32); 536*7fd79137SRobert Mustacchi break; 537*7fd79137SRobert Mustacchi #endif 538*7fd79137SRobert Mustacchi #if defined(EM_X86_64) && defined (R_X86_64_32) 539*7fd79137SRobert Mustacchi case EM_X86_64: 540*7fd79137SRobert Mustacchi r = (type == R_X86_64_32); 541*7fd79137SRobert Mustacchi break; 542*7fd79137SRobert Mustacchi #endif 543*7fd79137SRobert Mustacchi } 544*7fd79137SRobert Mustacchi return r; 545*7fd79137SRobert Mustacchi } 546*7fd79137SRobert Mustacchi 547*7fd79137SRobert Mustacchi static Dwarf_Bool 548*7fd79137SRobert Mustacchi is_64bit_abs_reloc(unsigned int type, Dwarf_Half machine) 549*7fd79137SRobert Mustacchi { 550*7fd79137SRobert Mustacchi Dwarf_Bool r = 0; 551*7fd79137SRobert Mustacchi switch (machine) { 552*7fd79137SRobert Mustacchi #if defined(EM_MIPS) && defined (R_MIPS_64) 553*7fd79137SRobert Mustacchi case EM_MIPS: 554*7fd79137SRobert Mustacchi r = (type == R_MIPS_64); 555*7fd79137SRobert Mustacchi break; 556*7fd79137SRobert Mustacchi #endif 557*7fd79137SRobert Mustacchi #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64) 558*7fd79137SRobert Mustacchi case EM_SPARC32PLUS: 559*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA64); 560*7fd79137SRobert Mustacchi break; 561*7fd79137SRobert Mustacchi #endif 562*7fd79137SRobert Mustacchi #if defined(EM_SPARCV9) && defined (R_SPARC_UA64) 563*7fd79137SRobert Mustacchi case EM_SPARCV9: 564*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA64); 565*7fd79137SRobert Mustacchi break; 566*7fd79137SRobert Mustacchi #endif 567*7fd79137SRobert Mustacchi #if defined(EM_SPARC) && defined (R_SPARC_UA64) 568*7fd79137SRobert Mustacchi case EM_SPARC: 569*7fd79137SRobert Mustacchi r = (type == R_SPARC_UA64); 570*7fd79137SRobert Mustacchi break; 571*7fd79137SRobert Mustacchi #endif 572*7fd79137SRobert Mustacchi #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) 573*7fd79137SRobert Mustacchi case EM_IA_64: 574*7fd79137SRobert Mustacchi r = (type == R_IA64_DIR64LSB); 575*7fd79137SRobert Mustacchi break; 576*7fd79137SRobert Mustacchi #endif 577*7fd79137SRobert Mustacchi #if defined(EM_PPC64) && defined (R_PPC64_ADDR64) 578*7fd79137SRobert Mustacchi case EM_PPC64: 579*7fd79137SRobert Mustacchi r = (type == R_PPC64_ADDR64); 580*7fd79137SRobert Mustacchi break; 581*7fd79137SRobert Mustacchi #endif 582*7fd79137SRobert Mustacchi #if defined(EM_S390) && defined (R_390_64) 583*7fd79137SRobert Mustacchi case EM_S390: 584*7fd79137SRobert Mustacchi r = (type == R_390_64); 585*7fd79137SRobert Mustacchi break; 586*7fd79137SRobert Mustacchi #endif 587*7fd79137SRobert Mustacchi #if defined(EM_X86_64) && defined (R_X86_64_64) 588*7fd79137SRobert Mustacchi case EM_X86_64: 589*7fd79137SRobert Mustacchi r = (type == R_X86_64_64); 590*7fd79137SRobert Mustacchi break; 591*7fd79137SRobert Mustacchi #endif 592*7fd79137SRobert Mustacchi } 593*7fd79137SRobert Mustacchi return r; 594*7fd79137SRobert Mustacchi } 595*7fd79137SRobert Mustacchi 596*7fd79137SRobert Mustacchi 597*7fd79137SRobert Mustacchi static void 598*7fd79137SRobert Mustacchi update_entry(Dwarf_Debug dbg, 599*7fd79137SRobert Mustacchi Dwarf_Bool is_64bit, Dwarf_Endianness endianess, 600*7fd79137SRobert Mustacchi Dwarf_Half machine, struct Dwarf_Elf_Rela *rela, 601*7fd79137SRobert Mustacchi Dwarf_Small *target_section, Dwarf_Small *section_data) 602*7fd79137SRobert Mustacchi { 603*7fd79137SRobert Mustacchi unsigned int type = 0; 604*7fd79137SRobert Mustacchi unsigned int sym_idx = 0; 605*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_SYM 606*7fd79137SRobert Mustacchi Elf64_Sym sym_buf; 607*7fd79137SRobert Mustacchi Elf64_Sym *sym = 0; 608*7fd79137SRobert Mustacchi #else 609*7fd79137SRobert Mustacchi Elf32_Sym sym_buf; 610*7fd79137SRobert Mustacchi Elf32_Sym *sym = 0; 611*7fd79137SRobert Mustacchi #endif 612*7fd79137SRobert Mustacchi Elf32_Sym *sym32 = 0; 613*7fd79137SRobert Mustacchi Dwarf_ufixed64 offset = 0; 614*7fd79137SRobert Mustacchi Dwarf_sfixed64 addend = 0; 615*7fd79137SRobert Mustacchi Dwarf_Unsigned reloc_size = 0; 616*7fd79137SRobert Mustacchi 617*7fd79137SRobert Mustacchi 618*7fd79137SRobert Mustacchi /* Dwarf_Elf_Rela dereferencing */ 619*7fd79137SRobert Mustacchi offset = rela->r_offset; 620*7fd79137SRobert Mustacchi addend = rela->r_addend; 621*7fd79137SRobert Mustacchi type = rela->r_type; 622*7fd79137SRobert Mustacchi sym_idx = rela->r_symidx; 623*7fd79137SRobert Mustacchi 624*7fd79137SRobert Mustacchi if (is_64bit) { 625*7fd79137SRobert Mustacchi #ifdef HAVE_ELF64_SYM 626*7fd79137SRobert Mustacchi sym = &((Elf64_Sym*)section_data)[sym_idx]; 627*7fd79137SRobert Mustacchi #endif 628*7fd79137SRobert Mustacchi } else { 629*7fd79137SRobert Mustacchi sym32 = &((Elf32_Sym*)section_data)[sym_idx]; 630*7fd79137SRobert Mustacchi 631*7fd79137SRobert Mustacchi /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at 632*7fd79137SRobert Mustacchi * an Elf64_Sym local variable (sym_buf) to allow us to use the 633*7fd79137SRobert Mustacchi * same pointer (sym) for both 32-bit and 64-bit instances. 634*7fd79137SRobert Mustacchi */ 635*7fd79137SRobert Mustacchi sym = &sym_buf; 636*7fd79137SRobert Mustacchi sym->st_name = sym32->st_name; 637*7fd79137SRobert Mustacchi sym->st_info = sym32->st_info; 638*7fd79137SRobert Mustacchi sym->st_other = sym32->st_other; 639*7fd79137SRobert Mustacchi sym->st_shndx = sym32->st_shndx; 640*7fd79137SRobert Mustacchi sym->st_value = sym32->st_value; 641*7fd79137SRobert Mustacchi sym->st_size = sym32->st_size; 642*7fd79137SRobert Mustacchi } 643*7fd79137SRobert Mustacchi 644*7fd79137SRobert Mustacchi /* Determine relocation size */ 645*7fd79137SRobert Mustacchi if (is_32bit_abs_reloc(type, machine)) { 646*7fd79137SRobert Mustacchi reloc_size = 4; 647*7fd79137SRobert Mustacchi } else if (is_64bit_abs_reloc(type, machine)) { 648*7fd79137SRobert Mustacchi reloc_size = 8; 649*7fd79137SRobert Mustacchi } else { 650*7fd79137SRobert Mustacchi return; 651*7fd79137SRobert Mustacchi } 652*7fd79137SRobert Mustacchi 653*7fd79137SRobert Mustacchi 654*7fd79137SRobert Mustacchi { 655*7fd79137SRobert Mustacchi /* Assuming we do not need to do a READ_UNALIGNED here 656*7fd79137SRobert Mustacchi at target_section + offset and add its value to 657*7fd79137SRobert Mustacchi outval. Some ABIs say no read (for example MIPS), 658*7fd79137SRobert Mustacchi but if some do then which ones? */ 659*7fd79137SRobert Mustacchi Dwarf_Unsigned outval = sym->st_value + addend; 660*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg,target_section + offset, 661*7fd79137SRobert Mustacchi &outval,sizeof(outval),reloc_size); 662*7fd79137SRobert Mustacchi } 663*7fd79137SRobert Mustacchi } 664*7fd79137SRobert Mustacchi 665*7fd79137SRobert Mustacchi 666*7fd79137SRobert Mustacchi 667*7fd79137SRobert Mustacchi static int 668*7fd79137SRobert Mustacchi apply_rela_entries(Dwarf_Debug dbg, 669*7fd79137SRobert Mustacchi Dwarf_Bool is_64bit, 670*7fd79137SRobert Mustacchi Dwarf_Endianness endianess, 671*7fd79137SRobert Mustacchi Dwarf_Half machine, 672*7fd79137SRobert Mustacchi Dwarf_Small *target_section, 673*7fd79137SRobert Mustacchi Dwarf_Small *symtab_section, 674*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela *relas, unsigned int nrelas, 675*7fd79137SRobert Mustacchi int *error) 676*7fd79137SRobert Mustacchi { 677*7fd79137SRobert Mustacchi if ((target_section != NULL) && (relas != NULL)) { 678*7fd79137SRobert Mustacchi unsigned int i; 679*7fd79137SRobert Mustacchi for (i = 0; i < nrelas; i++) { 680*7fd79137SRobert Mustacchi update_entry(dbg, is_64bit, 681*7fd79137SRobert Mustacchi endianess, 682*7fd79137SRobert Mustacchi machine, 683*7fd79137SRobert Mustacchi &(relas)[i], 684*7fd79137SRobert Mustacchi target_section, 685*7fd79137SRobert Mustacchi symtab_section); 686*7fd79137SRobert Mustacchi } 687*7fd79137SRobert Mustacchi } 688*7fd79137SRobert Mustacchi return DW_DLV_OK; 689*7fd79137SRobert Mustacchi } 690*7fd79137SRobert Mustacchi 691*7fd79137SRobert Mustacchi 692*7fd79137SRobert Mustacchi static int 693*7fd79137SRobert Mustacchi loop_through_relocations( 694*7fd79137SRobert Mustacchi Dwarf_Debug dbg, 695*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t* obj, 696*7fd79137SRobert Mustacchi struct Dwarf_Section_s *relocatablesec, 697*7fd79137SRobert Mustacchi int *error) 698*7fd79137SRobert Mustacchi { 699*7fd79137SRobert Mustacchi Dwarf_Small *target_section = 0; 700*7fd79137SRobert Mustacchi Dwarf_Small *symtab_section = obj->symtab->dss_data; 701*7fd79137SRobert Mustacchi Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data; 702*7fd79137SRobert Mustacchi Dwarf_Unsigned relocation_section_size = 703*7fd79137SRobert Mustacchi relocatablesec->dss_reloc_size; 704*7fd79137SRobert Mustacchi int ret = DW_DLV_ERROR; 705*7fd79137SRobert Mustacchi struct Dwarf_Elf_Rela *relas = 0; 706*7fd79137SRobert Mustacchi unsigned int nrelas = 0; 707*7fd79137SRobert Mustacchi Dwarf_Small *mspace = 0; 708*7fd79137SRobert Mustacchi 709*7fd79137SRobert Mustacchi ret = get_relocation_entries(obj->is_64bit, 710*7fd79137SRobert Mustacchi obj->endianness, 711*7fd79137SRobert Mustacchi obj->machine, 712*7fd79137SRobert Mustacchi relocation_section, 713*7fd79137SRobert Mustacchi relocation_section_size, 714*7fd79137SRobert Mustacchi &relas, &nrelas, error); 715*7fd79137SRobert Mustacchi if(ret != DW_DLV_OK) { 716*7fd79137SRobert Mustacchi free(relas); 717*7fd79137SRobert Mustacchi return ret; 718*7fd79137SRobert Mustacchi } 719*7fd79137SRobert Mustacchi 720*7fd79137SRobert Mustacchi /* Some systems read Elf in read-only memory via mmap or the like. 721*7fd79137SRobert Mustacchi So the only safe thing is to copy the current data into 722*7fd79137SRobert Mustacchi malloc space and refer to the malloc space instead of the 723*7fd79137SRobert Mustacchi space returned by the elf library */ 724*7fd79137SRobert Mustacchi mspace = malloc(relocatablesec->dss_size); 725*7fd79137SRobert Mustacchi if(!mspace) { 726*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL; 727*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 728*7fd79137SRobert Mustacchi } 729*7fd79137SRobert Mustacchi memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size); 730*7fd79137SRobert Mustacchi relocatablesec->dss_data = mspace; 731*7fd79137SRobert Mustacchi target_section = relocatablesec->dss_data; 732*7fd79137SRobert Mustacchi relocatablesec->dss_data_was_malloc = 1; 733*7fd79137SRobert Mustacchi 734*7fd79137SRobert Mustacchi ret = apply_rela_entries( 735*7fd79137SRobert Mustacchi dbg, 736*7fd79137SRobert Mustacchi obj->is_64bit, 737*7fd79137SRobert Mustacchi obj->endianness, obj->machine, 738*7fd79137SRobert Mustacchi target_section, 739*7fd79137SRobert Mustacchi symtab_section, 740*7fd79137SRobert Mustacchi relas, nrelas, error); 741*7fd79137SRobert Mustacchi 742*7fd79137SRobert Mustacchi free(relas); 743*7fd79137SRobert Mustacchi 744*7fd79137SRobert Mustacchi return ret; 745*7fd79137SRobert Mustacchi } 746*7fd79137SRobert Mustacchi 747*7fd79137SRobert Mustacchi /* 748*7fd79137SRobert Mustacchi Find the section data in dbg and find all the relevant 749*7fd79137SRobert Mustacchi sections. Then do relocations. 750*7fd79137SRobert Mustacchi */ 751*7fd79137SRobert Mustacchi static int 752*7fd79137SRobert Mustacchi dwarf_elf_object_relocate_a_section(void* obj_in, 753*7fd79137SRobert Mustacchi Dwarf_Half section_index, 754*7fd79137SRobert Mustacchi Dwarf_Debug dbg, 755*7fd79137SRobert Mustacchi int* error) 756*7fd79137SRobert Mustacchi { 757*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 758*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 0; 759*7fd79137SRobert Mustacchi struct Dwarf_Section_s * relocatablesec = 0; 760*7fd79137SRobert Mustacchi if (section_index == 0) { 761*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 762*7fd79137SRobert Mustacchi } 763*7fd79137SRobert Mustacchi obj = (dwarf_elf_object_access_internals_t*)obj_in; 764*7fd79137SRobert Mustacchi 765*7fd79137SRobert Mustacchi /* The section to relocate must already be loaded into memory. */ 766*7fd79137SRobert Mustacchi res = find_section_to_relocate(dbg, section_index,&relocatablesec,error); 767*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) { 768*7fd79137SRobert Mustacchi return res; 769*7fd79137SRobert Mustacchi } 770*7fd79137SRobert Mustacchi 771*7fd79137SRobert Mustacchi /* Sun and possibly others do not always set sh_link in .debug_* sections. 772*7fd79137SRobert Mustacchi So we cannot do full consistency checks. */ 773*7fd79137SRobert Mustacchi if(relocatablesec->dss_reloc_index == 0 ) { 774*7fd79137SRobert Mustacchi /* Something is wrong. */ 775*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; 776*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 777*7fd79137SRobert Mustacchi } 778*7fd79137SRobert Mustacchi /* Now load the relocations themselves. */ 779*7fd79137SRobert Mustacchi res = dwarf_elf_object_access_load_section(obj_in, 780*7fd79137SRobert Mustacchi relocatablesec->dss_reloc_index, 781*7fd79137SRobert Mustacchi &relocatablesec->dss_reloc_data, error); 782*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) { 783*7fd79137SRobert Mustacchi return res; 784*7fd79137SRobert Mustacchi } 785*7fd79137SRobert Mustacchi 786*7fd79137SRobert Mustacchi /* Now get the symtab. */ 787*7fd79137SRobert Mustacchi if (!obj->symtab) { 788*7fd79137SRobert Mustacchi obj->symtab = &dbg->de_elf_symtab; 789*7fd79137SRobert Mustacchi obj->strtab = &dbg->de_elf_strtab; 790*7fd79137SRobert Mustacchi } 791*7fd79137SRobert Mustacchi if( obj->symtab->dss_index != relocatablesec->dss_reloc_link) { 792*7fd79137SRobert Mustacchi /* Something is wrong. */ 793*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; 794*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 795*7fd79137SRobert Mustacchi } 796*7fd79137SRobert Mustacchi if( obj->strtab->dss_index != obj->symtab->dss_link) { 797*7fd79137SRobert Mustacchi /* Something is wrong. */ 798*7fd79137SRobert Mustacchi *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX; 799*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 800*7fd79137SRobert Mustacchi } 801*7fd79137SRobert Mustacchi if(!obj->symtab->dss_data) { 802*7fd79137SRobert Mustacchi /* Now load the symtab */ 803*7fd79137SRobert Mustacchi res = dwarf_elf_object_access_load_section(obj_in, 804*7fd79137SRobert Mustacchi obj->symtab->dss_index, 805*7fd79137SRobert Mustacchi &obj->symtab->dss_data, error); 806*7fd79137SRobert Mustacchi if(res != DW_DLV_OK) { 807*7fd79137SRobert Mustacchi return res; 808*7fd79137SRobert Mustacchi } 809*7fd79137SRobert Mustacchi } 810*7fd79137SRobert Mustacchi if(! obj->strtab->dss_data) { 811*7fd79137SRobert Mustacchi /* Now load the strtab */ 812*7fd79137SRobert Mustacchi res = dwarf_elf_object_access_load_section(obj_in, 813*7fd79137SRobert Mustacchi obj->strtab->dss_index, 814*7fd79137SRobert Mustacchi &obj->strtab->dss_data,error); 815*7fd79137SRobert Mustacchi if(res != DW_DLV_OK){ 816*7fd79137SRobert Mustacchi return res; 817*7fd79137SRobert Mustacchi } 818*7fd79137SRobert Mustacchi } 819*7fd79137SRobert Mustacchi 820*7fd79137SRobert Mustacchi /* We have all the data we need in memory. */ 821*7fd79137SRobert Mustacchi res = loop_through_relocations(dbg,obj,relocatablesec,error); 822*7fd79137SRobert Mustacchi 823*7fd79137SRobert Mustacchi return res; 824*7fd79137SRobert Mustacchi } 825*7fd79137SRobert Mustacchi 826*7fd79137SRobert Mustacchi /* 827*7fd79137SRobert Mustacchi dwarf_elf_object_access_load_section 828*7fd79137SRobert Mustacchi */ 829*7fd79137SRobert Mustacchi static int 830*7fd79137SRobert Mustacchi dwarf_elf_object_access_load_section(void* obj_in, 831*7fd79137SRobert Mustacchi Dwarf_Half section_index, 832*7fd79137SRobert Mustacchi Dwarf_Small** section_data, 833*7fd79137SRobert Mustacchi int* error) 834*7fd79137SRobert Mustacchi { 835*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 836*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj_in; 837*7fd79137SRobert Mustacchi if (section_index == 0) { 838*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 839*7fd79137SRobert Mustacchi } 840*7fd79137SRobert Mustacchi 841*7fd79137SRobert Mustacchi { 842*7fd79137SRobert Mustacchi Elf_Scn *scn = 0; 843*7fd79137SRobert Mustacchi Elf_Data *data = 0; 844*7fd79137SRobert Mustacchi 845*7fd79137SRobert Mustacchi scn = elf_getscn(obj->elf, section_index); 846*7fd79137SRobert Mustacchi if (scn == NULL) { 847*7fd79137SRobert Mustacchi *error = DW_DLE_MDE; 848*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 849*7fd79137SRobert Mustacchi } 850*7fd79137SRobert Mustacchi 851*7fd79137SRobert Mustacchi /* 852*7fd79137SRobert Mustacchi When using libelf as a producer, section data may be stored 853*7fd79137SRobert Mustacchi in multiple buffers. In libdwarf however, we only use libelf 854*7fd79137SRobert Mustacchi as a consumer (there is a dwarf producer API, but it doesn't 855*7fd79137SRobert Mustacchi use libelf). Because of this, this single call to elf_getdata 856*7fd79137SRobert Mustacchi will retrieve the entire section in a single contiguous 857*7fd79137SRobert Mustacchi buffer. */ 858*7fd79137SRobert Mustacchi data = elf_getdata(scn, NULL); 859*7fd79137SRobert Mustacchi if (data == NULL) { 860*7fd79137SRobert Mustacchi *error = DW_DLE_MDE; 861*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 862*7fd79137SRobert Mustacchi } 863*7fd79137SRobert Mustacchi *section_data = data->d_buf; 864*7fd79137SRobert Mustacchi } 865*7fd79137SRobert Mustacchi return DW_DLV_OK; 866*7fd79137SRobert Mustacchi } 867*7fd79137SRobert Mustacchi 868*7fd79137SRobert Mustacchi 869*7fd79137SRobert Mustacchi /* dwarf_elf_access method table. */ 870*7fd79137SRobert Mustacchi static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods = 871*7fd79137SRobert Mustacchi { 872*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section_info, 873*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_byte_order, 874*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_length_size, 875*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_pointer_size, 876*7fd79137SRobert Mustacchi dwarf_elf_object_access_get_section_count, 877*7fd79137SRobert Mustacchi dwarf_elf_object_access_load_section, 878*7fd79137SRobert Mustacchi dwarf_elf_object_relocate_a_section 879*7fd79137SRobert Mustacchi }; 880*7fd79137SRobert Mustacchi 881*7fd79137SRobert Mustacchi 882*7fd79137SRobert Mustacchi /* 883*7fd79137SRobert Mustacchi Interface for the ELF object file implementation. 884*7fd79137SRobert Mustacchi */ 885*7fd79137SRobert Mustacchi int 886*7fd79137SRobert Mustacchi dwarf_elf_object_access_init(dwarf_elf_handle elf, 887*7fd79137SRobert Mustacchi int libdwarf_owns_elf, 888*7fd79137SRobert Mustacchi Dwarf_Obj_Access_Interface** ret_obj, 889*7fd79137SRobert Mustacchi int *err) 890*7fd79137SRobert Mustacchi { 891*7fd79137SRobert Mustacchi int res = 0; 892*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t *internals = 0; 893*7fd79137SRobert Mustacchi Dwarf_Obj_Access_Interface *intfc = 0; 894*7fd79137SRobert Mustacchi 895*7fd79137SRobert Mustacchi internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); 896*7fd79137SRobert Mustacchi if(!internals) { 897*7fd79137SRobert Mustacchi /* Impossible case, we hope. Give up. */ 898*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 899*7fd79137SRobert Mustacchi } 900*7fd79137SRobert Mustacchi memset(internals,0,sizeof(*internals)); 901*7fd79137SRobert Mustacchi res = dwarf_elf_object_access_internals_init(internals, elf, err); 902*7fd79137SRobert Mustacchi if(res != DW_DLV_OK){ 903*7fd79137SRobert Mustacchi free(internals); 904*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 905*7fd79137SRobert Mustacchi } 906*7fd79137SRobert Mustacchi internals->libdwarf_owns_elf = libdwarf_owns_elf; 907*7fd79137SRobert Mustacchi 908*7fd79137SRobert Mustacchi intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); 909*7fd79137SRobert Mustacchi if(!intfc) { 910*7fd79137SRobert Mustacchi /* Impossible case, we hope. Give up. */ 911*7fd79137SRobert Mustacchi free(internals); 912*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 913*7fd79137SRobert Mustacchi } 914*7fd79137SRobert Mustacchi /* Initialize the interface struct */ 915*7fd79137SRobert Mustacchi intfc->object = internals; 916*7fd79137SRobert Mustacchi intfc->methods = &dwarf_elf_object_access_methods; 917*7fd79137SRobert Mustacchi 918*7fd79137SRobert Mustacchi *ret_obj = intfc; 919*7fd79137SRobert Mustacchi return DW_DLV_OK; 920*7fd79137SRobert Mustacchi } 921*7fd79137SRobert Mustacchi 922*7fd79137SRobert Mustacchi 923*7fd79137SRobert Mustacchi 924*7fd79137SRobert Mustacchi /* 925*7fd79137SRobert Mustacchi Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init. 926*7fd79137SRobert Mustacchi */ 927*7fd79137SRobert Mustacchi void 928*7fd79137SRobert Mustacchi dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj) 929*7fd79137SRobert Mustacchi { 930*7fd79137SRobert Mustacchi if(!obj) { 931*7fd79137SRobert Mustacchi return; 932*7fd79137SRobert Mustacchi } 933*7fd79137SRobert Mustacchi if(obj->object) { 934*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t *internals = 935*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t *)obj->object; 936*7fd79137SRobert Mustacchi if(internals->libdwarf_owns_elf){ 937*7fd79137SRobert Mustacchi elf_end(internals->elf); 938*7fd79137SRobert Mustacchi } 939*7fd79137SRobert Mustacchi } 940*7fd79137SRobert Mustacchi free(obj->object); 941*7fd79137SRobert Mustacchi free(obj); 942*7fd79137SRobert Mustacchi } 943*7fd79137SRobert Mustacchi 944*7fd79137SRobert Mustacchi /* 945*7fd79137SRobert Mustacchi This function returns the Elf * pointer 946*7fd79137SRobert Mustacchi associated with a Dwarf_Debug. 947*7fd79137SRobert Mustacchi 948*7fd79137SRobert Mustacchi This function only makes sense if ELF is implied. 949*7fd79137SRobert Mustacchi */ 950*7fd79137SRobert Mustacchi int 951*7fd79137SRobert Mustacchi dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, 952*7fd79137SRobert Mustacchi Dwarf_Error * error) 953*7fd79137SRobert Mustacchi { 954*7fd79137SRobert Mustacchi struct Dwarf_Obj_Access_Interface_s * obj = 0; 955*7fd79137SRobert Mustacchi if (dbg == NULL) { 956*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 957*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 958*7fd79137SRobert Mustacchi } 959*7fd79137SRobert Mustacchi 960*7fd79137SRobert Mustacchi obj = dbg->de_obj_file; 961*7fd79137SRobert Mustacchi if(obj) { 962*7fd79137SRobert Mustacchi dwarf_elf_object_access_internals_t *internals = 963*7fd79137SRobert Mustacchi (dwarf_elf_object_access_internals_t*)obj->object; 964*7fd79137SRobert Mustacchi if(internals->elf == NULL) { 965*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FNO); 966*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 967*7fd79137SRobert Mustacchi } 968*7fd79137SRobert Mustacchi *elf = internals->elf; 969*7fd79137SRobert Mustacchi return DW_DLV_OK; 970*7fd79137SRobert Mustacchi 971*7fd79137SRobert Mustacchi } 972*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FNO); 973*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 974*7fd79137SRobert Mustacchi } 975*7fd79137SRobert Mustacchi 976*7fd79137SRobert Mustacchi 977