1 /*
2   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
4   Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
5   Portions Copyright 2009-2012 David Anderson. All rights reserved.
6   Portions Copyright 2009-2010 Novell Inc. All rights reserved.
7   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
8 
9   This program is free software; you can redistribute it and/or modify it
10   under the terms of version 2.1 of the GNU Lesser General Public License
11   as published by the Free Software Foundation.
12 
13   This program is distributed in the hope that it would be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17   Further, this software is distributed without any warranty that it is
18   free of the rightful claim of any third person regarding infringement
19   or the like.  Any license provided herein, whether implied or
20   otherwise, applies only to this software file.  Patent licenses, if
21   any, provided herein do not apply to combinations of this program with
22   other software, or any other product whatsoever.
23 
24   You should have received a copy of the GNU Lesser General Public
25   License along with this program; if not, write the Free Software
26   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
27   USA.
28 
29 */
30 
31 #include "config.h"
32 #include "dwarf_incl.h"
33 #include "dwarf_elf_access.h"
34 
35 /* Include Relocation definitions in the case of Windows */
36 #ifdef _WIN32
37 #include "dwarf_reloc_arm.h"
38 #include "dwarf_reloc_mips.h"
39 #include "dwarf_reloc_ppc.h"
40 #include "dwarf_reloc_ppc64.h"
41 #include "dwarf_reloc_x86_64.h"
42 #endif /* _WIN32 */
43 
44 #ifdef HAVE_ELF_H
45 #include <elf.h>
46 #endif
47 #ifdef HAVE_LIBELF_H
48 #include <libelf.h>
49 #else
50 #ifdef HAVE_LIBELF_LIBELF_H
51 #include <libelf/libelf.h>
52 #else
53 #error Without libelf.h dwarf_elf_access.c cannot compile, so giving up.
54 #endif
55 #endif
56 
57 #include <stdio.h>
58 #include <sys/stat.h>
59 #include <sys/types.h>
60 #include <string.h>
61 #include <stdlib.h>
62 
63 #define FALSE 0
64 #define TRUE  1
65 
66 #ifndef EM_MIPS
67 /* This is the standard elf value EM_MIPS. */
68 #define EM_MIPS 8
69 #endif
70 
71 #ifndef EM_K10M
72 #define EM_K10M 181  /* Intel K10M */
73 #endif
74 #ifndef EM_L10M
75 #define EM_L10M 180  /* Intel L10M */
76 #endif
77 #ifndef EM_AARCH64
78 #define EM_AARCH64 183  /* Arm 64 */
79 #endif
80 #ifndef R_AARCH64_ABS64
81 #define R_AARCH64_ABS64 0x101
82 #endif
83 #ifndef R_AARCH64_ABS32
84 #define R_AARCH64_ABS32 0x102
85 #endif
86 #ifndef R_MIPS_64
87 #define R_MIPS_64   18
88 #endif
89 #ifndef R_MIPS_TLS_TPREL64
90 #define R_MIPS_TLS_TPREL64	48
91 #endif
92 
93 #ifndef EM_IA_64
94 #define EM_IA_64            50
95 #endif
96 #ifndef R_IA64_SECREL32LSB
97 #define R_IA64_SECREL32LSB 0x65
98 #endif
99 #ifndef R_IA64_DIR32MSB
100 #define R_IA64_DIR32MSB    0x24
101 #endif
102 #ifndef R_IA64_DIR32LSB
103 #define R_IA64_DIR32LSB    0x25
104 #endif
105 #ifndef R_IA64_DIR64MSB
106 #define R_IA64_DIR64MSB    0x26
107 #endif
108 #ifndef R_IA64_DIR64LSB
109 #define R_IA64_DIR64LSB    0x27
110 #endif
111 #ifndef R_IA64_SECREL64LSB
112 #define R_IA64_SECREL64LSB 0x67
113 #endif
114 #ifndef R_IA64_SECREL64MSB
115 #define R_IA64_SECREL64MSB 0x66
116 #endif
117 #ifndef R_IA64_DTPREL32LSB
118 #define  R_IA64_DTPREL32LSB 0xb5
119 #endif
120 #ifndef R_IA64_DTPREL32MSB
121 #define  R_IA64_DTPREL32MSB 0xb4
122 #endif
123 #ifndef R_IA64_DTPREL64LSB
124 #define  R_IA64_DTPREL64LSB  0xb7
125 #endif
126 #ifndef R_IA64_DTPREL64MSB
127 #define  R_IA64_DTPREL64MSB  0xb6
128 #endif
129 
130 #ifndef EM_S390
131 #define EM_S390             22
132 #endif
133 #ifndef R_390_TLS_LDO32
134 #define R_390_TLS_LDO32         52
135 #endif
136 #ifndef R_390_TLS_LDO64
137 #define R_390_TLS_LDO64         53
138 #endif
139 
140 #ifndef R_390_32
141 #define R_390_32                4
142 #endif
143 #ifndef  R_390_64
144 #define  R_390_64                22
145 #endif
146 
147 #ifndef EM_SH
148 #define EM_SH                42
149 #endif
150 #ifndef R_SH_DIR32
151 #define R_SH_DIR32           1
152 #endif
153 #ifndef R_SH_TLS_DTPOFF32
154 #define R_SH_TLS_DTPOFF32    150
155 #endif
156 
157 
158 
159 
160 
161 
162 
163 #ifdef HAVE_ELF64_GETEHDR
164 extern Elf64_Ehdr *elf64_getehdr(Elf *);
165 #endif
166 #ifdef HAVE_ELF64_GETSHDR
167 extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
168 #endif
169 #ifdef WORDS_BIGENDIAN
170 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
171     {                                             \
172         dbg->de_copy_word(dest,                   \
173             ((char *)source) +srclength-len_out,  \
174             len_out) ;                            \
175     }
176 
177 
178 #else /* LITTLE ENDIAN */
179 
180 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
181     {                               \
182         dbg->de_copy_word( (dest) , \
183             ((char *)source) ,      \
184             len_out) ;              \
185     }
186 #endif
187 
188 
189 
190 typedef struct {
191     dwarf_elf_handle elf;
192     int              is_64bit;
193     Dwarf_Small      length_size;
194     Dwarf_Small      pointer_size;
195     Dwarf_Unsigned   section_count;
196     Dwarf_Endianness endianness;
197     Dwarf_Small      machine;
198     int              libdwarf_owns_elf;
199     Elf32_Ehdr *ehdr32;
200 
201 #ifdef HAVE_ELF64_GETEHDR
202     Elf64_Ehdr *ehdr64;
203 #endif
204     /*  Elf symtab and its strtab.  Initialized at first
205         call to do relocations, the actual data is in the Dwarf_Debug
206         struct, not allocated locally here. */
207     struct Dwarf_Section_s *symtab;
208     struct Dwarf_Section_s *strtab;
209 
210 } dwarf_elf_object_access_internals_t;
211 
212 struct Dwarf_Elf_Rela {
213     Dwarf_ufixed64 r_offset;
214     /*Dwarf_ufixed64 r_info; */
215     Dwarf_ufixed64 r_type;
216     Dwarf_ufixed64 r_symidx;
217     Dwarf_ufixed64 r_addend;
218 };
219 
220 
221 static int dwarf_elf_object_access_load_section(void* obj_in,
222     Dwarf_Half section_index,
223     Dwarf_Small** section_data,
224     int* error);
225 
226 /*  dwarf_elf_object_access_internals_init()
227     On error, set *error with libdwarf error code.
228 */
229 static int
dwarf_elf_object_access_internals_init(void * obj_in,dwarf_elf_handle elf,int * error)230 dwarf_elf_object_access_internals_init(void* obj_in,
231     dwarf_elf_handle elf,
232     int* error)
233 {
234     dwarf_elf_object_access_internals_t*obj =
235         (dwarf_elf_object_access_internals_t*)obj_in;
236     char *ehdr_ident = 0;
237     Dwarf_Half machine = 0;
238     obj->elf = elf;
239 
240     if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
241         *error = DW_DLE_ELF_GETIDENT_ERROR;
242         return DW_DLV_ERROR;
243     }
244 
245     obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
246 
247 
248     if (ehdr_ident[EI_DATA] == ELFDATA2LSB){
249         obj->endianness = DW_OBJECT_LSB;
250     } else if (ehdr_ident[EI_DATA] == ELFDATA2MSB){
251         obj->endianness = DW_OBJECT_MSB;
252     }
253 
254     if (obj->is_64bit) {
255 #ifdef HAVE_ELF64_GETEHDR
256         obj->ehdr64 = elf64_getehdr(elf);
257         if (obj->ehdr64 == NULL) {
258             *error = DW_DLE_ELF_GETEHDR_ERROR;
259             return DW_DLV_ERROR;
260         }
261         obj->section_count = obj->ehdr64->e_shnum;
262         machine = obj->ehdr64->e_machine;
263         obj->machine = machine;
264 #else
265         *error = DW_DLE_NO_ELF64_SUPPORT;
266         return DW_DLV_ERROR;
267 #endif
268     } else {
269         obj->ehdr32 = elf32_getehdr(elf);
270         if (obj->ehdr32 == NULL) {
271             *error = DW_DLE_ELF_GETEHDR_ERROR;
272             return DW_DLV_ERROR;
273         }
274         obj->section_count = obj->ehdr32->e_shnum;
275         machine = obj->ehdr32->e_machine;
276         obj->machine = machine;
277     }
278 
279     /*  The following length_size is Not Too Significant. Only used
280         one calculation, and an approximate one at that. */
281     obj->length_size = obj->is_64bit ? 8 : 4;
282     obj->pointer_size = obj->is_64bit ? 8 : 4;
283 
284 #ifdef _WIN32
285     if (obj->is_64bit && machine == EM_PPC64) {
286         /*  The SNC compiler generates the EM_PPC64 machine type for the
287             PS3 platform, but is a 32 bits pointer size in user mode. */
288         obj->pointer_size = 4;
289     }
290 #endif /* _WIN32 */
291 
292     if (obj->is_64bit && machine != EM_MIPS) {
293         /*  MIPS/IRIX makes pointer size and length size 8 for -64.
294             Other platforms make length 4 always. */
295         /*  4 here supports 32bit-offset dwarf2, as emitted by cygnus
296             tools, and the dwarfv2.1 64bit extension setting.
297             This is not the same as the size-of-an-offset, which
298             is 4 in 32bit dwarf and 8 in 64bit dwarf.  */
299         obj->length_size = 4;
300     }
301     return DW_DLV_OK;
302 }
303 
304 /* dwarf_elf_object_access_get_byte_order */
305 static
306 Dwarf_Endianness
dwarf_elf_object_access_get_byte_order(void * obj_in)307 dwarf_elf_object_access_get_byte_order(void* obj_in)
308 {
309     dwarf_elf_object_access_internals_t*obj =
310         (dwarf_elf_object_access_internals_t*)obj_in;
311     return obj->endianness;
312 }
313 
314 /* dwarf_elf_object_access_get_section_count() */
315 static
316 Dwarf_Unsigned
dwarf_elf_object_access_get_section_count(void * obj_in)317 dwarf_elf_object_access_get_section_count(void * obj_in)
318 {
319     dwarf_elf_object_access_internals_t*obj =
320         (dwarf_elf_object_access_internals_t*)obj_in;
321     return obj->section_count;
322 }
323 
324 
325 static int
_dwarf_get_elf_flags_func(void * obj_in,Dwarf_Half section_index,Dwarf_Unsigned * flags_out,Dwarf_Unsigned * addralign_out,int * error)326 _dwarf_get_elf_flags_func(
327     void* obj_in,
328     Dwarf_Half section_index,
329     Dwarf_Unsigned *flags_out,
330     Dwarf_Unsigned *addralign_out,
331     int *error)
332 {
333    dwarf_elf_object_access_internals_t*obj =
334         (dwarf_elf_object_access_internals_t*)obj_in;
335 
336     Elf32_Shdr *shdr32 = 0;
337 
338 #ifdef HAVE_ELF64_GETSHDR
339     Elf64_Shdr *shdr64 = 0;
340 #endif
341     Elf_Scn *scn = 0;
342 
343 
344     scn = elf_getscn(obj->elf, section_index);
345     if (scn == NULL) {
346         *error = DW_DLE_MDE;
347         return DW_DLV_ERROR;
348     }
349     if (obj->is_64bit) {
350 #ifdef HAVE_ELF64_GETSHDR
351         shdr64 = elf64_getshdr(scn);
352         if (shdr64 == NULL) {
353             *error = DW_DLE_ELF_GETSHDR_ERROR;
354             return DW_DLV_ERROR;
355         }
356 
357         /*  Get also section 'sh_type' and sh_info' fields, so the caller
358             can use it for additional tasks that require that info. */
359         *flags_out = shdr64->sh_flags;
360         *addralign_out = shdr64->sh_addralign;
361         return DW_DLV_OK;
362 #else
363         *error = DW_DLE_MISSING_ELF64_SUPPORT;
364         return DW_DLV_ERROR;
365 #endif /* HAVE_ELF64_GETSHDR */
366     }
367     if ((shdr32 = elf32_getshdr(scn)) == NULL) {
368         *error = DW_DLE_ELF_GETSHDR_ERROR;
369         return DW_DLV_ERROR;
370     }
371 
372     /*  Get also the section type, so the caller can use it for
373         additional tasks that require to know the section type. */
374     *flags_out = shdr32->sh_flags;
375     *addralign_out = shdr32->sh_addralign;
376     return DW_DLV_OK;
377 }
378 
379 
380 /*  dwarf_elf_object_access_get_section()
381 
382     If writing a function vaguely like this for a non-elf object,
383     be sure that when section-index is passed in as zero that
384     you set the fields in *ret_scn to reflect an empty section
385     with an empty string as the section name.  Adjust your
386     section indexes of your non-elf-reading-code
387     for all the necessary functions in Dwarf_Obj_Access_Methods_s
388     accordingly.
389 
390     Should have gotten sh_flags, sh_addralign too.
391     But Dwarf_Obj_Access_Section is publically defined so changing
392     it is quite painful for everyone.
393 */
394 static
395 int
dwarf_elf_object_access_get_section_info(void * obj_in,Dwarf_Half section_index,Dwarf_Obj_Access_Section * ret_scn,int * error)396 dwarf_elf_object_access_get_section_info(
397     void* obj_in,
398     Dwarf_Half section_index,
399     Dwarf_Obj_Access_Section* ret_scn,
400     int* error)
401 {
402     dwarf_elf_object_access_internals_t*obj =
403         (dwarf_elf_object_access_internals_t*)obj_in;
404 
405     Elf32_Shdr *shdr32 = 0;
406 
407 #ifdef HAVE_ELF64_GETSHDR
408     Elf64_Shdr *shdr64 = 0;
409 #endif
410     Elf_Scn *scn = 0;
411 
412 
413     scn = elf_getscn(obj->elf, section_index);
414     if (scn == NULL) {
415         *error = DW_DLE_MDE;
416         return DW_DLV_ERROR;
417     }
418     if (obj->is_64bit) {
419 #ifdef HAVE_ELF64_GETSHDR
420         shdr64 = elf64_getshdr(scn);
421         if (shdr64 == NULL) {
422             *error = DW_DLE_ELF_GETSHDR_ERROR;
423             return DW_DLV_ERROR;
424         }
425 
426         /*  Get also section 'sh_type' and sh_info' fields, so the caller
427             can use it for additional tasks that require that info. */
428         ret_scn->type = shdr64->sh_type;
429         ret_scn->size = shdr64->sh_size;
430         ret_scn->addr = shdr64->sh_addr;
431         ret_scn->link = shdr64->sh_link;
432         ret_scn->info = shdr64->sh_info;
433         ret_scn->entrysize = shdr64->sh_entsize;
434         ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx,
435             shdr64->sh_name);
436         if (ret_scn->name == NULL) {
437             *error = DW_DLE_ELF_STRPTR_ERROR;
438             return DW_DLV_ERROR;
439         }
440         return DW_DLV_OK;
441 #else
442         *error = DW_DLE_MISSING_ELF64_SUPPORT;
443         return DW_DLV_ERROR;
444 #endif /* HAVE_ELF64_GETSHDR */
445     }
446     if ((shdr32 = elf32_getshdr(scn)) == NULL) {
447         *error = DW_DLE_ELF_GETSHDR_ERROR;
448         return DW_DLV_ERROR;
449     }
450 
451     /*  Get also the section type, so the caller can use it for
452         additional tasks that require to know the section type. */
453     ret_scn->type = shdr32->sh_type;
454     ret_scn->size = shdr32->sh_size;
455     ret_scn->addr = shdr32->sh_addr;
456     ret_scn->link = shdr32->sh_link;
457     ret_scn->info = shdr32->sh_info;
458     ret_scn->entrysize = shdr32->sh_entsize;
459     ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx,
460         shdr32->sh_name);
461     if (ret_scn->name == NULL) {
462         *error = DW_DLE_ELF_STRPTR_ERROR;
463         return DW_DLV_ERROR;
464     }
465     return DW_DLV_OK;
466 }
467 
468 /* dwarf_elf_object_access_get_length_size */
469 static
470 Dwarf_Small
dwarf_elf_object_access_get_length_size(void * obj_in)471 dwarf_elf_object_access_get_length_size(void* obj_in)
472 {
473     dwarf_elf_object_access_internals_t*obj =
474         (dwarf_elf_object_access_internals_t*)obj_in;
475     return obj->length_size;
476 }
477 
478 /* dwarf_elf_object_access_get_pointer_size */
479 static
480 Dwarf_Small
dwarf_elf_object_access_get_pointer_size(void * obj_in)481 dwarf_elf_object_access_get_pointer_size(void* obj_in)
482 {
483     dwarf_elf_object_access_internals_t*obj =
484         (dwarf_elf_object_access_internals_t*)obj_in;
485     return obj->pointer_size;
486 }
487 
488 #define MATCH_REL_SEC(i_,s_,r_)  \
489 if (i_ == s_.dss_index) { \
490     *r_ = &s_;            \
491     return DW_DLV_OK;    \
492 }
493 
494 static int
find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,struct Dwarf_Section_s ** relocatablesec,int * error)495 find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
496    struct Dwarf_Section_s **relocatablesec, int *error)
497 {
498     MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
499     MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
500     MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
501     MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
502     MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
503     MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
504     MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
505     MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
506     MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
507     MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
508     MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
509     MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
510     MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
511     MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
512     MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
513     MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec);
514     /* dbg-> de_debug_tu_index,reloctablesec); */
515     /* dbg-> de_debug_cu_index,reloctablesec); */
516     /* dbg-> de_debug_gdbindex,reloctablesec); */
517     /* dbg-> de_debug_str,syms); */
518     /* de_elf_symtab,syms); */
519     /* de_elf_strtab,syms); */
520     *error = DW_DLE_RELOC_SECTION_MISMATCH;
521     return DW_DLV_ERROR;
522 
523 }
524 #undef MATCH_REL_SEC
525 
526 static void
get_rela_elf32(Dwarf_Small * data,unsigned int i,UNUSEDARG int endianness,UNUSEDARG int machine,struct Dwarf_Elf_Rela * relap)527 get_rela_elf32(Dwarf_Small *data, unsigned int i,
528   UNUSEDARG int endianness,
529   UNUSEDARG int machine,
530   struct Dwarf_Elf_Rela *relap)
531 {
532     Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela)));
533     relap->r_offset = relp->r_offset;
534     /*
535     relap->r_info = relp->r_info;
536    */
537     relap->r_type = ELF32_R_TYPE(relp->r_info);
538     relap->r_symidx = ELF32_R_SYM(relp->r_info);
539     relap->r_addend = relp->r_addend;
540 }
541 
542 static void
get_rela_elf64(Dwarf_Small * data,unsigned int i,int endianness,int machine,struct Dwarf_Elf_Rela * relap)543 get_rela_elf64(Dwarf_Small *data, unsigned int i,
544   int endianness,
545   int machine,
546   struct Dwarf_Elf_Rela *relap)
547 {
548 #ifdef HAVE_ELF64_RELA
549     Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela)));
550     relap->r_offset = relp->r_offset;
551     /*
552     relap->r_info = relp->r_info;
553     */
554 #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
555 #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
556     if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){
557         /*  This is really wierd. Treat this very specially.
558             The Elf64 LE MIPS object used for
559             testing (that has rela) wants the
560             values as  sym  ssym type3 type2 type, treating
561             each value as independent value. But libelf xlate
562             treats it as something else so we fudge here.
563             It is unclear
564             how to precisely characterize where these relocations
565             were used.
566             SGI MIPS on IRIX never used .rela relocations.
567             The BE 64bit elf MIPS test object with rela uses traditional
568             elf relocation layouts, not this special case.  */
569         /*  We ignore the special TYPE2 and TYPE3, they should be
570             value R_MIPS_NONE in rela. */
571         relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
572         relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
573 #undef MIPS64SYM
574 #undef MIPS64TYPE
575     } else
576     {
577         relap->r_type = ELF64_R_TYPE(relp->r_info);
578         relap->r_symidx = ELF64_R_SYM(relp->r_info);
579     }
580     relap->r_addend = relp->r_addend;
581 #endif
582 }
583 
584 static void
get_relocations_array(Dwarf_Bool is_64bit,int endianness,int machine,Dwarf_Small * data,unsigned int num_relocations,struct Dwarf_Elf_Rela * relap)585 get_relocations_array(Dwarf_Bool is_64bit,
586     int endianness,
587     int machine,
588     Dwarf_Small *data,
589     unsigned int num_relocations,
590     struct Dwarf_Elf_Rela *relap)
591 {
592     unsigned int i = 0;
593     void (*get_relocations)(Dwarf_Small *data, unsigned int i,
594         int endianness,
595         int machine,
596         struct Dwarf_Elf_Rela *relap);
597 
598     /* Handle 32/64 bit issue */
599     if (is_64bit) {
600         get_relocations = get_rela_elf64;
601     } else {
602         get_relocations = get_rela_elf32;
603     }
604 
605     for (i=0; i < num_relocations; i++) {
606         get_relocations(data, i,endianness,machine,
607             &(relap[i]));
608     }
609 
610 }
611 
612 static int
get_relocation_entries(Dwarf_Bool is_64bit,int endianness,int machine,Dwarf_Small * relocation_section,Dwarf_Unsigned relocation_section_size,Dwarf_Unsigned relocation_section_entrysize,struct Dwarf_Elf_Rela ** relas,unsigned int * nrelas,int * error)613 get_relocation_entries(Dwarf_Bool is_64bit,
614     int endianness,
615     int machine,
616     Dwarf_Small *relocation_section,
617     Dwarf_Unsigned relocation_section_size,
618     Dwarf_Unsigned relocation_section_entrysize,
619     struct Dwarf_Elf_Rela **relas,
620     unsigned int *nrelas,
621     int *error)
622 {
623     unsigned int relocation_size = 0;
624 
625     if (is_64bit) {
626 #ifdef HAVE_ELF64_RELA
627         relocation_size = sizeof(Elf64_Rela);
628 #else
629         *error = DW_DLE_MISSING_ELF64_SUPPORT;
630         return DW_DLV_ERROR;
631 #endif
632     } else {
633         relocation_size = sizeof(Elf32_Rela);
634     }
635     if (relocation_size != relocation_section_entrysize) {
636         /*  Means our struct definition does not match the
637             real object. */
638         *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
639         return DW_DLV_ERROR;
640     }
641 
642     if (relocation_section == NULL) {
643         *error = DW_DLE_RELOC_SECTION_PTR_NULL;
644         return(DW_DLV_ERROR);
645     }
646 
647     if ((relocation_section_size != 0)) {
648         size_t bytescount = 0;
649         if (relocation_section_size%relocation_size) {
650             *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
651             return DW_DLV_ERROR;
652         }
653         *nrelas = relocation_section_size/relocation_size;
654         bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela);
655         *relas = malloc(bytescount);
656         if (!*relas) {
657             *error = DW_DLE_MAF;
658             return(DW_DLV_ERROR);
659         }
660         memset(*relas,0,bytescount);
661         get_relocations_array(is_64bit,endianness,machine,
662             relocation_section,
663             *nrelas, *relas);
664     }
665     return(DW_DLV_OK);
666 }
667 
668 /*  We have a EM_QUALCOMM_DSP6 relocatable object
669     test case in dwarf regression tests, atefail/ig_server.
670     Values for QUALCOMM were derived from this executable.
671 
672     The r = 0 in the function will get optimized away
673     when not needed.
674 
675 */
676 
677 #define EM_QUALCOMM_DSP6 0xa4
678 #define QUALCOMM_REL32   6
679 
680 static Dwarf_Bool
is_32bit_abs_reloc(unsigned int type,Dwarf_Half machine)681 is_32bit_abs_reloc(unsigned int type, Dwarf_Half machine)
682 {
683     Dwarf_Bool r = 0;
684     switch (machine) {
685 #if defined(EM_MIPS) && defined (R_MIPS_32)
686     case EM_MIPS:
687         r =  (0
688 #if defined (R_MIPS_32)
689             | (type == R_MIPS_32)
690 #endif
691 #if defined (R_MIPS_TLS_DTPREL32)
692             | (type == R_MIPS_TLS_DTPREL32)
693 #endif /* DTPREL32 */
694             );
695         break;
696 #endif /* MIPS case */
697 #if defined(EM_SPARC32PLUS)  && defined (R_SPARC_UA32)
698     case EM_SPARC32PLUS:
699         r =  (type == R_SPARC_UA32);
700         break;
701 #endif
702 #if defined(EM_SPARCV9)  && defined (R_SPARC_UA32)
703     case EM_SPARCV9:
704         r =  (type == R_SPARC_UA32);
705         break;
706 #endif
707 #if defined(EM_SPARC) && defined (R_SPARC_UA32)
708     case EM_SPARC:
709         r =  (0
710 #if defined(R_SPARC_UA32)
711             | (type == R_SPARC_UA32)
712 #endif
713 #if (R_SPARC_TLS_DTPOFF32)
714             | (type == R_SPARC_TLS_DTPOFF32)
715 #endif
716             );
717         break;
718 #endif /* EM_SPARC */
719 #if defined(EM_386) && defined (R_386_32)
720     case EM_386:
721         r = (0
722 #if defined (R_386_32)
723             |  (type == R_386_32)
724 #endif
725 #if defined (R_386_TLS_LDO_32)
726             | (type == R_386_TLS_LDO_32)
727 #endif
728 #if defined (R_386_TLS_DTPOFF32)
729             | (type == R_386_TLS_DTPOFF32)
730 #endif
731             );
732         break;
733 #endif /* EM_386 */
734 
735 #if defined (EM_SH) && defined (R_SH_DIR32)
736     case EM_SH:
737         r = (0
738 #if defined (R_SH_DIR32)
739             | (type == R_SH_DIR32)
740 #endif
741 #if defined (R_SH_DTPOFF32)
742             | (type == R_SH_TLS_DTPOFF32)
743 #endif
744             );
745         break;
746 #endif /* SH */
747 
748 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
749     case EM_IA_64:  /* 32bit? ! */
750         r = (0
751 #if defined (R_IA64_SECREL32LSB)
752             | (type == R_IA64_SECREL32LSB)
753 #endif
754 #if defined (R_IA64_DIR32LSB)
755             | (type == R_IA64_DIR32LSB)
756 #endif
757 #if defined (R_IA64_DTPREL32LSB)
758             | (type == R_IA64_DTPREL32LSB)
759 #endif
760             );
761         break;
762 #endif /* EM_IA_64 */
763 
764 #if defined(EM_ARM) && defined (R_ARM_ABS32)
765     case EM_ARM:
766     case EM_AARCH64:
767         r = (0
768 #if defined (R_ARM_ABS32)
769             | ( type == R_ARM_ABS32)
770 #endif
771 #if defined (R_AARCH64_ABS32)
772             | ( type == R_AARCH64_ABS32)
773 #endif
774 #if defined (R_ARM_TLS_LDO32)
775             | ( type == R_ARM_TLS_LDO32)
776 #endif
777             );
778         break;
779 #endif /* EM_ARM */
780 
781 /*  On FreeBSD R_PPC64_ADDR32 not defined
782     so we use the R_PPC_ names which
783     have the proper value.
784     Our headers have:
785     R_PPC64_ADDR64   38
786     R_PPC_ADDR32     1 so we use this one
787     R_PPC64_ADDR32   R_PPC_ADDR32
788 
789     R_PPC64_DTPREL32 110  which may be wrong/unavailable
790     R_PPC64_DTPREL64 78
791     R_PPC_DTPREL32   78
792     */
793 #if defined(EM_PPC64) && defined (R_PPC_ADDR32)
794     case EM_PPC64:
795         r = (0
796 #if defined(R_PPC_ADDR32)
797             | (type == R_PPC_ADDR32)
798 #endif
799 #if defined(R_PPC64_DTPREL32)
800             | (type == R_PPC64_DTPREL32)
801 #endif
802             );
803         break;
804 #endif /* EM_PPC64 */
805 
806 
807 #if defined(EM_PPC) && defined (R_PPC_ADDR32)
808     case EM_PPC:
809         r = (0
810 #if defined (R_PPC_ADDR32)
811             | (type == R_PPC_ADDR32)
812 #endif
813 #if defined (R_PPC_DTPREL32)
814             | (type == R_PPC_DTPREL32)
815 #endif
816             );
817         break;
818 #endif /* EM_PPC */
819 
820 #if defined(EM_S390) && defined (R_390_32)
821     case EM_S390:
822         r = (0
823 #if defined (R_390_32)
824             | (type == R_390_32)
825 #endif
826 #if defined (R_390_TLS_LDO32)
827             | (type == R_390_TLS_LDO32)
828 #endif
829             );
830         break;
831 #endif /* EM_S390 */
832 
833 #if defined(EM_X86_64) && defined (R_X86_64_32)
834 #if defined(EM_K10M)
835     case EM_K10M:
836 #endif
837 #if defined(EM_L10M)
838     case EM_L10M:
839 #endif
840     case EM_X86_64:
841         r = (0
842 #if defined (R_X86_64_32)
843             | (type == R_X86_64_32)
844 #endif
845 #if defined (R_X86_64_DTPOFF32)
846             | (type ==  R_X86_64_DTPOFF32)
847 #endif
848             );
849         break;
850 #endif /* EM_X86_64 */
851 
852     case  EM_QUALCOMM_DSP6:
853         r = (type == QUALCOMM_REL32);
854         break;
855     }
856     return r;
857 }
858 
859 static Dwarf_Bool
is_64bit_abs_reloc(unsigned int type,Dwarf_Half machine)860 is_64bit_abs_reloc(unsigned int type, Dwarf_Half machine)
861 {
862     Dwarf_Bool r = 0;
863     switch (machine) {
864 #if defined(EM_MIPS) && defined (R_MIPS_64)
865     case EM_MIPS:
866         r = (0
867 #if defined (R_MIPS_64)
868             | (type == R_MIPS_64)
869 #endif
870 #if defined (R_MIPS_32)
871             | (type == R_MIPS_32)
872 #endif
873 #if defined(R_MIPS_TLS_DTPREL64)
874             | (type == R_MIPS_TLS_DTPREL64)
875 #endif
876             );
877         break;
878 #endif /* EM_MIPS */
879 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
880     case EM_SPARC32PLUS:
881         r =  (type == R_SPARC_UA64);
882         break;
883 #endif
884 #if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
885     case EM_SPARCV9:
886         r = (0
887 #if defined (R_SPARC_UA64)
888             | (type == R_SPARC_UA64)
889 #endif
890 #if defined (R_SPARC_TLS_DTPOFF64)
891             | (type == R_SPARC_TLS_DTPOFF64)
892 #endif
893             );
894         break;
895 #endif
896 #if defined(EM_SPARC) && defined (R_SPARC_UA64)
897     case EM_SPARC:
898         r = (0
899 #if defined(R_SPARC_UA64)
900             | (type == R_SPARC_UA64)
901 #endif
902 #if defined (R_SPARC_TLS_DTPOFF64)
903             | (type == R_SPARC_TLS_DTPOFF64)
904 #endif
905             );
906         break;
907 #endif /* EM_SPARC */
908 
909 #if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB)
910     case EM_IA_64: /* 64bit */
911         r = (0
912 #if defined (R_IA64_SECREL64LSB)
913             | (type == R_IA64_SECREL64LSB)
914 #endif
915 #if defined (R_IA64_SECREL32LSB)
916             | (type == R_IA64_SECREL32LSB)
917 #endif
918 #if defined (R_IA64_DIR64LSB)
919             | (type == R_IA64_DIR64LSB)
920 #endif
921 #if defined (R_IA64_DTPREL64LSB)
922             | (type == R_IA64_DTPREL64LSB)
923 #endif
924 #if defined (R_IA64_REL32LSB)
925             | (type == R_IA64_REL32LSB)
926 #endif
927             );
928         break;
929 #endif /* EM_IA_64 */
930 
931 #if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
932     case EM_PPC64:
933         r = (0
934 #if defined(R_PPC64_ADDR64)
935             | (type == R_PPC64_ADDR64)
936 #endif
937 #if defined(R_PPC64_DTPREL64)
938             | (type == R_PPC64_DTPREL64)
939 #endif
940             );
941         break;
942 #endif /* EM_PPC64 */
943 
944 #if defined(EM_S390) && defined (R_390_64)
945     case EM_S390:
946         r = (0
947 #if defined(R_390_64)
948             | (type == R_390_64)
949 #endif
950 #if defined(R_390_TLS_LDO64)
951             | (type == R_390_TLS_LDO64)
952 #endif
953             );
954         break;
955 #endif /* EM_390 */
956 
957 #if defined(EM_X86_64) && defined (R_X86_64_64)
958 #if defined(EM_K10M)
959     case EM_K10M:
960 #endif
961 #if defined(EM_L10M)
962     case EM_L10M:
963 #endif
964     case EM_X86_64:
965         r = (0
966 #if defined (R_X86_64_64)
967             | (type == R_X86_64_64)
968 #endif
969 #if defined (R_X86_64_DTPOFF32)
970             | (type == R_X86_64_DTPOFF64)
971 #endif
972             );
973         break;
974 #endif /* EM_X86_64 */
975 #if defined(EM_AARCH64) && defined (R_AARCH64_ABS64)
976     case EM_AARCH64:
977         r = (0
978 #if defined (R_AARCH64_ABS64)
979             | ( type == R_AARCH64_ABS64)
980 #endif
981             );
982         break;
983 #endif /* EM_AARCH64 */
984 
985     }
986     return r;
987 }
988 
989 
990 /*  Returns DW_DLV_OK if it works, else DW_DLV_ERROR.
991     The caller may decide to ignore the errors or report them. */
992 static int
update_entry(Dwarf_Debug dbg,Dwarf_Bool is_64bit,UNUSEDARG Dwarf_Endianness endianess,UNUSEDARG Dwarf_Half machine,struct Dwarf_Elf_Rela * rela,Dwarf_Small * target_section,Dwarf_Unsigned target_section_size,Dwarf_Small * symtab_section_data,Dwarf_Unsigned symtab_section_size,Dwarf_Unsigned symtab_section_entrysize,int * error)993 update_entry(Dwarf_Debug dbg,
994     Dwarf_Bool is_64bit,
995     UNUSEDARG Dwarf_Endianness endianess,
996     UNUSEDARG Dwarf_Half machine,
997     struct Dwarf_Elf_Rela *rela,
998     Dwarf_Small *target_section,
999     Dwarf_Unsigned target_section_size,
1000     Dwarf_Small *symtab_section_data,
1001     Dwarf_Unsigned symtab_section_size,
1002     Dwarf_Unsigned symtab_section_entrysize,
1003     int *error)
1004 {
1005     unsigned int type = 0;
1006     unsigned int sym_idx = 0;
1007 #ifdef HAVE_ELF64_SYM
1008     Elf64_Sym sym_buf;
1009     Elf64_Sym *sym = 0;
1010 #else
1011     Elf32_Sym sym_buf;
1012     Elf32_Sym *sym = 0;
1013 #endif
1014     Elf32_Sym *sym32 = 0;
1015     Dwarf_ufixed64 offset = 0;
1016     Dwarf_sfixed64 addend = 0;
1017     Dwarf_Unsigned reloc_size = 0;
1018     Dwarf_Unsigned symtab_entry_count = 0;
1019 
1020     if (symtab_section_entrysize == 0) {
1021         *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO;
1022         return DW_DLV_ERROR;
1023     }
1024     symtab_entry_count = symtab_section_size/symtab_section_entrysize;
1025 
1026     /* Dwarf_Elf_Rela dereferencing */
1027     offset = rela->r_offset;
1028     addend = rela->r_addend;
1029     type = rela->r_type;
1030     sym_idx = rela->r_symidx;
1031     if (sym_idx >= symtab_entry_count) {
1032         *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD;
1033         return DW_DLV_ERROR;
1034     }
1035     if (offset >= target_section_size) {
1036         /*  If offset really big, any add will overflow.
1037             So lets stop early if offset is corrupt. */
1038         *error = DW_DLE_RELOC_INVALID;
1039         return DW_DLV_ERROR;
1040     }
1041     if (is_64bit) {
1042 #ifdef HAVE_ELF64_SYM
1043         sym = &((Elf64_Sym*)symtab_section_data)[sym_idx];
1044 #endif
1045     } else {
1046         sym32 = &((Elf32_Sym*)symtab_section_data)[sym_idx];
1047 
1048         /*  Convert Elf32_Sym struct to Elf64_Sym struct. We point at
1049             an Elf64_Sym local variable (sym_buf) to allow us to use the
1050             same pointer (sym) for both 32-bit and 64-bit instances.  */
1051         sym = &sym_buf;
1052         sym->st_name = sym32->st_name;
1053         sym->st_info = sym32->st_info;
1054         sym->st_other = sym32->st_other;
1055         sym->st_shndx = sym32->st_shndx;
1056         sym->st_value = sym32->st_value;
1057         sym->st_size = sym32->st_size;
1058     }
1059 
1060     /* Determine relocation size */
1061     if (is_32bit_abs_reloc(type, machine)) {
1062         reloc_size = 4;
1063     } else if (is_64bit_abs_reloc(type, machine)) {
1064         reloc_size = 8;
1065     } else {
1066         *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN;
1067         return DW_DLV_ERROR;
1068     }
1069     if ( (offset + reloc_size) < offset) {
1070         /* Another check for overflow. */
1071         *error = DW_DLE_RELOC_INVALID;
1072         return DW_DLV_ERROR;
1073     }
1074     if ( (offset + reloc_size) > target_section_size) {
1075         *error = DW_DLE_RELOC_INVALID;
1076         return DW_DLV_ERROR;
1077     }
1078     {
1079         /*  Assuming we do not need to do a READ_UNALIGNED here
1080             at target_section + offset and add its value to
1081             outval.  Some ABIs say no read (for example MIPS),
1082             but if some do then which ones? */
1083         Dwarf_Unsigned outval = sym->st_value + addend;
1084         /*  The 0th byte goes at offset. */
1085         WRITE_UNALIGNED(dbg,target_section + offset,
1086             &outval,sizeof(outval),reloc_size);
1087     }
1088     return DW_DLV_OK;
1089 }
1090 
1091 
1092 
1093 /*  Somewhat arbitrarily, we attempt to apply all the relocations we can
1094     and still notify the caller of at least one error if we found
1095     any errors.  */
1096 static int
apply_rela_entries(Dwarf_Debug dbg,Dwarf_Bool is_64bit,Dwarf_Endianness endianess,Dwarf_Half machine,Dwarf_Small * target_section,Dwarf_Unsigned target_section_size,Dwarf_Small * symtab_section,Dwarf_Unsigned symtab_section_size,Dwarf_Unsigned symtab_section_entrysize,struct Dwarf_Elf_Rela * relas,unsigned int nrelas,int * error)1097 apply_rela_entries(Dwarf_Debug dbg,
1098     Dwarf_Bool is_64bit,
1099     Dwarf_Endianness endianess,
1100     Dwarf_Half machine,
1101     Dwarf_Small *target_section,
1102     Dwarf_Unsigned target_section_size,
1103     Dwarf_Small *symtab_section,
1104     Dwarf_Unsigned symtab_section_size,
1105     Dwarf_Unsigned symtab_section_entrysize,
1106     struct Dwarf_Elf_Rela *relas, unsigned int nrelas,
1107     int *error)
1108 {
1109     int return_res = DW_DLV_OK;
1110     if ((target_section != NULL)  && (relas != NULL)) {
1111         unsigned int i;
1112         if (symtab_section_entrysize == 0) {
1113             *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO;
1114             return DW_DLV_ERROR;
1115         }
1116         if (symtab_section_size%symtab_section_entrysize) {
1117             *error = DW_DLE_SYMTAB_SECTION_LENGTH_ODD;
1118             return DW_DLV_ERROR;
1119         }
1120         for (i = 0; i < nrelas; i++) {
1121             int res = update_entry(dbg, is_64bit,
1122                 endianess,
1123                 machine,
1124                 &(relas)[i],
1125                 target_section,
1126                 target_section_size,
1127                 symtab_section,
1128                 symtab_section_size,
1129                 symtab_section_entrysize,
1130                 error);
1131             if (res != DW_DLV_OK) {
1132                 return_res = res;
1133             }
1134         }
1135     }
1136     return return_res;
1137 }
1138 
1139 
1140 static int
loop_through_relocations(Dwarf_Debug dbg,dwarf_elf_object_access_internals_t * obj,struct Dwarf_Section_s * relocatablesec,int * error)1141 loop_through_relocations(
1142    Dwarf_Debug dbg,
1143    dwarf_elf_object_access_internals_t* obj,
1144    struct Dwarf_Section_s *relocatablesec,
1145    int *error)
1146 {
1147     Dwarf_Small *target_section = 0;
1148     Dwarf_Small *symtab_section = obj->symtab->dss_data;
1149     Dwarf_Unsigned symtab_section_entrysize = obj->symtab->dss_entrysize;
1150     Dwarf_Unsigned symtab_section_size = obj->symtab->dss_size;
1151     Dwarf_Small *relocation_section  = relocatablesec->dss_reloc_data;
1152     Dwarf_Unsigned relocation_section_size =
1153         relocatablesec->dss_reloc_size;
1154     Dwarf_Unsigned relocation_section_entrysize = relocatablesec->dss_reloc_entrysize;
1155 
1156     int ret = DW_DLV_ERROR;
1157     struct Dwarf_Elf_Rela *relas = 0;
1158     unsigned int nrelas = 0;
1159     Dwarf_Small *mspace = 0;
1160 
1161     ret = get_relocation_entries(obj->is_64bit,
1162         obj->endianness,
1163         obj->machine,
1164         relocation_section,
1165         relocation_section_size,
1166         relocation_section_entrysize,
1167         &relas, &nrelas, error);
1168     if (ret != DW_DLV_OK) {
1169         free(relas);
1170         return ret;
1171     }
1172 
1173     if(!relocatablesec->dss_data_was_malloc) {
1174         /*  Some systems read Elf in read-only memory via mmap or the like.
1175             So the only safe thing is to copy the current data into
1176             malloc space and refer to the malloc space instead of the
1177             space returned by the elf library */
1178         mspace = malloc(relocatablesec->dss_size);
1179         if (!mspace) {
1180             *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL;
1181             return DW_DLV_ERROR;
1182         }
1183         memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size);
1184         relocatablesec->dss_data = mspace;
1185         target_section = relocatablesec->dss_data;
1186         relocatablesec->dss_data_was_malloc = TRUE;
1187     }
1188     target_section = relocatablesec->dss_data;
1189     ret = apply_rela_entries(
1190         dbg,
1191         obj->is_64bit,
1192         obj->endianness, obj->machine,
1193         target_section,
1194         relocatablesec->dss_size,
1195         symtab_section,
1196         symtab_section_size,
1197         symtab_section_entrysize,
1198         relas, nrelas, error);
1199     free(relas);
1200     return ret;
1201 }
1202 
1203 /*  Find the section data in dbg and find all the relevant
1204     sections.  Then do relocations.
1205 */
1206 static int
dwarf_elf_object_relocate_a_section(void * obj_in,Dwarf_Half section_index,Dwarf_Debug dbg,int * error)1207 dwarf_elf_object_relocate_a_section(void* obj_in,
1208     Dwarf_Half section_index,
1209     Dwarf_Debug dbg,
1210     int* error)
1211 {
1212     int res = DW_DLV_ERROR;
1213     dwarf_elf_object_access_internals_t*obj = 0;
1214     struct Dwarf_Section_s * relocatablesec = 0;
1215     if (section_index == 0) {
1216         return DW_DLV_NO_ENTRY;
1217     }
1218     obj = (dwarf_elf_object_access_internals_t*)obj_in;
1219 
1220     /* The section to relocate must already be loaded into memory. */
1221     res = find_section_to_relocate(dbg, section_index,&relocatablesec,error);
1222     if (res != DW_DLV_OK) {
1223         return res;
1224     }
1225 
1226     /*  Sun and possibly others do not always set sh_link in .debug_* sections.
1227         So we cannot do full  consistency checks. */
1228     if (relocatablesec->dss_reloc_index == 0 ) {
1229         /* Something is wrong. */
1230         *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
1231         return DW_DLV_ERROR;
1232     }
1233     /* Now load the relocations themselves. */
1234     res =  dwarf_elf_object_access_load_section(obj_in,
1235         relocatablesec->dss_reloc_index,
1236         &relocatablesec->dss_reloc_data, error);
1237     if (res != DW_DLV_OK) {
1238         return res;
1239     }
1240 
1241     /* Now get the symtab. */
1242     if (!obj->symtab) {
1243         obj->symtab = &dbg->de_elf_symtab;
1244         obj->strtab = &dbg->de_elf_strtab;
1245     }
1246     if (obj->symtab->dss_index != relocatablesec->dss_reloc_link) {
1247         /* Something is wrong. */
1248         *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
1249         return DW_DLV_ERROR;
1250     }
1251     if (obj->strtab->dss_index != obj->symtab->dss_link) {
1252         /* Something is wrong. */
1253         *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX;
1254         return DW_DLV_ERROR;
1255     }
1256     if (!obj->symtab->dss_data) {
1257         /* Now load the symtab */
1258         res =  dwarf_elf_object_access_load_section(obj_in,
1259             obj->symtab->dss_index,
1260             &obj->symtab->dss_data, error);
1261         if (res != DW_DLV_OK) {
1262             return res;
1263         }
1264     }
1265     if (!obj->strtab->dss_data) {
1266         /* Now load the strtab */
1267         res = dwarf_elf_object_access_load_section(obj_in,
1268             obj->strtab->dss_index,
1269             &obj->strtab->dss_data,error);
1270         if (res != DW_DLV_OK){
1271             return res;
1272         }
1273     }
1274 
1275     /* We have all the data we need in memory. */
1276     res = loop_through_relocations(dbg,obj,relocatablesec,error);
1277 
1278     return res;
1279 }
1280 
1281 /*  dwarf_elf_object_access_load_section()
1282     We are only asked to load sections that
1283     libdwarf really needs. */
1284 static int
dwarf_elf_object_access_load_section(void * obj_in,Dwarf_Half section_index,Dwarf_Small ** section_data,int * error)1285 dwarf_elf_object_access_load_section(void* obj_in,
1286     Dwarf_Half section_index,
1287     Dwarf_Small** section_data,
1288     int* error)
1289 {
1290     dwarf_elf_object_access_internals_t*obj =
1291         (dwarf_elf_object_access_internals_t*)obj_in;
1292     if (section_index == 0) {
1293         return DW_DLV_NO_ENTRY;
1294     }
1295 
1296     {
1297         Elf_Scn *scn = 0;
1298         Elf_Data *data = 0;
1299 
1300         scn = elf_getscn(obj->elf, section_index);
1301         if (scn == NULL) {
1302             /*  The section_index does not exist or
1303                 obj->elf is NULL. */
1304             *error = DW_DLE_MDE;
1305             return DW_DLV_ERROR;
1306         }
1307 
1308         /*  When using libelf as a producer, section data may be stored
1309             in multiple buffers. In libdwarf however, we only use libelf
1310             as a consumer (there is a dwarf producer API, but it doesn't
1311             use libelf). Because of this, this single call to elf_getdata
1312             will retrieve the entire section in a single contiguous
1313             buffer. */
1314         data = elf_getdata(scn, NULL);
1315         if (data == NULL) {
1316             /*  Most likely means that the Elf section header
1317                 is damaged/corrupt and the data is
1318                 impossible to read into
1319                 memory.   The size specified in the
1320                 Elf section is too large to allocate memory
1321                 for so the data could not be loaded. */
1322             *error = DW_DLE_MDE;
1323             return DW_DLV_ERROR;
1324         }
1325         if (!data->d_buf) {
1326             /*  If NULL it means 'the section has no data'
1327                 according to libelf documentation.
1328                 No DWARF-related section should ever have
1329                 'no data'.  Happens if a section type is
1330                 SHT_NOBITS and no section libdwarf
1331                 wants to look at should be SHT_NOBITS. */
1332             *error = DW_DLE_MDE;
1333             return DW_DLV_ERROR;
1334         }
1335         *section_data = data->d_buf;
1336     }
1337     return DW_DLV_OK;
1338 }
1339 
1340 
1341 /* dwarf_elf_access method table. */
1342 static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods =
1343 {
1344     dwarf_elf_object_access_get_section_info,
1345     dwarf_elf_object_access_get_byte_order,
1346     dwarf_elf_object_access_get_length_size,
1347     dwarf_elf_object_access_get_pointer_size,
1348     dwarf_elf_object_access_get_section_count,
1349     dwarf_elf_object_access_load_section,
1350     dwarf_elf_object_relocate_a_section
1351 };
1352 
1353 
1354 /*  Interface for the ELF object file implementation.
1355     On error this should set *err with the
1356     libdwarf error code.
1357 */
1358 int
dwarf_elf_object_access_init(dwarf_elf_handle elf,int libdwarf_owns_elf,Dwarf_Obj_Access_Interface ** ret_obj,int * err)1359 dwarf_elf_object_access_init(dwarf_elf_handle elf,
1360     int libdwarf_owns_elf,
1361     Dwarf_Obj_Access_Interface** ret_obj,
1362     int *err)
1363 {
1364     int res = 0;
1365     dwarf_elf_object_access_internals_t *internals = 0;
1366     Dwarf_Obj_Access_Interface *intfc = 0;
1367 
1368     internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
1369     if (!internals) {
1370         *err = DW_DLE_ALLOC_FAIL;
1371         /* Impossible case, we hope. Give up. */
1372         return DW_DLV_ERROR;
1373     }
1374     memset(internals,0,sizeof(*internals));
1375     res = dwarf_elf_object_access_internals_init(internals, elf, err);
1376     if (res != DW_DLV_OK){
1377         /* *err is already set. */
1378         free(internals);
1379         return DW_DLV_ERROR;
1380     }
1381     internals->libdwarf_owns_elf = libdwarf_owns_elf;
1382 
1383     intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
1384     if (!intfc) {
1385         /* Impossible case, we hope. Give up. */
1386         *err = DW_DLE_ALLOC_FAIL;
1387         free(internals);
1388         return DW_DLV_ERROR;
1389     }
1390     /* Initialize the interface struct */
1391     intfc->object = internals;
1392     intfc->methods = &dwarf_elf_object_access_methods;
1393 
1394     /*  An access method hidden from non-elf. Needed to
1395         handle new-ish SHF_COMPRESSED flag in elf.  */
1396     _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func;
1397 
1398 
1399     *ret_obj = intfc;
1400     return DW_DLV_OK;
1401 }
1402 
1403 
1404 
1405 /* Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init.  */
1406 void
dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface * obj)1407 dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj)
1408 {
1409     if (!obj) {
1410         return;
1411     }
1412     if (obj->object) {
1413         dwarf_elf_object_access_internals_t *internals =
1414             (dwarf_elf_object_access_internals_t *)obj->object;
1415         if (internals->libdwarf_owns_elf){
1416             elf_end(internals->elf);
1417         }
1418     }
1419     free(obj->object);
1420     free(obj);
1421 }
1422 
1423 /*  This function returns the Elf * pointer
1424     associated with a Dwarf_Debug.
1425 
1426     This function only makes sense if ELF is implied.  */
1427 int
dwarf_get_elf(Dwarf_Debug dbg,dwarf_elf_handle * elf,Dwarf_Error * error)1428 dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
1429     Dwarf_Error * error)
1430 {
1431     struct Dwarf_Obj_Access_Interface_s * obj = 0;
1432     if (dbg == NULL) {
1433         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1434         return (DW_DLV_ERROR);
1435     }
1436 
1437     obj = dbg->de_obj_file;
1438     if (obj) {
1439         dwarf_elf_object_access_internals_t *internals =
1440             (dwarf_elf_object_access_internals_t*)obj->object;
1441         if (internals->elf == NULL) {
1442             _dwarf_error(dbg, error, DW_DLE_FNO);
1443             return (DW_DLV_ERROR);
1444         }
1445         *elf = internals->elf;
1446         return DW_DLV_OK;
1447 
1448     }
1449     _dwarf_error(dbg, error, DW_DLE_FNO);
1450     return DW_DLV_ERROR;
1451 }
1452 
1453 
1454