xref: /titanic_50/usr/src/lib/libdwarf/common/dwarf_elf_access.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
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