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