1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright (c) 2019, David Anderson
3*4d9fdb46SRobert Mustacchi All rights reserved.
4*4d9fdb46SRobert Mustacchi cc
5*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
6*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
7*4d9fdb46SRobert Mustacchi following conditions are met:
8*4d9fdb46SRobert Mustacchi
9*4d9fdb46SRobert Mustacchi Redistributions of source code must retain the above
10*4d9fdb46SRobert Mustacchi copyright notice, this list of conditions and the following
11*4d9fdb46SRobert Mustacchi disclaimer.
12*4d9fdb46SRobert Mustacchi
13*4d9fdb46SRobert Mustacchi Redistributions in binary form must reproduce the above
14*4d9fdb46SRobert Mustacchi copyright notice, this list of conditions and the following
15*4d9fdb46SRobert Mustacchi disclaimer in the documentation and/or other materials
16*4d9fdb46SRobert Mustacchi provided with the distribution.
17*4d9fdb46SRobert Mustacchi
18*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4d9fdb46SRobert Mustacchi */
32*4d9fdb46SRobert Mustacchi
33*4d9fdb46SRobert Mustacchi /* This file reads the parts of an Elf
34*4d9fdb46SRobert Mustacchi file appropriate to reading DWARF debugging data.
35*4d9fdb46SRobert Mustacchi Overview:
36*4d9fdb46SRobert Mustacchi _dwarf_elf_nlsetup() Does all elf setup.
37*4d9fdb46SRobert Mustacchi calls _dwarf_elf_access_init()
38*4d9fdb46SRobert Mustacchi calls _dwarf_elf_object_access_internals_init()
39*4d9fdb46SRobert Mustacchi Creates internals record 'M',
40*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t
41*4d9fdb46SRobert Mustacchi Sets flags/data in internals record
42*4d9fdb46SRobert Mustacchi Loads elf object data needed later.
43*4d9fdb46SRobert Mustacchi Sets methods struct to access elf object.
44*4d9fdb46SRobert Mustacchi calls _dwarf_object_init_b() Creates Dwarf_Debug, independent
45*4d9fdb46SRobert Mustacchi of any elf code.
46*4d9fdb46SRobert Mustacchi Sets internals record into dbg.
47*4d9fdb46SRobert Mustacchi ----------------------
48*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(). This frees
49*4d9fdb46SRobert Mustacchi the elf internals record created in
50*4d9fdb46SRobert Mustacchi _dwarf_elf_object_access_internals_init()
51*4d9fdb46SRobert Mustacchi in case of errors during setup or when
52*4d9fdb46SRobert Mustacchi dwarf_finish() is called. Works safely for
53*4d9fdb46SRobert Mustacchi partially or fully set-up elf internals record.
54*4d9fdb46SRobert Mustacchi
55*4d9fdb46SRobert Mustacchi Other than in _dwarf_elf_nlsetup() the elf code
56*4d9fdb46SRobert Mustacchi knows nothing about Dwarf_Debug, and the rest of
57*4d9fdb46SRobert Mustacchi libdwarf knows nothing about the content of the
58*4d9fdb46SRobert Mustacchi object-type-specific (for Elf here)
59*4d9fdb46SRobert Mustacchi internals record.
60*4d9fdb46SRobert Mustacchi */
61*4d9fdb46SRobert Mustacchi
62*4d9fdb46SRobert Mustacchi #include "config.h"
63*4d9fdb46SRobert Mustacchi #include <stdio.h>
64*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
65*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
66*4d9fdb46SRobert Mustacchi #include <malloc.h>
67*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
68*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
69*4d9fdb46SRobert Mustacchi #include <stdlib.h>
70*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
71*4d9fdb46SRobert Mustacchi #include <string.h>
72*4d9fdb46SRobert Mustacchi #include <stdlib.h>
73*4d9fdb46SRobert Mustacchi #include <sys/types.h> /* open() */
74*4d9fdb46SRobert Mustacchi #include <sys/stat.h> /* open() */
75*4d9fdb46SRobert Mustacchi #include <fcntl.h> /* open() */
76*4d9fdb46SRobert Mustacchi #include <time.h>
77*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNISTD_H
78*4d9fdb46SRobert Mustacchi #include <unistd.h> /* lseek read close */
79*4d9fdb46SRobert Mustacchi #elif defined(_WIN32) && defined(_MSC_VER)
80*4d9fdb46SRobert Mustacchi #include <io.h>
81*4d9fdb46SRobert Mustacchi #endif /* HAVE_UNISTD_H */
82*4d9fdb46SRobert Mustacchi
83*4d9fdb46SRobert Mustacchi /* Windows specific header files */
84*4d9fdb46SRobert Mustacchi #if defined(_WIN32) && defined(HAVE_STDAFX_H)
85*4d9fdb46SRobert Mustacchi #include "stdafx.h"
86*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDAFX_H */
87*4d9fdb46SRobert Mustacchi
88*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
89*4d9fdb46SRobert Mustacchi #include "libdwarfdefs.h"
90*4d9fdb46SRobert Mustacchi #include "dwarf_base_types.h"
91*4d9fdb46SRobert Mustacchi #include "dwarf_opaque.h"
92*4d9fdb46SRobert Mustacchi #include "dwarf_error.h" /* for _dwarf_error() declaration */
93*4d9fdb46SRobert Mustacchi #include "dwarf_reading.h"
94*4d9fdb46SRobert Mustacchi #include "memcpy_swap.h"
95*4d9fdb46SRobert Mustacchi #include "dwarf_object_read_common.h"
96*4d9fdb46SRobert Mustacchi #include "dwarf_object_detector.h"
97*4d9fdb46SRobert Mustacchi #include "dwarf_elfstructs.h"
98*4d9fdb46SRobert Mustacchi #include "dwarf_elf_defines.h"
99*4d9fdb46SRobert Mustacchi #include "dwarf_elf_rel_detector.h"
100*4d9fdb46SRobert Mustacchi #include "dwarf_elfread.h"
101*4d9fdb46SRobert Mustacchi
102*4d9fdb46SRobert Mustacchi
103*4d9fdb46SRobert Mustacchi #ifndef TYP
104*4d9fdb46SRobert Mustacchi #define TYP(n,l) char n[l]
105*4d9fdb46SRobert Mustacchi #endif /* TYPE */
106*4d9fdb46SRobert Mustacchi
107*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
108*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_SAFE(dbg,dest, source, length) \
109*4d9fdb46SRobert Mustacchi do { \
110*4d9fdb46SRobert Mustacchi Dwarf_Unsigned _ltmp = 0; \
111*4d9fdb46SRobert Mustacchi dbg->de_copy_word( (((char *)(&_ltmp)) + \
112*4d9fdb46SRobert Mustacchi sizeof(_ltmp) - length),source, length); \
113*4d9fdb46SRobert Mustacchi dest = _ltmp; \
114*4d9fdb46SRobert Mustacchi } while (0)
115*4d9fdb46SRobert Mustacchi
116*4d9fdb46SRobert Mustacchi #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \
117*4d9fdb46SRobert Mustacchi { \
118*4d9fdb46SRobert Mustacchi dbg->de_copy_word(dest, \
119*4d9fdb46SRobert Mustacchi ((char *)source) +srclength-len_out, \
120*4d9fdb46SRobert Mustacchi len_out) ; \
121*4d9fdb46SRobert Mustacchi }
122*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
123*4d9fdb46SRobert Mustacchi #define READ_UNALIGNED_SAFE(dbg,dest, source, srclength) \
124*4d9fdb46SRobert Mustacchi do { \
125*4d9fdb46SRobert Mustacchi Dwarf_Unsigned _ltmp = 0; \
126*4d9fdb46SRobert Mustacchi dbg->de_copy_word( (char *)(&_ltmp), \
127*4d9fdb46SRobert Mustacchi source, srclength) ; \
128*4d9fdb46SRobert Mustacchi dest = _ltmp; \
129*4d9fdb46SRobert Mustacchi } while (0)
130*4d9fdb46SRobert Mustacchi
131*4d9fdb46SRobert Mustacchi #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \
132*4d9fdb46SRobert Mustacchi { \
133*4d9fdb46SRobert Mustacchi dbg->de_copy_word( (dest) , \
134*4d9fdb46SRobert Mustacchi ((char *)source) , \
135*4d9fdb46SRobert Mustacchi len_out) ; \
136*4d9fdb46SRobert Mustacchi }
137*4d9fdb46SRobert Mustacchi #endif /* *-ENDIAN */
138*4d9fdb46SRobert Mustacchi
139*4d9fdb46SRobert Mustacchi
140*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
141*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s) \
142*4d9fdb46SRobert Mustacchi do { \
143*4d9fdb46SRobert Mustacchi unsigned tbyte = sizeof(t) - sizeof(s); \
144*4d9fdb46SRobert Mustacchi t = 0; \
145*4d9fdb46SRobert Mustacchi func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \
146*4d9fdb46SRobert Mustacchi } while (0)
147*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
148*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s) \
149*4d9fdb46SRobert Mustacchi do { \
150*4d9fdb46SRobert Mustacchi t = 0; \
151*4d9fdb46SRobert Mustacchi func(&t,&s[0],sizeof(s)); \
152*4d9fdb46SRobert Mustacchi } while (0)
153*4d9fdb46SRobert Mustacchi #endif /* end LITTLE- BIG-ENDIAN */
154*4d9fdb46SRobert Mustacchi
155*4d9fdb46SRobert Mustacchi
156*4d9fdb46SRobert Mustacchi static int
157*4d9fdb46SRobert Mustacchi _dwarf_elf_object_access_init(
158*4d9fdb46SRobert Mustacchi int fd,
159*4d9fdb46SRobert Mustacchi unsigned ftype,
160*4d9fdb46SRobert Mustacchi unsigned endian,
161*4d9fdb46SRobert Mustacchi unsigned offsetsize,
162*4d9fdb46SRobert Mustacchi size_t filesize,
163*4d9fdb46SRobert Mustacchi Dwarf_Unsigned access,
164*4d9fdb46SRobert Mustacchi Dwarf_Obj_Access_Interface **binary_interface,
165*4d9fdb46SRobert Mustacchi int *localerrnum);
166*4d9fdb46SRobert Mustacchi
167*4d9fdb46SRobert Mustacchi
elf_get_nolibelf_byte_order(void * obj)168*4d9fdb46SRobert Mustacchi static Dwarf_Endianness elf_get_nolibelf_byte_order (void *obj)
169*4d9fdb46SRobert Mustacchi {
170*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
171*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
172*4d9fdb46SRobert Mustacchi return elf->f_endian;
173*4d9fdb46SRobert Mustacchi }
174*4d9fdb46SRobert Mustacchi
175*4d9fdb46SRobert Mustacchi
elf_get_nolibelf_length_size(void * obj)176*4d9fdb46SRobert Mustacchi static Dwarf_Small elf_get_nolibelf_length_size (void *obj)
177*4d9fdb46SRobert Mustacchi {
178*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
179*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
180*4d9fdb46SRobert Mustacchi return elf->f_offsetsize/8;
181*4d9fdb46SRobert Mustacchi }
182*4d9fdb46SRobert Mustacchi
183*4d9fdb46SRobert Mustacchi
elf_get_nolibelf_pointer_size(void * obj)184*4d9fdb46SRobert Mustacchi static Dwarf_Small elf_get_nolibelf_pointer_size (void *obj)
185*4d9fdb46SRobert Mustacchi {
186*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
187*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
188*4d9fdb46SRobert Mustacchi return elf->f_pointersize/8;
189*4d9fdb46SRobert Mustacchi }
190*4d9fdb46SRobert Mustacchi
191*4d9fdb46SRobert Mustacchi
elf_get_nolibelf_section_count(void * obj)192*4d9fdb46SRobert Mustacchi static Dwarf_Unsigned elf_get_nolibelf_section_count (void *obj)
193*4d9fdb46SRobert Mustacchi {
194*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
195*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
196*4d9fdb46SRobert Mustacchi return elf->f_loc_shdr.g_count;
197*4d9fdb46SRobert Mustacchi }
198*4d9fdb46SRobert Mustacchi
elf_get_nolibelf_section_info(void * obj,Dwarf_Half section_index,Dwarf_Obj_Access_Section * return_section,UNUSEDARG int * error)199*4d9fdb46SRobert Mustacchi static int elf_get_nolibelf_section_info (void *obj,
200*4d9fdb46SRobert Mustacchi Dwarf_Half section_index,
201*4d9fdb46SRobert Mustacchi Dwarf_Obj_Access_Section *return_section,
202*4d9fdb46SRobert Mustacchi UNUSEDARG int *error)
203*4d9fdb46SRobert Mustacchi {
204*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
205*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
206*4d9fdb46SRobert Mustacchi
207*4d9fdb46SRobert Mustacchi
208*4d9fdb46SRobert Mustacchi if (section_index < elf->f_loc_shdr.g_count) {
209*4d9fdb46SRobert Mustacchi struct generic_shdr *sp = 0;
210*4d9fdb46SRobert Mustacchi
211*4d9fdb46SRobert Mustacchi sp = elf->f_shdr + section_index;
212*4d9fdb46SRobert Mustacchi return_section->addr = sp->gh_addr;
213*4d9fdb46SRobert Mustacchi return_section->type = sp->gh_type;
214*4d9fdb46SRobert Mustacchi return_section->size = sp->gh_size;
215*4d9fdb46SRobert Mustacchi return_section->name = sp->gh_namestring;
216*4d9fdb46SRobert Mustacchi return_section->link = sp->gh_link;
217*4d9fdb46SRobert Mustacchi return_section->info = sp->gh_info;
218*4d9fdb46SRobert Mustacchi return_section->entrysize = sp->gh_entsize;
219*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
220*4d9fdb46SRobert Mustacchi }
221*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
222*4d9fdb46SRobert Mustacchi }
223*4d9fdb46SRobert Mustacchi
224*4d9fdb46SRobert Mustacchi static int
elf_load_nolibelf_section(void * obj,Dwarf_Half section_index,Dwarf_Small ** return_data,int * error)225*4d9fdb46SRobert Mustacchi elf_load_nolibelf_section (void *obj, Dwarf_Half section_index,
226*4d9fdb46SRobert Mustacchi Dwarf_Small **return_data, int *error)
227*4d9fdb46SRobert Mustacchi {
228*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *elf =
229*4d9fdb46SRobert Mustacchi (dwarf_elf_object_access_internals_t*)(obj);
230*4d9fdb46SRobert Mustacchi
231*4d9fdb46SRobert Mustacchi if (0 < section_index &&
232*4d9fdb46SRobert Mustacchi section_index < elf->f_loc_shdr.g_count) {
233*4d9fdb46SRobert Mustacchi int res = 0;
234*4d9fdb46SRobert Mustacchi
235*4d9fdb46SRobert Mustacchi struct generic_shdr *sp =
236*4d9fdb46SRobert Mustacchi elf->f_shdr + section_index;
237*4d9fdb46SRobert Mustacchi if (sp->gh_content) {
238*4d9fdb46SRobert Mustacchi *return_data = (Dwarf_Small *)sp->gh_content;
239*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
240*4d9fdb46SRobert Mustacchi }
241*4d9fdb46SRobert Mustacchi if (!sp->gh_size) {
242*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
243*4d9fdb46SRobert Mustacchi }
244*4d9fdb46SRobert Mustacchi if ((sp->gh_size + sp->gh_offset) >
245*4d9fdb46SRobert Mustacchi elf->f_filesize) {
246*4d9fdb46SRobert Mustacchi *error = DW_DLE_ELF_SECTION_ERROR;
247*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
248*4d9fdb46SRobert Mustacchi }
249*4d9fdb46SRobert Mustacchi
250*4d9fdb46SRobert Mustacchi sp->gh_content = malloc((size_t)sp->gh_size);
251*4d9fdb46SRobert Mustacchi if(!sp->gh_content) {
252*4d9fdb46SRobert Mustacchi *error = DW_DLE_ALLOC_FAIL;
253*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
254*4d9fdb46SRobert Mustacchi }
255*4d9fdb46SRobert Mustacchi res = RRMOA(elf->f_fd,
256*4d9fdb46SRobert Mustacchi sp->gh_content, (off_t)sp->gh_offset,
257*4d9fdb46SRobert Mustacchi (size_t)sp->gh_size, (off_t)elf->f_filesize, error);
258*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
259*4d9fdb46SRobert Mustacchi free(sp->gh_content);
260*4d9fdb46SRobert Mustacchi sp->gh_content = 0;
261*4d9fdb46SRobert Mustacchi return res;
262*4d9fdb46SRobert Mustacchi }
263*4d9fdb46SRobert Mustacchi *return_data = (Dwarf_Small *)sp->gh_content;
264*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
265*4d9fdb46SRobert Mustacchi }
266*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
267*4d9fdb46SRobert Mustacchi }
268*4d9fdb46SRobert Mustacchi
269*4d9fdb46SRobert Mustacchi static int
_dwarf_get_elf_flags_func_nl(void * obj_in,Dwarf_Half section_index,Dwarf_Unsigned * flags_out,Dwarf_Unsigned * addralign_out,int * error)270*4d9fdb46SRobert Mustacchi _dwarf_get_elf_flags_func_nl(
271*4d9fdb46SRobert Mustacchi void* obj_in,
272*4d9fdb46SRobert Mustacchi Dwarf_Half section_index,
273*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *flags_out,
274*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *addralign_out,
275*4d9fdb46SRobert Mustacchi int *error)
276*4d9fdb46SRobert Mustacchi {
277*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *ep = 0;
278*4d9fdb46SRobert Mustacchi struct generic_shdr *shp = 0;
279*4d9fdb46SRobert Mustacchi
280*4d9fdb46SRobert Mustacchi ep = (dwarf_elf_object_access_internals_t *)obj_in;
281*4d9fdb46SRobert Mustacchi if (section_index == 0) {
282*4d9fdb46SRobert Mustacchi /* Nothing to do. Empty section */
283*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
284*4d9fdb46SRobert Mustacchi }
285*4d9fdb46SRobert Mustacchi if (section_index >= ep->f_loc_shdr.g_count) {
286*4d9fdb46SRobert Mustacchi *error = DW_DLE_SECTION_INDEX_BAD;
287*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
288*4d9fdb46SRobert Mustacchi }
289*4d9fdb46SRobert Mustacchi shp = ep->f_shdr + section_index;
290*4d9fdb46SRobert Mustacchi *flags_out = shp->gh_flags;
291*4d9fdb46SRobert Mustacchi *addralign_out = shp->gh_addralign;
292*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
293*4d9fdb46SRobert Mustacchi }
294*4d9fdb46SRobert Mustacchi
295*4d9fdb46SRobert Mustacchi
296*4d9fdb46SRobert Mustacchi #define MATCH_REL_SEC(i_,s_,r_) \
297*4d9fdb46SRobert Mustacchi if (i_ == s_.dss_index) { \
298*4d9fdb46SRobert Mustacchi *r_ = &s_; \
299*4d9fdb46SRobert Mustacchi return DW_DLV_OK; \
300*4d9fdb46SRobert Mustacchi }
301*4d9fdb46SRobert Mustacchi
302*4d9fdb46SRobert Mustacchi static int
find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,struct Dwarf_Section_s ** relocatablesec,int * error)303*4d9fdb46SRobert Mustacchi find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
304*4d9fdb46SRobert Mustacchi struct Dwarf_Section_s **relocatablesec, int *error)
305*4d9fdb46SRobert Mustacchi {
306*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
307*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
308*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
309*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
310*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
311*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
312*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
313*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
314*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
315*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
316*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
317*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
318*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
319*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
320*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
321*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec);
322*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec);
323*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec);
324*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec);
325*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
326*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec);
327*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec);
328*4d9fdb46SRobert Mustacchi MATCH_REL_SEC(section_index,dbg->de_debug_addr,relocatablesec);
329*4d9fdb46SRobert Mustacchi /* dbg-> de_debug_tu_index,reloctablesec); */
330*4d9fdb46SRobert Mustacchi /* dbg-> de_debug_cu_index,reloctablesec); */
331*4d9fdb46SRobert Mustacchi /* dbg-> de_debug_gdbindex,reloctablesec); */
332*4d9fdb46SRobert Mustacchi /* dbg-> de_debug_str,syms); */
333*4d9fdb46SRobert Mustacchi /* de_elf_symtab,syms); */
334*4d9fdb46SRobert Mustacchi /* de_elf_strtab,syms); */
335*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_MISMATCH;
336*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
337*4d9fdb46SRobert Mustacchi }
338*4d9fdb46SRobert Mustacchi
339*4d9fdb46SRobert Mustacchi
340*4d9fdb46SRobert Mustacchi /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR.
341*4d9fdb46SRobert Mustacchi The caller may decide to ignore the errors or report them. */
342*4d9fdb46SRobert Mustacchi static int
update_entry(Dwarf_Debug dbg,dwarf_elf_object_access_internals_t * obj,struct generic_rela * rela,Dwarf_Small * target_section,Dwarf_Unsigned target_section_size,int * error)343*4d9fdb46SRobert Mustacchi update_entry(Dwarf_Debug dbg,
344*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t*obj,
345*4d9fdb46SRobert Mustacchi struct generic_rela *rela,
346*4d9fdb46SRobert Mustacchi Dwarf_Small *target_section,
347*4d9fdb46SRobert Mustacchi Dwarf_Unsigned target_section_size,
348*4d9fdb46SRobert Mustacchi int *error)
349*4d9fdb46SRobert Mustacchi {
350*4d9fdb46SRobert Mustacchi unsigned int type = 0;
351*4d9fdb46SRobert Mustacchi unsigned int sym_idx = 0;
352*4d9fdb46SRobert Mustacchi Dwarf_Unsigned offset = 0;
353*4d9fdb46SRobert Mustacchi Dwarf_Signed addend = 0;
354*4d9fdb46SRobert Mustacchi Dwarf_Unsigned reloc_size = 0;
355*4d9fdb46SRobert Mustacchi Dwarf_Half machine = obj->f_machine;
356*4d9fdb46SRobert Mustacchi struct generic_symentry *symp = 0;
357*4d9fdb46SRobert Mustacchi int is_rela = rela->gr_is_rela;
358*4d9fdb46SRobert Mustacchi
359*4d9fdb46SRobert Mustacchi offset = rela->gr_offset;
360*4d9fdb46SRobert Mustacchi addend = rela->gr_addend;
361*4d9fdb46SRobert Mustacchi type = (unsigned int)rela->gr_type;
362*4d9fdb46SRobert Mustacchi sym_idx = (unsigned int)rela->gr_sym;
363*4d9fdb46SRobert Mustacchi if (sym_idx >= obj->f_loc_symtab.g_count) {
364*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD;
365*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
366*4d9fdb46SRobert Mustacchi }
367*4d9fdb46SRobert Mustacchi symp = obj->f_symtab + sym_idx;
368*4d9fdb46SRobert Mustacchi if (offset >= target_section_size) {
369*4d9fdb46SRobert Mustacchi /* If offset really big, any add will overflow.
370*4d9fdb46SRobert Mustacchi So lets stop early if offset is corrupt. */
371*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_INVALID;
372*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
373*4d9fdb46SRobert Mustacchi }
374*4d9fdb46SRobert Mustacchi
375*4d9fdb46SRobert Mustacchi /* Determine relocation size */
376*4d9fdb46SRobert Mustacchi if (_dwarf_is_32bit_abs_reloc(type, machine)) {
377*4d9fdb46SRobert Mustacchi reloc_size = 4;
378*4d9fdb46SRobert Mustacchi } else if (_dwarf_is_64bit_abs_reloc(type, machine)) {
379*4d9fdb46SRobert Mustacchi reloc_size = 8;
380*4d9fdb46SRobert Mustacchi } else {
381*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN;
382*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
383*4d9fdb46SRobert Mustacchi }
384*4d9fdb46SRobert Mustacchi if ( (offset + reloc_size) < offset) {
385*4d9fdb46SRobert Mustacchi /* Another check for overflow. */
386*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_INVALID;
387*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
388*4d9fdb46SRobert Mustacchi }
389*4d9fdb46SRobert Mustacchi if ( (offset + reloc_size) > target_section_size) {
390*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_INVALID;
391*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
392*4d9fdb46SRobert Mustacchi }
393*4d9fdb46SRobert Mustacchi /* Assuming we do not need to do a READ_UNALIGNED here
394*4d9fdb46SRobert Mustacchi at target_section + offset and add its value to
395*4d9fdb46SRobert Mustacchi outval. Some ABIs say no read (for example MIPS),
396*4d9fdb46SRobert Mustacchi but if some do then which ones? */
397*4d9fdb46SRobert Mustacchi { /* .rel. (addend is 0), or .rela. */
398*4d9fdb46SRobert Mustacchi Dwarf_Small *targ = target_section+offset;
399*4d9fdb46SRobert Mustacchi Dwarf_Unsigned presentval = 0;
400*4d9fdb46SRobert Mustacchi Dwarf_Unsigned outval = 0;
401*4d9fdb46SRobert Mustacchi /* See also: READ_UNALIGNED_SAFE in
402*4d9fdb46SRobert Mustacchi dwarf_elf_access.c */
403*4d9fdb46SRobert Mustacchi
404*4d9fdb46SRobert Mustacchi if (!is_rela) {
405*4d9fdb46SRobert Mustacchi READ_UNALIGNED_SAFE(dbg,presentval,
406*4d9fdb46SRobert Mustacchi targ,reloc_size);
407*4d9fdb46SRobert Mustacchi }
408*4d9fdb46SRobert Mustacchi /* There is no addend in .rel.
409*4d9fdb46SRobert Mustacchi Normally presentval is correct
410*4d9fdb46SRobert Mustacchi and st_value will be zero.
411*4d9fdb46SRobert Mustacchi But a few compilers have
412*4d9fdb46SRobert Mustacchi presentval zero and st_value set. */
413*4d9fdb46SRobert Mustacchi outval = presentval + symp->gs_value + addend;
414*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED_LOCAL(dbg,targ,
415*4d9fdb46SRobert Mustacchi &outval,sizeof(outval),reloc_size);
416*4d9fdb46SRobert Mustacchi }
417*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
418*4d9fdb46SRobert Mustacchi }
419*4d9fdb46SRobert Mustacchi
420*4d9fdb46SRobert Mustacchi
421*4d9fdb46SRobert Mustacchi
422*4d9fdb46SRobert Mustacchi /* Somewhat arbitrarily, we attempt to apply all the
423*4d9fdb46SRobert Mustacchi relocations we can
424*4d9fdb46SRobert Mustacchi and still notify the caller of at least one error if we found
425*4d9fdb46SRobert Mustacchi any errors. */
426*4d9fdb46SRobert Mustacchi
427*4d9fdb46SRobert Mustacchi static int
apply_rela_entries(Dwarf_Debug dbg,Dwarf_Half r_section_index,dwarf_elf_object_access_internals_t * obj,struct Dwarf_Section_s * relocatablesec,int * error)428*4d9fdb46SRobert Mustacchi apply_rela_entries(
429*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
430*4d9fdb46SRobert Mustacchi /* Section_index of the relocation section, .rela entries */
431*4d9fdb46SRobert Mustacchi Dwarf_Half r_section_index,
432*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t*obj,
433*4d9fdb46SRobert Mustacchi /* relocatablesec is the .debug_info(etc) in Dwarf_Debug */
434*4d9fdb46SRobert Mustacchi struct Dwarf_Section_s * relocatablesec,
435*4d9fdb46SRobert Mustacchi int *error)
436*4d9fdb46SRobert Mustacchi {
437*4d9fdb46SRobert Mustacchi int return_res = DW_DLV_OK;
438*4d9fdb46SRobert Mustacchi struct generic_shdr * rels_shp = 0;
439*4d9fdb46SRobert Mustacchi Dwarf_Unsigned relcount;
440*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
441*4d9fdb46SRobert Mustacchi
442*4d9fdb46SRobert Mustacchi if (r_section_index >= obj->f_loc_shdr.g_count) {
443*4d9fdb46SRobert Mustacchi *error = DW_DLE_SECTION_INDEX_BAD;
444*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
445*4d9fdb46SRobert Mustacchi }
446*4d9fdb46SRobert Mustacchi rels_shp = obj->f_shdr + r_section_index;
447*4d9fdb46SRobert Mustacchi relcount = rels_shp->gh_relcount;
448*4d9fdb46SRobert Mustacchi if (!relcount) {
449*4d9fdb46SRobert Mustacchi /* Nothing to do. */
450*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
451*4d9fdb46SRobert Mustacchi }
452*4d9fdb46SRobert Mustacchi if (!rels_shp->gh_rels) {
453*4d9fdb46SRobert Mustacchi /* something wrong. */
454*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOCS_ERROR;
455*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
456*4d9fdb46SRobert Mustacchi }
457*4d9fdb46SRobert Mustacchi for (i = 0; i < relcount; i++) {
458*4d9fdb46SRobert Mustacchi int res = update_entry(dbg,obj,
459*4d9fdb46SRobert Mustacchi rels_shp->gh_rels+i,
460*4d9fdb46SRobert Mustacchi relocatablesec->dss_data,
461*4d9fdb46SRobert Mustacchi relocatablesec->dss_size,
462*4d9fdb46SRobert Mustacchi error);
463*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
464*4d9fdb46SRobert Mustacchi /* We try to keep going, not stop. */
465*4d9fdb46SRobert Mustacchi return_res = res;
466*4d9fdb46SRobert Mustacchi }
467*4d9fdb46SRobert Mustacchi }
468*4d9fdb46SRobert Mustacchi return return_res;
469*4d9fdb46SRobert Mustacchi }
470*4d9fdb46SRobert Mustacchi
471*4d9fdb46SRobert Mustacchi /* Find the section data in dbg and find all the relevant
472*4d9fdb46SRobert Mustacchi sections. Then do relocations.
473*4d9fdb46SRobert Mustacchi
474*4d9fdb46SRobert Mustacchi section_index is the index of a .debug_info (for example)
475*4d9fdb46SRobert Mustacchi so we have to find the section(s) with relocations
476*4d9fdb46SRobert Mustacchi targeting section_index.
477*4d9fdb46SRobert Mustacchi Normally there is exactly one such, though.
478*4d9fdb46SRobert Mustacchi */
479*4d9fdb46SRobert Mustacchi static int
elf_relocations_nolibelf(void * obj_in,Dwarf_Half section_index,Dwarf_Debug dbg,int * error)480*4d9fdb46SRobert Mustacchi elf_relocations_nolibelf(void* obj_in,
481*4d9fdb46SRobert Mustacchi Dwarf_Half section_index,
482*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg,
483*4d9fdb46SRobert Mustacchi int* error)
484*4d9fdb46SRobert Mustacchi {
485*4d9fdb46SRobert Mustacchi int res = DW_DLV_ERROR;
486*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t*obj = 0;
487*4d9fdb46SRobert Mustacchi struct Dwarf_Section_s * relocatablesec = 0;
488*4d9fdb46SRobert Mustacchi unsigned section_with_reloc_records = 0;
489*4d9fdb46SRobert Mustacchi
490*4d9fdb46SRobert Mustacchi if (section_index == 0) {
491*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
492*4d9fdb46SRobert Mustacchi }
493*4d9fdb46SRobert Mustacchi obj = (dwarf_elf_object_access_internals_t*)obj_in;
494*4d9fdb46SRobert Mustacchi
495*4d9fdb46SRobert Mustacchi /* The section to relocate must already be loaded into memory.
496*4d9fdb46SRobert Mustacchi This just turns section_index into a pointer
497*4d9fdb46SRobert Mustacchi to a de_debug_info or other section record in
498*4d9fdb46SRobert Mustacchi Dwarf_Debug. */
499*4d9fdb46SRobert Mustacchi res = find_section_to_relocate(dbg, section_index,
500*4d9fdb46SRobert Mustacchi &relocatablesec, error);
501*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
502*4d9fdb46SRobert Mustacchi return res;
503*4d9fdb46SRobert Mustacchi }
504*4d9fdb46SRobert Mustacchi /* Now we know the Dwarf_Section_s section
505*4d9fdb46SRobert Mustacchi we need to relocate.
506*4d9fdb46SRobert Mustacchi So lets find the rela section(s) targeting this.
507*4d9fdb46SRobert Mustacchi */
508*4d9fdb46SRobert Mustacchi
509*4d9fdb46SRobert Mustacchi /* Sun and possibly others do not always set
510*4d9fdb46SRobert Mustacchi sh_link in .debug_* sections.
511*4d9fdb46SRobert Mustacchi So we cannot do full consistency checks.
512*4d9fdb46SRobert Mustacchi FIXME: This approach assumes there is only one
513*4d9fdb46SRobert Mustacchi relocation section applying to section section_index! */
514*4d9fdb46SRobert Mustacchi section_with_reloc_records = relocatablesec->dss_reloc_index;
515*4d9fdb46SRobert Mustacchi if (!section_with_reloc_records) {
516*4d9fdb46SRobert Mustacchi /* Something is wrong. */
517*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
518*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
519*4d9fdb46SRobert Mustacchi }
520*4d9fdb46SRobert Mustacchi /* The relocations, if they exist, have been loaded. */
521*4d9fdb46SRobert Mustacchi /* The symtab was already loaded. */
522*4d9fdb46SRobert Mustacchi if (!obj->f_symtab || !obj->f_symtab_sect_strings) {
523*4d9fdb46SRobert Mustacchi *error = DW_DLE_DEBUG_SYMTAB_ERR;
524*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
525*4d9fdb46SRobert Mustacchi }
526*4d9fdb46SRobert Mustacchi if (obj->f_symtab_sect_index != relocatablesec->dss_reloc_link) {
527*4d9fdb46SRobert Mustacchi /* Something is wrong. */
528*4d9fdb46SRobert Mustacchi *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
529*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
530*4d9fdb46SRobert Mustacchi }
531*4d9fdb46SRobert Mustacchi /* We have all the data we need in memory. */
532*4d9fdb46SRobert Mustacchi /* Now we apply the relocs in section_with_reloc_records to the
533*4d9fdb46SRobert Mustacchi target, relocablesec */
534*4d9fdb46SRobert Mustacchi res = apply_rela_entries(dbg,section_with_reloc_records,
535*4d9fdb46SRobert Mustacchi obj, relocatablesec,error);
536*4d9fdb46SRobert Mustacchi return res;
537*4d9fdb46SRobert Mustacchi }
538*4d9fdb46SRobert Mustacchi
539*4d9fdb46SRobert Mustacchi void
_dwarf_destruct_elf_nlaccess(struct Dwarf_Obj_Access_Interface_s * aip)540*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(
541*4d9fdb46SRobert Mustacchi struct Dwarf_Obj_Access_Interface_s *aip)
542*4d9fdb46SRobert Mustacchi {
543*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *ep = 0;
544*4d9fdb46SRobert Mustacchi struct generic_shdr *shp = 0;
545*4d9fdb46SRobert Mustacchi Dwarf_Unsigned shcount = 0;
546*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
547*4d9fdb46SRobert Mustacchi
548*4d9fdb46SRobert Mustacchi ep = (dwarf_elf_object_access_internals_t *)aip->object;
549*4d9fdb46SRobert Mustacchi free(ep->f_ehdr);
550*4d9fdb46SRobert Mustacchi shp = ep->f_shdr;
551*4d9fdb46SRobert Mustacchi shcount = ep->f_loc_shdr.g_count;
552*4d9fdb46SRobert Mustacchi for(i = 0; i < shcount; ++i,++shp) {
553*4d9fdb46SRobert Mustacchi free(shp->gh_rels);
554*4d9fdb46SRobert Mustacchi shp->gh_rels = 0;
555*4d9fdb46SRobert Mustacchi free(shp->gh_content);
556*4d9fdb46SRobert Mustacchi shp->gh_content = 0;
557*4d9fdb46SRobert Mustacchi free(shp->gh_sht_group_array);
558*4d9fdb46SRobert Mustacchi shp->gh_sht_group_array = 0;
559*4d9fdb46SRobert Mustacchi shp->gh_sht_group_array_count = 0;
560*4d9fdb46SRobert Mustacchi }
561*4d9fdb46SRobert Mustacchi free(ep->f_shdr);
562*4d9fdb46SRobert Mustacchi ep->f_loc_shdr.g_count = 0;
563*4d9fdb46SRobert Mustacchi free(ep->f_phdr);
564*4d9fdb46SRobert Mustacchi free(ep->f_elf_shstrings_data);
565*4d9fdb46SRobert Mustacchi free(ep->f_dynamic);
566*4d9fdb46SRobert Mustacchi free(ep->f_symtab_sect_strings);
567*4d9fdb46SRobert Mustacchi free(ep->f_dynsym_sect_strings);
568*4d9fdb46SRobert Mustacchi free(ep->f_symtab);
569*4d9fdb46SRobert Mustacchi free(ep->f_dynsym);
570*4d9fdb46SRobert Mustacchi
571*4d9fdb46SRobert Mustacchi /* if TRUE close f_fd on destruct.*/
572*4d9fdb46SRobert Mustacchi if (ep->f_destruct_close_fd) {
573*4d9fdb46SRobert Mustacchi close(ep->f_fd);
574*4d9fdb46SRobert Mustacchi }
575*4d9fdb46SRobert Mustacchi ep->f_ident[0] = 'X';
576*4d9fdb46SRobert Mustacchi free(ep->f_path);
577*4d9fdb46SRobert Mustacchi free(ep);
578*4d9fdb46SRobert Mustacchi free(aip);
579*4d9fdb46SRobert Mustacchi }
580*4d9fdb46SRobert Mustacchi
581*4d9fdb46SRobert Mustacchi
582*4d9fdb46SRobert Mustacchi int
_dwarf_elf_nlsetup(int fd,char * true_path,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,Dwarf_Unsigned access,unsigned groupnumber,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * dbg,Dwarf_Error * error)583*4d9fdb46SRobert Mustacchi _dwarf_elf_nlsetup(int fd,
584*4d9fdb46SRobert Mustacchi char *true_path,
585*4d9fdb46SRobert Mustacchi unsigned ftype,
586*4d9fdb46SRobert Mustacchi unsigned endian,
587*4d9fdb46SRobert Mustacchi unsigned offsetsize,
588*4d9fdb46SRobert Mustacchi size_t filesize,
589*4d9fdb46SRobert Mustacchi Dwarf_Unsigned access,
590*4d9fdb46SRobert Mustacchi unsigned groupnumber,
591*4d9fdb46SRobert Mustacchi Dwarf_Handler errhand,
592*4d9fdb46SRobert Mustacchi Dwarf_Ptr errarg,
593*4d9fdb46SRobert Mustacchi Dwarf_Debug *dbg,Dwarf_Error *error)
594*4d9fdb46SRobert Mustacchi {
595*4d9fdb46SRobert Mustacchi Dwarf_Obj_Access_Interface *binary_interface = 0;
596*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *intfc = 0;
597*4d9fdb46SRobert Mustacchi int res = DW_DLV_OK;
598*4d9fdb46SRobert Mustacchi int localerrnum = 0;
599*4d9fdb46SRobert Mustacchi
600*4d9fdb46SRobert Mustacchi res = _dwarf_elf_object_access_init(
601*4d9fdb46SRobert Mustacchi fd,
602*4d9fdb46SRobert Mustacchi ftype,endian,offsetsize,filesize,access,
603*4d9fdb46SRobert Mustacchi &binary_interface,
604*4d9fdb46SRobert Mustacchi &localerrnum);
605*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
606*4d9fdb46SRobert Mustacchi if (res == DW_DLV_NO_ENTRY) {
607*4d9fdb46SRobert Mustacchi return res;
608*4d9fdb46SRobert Mustacchi }
609*4d9fdb46SRobert Mustacchi _dwarf_error(NULL, error, localerrnum);
610*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
611*4d9fdb46SRobert Mustacchi }
612*4d9fdb46SRobert Mustacchi /* allocates and initializes Dwarf_Debug,
613*4d9fdb46SRobert Mustacchi generic code */
614*4d9fdb46SRobert Mustacchi res = dwarf_object_init_b(binary_interface, errhand, errarg,
615*4d9fdb46SRobert Mustacchi groupnumber, dbg, error);
616*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK){
617*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(binary_interface);
618*4d9fdb46SRobert Mustacchi return res;
619*4d9fdb46SRobert Mustacchi }
620*4d9fdb46SRobert Mustacchi intfc = binary_interface->object;
621*4d9fdb46SRobert Mustacchi intfc->f_path = strdup(true_path);
622*4d9fdb46SRobert Mustacchi return res;
623*4d9fdb46SRobert Mustacchi }
624*4d9fdb46SRobert Mustacchi
625*4d9fdb46SRobert Mustacchi /* dwarf_elf_access method table for use with non-libelf.
626*4d9fdb46SRobert Mustacchi See also the methods table in dwarf_elf_access.c for libelf.
627*4d9fdb46SRobert Mustacchi */
628*4d9fdb46SRobert Mustacchi static Dwarf_Obj_Access_Methods const elf_nlmethods = {
629*4d9fdb46SRobert Mustacchi elf_get_nolibelf_section_info,
630*4d9fdb46SRobert Mustacchi elf_get_nolibelf_byte_order,
631*4d9fdb46SRobert Mustacchi elf_get_nolibelf_length_size,
632*4d9fdb46SRobert Mustacchi elf_get_nolibelf_pointer_size,
633*4d9fdb46SRobert Mustacchi elf_get_nolibelf_section_count,
634*4d9fdb46SRobert Mustacchi elf_load_nolibelf_section,
635*4d9fdb46SRobert Mustacchi elf_relocations_nolibelf
636*4d9fdb46SRobert Mustacchi };
637*4d9fdb46SRobert Mustacchi
638*4d9fdb46SRobert Mustacchi /* On any error this frees internals argument. */
639*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_object_access_internals_init(dwarf_elf_object_access_internals_t * internals,int fd,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,UNUSEDARG Dwarf_Unsigned access,int * errcode)640*4d9fdb46SRobert Mustacchi _dwarf_elf_object_access_internals_init(
641*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t * internals,
642*4d9fdb46SRobert Mustacchi int fd,
643*4d9fdb46SRobert Mustacchi unsigned ftype,
644*4d9fdb46SRobert Mustacchi unsigned endian,
645*4d9fdb46SRobert Mustacchi unsigned offsetsize,
646*4d9fdb46SRobert Mustacchi size_t filesize,
647*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Unsigned access,
648*4d9fdb46SRobert Mustacchi int *errcode)
649*4d9fdb46SRobert Mustacchi {
650*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t * intfc = internals;
651*4d9fdb46SRobert Mustacchi Dwarf_Unsigned i = 0;
652*4d9fdb46SRobert Mustacchi struct Dwarf_Obj_Access_Interface_s *localdoas;
653*4d9fdb46SRobert Mustacchi int res = 0;
654*4d9fdb46SRobert Mustacchi
655*4d9fdb46SRobert Mustacchi /* Must malloc as _dwarf_destruct_elf_access()
656*4d9fdb46SRobert Mustacchi forces that due to other uses. */
657*4d9fdb46SRobert Mustacchi localdoas = (struct Dwarf_Obj_Access_Interface_s *)
658*4d9fdb46SRobert Mustacchi malloc(sizeof(struct Dwarf_Obj_Access_Interface_s));
659*4d9fdb46SRobert Mustacchi if (!localdoas) {
660*4d9fdb46SRobert Mustacchi free(internals);
661*4d9fdb46SRobert Mustacchi *errcode = DW_DLE_ALLOC_FAIL;
662*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
663*4d9fdb46SRobert Mustacchi }
664*4d9fdb46SRobert Mustacchi memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s));
665*4d9fdb46SRobert Mustacchi /* E is used with libelf. F with this elf reader. */
666*4d9fdb46SRobert Mustacchi intfc->f_ident[0] = 'F';
667*4d9fdb46SRobert Mustacchi intfc->f_ident[1] = '1';
668*4d9fdb46SRobert Mustacchi intfc->f_fd = fd;
669*4d9fdb46SRobert Mustacchi intfc->f_is_64bit = ((offsetsize==64)?TRUE:FALSE);
670*4d9fdb46SRobert Mustacchi intfc->f_offsetsize = offsetsize;
671*4d9fdb46SRobert Mustacchi intfc->f_pointersize = offsetsize;
672*4d9fdb46SRobert Mustacchi intfc->f_filesize = filesize;
673*4d9fdb46SRobert Mustacchi intfc->f_ftype = ftype;
674*4d9fdb46SRobert Mustacchi intfc->f_destruct_close_fd = FALSE;
675*4d9fdb46SRobert Mustacchi
676*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
677*4d9fdb46SRobert Mustacchi if (endian == DW_ENDIAN_LITTLE ) {
678*4d9fdb46SRobert Mustacchi intfc->f_copy_word = _dwarf_memcpy_swap_bytes;
679*4d9fdb46SRobert Mustacchi intfc->f_endian = DW_OBJECT_LSB;
680*4d9fdb46SRobert Mustacchi } else {
681*4d9fdb46SRobert Mustacchi intfc->f_copy_word = _dwarf_memcpy_noswap_bytes;
682*4d9fdb46SRobert Mustacchi intfc->f_endian = DW_OBJECT_MSB;
683*4d9fdb46SRobert Mustacchi }
684*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
685*4d9fdb46SRobert Mustacchi if (endian == DW_ENDIAN_LITTLE ) {
686*4d9fdb46SRobert Mustacchi intfc->f_copy_word = _dwarf_memcpy_noswap_bytes;
687*4d9fdb46SRobert Mustacchi intfc->f_endian = DW_OBJECT_LSB;
688*4d9fdb46SRobert Mustacchi } else {
689*4d9fdb46SRobert Mustacchi intfc->f_copy_word = _dwarf_memcpy_swap_bytes;
690*4d9fdb46SRobert Mustacchi intfc->f_endian = DW_OBJECT_MSB;
691*4d9fdb46SRobert Mustacchi }
692*4d9fdb46SRobert Mustacchi #endif /* LITTLE- BIG-ENDIAN */
693*4d9fdb46SRobert Mustacchi _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func_nl;
694*4d9fdb46SRobert Mustacchi /* The following sets f_machine. */
695*4d9fdb46SRobert Mustacchi res = _dwarf_load_elf_header(intfc,errcode);
696*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
697*4d9fdb46SRobert Mustacchi localdoas->object = intfc;
698*4d9fdb46SRobert Mustacchi localdoas->methods = 0;
699*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(localdoas);
700*4d9fdb46SRobert Mustacchi localdoas = 0;
701*4d9fdb46SRobert Mustacchi return res;
702*4d9fdb46SRobert Mustacchi }
703*4d9fdb46SRobert Mustacchi /* Not loading progheaders */
704*4d9fdb46SRobert Mustacchi res = _dwarf_load_elf_sectheaders(intfc,errcode);
705*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
706*4d9fdb46SRobert Mustacchi localdoas->object = intfc;
707*4d9fdb46SRobert Mustacchi localdoas->methods = 0;
708*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(localdoas);
709*4d9fdb46SRobert Mustacchi localdoas = 0;
710*4d9fdb46SRobert Mustacchi return res;
711*4d9fdb46SRobert Mustacchi }
712*4d9fdb46SRobert Mustacchi /* We are not looking at symbol strings for now. */
713*4d9fdb46SRobert Mustacchi res = _dwarf_load_elf_symstr(intfc,errcode);
714*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
715*4d9fdb46SRobert Mustacchi localdoas->object = intfc;
716*4d9fdb46SRobert Mustacchi localdoas->methods = 0;
717*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(localdoas);
718*4d9fdb46SRobert Mustacchi localdoas = 0;
719*4d9fdb46SRobert Mustacchi return res;
720*4d9fdb46SRobert Mustacchi }
721*4d9fdb46SRobert Mustacchi res = _dwarf_load_elf_symtab_symbols(intfc,errcode);
722*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
723*4d9fdb46SRobert Mustacchi localdoas->object = intfc;
724*4d9fdb46SRobert Mustacchi localdoas->methods = 0;
725*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(localdoas);
726*4d9fdb46SRobert Mustacchi localdoas = 0;
727*4d9fdb46SRobert Mustacchi return res;
728*4d9fdb46SRobert Mustacchi }
729*4d9fdb46SRobert Mustacchi for ( i = 1; i < intfc->f_loc_shdr.g_count; ++i) {
730*4d9fdb46SRobert Mustacchi struct generic_shdr *shp = 0;
731*4d9fdb46SRobert Mustacchi Dwarf_Unsigned section_type = 0;
732*4d9fdb46SRobert Mustacchi enum RelocRela localrel = RelocIsRela;
733*4d9fdb46SRobert Mustacchi
734*4d9fdb46SRobert Mustacchi shp = intfc->f_shdr +i;
735*4d9fdb46SRobert Mustacchi section_type = shp->gh_type;
736*4d9fdb46SRobert Mustacchi if (section_type == SHT_REL ||
737*4d9fdb46SRobert Mustacchi (!strncmp(".rel.",shp->gh_namestring,5))) {
738*4d9fdb46SRobert Mustacchi localrel = RelocIsRel;
739*4d9fdb46SRobert Mustacchi } else if (section_type == SHT_RELA ||
740*4d9fdb46SRobert Mustacchi (!strncmp(".rela.",shp->gh_namestring,6))) {
741*4d9fdb46SRobert Mustacchi localrel = RelocIsRela;
742*4d9fdb46SRobert Mustacchi } else {
743*4d9fdb46SRobert Mustacchi continue;
744*4d9fdb46SRobert Mustacchi }
745*4d9fdb46SRobert Mustacchi /* ASSERT: local rel is either RelocIsRel or
746*4d9fdb46SRobert Mustacchi RelocIsRela. Never any other value. */
747*4d9fdb46SRobert Mustacchi /* Possibly we should check if the target section
748*4d9fdb46SRobert Mustacchi is one we care about before loading rela
749*4d9fdb46SRobert Mustacchi FIXME */
750*4d9fdb46SRobert Mustacchi res = _dwarf_load_elf_relx(intfc,i,localrel,errcode);
751*4d9fdb46SRobert Mustacchi if (res == DW_DLV_ERROR) {
752*4d9fdb46SRobert Mustacchi localdoas->object = intfc;
753*4d9fdb46SRobert Mustacchi localdoas->methods = 0;
754*4d9fdb46SRobert Mustacchi _dwarf_destruct_elf_nlaccess(localdoas);
755*4d9fdb46SRobert Mustacchi localdoas = 0;
756*4d9fdb46SRobert Mustacchi return res;
757*4d9fdb46SRobert Mustacchi }
758*4d9fdb46SRobert Mustacchi }
759*4d9fdb46SRobert Mustacchi free(localdoas);
760*4d9fdb46SRobert Mustacchi localdoas = 0;
761*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
762*4d9fdb46SRobert Mustacchi }
763*4d9fdb46SRobert Mustacchi
764*4d9fdb46SRobert Mustacchi
765*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_object_access_init(int fd,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,Dwarf_Unsigned access,Dwarf_Obj_Access_Interface ** binary_interface,int * localerrnum)766*4d9fdb46SRobert Mustacchi _dwarf_elf_object_access_init(
767*4d9fdb46SRobert Mustacchi int fd,
768*4d9fdb46SRobert Mustacchi unsigned ftype,
769*4d9fdb46SRobert Mustacchi unsigned endian,
770*4d9fdb46SRobert Mustacchi unsigned offsetsize,
771*4d9fdb46SRobert Mustacchi size_t filesize,
772*4d9fdb46SRobert Mustacchi Dwarf_Unsigned access,
773*4d9fdb46SRobert Mustacchi Dwarf_Obj_Access_Interface **binary_interface,
774*4d9fdb46SRobert Mustacchi int *localerrnum)
775*4d9fdb46SRobert Mustacchi {
776*4d9fdb46SRobert Mustacchi
777*4d9fdb46SRobert Mustacchi int res = 0;
778*4d9fdb46SRobert Mustacchi dwarf_elf_object_access_internals_t *internals = 0;
779*4d9fdb46SRobert Mustacchi Dwarf_Obj_Access_Interface *intfc = 0;
780*4d9fdb46SRobert Mustacchi
781*4d9fdb46SRobert Mustacchi internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
782*4d9fdb46SRobert Mustacchi if (!internals) {
783*4d9fdb46SRobert Mustacchi *localerrnum = DW_DLE_ALLOC_FAIL;
784*4d9fdb46SRobert Mustacchi /* Impossible case, we hope. Give up. */
785*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
786*4d9fdb46SRobert Mustacchi }
787*4d9fdb46SRobert Mustacchi memset(internals,0,sizeof(*internals));
788*4d9fdb46SRobert Mustacchi res = _dwarf_elf_object_access_internals_init(internals,
789*4d9fdb46SRobert Mustacchi fd,
790*4d9fdb46SRobert Mustacchi ftype, endian, offsetsize, filesize,
791*4d9fdb46SRobert Mustacchi access,
792*4d9fdb46SRobert Mustacchi localerrnum);
793*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK){
794*4d9fdb46SRobert Mustacchi return res;
795*4d9fdb46SRobert Mustacchi }
796*4d9fdb46SRobert Mustacchi
797*4d9fdb46SRobert Mustacchi intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
798*4d9fdb46SRobert Mustacchi if (!intfc) {
799*4d9fdb46SRobert Mustacchi /* Impossible case, we hope. Give up. */
800*4d9fdb46SRobert Mustacchi free(internals);
801*4d9fdb46SRobert Mustacchi *localerrnum = DW_DLE_ALLOC_FAIL;
802*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
803*4d9fdb46SRobert Mustacchi }
804*4d9fdb46SRobert Mustacchi /* Initialize the interface struct */
805*4d9fdb46SRobert Mustacchi intfc->object = internals;
806*4d9fdb46SRobert Mustacchi intfc->methods = &elf_nlmethods;
807*4d9fdb46SRobert Mustacchi *binary_interface = intfc;
808*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
809*4d9fdb46SRobert Mustacchi }
810