diff options
author | emaste <emaste@FreeBSD.org> | 2014-12-29 19:16:40 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2014-12-29 19:16:40 +0000 |
commit | ac70b524c609ef66e4327559c42d771b26250ec6 (patch) | |
tree | 39384bc31a2520bce88895fd31d2a33ecb940fb4 /contrib/elftoolchain/libdwarf | |
parent | 26a3ad9386bf869d784d11528eaaf1ef7924fe73 (diff) | |
parent | 46be049bf4ca89859159bdcdffee1da04d3ae080 (diff) | |
download | FreeBSD-src-ac70b524c609ef66e4327559c42d771b26250ec6.zip FreeBSD-src-ac70b524c609ef66e4327559c42d771b26250ec6.tar.gz |
Update elftoolchain to upstream rev 3130
This includes a number of libdwarf improvements (particularly DWARF4
related) and updates to elftoolchain tools such as strip(1). It also
includes a large number of miscellaneous fixes (memory leaks, sign and
cast warnings, integer overflow and underflow, etc.).
This is a merge of r276167,276170-276172 from the
projects/elftoolchain-update-r3130 branch.
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/elftoolchain/libdwarf')
39 files changed, 1829 insertions, 502 deletions
diff --git a/contrib/elftoolchain/libdwarf/Makefile b/contrib/elftoolchain/libdwarf/Makefile index 81b5657..d0a5443 100644 --- a/contrib/elftoolchain/libdwarf/Makefile +++ b/contrib/elftoolchain/libdwarf/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2937 2013-04-27 04:48:23Z jkoshy $ +# $Id: Makefile 3097 2014-09-02 22:10:18Z kaiwang27 $ TOP= ${.CURDIR}/.. @@ -42,6 +42,7 @@ SRCS= \ dwarf_pubtypes.c \ dwarf_ranges.c \ dwarf_reloc.c \ + dwarf_sections.c \ dwarf_seterror.c \ dwarf_str.c \ dwarf_types.c \ @@ -115,6 +116,7 @@ MAN= dwarf.3 \ dwarf_add_weakname.3 \ dwarf_attr.3 \ dwarf_attrlist.3 \ + dwarf_attroffset.3 \ dwarf_attrval_signed.3 \ dwarf_child.3 \ dwarf_dealloc.3 \ @@ -154,6 +156,7 @@ MAN= dwarf.3 \ dwarf_get_cie_info.3 \ dwarf_get_cie_of_fde.3 \ dwarf_get_cu_die_offset.3 \ + dwarf_get_die_infotypes_flag.3 \ dwarf_get_elf.3 \ dwarf_get_fde_at_pc.3 \ dwarf_get_fde_info_for_all_regs.3 \ @@ -175,6 +178,7 @@ MAN= dwarf.3 \ dwarf_get_relocation_info.3 \ dwarf_get_relocation_info_count.3 \ dwarf_get_section_bytes.3 \ + dwarf_get_section_max_offsets.3 \ dwarf_get_str.3 \ dwarf_get_types.3 \ dwarf_get_vars.3 \ @@ -192,6 +196,7 @@ MAN= dwarf.3 \ dwarf_new_expr.3 \ dwarf_new_fde.3 \ dwarf_next_cu_header.3 \ + dwarf_next_types_section.3 \ dwarf_object_init.3 \ dwarf_producer_init.3 \ dwarf_producer_set_isa.3 \ @@ -220,7 +225,9 @@ MLINKS+= \ dwarf_attrval_signed.3 dwarf_attrval_string.3 \ dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \ dwarf_child.3 dwarf_offdie.3 \ + dwarf_child.3 dwarf_offdie_b.3 \ dwarf_child.3 dwarf_siblingof.3 \ + dwarf_child.3 dwarf_siblingof_b.3 \ dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \ dwarf_dealloc.3 dwarf_funcs_dealloc.3 \ dwarf_dealloc.3 dwarf_globals_dealloc.3 \ @@ -234,6 +241,7 @@ MLINKS+= \ dwarf_dieoffset.3 dwarf_die_CU_offset.3 \ dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \ dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \ + dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset_b.3 \ dwarf_finish.3 dwarf_object_finish.3 \ dwarf_formref.3 dwarf_global_formref.3 \ dwarf_formudata.3 dwarf_formsdata.3 \ @@ -273,6 +281,7 @@ MLINKS+= \ dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \ dwarf_get_pubtypes.3 dwarf_pubtypename.3 \ dwarf_get_ranges.3 dwarf_get_ranges_a.3 \ + dwarf_get_section_max_offsets.3 dwarf_get_section_max_offsets_b.3 \ dwarf_get_types.3 dwarf_type_die_offset.3 \ dwarf_get_types.3 dwarf_type_cu_offset.3 \ dwarf_get_types.3 dwarf_type_name_offsets.3 \ @@ -291,6 +300,7 @@ MLINKS+= \ dwarf_highpc.3 dwarf_bitoffset.3 \ dwarf_highpc.3 dwarf_bitsize.3 \ dwarf_highpc.3 dwarf_bytesize.3 \ + dwarf_highpc.3 dwarf_highpc_b.3 \ dwarf_highpc.3 dwarf_lowpc.3 \ dwarf_highpc.3 dwarf_srclang.3 \ dwarf_lineno.3 dwarf_lineaddr.3 \ @@ -302,6 +312,9 @@ MLINKS+= \ dwarf_lineno.3 dwarf_line_srcfileno.3 \ dwarf_loclist.3 dwarf_loclist_n.3 \ dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \ + dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_c.3 \ dwarf_producer_init.3 dwarf_producer_init_b.3 \ dwarf_seterrarg.3 dwarf_seterrhand.3 \ dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \ diff --git a/contrib/elftoolchain/libdwarf/Version.map b/contrib/elftoolchain/libdwarf/Version.map index 6e6548b..669f70e 100644 --- a/contrib/elftoolchain/libdwarf/Version.map +++ b/contrib/elftoolchain/libdwarf/Version.map @@ -1,4 +1,4 @@ -/* $Id: Version.map 2576 2012-09-13 09:16:11Z jkoshy $ */ +/* $Id: Version.map 3085 2014-09-02 22:08:23Z kaiwang27 $ */ R1.0 { global: @@ -39,6 +39,7 @@ global: dwarf_arrayorder; dwarf_attr; dwarf_attrlist; + dwarf_attroffset; dwarf_attrval_flag; dwarf_attrval_signed; dwarf_attrval_string; @@ -116,6 +117,8 @@ global: dwarf_get_cie_of_fde; dwarf_get_cu_die_offset; dwarf_get_cu_die_offset_given_cu_header_offset; + dwarf_get_cu_die_offset_given_cu_header_offset_b; + dwarf_get_die_infotypes_flag; dwarf_get_elf; dwarf_get_fde_at_pc; dwarf_get_fde_info_for_all_regs3; @@ -139,6 +142,8 @@ global: dwarf_get_relocation_info; dwarf_get_relocation_info_count; dwarf_get_section_bytes; + dwarf_get_section_max_offsets; + dwarf_get_section_max_offsets_b; dwarf_get_str; dwarf_get_types; dwarf_get_vars; @@ -152,6 +157,7 @@ global: dwarf_hasattr; dwarf_hasform; dwarf_highpc; + dwarf_highpc_b; dwarf_init; dwarf_line_srcfileno; dwarf_lineaddr; @@ -166,6 +172,7 @@ global: dwarf_loclist; dwarf_loclist_from_expr; dwarf_loclist_from_expr_a; + dwarf_loclist_from_expr_b; dwarf_loclist_n; dwarf_lowpc; dwarf_new_die; @@ -173,9 +180,12 @@ global: dwarf_new_fde; dwarf_next_cu_header; dwarf_next_cu_header_b; + dwarf_next_cu_header_c; + dwarf_next_types_section; dwarf_object_finish; dwarf_object_init; dwarf_offdie; + dwarf_offdie_b; dwarf_producer_finish; dwarf_producer_init; dwarf_producer_init_b; @@ -196,6 +206,7 @@ global: dwarf_seterrarg; dwarf_seterrhand; dwarf_siblingof; + dwarf_siblingof_b; dwarf_srcfiles; dwarf_srclang; dwarf_srclines; diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h index 23f60e8..d2e74c1 100644 --- a/contrib/elftoolchain/libdwarf/_libdwarf.h +++ b/contrib/elftoolchain/libdwarf/_libdwarf.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _libdwarf.h 2075 2011-10-27 03:47:28Z jkoshy $ + * $Id: _libdwarf.h 3106 2014-12-19 16:00:58Z kaiwang27 $ */ #ifndef __LIBDWARF_H_ @@ -89,6 +89,7 @@ extern struct _libdwarf_globals _libdwarf; goto gen_fail; \ } while(0) +typedef struct _Dwarf_CU *Dwarf_CU; struct _Dwarf_AttrDef { uint64_t ad_attrib; /* DW_AT_XXX */ @@ -147,14 +148,6 @@ struct _Dwarf_Die { STAILQ_ENTRY(_Dwarf_Die) die_pro_next; /* Next die in pro-die list. */ }; -struct _Dwarf_Loclist { - Dwarf_Locdesc **ll_ldlist; /* Array of Locdesc pointer. */ - int ll_ldlen; /* Number of Locdesc. */ - Dwarf_Unsigned ll_offset; /* Offset in .debug_loc section. */ - Dwarf_Unsigned ll_length; /* Length (in bytes) of the loclist. */ - TAILQ_ENTRY(_Dwarf_Loclist) ll_next; /* Next loclist in list. */ -}; - struct _Dwarf_P_Expr_Entry { Dwarf_Loc ee_loc; /* Location expression. */ Dwarf_Unsigned ee_sym; /* Optional related reloc sym index. */ @@ -265,6 +258,8 @@ struct _Dwarf_Cie { Dwarf_Half cie_version; /* CIE version. */ uint8_t *cie_augment; /* CIE augmentation (UTF-8). */ Dwarf_Unsigned cie_ehdata; /* Optional EH Data. */ + uint8_t cie_addrsize; /* Address size. (DWARF4) */ + uint8_t cie_segmentsize; /* Segment size. (DWARF4) */ Dwarf_Unsigned cie_caf; /* Code alignment factor. */ Dwarf_Signed cie_daf; /* Data alignment factor. */ Dwarf_Unsigned cie_ra; /* Return address register. */ @@ -333,11 +328,14 @@ struct _Dwarf_CU { uint64_t cu_lineno_offset; /* Offset into .debug_lineno. */ uint8_t cu_pointer_size;/* Number of bytes in pointer. */ uint8_t cu_dwarf_size; /* CU section dwarf size. */ + Dwarf_Sig8 cu_type_sig; /* Type unit's signature. */ + uint64_t cu_type_offset; /* Type unit's type offset. */ Dwarf_Off cu_next_offset; /* Offset to the next CU. */ uint64_t cu_1st_offset; /* First DIE offset. */ int cu_pass2; /* Two pass DIE traverse. */ Dwarf_LineInfo cu_lineinfo; /* Ptr to Dwarf_LineInfo. */ Dwarf_Abbrev cu_abbrev_hash; /* Abbrev hash table. */ + Dwarf_Bool cu_is_info; /* Compilation/type unit flag. */ STAILQ_ENTRY(_Dwarf_CU) cu_next; /* Next compilation unit. */ }; @@ -399,17 +397,21 @@ struct _Dwarf_Debug { Dwarf_Section *dbg_section; /* Dwarf section list. */ Dwarf_Section *dbg_info_sec; /* Pointer to info section. */ Dwarf_Off dbg_info_off; /* Current info section offset. */ + Dwarf_Section *dbg_types_sec; /* Pointer to type section. */ + Dwarf_Off dbg_types_off; /* Current types section offset. */ Dwarf_Unsigned dbg_seccnt; /* Total number of dwarf sections. */ int dbg_mode; /* Access mode. */ int dbg_pointer_size; /* Object address size. */ int dbg_offset_size; /* DWARF offset size. */ int dbg_info_loaded; /* Flag indicating all CU loaded. */ + int dbg_types_loaded; /* Flag indicating all TU loaded. */ Dwarf_Half dbg_machine; /* ELF machine architecture. */ Dwarf_Handler dbg_errhand; /* Error handler. */ Dwarf_Ptr dbg_errarg; /* Argument to the error handler. */ STAILQ_HEAD(, _Dwarf_CU) dbg_cu;/* List of compilation units. */ + STAILQ_HEAD(, _Dwarf_CU) dbg_tu;/* List of type units. */ Dwarf_CU dbg_cu_current; /* Ptr to the current CU. */ - TAILQ_HEAD(, _Dwarf_Loclist) dbg_loclist; /* List of location list. */ + Dwarf_CU dbg_tu_current; /* Ptr to the current TU. */ Dwarf_NameSec dbg_globals; /* Ptr to pubnames lookup section. */ Dwarf_NameSec dbg_pubtypes; /* Ptr to pubtypes lookup section. */ Dwarf_NameSec dbg_weaks; /* Ptr to weaknames lookup section. */ @@ -532,13 +534,15 @@ int _dwarf_elf_get_section_info(void *, Dwarf_Half, Dwarf_Obj_Access_Section *, int *); void _dwarf_expr_cleanup(Dwarf_P_Debug); int _dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Error *); +Dwarf_Section *_dwarf_find_next_types_section(Dwarf_Debug, Dwarf_Section *); Dwarf_Section *_dwarf_find_section(Dwarf_Debug, const char *); void _dwarf_frame_cleanup(Dwarf_Debug); int _dwarf_frame_fde_add_inst(Dwarf_P_Fde, Dwarf_Small, Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); int _dwarf_frame_gen(Dwarf_P_Debug, Dwarf_Error *); -int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t *, Dwarf_Unsigned, - Dwarf_Frame_Op **, Dwarf_Signed *, Dwarf_Error *); +int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t, uint8_t *, + Dwarf_Unsigned, Dwarf_Frame_Op **, Dwarf_Signed *, + Dwarf_Error *); int _dwarf_frame_get_internal_table(Dwarf_Fde, Dwarf_Addr, Dwarf_Regtable3 **, Dwarf_Addr *, Dwarf_Error *); int _dwarf_frame_interal_table_init(Dwarf_Debug, Dwarf_Error *); @@ -553,9 +557,12 @@ Dwarf_Unsigned _dwarf_get_reloc_type(Dwarf_P_Debug, int); int _dwarf_get_reloc_size(Dwarf_Debug, Dwarf_Unsigned); void _dwarf_info_cleanup(Dwarf_Debug); int _dwarf_info_first_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_first_tu(Dwarf_Debug, Dwarf_Error *); int _dwarf_info_gen(Dwarf_P_Debug, Dwarf_Error *); -int _dwarf_info_load(Dwarf_Debug, int, Dwarf_Error *); +int _dwarf_info_load(Dwarf_Debug, Dwarf_Bool, Dwarf_Bool, + Dwarf_Error *); int _dwarf_info_next_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_next_tu(Dwarf_Debug, Dwarf_Error *); void _dwarf_info_pro_cleanup(Dwarf_P_Debug); int _dwarf_init(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); @@ -563,20 +570,19 @@ int _dwarf_lineno_gen(Dwarf_P_Debug, Dwarf_Error *); int _dwarf_lineno_init(Dwarf_Die, uint64_t, Dwarf_Error *); void _dwarf_lineno_cleanup(Dwarf_LineInfo); void _dwarf_lineno_pro_cleanup(Dwarf_P_Debug); -int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *, uint8_t *, - uint64_t, uint8_t, Dwarf_Error *); +int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *, + uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t, + Dwarf_Error *); int _dwarf_loc_fill_locexpr(Dwarf_Debug, Dwarf_Locdesc **, - uint8_t *, uint64_t, uint8_t, Dwarf_Error *); + uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t, + Dwarf_Error *); int _dwarf_loc_add(Dwarf_Die, Dwarf_Attribute, Dwarf_Error *); int _dwarf_loc_expr_add_atom(Dwarf_Debug, uint8_t *, uint8_t *, Dwarf_Small, Dwarf_Unsigned, Dwarf_Unsigned, int *, Dwarf_Error *); int _dwarf_loclist_find(Dwarf_Debug, Dwarf_CU, uint64_t, - Dwarf_Loclist *, Dwarf_Error *); -void _dwarf_loclist_cleanup(Dwarf_Debug); -void _dwarf_loclist_free(Dwarf_Loclist); -int _dwarf_loclist_add(Dwarf_Debug, Dwarf_CU, uint64_t, - Dwarf_Loclist *, Dwarf_Error *); + Dwarf_Locdesc ***, Dwarf_Signed *, Dwarf_Unsigned *, + Dwarf_Error *); void _dwarf_macinfo_cleanup(Dwarf_Debug); int _dwarf_macinfo_gen(Dwarf_P_Debug, Dwarf_Error *); int _dwarf_macinfo_init(Dwarf_Debug, Dwarf_Error *); @@ -633,6 +639,7 @@ void _dwarf_strtab_cleanup(Dwarf_Debug); int _dwarf_strtab_gen(Dwarf_P_Debug, Dwarf_Error *); char *_dwarf_strtab_get_table(Dwarf_Debug); int _dwarf_strtab_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_type_unit_cleanup(Dwarf_Debug); void _dwarf_write_block(void *, uint64_t *, uint8_t *, uint64_t); int _dwarf_write_block_alloc(uint8_t **, uint64_t *, uint64_t *, uint8_t *, uint64_t, Dwarf_Error *); diff --git a/contrib/elftoolchain/libdwarf/dwarf.3 b/contrib/elftoolchain/libdwarf/dwarf.3 index b32299c..5363034 100644 --- a/contrib/elftoolchain/libdwarf/dwarf.3 +++ b/contrib/elftoolchain/libdwarf/dwarf.3 @@ -21,9 +21,9 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: dwarf.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf.3 3130 2014-12-21 20:06:29Z jkoshy $ .\" -.Dd September 17, 2011 +.Dd December 21, 2014 .Os .Dt DWARF 3 .Sh NAME @@ -217,6 +217,8 @@ attribute. Retrieve an attribute descriptor. .It Fn dwarf_attrlist Retrieve attribute descriptors for a debugging information entry. +.It Fn dwarf_attroffset +Retrieve the section-relative offset of an attribute descriptor. .It Fn dwarf_attrval_flag Retrieve a .Dv DW_AT_FORM_flag @@ -309,10 +311,17 @@ Retrieve range information from an FDE descriptor. .El .It Compilation Units .Bl -tag -compact -.It Fn dwarf_get_cu_die_offset_given_cu_header_offset +.It Xo +.Fn dwarf_get_cu_die_offset_given_cu_header_offset , +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +.Xc Retrieve the offset of the debugging information entry for a -compilation unit. -.It Fn dwarf_next_cu_header , Fn dwarf_next_cu_header_b +compilation or type unit. +.It Xo +.Fn dwarf_next_cu_header , +.Fn dwarf_next_cu_header_b , +.Fn dwarf_next_cu_header_c +.Xc Step through compilation units in a debug context. .El .It Debugging Information Entries @@ -329,13 +338,15 @@ Returns the attribute for a debugging information entry. .It Fn dwarf_dieoffset Retrieves the offset for a debugging information entry. -.It Fn dwarf_highpc +.It Fn dwarf_get_die_infotypes_flag +Indicate the originating section for a debugging information entry. +.It Fn dwarf_highpc , Fn dwarf_highpc_b Return the highest PC value for a debugging information entry. .It Fn dwarf_lowpc Return the lowest PC value for a debugging information entry. -.It Fn dwarf_offdie +.It Fn dwarf_offdie , Fn dwarf_offdie_b Retrieve a debugging information entry given an offset. -.It Fn dwarf_siblingof +.It Fn dwarf_siblingof , Fn dwarf_siblingof_b Retrieve the sibling descriptor for a debugging information entry. .It Fn dwarf_srclang Retrive the source language attribute for a debugging information @@ -416,7 +427,11 @@ Return line number information for a compilation unit. Retrieve a location list entry. .It Fn dwarf_loclist , Fn dwarf_loclist_n Retrieve location expressions. -.It Fn dwarf_loclist_from_expr , Fn dwarf_loclist_from_expr_a +.It Xo +.Fn dwarf_loclist_from_expr , +.Fn dwarf_loclist_from_expr_a , +.Fn dwarf_loclist_from_expr_b +.Xc Translate a location expression into a location descriptor. .El .It Error Handling @@ -513,6 +528,10 @@ and .Bl -tag -compact .It Fn dwarf_get_pubtypes , Fn dwarf_get_types Retrieve descriptors for user-defined types. +.It Fn dwarf_next_types_section +Step through +.Dq \&.debug_types +sections in a debug context. .It Fn dwarf_pubtype_cu_offset , Fn dwarf_type_cu_offset Return the offset for the compilation unit for a type. .It Fn dwarf_pubtype_die_offset , Fn dwarf_type_die_offset @@ -699,9 +718,16 @@ addition to the per-debug context handlers supported by the SGI/GNU API, see the subsection .Sx Error Handling above. +.El +.Ss Extensions +The following APIs are extensions specific to this implementation: +.Bl -bullet -compact +.It +.Fn dwarf_attroffset .It -The following API is an extension: -.Fn dwarf_producer_set_isa . +.Fn dwarf_next_types_section +.It +.Fn dwarf_producer_set_isa .El .Sh SEE ALSO .Xr elf 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf.h b/contrib/elftoolchain/libdwarf/dwarf.h index b1a3e4e..c79da96 100644 --- a/contrib/elftoolchain/libdwarf/dwarf.h +++ b/contrib/elftoolchain/libdwarf/dwarf.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dwarf.h 2075 2011-10-27 03:47:28Z jkoshy $ + * $Id: dwarf.h 3052 2014-05-26 20:36:24Z kaiwang27 $ */ #ifndef _DWARF_H_ @@ -93,6 +93,19 @@ #define DW_TAG_lo_user 0x4080 #define DW_TAG_hi_user 0xffff +/* GNU extensions. */ +#define DW_TAG_format_label 0x4101 +#define DW_TAG_function_template 0x4102 +#define DW_TAG_class_template 0x4103 +#define DW_TAG_GNU_BINCL 0x4104 +#define DW_TAG_GNU_EINCL 0x4105 +#define DW_TAG_GNU_template_template_parameter 0x4106 +#define DW_TAG_GNU_template_template_param 0x4106 +#define DW_TAG_GNU_template_parameter_pack 0x4107 +#define DW_TAG_GNU_formal_parameter_pack 0x4108 +#define DW_TAG_GNU_call_site 0x4109 +#define DW_TAG_GNU_call_site_parameter 0x410a + #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 @@ -195,6 +208,32 @@ #define DW_AT_lo_user 0x2000 #define DW_AT_hi_user 0x3fff +/* GNU extensions. */ +#define DW_AT_sf_names 0x2101 +#define DW_AT_src_info 0x2102 +#define DW_AT_mac_info 0x2103 +#define DW_AT_src_coords 0x2104 +#define DW_AT_body_begin 0x2105 +#define DW_AT_body_end 0x2106 +#define DW_AT_GNU_vector 0x2107 +#define DW_AT_GNU_guarded_by 0x2108 +#define DW_AT_GNU_pt_guarded_by 0x2109 +#define DW_AT_GNU_guarded 0x210a +#define DW_AT_GNU_pt_guarded 0x210b +#define DW_AT_GNU_locks_excluded 0x210c +#define DW_AT_GNU_exclusive_locks_required 0x210d +#define DW_AT_GNU_shared_locks_required 0x210e +#define DW_AT_GNU_odr_signature 0x210f +#define DW_AT_GNU_template_name 0x2110 +#define DW_AT_GNU_call_site_value 0x2111 +#define DW_AT_GNU_call_site_data_value 0x2112 +#define DW_AT_GNU_call_site_target 0x2113 +#define DW_AT_GNU_call_site_target_clobbered 0x2114 +#define DW_AT_GNU_tail_call 0x2115 +#define DW_AT_GNU_all_tail_call_sites 0x2116 +#define DW_AT_GNU_all_call_sites 0x2117 +#define DW_AT_GNU_all_source_call_sites 0x2118 + #define DW_FORM_addr 0x01 #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 @@ -220,6 +259,8 @@ #define DW_FORM_exprloc 0x18 #define DW_FORM_flag_present 0x19 #define DW_FORM_ref_sig8 0x20 +#define DW_FORM_GNU_ref_alt 0x1f20 +#define DW_FORM_GNU_strp_alt 0x1f21 #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 @@ -376,9 +417,23 @@ #define DW_OP_implicit_value 0x9e #define DW_OP_stack_value 0x9f #define DW_OP_lo_user 0xe0 -#define DW_OP_GNU_push_tls_address 0xe0 #define DW_OP_hi_user 0xff +/* GNU extensions. */ +#define DW_OP_GNU_push_tls_address 0xe0 +#define DW_OP_GNU_uninit 0xf0 +#define DW_OP_GNU_encoded_addr 0xf1 +#define DW_OP_GNU_implicit_pointer 0xf2 +#define DW_OP_GNU_entry_value 0xf3 +#define DW_OP_GNU_const_type 0xf4 +#define DW_OP_GNU_regval_type 0xf5 +#define DW_OP_GNU_deref_type 0xf6 +#define DW_OP_GNU_convert 0xf7 +#define DW_OP_GNU_reinterpret 0xf9 +#define DW_OP_GNU_parameter_ref 0xfa +#define DW_OP_GNU_addr_index 0xfb +#define DW_OP_GNU_const_index 0xfc + #define DW_ATE_address 0x1 #define DW_ATE_boolean 0x2 #define DW_ATE_complex_float 0x3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.3 b/contrib/elftoolchain/libdwarf/dwarf_attr.3 index b1e3001..9ba367b 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_attr.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_attr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_attr.3 3093 2014-09-02 22:09:40Z kaiwang27 $ .\" .Dd April 8, 2010 .Os @@ -113,6 +113,7 @@ in argument .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attrlist 3 , +.Xr dwarf_attroffset 3 , .Xr dwarf_hasattr 3 , .Xr dwarf_hasform 3 , .Xr dwarf_whatattr 3 , diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.c b/contrib/elftoolchain/libdwarf/dwarf_attr.c index ce40294..a081d7b 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_attr.c +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_attr.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, @@ -114,6 +114,23 @@ dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, } int +dwarf_attroffset(Dwarf_Attribute at, Dwarf_Off *ret_off, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || ret_off == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_off = at->at_offset; + + return (DW_DLV_OK); +} + +int dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) { Dwarf_Attribute at; @@ -139,8 +156,17 @@ dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) int dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) { + + return (dwarf_highpc_b(die, ret_highpc, NULL, NULL, error)); +} + +int +dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form, + enum Dwarf_Form_Class *ret_class, Dwarf_Error *error) +{ Dwarf_Attribute at; Dwarf_Debug dbg; + Dwarf_CU cu; dbg = die != NULL ? die->die_dbg : NULL; @@ -156,6 +182,17 @@ dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) *ret_highpc = at->u[0].u64; + if (ret_form != NULL) { + *ret_form = at->at_form; + } + + if (ret_class != NULL) { + cu = die->die_cu; + *ret_class = dwarf_get_form_class(cu->cu_version, + DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8, + at->at_form); + } + return (DW_DLV_OK); } diff --git a/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 b/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 new file mode 100644 index 0000000..af24ceb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_attroffset.3 3115 2014-12-20 18:26:46Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_ATTROFFSET 3 +.Sh NAME +.Nm dwarf_attroffset +.Nd retrieve the section-relative offset of an attribute descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attroffset +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Off *ret_off" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attroffset +retrieves the section-relative offset of the attribute descriptor +referenced by argument +.Ar at . +.Pp +Argument +.Ar ret_off +should point to a location that is to hold the returned +section-relative offset. +If argument +.Ar err +is non-NULL, it is used to return an error descriptor in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_attroffset +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_attroffset +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar at +or +.Ar ret_off +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval.c b/contrib/elftoolchain/libdwarf/dwarf_attrval.c index 31d19f7..3bddae9 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_attrval.c +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_attrval.c 2977 2014-01-21 20:13:31Z kaiwang27 $"); int dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 index 3fd01d0..93d4ae0 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_attrval_signed.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_attrval_signed.3 2980 2014-01-21 20:15:54Z kaiwang27 $ .\" .Dd January 18, 2014 .Os diff --git a/contrib/elftoolchain/libdwarf/dwarf_child.3 b/contrib/elftoolchain/libdwarf/dwarf_child.3 index 57549c0..1e32e58 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_child.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_child.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,15 +22,17 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_child.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_child.3 3127 2014-12-21 19:09:19Z jkoshy $ .\" -.Dd November 9, 2011 +.Dd December 21, 2014 .Os .Dt DWARF_CHILD 3 .Sh NAME .Nm dwarf_child , +.Nm dwarf_offdie , +.Nm dwarf_offdie_b , .Nm dwarf_siblingof , -.Nm dwarf_offdie +.Nm dwarf_siblingof_b .Nd retrieve DWARF Debugging Information Entry descriptors .Sh LIBRARY .Lb libdwarf @@ -39,6 +41,21 @@ .Ft int .Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err" .Ft int +.Fo dwarf_offdie +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_offdie_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int .Fo dwarf_siblingof .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Die die" @@ -46,10 +63,11 @@ .Fa "Dwarf_Error *err" .Fc .Ft int -.Fo dwarf_offdie +.Fo dwarf_siblingof_b .Fa "Dwarf_Debug dbg" -.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die die" .Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Bool is_info" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION @@ -92,6 +110,34 @@ may be used together to traverse the tree of debugging information entry descriptors for a compilation unit. .Pp Function +.Fn dwarf_siblingof_b +is identical to the function +.Fn dwarf_siblingof +except that it can retrieve the sibling descriptor from either the +current compilation unit or type unit. +If argument +.Ar is_info +is non-zero, the function behaves identically to function +.Fn dwarf_siblingof . +If argument +.Ar is_info +is zero, the descriptor referred by argument +.Ar die +should be associated with a debugging information entry in the +type unit. +The function will store the sibling of the descriptor in the location +pointed to by argument +.Ar ret_die . +If argument +.Ar is_info +is zero and argument +.Ar die +is +.Dv NULL , +the first debugging information entry descriptor for the +current type unit will be returned. +.Pp +Function .Fn dwarf_offdie retrieves the debugging information entry descriptor at global offset .Ar offset @@ -101,6 +147,31 @@ section of the object associated with argument .Ar dbg . The returned descriptor is written to the location pointed to by argument .Ar ret_die . +.Pp +Function +.Fn dwarf_offdie_b +is identical to the function +.Fn dwarf_offdie +except that it can retrieve the debugging information entry descriptor at +global offset +.Ar offset +from either of the +.Dq .debug_info +and +.Dq .debug_types +sections of the object associated with argument +.Ar dbg . +If argument +.Ar is_info +is non-zero, the function will retrieve the debugging information +entry from the +.Dq .debug_info +section, otherwise the function will retrieve the debugging +information entry from the +.Dq .debug_types +section. +The returned descriptor is written to the location pointed to by argument +.Ar ret_die . .Ss Memory Management The memory area used for the .Vt Dwarf_Die @@ -128,14 +199,18 @@ argument if it is not NULL. .It Bq Er DW_DLV_NO_ENTRY For functions -.Fn dwarf_child +.Fn dwarf_child , +.Fn dwarf_siblingof and -.Fn dwarf_siblingof , +.Fn dwarf_siblingof_b , the descriptor denoted by argument .Ar die did not have a child or sibling. -For function -.Fn dwarf_offdie , +.Pp +For functions +.Fn dwarf_offdie +and +.Fn dwarf_offdie_b , there was no debugging information entry at the offset specified by argument .Ar offset . @@ -199,4 +274,5 @@ do { .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , +.Xr dwarf_get_die_infotypes_flag.3 , .Xr dwarf_next_cu_header 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_cu.c b/contrib/elftoolchain/libdwarf/dwarf_cu.c index c203dc2..d103488 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_cu.c +++ b/contrib/elftoolchain/libdwarf/dwarf_cu.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,14 +27,15 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_cu.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_cu.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); int -dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, - Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, - Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size, - Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset, - Dwarf_Error *error) +dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info, + Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, + Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size, + Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size, + Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset, + Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error) { Dwarf_CU cu; int ret; @@ -43,10 +45,17 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, return (DW_DLV_ERROR); } - if (dbg->dbg_cu_current == NULL) - ret = _dwarf_info_first_cu(dbg, error); - else - ret = _dwarf_info_next_cu(dbg, error); + if (is_info) { + if (dbg->dbg_cu_current == NULL) + ret = _dwarf_info_first_cu(dbg, error); + else + ret = _dwarf_info_next_cu(dbg, error); + } else { + if (dbg->dbg_tu_current == NULL) + ret = _dwarf_info_first_tu(dbg, error); + else + ret = _dwarf_info_next_tu(dbg, error); + } if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -54,11 +63,19 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, } else if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); - if (dbg->dbg_cu_current == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); - return (DW_DLV_NO_ENTRY); + if (is_info) { + if (dbg->dbg_cu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_cu_current; + } else { + if (dbg->dbg_tu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_tu_current; } - cu = dbg->dbg_cu_current; if (cu_length) *cu_length = cu->cu_length; @@ -81,11 +98,32 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, *cu_extension_size = 4; } if (cu_next_offset) - *cu_next_offset = dbg->dbg_cu_current->cu_next_offset; + *cu_next_offset = cu->cu_next_offset; + + if (!is_info) { + if (type_signature) + *type_signature = cu->cu_type_sig; + if (type_offset) + *type_offset = cu->cu_type_offset; + } return (DW_DLV_OK); } + +int +dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, + Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, + Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size, + Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset, + Dwarf_Error *error) +{ + + return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, cu_offset_size, + cu_extension_size, NULL, NULL, cu_next_offset, error)); +} + int dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, @@ -97,3 +135,27 @@ dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset, error)); } + +int +dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error) +{ + + /* Free resource allocated for current .debug_types section. */ + _dwarf_type_unit_cleanup(dbg); + dbg->dbg_types_loaded = 0; + dbg->dbg_types_off = 0; + + /* Reset type unit pointer. */ + dbg->dbg_tu_current = NULL; + + /* Search for the next .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, + dbg->dbg_types_sec); + + if (dbg->dbg_types_sec == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_die.c b/contrib/elftoolchain/libdwarf/dwarf_die.c index 055d952..de6351a 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_die.c +++ b/contrib/elftoolchain/libdwarf/dwarf_die.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009,2011 Kai Wang + * Copyright (c) 2009,2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,12 +27,13 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_die.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); int dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) { Dwarf_Debug dbg; + Dwarf_Section *ds; Dwarf_CU cu; int ret; @@ -48,9 +49,9 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) dbg = die->die_dbg; cu = die->die_cu; - ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu, - cu->cu_dwarf_size, die->die_next_off, cu->cu_next_offset, - ret_die, 0, error); + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size, + die->die_next_off, cu->cu_next_offset, ret_die, 0, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -62,11 +63,12 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) } int -dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, - Dwarf_Error *error) +dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Bool is_info, Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Attribute at; + Dwarf_Section *ds; uint64_t offset; int ret, search_sibling; @@ -75,15 +77,27 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, return (DW_DLV_ERROR); } - if ((cu = dbg->dbg_cu_current) == NULL) { + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + + if (cu == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); return (DW_DLV_ERROR); } /* Application requests the first DIE in this CU. */ if (die == NULL) - return (dwarf_offdie(dbg, cu->cu_1st_offset, ret_die, - error)); + return (dwarf_offdie_b(dbg, cu->cu_1st_offset, is_info, + ret_die, error)); + + /* + * Check if the `is_info' flag matches the debug section the + * DIE belongs to. + */ + if (is_info != die->die_cu->cu_is_info) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } /* * If the DIE doesn't have any children, its sibling sits next @@ -108,9 +122,8 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, } } - ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu, - cu->cu_dwarf_size, offset, cu->cu_next_offset, ret_die, - search_sibling, error); + ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size, offset, + cu->cu_next_offset, ret_die, search_sibling, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -121,21 +134,31 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, return (DW_DLV_OK); } + +int +dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_siblingof_b(dbg, die, ret_die, 1, error)); +} + static int -_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off offset, - Dwarf_Die *ret_die, Dwarf_Error *error) +_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_Section *s, Dwarf_CU cu, + Dwarf_Off offset, Dwarf_Die *ret_die, Dwarf_Error *error) { assert(dbg != NULL && cu != NULL && ret_die != NULL); - return (_dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, + return (_dwarf_die_parse(dbg, s, cu, cu->cu_dwarf_size, offset, cu->cu_next_offset, ret_die, 0, error)); } int -dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, - Dwarf_Error *error) +dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, + Dwarf_Die *ret_die, Dwarf_Error *error) { + Dwarf_Section *ds; Dwarf_CU cu; int ret; @@ -144,11 +167,13 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, return (DW_DLV_ERROR); } + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + /* First search the current CU. */ - if (dbg->dbg_cu_current != NULL) { - cu = dbg->dbg_cu_current; + if (cu != NULL) { if (offset > cu->cu_offset && offset < cu->cu_next_offset) { - ret = _dwarf_search_die_within_cu(dbg, cu, offset, + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, ret_die, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -160,21 +185,38 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, } /* Search other CUs. */ - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, is_info, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); - STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { - if (offset < cu->cu_offset || offset > cu->cu_next_offset) - continue; - ret = _dwarf_search_die_within_cu(dbg, cu, offset, - ret_die, error); - if (ret == DW_DLE_NO_ENTRY) { - DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); - return (DW_DLV_NO_ENTRY); - } else if (ret != DW_DLE_NONE) - return (DW_DLV_ERROR); - return (DW_DLV_OK); + if (is_info) { + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (offset < cu->cu_offset || + offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (offset < cu->cu_offset || + offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } } DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -182,6 +224,14 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, } int +dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_offdie_b(dbg, offset, 1, ret_die, error)); +} + +int dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *error) { Dwarf_Debug dbg; @@ -293,9 +343,9 @@ dwarf_die_abbrev_code(Dwarf_Die die) } int -dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, - Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset, - Dwarf_Error *error) +dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, + Dwarf_Off *out_cu_die_offset, Dwarf_Error *error) { Dwarf_CU cu; @@ -304,10 +354,19 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, return (DW_DLV_ERROR); } - STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { - if (cu->cu_offset == in_cu_header_offset) { - *out_cu_die_offset = cu->cu_1st_offset; - break; + if (is_info) { + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } } } @@ -320,6 +379,16 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, } int +dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset, + Dwarf_Error *error) +{ + + return (dwarf_get_cu_die_offset_given_cu_header_offset_b(dbg, + in_cu_header_offset, 1, out_cu_die_offset, error)); +} + +int dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, Dwarf_Error *error) { @@ -333,3 +402,12 @@ dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, return (DW_DLV_OK); } + +Dwarf_Bool +dwarf_get_die_infotypes_flag(Dwarf_Die die) +{ + + assert(die != NULL); + + return (die->die_cu->cu_is_info); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 index 545bf26..00b0e71 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,16 +22,17 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_dieoffset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_dieoffset.3 3129 2014-12-21 20:06:26Z jkoshy $ .\" -.Dd April 17, 2010 +.Dd December 21, 2014 .Os .Dt DWARF_DIEOFFSET 3 .Sh NAME .Nm dwarf_die_CU_offset , .Nm dwarf_die_CU_offset_range , .Nm dwarf_dieoffset , -.Nm dwarf_get_cu_die_offset_given_cu_header_offset +.Nm dwarf_get_cu_die_offset_given_cu_header_offset , +.Nm dwarf_get_cu_die_offset_given_cu_header_offset_b .Nd return offsets of DWARF debugging information entries .Sh LIBRARY .Lb libdwarf @@ -63,6 +64,14 @@ .Fa "Dwarf_Off *out_cu_die_offset" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_get_cu_die_offset_given_cu_header_offset_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off in_cu_header_offset" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Off *out_cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc .Sh DESCRIPTION These functions are used to retrieve offsets for DWARF debugging information entries. @@ -114,7 +123,7 @@ an error. .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset -returns the offset for the debugging information entry for a +returns the offset for the first debugging information entry for a compilation unit, given an offset to the header of the compilation unit. Argument @@ -131,8 +140,30 @@ If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +behaves identically to the function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +when the argument +.Ar is_info +is non-zero. +When the argument +.Ar is_info +is zero, function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +returns the offset for the first debugging information entry for a +type unit, given an offset to the header of the type unit in argument +.Ar in_cu_header_offset . +Argument +.Ar out_cu_die_offset +points to a location that will hold the returned offset. +If the argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case of +an error. .Sh RETURN VALUES -On success, these functions returns +On success, these functions return .Dv DW_DLV_OK . In case of an error, these functions return .Dv DW_DLV_ERROR @@ -141,11 +172,13 @@ and set argument .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset +and +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err -if there is no compilation unit located at the +if there is no compilation or type unit located at the offset specified in argument .Ar in_cu_header_offset . .Sh ERRORS @@ -169,4 +202,5 @@ specified an unknown offset. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_next_cu_header 3 , -.Xr dwarf_offdie 3 +.Xr dwarf_offdie 3 , +.Xr dwarf_offdie_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dump.c b/contrib/elftoolchain/libdwarf/dwarf_dump.c index 9b5d1f7..3219fa4 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_dump.c +++ b/contrib/elftoolchain/libdwarf/dwarf_dump.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_dump.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_dump.c 3052 2014-05-26 20:36:24Z kaiwang27 $"); int dwarf_get_ACCESS_name(unsigned access, const char **s) @@ -250,6 +250,54 @@ dwarf_get_AT_name(unsigned attr, const char **s) *s = "DW_AT_visibility"; break; case DW_AT_vtable_elem_location: *s = "DW_AT_vtable_elem_location"; break; + case DW_AT_sf_names: + *s = "DW_AT_sf_names"; break; + case DW_AT_src_info: + *s = "DW_AT_src_info"; break; + case DW_AT_mac_info: + *s = "DW_AT_mac_info"; break; + case DW_AT_src_coords: + *s = "DW_AT_src_coords"; break; + case DW_AT_body_begin: + *s = "DW_AT_body_begin"; break; + case DW_AT_body_end: + *s = "DW_AT_body_end"; break; + case DW_AT_GNU_vector: + *s = "DW_AT_GNU_vector"; break; + case DW_AT_GNU_guarded_by: + *s = "DW_AT_GNU_guarded_by"; break; + case DW_AT_GNU_pt_guarded_by: + *s = "DW_AT_GNU_pt_guarded_by"; break; + case DW_AT_GNU_guarded: + *s = "DW_AT_GNU_guarded"; break; + case DW_AT_GNU_pt_guarded: + *s = "DW_AT_GNU_pt_guarded"; break; + case DW_AT_GNU_locks_excluded: + *s = "DW_AT_GNU_locks_excluded"; break; + case DW_AT_GNU_exclusive_locks_required: + *s = "DW_AT_GNU_exclusive_locks_required"; break; + case DW_AT_GNU_shared_locks_required: + *s = "DW_AT_GNU_shared_locks_required"; break; + case DW_AT_GNU_odr_signature: + *s = "DW_AT_GNU_odr_signature"; break; + case DW_AT_GNU_template_name: + *s = "DW_AT_GNU_template_name"; break; + case DW_AT_GNU_call_site_value: + *s = "DW_AT_GNU_call_site_value"; break; + case DW_AT_GNU_call_site_data_value: + *s = "DW_AT_GNU_call_site_data_value"; break; + case DW_AT_GNU_call_site_target: + *s = "DW_AT_GNU_call_site_target"; break; + case DW_AT_GNU_call_site_target_clobbered: + *s = "DW_AT_GNU_call_site_target_clobbered"; break; + case DW_AT_GNU_tail_call: + *s = "DW_AT_GNU_tail_call"; break; + case DW_AT_GNU_all_tail_call_sites: + *s = "DW_AT_GNU_all_tail_call_sites"; break; + case DW_AT_GNU_all_call_sites: + *s = "DW_AT_GNU_all_call_sites"; break; + case DW_AT_GNU_all_source_call_sites: + *s = "DW_AT_GNU_all_source_call_sites"; break; default: return (DW_DLV_NO_ENTRY); } @@ -1094,6 +1142,30 @@ dwarf_get_OP_name(unsigned op, const char **s) *s = "DW_OP_stack_value"; break; case DW_OP_GNU_push_tls_address: *s = "DW_OP_GNU_push_tls_address"; break; + case DW_OP_GNU_uninit: + *s = "DW_OP_GNU_uninit"; break; + case DW_OP_GNU_encoded_addr: + *s = "DW_OP_GNU_encoded_addr"; break; + case DW_OP_GNU_implicit_pointer: + *s = "DW_OP_GNU_implicit_pointer"; break; + case DW_OP_GNU_entry_value: + *s = "DW_OP_GNU_entry_value"; break; + case DW_OP_GNU_const_type: + *s = "DW_OP_GNU_const_type"; break; + case DW_OP_GNU_regval_type: + *s = "DW_OP_GNU_regval_type"; break; + case DW_OP_GNU_deref_type: + *s = "DW_OP_GNU_deref_type"; break; + case DW_OP_GNU_convert: + *s = "DW_OP_GNU_convert"; break; + case DW_OP_GNU_reinterpret: + *s = "DW_OP_GNU_reinterpret"; break; + case DW_OP_GNU_parameter_ref: + *s = "DW_OP_GNU_parameter_ref"; break; + case DW_OP_GNU_addr_index: + *s = "DW_OP_GNU_addr_index"; break; + case DW_OP_GNU_const_index: + *s = "DW_OP_GNU_const_index"; break; default: return (DW_DLV_NO_ENTRY); } @@ -1244,6 +1316,26 @@ dwarf_get_TAG_name(unsigned tag, const char **s) *s = "DW_TAG_volatile_type"; break; case DW_TAG_with_stmt: *s = "DW_TAG_with_stmt"; break; + case DW_TAG_format_label: + *s = "DW_TAG_format_label"; break; + case DW_TAG_function_template: + *s = "DW_TAG_function_template"; break; + case DW_TAG_class_template: + *s = "DW_TAG_class_template"; break; + case DW_TAG_GNU_BINCL: + *s = "DW_TAG_GNU_BINCL"; break; + case DW_TAG_GNU_EINCL: + *s = "DW_TAG_GNU_EINCL"; break; + case DW_TAG_GNU_template_template_param: + *s = "DW_TAG_GNU_template_template_param"; break; + case DW_TAG_GNU_template_parameter_pack: + *s = "DW_TAG_GNU_template_parameter_pack"; break; + case DW_TAG_GNU_formal_parameter_pack: + *s = "DW_TAG_GNU_formal_parameter_pack"; break; + case DW_TAG_GNU_call_site: + *s = "DW_TAG_GNU_call_site"; break; + case DW_TAG_GNU_call_site_parameter: + *s = "DW_TAG_GNU_call_site_parameter"; break; default: return (DW_DLV_NO_ENTRY); } diff --git a/contrib/elftoolchain/libdwarf/dwarf_errmsg.c b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c index 16f8e4b..e300893 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_errmsg.c +++ b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_errmsg.c 2576 2012-09-13 09:16:11Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_errmsg.c 2975 2014-01-21 20:08:04Z kaiwang27 $"); static const char *_libdwarf_errors[] = { #define DEFINE_ERROR(N,S) [DW_DLE_##N] = S diff --git a/contrib/elftoolchain/libdwarf/dwarf_frame.c b/contrib/elftoolchain/libdwarf/dwarf_frame.c index 5ccbbc4..442f232 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_frame.c +++ b/contrib/elftoolchain/libdwarf/dwarf_frame.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); int dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list, @@ -539,8 +539,8 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, return (DW_DLV_ERROR); } - ret = _dwarf_frame_get_fop(dbg, instruction, len, ret_oplist, ret_opcnt, - error); + ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len, + ret_oplist, ret_opcnt, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 new file mode 100644 index 0000000..4f5a19a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_die_infotypes_flag.3 3118 2014-12-20 20:30:06Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_GET_DIE_INFOTYPES_FLAG 3 +.Sh NAME +.Nm dwarf_get_die_infotypes_flag +.Nd indicate the originating DWARF section for a DIE +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Bool +.Fo dwarf_get_die_infotypes_flag +.Fa "Dwarf_Die die" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_die_infotypes_flag +returns a flag indicating the originating DWARF section for the +debugging information entry referenced by argument +.Ar die . +.Pp +Argument +.Ar die +should reference a valid debugging information entry descriptor. +.Sh RETURN VALUES +Function +.Fn dwarf_get_die_infotypes_flag +returns a non-zero value if argument +.Ar die +originates in the +.Dq .debug_info +section. +.Pp +It returns zero if argument +.Ar die +originates in the +.Dq .debug_types +section. +.Sh ERRORS +Function +.Fn dwarf_get_die_infotypes_flag +always succeeds. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_next_cu_header_c 3 , +.Xr dwarf_offdie_b 3 , +.Xr dwarf_siblingof_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 b/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 new file mode 100644 index 0000000..6f79341 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_get_section_max_offsets.3 3098 2014-09-02 22:18:29Z kaiwang27 $ +.\" +.Dd July 27, 2014 +.Os +.Dt DWARF_GET_SECTION_MAX_OFFSETS +.Sh NAME +.Nm dwarf_get_section_max_offsets , +.Nm dwarf_get_section_max_offsets_b +.Nd return the size of DWARF sections +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_section_max_offsets +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fc +.Ft int +.Fo dwarf_get_section_max_offsets_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fa "Dwarf_Unsigned *debug_types" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_section_max_offsets_b +retrieves the sizes of the DWARF sections in a DWARF debug context. +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +The function stores the size of each DWARF section to the location +pointed to by the argument corresponding to the section name. +If a DWARF section does not exist, the location pointed to by the +argument corresponding to that section will be set to zero. +.Pp +A value of NULL may be used for any of the arguments +.Ar debug_info , +.Ar debug_abbrev , +.Ar debug_line , +.Ar debug_loc , +.Ar debug_aranges , +.Ar debug_macinfo , +.Ar debug_pubnames , +.Ar debug_str , +.Ar debug_frame , +.Ar debug_ranges , +.Ar debug_pubtypes +and +.Ar debug_types +if the caller is not interested in the respective section size. +.Pp +Function +.Fn dwarf_get_section_max_offsets +is identical to function +.Fn dwarf_get_section_max_offsets_b +except that it does not provide argument +.Ar debug_types , +thus it can not retrieve the size of the +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +If argument +.Ar dbg +is NULL, they return +.Dv DW_DLV_ERROR . +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_highpc.3 b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 index 998a3b6..4d31f5c 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_highpc.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,9 +22,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_highpc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_highpc.3 3092 2014-09-02 22:09:30Z kaiwang27 $ .\" -.Dd April 7, 2010 +.Dd July 22, 2014 .Os .Dt DWARF_HIGHPC 3 .Sh NAME @@ -33,6 +33,7 @@ .Nm dwarf_bitsize , .Nm dwarf_bytesize , .Nm dwarf_highpc , +.Nm dwarf_highpc_b , .Nm dwarf_lowpc , .Nm dwarf_srclang .Nd retrieve the value of a DWARF attribute @@ -71,6 +72,14 @@ .Fa "Dwarf_Error *err" .Fc .Ft int +.Fo dwarf_highpc_b +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_highpc" +.Fa "Dwarf_Half *ret_form" +.Fa "enum Dwarf_Form_Class *ret_class" +.Fa "Dwarf_Error *err" +.Fc +.Ft int .Fo dwarf_lowpc .Fa "Dwarf_Die die" .Fa "Dwarf_Addr *ret_lowpc" @@ -114,6 +123,10 @@ attribute value. Retrieve the .Dv DW_AT_high_pc attribute value. +.It Fn dwarf_highpc_b +Retrieve the +.Dv DW_AT_high_pc +attribute value. .It Fn dwarf_lowpc Retrieve the .Dv DW_AT_low_pc @@ -123,6 +136,23 @@ Retrieve the .Dv DW_AT_language attribute value. .El +.Pp +Function +.Fn dwarf_highpc_b +is an enhanced version of function +.Fn dwarf_highpc . +It sets the location specified by argument +.Ar ret_form +to the form code of the attribute +.Dv DW_AT_high_pc , +and sets the location specified by argument +.Ar ret_class +to the class of that form. +A value of NULL may be used for either of the arguments +.Ar ret_form +or +.Ar ret_class +if the caller is not interested in the respective value. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. @@ -159,4 +189,5 @@ had no requested attribute. .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_attrlist 3 , -.Xr dwarf_hasattr 3 +.Xr dwarf_hasattr 3 , +.Xr dwarf_get_form_class 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_lineno.c b/contrib/elftoolchain/libdwarf/dwarf_lineno.c index d0c24b1..cbcc9ae 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_lineno.c +++ b/contrib/elftoolchain/libdwarf/dwarf_lineno.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 $"); int dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, @@ -75,8 +75,8 @@ dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, return (DW_DLV_OK); } - if ((li->li_lnarray = malloc(*linecount * - sizeof(struct _Dwarf_Line))) == NULL) { + if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) == + NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_ERROR); } diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist.c b/contrib/elftoolchain/libdwarf/dwarf_loclist.c index 4696bc5..e780a87 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_loclist.c +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009 Kai Wang + * Copyright (c) 2009,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,13 +26,37 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_loclist.c 2074 2011-10-27 03:34:33Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_loclist.c 3066 2014-06-06 19:36:06Z kaiwang27 $"); + +static int +copy_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *dst, Dwarf_Locdesc *src, + Dwarf_Error *error) +{ + + assert(src != NULL && dst != NULL); + + dst->ld_lopc = src->ld_lopc; + dst->ld_hipc = src->ld_hipc; + dst->ld_cents = src->ld_cents; + + if (dst->ld_cents > 0) { + dst->ld_s = calloc(dst->ld_cents, sizeof(Dwarf_Loc)); + if (dst->ld_s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(dst->ld_s, src->ld_s, src->ld_cents * + sizeof(Dwarf_Loc)); + } else + dst->ld_s = NULL; + + return (DW_DLE_NONE); +} int dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { - Dwarf_Loclist ll; Dwarf_Debug dbg; int ret; @@ -69,26 +93,41 @@ dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, /* FALLTHROUGH */ case DW_FORM_sec_offset: ret = _dwarf_loclist_find(dbg, at->at_die->die_cu, - at->u[0].u64, &ll, error); + at->u[0].u64, llbuf, listlen, NULL, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, ret); return (DW_DLV_NO_ENTRY); } if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); - *llbuf = ll->ll_ldlist; - *listlen = ll->ll_ldlen; return (DW_DLV_OK); case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: + case DW_FORM_exprloc: if (at->at_ld == NULL) { ret = _dwarf_loc_add(at->at_die, at, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); } - *llbuf = &at->at_ld; + *llbuf = calloc(1, sizeof(Dwarf_Locdesc *)); + if (*llbuf == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + (*llbuf)[0] = calloc(1, sizeof(Dwarf_Locdesc)); + if ((*llbuf)[0] == NULL) { + free(*llbuf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + if (copy_locdesc(dbg, (*llbuf)[0], at->at_ld, error) != + DW_DLE_NONE) { + free((*llbuf)[0]); + free(*llbuf); + return (DW_DLV_ERROR); + } *listlen = 1; return (DW_DLV_OK); default: @@ -107,75 +146,27 @@ int dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { - Dwarf_Loclist ll; - Dwarf_Debug dbg; - int ret; + Dwarf_Locdesc **_llbuf; + int i, ret; - dbg = at != NULL ? at->at_die->die_dbg : NULL; + ret = dwarf_loclist_n(at, &_llbuf, listlen, error); + if (ret != DW_DLV_OK) + return (ret); - if (at == NULL || llbuf == NULL || listlen == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); - return (DW_DLV_ERROR); - } + /* Only return the first location description of the list. */ + *llbuf = _llbuf[0]; - switch (at->at_attrib) { - case DW_AT_location: - case DW_AT_string_length: - case DW_AT_return_addr: - case DW_AT_data_member_location: - case DW_AT_frame_base: - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: - case DW_AT_vtable_elem_location: - switch (at->at_form) { - case DW_FORM_data4: - case DW_FORM_data8: - /* - * DW_FORM_data[48] can not be used as section offset - * since DWARF4. For DWARF[23], the application needs - * to determine if DW_FORM_data[48] is representing - * a constant or a section offset. - */ - if (at->at_die->die_cu->cu_version >= 4) { - printf("called cu_version >= 4\n"); - DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); - return (DW_DLV_NO_ENTRY); - } - /* FALLTHROUGH */ - case DW_FORM_sec_offset: - ret = _dwarf_loclist_find(at->at_die->die_dbg, - at->at_die->die_cu, at->u[0].u64, &ll, error); - if (ret == DW_DLE_NO_ENTRY) { - DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); - return (DW_DLV_NO_ENTRY); - } - if (ret != DW_DLE_NONE) - return (DW_DLV_ERROR); - *llbuf = ll->ll_ldlist[0]; - *listlen = 1; - return (DW_DLV_OK); - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - if (at->at_ld == NULL) { - ret = _dwarf_loc_add(at->at_die, at, error); - if (ret != DW_DLE_NONE) - return (DW_DLV_ERROR); - } - *llbuf = at->at_ld; - *listlen = 1; - return (DW_DLV_OK); - default: - DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); - return (DW_DLV_ERROR); - } - default: - /* Wrong attr supplied. */ - DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); - return (DW_DLV_ERROR); + /* Free the rest of the list. */ + for (i = 1; i < *listlen; i++) { + if (_llbuf[i]->ld_s) + free(_llbuf[i]->ld_s); + free(_llbuf[i]); } + free(_llbuf); + + *listlen = 1; + + return (DW_DLV_OK); } int @@ -184,19 +175,25 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error) { - Dwarf_Loclist ll, next_ll; - Dwarf_Locdesc *ld; + Dwarf_Locdesc *ld, **llbuf; Dwarf_Section *ds; + Dwarf_Signed listlen; int i, ret; + /* + * Note that this API sometimes will not work correctly because + * it assumes that all units have the same pointer size and offset + * size. + */ + if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL || entry_len == NULL || next_entry == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } - ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll, - error); + ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, + &llbuf, &listlen, entry_len, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); return (DW_DLV_NO_ENTRY); @@ -204,8 +201,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, return (DW_DLV_ERROR); *hipc = *lopc = 0; - for (i = 0; i < ll->ll_ldlen; i++) { - ld = ll->ll_ldlist[i]; + for (i = 0; i < listlen; i++) { + ld = llbuf[i]; if (i == 0) { *hipc = ld->ld_hipc; *lopc = ld->ld_lopc; @@ -219,14 +216,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, ds = _dwarf_find_section(dbg, ".debug_loc"); assert(ds != NULL); - *data = (uint8_t *) ds->ds_data + ll->ll_offset; - *entry_len = ll->ll_length; - - next_ll = TAILQ_NEXT(ll, ll_next); - if (next_ll != NULL) - *next_entry = next_ll->ll_offset; - else - *next_entry = ds->ds_size; + *data = (uint8_t *) ds->ds_data + offset; + *next_entry = offset + *entry_len; return (DW_DLV_OK); } @@ -236,24 +227,9 @@ dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { - Dwarf_Locdesc *ld; - int ret; - - if (dbg == NULL || bytes_in == NULL || bytes_len == 0 || - llbuf == NULL || listlen == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); - return (DW_DLV_ERROR); - } - - ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, - dbg->dbg_pointer_size, error); - if (ret != DW_DLE_NONE) - return (DW_DLV_ERROR); - - *llbuf = ld; - *listlen = 1; - return (DW_DLV_OK); + return (dwarf_loclist_from_expr_a(dbg, bytes_in, bytes_len, + dbg->dbg_pointer_size, llbuf, listlen, error)); } int @@ -261,6 +237,40 @@ dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { + Dwarf_Half offset_size; + Dwarf_Small version; + + /* + * Obtain offset size and DWARF version from the current + * Compilation Unit or Type Unit. These values are needed + * for correctly parsing DW_OP_GNU_implicit_pointer operator. + * + * Note that dwarf_loclist_from_expr_b() should be used instead + * if the application knows correct values for offset size + * and DWARF version. + */ + if (dbg->dbg_cu_current) { + offset_size = dbg->dbg_cu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_cu_current->cu_version; + } else if (dbg->dbg_tu_current) { + offset_size = dbg->dbg_tu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_tu_current->cu_version; + } else { + /* Default values if no CU/TU context. */ + offset_size = 4; + version = 2; /* DWARF2 */ + } + + return (dwarf_loclist_from_expr_b(dbg, bytes_in, bytes_len, addr_size, + offset_size, version, llbuf, listlen, error)); +} + +int +dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, + Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, + Dwarf_Error *error) +{ Dwarf_Locdesc *ld; int ret; @@ -275,8 +285,13 @@ dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, return (DW_DLV_ERROR); } + if (offset_size != 4 && offset_size != 8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size, - error); + offset_size, version, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 index d317f7e..d0eb88c 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Kai Wang +.\" Copyright (c) 2011,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,14 +22,15 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_loclist_from_expr.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_loclist_from_expr.3 3129 2014-12-21 20:06:26Z jkoshy $ .\" -.Dd July 6, 2011 +.Dd December 21, 2014 .Os .Dt DWARF_LOCLIST_FROM_EXPR 3 .Sh NAME .Nm dwarf_loclist_from_expr , -.Nm dwarf_loclist_from_expr_a +.Nm dwarf_loclist_from_expr_a , +.Nm dwarf_loclist_from_expr_b .Nd translate DWARF location expression bytes .Sh LIBRARY .Lb libdwarf @@ -54,6 +55,18 @@ .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_loclist_from_expr_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Half addr_size" +.Fa "Dwarf_Half offset_size" +.Fa "Dwarf_Small version" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc .Sh DESCRIPTION Function .Fn dwarf_loclist_from_expr @@ -104,6 +117,21 @@ except that it requires one additional argument .Ar addr_size , which specifies the address size to use when translating the location expression bytes. +.Pp +Function +.Fn dwarf_loclist_from_expr_b +is identical to function +.Fn dwarf_loclist_from_expr_a +except that it requires two additional arguments for translating the +location expression bytes. +Argument +.Ar offset_size +specifies the offset size, and argument +.Ar version +specifies the DWARF version. +These values are required to correctly translate the +.Dv DW_OP_GNU_implicit_pointer +opcode. .Ss Memory Management The memory area used for the descriptor returned in argument .Ar llbuf diff --git a/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 index 5be00b8..f172322 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,14 +22,15 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: dwarf_next_cu_header.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_next_cu_header.3 3128 2014-12-21 20:06:22Z jkoshy $ .\" -.Dd July 24, 2010 +.Dd December 21, 2014 .Os .Dt DWARF_NEXT_CU_HEADER 3 .Sh NAME .Nm dwarf_next_cu_header , -.Nm dwarf_next_cu_header_b +.Nm dwarf_next_cu_header_b , +.Nm dwarf_next_cu_header_c .Nd step through compilation units in a DWARF debug context .Sh LIBRARY .Lb libdwarf @@ -57,33 +58,71 @@ .Fa "Dwarf_Unsigned *cu_next_offset" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_next_cu_header_c +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Half *cu_offset_size" +.Fa "Dwarf_Half *cu_extension_size" +.Fa "Dwarf_Sig8 *type_signature" +.Fa "Dwarf_Unsigned *type_offset" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc .Sh DESCRIPTION -These functions are used to step through compilation unit contexts +These functions are used to step through compilation or type units associated with a DWARF debug context, optionally returning information about the unit. .Pp Function -.Fn dwarf_next_cu_header_b +.Fn dwarf_next_cu_header_c is the API recommended for new application code. +Function +.Fn dwarf_next_cu_header +and +.Fn dwarf_next_cu_header_b +can only operate on compilation units associated with the +.Dq \&.debug_info +section. +They are less general than function +.Fn dwarf_next_cu_header_c , +and are deprecated for use by new application code. +.Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . +If argument +.Ar is_info +is set to 1, +the function returns information for compilation units found in the +.Dq \&.debug_info +section. +If argument +.Ar is_info +is set to 0, +the function returns information for type units found in the +.Dq \&.debug_types +sections. Argument .Ar cu_length should point to a location that will be set to the -length of the compilation unit. +length of the compilation or type unit. Argument .Ar cu_version should point to a location that will be set to the -version number for the compilation unit. +version number for the compilation or type unit. Argument .Ar cu_abbrev_offset should point to a location that will be set to the starting offset (in the .Dq .debug_abbrev section) of the set of debugging information entry abbreviations -associated with this compilation unit. +associated with this compilation or type unit. Argument .Ar cu_pointer_size should point to a location that will be set to the @@ -92,7 +131,7 @@ underlying object being debugged. Argument .Ar cu_offset_size should point to a location that will be set to the -size in bytes for a DWARF offset in the compilation unit. +size in bytes for a DWARF offset in the compilation or type unit. Argument .Ar cu_extension_size is only needed for processing MIPS/IRIX objects that use @@ -100,10 +139,26 @@ a non-standard DWARF format. It should point to a location that will be set to 4 for normal objects and to 0 for non-standard ones. Argument +.Ar type_signature +and +.Ar type_offset +is only needed for processing type units. +Argument +.Ar type_signature +should point to a location that will be set to the 64-bit unique signature +of the type described in the type unit. +Argument +.Ar type_offset +should point to a location that will be set to the offset of the debugging +information entry that describes the type. +Argument .Ar cu_next_offset should point to a location that will be set to the offset of the next compilation unit header in the .Dq \&.debug_info +section, +or the offset of the next type unit header in the +.Dq \&.debug_types section. Argument .Ar err @@ -111,42 +166,23 @@ should point to a location that will hold an error descriptor in case of an error. .Pp Function +.Fn dwarf_next_cu_header_b +is identical to function +.Fn dwarf_next_cu_header_c +except that it does not provide arguments +.Ar is_info , +.Ar type_signature +and +.Ar type_offset . +.Pp +Function .Fn dwarf_next_cu_header -is less general than -.Fn dwarf_next_cu_header_b , -and is deprecated for use by new application code. -Argument -.Ar dbg -should reference a DWARF debug context allocated using -.Xr dwarf_init 3 . -Argument -.Ar cu_length -should point to a location that will be set to the -length of the compilation unit. -Argument -.Ar cu_version -should point to a location that will be set to the -version number for the compilation unit. -Argument -.Ar cu_abbrev_offset -should point to a location that will be set to the -starting offset in the -.Dq .debug_abbrev -section of the set of debugging information entry abbreviations -associated with this compilation unit. -Argument -.Ar cu_pointer_size -should point to a location that will be set to the -size of an address in bytes for the machine architecture of the -underlying debugging object. -Argument -.Ar cu_next_offset -should point to a location that will be set to the -offset of the next compilation unit. -Argument -.Ar err -should point to a location that will hold an error descriptor in case -of an error. +is identical to function +.Fn dwarf_next_cu_header_b +except that it does not provide arguments +.Ar cu_offset_size +and +.Ar cu_extension_size . .Pp A value of NULL may be used for any of the arguments .Ar cu_length , @@ -155,30 +191,79 @@ A value of NULL may be used for any of the arguments .Ar cu_pointer_size , .Ar cu_offset_size , .Ar cu_extension_size , +.Ar type_signature , +.Ar type_offset , .Ar cu_next_offset and .Ar err if the caller is not interested in the respective value. .Ss Iterating Through Compilation Units in a Debug Context .Pp -The first call to functions -.Fn dwarf_next_cu_header_b -and -.Fn dwarf_next_cu_header -for a given debug context will return information about the first -compilation unit in the debug context. -Subsequent calls to these functions will iterate through the remaining -compilation units in the debug context. -On stepping past the last compilation unit in the debug context, -functions -.Fn dwarf_next_cu_header -and -.Fn dwarf_next_cu_header_b -return +The first call to function +.Fn dwarf_next_cu_header_c +for a given debug context with argument +.Ar is_info +set to 1 will return information about the first +compilation unit in the +.Dq \&.debug_info +section. +Subsequent calls to the function will iterate through the remaining +compilation units in the section. +On stepping past the last compilation unit in the section, +function +.Fn dwarf_next_cu_header_c +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first compilation +unit in the section. +.Ss Iterating Through Type Units in a Debug Context +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer assoicated with the context will point to the +fisrt +.Dq \&.debug_types +section found in the debug object. +The first call to function +.Fn dwarf_next_cu_header_c +for the debug context with argument +.Ar is_info +set to 0 will return information about the first +type unit in that +.Dq \&.debug_types +section. +Subsequent calls to the function will iterate through the remaining +type units in the section. +On stepping past the last type unit in the debug context, +function +.Fn dwarf_next_cu_header_c +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first type +unit in the +.Dq \&.debug_types +section. +.Pp +If the debug object contains multiple +.Dq \&.debug_types +sections, the function +.Fn dwarf_next_types_section +can be called to move the internal pointer to the next +.Dq \&.debug_types +section. +As a result, subsequent calls of the function +.Fn dwarf_next_cu_header_c +will operate on the new +.Dq \&.debug_types +section. +Function +.Fn dwarf_next_types_section +returns .Dv DW_DLV_NO_ENTRY -and reset their internal state. -The next call to these functions will restart from the first compilation -unit in the debug context. +when there are no more +.Dq \&.debug_types +sections left in the debug object. .Sh RETURN VALUES On success, these functions return .Dv DW_DLV_OK . @@ -200,4 +285,5 @@ was NULL. .Xr dwarf 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_init 3 , +.Xr dwarf_next_types_section 3 , .Xr dwarf_siblingof 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 b/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 new file mode 100644 index 0000000..98ff70d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2014 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: dwarf_next_types_section.3 3116 2014-12-20 18:26:55Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_NEXT_TYPES_SECTION 3 +.Sh NAME +.Nm dwarf_next_types_section +.Nd step through .debug_types sections in a debug context +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_next_types_section +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_next_types_section +steps through the +.Dq \&.debug_types +sections found in a debug context. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Ar err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer associated with the context will point to the +first +.Dq \&.debug_types +section present in the debug object. +When the application calls function +.Fn dwarf_next_types_section , +this internal pointer will move to the next +.Dq \&.debug_types +section present. +On stepping past the last +.Dq \&.debug_types +section left in the debug context, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_NO_ENTRY . +The next call to the function will restart from the first +.Dq \&.debug_types +section in the debug context. +.Pp +Application code should call function +.Xr dwarf_next_cu_header_c 3 +to iterate though the type units associated with the current +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +When there are no more +.Dq \&.debug_types +sections left to traverse, it returns +.Dv DW_DLV_NO_ENTRY . +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_next_types_section +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was NULL. +.El +.Sh EXAMPLES +To iterate though every type unit in all the +.Dq \&.debug_types +sections found in a debug context: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Sig8 sig8; +Dwarf_Unsigned typeoff; +Dwarf_Error de; + +\&... allocate dbg using dwarf_init() etc ... + +do { + while ((ret = dwarf_next_cu_header_c(dbg, 0, NULL, NULL, NULL, + NULL, NULL, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) { + /* Access DIEs etc ... */ + } +} while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_next_cu_header_c 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_ranges.c b/contrib/elftoolchain/libdwarf/dwarf_ranges.c index 9ad6083..2e01da5 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_ranges.c +++ b/contrib/elftoolchain/libdwarf/dwarf_ranges.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_ranges.c 2075 2011-10-27 03:47:28Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_ranges.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); static int _dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off off, @@ -63,7 +63,7 @@ dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Ranges **ranges, } if (!dbg->dbg_info_loaded) { - if (_dwarf_info_load(dbg, 1, error) != DW_DLE_NONE) + if (_dwarf_info_load(dbg, 1, 1, error) != DW_DLE_NONE) return (DW_DLV_ERROR); } diff --git a/contrib/elftoolchain/libdwarf/dwarf_sections.c b/contrib/elftoolchain/libdwarf/dwarf_sections.c new file mode 100644 index 0000000..d3c1379 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_sections.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2014 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_sections.c 3036 2014-05-05 19:19:31Z kaiwang27 $"); + +#define SET(N, V) \ + do { \ + if ((N) != NULL) \ + *(N) = (V); \ + } while (0) + +int +dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes, + Dwarf_Unsigned *debug_types) +{ + const char *n; + Dwarf_Unsigned sz; + int i; + + if (dbg == NULL) + return (DW_DLV_ERROR); + + SET(debug_info, 0); + SET(debug_abbrev, 0); + SET(debug_line, 0); + SET(debug_loc, 0); + SET(debug_aranges, 0); + SET(debug_macinfo, 0); + SET(debug_pubnames, 0); + SET(debug_str, 0); + SET(debug_frame, 0); + SET(debug_ranges, 0); + SET(debug_pubtypes, 0); + SET(debug_types, 0); + + for (i = 0; (Dwarf_Unsigned) i < dbg->dbg_seccnt; i++) { + n = dbg->dbg_section[i].ds_name; + sz = dbg->dbg_section[i].ds_size; + if (!strcmp(n, ".debug_info")) + SET(debug_info, sz); + else if (!strcmp(n, ".debug_abbrev")) + SET(debug_abbrev, sz); + else if (!strcmp(n, ".debug_line")) + SET(debug_line, sz); + else if (!strcmp(n, ".debug_loc")) + SET(debug_loc, sz); + else if (!strcmp(n, ".debug_aranges")) + SET(debug_aranges, sz); + else if (!strcmp(n, ".debug_macinfo")) + SET(debug_macinfo, sz); + else if (!strcmp(n, ".debug_pubnames")) + SET(debug_pubnames, sz); + else if (!strcmp(n, ".debug_str")) + SET(debug_str, sz); + else if (!strcmp(n, ".debug_frame")) + SET(debug_frame, sz); + else if (!strcmp(n, ".debug_ranges")) + SET(debug_ranges, sz); + else if (!strcmp(n, ".debug_pubtypes")) + SET(debug_pubtypes, sz); + else if (!strcmp(n, ".debug_types")) + SET(debug_types, sz); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes) +{ + + return (dwarf_get_section_max_offsets(dbg, debug_info, debug_abbrev, + debug_line, debug_loc, debug_aranges, debug_macinfo, + debug_pubnames, debug_str, debug_frame, debug_ranges, + debug_pubtypes)); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h index 105a0e7..9a4a899 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf.h +++ b/contrib/elftoolchain/libdwarf/libdwarf.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: libdwarf.h 2576 2012-09-13 09:16:11Z jkoshy $ + * $Id: libdwarf.h 3064 2014-06-06 19:35:55Z kaiwang27 $ */ #ifndef _LIBDWARF_H_ @@ -47,7 +47,6 @@ typedef struct _Dwarf_ArangeSet *Dwarf_ArangeSet; typedef struct _Dwarf_Attribute *Dwarf_Attribute; typedef struct _Dwarf_Attribute *Dwarf_P_Attribute; typedef struct _Dwarf_AttrDef *Dwarf_AttrDef; -typedef struct _Dwarf_CU *Dwarf_CU; typedef struct _Dwarf_Cie *Dwarf_Cie; typedef struct _Dwarf_Cie *Dwarf_P_Cie; typedef struct _Dwarf_Debug *Dwarf_Debug; @@ -60,7 +59,6 @@ typedef struct _Dwarf_FrameSec *Dwarf_FrameSec; typedef struct _Dwarf_Line *Dwarf_Line; typedef struct _Dwarf_LineFile *Dwarf_LineFile; typedef struct _Dwarf_LineInfo *Dwarf_LineInfo; -typedef struct _Dwarf_Loclist *Dwarf_Loclist; typedef struct _Dwarf_MacroSet *Dwarf_MacroSet; typedef struct _Dwarf_NamePair *Dwarf_NamePair; typedef struct _Dwarf_NamePair *Dwarf_Func; @@ -519,6 +517,7 @@ int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *, Dwarf_Error *); int dwarf_attrlist(Dwarf_Die, Dwarf_Attribute **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_attroffset(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *); int dwarf_attrval_flag(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, Dwarf_Error *); int dwarf_attrval_signed(Dwarf_Die, Dwarf_Half, Dwarf_Signed *, @@ -626,6 +625,9 @@ int dwarf_get_cu_die_offset(Dwarf_Arange, Dwarf_Off *, Dwarf_Error *); int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug, Dwarf_Off, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug, + Dwarf_Off, Dwarf_Bool, Dwarf_Off *, Dwarf_Error *); +Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die); int dwarf_get_elf(Dwarf_Debug, Elf **, Dwarf_Error *); int dwarf_get_fde_at_pc(Dwarf_Fde *, Dwarf_Addr, Dwarf_Fde *, Dwarf_Addr *, Dwarf_Addr *, Dwarf_Error *); @@ -678,6 +680,16 @@ int dwarf_get_relocation_info_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug, Dwarf_Signed, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_section_max_offsets(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *); +int dwarf_get_section_max_offsets_b(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *); int dwarf_get_str(Dwarf_Debug, Dwarf_Off, char **, Dwarf_Signed *, Dwarf_Error *); int dwarf_get_types(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, @@ -700,6 +712,8 @@ int dwarf_hasattr(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, int dwarf_hasform(Dwarf_Attribute, Dwarf_Half, Dwarf_Bool *, Dwarf_Error *); int dwarf_highpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +int dwarf_highpc_b(Dwarf_Die, Dwarf_Addr *, Dwarf_Half *, + enum Dwarf_Form_Class *, Dwarf_Error *); int dwarf_init(int, int, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *); int dwarf_line_srcfileno(Dwarf_Line, Dwarf_Unsigned *, @@ -722,6 +736,10 @@ int dwarf_loclist_from_expr(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, int dwarf_loclist_from_expr_a(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, Dwarf_Half, Dwarf_Locdesc **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_from_expr_b(Dwarf_Debug, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Half, Dwarf_Half, + Dwarf_Small, Dwarf_Locdesc **, Dwarf_Signed *, + Dwarf_Error *); int dwarf_loclist_n(Dwarf_Attribute, Dwarf_Locdesc ***, Dwarf_Signed *, Dwarf_Error *); int dwarf_lowpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); @@ -735,11 +753,18 @@ int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *, int dwarf_next_cu_header_b(Dwarf_Debug, Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, Dwarf_Half *, Dwarf_Half *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_cu_header_c(Dwarf_Debug, Dwarf_Bool, + Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Half *, Dwarf_Sig8 *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_types_section(Dwarf_Debug, Dwarf_Error *); int dwarf_object_finish(Dwarf_Debug, Dwarf_Error *); int dwarf_object_init(Dwarf_Obj_Access_Interface *, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *); int dwarf_offdie(Dwarf_Debug, Dwarf_Off, Dwarf_Die *, Dwarf_Error *); +int dwarf_offdie_b(Dwarf_Debug, Dwarf_Off, Dwarf_Bool, Dwarf_Die *, + Dwarf_Error *); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug, Dwarf_Error *); Dwarf_P_Debug dwarf_producer_init(Dwarf_Unsigned, Dwarf_Callback_Func, Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); @@ -765,6 +790,8 @@ int dwarf_set_reloc_application(int); Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug, Dwarf_Ptr); Dwarf_Handler dwarf_seterrhand(Dwarf_Debug, Dwarf_Handler); int dwarf_siblingof(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Error *); +int dwarf_siblingof_b(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Bool, + Dwarf_Error *); int dwarf_srcfiles(Dwarf_Die, char ***, Dwarf_Signed *, Dwarf_Error *); int dwarf_srclang(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); int dwarf_srclines(Dwarf_Die, Dwarf_Line **, Dwarf_Signed *, diff --git a/contrib/elftoolchain/libdwarf/libdwarf_arange.c b/contrib/elftoolchain/libdwarf/libdwarf_arange.c index 75434f6..eefb63b 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_arange.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_arange.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_arange.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_arange.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); void _dwarf_arange_cleanup(Dwarf_Debug dbg) @@ -67,7 +67,7 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NONE); if (!dbg->dbg_info_loaded) { - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, 1, error); if (ret != DW_DLE_NONE) return (ret); } @@ -137,8 +137,8 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) /* Build arange array. */ if (dbg->dbg_arange_cnt > 0) { - if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * - sizeof(struct _Dwarf_Arange))) == NULL) { + if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * + sizeof(Dwarf_Arange))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); ret = DW_DLE_MEMORY; goto fail_cleanup; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_attr.c b/contrib/elftoolchain/libdwarf/libdwarf_attr.c index a7fb71c..dfbbc48 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_attr.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_attr.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_attr.c 2966 2013-09-21 14:40:14Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); int _dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) @@ -106,6 +106,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, ret = DW_DLE_NONE; memset(&atref, 0, sizeof(atref)); atref.at_die = die; + atref.at_offset = *offsetp; atref.at_attrib = ad->ad_attrib; atref.at_form = indirect ? form : ad->ad_form; atref.at_indirect = indirect; @@ -162,7 +163,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, if (cu->cu_version == 2) atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, cu->cu_pointer_size); - else if (cu->cu_version == 3) + else atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); break; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_die.c b/contrib/elftoolchain/libdwarf/libdwarf_die.c index 4572875..b7796d3 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_die.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_die.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_die.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); int _dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) @@ -81,6 +81,7 @@ Dwarf_Die _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) { Dwarf_Debug dbg; + Dwarf_Section *ds; Dwarf_CU cu; Dwarf_Die die1; Dwarf_Error de; @@ -88,9 +89,10 @@ _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) cu = die->die_cu; dbg = die->die_dbg; + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; - ret = _dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, - off, cu->cu_next_offset, &die1, 0, &de); + ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off, + cu->cu_next_offset, &die1, 0, &de); if (ret == DW_DLE_NONE) return (die1); diff --git a/contrib/elftoolchain/libdwarf/libdwarf_frame.c b/contrib/elftoolchain/libdwarf/libdwarf_frame.c index 375d64f..dd33137 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_frame.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_frame.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_frame.c 2529 2012-07-29 23:31:12Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); static int _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, @@ -49,8 +49,9 @@ _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, } static int -_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data, - uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, Dwarf_Error *error) +_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val, + uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, + Dwarf_Error *error) { uint8_t application; @@ -62,7 +63,7 @@ _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data, switch (encode) { case DW_EH_PE_absptr: - *val = dbg->read(data, offsetp, dbg->dbg_pointer_size); + *val = dbg->read(data, offsetp, cie->cie_addrsize); break; case DW_EH_PE_uleb128: *val = _dwarf_read_uleb128(data, offsetp); @@ -149,7 +150,7 @@ _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie, /* Skip two augments in augment data. */ encode = *augdata_p++; offset = 0; - ret = _dwarf_frame_read_lsb_encoded(dbg, &val, + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, augdata_p, &offset, encode, 0, error); if (ret != DW_DLE_NONE) return (ret); @@ -233,6 +234,18 @@ _dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, cie->cie_ehdata = dbg->read(ds->ds_data, off, dbg->dbg_pointer_size); + /* DWARF4 added "address_size" and "segment_size". */ + if (cie->cie_version == 4) { + cie->cie_addrsize = dbg->read(ds->ds_data, off, 1); + cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1); + } else { + /* + * Otherwise (DWARF[23]) we just set CIE addrsize to the + * debug context pointer size. + */ + cie->cie_addrsize = dbg->dbg_pointer_size; + } + cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off); cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off); @@ -345,8 +358,9 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, * The FDE PC start/range for .eh_frame is encoded according * to the LSB spec's extension to DWARF2. */ - ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data, - off, cie->cie_fde_encode, ds->ds_addr + *off, error); + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, + ds->ds_data, off, cie->cie_fde_encode, ds->ds_addr + *off, + error); if (ret != DW_DLE_NONE) return (ret); fde->fde_initloc = val; @@ -354,16 +368,16 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, * FDE PC range should not be relative value to anything. * So pass 0 for pc value. */ - ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data, - off, cie->cie_fde_encode, 0, error); + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, + ds->ds_data, off, cie->cie_fde_encode, 0, error); if (ret != DW_DLE_NONE) return (ret); fde->fde_adrange = val; } else { fde->fde_initloc = dbg->read(ds->ds_data, off, - dbg->dbg_pointer_size); + cie->cie_addrsize); fde->fde_adrange = dbg->read(ds->ds_data, off, - dbg->dbg_pointer_size); + cie->cie_addrsize); } /* Optional FDE augmentation data for .eh_frame section. (ignored) */ @@ -530,9 +544,9 @@ fail_cleanup: } static int -_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts, - Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, - Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error) +_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size, + uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, + Dwarf_Addr pc, Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error) { Dwarf_Regtable3 *init_rt, *saved_rt; uint8_t *p, *pe; @@ -632,7 +646,7 @@ _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts, switch (low6) { case DW_CFA_set_loc: - pc = dbg->decode(&p, dbg->dbg_pointer_size); + pc = dbg->decode(&p, addr_size); #ifdef FRAME_DEBUG printf("DW_CFA_set_loc(pc=%#jx)\n", pc); #endif @@ -898,14 +912,13 @@ program_done: } static int -_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, - Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, Dwarf_Frame_Op3 *fop3, - Dwarf_Error *error) +_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, + Dwarf_Frame_Op3 *fop3, Dwarf_Error *error) { uint8_t *p, *pe; uint8_t high2, low6; uint64_t reg, reg2, uoff, soff, blen; - int ret; #define SET_BASE_OP(x) \ do { \ @@ -970,7 +983,6 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, } \ } while(0) - ret = DW_DLE_NONE; *count = 0; p = insts; @@ -1020,7 +1032,7 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, switch (low6) { case DW_CFA_set_loc: - uoff = dbg->decode(&p, dbg->dbg_pointer_size); + uoff = dbg->decode(&p, addr_size); SET_OFFSET(uoff); break; case DW_CFA_advance_loc1: @@ -1103,15 +1115,16 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, } int -_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, - Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, Dwarf_Error *error) +_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, + Dwarf_Error *error) { Dwarf_Frame_Op *oplist; Dwarf_Unsigned count; int ret; - ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, NULL, NULL, - error); + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + NULL, NULL, error); if (ret != DW_DLE_NONE) return (ret); @@ -1120,8 +1133,8 @@ _dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, return (DW_DLE_MEMORY); } - ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, oplist, NULL, - error); + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + oplist, NULL, error); if (ret != DW_DLE_NONE) { free(oplist); return (ret); @@ -1201,17 +1214,17 @@ _dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req, /* Run initial instructions in CIE. */ cie = fde->fde_cie; assert(cie != NULL); - ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_initinst, - cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, ~0ULL, - &row_pc, error); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + cie->cie_initinst, cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, + ~0ULL, &row_pc, error); if (ret != DW_DLE_NONE) return (ret); /* Run instructions in FDE. */ if (pc_req >= fde->fde_initloc) { - ret = _dwarf_frame_run_inst(dbg, rt, fde->fde_inst, - fde->fde_instlen, cie->cie_caf, cie->cie_daf, - fde->fde_initloc, pc_req, &row_pc, error); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + fde->fde_inst, fde->fde_instlen, cie->cie_caf, + cie->cie_daf, fde->fde_initloc, pc_req, &row_pc, error); if (ret != DW_DLE_NONE) return (ret); } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_info.c b/contrib/elftoolchain/libdwarf/libdwarf_info.c index dc82b7d..261bee6 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_info.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_info.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2010,2011 Kai Wang + * Copyright (c) 2010,2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_info.c 2942 2013-05-04 23:03:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_info.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); int _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) @@ -46,7 +46,7 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NO_ENTRY); dbg->dbg_info_off = 0; - ret = _dwarf_info_load(dbg, 0, error); + ret = _dwarf_info_load(dbg, 0, 1, error); if (ret != DW_DLE_NONE) return (ret); @@ -56,6 +56,32 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) } int +_dwarf_info_first_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU tu; + int ret; + + assert(dbg->dbg_tu_current == NULL); + tu = STAILQ_FIRST(&dbg->dbg_tu); + if (tu != NULL) { + dbg->dbg_tu_current = tu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) + return (DW_DLE_NO_ENTRY); + + dbg->dbg_types_off = 0; + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_FIRST(&dbg->dbg_tu); + + return (DW_DLE_NONE); +} + +int _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_CU cu; @@ -73,7 +99,7 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NO_ENTRY); } - ret = _dwarf_info_load(dbg, 0, error); + ret = _dwarf_info_load(dbg, 0, 1, error); if (ret != DW_DLE_NONE) return (ret); @@ -83,7 +109,35 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) } int -_dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) +_dwarf_info_next_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_tu_current != NULL); + cu = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + if (cu != NULL) { + dbg->dbg_tu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) { + dbg->dbg_tu_current = NULL; + return (DW_DLE_NO_ENTRY); + } + + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, + Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Section *ds; @@ -93,12 +147,22 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) uint64_t offset; ret = DW_DLE_NONE; - if (dbg->dbg_info_loaded) - return (DW_DLE_NONE); - offset = dbg->dbg_info_off; - ds = dbg->dbg_info_sec; - assert(ds != NULL); + if (is_info) { + if (dbg->dbg_info_loaded) + return (ret); + offset = dbg->dbg_info_off; + ds = dbg->dbg_info_sec; + assert(ds != NULL); + } else { + if (dbg->dbg_types_loaded) + return (ret); + offset = dbg->dbg_types_off; + ds = dbg->dbg_types_sec; + if (ds == NULL) + return (DW_DLE_NO_ENTRY); + } + while (offset < ds->ds_size) { if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); @@ -106,6 +170,7 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) } cu->cu_dbg = dbg; + cu->cu_is_info = is_info; cu->cu_offset = offset; length = dbg->read(ds->ds_data, &offset, 4); @@ -129,7 +194,10 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) /* Compute the offset to the next compilation unit: */ next_offset = offset + length; - dbg->dbg_info_off = next_offset; + if (is_info) + dbg->dbg_info_off = next_offset; + else + dbg->dbg_types_off = next_offset; /* Initialise the compilation unit. */ cu->cu_length = length; @@ -141,8 +209,20 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1); cu->cu_next_offset = next_offset; + /* .debug_types extra fields. */ + if (!is_info) { + memcpy(cu->cu_type_sig.signature, + (char *) ds->ds_data + offset, 8); + offset += 8; + cu->cu_type_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + } + /* Add the compilation unit to the list. */ - STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + if (is_info) + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + else + STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next); if (cu->cu_version < 2 || cu->cu_version > 4) { DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); @@ -158,8 +238,13 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) break; } - if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) - dbg->dbg_info_loaded = 1; + if (is_info) { + if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) + dbg->dbg_info_loaded = 1; + } else { + if ((Dwarf_Unsigned) dbg->dbg_types_off >= ds->ds_size) + dbg->dbg_types_loaded = 1; + } return (ret); } @@ -180,6 +265,22 @@ _dwarf_info_cleanup(Dwarf_Debug dbg) } free(cu); } + + _dwarf_type_unit_cleanup(dbg); +} + +void +_dwarf_type_unit_cleanup(Dwarf_Debug dbg) +{ + Dwarf_CU cu, tcu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + STAILQ_FOREACH_SAFE(cu, &dbg->dbg_tu, cu_next, tcu) { + STAILQ_REMOVE(&dbg->dbg_tu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + free(cu); + } } int diff --git a/contrib/elftoolchain/libdwarf/libdwarf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_init.c index 71d5966..8e3fbbe 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_init.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_init.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_init.c 3061 2014-06-02 00:42:41Z kaiwang27 $"); static int _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) @@ -69,7 +69,8 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) dbg->dbg_seccnt = cnt; - if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) { + if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == + NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } @@ -90,6 +91,7 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) return (ret); } } + dbg->dbg_section[cnt].ds_name = NULL; if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == @@ -98,6 +100,9 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_DEBUG_INFO_NULL); } + /* Try to find the optional DWARF4 .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); + /* Initialise call frame API related parameters. */ _dwarf_frame_params_init(dbg); @@ -210,10 +215,10 @@ _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, dbg->dbg_errarg = errarg; STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_tu); STAILQ_INIT(&dbg->dbg_rllist); STAILQ_INIT(&dbg->dbg_aslist); STAILQ_INIT(&dbg->dbg_mslist); - TAILQ_INIT(&dbg->dbg_loclist); if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { ret = _dwarf_consumer_init(dbg, error); @@ -270,7 +275,6 @@ _dwarf_consumer_deinit(Dwarf_Debug dbg) assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); _dwarf_info_cleanup(dbg); - _dwarf_loclist_cleanup(dbg); _dwarf_ranges_cleanup(dbg); _dwarf_frame_cleanup(dbg); _dwarf_arange_cleanup(dbg); diff --git a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c index 8bb3c85..63627f7 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_lineno.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_lineno.c 3100 2014-10-25 20:34:29Z jkoshy $"); static int _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, @@ -87,9 +87,8 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, { Dwarf_Debug dbg; Dwarf_Line ln, tln; - uint64_t address, file, line, column, isa, opsize; + uint64_t address, file, line, column, opsize; int is_stmt, basic_block, end_sequence; - int prologue_end, epilogue_begin; int ret; #define RESET_REGISTERS \ @@ -101,8 +100,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, is_stmt = li->li_defstmt; \ basic_block = 0; \ end_sequence = 0; \ - prologue_end = 0; \ - epilogue_begin = 0; \ } while(0) #define APPEND_ROW \ @@ -181,8 +178,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, case DW_LNS_copy: APPEND_ROW; basic_block = 0; - prologue_end = 0; - epilogue_begin = 0; break; case DW_LNS_advance_pc: address += _dwarf_decode_uleb128(&p) * @@ -210,13 +205,11 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, address += dbg->decode(&p, 2); break; case DW_LNS_set_prologue_end: - prologue_end = 1; break; case DW_LNS_set_epilogue_begin: - epilogue_begin = 1; break; case DW_LNS_set_isa: - isa = _dwarf_decode_uleb128(&p); + (void) _dwarf_decode_uleb128(&p); break; default: /* Unrecognized extened opcodes. What to do? */ @@ -233,8 +226,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, address += ADDRESS(*p); APPEND_ROW; basic_block = 0; - prologue_end = 0; - epilogue_begin = 0; p++; } } @@ -482,7 +473,7 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Unsigned address, file, line, spc; Dwarf_Unsigned addr0, maddr; Dwarf_Signed line0, column; - int is_stmt, basic_block, end_sequence; + int is_stmt, basic_block; int need_copy; int ret; @@ -494,7 +485,6 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, column = 0; \ is_stmt = li->li_defstmt; \ basic_block = 0; \ - end_sequence = 0; \ } while(0) li = dbg->dbgp_lineinfo; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loc.c b/contrib/elftoolchain/libdwarf/libdwarf_loc.c index ea366fb..c2d3f5c 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_loc.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_loc.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $"); /* * Given an array of bytes of length 'len' representing a @@ -38,12 +39,12 @@ ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); */ static int _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, - uint8_t *p, int len) + uint8_t offset_size, uint8_t version, uint8_t *p, int len) { int count; uint64_t operand1; uint64_t operand2; - uint8_t *ps, *pe; + uint8_t *ps, *pe, s; count = 0; ps = p; @@ -165,37 +166,49 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, case DW_OP_ne: case DW_OP_nop: + case DW_OP_push_object_address: case DW_OP_form_tls_address: case DW_OP_call_frame_cfa: case DW_OP_stack_value: case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: break; /* Operations with 1-byte operands. */ case DW_OP_const1u: - case DW_OP_const1s: case DW_OP_pick: case DW_OP_deref_size: case DW_OP_xderef_size: operand1 = *p++; break; + case DW_OP_const1s: + operand1 = (int8_t) *p++; + break; + /* Operations with 2-byte operands. */ case DW_OP_call2: case DW_OP_const2u: - case DW_OP_const2s: case DW_OP_bra: case DW_OP_skip: operand1 = dbg->decode(&p, 2); break; + case DW_OP_const2s: + operand1 = (int16_t) dbg->decode(&p, 2); + break; + /* Operations with 4-byte operands. */ case DW_OP_call4: case DW_OP_const4u: - case DW_OP_const4s: + case DW_OP_GNU_parameter_ref: operand1 = dbg->decode(&p, 4); break; + case DW_OP_const4s: + operand1 = (int32_t) dbg->decode(&p, 4); + break; + /* Operations with 8-byte operands. */ case DW_OP_const8u: case DW_OP_const8s: @@ -207,6 +220,9 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: + case DW_OP_GNU_deref_type: + case DW_OP_GNU_convert: + case DW_OP_GNU_reinterpret: operand1 = _dwarf_decode_uleb128(&p); break; @@ -252,6 +268,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, * Oeration with two unsigned LEB128 operands. */ case DW_OP_bit_piece: + case DW_OP_GNU_regval_type: operand1 = _dwarf_decode_uleb128(&p); operand2 = _dwarf_decode_uleb128(&p); break; @@ -267,10 +284,14 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, /* * Operation with an unsigned LEB128 operand - * followed by a block. Store a pointer to the - * block in the operand2. + * representing the size of a block, followed + * by the block content. + * + * Store the size of the block in the operand1 + * and a pointer to the block in the operand2. */ case DW_OP_implicit_value: + case DW_OP_GNU_entry_value: operand1 = _dwarf_decode_uleb128(&p); operand2 = (Dwarf_Unsigned) (uintptr_t) p; p += operand1; @@ -278,25 +299,59 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, /* Target address size operand. */ case DW_OP_addr: + case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: operand1 = dbg->decode(&p, pointer_size); break; + /* Offset size operand. */ + case DW_OP_call_ref: + operand1 = dbg->decode(&p, offset_size); + break; + /* - * XXX Opcode DW_OP_call_ref has an operand with size - * "dwarf_size". Here we use dbg->dbg_offset_size - * as "dwarf_size" to be compatible with SGI libdwarf. - * However note that dbg->dbg_offset_size is just - * a "guess" value so the parsing result of - * DW_OP_call_ref might not be correct at all. XXX + * The first byte is address byte length, followed by + * the address value. If the length is 0, the address + * size is the same as target pointer size. */ - case DW_OP_call_ref: - operand1 = dbg->decode(&p, dbg->dbg_offset_size); + case DW_OP_GNU_encoded_addr: + s = *p++; + if (s == 0) + s = pointer_size; + operand1 = dbg->decode(&p, s); + break; + + /* + * Operand1: DIE offset (size depending on DWARF version) + * DWARF2: pointer size + * DWARF{3,4}: offset size + * + * Operand2: SLEB128 + */ + case DW_OP_GNU_implicit_pointer: + if (version == 2) + operand1 = dbg->decode(&p, pointer_size); + else + operand1 = dbg->decode(&p, offset_size); + operand2 = _dwarf_decode_sleb128(&p); + break; + + /* + * Operand1: DIE offset (ULEB128) + * Operand2: pointer to a block. The block's first byte + * is its size. + */ + case DW_OP_GNU_const_type: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = (Dwarf_Unsigned) (uintptr_t) p; + s = *p++; + p += s; break; /* All other operations cause an error. */ default: count = -1; - break; + goto done; } if (lbuf != NULL) { @@ -307,6 +362,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, count++; } +done: return (count); } @@ -561,7 +617,8 @@ _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, int _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, - uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) { int num; @@ -570,8 +627,8 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, assert(in_len > 0); /* Compute the number of locations. */ - if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) < - 0) { + if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, + version, in, in_len)) < 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); return (DW_DLE_LOC_EXPR_BAD); } @@ -585,14 +642,16 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, return (DW_DLE_MEMORY); } - (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len); + (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, + version, in, in_len); return (DW_DLE_NONE); } int _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, - uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) { Dwarf_Locdesc *llbuf; int ret; @@ -606,7 +665,7 @@ _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, llbuf->ld_s = NULL; ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, - error); + offset_size, version, error); if (ret != DW_DLE_NONE) { free(llbuf); return (ret); @@ -635,7 +694,8 @@ _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) assert(dbg != NULL); ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, - at->u[0].u64, cu->cu_pointer_size, error); + at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8, + cu->cu_version, error); return (ret); } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loclist.c b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c index 8030e9a..bb3e39f 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_loclist.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c @@ -26,11 +26,11 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_loclist.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_loclist.c 3061 2014-06-02 00:42:41Z kaiwang27 $"); static int _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, - uint64_t *off, Dwarf_Locdesc **ld, uint64_t *ldlen, + Dwarf_Unsigned *off, Dwarf_Locdesc **ld, Dwarf_Signed *ldlen, Dwarf_Unsigned *total_len, Dwarf_Error *error) { uint64_t start, end; @@ -75,6 +75,7 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, if (ld != NULL) { ret = _dwarf_loc_fill_locdesc(dbg, ld[i], ds->ds_data + *off, len, cu->cu_pointer_size, + cu->cu_length_size == 4 ? 4 : 8, cu->cu_version, error); if (ret != DW_DLE_NONE) return (ret); @@ -91,37 +92,15 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, int _dwarf_loclist_find(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, - Dwarf_Loclist *ret_ll, Dwarf_Error *error) -{ - Dwarf_Loclist ll; - int ret; - - assert(ret_ll != NULL); - ret = DW_DLE_NONE; - - TAILQ_FOREACH(ll, &dbg->dbg_loclist, ll_next) - if (ll->ll_offset == lloff) - break; - - if (ll == NULL) - ret = _dwarf_loclist_add(dbg, cu, lloff, ret_ll, error); - else - *ret_ll = ll; - - return (ret); -} - -int -_dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, - Dwarf_Loclist *ret_ll, Dwarf_Error *error) + Dwarf_Locdesc ***ret_llbuf, Dwarf_Signed *listlen, + Dwarf_Unsigned *entry_len, Dwarf_Error *error) { + Dwarf_Locdesc **llbuf; Dwarf_Section *ds; - Dwarf_Loclist ll, tll; - uint64_t ldlen; + Dwarf_Signed ldlen; + Dwarf_Unsigned off; int i, ret; - ret = DW_DLE_NONE; - if ((ds = _dwarf_find_section(dbg, ".debug_loc")) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLE_NO_ENTRY); @@ -132,98 +111,55 @@ _dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, return (DW_DLE_NO_ENTRY); } - if ((ll = malloc(sizeof(struct _Dwarf_Loclist))) == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); - return (DW_DLE_MEMORY); - } - - ll->ll_offset = lloff; - /* Get the number of locdesc the first round. */ - ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, NULL, &ldlen, + off = lloff; + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, NULL, &ldlen, NULL, error); if (ret != DW_DLE_NONE) - goto fail_cleanup; + return (ret); + + if (ldlen == 0) + return (DW_DLE_NO_ENTRY); /* * Dwarf_Locdesc list memory is allocated in this way (one more level * of indirect) to make the loclist API be compatible with SGI libdwarf. */ - ll->ll_ldlen = ldlen; - if (ldlen != 0) { - if ((ll->ll_ldlist = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == - NULL) { + if ((llbuf = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + for (i = 0; i < ldlen; i++) { + if ((llbuf[i] = calloc(1, sizeof(Dwarf_Locdesc))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); ret = DW_DLE_MEMORY; goto fail_cleanup; } - for (i = 0; (uint64_t) i < ldlen; i++) { - if ((ll->ll_ldlist[i] = - calloc(1, sizeof(Dwarf_Locdesc))) == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); - ret = DW_DLE_MEMORY; - goto fail_cleanup; - } - } - } else - ll->ll_ldlist = NULL; + } - lloff = ll->ll_offset; + off = lloff; /* Fill in locdesc. */ - ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, ll->ll_ldlist, - NULL, &ll->ll_length, error); + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, llbuf, NULL, + entry_len, error); if (ret != DW_DLE_NONE) goto fail_cleanup; - /* Insert to the queue. Sort by offset. */ - TAILQ_FOREACH(tll, &dbg->dbg_loclist, ll_next) - if (tll->ll_offset > ll->ll_offset) { - TAILQ_INSERT_BEFORE(tll, ll, ll_next); - break; - } - - if (tll == NULL) - TAILQ_INSERT_TAIL(&dbg->dbg_loclist, ll, ll_next); + *ret_llbuf = llbuf; + *listlen = ldlen; - *ret_ll = ll; return (DW_DLE_NONE); fail_cleanup: - _dwarf_loclist_free(ll); - - return (ret); -} - -void -_dwarf_loclist_free(Dwarf_Loclist ll) -{ - int i; - - if (ll == NULL) - return; - - if (ll->ll_ldlist != NULL) { - for (i = 0; i < ll->ll_ldlen; i++) { - if (ll->ll_ldlist[i]->ld_s) - free(ll->ll_ldlist[i]->ld_s); - free(ll->ll_ldlist[i]); + if (llbuf != NULL) { + for (i = 0; i < ldlen; i++) { + if (llbuf[i]->ld_s) + free(llbuf[i]->ld_s); + free(llbuf[i]); } - free(ll->ll_ldlist); + free(llbuf); } - free(ll); -} -void -_dwarf_loclist_cleanup(Dwarf_Debug dbg) -{ - Dwarf_Loclist ll, tll; - - assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); - - TAILQ_FOREACH_SAFE(ll, &dbg->dbg_loclist, ll_next, tll) { - TAILQ_REMOVE(&dbg->dbg_loclist, ll, ll_next); - _dwarf_loclist_free(ll); - } + return (ret); } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c index 158aca3..661b56f 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_nametbl.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_nametbl.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); void _dwarf_nametbl_cleanup(Dwarf_NameSec *nsp) @@ -103,7 +103,7 @@ _dwarf_nametbl_init(Dwarf_Debug dbg, Dwarf_NameSec *namesec, Dwarf_Section *ds, nt->nt_cu_length = dbg->read(ds->ds_data, &offset, dwarf_size); if (!dbg->dbg_info_loaded) { - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, 1, error); if (ret != DW_DLE_NONE) goto fail_cleanup; } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_sections.c b/contrib/elftoolchain/libdwarf/libdwarf_sections.c index 3ac30b2..24d5db8 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_sections.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_sections.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_sections.c 2379 2012-01-05 02:08:20Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_sections.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); #define _SECTION_INIT_SIZE 128 @@ -212,7 +212,7 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name) Dwarf_Section *ds; Dwarf_Half i; - assert(name != NULL); + assert(dbg != NULL && name != NULL); for (i = 0; i < dbg->dbg_seccnt; i++) { ds = &dbg->dbg_section[i]; @@ -223,6 +223,27 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name) return (NULL); } +Dwarf_Section * +_dwarf_find_next_types_section(Dwarf_Debug dbg, Dwarf_Section *ds) +{ + + assert(dbg != NULL); + + if (ds == NULL) + return (_dwarf_find_section(dbg, ".debug_types")); + + assert(ds->ds_name != NULL); + + do { + ds++; + if (ds->ds_name != NULL && + !strcmp(ds->ds_name, ".debug_types")) + return (ds); + } while (ds->ds_name != NULL); + + return (NULL); +} + Dwarf_P_Section _dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name) { |