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