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