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