1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright 2018 David Anderson. All rights reserved.
3*4d9fdb46SRobert Mustacchi 
4*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
5*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
6*4d9fdb46SRobert Mustacchi following conditions are met:
7*4d9fdb46SRobert Mustacchi 
8*4d9fdb46SRobert Mustacchi     Redistributions of source code must retain the above
9*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
10*4d9fdb46SRobert Mustacchi     disclaimer.
11*4d9fdb46SRobert Mustacchi 
12*4d9fdb46SRobert Mustacchi     Redistributions in binary form must reproduce the above
13*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
14*4d9fdb46SRobert Mustacchi     disclaimer in the documentation and/or other materials
15*4d9fdb46SRobert Mustacchi     provided with the distribution.
16*4d9fdb46SRobert Mustacchi 
17*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*4d9fdb46SRobert Mustacchi */
31*4d9fdb46SRobert Mustacchi 
32*4d9fdb46SRobert Mustacchi /*
33*4d9fdb46SRobert Mustacchi This reads elf headers and creates generic-elf
34*4d9fdb46SRobert Mustacchi structures containing the Elf headers.
35*4d9fdb46SRobert Mustacchi 
36*4d9fdb46SRobert Mustacchi These two enums used for type safety in passing
37*4d9fdb46SRobert Mustacchi values.  See dwarf_elfread.h
38*4d9fdb46SRobert Mustacchi 
39*4d9fdb46SRobert Mustacchi enum RelocRela
40*4d9fdb46SRobert Mustacchi enum RelocOffsetSize
41*4d9fdb46SRobert Mustacchi 
42*4d9fdb46SRobert Mustacchi dwarf_elfread.c
43*4d9fdb46SRobert Mustacchi calls
44*4d9fdb46SRobert Mustacchi     _dwarf_load_elf_relx(intfc,i,...,enum RelocRela,errcode)
45*4d9fdb46SRobert Mustacchi         calls _dwarf_elf_load_a_relx_batch(ep,...enum RelocRela,
46*4d9fdb46SRobert Mustacchi             enum RelocOffsetSize,errcode)
47*4d9fdb46SRobert Mustacchi             which calls generic_rel_from_rela32(ep,gsh,relp,grel
48*4d9fdb46SRobert Mustacchi             or    calls generic_rel_from_rela64(ep,gsh,relp,grel
49*4d9fdb46SRobert Mustacchi             or    calls generic_rel_from_rel32(ep,gsh,relp,grel...
50*4d9fdb46SRobert Mustacchi             or    calls generic_rel_from_rel64(ep,gsh,relp,grel...
51*4d9fdb46SRobert Mustacchi */
52*4d9fdb46SRobert Mustacchi 
53*4d9fdb46SRobert Mustacchi 
54*4d9fdb46SRobert Mustacchi #include "config.h"
55*4d9fdb46SRobert Mustacchi #include <stdio.h>
56*4d9fdb46SRobert Mustacchi #include <string.h> /* For memcpy etc */
57*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
58*4d9fdb46SRobert Mustacchi #include <stdlib.h>
59*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
60*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
61*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
62*4d9fdb46SRobert Mustacchi #include <malloc.h>
63*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
64*4d9fdb46SRobert Mustacchi #include <stddef.h>
65*4d9fdb46SRobert Mustacchi #include <sys/types.h>   /* for open() */
66*4d9fdb46SRobert Mustacchi #include <sys/stat.h>   /* for open() */
67*4d9fdb46SRobert Mustacchi #include <fcntl.h>   /* for open() */
68*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNISTD_H
69*4d9fdb46SRobert Mustacchi #include <unistd.h> /* lseek read close */
70*4d9fdb46SRobert Mustacchi #elif defined(_WIN32) && defined(_MSC_VER)
71*4d9fdb46SRobert Mustacchi #include <io.h>
72*4d9fdb46SRobert Mustacchi #endif /* HAVE_UNISTD_H */
73*4d9fdb46SRobert Mustacchi 
74*4d9fdb46SRobert Mustacchi /* Windows specific header files */
75*4d9fdb46SRobert Mustacchi #if defined(_WIN32) && defined(HAVE_STDAFX_H)
76*4d9fdb46SRobert Mustacchi #include "stdafx.h"
77*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDAFX_H */
78*4d9fdb46SRobert Mustacchi 
79*4d9fdb46SRobert Mustacchi #include "libdwarfdefs.h"
80*4d9fdb46SRobert Mustacchi #include "dwarf.h"
81*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
82*4d9fdb46SRobert Mustacchi #include "dwarf_base_types.h"
83*4d9fdb46SRobert Mustacchi #include "dwarf_opaque.h"
84*4d9fdb46SRobert Mustacchi #include "memcpy_swap.h"
85*4d9fdb46SRobert Mustacchi #include "dwarf_elfstructs.h"
86*4d9fdb46SRobert Mustacchi #include "dwarf_reading.h"
87*4d9fdb46SRobert Mustacchi #include "dwarf_elf_defines.h"
88*4d9fdb46SRobert Mustacchi #include "dwarf_elfread.h"
89*4d9fdb46SRobert Mustacchi #include "dwarf_object_detector.h"
90*4d9fdb46SRobert Mustacchi #include "dwarf_object_read_common.h"
91*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
92*4d9fdb46SRobert Mustacchi 
93*4d9fdb46SRobert Mustacchi #ifndef O_BINARY
94*4d9fdb46SRobert Mustacchi #define O_BINARY 0
95*4d9fdb46SRobert Mustacchi #endif /* O_BINARY */
96*4d9fdb46SRobert Mustacchi 
97*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNUSED_ATTRIBUTE
98*4d9fdb46SRobert Mustacchi #define  UNUSEDARG __attribute__ ((unused))
99*4d9fdb46SRobert Mustacchi #else
100*4d9fdb46SRobert Mustacchi #define  UNUSEDARG
101*4d9fdb46SRobert Mustacchi #endif
102*4d9fdb46SRobert Mustacchi #define TRUE  1
103*4d9fdb46SRobert Mustacchi #define FALSE 0
104*4d9fdb46SRobert Mustacchi 
105*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
106*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
107*4d9fdb46SRobert Mustacchi     do {                                        \
108*4d9fdb46SRobert Mustacchi         unsigned tbyte = sizeof(t) - sizeof(s); \
109*4d9fdb46SRobert Mustacchi         t = 0;                                  \
110*4d9fdb46SRobert Mustacchi         func(((char *)&t)+tbyte ,&s[0],sizeof(s));  \
111*4d9fdb46SRobert Mustacchi     } while (0)
112*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
113*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
114*4d9fdb46SRobert Mustacchi     do {                                        \
115*4d9fdb46SRobert Mustacchi         t = 0;                                  \
116*4d9fdb46SRobert Mustacchi         func(&t,&s[0],sizeof(s));               \
117*4d9fdb46SRobert Mustacchi     } while (0)
118*4d9fdb46SRobert Mustacchi #endif /* end LITTLE- BIG-ENDIAN */
119*4d9fdb46SRobert Mustacchi 
120*4d9fdb46SRobert Mustacchi static int
_dwarf_load_elf_section_is_dwarf(const char * sname,int * is_rela,int * is_rel)121*4d9fdb46SRobert Mustacchi _dwarf_load_elf_section_is_dwarf(const char *sname,
122*4d9fdb46SRobert Mustacchi     int *is_rela,int *is_rel)
123*4d9fdb46SRobert Mustacchi {
124*4d9fdb46SRobert Mustacchi     *is_rel = FALSE;
125*4d9fdb46SRobert Mustacchi     *is_rela = FALSE;
126*4d9fdb46SRobert Mustacchi     if(_dwarf_ignorethissection(sname)) {
127*4d9fdb46SRobert Mustacchi         return FALSE;
128*4d9fdb46SRobert Mustacchi     }
129*4d9fdb46SRobert Mustacchi     if (!strncmp(sname,".rel",4)) {
130*4d9fdb46SRobert Mustacchi         if (!strncmp(sname,".rela.",6)) {
131*4d9fdb46SRobert Mustacchi             *is_rela = TRUE;
132*4d9fdb46SRobert Mustacchi             return TRUE;
133*4d9fdb46SRobert Mustacchi         }
134*4d9fdb46SRobert Mustacchi         if (!strncmp(sname,".rel.",5)) {
135*4d9fdb46SRobert Mustacchi             *is_rela = TRUE;
136*4d9fdb46SRobert Mustacchi             return TRUE;
137*4d9fdb46SRobert Mustacchi         }
138*4d9fdb46SRobert Mustacchi         /*  Else something is goofy/Impossible */
139*4d9fdb46SRobert Mustacchi         return FALSE;
140*4d9fdb46SRobert Mustacchi     }
141*4d9fdb46SRobert Mustacchi     if (!strncmp(sname,".debug_",7)) {
142*4d9fdb46SRobert Mustacchi         return TRUE;
143*4d9fdb46SRobert Mustacchi     }
144*4d9fdb46SRobert Mustacchi     if (!strncmp(sname,".zdebug_",8)) {
145*4d9fdb46SRobert Mustacchi         return TRUE;
146*4d9fdb46SRobert Mustacchi     }
147*4d9fdb46SRobert Mustacchi     if (!strcmp(sname,".eh_frame")) {
148*4d9fdb46SRobert Mustacchi         return TRUE;
149*4d9fdb46SRobert Mustacchi     }
150*4d9fdb46SRobert Mustacchi     if (!strncmp(sname,".gdb_index",10)) {
151*4d9fdb46SRobert Mustacchi         return TRUE;
152*4d9fdb46SRobert Mustacchi     }
153*4d9fdb46SRobert Mustacchi     return FALSE;
154*4d9fdb46SRobert Mustacchi }
155*4d9fdb46SRobert Mustacchi 
156*4d9fdb46SRobert Mustacchi 
157*4d9fdb46SRobert Mustacchi static int
is_empty_section(Dwarf_Unsigned type)158*4d9fdb46SRobert Mustacchi is_empty_section(Dwarf_Unsigned type)
159*4d9fdb46SRobert Mustacchi {
160*4d9fdb46SRobert Mustacchi     if (type == SHT_NOBITS) {
161*4d9fdb46SRobert Mustacchi         return TRUE;
162*4d9fdb46SRobert Mustacchi     }
163*4d9fdb46SRobert Mustacchi     if (type == SHT_NULL) {
164*4d9fdb46SRobert Mustacchi         return TRUE;
165*4d9fdb46SRobert Mustacchi     }
166*4d9fdb46SRobert Mustacchi     return FALSE;
167*4d9fdb46SRobert Mustacchi }
168*4d9fdb46SRobert Mustacchi 
169*4d9fdb46SRobert Mustacchi #if 0
170*4d9fdb46SRobert Mustacchi int
171*4d9fdb46SRobert Mustacchi dwarf_construct_elf_access_path(const char *path,
172*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t **mp,int *errcode)
173*4d9fdb46SRobert Mustacchi {
174*4d9fdb46SRobert Mustacchi     int fd = -1;
175*4d9fdb46SRobert Mustacchi     int res = 0;
176*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *mymp = 0;
177*4d9fdb46SRobert Mustacchi 
178*4d9fdb46SRobert Mustacchi     fd = open(path, O_RDONLY|O_BINARY);
179*4d9fdb46SRobert Mustacchi     if (fd < 0) {
180*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_PATH_SIZE_TOO_SMALL;
181*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
182*4d9fdb46SRobert Mustacchi     }
183*4d9fdb46SRobert Mustacchi     res = dwarf_construct_elf_access(fd,
184*4d9fdb46SRobert Mustacchi         path,&mymp,errcode);
185*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
186*4d9fdb46SRobert Mustacchi         close(fd);
187*4d9fdb46SRobert Mustacchi         return res;
188*4d9fdb46SRobert Mustacchi     }
189*4d9fdb46SRobert Mustacchi     mymp->f_destruct_close_fd = TRUE;
190*4d9fdb46SRobert Mustacchi     *mp = mymp;
191*4d9fdb46SRobert Mustacchi     return res;
192*4d9fdb46SRobert Mustacchi }
193*4d9fdb46SRobert Mustacchi #endif /* 0 */
194*4d9fdb46SRobert Mustacchi 
195*4d9fdb46SRobert Mustacchi /* Here path is not essential. Pass in with "" if unknown. */
196*4d9fdb46SRobert Mustacchi int
dwarf_construct_elf_access(int fd,const char * path,dwarf_elf_object_access_internals_t ** mp,int * errcode)197*4d9fdb46SRobert Mustacchi dwarf_construct_elf_access(int fd,
198*4d9fdb46SRobert Mustacchi     const char *path,
199*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t **mp,int *errcode)
200*4d9fdb46SRobert Mustacchi {
201*4d9fdb46SRobert Mustacchi     unsigned ftype = 0;
202*4d9fdb46SRobert Mustacchi     unsigned endian = 0;
203*4d9fdb46SRobert Mustacchi     unsigned offsetsize = 0;
204*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned filesize = 0;
205*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *mfp = 0;
206*4d9fdb46SRobert Mustacchi     int      res = 0;
207*4d9fdb46SRobert Mustacchi 
208*4d9fdb46SRobert Mustacchi     res = dwarf_object_detector_fd(fd,
209*4d9fdb46SRobert Mustacchi         &ftype,&endian,&offsetsize, &filesize, errcode);
210*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
211*4d9fdb46SRobert Mustacchi         return res;
212*4d9fdb46SRobert Mustacchi     }
213*4d9fdb46SRobert Mustacchi 
214*4d9fdb46SRobert Mustacchi     mfp = calloc(1,sizeof(dwarf_elf_object_access_internals_t));
215*4d9fdb46SRobert Mustacchi     if (!mfp) {
216*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
217*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
218*4d9fdb46SRobert Mustacchi     }
219*4d9fdb46SRobert Mustacchi     /* For non-libelf Elf, call it 'F'. Libelf Elf uses 'E' */
220*4d9fdb46SRobert Mustacchi     mfp->f_ident[0] = 'F';
221*4d9fdb46SRobert Mustacchi     mfp->f_ident[1] = 1;
222*4d9fdb46SRobert Mustacchi     mfp->f_fd = fd;
223*4d9fdb46SRobert Mustacchi     mfp->f_destruct_close_fd = FALSE;
224*4d9fdb46SRobert Mustacchi     mfp->f_is_64bit =  ((offsetsize==64)?TRUE:FALSE);
225*4d9fdb46SRobert Mustacchi     mfp->f_filesize = filesize;
226*4d9fdb46SRobert Mustacchi     mfp->f_offsetsize = offsetsize;
227*4d9fdb46SRobert Mustacchi     mfp->f_pointersize = offsetsize;
228*4d9fdb46SRobert Mustacchi     mfp->f_endian = endian;
229*4d9fdb46SRobert Mustacchi     mfp->f_ftype = ftype;
230*4d9fdb46SRobert Mustacchi     mfp->f_path = strdup(path);
231*4d9fdb46SRobert Mustacchi 
232*4d9fdb46SRobert Mustacchi     *mp = mfp;
233*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
234*4d9fdb46SRobert Mustacchi }
235*4d9fdb46SRobert Mustacchi 
236*4d9fdb46SRobert Mustacchi /*  Caller must zero the passed in pointer
237*4d9fdb46SRobert Mustacchi     after this returns to remind
238*4d9fdb46SRobert Mustacchi     the caller to avoid use of the pointer. */
239*4d9fdb46SRobert Mustacchi int
dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t * ep,UNUSEDARG int * errcode)240*4d9fdb46SRobert Mustacchi dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t* ep,
241*4d9fdb46SRobert Mustacchi     UNUSEDARG int *errcode)
242*4d9fdb46SRobert Mustacchi {
243*4d9fdb46SRobert Mustacchi     struct generic_shdr *shp = 0;
244*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned shcount = 0;
245*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
246*4d9fdb46SRobert Mustacchi 
247*4d9fdb46SRobert Mustacchi     free(ep->f_ehdr);
248*4d9fdb46SRobert Mustacchi     shp = ep->f_shdr;
249*4d9fdb46SRobert Mustacchi     shcount = ep->f_loc_shdr.g_count;
250*4d9fdb46SRobert Mustacchi     for(i = 0; i < shcount; ++i,++shp) {
251*4d9fdb46SRobert Mustacchi         free(shp->gh_rels);
252*4d9fdb46SRobert Mustacchi         shp->gh_rels = 0;
253*4d9fdb46SRobert Mustacchi         free(shp->gh_content);
254*4d9fdb46SRobert Mustacchi         shp->gh_content = 0;
255*4d9fdb46SRobert Mustacchi         free(shp->gh_sht_group_array);
256*4d9fdb46SRobert Mustacchi         shp->gh_sht_group_array = 0;
257*4d9fdb46SRobert Mustacchi         shp->gh_sht_group_array_count = 0;
258*4d9fdb46SRobert Mustacchi     }
259*4d9fdb46SRobert Mustacchi     free(ep->f_shdr);
260*4d9fdb46SRobert Mustacchi     free(ep->f_phdr);
261*4d9fdb46SRobert Mustacchi     free(ep->f_elf_shstrings_data);
262*4d9fdb46SRobert Mustacchi     free(ep->f_dynamic);
263*4d9fdb46SRobert Mustacchi     free(ep->f_symtab_sect_strings);
264*4d9fdb46SRobert Mustacchi     free(ep->f_dynsym_sect_strings);
265*4d9fdb46SRobert Mustacchi     free(ep->f_symtab);
266*4d9fdb46SRobert Mustacchi     free(ep->f_dynsym);
267*4d9fdb46SRobert Mustacchi 
268*4d9fdb46SRobert Mustacchi     /* if TRUE close f_fd on destruct.*/
269*4d9fdb46SRobert Mustacchi     if (ep->f_destruct_close_fd) {
270*4d9fdb46SRobert Mustacchi         close(ep->f_fd);
271*4d9fdb46SRobert Mustacchi     }
272*4d9fdb46SRobert Mustacchi     ep->f_ident[0] = 'X';
273*4d9fdb46SRobert Mustacchi     free(ep->f_path);
274*4d9fdb46SRobert Mustacchi     free(ep);
275*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
276*4d9fdb46SRobert Mustacchi }
277*4d9fdb46SRobert Mustacchi 
278*4d9fdb46SRobert Mustacchi 
279*4d9fdb46SRobert Mustacchi 
280*4d9fdb46SRobert Mustacchi 
281*4d9fdb46SRobert Mustacchi static int
generic_ehdr_from_32(dwarf_elf_object_access_internals_t * ep,struct generic_ehdr * ehdr,dw_elf32_ehdr * e,UNUSEDARG int * errcode)282*4d9fdb46SRobert Mustacchi generic_ehdr_from_32(dwarf_elf_object_access_internals_t *ep,
283*4d9fdb46SRobert Mustacchi     struct generic_ehdr *ehdr, dw_elf32_ehdr *e,
284*4d9fdb46SRobert Mustacchi     UNUSEDARG int *errcode)
285*4d9fdb46SRobert Mustacchi {
286*4d9fdb46SRobert Mustacchi     int i = 0;
287*4d9fdb46SRobert Mustacchi 
288*4d9fdb46SRobert Mustacchi     for (i = 0; i < EI_NIDENT; ++i) {
289*4d9fdb46SRobert Mustacchi         ehdr->ge_ident[i] = e->e_ident[i];
290*4d9fdb46SRobert Mustacchi     }
291*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type);
292*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine);
293*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version);
294*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry);
295*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff);
296*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff);
297*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags);
298*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize);
299*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize);
300*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum);
301*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize);
302*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum);
303*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx);
304*4d9fdb46SRobert Mustacchi     ep->f_machine = ehdr->ge_machine;
305*4d9fdb46SRobert Mustacchi     ep->f_ehdr = ehdr;
306*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_name = "Elf File Header";
307*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_offset = 0;
308*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_count = 1;
309*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf32_ehdr);
310*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf32_ehdr);
311*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
312*4d9fdb46SRobert Mustacchi }
313*4d9fdb46SRobert Mustacchi 
314*4d9fdb46SRobert Mustacchi static int
generic_ehdr_from_64(dwarf_elf_object_access_internals_t * ep,struct generic_ehdr * ehdr,dw_elf64_ehdr * e,UNUSEDARG int * errcode)315*4d9fdb46SRobert Mustacchi generic_ehdr_from_64(dwarf_elf_object_access_internals_t* ep,
316*4d9fdb46SRobert Mustacchi     struct generic_ehdr *ehdr, dw_elf64_ehdr *e,
317*4d9fdb46SRobert Mustacchi     UNUSEDARG int *errcode)
318*4d9fdb46SRobert Mustacchi {
319*4d9fdb46SRobert Mustacchi     int i = 0;
320*4d9fdb46SRobert Mustacchi 
321*4d9fdb46SRobert Mustacchi     for (i = 0; i < EI_NIDENT; ++i) {
322*4d9fdb46SRobert Mustacchi         ehdr->ge_ident[i] = e->e_ident[i];
323*4d9fdb46SRobert Mustacchi     }
324*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type);
325*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine);
326*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version);
327*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry);
328*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff);
329*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff);
330*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags);
331*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize);
332*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize);
333*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum);
334*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize);
335*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum);
336*4d9fdb46SRobert Mustacchi     ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx);
337*4d9fdb46SRobert Mustacchi     ep->f_machine = ehdr->ge_machine;
338*4d9fdb46SRobert Mustacchi     ep->f_ehdr = ehdr;
339*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_name = "Elf File Header";
340*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_offset = 0;
341*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_count = 1;
342*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf64_ehdr);
343*4d9fdb46SRobert Mustacchi     ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf64_ehdr);
344*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
345*4d9fdb46SRobert Mustacchi }
346*4d9fdb46SRobert Mustacchi 
347*4d9fdb46SRobert Mustacchi 
348*4d9fdb46SRobert Mustacchi #if 0 /* not used */
349*4d9fdb46SRobert Mustacchi static int
350*4d9fdb46SRobert Mustacchi generic_phdr_from_phdr32(dwarf_elf_object_access_internals_t* ep,
351*4d9fdb46SRobert Mustacchi     struct generic_phdr **phdr_out,
352*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * count_out,
353*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
354*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entsize,
355*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,
356*4d9fdb46SRobert Mustacchi     int *errcode)
357*4d9fdb46SRobert Mustacchi {
358*4d9fdb46SRobert Mustacchi     dw_elf32_phdr *pph =0;
359*4d9fdb46SRobert Mustacchi     dw_elf32_phdr *orig_pph =0;
360*4d9fdb46SRobert Mustacchi     struct generic_phdr *gphdr =0;
361*4d9fdb46SRobert Mustacchi     struct generic_phdr *orig_gphdr =0;
362*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
363*4d9fdb46SRobert Mustacchi     int res = 0;
364*4d9fdb46SRobert Mustacchi 
365*4d9fdb46SRobert Mustacchi     *count_out = 0;
366*4d9fdb46SRobert Mustacchi     pph = (dw_elf32_phdr *)calloc(count , entsize);
367*4d9fdb46SRobert Mustacchi     if(pph == 0) {
368*4d9fdb46SRobert Mustacchi         *errcode =  DW_DLE_ALLOC_FAIL;
369*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
370*4d9fdb46SRobert Mustacchi     }
371*4d9fdb46SRobert Mustacchi     gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr));
372*4d9fdb46SRobert Mustacchi     if(gphdr == 0) {
373*4d9fdb46SRobert Mustacchi         free(pph);
374*4d9fdb46SRobert Mustacchi         *errcode =  DW_DLE_ALLOC_FAIL;
375*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
376*4d9fdb46SRobert Mustacchi     }
377*4d9fdb46SRobert Mustacchi 
378*4d9fdb46SRobert Mustacchi     orig_pph = pph;
379*4d9fdb46SRobert Mustacchi     orig_gphdr = gphdr;
380*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,pph,offset,count*entsize,
381*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
382*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
383*4d9fdb46SRobert Mustacchi         free(pph);
384*4d9fdb46SRobert Mustacchi         free(gphdr);
385*4d9fdb46SRobert Mustacchi         return res;
386*4d9fdb46SRobert Mustacchi     }
387*4d9fdb46SRobert Mustacchi     for( i = 0; i < count;
388*4d9fdb46SRobert Mustacchi         ++i,  pph++,gphdr++) {
389*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type);
390*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset);
391*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr);
392*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr);
393*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz);
394*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz);
395*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags);
396*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align);
397*4d9fdb46SRobert Mustacchi     }
398*4d9fdb46SRobert Mustacchi     free(orig_pph);
399*4d9fdb46SRobert Mustacchi     *phdr_out = orig_gphdr;
400*4d9fdb46SRobert Mustacchi     *count_out = count;
401*4d9fdb46SRobert Mustacchi     ep->f_phdr = orig_gphdr;
402*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_name = "Program Header";
403*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_offset = offset;
404*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_count = count;
405*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_entrysize = sizeof(dw_elf32_phdr);
406*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_totalsize = sizeof(dw_elf32_phdr)*count;
407*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
408*4d9fdb46SRobert Mustacchi }
409*4d9fdb46SRobert Mustacchi 
410*4d9fdb46SRobert Mustacchi static int
411*4d9fdb46SRobert Mustacchi generic_phdr_from_phdr64(dwarf_elf_object_access_internals_t* ep,
412*4d9fdb46SRobert Mustacchi     struct generic_phdr **phdr_out,
413*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * count_out,
414*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
415*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entsize,
416*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,
417*4d9fdb46SRobert Mustacchi     int *errcode)
418*4d9fdb46SRobert Mustacchi {
419*4d9fdb46SRobert Mustacchi     dw_elf64_phdr *pph =0;
420*4d9fdb46SRobert Mustacchi     dw_elf64_phdr *orig_pph =0;
421*4d9fdb46SRobert Mustacchi     struct generic_phdr *gphdr =0;
422*4d9fdb46SRobert Mustacchi     struct generic_phdr *orig_gphdr =0;
423*4d9fdb46SRobert Mustacchi     int res = 0;
424*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
425*4d9fdb46SRobert Mustacchi 
426*4d9fdb46SRobert Mustacchi     *count_out = 0;
427*4d9fdb46SRobert Mustacchi     pph = (dw_elf64_phdr *)calloc(count , entsize);
428*4d9fdb46SRobert Mustacchi     if(pph == 0) {
429*4d9fdb46SRobert Mustacchi         *errcode =  DW_DLE_ALLOC_FAIL;
430*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
431*4d9fdb46SRobert Mustacchi     }
432*4d9fdb46SRobert Mustacchi     gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr));
433*4d9fdb46SRobert Mustacchi     if(gphdr == 0) {
434*4d9fdb46SRobert Mustacchi         free(pph);
435*4d9fdb46SRobert Mustacchi         *errcode =  DW_DLE_ALLOC_FAIL;
436*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
437*4d9fdb46SRobert Mustacchi     }
438*4d9fdb46SRobert Mustacchi 
439*4d9fdb46SRobert Mustacchi     orig_pph = pph;
440*4d9fdb46SRobert Mustacchi     orig_gphdr = gphdr;
441*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,pph,offset,count*entsize,
442*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
443*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
444*4d9fdb46SRobert Mustacchi         free(pph);
445*4d9fdb46SRobert Mustacchi         free(gphdr);
446*4d9fdb46SRobert Mustacchi         return res;
447*4d9fdb46SRobert Mustacchi     }
448*4d9fdb46SRobert Mustacchi     for( i = 0; i < count;
449*4d9fdb46SRobert Mustacchi         ++i,  pph++,gphdr++) {
450*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type);
451*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset);
452*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr);
453*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr);
454*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz);
455*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz);
456*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags);
457*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align);
458*4d9fdb46SRobert Mustacchi     }
459*4d9fdb46SRobert Mustacchi     free(orig_pph);
460*4d9fdb46SRobert Mustacchi     *phdr_out = orig_gphdr;
461*4d9fdb46SRobert Mustacchi     *count_out = count;
462*4d9fdb46SRobert Mustacchi     ep->f_phdr = orig_gphdr;
463*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_name = "Program Header";
464*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_offset = offset;
465*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_count = count;
466*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_entrysize = sizeof(dw_elf64_phdr);
467*4d9fdb46SRobert Mustacchi     ep->f_loc_phdr.g_totalsize = sizeof(dw_elf64_phdr)*count;
468*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
469*4d9fdb46SRobert Mustacchi }
470*4d9fdb46SRobert Mustacchi #endif /* not used */
471*4d9fdb46SRobert Mustacchi 
472*4d9fdb46SRobert Mustacchi static int
generic_shdr_from_shdr32(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned * count_out,Dwarf_Unsigned offset,Dwarf_Unsigned entsize,Dwarf_Unsigned count,int * errcode)473*4d9fdb46SRobert Mustacchi generic_shdr_from_shdr32(dwarf_elf_object_access_internals_t *ep,
474*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * count_out,
475*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
476*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entsize,
477*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,
478*4d9fdb46SRobert Mustacchi     int *errcode)
479*4d9fdb46SRobert Mustacchi {
480*4d9fdb46SRobert Mustacchi     dw_elf32_shdr          *psh =0;
481*4d9fdb46SRobert Mustacchi     dw_elf32_shdr          *orig_psh =0;
482*4d9fdb46SRobert Mustacchi     struct generic_shdr *gshdr =0;
483*4d9fdb46SRobert Mustacchi     struct generic_shdr *orig_gshdr =0;
484*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
485*4d9fdb46SRobert Mustacchi     int res = 0;
486*4d9fdb46SRobert Mustacchi 
487*4d9fdb46SRobert Mustacchi     *count_out = 0;
488*4d9fdb46SRobert Mustacchi     psh = (dw_elf32_shdr *)calloc(count , entsize);
489*4d9fdb46SRobert Mustacchi     if(!psh) {
490*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
491*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
492*4d9fdb46SRobert Mustacchi     }
493*4d9fdb46SRobert Mustacchi     gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr));
494*4d9fdb46SRobert Mustacchi     if(!gshdr) {
495*4d9fdb46SRobert Mustacchi         free(psh);
496*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
497*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
498*4d9fdb46SRobert Mustacchi     }
499*4d9fdb46SRobert Mustacchi 
500*4d9fdb46SRobert Mustacchi     orig_psh = psh;
501*4d9fdb46SRobert Mustacchi     orig_gshdr = gshdr;
502*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,psh,offset,count*entsize,
503*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
504*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
505*4d9fdb46SRobert Mustacchi         free(psh);
506*4d9fdb46SRobert Mustacchi         free(gshdr);
507*4d9fdb46SRobert Mustacchi         return res;
508*4d9fdb46SRobert Mustacchi     }
509*4d9fdb46SRobert Mustacchi     for(i = 0; i < count;
510*4d9fdb46SRobert Mustacchi         ++i,  psh++,gshdr++) {
511*4d9fdb46SRobert Mustacchi         gshdr->gh_secnum = i;
512*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name);
513*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type);
514*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags);
515*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr);
516*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset);
517*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size);
518*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link);
519*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info);
520*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign);
521*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize);
522*4d9fdb46SRobert Mustacchi         if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){
523*4d9fdb46SRobert Mustacchi             gshdr->gh_reloc_target_secnum = gshdr->gh_info;
524*4d9fdb46SRobert Mustacchi         }
525*4d9fdb46SRobert Mustacchi     }
526*4d9fdb46SRobert Mustacchi     free(orig_psh);
527*4d9fdb46SRobert Mustacchi     *count_out = count;
528*4d9fdb46SRobert Mustacchi     ep->f_shdr = orig_gshdr;
529*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_name = "Section Header";
530*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_count = count;
531*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_offset = offset;
532*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_entrysize = sizeof(dw_elf32_shdr);
533*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_totalsize = sizeof(dw_elf32_shdr)*count;
534*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
535*4d9fdb46SRobert Mustacchi }
536*4d9fdb46SRobert Mustacchi 
537*4d9fdb46SRobert Mustacchi static int
generic_shdr_from_shdr64(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned * count_out,Dwarf_Unsigned offset,Dwarf_Unsigned entsize,Dwarf_Unsigned count,int * errcode)538*4d9fdb46SRobert Mustacchi generic_shdr_from_shdr64(dwarf_elf_object_access_internals_t *ep,
539*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned * count_out,
540*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,
541*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned entsize,
542*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,
543*4d9fdb46SRobert Mustacchi     int *errcode)
544*4d9fdb46SRobert Mustacchi {
545*4d9fdb46SRobert Mustacchi     dw_elf64_shdr          *psh =0;
546*4d9fdb46SRobert Mustacchi     dw_elf64_shdr          *orig_psh =0;
547*4d9fdb46SRobert Mustacchi     struct generic_shdr *gshdr =0;
548*4d9fdb46SRobert Mustacchi     struct generic_shdr *orig_gshdr =0;
549*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
550*4d9fdb46SRobert Mustacchi     int res = 0;
551*4d9fdb46SRobert Mustacchi 
552*4d9fdb46SRobert Mustacchi     *count_out = 0;
553*4d9fdb46SRobert Mustacchi     psh = (dw_elf64_shdr *)calloc(count , entsize);
554*4d9fdb46SRobert Mustacchi     if(!psh) {
555*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
556*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
557*4d9fdb46SRobert Mustacchi     }
558*4d9fdb46SRobert Mustacchi     gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr));
559*4d9fdb46SRobert Mustacchi     if(gshdr == 0) {
560*4d9fdb46SRobert Mustacchi         free(psh);
561*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
562*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
563*4d9fdb46SRobert Mustacchi     }
564*4d9fdb46SRobert Mustacchi 
565*4d9fdb46SRobert Mustacchi     orig_psh = psh;
566*4d9fdb46SRobert Mustacchi     orig_gshdr = gshdr;
567*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,psh,offset,count*entsize,
568*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
569*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
570*4d9fdb46SRobert Mustacchi         free(psh);
571*4d9fdb46SRobert Mustacchi         free(gshdr);
572*4d9fdb46SRobert Mustacchi         return res;
573*4d9fdb46SRobert Mustacchi     }
574*4d9fdb46SRobert Mustacchi     for( i = 0; i < count;
575*4d9fdb46SRobert Mustacchi         ++i,  psh++,gshdr++) {
576*4d9fdb46SRobert Mustacchi         gshdr->gh_secnum = i;
577*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name);
578*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type);
579*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags);
580*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr);
581*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset);
582*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size);
583*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link);
584*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info);
585*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign);
586*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize);
587*4d9fdb46SRobert Mustacchi         if (gshdr->gh_type == SHT_REL ||
588*4d9fdb46SRobert Mustacchi             gshdr->gh_type == SHT_RELA){
589*4d9fdb46SRobert Mustacchi             gshdr->gh_reloc_target_secnum = gshdr->gh_info;
590*4d9fdb46SRobert Mustacchi         }
591*4d9fdb46SRobert Mustacchi     }
592*4d9fdb46SRobert Mustacchi     free(orig_psh);
593*4d9fdb46SRobert Mustacchi     *count_out = count;
594*4d9fdb46SRobert Mustacchi     ep->f_shdr = orig_gshdr;
595*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_name = "Section Header";
596*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_count = count;
597*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_offset = offset;
598*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_entrysize = sizeof(dw_elf64_shdr);
599*4d9fdb46SRobert Mustacchi     ep->f_loc_shdr.g_totalsize = sizeof(dw_elf64_shdr)*count;
600*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
601*4d9fdb46SRobert Mustacchi }
602*4d9fdb46SRobert Mustacchi 
603*4d9fdb46SRobert Mustacchi 
604*4d9fdb46SRobert Mustacchi 
605*4d9fdb46SRobert Mustacchi static int
dwarf_generic_elf_load_symbols32(dwarf_elf_object_access_internals_t * ep,struct generic_symentry ** gsym_out,Dwarf_Unsigned offset,Dwarf_Unsigned size,Dwarf_Unsigned * count_out,int * errcode)606*4d9fdb46SRobert Mustacchi dwarf_generic_elf_load_symbols32(
607*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
608*4d9fdb46SRobert Mustacchi     struct generic_symentry **gsym_out,
609*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,Dwarf_Unsigned size,
610*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *count_out,int *errcode)
611*4d9fdb46SRobert Mustacchi {
612*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
613*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
614*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
615*4d9fdb46SRobert Mustacchi     dw_elf32_sym *psym = 0;
616*4d9fdb46SRobert Mustacchi     dw_elf32_sym *orig_psym = 0;
617*4d9fdb46SRobert Mustacchi     struct generic_symentry * gsym = 0;
618*4d9fdb46SRobert Mustacchi     struct generic_symentry * orig_gsym = 0;
619*4d9fdb46SRobert Mustacchi     int res = 0;
620*4d9fdb46SRobert Mustacchi 
621*4d9fdb46SRobert Mustacchi     ecount = (long)(size/sizeof(dw_elf32_sym));
622*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf32_sym);
623*4d9fdb46SRobert Mustacchi     if(size != size2) {
624*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
625*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
626*4d9fdb46SRobert Mustacchi     }
627*4d9fdb46SRobert Mustacchi     psym = calloc(ecount,sizeof(dw_elf32_sym));
628*4d9fdb46SRobert Mustacchi     if (!psym) {
629*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
630*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
631*4d9fdb46SRobert Mustacchi     }
632*4d9fdb46SRobert Mustacchi     gsym = calloc(ecount,sizeof(struct generic_symentry));
633*4d9fdb46SRobert Mustacchi     if (!gsym) {
634*4d9fdb46SRobert Mustacchi         free(psym);
635*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
636*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
637*4d9fdb46SRobert Mustacchi     }
638*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,psym,offset,size,
639*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
640*4d9fdb46SRobert Mustacchi     if(res!= DW_DLV_OK) {
641*4d9fdb46SRobert Mustacchi         free(psym);
642*4d9fdb46SRobert Mustacchi         free(gsym);
643*4d9fdb46SRobert Mustacchi         return res;
644*4d9fdb46SRobert Mustacchi     }
645*4d9fdb46SRobert Mustacchi     orig_psym = psym;
646*4d9fdb46SRobert Mustacchi     orig_gsym = gsym;
647*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++psym,++gsym) {
648*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned bind = 0;
649*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned type = 0;
650*4d9fdb46SRobert Mustacchi 
651*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name);
652*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value);
653*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size);
654*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info);
655*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other);
656*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx);
657*4d9fdb46SRobert Mustacchi         bind = gsym->gs_info >> 4;
658*4d9fdb46SRobert Mustacchi         type = gsym->gs_info & 0xf;
659*4d9fdb46SRobert Mustacchi         gsym->gs_bind = bind;
660*4d9fdb46SRobert Mustacchi         gsym->gs_type = type;
661*4d9fdb46SRobert Mustacchi     }
662*4d9fdb46SRobert Mustacchi     *count_out = ecount;
663*4d9fdb46SRobert Mustacchi     *gsym_out = orig_gsym;
664*4d9fdb46SRobert Mustacchi     free(orig_psym);
665*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
666*4d9fdb46SRobert Mustacchi }
667*4d9fdb46SRobert Mustacchi 
668*4d9fdb46SRobert Mustacchi 
669*4d9fdb46SRobert Mustacchi static int
dwarf_generic_elf_load_symbols64(dwarf_elf_object_access_internals_t * ep,struct generic_symentry ** gsym_out,Dwarf_Unsigned offset,Dwarf_Unsigned size,Dwarf_Unsigned * count_out,int * errcode)670*4d9fdb46SRobert Mustacchi dwarf_generic_elf_load_symbols64(
671*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
672*4d9fdb46SRobert Mustacchi     struct generic_symentry **gsym_out,
673*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,Dwarf_Unsigned size,
674*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *count_out,int *errcode)
675*4d9fdb46SRobert Mustacchi {
676*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
677*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
678*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
679*4d9fdb46SRobert Mustacchi     dw_elf64_sym *psym = 0;
680*4d9fdb46SRobert Mustacchi     dw_elf64_sym *orig_psym = 0;
681*4d9fdb46SRobert Mustacchi     struct generic_symentry * gsym = 0;
682*4d9fdb46SRobert Mustacchi     struct generic_symentry * orig_gsym = 0;
683*4d9fdb46SRobert Mustacchi     int res = 0;
684*4d9fdb46SRobert Mustacchi 
685*4d9fdb46SRobert Mustacchi     ecount = (long)(size/sizeof(dw_elf64_sym));
686*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf64_sym);
687*4d9fdb46SRobert Mustacchi     if(size != size2) {
688*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
689*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
690*4d9fdb46SRobert Mustacchi     }
691*4d9fdb46SRobert Mustacchi     psym = calloc(ecount,sizeof(dw_elf64_sym));
692*4d9fdb46SRobert Mustacchi     if (!psym) {
693*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
694*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
695*4d9fdb46SRobert Mustacchi     }
696*4d9fdb46SRobert Mustacchi     gsym = calloc(ecount,sizeof(struct generic_symentry));
697*4d9fdb46SRobert Mustacchi     if (!gsym) {
698*4d9fdb46SRobert Mustacchi         free(psym);
699*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
700*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
701*4d9fdb46SRobert Mustacchi     }
702*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,psym,offset,size,
703*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
704*4d9fdb46SRobert Mustacchi     if(res!= DW_DLV_OK) {
705*4d9fdb46SRobert Mustacchi         free(psym);
706*4d9fdb46SRobert Mustacchi         free(gsym);
707*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
708*4d9fdb46SRobert Mustacchi         return res;
709*4d9fdb46SRobert Mustacchi     }
710*4d9fdb46SRobert Mustacchi     orig_psym = psym;
711*4d9fdb46SRobert Mustacchi     orig_gsym = gsym;
712*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++psym,++gsym) {
713*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned bind = 0;
714*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned type = 0;
715*4d9fdb46SRobert Mustacchi 
716*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name);
717*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value);
718*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size);
719*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info);
720*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other);
721*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx);
722*4d9fdb46SRobert Mustacchi         bind = gsym->gs_info >> 4;
723*4d9fdb46SRobert Mustacchi         type = gsym->gs_info & 0xf;
724*4d9fdb46SRobert Mustacchi         gsym->gs_bind = bind;
725*4d9fdb46SRobert Mustacchi         gsym->gs_type = type;
726*4d9fdb46SRobert Mustacchi     }
727*4d9fdb46SRobert Mustacchi     *count_out = ecount;
728*4d9fdb46SRobert Mustacchi     *gsym_out = orig_gsym;
729*4d9fdb46SRobert Mustacchi     free(orig_psym);
730*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
731*4d9fdb46SRobert Mustacchi }
732*4d9fdb46SRobert Mustacchi 
733*4d9fdb46SRobert Mustacchi static int
dwarf_generic_elf_load_symbols(dwarf_elf_object_access_internals_t * ep,int secnum,struct generic_shdr * psh,struct generic_symentry ** gsym_out,Dwarf_Unsigned * count_out,int * errcode)734*4d9fdb46SRobert Mustacchi dwarf_generic_elf_load_symbols(
735*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
736*4d9fdb46SRobert Mustacchi     int secnum,
737*4d9fdb46SRobert Mustacchi     struct generic_shdr *psh,
738*4d9fdb46SRobert Mustacchi     struct generic_symentry **gsym_out,
739*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *count_out,int *errcode)
740*4d9fdb46SRobert Mustacchi {
741*4d9fdb46SRobert Mustacchi     int res = 0;
742*4d9fdb46SRobert Mustacchi     struct generic_symentry *gsym = 0;
743*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
744*4d9fdb46SRobert Mustacchi 
745*4d9fdb46SRobert Mustacchi     if(!secnum) {
746*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
747*4d9fdb46SRobert Mustacchi     }
748*4d9fdb46SRobert Mustacchi     if (ep->f_offsetsize == 32) {
749*4d9fdb46SRobert Mustacchi         res = dwarf_generic_elf_load_symbols32(ep,
750*4d9fdb46SRobert Mustacchi             &gsym,
751*4d9fdb46SRobert Mustacchi             psh->gh_offset,psh->gh_size,
752*4d9fdb46SRobert Mustacchi             &count,errcode);
753*4d9fdb46SRobert Mustacchi     } else if (ep->f_offsetsize == 64) {
754*4d9fdb46SRobert Mustacchi         res = dwarf_generic_elf_load_symbols64(ep,
755*4d9fdb46SRobert Mustacchi             &gsym,
756*4d9fdb46SRobert Mustacchi             psh->gh_offset,psh->gh_size,
757*4d9fdb46SRobert Mustacchi             &count,errcode);
758*4d9fdb46SRobert Mustacchi     } else {
759*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
760*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
761*4d9fdb46SRobert Mustacchi     }
762*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
763*4d9fdb46SRobert Mustacchi         *gsym_out = gsym;
764*4d9fdb46SRobert Mustacchi         *count_out = count;
765*4d9fdb46SRobert Mustacchi     }
766*4d9fdb46SRobert Mustacchi     return res;
767*4d9fdb46SRobert Mustacchi }
768*4d9fdb46SRobert Mustacchi #if 0
769*4d9fdb46SRobert Mustacchi int
770*4d9fdb46SRobert Mustacchi dwarf_load_elf_dynsym_symbols(
771*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep, int*errcode)
772*4d9fdb46SRobert Mustacchi {
773*4d9fdb46SRobert Mustacchi     int res = 0;
774*4d9fdb46SRobert Mustacchi     struct generic_symentry *gsym = 0;
775*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
776*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secnum = ep->f_dynsym_sect_index;
777*4d9fdb46SRobert Mustacchi     struct generic_shdr * psh = 0;
778*4d9fdb46SRobert Mustacchi 
779*4d9fdb46SRobert Mustacchi     if(!secnum) {
780*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
781*4d9fdb46SRobert Mustacchi     }
782*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr + secnum;
783*4d9fdb46SRobert Mustacchi     res = dwarf_generic_elf_load_symbols(ep,
784*4d9fdb46SRobert Mustacchi         secnum,
785*4d9fdb46SRobert Mustacchi         psh,
786*4d9fdb46SRobert Mustacchi         &gsym,
787*4d9fdb46SRobert Mustacchi         &count,errcode);
788*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
789*4d9fdb46SRobert Mustacchi         ep->f_dynsym = gsym;
790*4d9fdb46SRobert Mustacchi         ep->f_loc_dynsym.g_count = count;
791*4d9fdb46SRobert Mustacchi     }
792*4d9fdb46SRobert Mustacchi     return res;
793*4d9fdb46SRobert Mustacchi }
794*4d9fdb46SRobert Mustacchi #endif /* 0 */
795*4d9fdb46SRobert Mustacchi 
796*4d9fdb46SRobert Mustacchi int
_dwarf_load_elf_symtab_symbols(dwarf_elf_object_access_internals_t * ep,int * errcode)797*4d9fdb46SRobert Mustacchi _dwarf_load_elf_symtab_symbols(
798*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep, int*errcode)
799*4d9fdb46SRobert Mustacchi {
800*4d9fdb46SRobert Mustacchi     int res = 0;
801*4d9fdb46SRobert Mustacchi     struct generic_symentry *gsym = 0;
802*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
803*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secnum = ep->f_symtab_sect_index;
804*4d9fdb46SRobert Mustacchi     struct generic_shdr * psh = 0;
805*4d9fdb46SRobert Mustacchi 
806*4d9fdb46SRobert Mustacchi     if(!secnum) {
807*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
808*4d9fdb46SRobert Mustacchi     }
809*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr + secnum;
810*4d9fdb46SRobert Mustacchi     res = dwarf_generic_elf_load_symbols(ep,
811*4d9fdb46SRobert Mustacchi         secnum,
812*4d9fdb46SRobert Mustacchi         psh,
813*4d9fdb46SRobert Mustacchi         &gsym,
814*4d9fdb46SRobert Mustacchi         &count,errcode);
815*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
816*4d9fdb46SRobert Mustacchi         ep->f_symtab = gsym;
817*4d9fdb46SRobert Mustacchi         ep->f_loc_symtab.g_count = count;
818*4d9fdb46SRobert Mustacchi     }
819*4d9fdb46SRobert Mustacchi     return res;
820*4d9fdb46SRobert Mustacchi }
821*4d9fdb46SRobert Mustacchi 
822*4d9fdb46SRobert Mustacchi static int
generic_rel_from_rela32(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gsh,dw_elf32_rela * relp,struct generic_rela * grel,int * errcode)823*4d9fdb46SRobert Mustacchi generic_rel_from_rela32(
824*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
825*4d9fdb46SRobert Mustacchi     struct generic_shdr * gsh,
826*4d9fdb46SRobert Mustacchi     dw_elf32_rela *relp,
827*4d9fdb46SRobert Mustacchi     struct generic_rela *grel,
828*4d9fdb46SRobert Mustacchi     int *errcode)
829*4d9fdb46SRobert Mustacchi {
830*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
831*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = gsh->gh_size;
832*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
833*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
834*4d9fdb46SRobert Mustacchi 
835*4d9fdb46SRobert Mustacchi     ecount = size/sizeof(dw_elf32_rela);
836*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf32_rela);
837*4d9fdb46SRobert Mustacchi     if(size != size2) {
838*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
839*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
840*4d9fdb46SRobert Mustacchi     }
841*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++relp,++grel) {
842*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset);
843*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info);
844*4d9fdb46SRobert Mustacchi         /* addend signed */
845*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend);
846*4d9fdb46SRobert Mustacchi         SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend));
847*4d9fdb46SRobert Mustacchi         grel->gr_sym  = grel->gr_info>>8; /* ELF32_R_SYM */
848*4d9fdb46SRobert Mustacchi         grel->gr_type = grel->gr_info & 0xff;
849*4d9fdb46SRobert Mustacchi         grel->gr_is_rela = TRUE;
850*4d9fdb46SRobert Mustacchi     }
851*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
852*4d9fdb46SRobert Mustacchi }
853*4d9fdb46SRobert Mustacchi 
854*4d9fdb46SRobert Mustacchi static int
generic_rel_from_rela64(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gsh,dw_elf64_rela * relp,struct generic_rela * grel,int * errcode)855*4d9fdb46SRobert Mustacchi generic_rel_from_rela64(
856*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
857*4d9fdb46SRobert Mustacchi     struct generic_shdr * gsh,
858*4d9fdb46SRobert Mustacchi     dw_elf64_rela *relp,
859*4d9fdb46SRobert Mustacchi     struct generic_rela *grel, int *errcode)
860*4d9fdb46SRobert Mustacchi {
861*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
862*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = gsh->gh_size;
863*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
864*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
865*4d9fdb46SRobert Mustacchi     int objlittleendian = (ep->f_endian == DW_OBJECT_LSB);
866*4d9fdb46SRobert Mustacchi     int ismips64 = (ep->f_machine == EM_MIPS);
867*4d9fdb46SRobert Mustacchi     int issparcv9 = (ep->f_machine == EM_SPARCV9);
868*4d9fdb46SRobert Mustacchi 
869*4d9fdb46SRobert Mustacchi     ecount = size/sizeof(dw_elf64_rela);
870*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf64_rela);
871*4d9fdb46SRobert Mustacchi     if(size != size2) {
872*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
873*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
874*4d9fdb46SRobert Mustacchi     }
875*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++relp,++grel) {
876*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset);
877*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info);
878*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend);
879*4d9fdb46SRobert Mustacchi         SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend));
880*4d9fdb46SRobert Mustacchi         if (ismips64 && objlittleendian ) {
881*4d9fdb46SRobert Mustacchi             char realsym[4];
882*4d9fdb46SRobert Mustacchi 
883*4d9fdb46SRobert Mustacchi             memcpy(realsym,&relp->r_info,sizeof(realsym));
884*4d9fdb46SRobert Mustacchi             ASNAR(ep->f_copy_word,grel->gr_sym,realsym);
885*4d9fdb46SRobert Mustacchi             grel->gr_type  = relp->r_info[7];
886*4d9fdb46SRobert Mustacchi             grel->gr_type2 = relp->r_info[6];
887*4d9fdb46SRobert Mustacchi             grel->gr_type3 = relp->r_info[5];
888*4d9fdb46SRobert Mustacchi         } else if (issparcv9) {
889*4d9fdb46SRobert Mustacchi             /*  Always Big Endian?  */
890*4d9fdb46SRobert Mustacchi             char realsym[4];
891*4d9fdb46SRobert Mustacchi 
892*4d9fdb46SRobert Mustacchi             memcpy(realsym,&relp->r_info,sizeof(realsym));
893*4d9fdb46SRobert Mustacchi             ASNAR(ep->f_copy_word,grel->gr_sym,realsym);
894*4d9fdb46SRobert Mustacchi             grel->gr_type  = relp->r_info[7];
895*4d9fdb46SRobert Mustacchi         } else {
896*4d9fdb46SRobert Mustacchi             grel->gr_sym  = grel->gr_info >> 32;
897*4d9fdb46SRobert Mustacchi             grel->gr_type = grel->gr_info & 0xffffffff;
898*4d9fdb46SRobert Mustacchi         }
899*4d9fdb46SRobert Mustacchi         grel->gr_is_rela = TRUE;
900*4d9fdb46SRobert Mustacchi     }
901*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
902*4d9fdb46SRobert Mustacchi }
903*4d9fdb46SRobert Mustacchi 
904*4d9fdb46SRobert Mustacchi static int
generic_rel_from_rel32(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gsh,dw_elf32_rel * relp,struct generic_rela * grel,int * errcode)905*4d9fdb46SRobert Mustacchi generic_rel_from_rel32(
906*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
907*4d9fdb46SRobert Mustacchi     struct generic_shdr * gsh,
908*4d9fdb46SRobert Mustacchi     dw_elf32_rel *relp,
909*4d9fdb46SRobert Mustacchi     struct generic_rela *grel,int *errcode)
910*4d9fdb46SRobert Mustacchi {
911*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
912*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = gsh->gh_size;
913*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
914*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
915*4d9fdb46SRobert Mustacchi 
916*4d9fdb46SRobert Mustacchi     ecount = size/sizeof(dw_elf32_rel);
917*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf32_rel);
918*4d9fdb46SRobert Mustacchi     if(size != size2) {
919*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
920*4d9fdb46SRobert Mustacchi         return  DW_DLV_ERROR;
921*4d9fdb46SRobert Mustacchi     }
922*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++relp,++grel) {
923*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset);
924*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info);
925*4d9fdb46SRobert Mustacchi         grel->gr_addend  = 0; /* Unused for plain .rel */
926*4d9fdb46SRobert Mustacchi         grel->gr_sym  = grel->gr_info >>8; /* ELF32_R_SYM */
927*4d9fdb46SRobert Mustacchi         grel->gr_is_rela = FALSE;
928*4d9fdb46SRobert Mustacchi         grel->gr_type = grel->gr_info & 0xff;
929*4d9fdb46SRobert Mustacchi     }
930*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
931*4d9fdb46SRobert Mustacchi }
932*4d9fdb46SRobert Mustacchi 
933*4d9fdb46SRobert Mustacchi static int
generic_rel_from_rel64(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gsh,dw_elf64_rel * relp,struct generic_rela * grel,int * errcode)934*4d9fdb46SRobert Mustacchi generic_rel_from_rel64(
935*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
936*4d9fdb46SRobert Mustacchi     struct generic_shdr * gsh,
937*4d9fdb46SRobert Mustacchi     dw_elf64_rel *relp,
938*4d9fdb46SRobert Mustacchi     struct generic_rela *grel,int *errcode)
939*4d9fdb46SRobert Mustacchi {
940*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned ecount = 0;
941*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = gsh->gh_size;
942*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
943*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
944*4d9fdb46SRobert Mustacchi     int objlittleendian = (ep->f_endian == DW_OBJECT_LSB);
945*4d9fdb46SRobert Mustacchi     int ismips64 = (ep->f_machine == EM_MIPS);
946*4d9fdb46SRobert Mustacchi     int issparcv9 = (ep->f_machine == EM_SPARCV9);
947*4d9fdb46SRobert Mustacchi 
948*4d9fdb46SRobert Mustacchi     ecount = size/sizeof(dw_elf64_rel);
949*4d9fdb46SRobert Mustacchi     size2 = ecount * sizeof(dw_elf64_rel);
950*4d9fdb46SRobert Mustacchi     if(size != size2) {
951*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
952*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
953*4d9fdb46SRobert Mustacchi     }
954*4d9fdb46SRobert Mustacchi     for ( i = 0; i < ecount; ++i,++relp,++grel) {
955*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset);
956*4d9fdb46SRobert Mustacchi         ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info);
957*4d9fdb46SRobert Mustacchi         grel->gr_addend  = 0; /* Unused for plain .rel */
958*4d9fdb46SRobert Mustacchi         if (ismips64 && objlittleendian ) {
959*4d9fdb46SRobert Mustacchi             char realsym[4];
960*4d9fdb46SRobert Mustacchi 
961*4d9fdb46SRobert Mustacchi             memcpy(realsym,&relp->r_info,sizeof(realsym));
962*4d9fdb46SRobert Mustacchi             ASNAR(ep->f_copy_word,grel->gr_sym,realsym);
963*4d9fdb46SRobert Mustacchi             grel->gr_type  = relp->r_info[7];
964*4d9fdb46SRobert Mustacchi             grel->gr_type2 = relp->r_info[6];
965*4d9fdb46SRobert Mustacchi             grel->gr_type3 = relp->r_info[5];
966*4d9fdb46SRobert Mustacchi         } else if (issparcv9) {
967*4d9fdb46SRobert Mustacchi             /*  Always Big Endian?  */
968*4d9fdb46SRobert Mustacchi             char realsym[4];
969*4d9fdb46SRobert Mustacchi 
970*4d9fdb46SRobert Mustacchi             memcpy(realsym,&relp->r_info,sizeof(realsym));
971*4d9fdb46SRobert Mustacchi             ASNAR(ep->f_copy_word,grel->gr_sym,realsym);
972*4d9fdb46SRobert Mustacchi             grel->gr_type  = relp->r_info[7];
973*4d9fdb46SRobert Mustacchi         } else {
974*4d9fdb46SRobert Mustacchi             grel->gr_sym  = grel->gr_info >>32;
975*4d9fdb46SRobert Mustacchi             grel->gr_type = grel->gr_info & 0xffffffff;
976*4d9fdb46SRobert Mustacchi         }
977*4d9fdb46SRobert Mustacchi         grel->gr_is_rela = FALSE;
978*4d9fdb46SRobert Mustacchi     }
979*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
980*4d9fdb46SRobert Mustacchi }
981*4d9fdb46SRobert Mustacchi 
982*4d9fdb46SRobert Mustacchi #if 0
983*4d9fdb46SRobert Mustacchi int
984*4d9fdb46SRobert Mustacchi dwarf_load_elf_dynstr(
985*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep, int *errcode)
986*4d9fdb46SRobert Mustacchi {
987*4d9fdb46SRobert Mustacchi     struct generic_shdr *strpsh = 0;
988*4d9fdb46SRobert Mustacchi     int res = 0;
989*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned strsectindex  =0;
990*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned strsectlength = 0;
991*4d9fdb46SRobert Mustacchi 
992*4d9fdb46SRobert Mustacchi         if (!ep->f_dynsym_sect_strings_sect_index) {
993*4d9fdb46SRobert Mustacchi             return DW_DLV_NO_ENTRY;
994*4d9fdb46SRobert Mustacchi         }
995*4d9fdb46SRobert Mustacchi         strsectindex = ep->f_dynsym_sect_strings_sect_index;
996*4d9fdb46SRobert Mustacchi         strsectlength = ep->f_dynsym_sect_strings_max;
997*4d9fdb46SRobert Mustacchi         strpsh = ep->f_shdr + strsectindex;
998*4d9fdb46SRobert Mustacchi         /*  Alloc an extra byte as a guaranteed NUL byte
999*4d9fdb46SRobert Mustacchi             at the end of the strings in case the section
1000*4d9fdb46SRobert Mustacchi             is corrupted and lacks a NUL at end. */
1001*4d9fdb46SRobert Mustacchi         ep->f_dynsym_sect_strings = calloc(1,strsectlength+1);
1002*4d9fdb46SRobert Mustacchi         if(!ep->f_dynsym_sect_strings) {
1003*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings = 0;
1004*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_max = 0;
1005*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_sect_index = 0;
1006*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
1007*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1008*4d9fdb46SRobert Mustacchi         }
1009*4d9fdb46SRobert Mustacchi         res = RRMOA(ep->f_fd,ep->f_dynsym_sect_strings,
1010*4d9fdb46SRobert Mustacchi             strpsh->gh_offset,
1011*4d9fdb46SRobert Mustacchi             strsectlength,
1012*4d9fdb46SRobert Mustacchi             ep->f_filesize,errcode);
1013*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1014*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings = 0;
1015*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_max = 0;
1016*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_sect_index = 0;
1017*4d9fdb46SRobert Mustacchi             return res;
1018*4d9fdb46SRobert Mustacchi         }
1019*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1020*4d9fdb46SRobert Mustacchi }
1021*4d9fdb46SRobert Mustacchi #endif /* 0 */
1022*4d9fdb46SRobert Mustacchi 
1023*4d9fdb46SRobert Mustacchi int
_dwarf_load_elf_symstr(dwarf_elf_object_access_internals_t * ep,int * errcode)1024*4d9fdb46SRobert Mustacchi _dwarf_load_elf_symstr(
1025*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep, int *errcode)
1026*4d9fdb46SRobert Mustacchi {
1027*4d9fdb46SRobert Mustacchi     struct generic_shdr *strpsh = 0;
1028*4d9fdb46SRobert Mustacchi     int res = 0;
1029*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned strsectindex  =0;
1030*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned strsectlength = 0;
1031*4d9fdb46SRobert Mustacchi 
1032*4d9fdb46SRobert Mustacchi     if (!ep->f_symtab_sect_strings_sect_index) {
1033*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1034*4d9fdb46SRobert Mustacchi     }
1035*4d9fdb46SRobert Mustacchi     strsectindex = ep->f_symtab_sect_strings_sect_index;
1036*4d9fdb46SRobert Mustacchi     strsectlength = ep->f_symtab_sect_strings_max;
1037*4d9fdb46SRobert Mustacchi     strpsh = ep->f_shdr + strsectindex;
1038*4d9fdb46SRobert Mustacchi     /*  Alloc an extra byte as a guaranteed NUL byte
1039*4d9fdb46SRobert Mustacchi         at the end of the strings in case the section
1040*4d9fdb46SRobert Mustacchi         is corrupted and lacks a NUL at end. */
1041*4d9fdb46SRobert Mustacchi     ep->f_symtab_sect_strings = calloc(1,strsectlength+1);
1042*4d9fdb46SRobert Mustacchi     if(!ep->f_symtab_sect_strings) {
1043*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings = 0;
1044*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings_max = 0;
1045*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings_sect_index = 0;
1046*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
1047*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1048*4d9fdb46SRobert Mustacchi     }
1049*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,ep->f_symtab_sect_strings,
1050*4d9fdb46SRobert Mustacchi         strpsh->gh_offset,
1051*4d9fdb46SRobert Mustacchi         strsectlength,
1052*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
1053*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1054*4d9fdb46SRobert Mustacchi         free(ep->f_symtab_sect_strings);
1055*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings = 0;
1056*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings_max = 0;
1057*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings_sect_index = 0;
1058*4d9fdb46SRobert Mustacchi         return res;
1059*4d9fdb46SRobert Mustacchi     }
1060*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1061*4d9fdb46SRobert Mustacchi }
1062*4d9fdb46SRobert Mustacchi 
1063*4d9fdb46SRobert Mustacchi 
1064*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_load_sectstrings(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned stringsection,int * errcode)1065*4d9fdb46SRobert Mustacchi _dwarf_elf_load_sectstrings(
1066*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1067*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned stringsection,
1068*4d9fdb46SRobert Mustacchi     int *errcode)
1069*4d9fdb46SRobert Mustacchi {
1070*4d9fdb46SRobert Mustacchi     int res = 0;
1071*4d9fdb46SRobert Mustacchi     struct generic_shdr *psh = 0;
1072*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secoffset = 0;
1073*4d9fdb46SRobert Mustacchi 
1074*4d9fdb46SRobert Mustacchi     ep->f_elf_shstrings_length = 0;
1075*4d9fdb46SRobert Mustacchi     if (stringsection >= ep->f_ehdr->ge_shnum) {
1076*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_INDEX_BAD;
1077*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1078*4d9fdb46SRobert Mustacchi     }
1079*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr + stringsection;
1080*4d9fdb46SRobert Mustacchi     secoffset = psh->gh_offset;
1081*4d9fdb46SRobert Mustacchi     if(is_empty_section(psh->gh_type)) {
1082*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_STRING_SECTION_MISSING;
1083*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1084*4d9fdb46SRobert Mustacchi     }
1085*4d9fdb46SRobert Mustacchi     if(psh->gh_size > ep->f_elf_shstrings_max) {
1086*4d9fdb46SRobert Mustacchi         free(ep->f_elf_shstrings_data);
1087*4d9fdb46SRobert Mustacchi         ep->f_elf_shstrings_data = (char *)malloc(psh->gh_size);
1088*4d9fdb46SRobert Mustacchi         ep->f_elf_shstrings_max = psh->gh_size;
1089*4d9fdb46SRobert Mustacchi         if(!ep->f_elf_shstrings_data) {
1090*4d9fdb46SRobert Mustacchi             ep->f_elf_shstrings_max = 0;
1091*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
1092*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1093*4d9fdb46SRobert Mustacchi         }
1094*4d9fdb46SRobert Mustacchi     }
1095*4d9fdb46SRobert Mustacchi     ep->f_elf_shstrings_length = psh->gh_size;
1096*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,ep->f_elf_shstrings_data,secoffset,
1097*4d9fdb46SRobert Mustacchi         psh->gh_size,
1098*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
1099*4d9fdb46SRobert Mustacchi     return res;
1100*4d9fdb46SRobert Mustacchi }
1101*4d9fdb46SRobert Mustacchi 
1102*4d9fdb46SRobert Mustacchi static int
elf_load_sectheaders32(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned offset,Dwarf_Unsigned entsize,Dwarf_Unsigned count,int * errcode)1103*4d9fdb46SRobert Mustacchi elf_load_sectheaders32(
1104*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1105*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,Dwarf_Unsigned entsize,
1106*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,int *errcode)
1107*4d9fdb46SRobert Mustacchi {
1108*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned generic_count = 0;
1109*4d9fdb46SRobert Mustacchi     int res = 0;
1110*4d9fdb46SRobert Mustacchi 
1111*4d9fdb46SRobert Mustacchi 
1112*4d9fdb46SRobert Mustacchi     if(count == 0) {
1113*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1114*4d9fdb46SRobert Mustacchi     }
1115*4d9fdb46SRobert Mustacchi     if(entsize < sizeof(dw_elf32_shdr)) {
1116*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
1117*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1118*4d9fdb46SRobert Mustacchi     }
1119*4d9fdb46SRobert Mustacchi     if ((offset > ep->f_filesize)||
1120*4d9fdb46SRobert Mustacchi         (entsize > 200)||
1121*4d9fdb46SRobert Mustacchi         (count > ep->f_filesize) ||
1122*4d9fdb46SRobert Mustacchi         ((count *entsize +offset) > ep->f_filesize)) {
1123*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
1124*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1125*4d9fdb46SRobert Mustacchi     }
1126*4d9fdb46SRobert Mustacchi     res = generic_shdr_from_shdr32(ep,&generic_count,
1127*4d9fdb46SRobert Mustacchi         offset,entsize,count,errcode);
1128*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1129*4d9fdb46SRobert Mustacchi         return res;
1130*4d9fdb46SRobert Mustacchi     }
1131*4d9fdb46SRobert Mustacchi     if (generic_count != count) {
1132*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH;
1133*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1134*4d9fdb46SRobert Mustacchi     }
1135*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1136*4d9fdb46SRobert Mustacchi }
1137*4d9fdb46SRobert Mustacchi 
1138*4d9fdb46SRobert Mustacchi static int
elf_load_sectheaders64(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned offset,Dwarf_Unsigned entsize,Dwarf_Unsigned count,int * errcode)1139*4d9fdb46SRobert Mustacchi elf_load_sectheaders64(
1140*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1141*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset,Dwarf_Unsigned entsize,
1142*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count,int*errcode)
1143*4d9fdb46SRobert Mustacchi {
1144*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned generic_count = 0;
1145*4d9fdb46SRobert Mustacchi     int res = 0;
1146*4d9fdb46SRobert Mustacchi 
1147*4d9fdb46SRobert Mustacchi 
1148*4d9fdb46SRobert Mustacchi     if(count == 0) {
1149*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1150*4d9fdb46SRobert Mustacchi     }
1151*4d9fdb46SRobert Mustacchi     if(entsize < sizeof(dw_elf64_shdr)) {
1152*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_SIZE_ERROR;
1153*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1154*4d9fdb46SRobert Mustacchi     }
1155*4d9fdb46SRobert Mustacchi     if ((offset > ep->f_filesize)||
1156*4d9fdb46SRobert Mustacchi         (entsize > 200)||
1157*4d9fdb46SRobert Mustacchi         (count > ep->f_filesize) ||
1158*4d9fdb46SRobert Mustacchi         ((count *entsize +offset) > ep->f_filesize)) {
1159*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
1160*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1161*4d9fdb46SRobert Mustacchi     }
1162*4d9fdb46SRobert Mustacchi     res = generic_shdr_from_shdr64(ep,&generic_count,
1163*4d9fdb46SRobert Mustacchi         offset,entsize,count,errcode);
1164*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1165*4d9fdb46SRobert Mustacchi         return res;
1166*4d9fdb46SRobert Mustacchi     }
1167*4d9fdb46SRobert Mustacchi     if (generic_count != count) {
1168*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH;
1169*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1170*4d9fdb46SRobert Mustacchi     }
1171*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1172*4d9fdb46SRobert Mustacchi }
1173*4d9fdb46SRobert Mustacchi 
1174*4d9fdb46SRobert Mustacchi 
1175*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_load_a_relx_batch(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gsh,struct generic_rela ** grel_out,Dwarf_Unsigned * count_out,enum RelocRela localrela,enum RelocOffsetSize localoffsize,int * errcode)1176*4d9fdb46SRobert Mustacchi _dwarf_elf_load_a_relx_batch(
1177*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1178*4d9fdb46SRobert Mustacchi     struct generic_shdr * gsh,
1179*4d9fdb46SRobert Mustacchi     struct generic_rela ** grel_out,
1180*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned *count_out,
1181*4d9fdb46SRobert Mustacchi     enum RelocRela localrela,
1182*4d9fdb46SRobert Mustacchi     enum RelocOffsetSize localoffsize,
1183*4d9fdb46SRobert Mustacchi     int *errcode)
1184*4d9fdb46SRobert Mustacchi {
1185*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
1186*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size = 0;
1187*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned size2 = 0;
1188*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned sizeg = 0;
1189*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned offset = 0;
1190*4d9fdb46SRobert Mustacchi     int res = 0;
1191*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned object_reclen = 0;
1192*4d9fdb46SRobert Mustacchi     struct generic_rela *grel = 0;
1193*4d9fdb46SRobert Mustacchi 
1194*4d9fdb46SRobert Mustacchi     /*  ASSERT: Caller guarantees localoffsetsize
1195*4d9fdb46SRobert Mustacchi         is a valid 4 or 8. */
1196*4d9fdb46SRobert Mustacchi     /*  ASSERT: Caller guarantees localrela is one
1197*4d9fdb46SRobert Mustacchi         of the 2 valid values 1 or 2 */
1198*4d9fdb46SRobert Mustacchi 
1199*4d9fdb46SRobert Mustacchi     offset = gsh->gh_offset;
1200*4d9fdb46SRobert Mustacchi     size = gsh->gh_size;
1201*4d9fdb46SRobert Mustacchi     if(size == 0) {
1202*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1203*4d9fdb46SRobert Mustacchi     }
1204*4d9fdb46SRobert Mustacchi     if ((offset > ep->f_filesize)||
1205*4d9fdb46SRobert Mustacchi         (size > ep->f_filesize) ||
1206*4d9fdb46SRobert Mustacchi         ((size +offset) > ep->f_filesize)) {
1207*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
1208*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1209*4d9fdb46SRobert Mustacchi     }
1210*4d9fdb46SRobert Mustacchi     if (localoffsize == RelocOffset32) {
1211*4d9fdb46SRobert Mustacchi         if (localrela ==  RelocIsRela) {
1212*4d9fdb46SRobert Mustacchi             object_reclen = sizeof(dw_elf32_rela);
1213*4d9fdb46SRobert Mustacchi             count = (long)(size/object_reclen);
1214*4d9fdb46SRobert Mustacchi             size2 = count * object_reclen;
1215*4d9fdb46SRobert Mustacchi             if(size != size2) {
1216*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_SECTION_SIZE_ERROR;
1217*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1218*4d9fdb46SRobert Mustacchi             }
1219*4d9fdb46SRobert Mustacchi         } else {
1220*4d9fdb46SRobert Mustacchi             object_reclen = sizeof(dw_elf32_rel);
1221*4d9fdb46SRobert Mustacchi             count = (long)(size/object_reclen);
1222*4d9fdb46SRobert Mustacchi             size2 = count * object_reclen;
1223*4d9fdb46SRobert Mustacchi             if(size != size2) {
1224*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_SECTION_SIZE_ERROR;
1225*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1226*4d9fdb46SRobert Mustacchi             }
1227*4d9fdb46SRobert Mustacchi         }
1228*4d9fdb46SRobert Mustacchi     } else {
1229*4d9fdb46SRobert Mustacchi         if (localrela ==  RelocIsRela) {
1230*4d9fdb46SRobert Mustacchi             object_reclen = sizeof(dw_elf64_rela);
1231*4d9fdb46SRobert Mustacchi             count = (long)(size/object_reclen);
1232*4d9fdb46SRobert Mustacchi             size2 = count * object_reclen;
1233*4d9fdb46SRobert Mustacchi             if(size != size2) {
1234*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_SECTION_SIZE_ERROR;
1235*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1236*4d9fdb46SRobert Mustacchi             }
1237*4d9fdb46SRobert Mustacchi         } else {
1238*4d9fdb46SRobert Mustacchi             object_reclen = sizeof(dw_elf64_rel);
1239*4d9fdb46SRobert Mustacchi             count = (long)(size/object_reclen);
1240*4d9fdb46SRobert Mustacchi             size2 = count * object_reclen;
1241*4d9fdb46SRobert Mustacchi             if(size != size2) {
1242*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_SECTION_SIZE_ERROR;
1243*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1244*4d9fdb46SRobert Mustacchi             }
1245*4d9fdb46SRobert Mustacchi         }
1246*4d9fdb46SRobert Mustacchi     }
1247*4d9fdb46SRobert Mustacchi     sizeg = count*sizeof(struct generic_rela);
1248*4d9fdb46SRobert Mustacchi     grel = (struct generic_rela *)malloc(sizeg);
1249*4d9fdb46SRobert Mustacchi     if (!grel) {
1250*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
1251*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1252*4d9fdb46SRobert Mustacchi     }
1253*4d9fdb46SRobert Mustacchi     if (localoffsize == RelocOffset32) {
1254*4d9fdb46SRobert Mustacchi         if (localrela ==  RelocIsRela) {
1255*4d9fdb46SRobert Mustacchi             dw_elf32_rela *relp = 0;
1256*4d9fdb46SRobert Mustacchi             relp = (dw_elf32_rela *)malloc(size);
1257*4d9fdb46SRobert Mustacchi             if(!relp) {
1258*4d9fdb46SRobert Mustacchi                 free(grel);
1259*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ALLOC_FAIL;
1260*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1261*4d9fdb46SRobert Mustacchi             }
1262*4d9fdb46SRobert Mustacchi             res = RRMOA(ep->f_fd,relp,offset,size,
1263*4d9fdb46SRobert Mustacchi                 ep->f_filesize,errcode);
1264*4d9fdb46SRobert Mustacchi             if(res != DW_DLV_OK) {
1265*4d9fdb46SRobert Mustacchi                 free(relp);
1266*4d9fdb46SRobert Mustacchi                 free(grel);
1267*4d9fdb46SRobert Mustacchi                 return res;
1268*4d9fdb46SRobert Mustacchi             }
1269*4d9fdb46SRobert Mustacchi             res = generic_rel_from_rela32(ep,gsh,relp,grel,errcode);
1270*4d9fdb46SRobert Mustacchi             free(relp);
1271*4d9fdb46SRobert Mustacchi         } else {
1272*4d9fdb46SRobert Mustacchi             dw_elf32_rel *relp = 0;
1273*4d9fdb46SRobert Mustacchi             relp = (dw_elf32_rel *)malloc(size);
1274*4d9fdb46SRobert Mustacchi             if(!relp) {
1275*4d9fdb46SRobert Mustacchi                 free(grel);
1276*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ALLOC_FAIL;
1277*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1278*4d9fdb46SRobert Mustacchi             }
1279*4d9fdb46SRobert Mustacchi             res = RRMOA(ep->f_fd,relp,offset,size,
1280*4d9fdb46SRobert Mustacchi                 ep->f_filesize,errcode);
1281*4d9fdb46SRobert Mustacchi             if(res != DW_DLV_OK) {
1282*4d9fdb46SRobert Mustacchi                 free(relp);
1283*4d9fdb46SRobert Mustacchi                 free(grel);
1284*4d9fdb46SRobert Mustacchi                 return res;
1285*4d9fdb46SRobert Mustacchi             }
1286*4d9fdb46SRobert Mustacchi             res = generic_rel_from_rel32(ep,gsh,relp,grel,errcode);
1287*4d9fdb46SRobert Mustacchi             free(relp);
1288*4d9fdb46SRobert Mustacchi         }
1289*4d9fdb46SRobert Mustacchi     } else {
1290*4d9fdb46SRobert Mustacchi         if (localrela ==  RelocIsRela) {
1291*4d9fdb46SRobert Mustacchi             dw_elf64_rela *relp = 0;
1292*4d9fdb46SRobert Mustacchi             relp = (dw_elf64_rela *)malloc(size);
1293*4d9fdb46SRobert Mustacchi             if(!relp) {
1294*4d9fdb46SRobert Mustacchi                 free(grel);
1295*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ALLOC_FAIL;
1296*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1297*4d9fdb46SRobert Mustacchi             }
1298*4d9fdb46SRobert Mustacchi             res = RRMOA(ep->f_fd,relp,offset,size,
1299*4d9fdb46SRobert Mustacchi                 ep->f_filesize,errcode);
1300*4d9fdb46SRobert Mustacchi             if(res != DW_DLV_OK) {
1301*4d9fdb46SRobert Mustacchi                 free(relp);
1302*4d9fdb46SRobert Mustacchi                 free(grel);
1303*4d9fdb46SRobert Mustacchi                 return res;
1304*4d9fdb46SRobert Mustacchi             }
1305*4d9fdb46SRobert Mustacchi             res = generic_rel_from_rela64(ep,gsh,relp,grel,errcode);
1306*4d9fdb46SRobert Mustacchi             free(relp);
1307*4d9fdb46SRobert Mustacchi         } else {
1308*4d9fdb46SRobert Mustacchi             dw_elf64_rel *relp = 0;
1309*4d9fdb46SRobert Mustacchi             relp = (dw_elf64_rel *)malloc(size);
1310*4d9fdb46SRobert Mustacchi             if(!relp) {
1311*4d9fdb46SRobert Mustacchi                 free(grel);
1312*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ALLOC_FAIL;
1313*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1314*4d9fdb46SRobert Mustacchi             }
1315*4d9fdb46SRobert Mustacchi             res = RRMOA(ep->f_fd,relp,offset,size,
1316*4d9fdb46SRobert Mustacchi                 ep->f_filesize,errcode);
1317*4d9fdb46SRobert Mustacchi             if(res != DW_DLV_OK) {
1318*4d9fdb46SRobert Mustacchi                 free(relp);
1319*4d9fdb46SRobert Mustacchi                 free(grel);
1320*4d9fdb46SRobert Mustacchi                 return res;
1321*4d9fdb46SRobert Mustacchi             }
1322*4d9fdb46SRobert Mustacchi             res = generic_rel_from_rel64(ep,gsh,relp,grel,errcode);
1323*4d9fdb46SRobert Mustacchi             free(relp);
1324*4d9fdb46SRobert Mustacchi         }
1325*4d9fdb46SRobert Mustacchi     }
1326*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_OK) {
1327*4d9fdb46SRobert Mustacchi         gsh->gh_relcount = count;
1328*4d9fdb46SRobert Mustacchi         gsh->gh_rels = grel;
1329*4d9fdb46SRobert Mustacchi         *count_out = count;
1330*4d9fdb46SRobert Mustacchi         *grel_out = grel;
1331*4d9fdb46SRobert Mustacchi         return res;
1332*4d9fdb46SRobert Mustacchi     }
1333*4d9fdb46SRobert Mustacchi     /* Some sort of issue */
1334*4d9fdb46SRobert Mustacchi     count_out = 0;
1335*4d9fdb46SRobert Mustacchi     free(grel);
1336*4d9fdb46SRobert Mustacchi     return res;
1337*4d9fdb46SRobert Mustacchi }
1338*4d9fdb46SRobert Mustacchi 
1339*4d9fdb46SRobert Mustacchi 
1340*4d9fdb46SRobert Mustacchi /*  Is this rel/rela section related to dwarf at all?
1341*4d9fdb46SRobert Mustacchi     set oksecnum zero if not. Else set targ secnum.
1342*4d9fdb46SRobert Mustacchi     Never returns DW_DLV_NO_ENTRY. */
1343*4d9fdb46SRobert Mustacchi static int
this_rel_is_a_section_dwarf_related(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * gshdr,unsigned * oksecnum_out,int * errcode)1344*4d9fdb46SRobert Mustacchi this_rel_is_a_section_dwarf_related(
1345*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1346*4d9fdb46SRobert Mustacchi     struct generic_shdr *gshdr,
1347*4d9fdb46SRobert Mustacchi     unsigned *oksecnum_out,
1348*4d9fdb46SRobert Mustacchi     int *errcode)
1349*4d9fdb46SRobert Mustacchi {
1350*4d9fdb46SRobert Mustacchi     unsigned oksecnum = 0;
1351*4d9fdb46SRobert Mustacchi     struct generic_shdr *gstarg = 0;
1352*4d9fdb46SRobert Mustacchi 
1353*4d9fdb46SRobert Mustacchi     if (gshdr->gh_type != SHT_RELA &&
1354*4d9fdb46SRobert Mustacchi         gshdr->gh_type != SHT_REL)  {
1355*4d9fdb46SRobert Mustacchi         *oksecnum_out = 0;
1356*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1357*4d9fdb46SRobert Mustacchi     }
1358*4d9fdb46SRobert Mustacchi     oksecnum = gshdr->gh_reloc_target_secnum;
1359*4d9fdb46SRobert Mustacchi     if (oksecnum >= ep->f_loc_shdr.g_count) {
1360*4d9fdb46SRobert Mustacchi         *oksecnum_out = 0;
1361*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_SECTION_ERROR;
1362*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1363*4d9fdb46SRobert Mustacchi     }
1364*4d9fdb46SRobert Mustacchi     gstarg = ep->f_shdr+oksecnum;
1365*4d9fdb46SRobert Mustacchi     if (!gstarg->gh_is_dwarf) {
1366*4d9fdb46SRobert Mustacchi         *oksecnum_out = 0; /* no reloc needed. */
1367*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1368*4d9fdb46SRobert Mustacchi     }
1369*4d9fdb46SRobert Mustacchi     *oksecnum_out = oksecnum;
1370*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1371*4d9fdb46SRobert Mustacchi }
1372*4d9fdb46SRobert Mustacchi /* Secnum here is the secnum of rela. Not
1373*4d9fdb46SRobert Mustacchi    the target of the relocations.
1374*4d9fdb46SRobert Mustacchi    This also loads .rel. */
1375*4d9fdb46SRobert Mustacchi int
_dwarf_load_elf_relx(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned secnum,enum RelocRela localr,int * errcode)1376*4d9fdb46SRobert Mustacchi _dwarf_load_elf_relx(
1377*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1378*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secnum,
1379*4d9fdb46SRobert Mustacchi     enum RelocRela localr,
1380*4d9fdb46SRobert Mustacchi     int *errcode)
1381*4d9fdb46SRobert Mustacchi {
1382*4d9fdb46SRobert Mustacchi     struct generic_shdr *gshdr = 0;
1383*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned seccount = 0;
1384*4d9fdb46SRobert Mustacchi     unsigned offsetsize = 0;
1385*4d9fdb46SRobert Mustacchi     struct generic_rela *grp = 0;
1386*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count_read = 0;
1387*4d9fdb46SRobert Mustacchi     int res = 0;
1388*4d9fdb46SRobert Mustacchi     unsigned oksec = 0;
1389*4d9fdb46SRobert Mustacchi     enum RelocOffsetSize localoffsize = RelocOffset32;
1390*4d9fdb46SRobert Mustacchi 
1391*4d9fdb46SRobert Mustacchi     /*  ASSERT: Caller guarantees localr is
1392*4d9fdb46SRobert Mustacchi         a valid RelocRela  */
1393*4d9fdb46SRobert Mustacchi     if (!ep) {
1394*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_INTERNAL_NULL_POINTER;
1395*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1396*4d9fdb46SRobert Mustacchi     }
1397*4d9fdb46SRobert Mustacchi     offsetsize = ep->f_offsetsize;
1398*4d9fdb46SRobert Mustacchi     seccount = ep->f_loc_shdr.g_count;
1399*4d9fdb46SRobert Mustacchi     if (secnum >= seccount) {
1400*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_SECTION_ERROR;
1401*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1402*4d9fdb46SRobert Mustacchi     }
1403*4d9fdb46SRobert Mustacchi     gshdr = ep->f_shdr +secnum;
1404*4d9fdb46SRobert Mustacchi     if (is_empty_section(gshdr->gh_type)) {
1405*4d9fdb46SRobert Mustacchi 
1406*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
1407*4d9fdb46SRobert Mustacchi     }
1408*4d9fdb46SRobert Mustacchi 
1409*4d9fdb46SRobert Mustacchi     res = this_rel_is_a_section_dwarf_related(ep,gshdr,
1410*4d9fdb46SRobert Mustacchi         &oksec,errcode);
1411*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1412*4d9fdb46SRobert Mustacchi         return res;
1413*4d9fdb46SRobert Mustacchi     }
1414*4d9fdb46SRobert Mustacchi     if (!oksec) {
1415*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1416*4d9fdb46SRobert Mustacchi     }
1417*4d9fdb46SRobert Mustacchi     /*  We will actually read these relocations. */
1418*4d9fdb46SRobert Mustacchi     if (offsetsize == 64) {
1419*4d9fdb46SRobert Mustacchi         localoffsize = RelocOffset64;
1420*4d9fdb46SRobert Mustacchi     } else if (offsetsize == 32) {
1421*4d9fdb46SRobert Mustacchi         localoffsize = RelocOffset32;
1422*4d9fdb46SRobert Mustacchi     } else {
1423*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
1424*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1425*4d9fdb46SRobert Mustacchi     }
1426*4d9fdb46SRobert Mustacchi     /*  ASSERT: localoffsize is now a valid enum value,
1427*4d9fdb46SRobert Mustacchi         one of the two defined. */
1428*4d9fdb46SRobert Mustacchi     res = _dwarf_elf_load_a_relx_batch(ep,
1429*4d9fdb46SRobert Mustacchi         gshdr,&grp,&count_read,localr,localoffsize,errcode);
1430*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1431*4d9fdb46SRobert Mustacchi         return res;
1432*4d9fdb46SRobert Mustacchi     }
1433*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
1434*4d9fdb46SRobert Mustacchi         return res;
1435*4d9fdb46SRobert Mustacchi     }
1436*4d9fdb46SRobert Mustacchi     gshdr->gh_rels = grp;
1437*4d9fdb46SRobert Mustacchi     gshdr->gh_relcount = count_read;
1438*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1439*4d9fdb46SRobert Mustacchi }
1440*4d9fdb46SRobert Mustacchi static int
validate_section_name_string(Dwarf_Unsigned section_length,Dwarf_Unsigned string_loc_index,const char * strings_start,int * errcode)1441*4d9fdb46SRobert Mustacchi validate_section_name_string(Dwarf_Unsigned section_length,
1442*4d9fdb46SRobert Mustacchi   Dwarf_Unsigned string_loc_index,
1443*4d9fdb46SRobert Mustacchi   const char * strings_start,
1444*4d9fdb46SRobert Mustacchi   int  * errcode)
1445*4d9fdb46SRobert Mustacchi {
1446*4d9fdb46SRobert Mustacchi     const char *endpoint = strings_start + section_length;
1447*4d9fdb46SRobert Mustacchi     const char *cur = 0;
1448*4d9fdb46SRobert Mustacchi 
1449*4d9fdb46SRobert Mustacchi     if (section_length <= string_loc_index) {
1450*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD;
1451*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1452*4d9fdb46SRobert Mustacchi     }
1453*4d9fdb46SRobert Mustacchi     cur = string_loc_index+strings_start;
1454*4d9fdb46SRobert Mustacchi     for(  ; cur < endpoint;++cur) {
1455*4d9fdb46SRobert Mustacchi         if (!*cur) {
1456*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
1457*4d9fdb46SRobert Mustacchi         }
1458*4d9fdb46SRobert Mustacchi     }
1459*4d9fdb46SRobert Mustacchi     *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD;
1460*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
1461*4d9fdb46SRobert Mustacchi }
1462*4d9fdb46SRobert Mustacchi 
1463*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_load_sect_namestring(dwarf_elf_object_access_internals_t * ep,int * errcode)1464*4d9fdb46SRobert Mustacchi _dwarf_elf_load_sect_namestring(
1465*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1466*4d9fdb46SRobert Mustacchi     int *errcode)
1467*4d9fdb46SRobert Mustacchi {
1468*4d9fdb46SRobert Mustacchi     struct generic_shdr *gshdr = 0;
1469*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned generic_count = 0;
1470*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 1;
1471*4d9fdb46SRobert Mustacchi     const char *stringsecbase = 0;
1472*4d9fdb46SRobert Mustacchi 
1473*4d9fdb46SRobert Mustacchi     stringsecbase = ep->f_elf_shstrings_data;
1474*4d9fdb46SRobert Mustacchi     gshdr = ep->f_shdr;
1475*4d9fdb46SRobert Mustacchi     generic_count = ep->f_loc_shdr.g_count;
1476*4d9fdb46SRobert Mustacchi     for(i = 0; i < generic_count; i++, ++gshdr) {
1477*4d9fdb46SRobert Mustacchi         const char *namestr =
1478*4d9fdb46SRobert Mustacchi             "<Invalid sh_name value. Corrupt Elf.>";
1479*4d9fdb46SRobert Mustacchi         int res = 0;
1480*4d9fdb46SRobert Mustacchi 
1481*4d9fdb46SRobert Mustacchi         res = validate_section_name_string(ep->f_elf_shstrings_length,
1482*4d9fdb46SRobert Mustacchi             gshdr->gh_name, stringsecbase,
1483*4d9fdb46SRobert Mustacchi             errcode);
1484*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1485*4d9fdb46SRobert Mustacchi             gshdr->gh_namestring = namestr;
1486*4d9fdb46SRobert Mustacchi             return res;
1487*4d9fdb46SRobert Mustacchi         }
1488*4d9fdb46SRobert Mustacchi         gshdr->gh_namestring = stringsecbase + gshdr->gh_name;
1489*4d9fdb46SRobert Mustacchi     }
1490*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1491*4d9fdb46SRobert Mustacchi }
1492*4d9fdb46SRobert Mustacchi 
1493*4d9fdb46SRobert Mustacchi 
1494*4d9fdb46SRobert Mustacchi static int
elf_load_elf_header32(dwarf_elf_object_access_internals_t * ep,int * errcode)1495*4d9fdb46SRobert Mustacchi elf_load_elf_header32(
1496*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,int *errcode)
1497*4d9fdb46SRobert Mustacchi {
1498*4d9fdb46SRobert Mustacchi     int res = 0;
1499*4d9fdb46SRobert Mustacchi     dw_elf32_ehdr ehdr32;
1500*4d9fdb46SRobert Mustacchi     struct generic_ehdr *ehdr = 0;
1501*4d9fdb46SRobert Mustacchi 
1502*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,&ehdr32,0,sizeof(ehdr32),
1503*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
1504*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1505*4d9fdb46SRobert Mustacchi         return res;
1506*4d9fdb46SRobert Mustacchi     }
1507*4d9fdb46SRobert Mustacchi     ehdr = (struct generic_ehdr *)calloc(1,
1508*4d9fdb46SRobert Mustacchi         sizeof(struct generic_ehdr));
1509*4d9fdb46SRobert Mustacchi     if (!ehdr) {
1510*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
1511*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1512*4d9fdb46SRobert Mustacchi     }
1513*4d9fdb46SRobert Mustacchi     res  = generic_ehdr_from_32(ep,ehdr,&ehdr32,errcode);
1514*4d9fdb46SRobert Mustacchi     return res;
1515*4d9fdb46SRobert Mustacchi }
1516*4d9fdb46SRobert Mustacchi static int
elf_load_elf_header64(dwarf_elf_object_access_internals_t * ep,int * errcode)1517*4d9fdb46SRobert Mustacchi elf_load_elf_header64(
1518*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,int *errcode)
1519*4d9fdb46SRobert Mustacchi {
1520*4d9fdb46SRobert Mustacchi     int res = 0;
1521*4d9fdb46SRobert Mustacchi     dw_elf64_ehdr ehdr64;
1522*4d9fdb46SRobert Mustacchi     struct generic_ehdr *ehdr = 0;
1523*4d9fdb46SRobert Mustacchi 
1524*4d9fdb46SRobert Mustacchi     res = RRMOA(ep->f_fd,&ehdr64,0,sizeof(ehdr64),
1525*4d9fdb46SRobert Mustacchi         ep->f_filesize,errcode);
1526*4d9fdb46SRobert Mustacchi     if(res != DW_DLV_OK) {
1527*4d9fdb46SRobert Mustacchi         return res;
1528*4d9fdb46SRobert Mustacchi     }
1529*4d9fdb46SRobert Mustacchi     ehdr = (struct generic_ehdr *)calloc(1,
1530*4d9fdb46SRobert Mustacchi         sizeof(struct generic_ehdr));
1531*4d9fdb46SRobert Mustacchi     if (!ehdr) {
1532*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
1533*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1534*4d9fdb46SRobert Mustacchi     }
1535*4d9fdb46SRobert Mustacchi     res  = generic_ehdr_from_64(ep,ehdr,&ehdr64,errcode);
1536*4d9fdb46SRobert Mustacchi     return res;
1537*4d9fdb46SRobert Mustacchi }
1538*4d9fdb46SRobert Mustacchi 
1539*4d9fdb46SRobert Mustacchi static int
validate_struct_sizes(int * errcode)1540*4d9fdb46SRobert Mustacchi validate_struct_sizes(
1541*4d9fdb46SRobert Mustacchi #ifdef HAVE_ELF_H
1542*4d9fdb46SRobert Mustacchi     int*errcode
1543*4d9fdb46SRobert Mustacchi #else
1544*4d9fdb46SRobert Mustacchi     UNUSEDARG int*errcode
1545*4d9fdb46SRobert Mustacchi #endif
1546*4d9fdb46SRobert Mustacchi     )
1547*4d9fdb46SRobert Mustacchi {
1548*4d9fdb46SRobert Mustacchi #ifdef HAVE_ELF_H
1549*4d9fdb46SRobert Mustacchi     /*  This is a sanity check when we have an elf.h
1550*4d9fdb46SRobert Mustacchi         to check against. */
1551*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Ehdr) != sizeof(dw_elf32_ehdr)) {
1552*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1553*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1554*4d9fdb46SRobert Mustacchi     }
1555*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Ehdr) != sizeof(dw_elf64_ehdr)) {
1556*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1557*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1558*4d9fdb46SRobert Mustacchi     }
1559*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Shdr) != sizeof(dw_elf32_shdr)) {
1560*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1561*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1562*4d9fdb46SRobert Mustacchi     }
1563*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Shdr) != sizeof(dw_elf64_shdr)) {
1564*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1565*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1566*4d9fdb46SRobert Mustacchi     }
1567*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Phdr) != sizeof(dw_elf32_phdr)) {
1568*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1569*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1570*4d9fdb46SRobert Mustacchi     }
1571*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Phdr) != sizeof(dw_elf64_phdr)) {
1572*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1573*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1574*4d9fdb46SRobert Mustacchi     }
1575*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Rel) != sizeof(dw_elf32_rel)) {
1576*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1577*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1578*4d9fdb46SRobert Mustacchi     }
1579*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Rel) != sizeof(dw_elf64_rel)) {
1580*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1581*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1582*4d9fdb46SRobert Mustacchi     }
1583*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Rela) != sizeof(dw_elf32_rela)) {
1584*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1585*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1586*4d9fdb46SRobert Mustacchi     }
1587*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Rela) != sizeof(dw_elf64_rela)) {
1588*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1589*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1590*4d9fdb46SRobert Mustacchi     }
1591*4d9fdb46SRobert Mustacchi     if (sizeof(Elf32_Sym) != sizeof(dw_elf32_sym)) {
1592*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1593*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1594*4d9fdb46SRobert Mustacchi     }
1595*4d9fdb46SRobert Mustacchi     if (sizeof(Elf64_Sym) != sizeof(dw_elf64_sym)) {
1596*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_BAD_TYPE_SIZE;
1597*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1598*4d9fdb46SRobert Mustacchi     }
1599*4d9fdb46SRobert Mustacchi #endif /* HAVE_ELF_H */
1600*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1601*4d9fdb46SRobert Mustacchi }
1602*4d9fdb46SRobert Mustacchi 
1603*4d9fdb46SRobert Mustacchi int
_dwarf_load_elf_header(dwarf_elf_object_access_internals_t * ep,int * errcode)1604*4d9fdb46SRobert Mustacchi _dwarf_load_elf_header(
1605*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,int*errcode)
1606*4d9fdb46SRobert Mustacchi {
1607*4d9fdb46SRobert Mustacchi     unsigned offsetsize = ep->f_offsetsize;
1608*4d9fdb46SRobert Mustacchi     int res = 0;
1609*4d9fdb46SRobert Mustacchi 
1610*4d9fdb46SRobert Mustacchi     res = validate_struct_sizes(errcode);
1611*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1612*4d9fdb46SRobert Mustacchi         return res;
1613*4d9fdb46SRobert Mustacchi     }
1614*4d9fdb46SRobert Mustacchi 
1615*4d9fdb46SRobert Mustacchi     if (offsetsize == 32) {
1616*4d9fdb46SRobert Mustacchi         res = elf_load_elf_header32(ep,errcode);
1617*4d9fdb46SRobert Mustacchi     } else if (offsetsize == 64) {
1618*4d9fdb46SRobert Mustacchi         if (sizeof(Dwarf_Unsigned) < 8) {
1619*4d9fdb46SRobert Mustacchi             *errcode =  DW_DLE_INTEGER_TOO_SMALL;
1620*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1621*4d9fdb46SRobert Mustacchi         }
1622*4d9fdb46SRobert Mustacchi         res = elf_load_elf_header64(ep,errcode);
1623*4d9fdb46SRobert Mustacchi     } else {
1624*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
1625*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1626*4d9fdb46SRobert Mustacchi     }
1627*4d9fdb46SRobert Mustacchi     return res;
1628*4d9fdb46SRobert Mustacchi }
1629*4d9fdb46SRobert Mustacchi 
1630*4d9fdb46SRobert Mustacchi static int
validate_links(dwarf_elf_object_access_internals_t * ep,Dwarf_Unsigned knownsect,Dwarf_Unsigned string_sect,int * errcode)1631*4d9fdb46SRobert Mustacchi validate_links(
1632*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1633*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned knownsect,
1634*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned string_sect,
1635*4d9fdb46SRobert Mustacchi     int *errcode)
1636*4d9fdb46SRobert Mustacchi {
1637*4d9fdb46SRobert Mustacchi     struct generic_shdr* pshk = 0;
1638*4d9fdb46SRobert Mustacchi 
1639*4d9fdb46SRobert Mustacchi     if (!knownsect) {
1640*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1641*4d9fdb46SRobert Mustacchi     }
1642*4d9fdb46SRobert Mustacchi     if (!string_sect) {
1643*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_STRING_SECTION_ERROR;
1644*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1645*4d9fdb46SRobert Mustacchi     }
1646*4d9fdb46SRobert Mustacchi     pshk = ep->f_shdr + knownsect;
1647*4d9fdb46SRobert Mustacchi     if (string_sect != pshk->gh_link) {
1648*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ELF_SECTION_LINK_ERROR;
1649*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1650*4d9fdb46SRobert Mustacchi     }
1651*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1652*4d9fdb46SRobert Mustacchi }
1653*4d9fdb46SRobert Mustacchi 
1654*4d9fdb46SRobert Mustacchi 
1655*4d9fdb46SRobert Mustacchi static int
string_endswith(const char * n,const char * q)1656*4d9fdb46SRobert Mustacchi string_endswith(const char *n,const char *q)
1657*4d9fdb46SRobert Mustacchi {
1658*4d9fdb46SRobert Mustacchi     unsigned long len = strlen(n);
1659*4d9fdb46SRobert Mustacchi     unsigned long qlen = strlen(q);
1660*4d9fdb46SRobert Mustacchi     const char *startpt = 0;
1661*4d9fdb46SRobert Mustacchi 
1662*4d9fdb46SRobert Mustacchi     if ( len < qlen) {
1663*4d9fdb46SRobert Mustacchi         return FALSE;
1664*4d9fdb46SRobert Mustacchi     }
1665*4d9fdb46SRobert Mustacchi     startpt = n + (len-qlen);
1666*4d9fdb46SRobert Mustacchi     if (strcmp(startpt,q)) {
1667*4d9fdb46SRobert Mustacchi         return FALSE;
1668*4d9fdb46SRobert Mustacchi     }
1669*4d9fdb46SRobert Mustacchi     return TRUE;
1670*4d9fdb46SRobert Mustacchi }
1671*4d9fdb46SRobert Mustacchi 
1672*4d9fdb46SRobert Mustacchi /*  We are allowing either SHT_GROUP or .group to indicate
1673*4d9fdb46SRobert Mustacchi     a group section, but really one should have both
1674*4d9fdb46SRobert Mustacchi     or neither! */
1675*4d9fdb46SRobert Mustacchi static int
elf_sht_groupsec(Dwarf_Unsigned type,const char * sname)1676*4d9fdb46SRobert Mustacchi elf_sht_groupsec(Dwarf_Unsigned type, const char *sname)
1677*4d9fdb46SRobert Mustacchi {
1678*4d9fdb46SRobert Mustacchi     /*  ARM compilers name SHT group "__ARM_grp<long name here>"
1679*4d9fdb46SRobert Mustacchi         not .group */
1680*4d9fdb46SRobert Mustacchi     if ((type == SHT_GROUP) || (!strcmp(sname,".group"))){
1681*4d9fdb46SRobert Mustacchi         return TRUE;
1682*4d9fdb46SRobert Mustacchi     }
1683*4d9fdb46SRobert Mustacchi     return FALSE;
1684*4d9fdb46SRobert Mustacchi }
1685*4d9fdb46SRobert Mustacchi 
1686*4d9fdb46SRobert Mustacchi static int
elf_flagmatches(Dwarf_Unsigned flagsword,Dwarf_Unsigned flag)1687*4d9fdb46SRobert Mustacchi elf_flagmatches(Dwarf_Unsigned flagsword,Dwarf_Unsigned flag)
1688*4d9fdb46SRobert Mustacchi {
1689*4d9fdb46SRobert Mustacchi     if ((flagsword&flag) == flag) {
1690*4d9fdb46SRobert Mustacchi         return TRUE;
1691*4d9fdb46SRobert Mustacchi     }
1692*4d9fdb46SRobert Mustacchi     return FALSE;
1693*4d9fdb46SRobert Mustacchi }
1694*4d9fdb46SRobert Mustacchi 
1695*4d9fdb46SRobert Mustacchi /*  For SHT_GROUP sections. */
1696*4d9fdb46SRobert Mustacchi static int
read_gs_section_group(dwarf_elf_object_access_internals_t * ep,struct generic_shdr * psh,int * errcode)1697*4d9fdb46SRobert Mustacchi read_gs_section_group(
1698*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1699*4d9fdb46SRobert Mustacchi     struct generic_shdr* psh,
1700*4d9fdb46SRobert Mustacchi     int *errcode)
1701*4d9fdb46SRobert Mustacchi {
1702*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
1703*4d9fdb46SRobert Mustacchi     int res = 0;
1704*4d9fdb46SRobert Mustacchi 
1705*4d9fdb46SRobert Mustacchi     if (!psh->gh_sht_group_array) {
1706*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned seclen = psh->gh_size;
1707*4d9fdb46SRobert Mustacchi         char *data = 0;
1708*4d9fdb46SRobert Mustacchi         char *dp = 0;
1709*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned* grouparray = 0;
1710*4d9fdb46SRobert Mustacchi         char dblock[4];
1711*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned va = 0;
1712*4d9fdb46SRobert Mustacchi         Dwarf_Unsigned count = 0;
1713*4d9fdb46SRobert Mustacchi         int foundone = 0;
1714*4d9fdb46SRobert Mustacchi 
1715*4d9fdb46SRobert Mustacchi         if (seclen < DWARF_32BIT_SIZE) {
1716*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1717*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1718*4d9fdb46SRobert Mustacchi         }
1719*4d9fdb46SRobert Mustacchi         data = malloc(seclen);
1720*4d9fdb46SRobert Mustacchi         if (!data) {
1721*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
1722*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1723*4d9fdb46SRobert Mustacchi         }
1724*4d9fdb46SRobert Mustacchi         dp = data;
1725*4d9fdb46SRobert Mustacchi         if (psh->gh_entsize != DWARF_32BIT_SIZE) {
1726*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1727*4d9fdb46SRobert Mustacchi             free(data);
1728*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1729*4d9fdb46SRobert Mustacchi         }
1730*4d9fdb46SRobert Mustacchi         count = seclen/psh->gh_entsize;
1731*4d9fdb46SRobert Mustacchi         if (count > ep->f_loc_shdr.g_count) {
1732*4d9fdb46SRobert Mustacchi             /* Impossible */
1733*4d9fdb46SRobert Mustacchi             free(data);
1734*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1735*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1736*4d9fdb46SRobert Mustacchi         }
1737*4d9fdb46SRobert Mustacchi         res = RRMOA(ep->f_fd,data,psh->gh_offset,seclen,
1738*4d9fdb46SRobert Mustacchi             ep->f_filesize,errcode);
1739*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
1740*4d9fdb46SRobert Mustacchi             free(data);
1741*4d9fdb46SRobert Mustacchi             return res;
1742*4d9fdb46SRobert Mustacchi         }
1743*4d9fdb46SRobert Mustacchi         grouparray = malloc(count * sizeof(Dwarf_Unsigned));
1744*4d9fdb46SRobert Mustacchi         if (!grouparray) {
1745*4d9fdb46SRobert Mustacchi             free(data);
1746*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
1747*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1748*4d9fdb46SRobert Mustacchi         }
1749*4d9fdb46SRobert Mustacchi 
1750*4d9fdb46SRobert Mustacchi         memcpy(dblock,dp,DWARF_32BIT_SIZE);
1751*4d9fdb46SRobert Mustacchi         ASNAR(memcpy,va,dblock);
1752*4d9fdb46SRobert Mustacchi         /* There is ambiguity on the endianness of this stuff. */
1753*4d9fdb46SRobert Mustacchi         if (va != 1 && va != 0x1000000) {
1754*4d9fdb46SRobert Mustacchi             /*  Could be corrupted elf object. */
1755*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1756*4d9fdb46SRobert Mustacchi             free(data);
1757*4d9fdb46SRobert Mustacchi             free(grouparray);
1758*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
1759*4d9fdb46SRobert Mustacchi         }
1760*4d9fdb46SRobert Mustacchi         grouparray[0] = 1;
1761*4d9fdb46SRobert Mustacchi         dp = dp + DWARF_32BIT_SIZE;
1762*4d9fdb46SRobert Mustacchi         for( i = 1; i < count; ++i,dp += DWARF_32BIT_SIZE) {
1763*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned gseca = 0;
1764*4d9fdb46SRobert Mustacchi             Dwarf_Unsigned gsecb = 0;
1765*4d9fdb46SRobert Mustacchi             struct generic_shdr* targpsh = 0;
1766*4d9fdb46SRobert Mustacchi 
1767*4d9fdb46SRobert Mustacchi             memcpy(dblock,dp,DWARF_32BIT_SIZE);
1768*4d9fdb46SRobert Mustacchi             ASNAR(memcpy,gseca,dblock);
1769*4d9fdb46SRobert Mustacchi             ASNAR(_dwarf_memcpy_swap_bytes,gsecb,dblock);
1770*4d9fdb46SRobert Mustacchi             if (!gseca) {
1771*4d9fdb46SRobert Mustacchi                 free(data);
1772*4d9fdb46SRobert Mustacchi                 free(grouparray);
1773*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1774*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1775*4d9fdb46SRobert Mustacchi             }
1776*4d9fdb46SRobert Mustacchi             grouparray[i] = gseca;
1777*4d9fdb46SRobert Mustacchi             if (gseca > ep->f_loc_shdr.g_count) {
1778*4d9fdb46SRobert Mustacchi                 /*  Might be confused endianness by
1779*4d9fdb46SRobert Mustacchi                     the compiler generating the SHT_GROUP.
1780*4d9fdb46SRobert Mustacchi                     This is pretty horrible. */
1781*4d9fdb46SRobert Mustacchi 
1782*4d9fdb46SRobert Mustacchi                 if (gsecb > ep->f_loc_shdr.g_count) {
1783*4d9fdb46SRobert Mustacchi                     *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1784*4d9fdb46SRobert Mustacchi                     free(data);
1785*4d9fdb46SRobert Mustacchi                     free(grouparray);
1786*4d9fdb46SRobert Mustacchi                     return DW_DLV_ERROR;
1787*4d9fdb46SRobert Mustacchi                 }
1788*4d9fdb46SRobert Mustacchi                 /* Ok. Yes, ugly. */
1789*4d9fdb46SRobert Mustacchi                 gseca = gsecb;
1790*4d9fdb46SRobert Mustacchi                 grouparray[i] = gseca;
1791*4d9fdb46SRobert Mustacchi             }
1792*4d9fdb46SRobert Mustacchi             targpsh = ep->f_shdr + gseca;
1793*4d9fdb46SRobert Mustacchi             if (targpsh->gh_section_group_number) {
1794*4d9fdb46SRobert Mustacchi                 /* multi-assignment to groups. Oops. */
1795*4d9fdb46SRobert Mustacchi                 free(data);
1796*4d9fdb46SRobert Mustacchi                 free(grouparray);
1797*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1798*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1799*4d9fdb46SRobert Mustacchi             }
1800*4d9fdb46SRobert Mustacchi             targpsh->gh_section_group_number =
1801*4d9fdb46SRobert Mustacchi                 ep->f_sg_next_group_number;
1802*4d9fdb46SRobert Mustacchi             foundone = 1;
1803*4d9fdb46SRobert Mustacchi         }
1804*4d9fdb46SRobert Mustacchi         if (foundone) {
1805*4d9fdb46SRobert Mustacchi             ++ep->f_sg_next_group_number;
1806*4d9fdb46SRobert Mustacchi             ++ep->f_sht_group_type_section_count;
1807*4d9fdb46SRobert Mustacchi         }
1808*4d9fdb46SRobert Mustacchi         free(data);
1809*4d9fdb46SRobert Mustacchi         psh->gh_sht_group_array = grouparray;
1810*4d9fdb46SRobert Mustacchi         psh->gh_sht_group_array_count = count;
1811*4d9fdb46SRobert Mustacchi     }
1812*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1813*4d9fdb46SRobert Mustacchi }
1814*4d9fdb46SRobert Mustacchi /*  Does related things.
1815*4d9fdb46SRobert Mustacchi     A)  Counts the number of SHT_GROUP
1816*4d9fdb46SRobert Mustacchi         and for each builds an array of the sections in the group
1817*4d9fdb46SRobert Mustacchi         (which we expect are all DWARF-related)
1818*4d9fdb46SRobert Mustacchi         and sets the group number in each mentioned section.
1819*4d9fdb46SRobert Mustacchi     B)  Counts the number of SHF_GROUP flags.
1820*4d9fdb46SRobert Mustacchi     C)  If gnu groups:
1821*4d9fdb46SRobert Mustacchi         ensure all the DWARF sections marked with right group
1822*4d9fdb46SRobert Mustacchi         based on A(we will mark unmarked as group 1,
1823*4d9fdb46SRobert Mustacchi         DW_GROUPNUMBER_BASE).
1824*4d9fdb46SRobert Mustacchi     D)  If arm groups (SHT_GROUP zero, SHF_GROUP non-zero):
1825*4d9fdb46SRobert Mustacchi         Check the relocations of all SHF_GROUP section
1826*4d9fdb46SRobert Mustacchi         FIXME: algorithm needed.
1827*4d9fdb46SRobert Mustacchi 
1828*4d9fdb46SRobert Mustacchi 
1829*4d9fdb46SRobert Mustacchi     If SHT_GROUP and SHF_GROUP this is GNU groups.
1830*4d9fdb46SRobert Mustacchi     If no SHT_GROUP and have SHF_GROUP this is
1831*4d9fdb46SRobert Mustacchi     arm cc groups and we must use relocation information
1832*4d9fdb46SRobert Mustacchi     to identify the group members.
1833*4d9fdb46SRobert Mustacchi 
1834*4d9fdb46SRobert Mustacchi     It seems(?) impossible for an object to have both
1835*4d9fdb46SRobert Mustacchi     dwo sections and (SHF_GROUP or SHT_GROUP), but
1836*4d9fdb46SRobert Mustacchi     we do not rule that out here.  */
1837*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_setup_all_section_groups(dwarf_elf_object_access_internals_t * ep,int * errcode)1838*4d9fdb46SRobert Mustacchi _dwarf_elf_setup_all_section_groups(
1839*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1840*4d9fdb46SRobert Mustacchi     int *errcode)
1841*4d9fdb46SRobert Mustacchi {
1842*4d9fdb46SRobert Mustacchi     struct generic_shdr* psh = 0;
1843*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
1844*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
1845*4d9fdb46SRobert Mustacchi     int res = 0;
1846*4d9fdb46SRobert Mustacchi 
1847*4d9fdb46SRobert Mustacchi     count = ep->f_loc_shdr.g_count;
1848*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr;
1849*4d9fdb46SRobert Mustacchi 
1850*4d9fdb46SRobert Mustacchi     /* Does step A and step B */
1851*4d9fdb46SRobert Mustacchi     for (i = 0; i < count; ++psh,++i) {
1852*4d9fdb46SRobert Mustacchi         const char *name = psh->gh_namestring;
1853*4d9fdb46SRobert Mustacchi         if (is_empty_section(psh->gh_type)) {
1854*4d9fdb46SRobert Mustacchi             /*  No data here. */
1855*4d9fdb46SRobert Mustacchi             continue;
1856*4d9fdb46SRobert Mustacchi         }
1857*4d9fdb46SRobert Mustacchi         if (!elf_sht_groupsec(psh->gh_type,name)) {
1858*4d9fdb46SRobert Mustacchi             /* Step B */
1859*4d9fdb46SRobert Mustacchi             if (elf_flagmatches(psh->gh_flags,SHF_GROUP)) {
1860*4d9fdb46SRobert Mustacchi                 ep->f_shf_group_flag_section_count++;
1861*4d9fdb46SRobert Mustacchi             }
1862*4d9fdb46SRobert Mustacchi             continue;
1863*4d9fdb46SRobert Mustacchi         }
1864*4d9fdb46SRobert Mustacchi         /* Looks like a section group. Do Step A. */
1865*4d9fdb46SRobert Mustacchi         res  =read_gs_section_group(ep,psh,errcode);
1866*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
1867*4d9fdb46SRobert Mustacchi             return res;
1868*4d9fdb46SRobert Mustacchi         }
1869*4d9fdb46SRobert Mustacchi     }
1870*4d9fdb46SRobert Mustacchi     /*  Any sections not marked above or here are in
1871*4d9fdb46SRobert Mustacchi         grep DW_GROUPNUMBER_BASE (1).
1872*4d9fdb46SRobert Mustacchi         Section C. */
1873*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr;
1874*4d9fdb46SRobert Mustacchi     for (i = 0; i < count; ++psh,++i) {
1875*4d9fdb46SRobert Mustacchi         const char *name = psh->gh_namestring;
1876*4d9fdb46SRobert Mustacchi         int is_rel = FALSE;
1877*4d9fdb46SRobert Mustacchi         int is_rela = FALSE;
1878*4d9fdb46SRobert Mustacchi 
1879*4d9fdb46SRobert Mustacchi         if (is_empty_section(psh->gh_type)) {
1880*4d9fdb46SRobert Mustacchi             /*  No data here. */
1881*4d9fdb46SRobert Mustacchi             continue;
1882*4d9fdb46SRobert Mustacchi         }
1883*4d9fdb46SRobert Mustacchi         if (elf_sht_groupsec(psh->gh_type,name)) {
1884*4d9fdb46SRobert Mustacchi             continue;
1885*4d9fdb46SRobert Mustacchi         }
1886*4d9fdb46SRobert Mustacchi         /* Not a section group */
1887*4d9fdb46SRobert Mustacchi         if(string_endswith(name,".dwo")) {
1888*4d9fdb46SRobert Mustacchi             if (psh->gh_section_group_number) {
1889*4d9fdb46SRobert Mustacchi                 /* multi-assignment to groups. Oops. */
1890*4d9fdb46SRobert Mustacchi                 *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;
1891*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
1892*4d9fdb46SRobert Mustacchi             }
1893*4d9fdb46SRobert Mustacchi             psh->gh_is_dwarf = TRUE;
1894*4d9fdb46SRobert Mustacchi             psh->gh_section_group_number = DW_GROUPNUMBER_DWO;
1895*4d9fdb46SRobert Mustacchi             ep->f_dwo_group_section_count++;
1896*4d9fdb46SRobert Mustacchi         } else if (_dwarf_load_elf_section_is_dwarf(name,&is_rela,&is_rel)) {
1897*4d9fdb46SRobert Mustacchi             if(!psh->gh_section_group_number) {
1898*4d9fdb46SRobert Mustacchi                 psh->gh_section_group_number = DW_GROUPNUMBER_BASE;
1899*4d9fdb46SRobert Mustacchi             }
1900*4d9fdb46SRobert Mustacchi             psh->gh_is_dwarf = TRUE;
1901*4d9fdb46SRobert Mustacchi         } else {
1902*4d9fdb46SRobert Mustacchi             /* Do nothing. */
1903*4d9fdb46SRobert Mustacchi         }
1904*4d9fdb46SRobert Mustacchi     }
1905*4d9fdb46SRobert Mustacchi     if (ep->f_sht_group_type_section_count) {
1906*4d9fdb46SRobert Mustacchi         /*  Not ARM. Done. */
1907*4d9fdb46SRobert Mustacchi     }
1908*4d9fdb46SRobert Mustacchi     if (!ep->f_shf_group_flag_section_count) {
1909*4d9fdb46SRobert Mustacchi         /*  Nothing more to do. */
1910*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
1911*4d9fdb46SRobert Mustacchi     }
1912*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1913*4d9fdb46SRobert Mustacchi }
1914*4d9fdb46SRobert Mustacchi 
1915*4d9fdb46SRobert Mustacchi static int
_dwarf_elf_find_sym_sections(dwarf_elf_object_access_internals_t * ep,int * errcode)1916*4d9fdb46SRobert Mustacchi _dwarf_elf_find_sym_sections(
1917*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,
1918*4d9fdb46SRobert Mustacchi     int *errcode)
1919*4d9fdb46SRobert Mustacchi {
1920*4d9fdb46SRobert Mustacchi     struct generic_shdr* psh = 0;
1921*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
1922*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned count = 0;
1923*4d9fdb46SRobert Mustacchi     int res = 0;
1924*4d9fdb46SRobert Mustacchi 
1925*4d9fdb46SRobert Mustacchi     count = ep->f_loc_shdr.g_count;
1926*4d9fdb46SRobert Mustacchi     psh = ep->f_shdr;
1927*4d9fdb46SRobert Mustacchi     for (i = 0; i < count; ++psh,++i) {
1928*4d9fdb46SRobert Mustacchi         const char *name = psh->gh_namestring;
1929*4d9fdb46SRobert Mustacchi         if (is_empty_section(psh->gh_type)) {
1930*4d9fdb46SRobert Mustacchi             /*  No data here. */
1931*4d9fdb46SRobert Mustacchi             continue;
1932*4d9fdb46SRobert Mustacchi         }
1933*4d9fdb46SRobert Mustacchi         if (!strcmp(name,".dynsym")) {
1934*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_index = i;
1935*4d9fdb46SRobert Mustacchi             ep->f_loc_dynsym.g_offset = psh->gh_offset;
1936*4d9fdb46SRobert Mustacchi         } else if (!strcmp(name,".dynstr")) {
1937*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_sect_index = i;
1938*4d9fdb46SRobert Mustacchi             ep->f_dynsym_sect_strings_max = psh->gh_size;
1939*4d9fdb46SRobert Mustacchi         } else if (!strcmp(name,".symtab")) {
1940*4d9fdb46SRobert Mustacchi             ep->f_symtab_sect_index = i;
1941*4d9fdb46SRobert Mustacchi             ep->f_loc_symtab.g_offset = psh->gh_offset;
1942*4d9fdb46SRobert Mustacchi         } else if (!strcmp(name,".strtab")) {
1943*4d9fdb46SRobert Mustacchi             ep->f_symtab_sect_strings_sect_index = i;
1944*4d9fdb46SRobert Mustacchi             ep->f_symtab_sect_strings_max = psh->gh_size;
1945*4d9fdb46SRobert Mustacchi         } else if (!strcmp(name,".dynamic")) {
1946*4d9fdb46SRobert Mustacchi             ep->f_dynamic_sect_index = i;
1947*4d9fdb46SRobert Mustacchi             ep->f_loc_dynamic.g_offset = psh->gh_offset;
1948*4d9fdb46SRobert Mustacchi         }
1949*4d9fdb46SRobert Mustacchi     }
1950*4d9fdb46SRobert Mustacchi 
1951*4d9fdb46SRobert Mustacchi #if 0
1952*4d9fdb46SRobert Mustacchi     res = validate_links(ep,ep->f_dynsym_sect_index,
1953*4d9fdb46SRobert Mustacchi         ep->f_dynsym_sect_strings_sect_index,errcode);
1954*4d9fdb46SRobert Mustacchi     if (res!= DW_DLV_OK) {
1955*4d9fdb46SRobert Mustacchi         return res;
1956*4d9fdb46SRobert Mustacchi     }
1957*4d9fdb46SRobert Mustacchi #endif /* 0 */
1958*4d9fdb46SRobert Mustacchi     res = validate_links(ep,ep->f_symtab_sect_index,
1959*4d9fdb46SRobert Mustacchi         ep->f_symtab_sect_strings_sect_index,errcode);
1960*4d9fdb46SRobert Mustacchi     if (res!= DW_DLV_OK) {
1961*4d9fdb46SRobert Mustacchi         return res;
1962*4d9fdb46SRobert Mustacchi     }
1963*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
1964*4d9fdb46SRobert Mustacchi }
1965*4d9fdb46SRobert Mustacchi 
1966*4d9fdb46SRobert Mustacchi 
1967*4d9fdb46SRobert Mustacchi int
_dwarf_load_elf_sectheaders(dwarf_elf_object_access_internals_t * ep,int * errcode)1968*4d9fdb46SRobert Mustacchi _dwarf_load_elf_sectheaders(
1969*4d9fdb46SRobert Mustacchi     dwarf_elf_object_access_internals_t *ep,int*errcode)
1970*4d9fdb46SRobert Mustacchi {
1971*4d9fdb46SRobert Mustacchi     int res = 0;
1972*4d9fdb46SRobert Mustacchi 
1973*4d9fdb46SRobert Mustacchi     if (ep->f_offsetsize == 32) {
1974*4d9fdb46SRobert Mustacchi         res  = elf_load_sectheaders32(ep,ep->f_ehdr->ge_shoff,
1975*4d9fdb46SRobert Mustacchi             ep->f_ehdr->ge_shentsize,
1976*4d9fdb46SRobert Mustacchi             ep->f_ehdr->ge_shnum,errcode);
1977*4d9fdb46SRobert Mustacchi     } else  if (ep->f_offsetsize == 64) {
1978*4d9fdb46SRobert Mustacchi         res  = elf_load_sectheaders64(ep,ep->f_ehdr->ge_shoff,
1979*4d9fdb46SRobert Mustacchi             ep->f_ehdr->ge_shentsize,
1980*4d9fdb46SRobert Mustacchi             ep->f_ehdr->ge_shnum,errcode);
1981*4d9fdb46SRobert Mustacchi     } else {
1982*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
1983*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
1984*4d9fdb46SRobert Mustacchi     }
1985*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1986*4d9fdb46SRobert Mustacchi         return res;
1987*4d9fdb46SRobert Mustacchi     }
1988*4d9fdb46SRobert Mustacchi     res  = _dwarf_elf_load_sectstrings(ep,
1989*4d9fdb46SRobert Mustacchi         ep->f_ehdr->ge_shstrndx,errcode);
1990*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1991*4d9fdb46SRobert Mustacchi         return res;
1992*4d9fdb46SRobert Mustacchi     }
1993*4d9fdb46SRobert Mustacchi     res  = _dwarf_elf_load_sect_namestring(ep,errcode);
1994*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1995*4d9fdb46SRobert Mustacchi         return res;
1996*4d9fdb46SRobert Mustacchi     }
1997*4d9fdb46SRobert Mustacchi     res  = _dwarf_elf_find_sym_sections(ep,errcode);
1998*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
1999*4d9fdb46SRobert Mustacchi         return res;
2000*4d9fdb46SRobert Mustacchi     }
2001*4d9fdb46SRobert Mustacchi     res = _dwarf_elf_setup_all_section_groups(ep,errcode);
2002*4d9fdb46SRobert Mustacchi     return res;
2003*4d9fdb46SRobert Mustacchi }
2004