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-2010 David Anderson. All rights reserved.
6 Portions Copyright 2009-2010 Novell Inc. All rights reserved.
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of version 2.1 of the GNU Lesser General Public License
10 as published by the Free Software Foundation.
12 This program is distributed in the hope that it would be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 Further, this software is distributed without any warranty that it is
17 free of the rightful claim of any third person regarding infringement
18 or the like. Any license provided herein, whether implied or
19 otherwise, applies only to this software file. Patent licenses, if
20 any, provided herein do not apply to combinations of this program with
21 other software, or any other product whatsoever.
23 You should have received a copy of the GNU Lesser General Public
24 License along with this program; if not, write the Free Software
25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
28 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
29 Mountain View, CA 94043, or:
33 For further information regarding this notice, see:
35 http://oss.sgi.com/projects/GenInfo/NoticeExplan
40 #include "dwarf_incl.h"
41 #include "dwarf_elf_access.h"
49 #ifdef HAVE_LIBELF_LIBELF_H
50 #include <libelf/libelf.h>
56 #include <sys/types.h>
64 /* This is the standard elf value EM_MIPS. */
69 #ifdef HAVE_ELF64_GETEHDR
70 extern Elf64_Ehdr
*elf64_getehdr(Elf
*);
72 #ifdef HAVE_ELF64_GETSHDR
73 extern Elf64_Shdr
*elf64_getshdr(Elf_Scn
*);
75 #ifdef WORDS_BIGENDIAN
76 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
78 dbg->de_copy_word(dest, \
79 ((char *)source) +srclength-len_out, \
84 #else /* LITTLE ENDIAN */
86 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
88 dbg->de_copy_word( (dest) , \
99 Dwarf_Small length_size
;
100 Dwarf_Small pointer_size
;
101 Dwarf_Unsigned section_count
;
102 Dwarf_Endianness endianness
;
104 int libdwarf_owns_elf
;
107 #ifdef HAVE_ELF64_GETEHDR
110 /* Elf symtab and its strtab. Initialized at first
111 call to do relocations, the actual data is in the Dwarf_Debug
112 struct, not allocated locally here. */
113 struct Dwarf_Section_s
*symtab
;
114 struct Dwarf_Section_s
*strtab
;
116 } dwarf_elf_object_access_internals_t
;
118 struct Dwarf_Elf_Rela
{
119 Dwarf_ufixed64 r_offset
;
120 /*Dwarf_ufixed64 r_info; */
121 Dwarf_ufixed64 r_type
;
122 Dwarf_ufixed64 r_symidx
;
123 Dwarf_ufixed64 r_addend
;
127 static int dwarf_elf_object_access_load_section(void* obj_in
,
128 Dwarf_Half section_index
,
129 Dwarf_Small
** section_data
,
133 dwarf_elf_object_access_internals_init()
136 dwarf_elf_object_access_internals_init(void* obj_in
,
137 dwarf_elf_handle elf
,
140 dwarf_elf_object_access_internals_t
*obj
=
141 (dwarf_elf_object_access_internals_t
*)obj_in
;
142 char *ehdr_ident
= 0;
143 Dwarf_Half machine
= 0;
146 if ((ehdr_ident
= elf_getident(elf
, NULL
)) == NULL
) {
147 *error
= DW_DLE_ELF_GETIDENT_ERROR
;
151 obj
->is_64bit
= (ehdr_ident
[EI_CLASS
] == ELFCLASS64
);
154 if(ehdr_ident
[EI_DATA
] == ELFDATA2LSB
){
155 obj
->endianness
= DW_OBJECT_LSB
;
157 else if(ehdr_ident
[EI_DATA
] == ELFDATA2MSB
){
158 obj
->endianness
= DW_OBJECT_MSB
;
162 #ifdef HAVE_ELF64_GETEHDR
163 obj
->ehdr64
= elf64_getehdr(elf
);
164 if (obj
->ehdr64
== NULL
) {
165 *error
= DW_DLE_ELF_GETEHDR_ERROR
;
168 obj
->section_count
= obj
->ehdr64
->e_shnum
;
169 machine
= obj
->ehdr64
->e_machine
;
170 obj
->machine
= machine
;
172 *error
= DW_DLE_NO_ELF64_SUPPORT
;
177 obj
->ehdr32
= elf32_getehdr(elf
);
178 if (obj
->ehdr32
== NULL
) {
179 *error
= DW_DLE_ELF_GETEHDR_ERROR
;
182 obj
->section_count
= obj
->ehdr32
->e_shnum
;
183 machine
= obj
->ehdr32
->e_machine
;
184 obj
->machine
= machine
;
187 /* The following length_size is Not Too Significant. Only used
188 one calculation, and an approximate one at that. */
189 obj
->length_size
= obj
->is_64bit
? 8 : 4;
190 obj
->pointer_size
= obj
->is_64bit
? 8 : 4;
192 if (obj
->is_64bit
&& machine
!= EM_MIPS
) {
193 /* MIPS/IRIX makes pointer size and length size 8 for -64.
194 Other platforms make length 4 always. */
195 /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
196 tools, and the dwarfv2.1 64bit extension setting.
197 This is not the same as the size-of-an-offset, which
198 is 4 in 32bit dwarf and 8 in 64bit dwarf. */
199 obj
->length_size
= 4;
205 dwarf_elf_object_access_get_byte_order
209 dwarf_elf_object_access_get_byte_order(void* obj_in
)
211 dwarf_elf_object_access_internals_t
*obj
=
212 (dwarf_elf_object_access_internals_t
*)obj_in
;
213 return obj
->endianness
;
217 dwarf_elf_object_access_get_section_count()
221 dwarf_elf_object_access_get_section_count(void * obj_in
)
223 dwarf_elf_object_access_internals_t
*obj
=
224 (dwarf_elf_object_access_internals_t
*)obj_in
;
225 return obj
->section_count
;
230 dwarf_elf_object_access_get_section()
234 dwarf_elf_object_access_get_section_info(
236 Dwarf_Half section_index
,
237 Dwarf_Obj_Access_Section
* ret_scn
,
240 dwarf_elf_object_access_internals_t
*obj
=
241 (dwarf_elf_object_access_internals_t
*)obj_in
;
243 Elf32_Shdr
*shdr32
= 0;
245 #ifdef HAVE_ELF64_GETSHDR
246 Elf64_Shdr
*shdr64
= 0;
251 scn
= elf_getscn(obj
->elf
, section_index
);
257 #ifdef HAVE_ELF64_GETSHDR
258 shdr64
= elf64_getshdr(scn
);
259 if (shdr64
== NULL
) {
260 *error
= DW_DLE_ELF_GETSHDR_ERROR
;
264 ret_scn
->size
= shdr64
->sh_size
;
265 ret_scn
->addr
= shdr64
->sh_addr
;
266 ret_scn
->link
= shdr64
->sh_link
;
268 ret_scn
->name
= elf_strptr(obj
->elf
, obj
->ehdr64
->e_shstrndx
,
270 if(ret_scn
->name
== NULL
) {
271 *error
= DW_DLE_ELF_STRPTR_ERROR
;
276 *error
= DW_DLE_MISSING_ELF64_SUPPORT
;
278 #endif /* HAVE_ELF64_GETSHDR */
280 if ((shdr32
= elf32_getshdr(scn
)) == NULL
) {
281 *error
= DW_DLE_ELF_GETSHDR_ERROR
;
285 ret_scn
->size
= shdr32
->sh_size
;
286 ret_scn
->addr
= shdr32
->sh_addr
;
287 ret_scn
->link
= shdr32
->sh_link
;
289 ret_scn
->name
= elf_strptr(obj
->elf
, obj
->ehdr32
->e_shstrndx
,
291 if (ret_scn
->name
== NULL
) {
292 *error
= DW_DLE_ELF_STRPTR_ERROR
;
299 dwarf_elf_object_access_get_length_size
303 dwarf_elf_object_access_get_length_size(void* obj_in
)
305 dwarf_elf_object_access_internals_t
*obj
=
306 (dwarf_elf_object_access_internals_t
*)obj_in
;
307 return obj
->length_size
;
311 dwarf_elf_object_access_get_pointer_size
315 dwarf_elf_object_access_get_pointer_size(void* obj_in
)
317 dwarf_elf_object_access_internals_t
*obj
=
318 (dwarf_elf_object_access_internals_t
*)obj_in
;
319 return obj
->pointer_size
;
322 #define MATCH_REL_SEC(i_,s_,r_) \
323 if(i_ == s_.dss_index) { \
329 find_section_to_relocate(Dwarf_Debug dbg
,Dwarf_Half section_index
,
330 struct Dwarf_Section_s
**relocatablesec
, int *error
)
332 MATCH_REL_SEC(section_index
,dbg
->de_debug_info
,relocatablesec
);
333 MATCH_REL_SEC(section_index
,dbg
->de_debug_abbrev
,relocatablesec
);
334 MATCH_REL_SEC(section_index
,dbg
->de_debug_line
,relocatablesec
);
335 MATCH_REL_SEC(section_index
,dbg
->de_debug_loc
,relocatablesec
);
336 MATCH_REL_SEC(section_index
,dbg
->de_debug_aranges
,relocatablesec
);
337 MATCH_REL_SEC(section_index
,dbg
->de_debug_macinfo
,relocatablesec
);
338 MATCH_REL_SEC(section_index
,dbg
->de_debug_pubnames
,relocatablesec
);
339 MATCH_REL_SEC(section_index
,dbg
->de_debug_ranges
,relocatablesec
);
340 MATCH_REL_SEC(section_index
,dbg
->de_debug_frame
,relocatablesec
);
341 MATCH_REL_SEC(section_index
,dbg
->de_debug_frame_eh_gnu
,relocatablesec
);
342 MATCH_REL_SEC(section_index
,dbg
->de_debug_pubtypes
,relocatablesec
);
343 MATCH_REL_SEC(section_index
,dbg
->de_debug_funcnames
,relocatablesec
);
344 MATCH_REL_SEC(section_index
,dbg
->de_debug_typenames
,relocatablesec
);
345 MATCH_REL_SEC(section_index
,dbg
->de_debug_varnames
,relocatablesec
);
346 MATCH_REL_SEC(section_index
,dbg
->de_debug_weaknames
,relocatablesec
);
347 /* dbg-> de_debug_str,syms); */
348 /* de_elf_symtab,syms); */
349 /* de_elf_strtab,syms); */
350 *error
= DW_DLE_RELOC_SECTION_MISMATCH
;
357 get_rela_elf32(Dwarf_Small
*data
, unsigned int i
,
359 int machine
, struct Dwarf_Elf_Rela
*relap
)
361 Elf32_Rela
*relp
= (Elf32_Rela
*)(data
+ (i
* sizeof(Elf32_Rela
)));
362 relap
->r_offset
= relp
->r_offset
;
364 relap->r_info = relp->r_info;
366 relap
->r_type
= ELF32_R_TYPE(relp
->r_info
);
367 relap
->r_symidx
= ELF32_R_SYM(relp
->r_info
);
368 relap
->r_addend
= relp
->r_addend
;
372 get_rela_elf64(Dwarf_Small
*data
, unsigned int i
,
374 int machine
,struct Dwarf_Elf_Rela
*relap
)
376 #ifdef HAVE_ELF64_RELA
377 Elf64_Rela
* relp
= (Elf64_Rela
*)(data
+ (i
* sizeof(Elf64_Rela
)));
378 relap
->r_offset
= relp
->r_offset
;
380 relap->r_info = relp->r_info;
382 if(machine
== EM_MIPS
&& endianness
== DW_OBJECT_LSB
) {
383 /* This is really wierd. Treat this very specially.
384 The Elf64 LE MIPS object used for
385 testing (that has rela) wants the
386 values as sym ssym type3 type2 type, treating
387 each value as independent value. But libelf xlate
388 treats it as something else so we fudge here.
390 how to precisely characterize where these relocations
392 SGI MIPS on IRIX never used .rela relocations.
393 The BE 64bit elf MIPS test object with rela uses traditional
394 elf relocation layouts, not this special case. */
395 #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
396 #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
397 /* We ignore the special TYPE2 and TYPE3, they should be
398 value R_MIPS_NONE in rela. */
399 relap
->r_type
= ELF64MIPS_REL_TYPE(relp
->r_info
);
400 relap
->r_symidx
= ELF64MIPS_REL_SYM(relp
->r_info
);
405 relap
->r_type
= ELF64_R_TYPE(relp
->r_info
);
406 relap
->r_symidx
= ELF64_R_SYM(relp
->r_info
);
408 relap
->r_addend
= relp
->r_addend
;
413 get_relocations_array(Dwarf_Bool is_64bit
,
417 unsigned int num_relocations
,
418 struct Dwarf_Elf_Rela
*relap
)
421 void (*get_relocations
)(Dwarf_Small
*data
, unsigned int i
,
424 struct Dwarf_Elf_Rela
*relap
);
426 /* Handle 32/64 bit issue
429 get_relocations
= get_rela_elf64
;
431 get_relocations
= get_rela_elf32
;
434 for (i
=0; i
< num_relocations
; i
++) {
435 get_relocations(data
, i
,endianness
,machine
, &(relap
[i
]));
441 get_relocation_entries(Dwarf_Bool is_64bit
,
444 Dwarf_Small
*relocation_section
,
445 Dwarf_Unsigned relocation_section_size
,
446 struct Dwarf_Elf_Rela
**relas
,
447 unsigned int *nrelas
,
450 unsigned int relocation_size
= 0;
453 #ifdef HAVE_ELF64_RELA
454 relocation_size
= sizeof(Elf64_Rela
);
456 *error
= DW_DLE_MISSING_ELF64_SUPPORT
;
460 relocation_size
= sizeof(Elf32_Rela
);
463 if (relocation_section
== NULL
) {
464 *error
= DW_DLE_RELOC_SECTION_PTR_NULL
;
465 return(DW_DLV_ERROR
);
468 if ((relocation_section_size
!= 0)) {
469 size_t bytescount
= 0;
470 if(relocation_section_size
%relocation_size
) {
471 *error
= DW_DLE_RELOC_SECTION_LENGTH_ODD
;
474 *nrelas
= relocation_section_size
/relocation_size
;
475 bytescount
= (*nrelas
) * sizeof(struct Dwarf_Elf_Rela
);
476 *relas
= malloc(bytescount
);
479 return(DW_DLV_ERROR
);
481 memset(*relas
,0,bytescount
);
482 get_relocations_array(is_64bit
,endianness
,machine
, relocation_section
,
489 is_32bit_abs_reloc(unsigned int type
, Dwarf_Half machine
)
493 #if defined(EM_MIPS) && defined (R_MIPS_32)
495 r
= (type
== R_MIPS_32
);
498 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32)
500 r
= (type
== R_SPARC_UA32
);
503 #if defined(EM_SPARCV9) && defined (R_SPARC_UA32)
505 r
= (type
== R_SPARC_UA32
);
508 #if defined(EM_SPARC) && defined (R_SPARC_UA32)
510 r
= (type
== R_SPARC_UA32
);
513 #if defined(EM_386) && defined (R_386_32)
515 r
= (type
== R_386_32
);
518 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
520 r
= (type
== R_IA64_SECREL32LSB
);
523 #if defined(EM_PPC64) && defined (R_PPC64_ADDR32)
525 r
= (type
== R_PPC64_ADDR32
);
528 #if defined(EM_PPC) && defined (R_PPC_ADDR32)
530 r
= (type
== R_PPC_ADDR32
);
533 #if defined(EM_S390) && defined (R_390_32)
535 r
= (type
== R_390_32
);
538 #if defined(EM_X86_64) && defined (R_X86_64_32)
540 r
= (type
== R_X86_64_32
);
548 is_64bit_abs_reloc(unsigned int type
, Dwarf_Half machine
)
552 #if defined(EM_MIPS) && defined (R_MIPS_64)
554 r
= (type
== R_MIPS_64
);
557 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
559 r
= (type
== R_SPARC_UA64
);
562 #if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
564 r
= (type
== R_SPARC_UA64
);
567 #if defined(EM_SPARC) && defined (R_SPARC_UA64)
569 r
= (type
== R_SPARC_UA64
);
572 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
574 r
= (type
== R_IA64_DIR64LSB
);
577 #if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
579 r
= (type
== R_PPC64_ADDR64
);
582 #if defined(EM_S390) && defined (R_390_64)
584 r
= (type
== R_390_64
);
587 #if defined(EM_X86_64) && defined (R_X86_64_64)
589 r
= (type
== R_X86_64_64
);
598 update_entry(Dwarf_Debug dbg
,
599 Dwarf_Bool is_64bit
, Dwarf_Endianness endianess
,
600 Dwarf_Half machine
, struct Dwarf_Elf_Rela
*rela
,
601 Dwarf_Small
*target_section
, Dwarf_Small
*section_data
)
603 unsigned int type
= 0;
604 unsigned int sym_idx
= 0;
605 #ifdef HAVE_ELF64_SYM
612 Elf32_Sym
*sym32
= 0;
613 Dwarf_ufixed64 offset
= 0;
614 Dwarf_sfixed64 addend
= 0;
615 Dwarf_Unsigned reloc_size
= 0;
618 /* Dwarf_Elf_Rela dereferencing */
619 offset
= rela
->r_offset
;
620 addend
= rela
->r_addend
;
622 sym_idx
= rela
->r_symidx
;
625 #ifdef HAVE_ELF64_SYM
626 sym
= &((Elf64_Sym
*)section_data
)[sym_idx
];
629 sym32
= &((Elf32_Sym
*)section_data
)[sym_idx
];
631 /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at
632 * an Elf64_Sym local variable (sym_buf) to allow us to use the
633 * same pointer (sym) for both 32-bit and 64-bit instances.
636 sym
->st_name
= sym32
->st_name
;
637 sym
->st_info
= sym32
->st_info
;
638 sym
->st_other
= sym32
->st_other
;
639 sym
->st_shndx
= sym32
->st_shndx
;
640 sym
->st_value
= sym32
->st_value
;
641 sym
->st_size
= sym32
->st_size
;
644 /* Determine relocation size */
645 if (is_32bit_abs_reloc(type
, machine
)) {
647 } else if (is_64bit_abs_reloc(type
, machine
)) {
655 /* Assuming we do not need to do a READ_UNALIGNED here
656 at target_section + offset and add its value to
657 outval. Some ABIs say no read (for example MIPS),
658 but if some do then which ones? */
659 Dwarf_Unsigned outval
= sym
->st_value
+ addend
;
660 WRITE_UNALIGNED(dbg
,target_section
+ offset
,
661 &outval
,sizeof(outval
),reloc_size
);
668 apply_rela_entries(Dwarf_Debug dbg
,
670 Dwarf_Endianness endianess
,
672 Dwarf_Small
*target_section
,
673 Dwarf_Small
*symtab_section
,
674 struct Dwarf_Elf_Rela
*relas
, unsigned int nrelas
,
677 if ((target_section
!= NULL
) && (relas
!= NULL
)) {
679 for (i
= 0; i
< nrelas
; i
++) {
680 update_entry(dbg
, is_64bit
,
693 loop_through_relocations(
695 dwarf_elf_object_access_internals_t
* obj
,
696 struct Dwarf_Section_s
*relocatablesec
,
699 Dwarf_Small
*target_section
= 0;
700 Dwarf_Small
*symtab_section
= obj
->symtab
->dss_data
;
701 Dwarf_Small
*relocation_section
= relocatablesec
->dss_reloc_data
;
702 Dwarf_Unsigned relocation_section_size
=
703 relocatablesec
->dss_reloc_size
;
704 int ret
= DW_DLV_ERROR
;
705 struct Dwarf_Elf_Rela
*relas
= 0;
706 unsigned int nrelas
= 0;
707 Dwarf_Small
*mspace
= 0;
709 ret
= get_relocation_entries(obj
->is_64bit
,
713 relocation_section_size
,
714 &relas
, &nrelas
, error
);
715 if(ret
!= DW_DLV_OK
) {
720 /* Some systems read Elf in read-only memory via mmap or the like.
721 So the only safe thing is to copy the current data into
722 malloc space and refer to the malloc space instead of the
723 space returned by the elf library */
724 mspace
= malloc(relocatablesec
->dss_size
);
726 *error
= DW_DLE_RELOC_SECTION_MALLOC_FAIL
;
729 memcpy(mspace
,relocatablesec
->dss_data
,relocatablesec
->dss_size
);
730 relocatablesec
->dss_data
= mspace
;
731 target_section
= relocatablesec
->dss_data
;
732 relocatablesec
->dss_data_was_malloc
= 1;
734 ret
= apply_rela_entries(
737 obj
->endianness
, obj
->machine
,
740 relas
, nrelas
, error
);
748 Find the section data in dbg and find all the relevant
749 sections. Then do relocations.
752 dwarf_elf_object_relocate_a_section(void* obj_in
,
753 Dwarf_Half section_index
,
757 int res
= DW_DLV_ERROR
;
758 dwarf_elf_object_access_internals_t
*obj
= 0;
759 struct Dwarf_Section_s
* relocatablesec
= 0;
760 if (section_index
== 0) {
761 return DW_DLV_NO_ENTRY
;
763 obj
= (dwarf_elf_object_access_internals_t
*)obj_in
;
765 /* The section to relocate must already be loaded into memory. */
766 res
= find_section_to_relocate(dbg
, section_index
,&relocatablesec
,error
);
767 if(res
!= DW_DLV_OK
) {
771 /* Sun and possibly others do not always set sh_link in .debug_* sections.
772 So we cannot do full consistency checks. */
773 if(relocatablesec
->dss_reloc_index
== 0 ) {
774 /* Something is wrong. */
775 *error
= DW_DLE_RELOC_SECTION_MISSING_INDEX
;
778 /* Now load the relocations themselves. */
779 res
= dwarf_elf_object_access_load_section(obj_in
,
780 relocatablesec
->dss_reloc_index
,
781 &relocatablesec
->dss_reloc_data
, error
);
782 if(res
!= DW_DLV_OK
) {
786 /* Now get the symtab. */
788 obj
->symtab
= &dbg
->de_elf_symtab
;
789 obj
->strtab
= &dbg
->de_elf_strtab
;
791 if( obj
->symtab
->dss_index
!= relocatablesec
->dss_reloc_link
) {
792 /* Something is wrong. */
793 *error
= DW_DLE_RELOC_MISMATCH_RELOC_INDEX
;
796 if( obj
->strtab
->dss_index
!= obj
->symtab
->dss_link
) {
797 /* Something is wrong. */
798 *error
= DW_DLE_RELOC_MISMATCH_STRTAB_INDEX
;
801 if(!obj
->symtab
->dss_data
) {
802 /* Now load the symtab */
803 res
= dwarf_elf_object_access_load_section(obj_in
,
804 obj
->symtab
->dss_index
,
805 &obj
->symtab
->dss_data
, error
);
806 if(res
!= DW_DLV_OK
) {
810 if(! obj
->strtab
->dss_data
) {
811 /* Now load the strtab */
812 res
= dwarf_elf_object_access_load_section(obj_in
,
813 obj
->strtab
->dss_index
,
814 &obj
->strtab
->dss_data
,error
);
815 if(res
!= DW_DLV_OK
){
820 /* We have all the data we need in memory. */
821 res
= loop_through_relocations(dbg
,obj
,relocatablesec
,error
);
827 dwarf_elf_object_access_load_section
830 dwarf_elf_object_access_load_section(void* obj_in
,
831 Dwarf_Half section_index
,
832 Dwarf_Small
** section_data
,
835 dwarf_elf_object_access_internals_t
*obj
=
836 (dwarf_elf_object_access_internals_t
*)obj_in
;
837 if (section_index
== 0) {
838 return DW_DLV_NO_ENTRY
;
845 scn
= elf_getscn(obj
->elf
, section_index
);
852 When using libelf as a producer, section data may be stored
853 in multiple buffers. In libdwarf however, we only use libelf
854 as a consumer (there is a dwarf producer API, but it doesn't
855 use libelf). Because of this, this single call to elf_getdata
856 will retrieve the entire section in a single contiguous
858 data
= elf_getdata(scn
, NULL
);
863 *section_data
= data
->d_buf
;
869 /* dwarf_elf_access method table. */
870 static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods
=
872 dwarf_elf_object_access_get_section_info
,
873 dwarf_elf_object_access_get_byte_order
,
874 dwarf_elf_object_access_get_length_size
,
875 dwarf_elf_object_access_get_pointer_size
,
876 dwarf_elf_object_access_get_section_count
,
877 dwarf_elf_object_access_load_section
,
878 dwarf_elf_object_relocate_a_section
883 Interface for the ELF object file implementation.
886 dwarf_elf_object_access_init(dwarf_elf_handle elf
,
887 int libdwarf_owns_elf
,
888 Dwarf_Obj_Access_Interface
** ret_obj
,
892 dwarf_elf_object_access_internals_t
*internals
= 0;
893 Dwarf_Obj_Access_Interface
*intfc
= 0;
895 internals
= malloc(sizeof(dwarf_elf_object_access_internals_t
));
897 /* Impossible case, we hope. Give up. */
900 memset(internals
,0,sizeof(*internals
));
901 res
= dwarf_elf_object_access_internals_init(internals
, elf
, err
);
902 if(res
!= DW_DLV_OK
){
906 internals
->libdwarf_owns_elf
= libdwarf_owns_elf
;
908 intfc
= malloc(sizeof(Dwarf_Obj_Access_Interface
));
910 /* Impossible case, we hope. Give up. */
914 /* Initialize the interface struct */
915 intfc
->object
= internals
;
916 intfc
->methods
= &dwarf_elf_object_access_methods
;
925 Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init.
928 dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface
* obj
)
934 dwarf_elf_object_access_internals_t
*internals
=
935 (dwarf_elf_object_access_internals_t
*)obj
->object
;
936 if(internals
->libdwarf_owns_elf
){
937 elf_end(internals
->elf
);
945 This function returns the Elf * pointer
946 associated with a Dwarf_Debug.
948 This function only makes sense if ELF is implied.
951 dwarf_get_elf(Dwarf_Debug dbg
, dwarf_elf_handle
* elf
,
954 struct Dwarf_Obj_Access_Interface_s
* obj
= 0;
956 _dwarf_error(NULL
, error
, DW_DLE_DBG_NULL
);
957 return (DW_DLV_ERROR
);
960 obj
= dbg
->de_obj_file
;
962 dwarf_elf_object_access_internals_t
*internals
=
963 (dwarf_elf_object_access_internals_t
*)obj
->object
;
964 if(internals
->elf
== NULL
) {
965 _dwarf_error(dbg
, error
, DW_DLE_FNO
);
966 return (DW_DLV_ERROR
);
968 *elf
= internals
->elf
;
972 _dwarf_error(dbg
, error
, DW_DLE_FNO
);