diff options
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_query.c')
-rw-r--r-- | usr/src/tools/ctf/dwarf/common/dwarf_query.c | 754 |
1 files changed, 467 insertions, 287 deletions
diff --git a/usr/src/tools/ctf/dwarf/common/dwarf_query.c b/usr/src/tools/ctf/dwarf/common/dwarf_query.c index 8573f4be9c..3f21abd039 100644 --- a/usr/src/tools/ctf/dwarf/common/dwarf_query.c +++ b/usr/src/tools/ctf/dwarf/common/dwarf_query.c @@ -1,6 +1,7 @@ /* - Copyright (C) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved. + Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License @@ -19,10 +20,10 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. - Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com @@ -32,6 +33,13 @@ http://oss.sgi.com/projects/GenInfo/NoticeExplan */ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the Crittenden Lane address. +*/ + + #include "config.h" @@ -39,30 +47,52 @@ #include <stdio.h> #include "dwarf_die_deliv.h" +/* This is normally reliable. +But not always. +If different compilation +units have different address sizes +this may not give the correct value in all contexts. +If the Elf offset size != address_size +(for example if address_size = 4 but recorded in elf64 object) +this may not give the correct value in all contexts. +*/ int dwarf_get_address_size(Dwarf_Debug dbg, - Dwarf_Half * ret_addr_size, Dwarf_Error * error) + Dwarf_Half * ret_addr_size, Dwarf_Error * error) { - Dwarf_Half address_size; + Dwarf_Half address_size = 0; if (dbg == 0) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return (DW_DLV_ERROR); + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); } - /* length size same as address size */ address_size = dbg->de_pointer_size; *ret_addr_size = address_size; return DW_DLV_OK; } +/* This will be correct in all contexts where the + CU context of a DIE is known. +*/ +int +dwarf_get_die_address_size(Dwarf_Die die, + Dwarf_Half * ret_addr_size, Dwarf_Error * error) +{ + Dwarf_Half address_size = 0; + CHECK_DIE(die, DW_DLV_ERROR); + address_size = die->di_cu_context->cc_address_size; + *ret_addr_size = address_size; + return DW_DLV_OK; +} + int dwarf_dieoffset(Dwarf_Die die, - Dwarf_Off * ret_offset, Dwarf_Error * error) + Dwarf_Off * ret_offset, Dwarf_Error * error) { - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - * ret_offset = (die->di_debug_info_ptr - - die->di_cu_context->cc_dbg->de_debug_info); + *ret_offset = (die->di_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info.dss_data); return DW_DLV_OK; } @@ -75,123 +105,153 @@ dwarf_dieoffset(Dwarf_Die die, */ int dwarf_die_CU_offset(Dwarf_Die die, - Dwarf_Off * cu_off, Dwarf_Error * error) + Dwarf_Off * cu_off, Dwarf_Error * error) { - Dwarf_CU_Context cu_context; + Dwarf_CU_Context cu_context = 0; - CHECK_DIE(die, DW_DLV_ERROR) - cu_context = die->di_cu_context; + CHECK_DIE(die, DW_DLV_ERROR); + cu_context = die->di_cu_context; *cu_off = - (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info - - cu_context->cc_debug_info_offset); + (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info.dss_data - + cu_context->cc_debug_info_offset); return DW_DLV_OK; } - +/* + This function returns the global offset + (meaning the section offset) and length of + the CU that this die is a part of. + Used for correctness checking by dwarfdump. +*/ int -dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) +dwarf_die_CU_offset_range(Dwarf_Die die, + Dwarf_Off * cu_off, + Dwarf_Off * cu_length, + Dwarf_Error * error) { - CHECK_DIE(die, DW_DLV_ERROR) + Dwarf_CU_Context cu_context = 0; + CHECK_DIE(die, DW_DLV_ERROR); + cu_context = die->di_cu_context; - * tag = (die->di_abbrev_list->ab_tag); + *cu_off = cu_context->cc_debug_info_offset; + *cu_length = cu_context->cc_length + cu_context->cc_length_size + + cu_context->cc_extension_size; + return DW_DLV_OK; +} + + + +int +dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) +{ + CHECK_DIE(die, DW_DLV_ERROR); + *tag = (die->di_abbrev_list->ab_tag); return DW_DLV_OK; } int dwarf_attrlist(Dwarf_Die die, - Dwarf_Attribute ** attrbuf, - Dwarf_Signed * attrcnt, Dwarf_Error * error) + Dwarf_Attribute ** attrbuf, + Dwarf_Signed * attrcnt, Dwarf_Error * error) { Dwarf_Word attr_count = 0; - Dwarf_Word i; - Dwarf_Half attr; - Dwarf_Half attr_form; - Dwarf_Byte_Ptr abbrev_ptr; - Dwarf_Abbrev_List abbrev_list; - Dwarf_Attribute new_attr; - Dwarf_Attribute head_attr = NULL, curr_attr; - Dwarf_Attribute *attr_ptr; - Dwarf_Debug dbg; - Dwarf_Byte_Ptr info_ptr; - - CHECK_DIE(die, DW_DLV_ERROR) - dbg = die->di_cu_context->cc_dbg; + Dwarf_Word i = 0; + Dwarf_Half attr = 0; + Dwarf_Half attr_form = 0; + Dwarf_Byte_Ptr abbrev_ptr = 0; + Dwarf_Abbrev_List abbrev_list = 0; + Dwarf_Attribute new_attr = 0; + Dwarf_Attribute head_attr = NULL; + Dwarf_Attribute curr_attr = NULL; + Dwarf_Attribute *attr_ptr = 0; + Dwarf_Debug dbg = 0; + Dwarf_Byte_Ptr info_ptr = 0; + + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, - die->di_abbrev_list-> - ab_code); + die->di_abbrev_list-> + ab_code); if (abbrev_list == NULL) { - _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD); + return (DW_DLV_ERROR); } abbrev_ptr = abbrev_list->ab_abbrev_ptr; info_ptr = die->di_debug_info_ptr; - SKIP_LEB128_WORD(info_ptr) - - do { - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(abbrev_ptr, utmp2) - attr = (Dwarf_Half) utmp2; - DECODE_LEB128_UWORD(abbrev_ptr, utmp2) - attr_form = (Dwarf_Half) utmp2; - - if (attr != 0) { - new_attr = - (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); - if (new_attr == NULL) { - _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - - new_attr->ar_attribute = attr; - new_attr->ar_attribute_form_direct = attr_form; - new_attr->ar_attribute_form = attr_form; - if(attr_form == DW_FORM_indirect) { - Dwarf_Unsigned utmp6; - /* DECODE_LEB128_UWORD does info_ptr update */ - DECODE_LEB128_UWORD(info_ptr, utmp6) + SKIP_LEB128_WORD(info_ptr); + + do { + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr = (Dwarf_Half) utmp2; + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr_form = (Dwarf_Half) utmp2; + + if (attr != 0) { + new_attr = + (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); + if (new_attr == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + new_attr->ar_attribute = attr; + new_attr->ar_attribute_form_direct = attr_form; + new_attr->ar_attribute_form = attr_form; + if (attr_form == DW_FORM_indirect) { + Dwarf_Unsigned utmp6; + + /* DECODE_LEB128_UWORD does info_ptr update */ + DECODE_LEB128_UWORD(info_ptr, utmp6); attr_form = (Dwarf_Half) utmp6; - new_attr->ar_attribute_form = attr_form; - } - new_attr->ar_cu_context = die->di_cu_context; - new_attr->ar_debug_info_ptr = info_ptr; - - info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr, - die->di_cu_context-> - cc_length_size); - - if (head_attr == NULL) - head_attr = curr_attr = new_attr; - else { - curr_attr->ar_next = new_attr; - curr_attr = new_attr; - } - attr_count++; - } + new_attr->ar_attribute_form = attr_form; + } + new_attr->ar_cu_context = die->di_cu_context; + new_attr->ar_debug_info_ptr = info_ptr; + + { + Dwarf_Unsigned sov = _dwarf_get_size_of_val(dbg, + attr_form, + die->di_cu_context->cc_address_size, + info_ptr, + die->di_cu_context->cc_length_size); + info_ptr += sov; + } + + + if (head_attr == NULL) + head_attr = curr_attr = new_attr; + else { + curr_attr->ar_next = new_attr; + curr_attr = new_attr; + } + attr_count++; + } } while (attr != 0 || attr_form != 0); if (attr_count == 0) { - *attrbuf = NULL; - *attrcnt = 0; - return (DW_DLV_NO_ENTRY); + *attrbuf = NULL; + *attrcnt = 0; + return (DW_DLV_NO_ENTRY); } attr_ptr = (Dwarf_Attribute *) - _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); + _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); if (attr_ptr == NULL) { - _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); } curr_attr = head_attr; for (i = 0; i < attr_count; i++) { - *(attr_ptr + i) = curr_attr; - curr_attr = curr_attr->ar_next; + *(attr_ptr + i) = curr_attr; + curr_attr = curr_attr->ar_next; } *attrbuf = attr_ptr; @@ -212,50 +272,50 @@ dwarf_attrlist(Dwarf_Die die, */ static Dwarf_Byte_Ptr _dwarf_get_value_ptr(Dwarf_Die die, - Dwarf_Half attr, Dwarf_Half * attr_form) + Dwarf_Half attr, Dwarf_Half * attr_form) { - Dwarf_Byte_Ptr abbrev_ptr; + Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Abbrev_List abbrev_list; - Dwarf_Half curr_attr; - Dwarf_Half curr_attr_form; - Dwarf_Byte_Ptr info_ptr; + Dwarf_Half curr_attr = 0; + Dwarf_Half curr_attr_form = 0; + Dwarf_Byte_Ptr info_ptr = 0; abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, - die->di_abbrev_list-> - ab_code); + die->di_abbrev_list->ab_code); if (abbrev_list == NULL) { - *attr_form = 0; - return (NULL); + *attr_form = 0; + return (NULL); } abbrev_ptr = abbrev_list->ab_abbrev_ptr; info_ptr = die->di_debug_info_ptr; - SKIP_LEB128_WORD(info_ptr) + SKIP_LEB128_WORD(info_ptr); do { - Dwarf_Unsigned utmp3; - - DECODE_LEB128_UWORD(abbrev_ptr, utmp3) - curr_attr = (Dwarf_Half) utmp3; - DECODE_LEB128_UWORD(abbrev_ptr, utmp3) - curr_attr_form = (Dwarf_Half) utmp3; - if(curr_attr_form == DW_FORM_indirect) { - Dwarf_Unsigned utmp6; - - /* DECODE_LEB128_UWORD updates info_ptr */ - DECODE_LEB128_UWORD(info_ptr, utmp6) - curr_attr_form = (Dwarf_Half) utmp6; + Dwarf_Unsigned utmp3; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + curr_attr = (Dwarf_Half) utmp3; + DECODE_LEB128_UWORD(abbrev_ptr, utmp3); + curr_attr_form = (Dwarf_Half) utmp3; + if (curr_attr_form == DW_FORM_indirect) { + Dwarf_Unsigned utmp6; + + /* DECODE_LEB128_UWORD updates info_ptr */ + DECODE_LEB128_UWORD(info_ptr, utmp6); + curr_attr_form = (Dwarf_Half) utmp6; } - if (curr_attr == attr) { - *attr_form = curr_attr_form; - return (info_ptr); - } + if (curr_attr == attr) { + *attr_form = curr_attr_form; + return (info_ptr); + } - info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg, - curr_attr_form, info_ptr, - die->di_cu_context-> - cc_length_size); + info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg, + curr_attr_form, + die->di_cu_context->cc_address_size, + info_ptr, + die->di_cu_context->cc_length_size); } while (curr_attr != 0 || curr_attr_form != 0); *attr_form = 1; @@ -266,74 +326,70 @@ _dwarf_get_value_ptr(Dwarf_Die die, int dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error) { - Dwarf_Half attr_form; - Dwarf_Debug dbg; - Dwarf_Byte_Ptr info_ptr; - Dwarf_Unsigned string_offset; - int res; + Dwarf_Half attr_form = 0; + Dwarf_Debug dbg = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Unsigned string_offset = 0; + int res = DW_DLV_ERROR; - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form); + info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form); if (info_ptr == NULL) { - if (attr_form == 0) { - _dwarf_error(die->di_cu_context->cc_dbg, error, - DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); - } - return DW_DLV_NO_ENTRY; + if (attr_form == 0) { + _dwarf_error(die->di_cu_context->cc_dbg, error, + DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; } if (attr_form == DW_FORM_string) { - *ret_name = (char *) (info_ptr); - return DW_DLV_OK; + *ret_name = (char *) (info_ptr); + return DW_DLV_OK; } dbg = die->di_cu_context->cc_dbg; if (attr_form != DW_FORM_strp) { - _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); } READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned, - info_ptr, die->di_cu_context->cc_length_size); + info_ptr, die->di_cu_context->cc_length_size); - if (string_offset >= dbg->de_debug_str_size) { - _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD); - return (DW_DLV_ERROR); + if (string_offset >= dbg->de_debug_str.dss_size) { + _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD); + return (DW_DLV_ERROR); } - res = - _dwarf_load_section(dbg, - dbg->de_debug_str_index, - &dbg->de_debug_str, - error); + res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } - *ret_name = (char *) (dbg->de_debug_str + string_offset); + *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset); return DW_DLV_OK; } int dwarf_hasattr(Dwarf_Die die, - Dwarf_Half attr, - Dwarf_Bool * return_bool, Dwarf_Error * error) + Dwarf_Half attr, + Dwarf_Bool * return_bool, Dwarf_Error * error) { - Dwarf_Half attr_form; + Dwarf_Half attr_form = 0; - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) { - if (attr_form == 0) { - _dwarf_error(die->di_cu_context->cc_dbg, error, - DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); - } - *return_bool = false; - return DW_DLV_OK; + if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) { + if (attr_form == 0) { + _dwarf_error(die->di_cu_context->cc_dbg, error, + DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + *return_bool = false; + return DW_DLV_OK; } *return_bool = (true); @@ -343,30 +399,30 @@ dwarf_hasattr(Dwarf_Die die, int dwarf_attr(Dwarf_Die die, - Dwarf_Half attr, - Dwarf_Attribute * ret_attr, Dwarf_Error * error) + Dwarf_Half attr, + Dwarf_Attribute * ret_attr, Dwarf_Error * error) { - Dwarf_Half attr_form; - Dwarf_Attribute attrib; - Dwarf_Byte_Ptr info_ptr; - Dwarf_Debug dbg; + Dwarf_Half attr_form = 0; + Dwarf_Attribute attrib = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Debug dbg = 0; - CHECK_DIE(die, DW_DLV_ERROR) - dbg = die->di_cu_context->cc_dbg; + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); if (info_ptr == NULL) { - if (attr_form == 0) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); - } - return DW_DLV_NO_ENTRY; + if (attr_form == 0) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; } attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (attrib == NULL) { - _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); } attrib->ar_attribute = attr; @@ -381,29 +437,31 @@ dwarf_attr(Dwarf_Die die, int dwarf_lowpc(Dwarf_Die die, - Dwarf_Addr * return_addr, Dwarf_Error * error) + Dwarf_Addr * return_addr, Dwarf_Error * error) { - Dwarf_Addr ret_addr; - Dwarf_Byte_Ptr info_ptr; - Dwarf_Half attr_form; - Dwarf_Debug dbg; + Dwarf_Addr ret_addr = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Half attr_form = 0; + Dwarf_Debug dbg = 0; + Dwarf_Half address_size = 0; - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - dbg = die->di_cu_context->cc_dbg; + dbg = die->di_cu_context->cc_dbg; + address_size = die->di_cu_context->cc_address_size; info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form); if ((info_ptr == NULL && attr_form == 0) || - (info_ptr != NULL && attr_form != DW_FORM_addr)) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); + (info_ptr != NULL && attr_form != DW_FORM_addr)) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); } if (info_ptr == NULL) { - return (DW_DLV_NO_ENTRY); + return (DW_DLV_NO_ENTRY); } READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, - info_ptr, dbg->de_pointer_size); + info_ptr, address_size); *return_addr = ret_addr; return (DW_DLV_OK); @@ -412,28 +470,29 @@ dwarf_lowpc(Dwarf_Die die, int dwarf_highpc(Dwarf_Die die, - Dwarf_Addr * return_addr, Dwarf_Error * error) + Dwarf_Addr * return_addr, Dwarf_Error * error) { - Dwarf_Addr ret_addr; - Dwarf_Byte_Ptr info_ptr; - Dwarf_Half attr_form; - Dwarf_Debug dbg; + Dwarf_Addr ret_addr = 0; + Dwarf_Byte_Ptr info_ptr = 0; + Dwarf_Half attr_form = 0; + Dwarf_Debug dbg = 0; + Dwarf_Half address_size = 0; - CHECK_DIE(die, DW_DLV_ERROR) - - dbg = die->di_cu_context->cc_dbg; + CHECK_DIE(die, DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + address_size = die->di_cu_context->cc_address_size; info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form); if ((info_ptr == NULL && attr_form == 0) || - (info_ptr != NULL && attr_form != DW_FORM_addr)) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); + (info_ptr != NULL && attr_form != DW_FORM_addr)) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); } if (info_ptr == NULL) { - return (DW_DLV_NO_ENTRY); + return (DW_DLV_NO_ENTRY); } READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, - info_ptr, dbg->de_pointer_size); + info_ptr, address_size); *return_addr = ret_addr; return (DW_DLV_OK); @@ -453,56 +512,56 @@ dwarf_highpc(Dwarf_Die die, */ static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die, - Dwarf_Half attr, - Dwarf_Unsigned * return_val, - Dwarf_Error * error) + Dwarf_Half attr, + Dwarf_Unsigned * return_val, + Dwarf_Error * error) { Dwarf_Byte_Ptr info_ptr; Dwarf_Half attr_form; Dwarf_Unsigned ret_value; Dwarf_Debug dbg; - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - dbg = die->di_cu_context->cc_dbg; + dbg = die->di_cu_context->cc_dbg; info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); if (info_ptr != NULL) { - switch (attr_form) { - - case DW_FORM_data1: - *return_val = (*(Dwarf_Small *) info_ptr); - return (DW_DLV_OK); - - case DW_FORM_data2: - READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_Shalf)); - *return_val = ret_value; - return (DW_DLV_OK); - - case DW_FORM_data4: - READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_sfixed)); - *return_val = ret_value; - return (DW_DLV_OK); - - case DW_FORM_data8: - READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_Unsigned)); - *return_val = ret_value; - return (DW_DLV_OK); - - case DW_FORM_udata: - *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL)); - return (DW_DLV_OK); - - default: - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); - } + switch (attr_form) { + + case DW_FORM_data1: + *return_val = (*(Dwarf_Small *) info_ptr); + return (DW_DLV_OK); + + case DW_FORM_data2: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Shalf)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_data4: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_sfixed)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_data8: + READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Unsigned)); + *return_val = ret_value; + return (DW_DLV_OK); + + case DW_FORM_udata: + *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL)); + return (DW_DLV_OK); + + default: + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); + } } if (attr_form == 0) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return (DW_DLV_ERROR); } return DW_DLV_NO_ENTRY; } @@ -510,12 +569,11 @@ _dwarf_die_attr_unsigned_constant(Dwarf_Die die, int dwarf_bytesize(Dwarf_Die die, - Dwarf_Unsigned * ret_size, Dwarf_Error * error) + Dwarf_Unsigned * ret_size, Dwarf_Error * error) { - Dwarf_Unsigned luns; - int res = - _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, - error); + Dwarf_Unsigned luns = 0; + int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, + &luns, error); *ret_size = luns; return res; } @@ -523,14 +581,11 @@ dwarf_bytesize(Dwarf_Die die, int dwarf_bitsize(Dwarf_Die die, - Dwarf_Unsigned * ret_size, Dwarf_Error * error) + Dwarf_Unsigned * ret_size, Dwarf_Error * error) { - Dwarf_Unsigned luns; - int res; - - res = - _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns, - error); + Dwarf_Unsigned luns = 0; + int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, + &luns, error); *ret_size = luns; return res; } @@ -538,14 +593,11 @@ dwarf_bitsize(Dwarf_Die die, int dwarf_bitoffset(Dwarf_Die die, - Dwarf_Unsigned * ret_size, Dwarf_Error * error) + Dwarf_Unsigned * ret_size, Dwarf_Error * error) { - Dwarf_Unsigned luns; - int res; - - res = - _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns, - error); + Dwarf_Unsigned luns = 0; + int res = _dwarf_die_attr_unsigned_constant(die, + DW_AT_bit_offset, &luns, error); *ret_size = luns; return res; } @@ -554,14 +606,11 @@ dwarf_bitoffset(Dwarf_Die die, /* Refer section 3.1, page 21 in Dwarf Definition. */ int dwarf_srclang(Dwarf_Die die, - Dwarf_Unsigned * ret_size, Dwarf_Error * error) + Dwarf_Unsigned * ret_size, Dwarf_Error * error) { - Dwarf_Unsigned luns; - int res; - - res = - _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, - error); + Dwarf_Unsigned luns = 0; + int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language, + &luns, error); *ret_size = luns; return res; } @@ -570,40 +619,171 @@ dwarf_srclang(Dwarf_Die die, /* Refer section 5.4, page 37 in Dwarf Definition. */ int dwarf_arrayorder(Dwarf_Die die, - Dwarf_Unsigned * ret_size, Dwarf_Error * error) + Dwarf_Unsigned * ret_size, Dwarf_Error * error) { - Dwarf_Unsigned luns; - int res; - - res = - _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns, - error); + Dwarf_Unsigned luns = 0; + int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, + &luns, error); *ret_size = luns; return res; } /* - Return DW_DLV_OK if ok - DW_DLV_ERROR if failure. + Return DW_DLV_OK if ok + DW_DLV_ERROR if failure. - If the die and the attr are not related the result is - meaningless. + If the die and the attr are not related the result is + meaningless. */ int -dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset, /* return - offset - thru - this - ptr - */ - Dwarf_Error * error) +dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, + Dwarf_Off * offset /* return offset thru this ptr */, + Dwarf_Error * error) { - Dwarf_Off attroff; + Dwarf_Off attroff = 0; - CHECK_DIE(die, DW_DLV_ERROR) + CHECK_DIE(die, DW_DLV_ERROR); - attroff = (attr->ar_debug_info_ptr - - die->di_cu_context->cc_dbg->de_debug_info); + attroff = (attr->ar_debug_info_ptr - + die->di_cu_context->cc_dbg->de_debug_info.dss_data); *offset = attroff; return DW_DLV_OK; } + +int +dwarf_die_abbrev_code(Dwarf_Die die) +{ + return die->di_abbrev_code; +} + +/* Helper function for finding form class. */ +static enum Dwarf_Form_Class +dw_get_special_offset(Dwarf_Half attrnum) +{ + switch(attrnum) { + case DW_AT_stmt_list: + return DW_FORM_CLASS_LINEPTR; + case DW_AT_macro_info: + return DW_FORM_CLASS_MACPTR; + case DW_AT_ranges: + return DW_FORM_CLASS_RANGELISTPTR; + 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: + return DW_FORM_CLASS_LOCLISTPTR; + case DW_AT_sibling: + case DW_AT_byte_size : + case DW_AT_bit_offset : + case DW_AT_bit_size : + case DW_AT_discr : + case DW_AT_import : + case DW_AT_common_reference: + case DW_AT_containing_type: + case DW_AT_default_value: + case DW_AT_lower_bound: + case DW_AT_bit_stride: + case DW_AT_upper_bound: + case DW_AT_abstract_origin: + case DW_AT_base_types: + case DW_AT_count: + case DW_AT_friend: + case DW_AT_namelist_item: + case DW_AT_priority: + case DW_AT_specification: + case DW_AT_type: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_byte_stride: + case DW_AT_extension: + case DW_AT_trampoline: + case DW_AT_small: + case DW_AT_object_pointer: + case DW_AT_signature: + return DW_FORM_CLASS_REFERENCE; + case DW_AT_MIPS_fde: /* SGI/IRIX extension */ + return DW_FORM_CLASS_FRAMEPTR; + } + return DW_FORM_CLASS_UNKNOWN; +} + +/* It takes 4 pieces of data (including the FORM) + to accurately determine the form 'class' as documented + in the DWARF spec. This is per DWARF4, but will work + for DWARF2 or 3 as well. */ +enum Dwarf_Form_Class dwarf_get_form_class( + Dwarf_Half dwversion, + Dwarf_Half attrnum, + Dwarf_Half offset_size, + Dwarf_Half form) +{ + switch(form) { + case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS; + + case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT; + + case DW_FORM_data4: + if(dwversion <= 3 && offset_size == 4) { + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + if(class != DW_FORM_CLASS_UNKNOWN) { + return class; + } + } + return DW_FORM_CLASS_CONSTANT; + case DW_FORM_data8: + if(dwversion <= 3 && offset_size == 8) { + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + if(class != DW_FORM_CLASS_UNKNOWN) { + return class; + } + } + return DW_FORM_CLASS_CONSTANT; + + case DW_FORM_sec_offset: + { + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + if(class != DW_FORM_CLASS_UNKNOWN) { + return class; + } + } + /* We do not know what this is. */ + break; + + case DW_FORM_string: return DW_FORM_CLASS_STRING; + case DW_FORM_strp: return DW_FORM_CLASS_STRING; + + case DW_FORM_block: return DW_FORM_CLASS_BLOCK; + case DW_FORM_block1: return DW_FORM_CLASS_BLOCK; + case DW_FORM_block2: return DW_FORM_CLASS_BLOCK; + case DW_FORM_block4: return DW_FORM_CLASS_BLOCK; + + case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT; + case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT; + case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT; + + case DW_FORM_ref_addr: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref1: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref2: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref4: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref8: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref_udata: return DW_FORM_CLASS_REFERENCE; + case DW_FORM_ref_sig8: return DW_FORM_CLASS_REFERENCE; + + case DW_FORM_exprloc: return DW_FORM_CLASS_EXPRLOC; + + case DW_FORM_flag: return DW_FORM_CLASS_FLAG; + case DW_FORM_flag_present: return DW_FORM_CLASS_FLAG; + + + case DW_FORM_indirect: + default: + break; + }; + return DW_FORM_CLASS_UNKNOWN; +} + |