/* This function takes an Dwarf_Arange, and returns the offset of the CU header in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. */ int dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, Dwarf_Off * cu_header_offset_returned, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } *cu_header_offset_returned = arange->ar_info_offset; return DW_DLV_OK; }
/* Given a pubnames entry (or other like section entry) return thru the ret_off pointer the global offset of the DIE for this entry. The global offset is the offset within the .debug_info section as a whole. */ int dwarf_global_die_offset ( Dwarf_Global global, Dwarf_Off *ret_off, Dwarf_Error *error ) { if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return(DW_DLV_ERROR); } if (global->gl_context == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return(DW_DLV_ERROR); } *ret_off = (global->gl_named_die_offset_within_cu + global->gl_context->pu_offset_of_cu_header); return DW_DLV_OK; }
int dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; if (weak == NULL) { _dwarf_error(NULL, error, DW_DLE_WEAK_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (weak->gl_name); return DW_DLV_OK; }
/* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be over 16 bits. */ int dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half * returned_tag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_tag = abbrev->ab_tag; return (DW_DLV_OK); }
int dwarf_formflag(Dwarf_Attribute attr, Dwarf_Bool* ret_bool, Dwarf_Error * error) { Dwarf_CU_Context cu_context; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return (DW_DLV_ERROR); } cu_context = attr->ar_cu_context; if (cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } if (cu_context->cc_dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } if (attr->ar_attribute_form == DW_FORM_flag) { *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0); return (DW_DLV_OK); } /* * DWARF4: the attribute is implicitly indicated as present, and no value is * encoded in the debugging information entry itself. */ if (attr->ar_attribute_form == DW_FORM_flag_present) { *ret_bool = 1; return (DW_DLV_OK); } _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); }
/* Read in the common cie/fde prefix, including reading * the cie-value which shows which this is: cie or fde. * */ int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, Dwarf_Small * frame_ptr_in, Dwarf_Small * section_ptr_in, Dwarf_Unsigned section_index_in, Dwarf_Unsigned section_length_in, struct cie_fde_prefix_s *data_out, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Small *frame_ptr = frame_ptr_in; Dwarf_Small *cie_ptr_addr = 0; Dwarf_Unsigned cie_id = 0; /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, frame_ptr, local_length_size, local_extension_size); if (length % local_length_size != 0) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return (DW_DLV_ERROR); } if (length == 0) { /* nul bytes at end of section, seen at end of egcs eh_frame sections (in a.out). Take this as meaning no more CIE/FDE data. We should be very close to end of section. */ return DW_DLV_NO_ENTRY; } cie_ptr_addr = frame_ptr; READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned, frame_ptr, local_length_size); SIGN_EXTEND(cie_id, local_length_size); frame_ptr += local_length_size; data_out->cf_start_addr = frame_ptr_in; data_out->cf_addr_after_prefix = frame_ptr; data_out->cf_length = length; data_out->cf_local_length_size = local_length_size; data_out->cf_local_extension_size = local_extension_size; data_out->cf_cie_id = cie_id; data_out->cf_cie_id_addr = cie_ptr_addr; data_out->cf_section_ptr = section_ptr_in; data_out->cf_section_index = section_index_in; data_out->cf_section_length = section_length_in; return DW_DLV_OK; }
int dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned * returned_code, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_code = abbrev->ab_code; return (DW_DLV_OK); }
int dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; if (func == NULL) { _dwarf_error(NULL, error, DW_DLE_FUNC_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (func->gl_name); return DW_DLV_OK; }
int dwarf_formexprloc(Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } if (attr->ar_attribute_form == DW_FORM_exprloc ) { Dwarf_Die die = 0; Dwarf_Word leb_len = 0; Dwarf_Unsigned exprlen = (_dwarf_decode_u_leb128(attr->ar_debug_ptr, &leb_len)); Dwarf_Small * addr = attr->ar_debug_ptr; /* Is the block entirely in the section, or is there bug somewhere? */ die = attr->ar_die; if (_dwarf_reference_outside_section(die, (Dwarf_Small *)addr, ((Dwarf_Small *)addr)+exprlen +leb_len)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } *return_exprlen = exprlen; *block_ptr = addr + leb_len; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD); return (DW_DLV_ERROR); }
/* Given a pubnames entry (or other like section entry) return thru the ret_name pointer a pointer to the string which is the entry name. */ int dwarf_globname ( Dwarf_Global glob, char ** ret_name, Dwarf_Error *error ) { if (glob == NULL) {_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return(DW_DLV_ERROR);} *ret_name = (char *)(glob->gl_name); return DW_DLV_OK; }
int dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed * returned_flag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_flag = abbrev->ab_has_child; return (DW_DLV_OK); }
int dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; if (type == NULL) { _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (type->gl_name); return DW_DLV_OK; }
int dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; if (var == NULL) { _dwarf_error(NULL, error, DW_DLE_VAR_NULL); return (DW_DLV_ERROR); } *ret_varname = (char *) (var->gl_name); return DW_DLV_OK; }
int dwarf_formexprloc(Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return (DW_DLV_ERROR); } cu_context = attr->ar_cu_context; if (cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } dbg = cu_context->cc_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } if (attr->ar_attribute_form == DW_FORM_udata ) { Dwarf_Unsigned exprlen = (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL)); Dwarf_Small * addr = attr->ar_debug_info_ptr; *return_exprlen = exprlen; *block_ptr = addr + exprlen; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD); return (DW_DLV_ERROR); }
static int _dwarf_formsig8_internal(Dwarf_Attribute attr, int formexpected, int formerrnum, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned field_end_offset = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Small *dataptr = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (attr->ar_attribute_form != formexpected ) { _dwarf_error(dbg, error, formerrnum); return (DW_DLV_ERROR); } dataptr = cu_context->cc_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; field_end_offset = attr->ar_debug_ptr + sizeof(Dwarf_Sig8) - (dataptr + cu_context->cc_debug_offset); /* Check that offset is within current cu portion of .debug_info. */ if (field_end_offset > cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); return (DW_DLV_ERROR); } memcpy(returned_sig_bytes, attr->ar_debug_ptr, sizeof(Dwarf_Sig8)); return DW_DLV_OK; }
int dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed * returned_str_len, Dwarf_Error * error) { int res = DW_DLV_ERROR; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } if (offset == dbg->de_debug_str.dss_size) { /* Normal (if we've iterated thru the set of strings using dwarf_get_str and are at the end). */ return DW_DLV_NO_ENTRY; } if (offset > dbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD); return (DW_DLV_ERROR); } if (string == NULL) { _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } *string = (char *) dbg->de_debug_str.dss_data + offset; *returned_str_len = (strlen(*string)); return DW_DLV_OK; }
int dwarf_lineoff(Dwarf_Line line, Dwarf_Signed * ret_lineoff, Dwarf_Error * error) { if (line == NULL || ret_lineoff == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *ret_lineoff = (line->li_addr_line.li_l_data.li_column == 0 ? -1 : line->li_addr_line.li_l_data.li_column); return DW_DLV_OK; }
int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *info_data_ptr, Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, Dwarf_Unsigned *str_sect_offset_out, Dwarf_Error *error) { Dwarf_Unsigned offsettostr= 0; Dwarf_Unsigned offset_base = 0; Dwarf_Word leb_len = 0; Dwarf_Unsigned index_to_offset_entry = 0; Dwarf_Unsigned offsetintable = 0; Dwarf_Unsigned end_offsetintable = 0; int res = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } index_to_offset_entry = (_dwarf_decode_u_leb128(info_data_ptr, &leb_len)); /* DW_FORM_GNU_str_index has no 'base' value. DW_FORM_strx has a base value for the offset table */ if( attrform == DW_FORM_strx) { res = _dwarf_get_string_base_attr_value(dbg,cu_context, &offset_base,error); if (res != DW_DLV_OK) { return res; } } offsetintable = (index_to_offset_entry*cu_context->cc_length_size ) + offset_base; end_offsetintable = offsetintable + cu_context->cc_length_size; /* The offsets table is a series of offset-size entries. */ if ((end_offsetintable) >= dbg->de_debug_str_offsets.dss_size ) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); return (DW_DLV_ERROR); } /* Now read the string offset from the offset table. */ READ_UNALIGNED(dbg,offsettostr,Dwarf_Unsigned, dbg->de_debug_str_offsets.dss_data + offsetintable, cu_context->cc_length_size); *str_sect_offset_out = offsettostr; return DW_DLV_OK; }
int dwarf_formaddr(Dwarf_Attribute attr, Dwarf_Addr * return_addr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Addr ret_addr = 0; Dwarf_CU_Context cu_context = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (attr->ar_attribute_form == DW_FORM_GNU_addr_index || attr->ar_attribute_form == DW_FORM_addrx) { Dwarf_Addr addr_out = 0; res = _dwarf_extract_address_from_debug_addr(dbg, cu_context, attr->ar_debug_ptr, &addr_out, error); if (res != DW_DLV_OK) { return res; } *return_addr = addr_out; return (DW_DLV_OK); } if (attr->ar_attribute_form == DW_FORM_addr /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of DW_FORM_ref_addr was a mistake. The value returned in that case is NOT an address it is a global debug_info offset (ie, not CU-relative offset within the CU in debug_info). The Dwarf document refers to it as an address (misleadingly) in sec 6.5.4 where it describes the reference form. It is address-sized so that the linker can easily update it, but it is a reference inside the debug_info section. No longer allowed. */ ) { READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, attr->ar_debug_ptr, cu_context->cc_address_size); *return_addr = ret_addr; return (DW_DLV_OK); } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); }
/* Convert an offset within the local CU into a section-relative debug_info (or debug_types) offset. See dwarf_global_formref() and dwarf_formref() for additional information on conversion rules. */ int dwarf_convert_to_global_offset(Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } switch (attr->ar_attribute_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: /* It is a cu-local offset. Convert to section-global. */ /* It would be nice to put some code to check legality of the offset */ /* cc_debug_offset always has any DWP Package File offset included (when the cu_context created) so there is no extra work for DWP. /* globalize the offset */ offset += cu_context->cc_debug_offset; break; case DW_FORM_ref_addr: /* This offset is defined to be debug_info global already, so use this value unaltered. Since a DWP package file is not relocated there is no way that this reference offset to an address in any other CU can be correct for a DWP Package File offset */ break; default: _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); return (DW_DLV_ERROR); } *ret_offset = (offset); return DW_DLV_OK; }
void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt) { if(dbgs == dbgt) { if(errs != errt) { Dwarf_Error ers = *errs; *errs = 0; *errt = ers; } } else { int errno = dwarf_errno(*errs); dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR); *errs = 0; _dwarf_error(dbgt,errt, errno); } }
/* Richard Henderson: The operand is an absolute address. The first byte of the value is an encoding length: 0 2 4 or 8. If zero it means the following is address-size. The address then follows immediately for that number of bytes. */ static int read_encoded_addr(Dwarf_Small *loc_ptr, Dwarf_Debug dbg, Dwarf_Unsigned * val_out, int * len_out, Dwarf_Error *error) { int totallen = 0; int oplen = 0; int len = 0; Dwarf_Small op = *loc_ptr; Dwarf_Unsigned operand = 0; len++; if(op == 0) { /* FIXME: should be CU specific. */ op = dbg->de_pointer_size; } switch(op) { case 1: *val_out = *loc_ptr; len++; break; case 2: READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 2); *val_out = operand; len +=2; break; case 4: READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 4); *val_out = operand; len +=4; break; case 8: READ_UNALIGNED(dbg, operand, Dwarf_Unsigned, loc_ptr, 8); *val_out = operand; len +=8; break; default: /* We do not know how much to read. */ _dwarf_error(dbg, error, DW_DLE_GNU_OPCODE_ERROR); return DW_DLV_ERROR; }; *len_out = len; return DW_DLV_OK; }
int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error* error) { if (loc_block->bl_from_loclist) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Small *end_ptr = 0; loc_ptr = loc_block->bl_data; loc_len = loc_block->bl_len; end_ptr = dbg->de_debug_loc.dss_size + dbg->de_debug_loc.dss_data; if ((loc_ptr +loc_len) > end_ptr) { _dwarf_error(dbg,error,DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } return DW_DLV_OK; }
/* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b(Dwarf_Arange arange, Dwarf_Unsigned* segment, Dwarf_Unsigned* segment_entry_size, Dwarf_Addr * start, Dwarf_Unsigned* length, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } if(segment != NULL) { *segment = arange->ar_segment_selector; } if(segment_entry_size != NULL) { *segment_entry_size = arange->ar_segment_selector_size; } if (start != NULL) *start = arange->ar_address; if (length != NULL) *length = arange->ar_length; if (cu_die_offset != NULL) { Dwarf_Debug dbg = arange->ar_dbg; Dwarf_Off offset = arange->ar_info_offset; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } *cu_die_offset = offset + _dwarf_length_of_cu_header(dbg, offset,true); } return (DW_DLV_OK); }
static int context_is_cu_not_tu(Dwarf_CU_Context context, Dwarf_Bool *r,Dwarf_Error *err) { Dwarf_Debug dbg = 0; if(context->cc_unit_type == DW_UT_type) { *r =FALSE; return DW_DLV_OK; } if(context->cc_unit_type == DW_UT_compile) { *r = TRUE; return DW_DLV_OK; } if(context->cc_unit_type == DW_UT_partial) { *r = TRUE; return DW_DLV_OK; } /* This should be impossible */ dbg = context->cc_dbg; _dwarf_error(dbg,err, DW_DLE_NO_TIED_FILE_AVAILABLE); return DW_DLV_ERROR; }
int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned index, Dwarf_Small * lle_value_out, /* identifies type of loclist entry*/ Dwarf_Addr * lowpc_out, Dwarf_Addr * hipc_out, Dwarf_Unsigned * loclist_count_out, /* Returns pointer to the specific locdesc of the index; */ Dwarf_Locdesc_c* locdesc_entry_out, Dwarf_Small * loclist_source_out, /* 0,1, or 2 */ Dwarf_Unsigned * expression_offset_out, Dwarf_Unsigned * locdesc_offset_out, Dwarf_Error * error) { Dwarf_Locdesc_c descs_base = 0; Dwarf_Locdesc_c desc = 0; Dwarf_Unsigned desc_count = 0; Dwarf_Debug dbg; desc_count = loclist_head->ll_locdesc_count; descs_base = loclist_head->ll_locdesc; dbg = loclist_head->ll_dbg; if (index >= desc_count) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR); return (DW_DLV_ERROR); } desc = descs_base + index; *lle_value_out = desc->ld_lle_value; *lowpc_out = desc->ld_lopc; *hipc_out = desc->ld_hipc; *loclist_count_out = desc->ld_cents; *locdesc_entry_out = desc; *loclist_source_out = desc->ld_from_loclist; *expression_offset_out = desc->ld_section_offset; *locdesc_offset_out = desc->ld_locdesc_offset; return DW_DLV_OK; }
/* Convert an offset within the local CU into a section-relative debug_info offset. See dwarf_global_formref() and dwarf_formref() for additional information on conversion rules. */ int dwarf_convert_to_global_offset(Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } switch (attr->ar_attribute_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: /* It would be nice to put some code to check legality of the offset */ /* globalize the offset */ offset += cu_context->cc_debug_offset; break; case DW_FORM_ref_addr: /* This offset is defined to be debug_info global already, so use this value unaltered. */ break; default: _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); return (DW_DLV_ERROR); } *ret_offset = (offset); return DW_DLV_OK; }
/* This function takes an Dwarf_Arange, and returns the offset of the first die in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. */ int dwarf_get_cu_die_offset(Dwarf_Arange arange, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Debug dbg; Dwarf_Off offset = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } dbg = arange->ar_dbg; offset = arange->ar_info_offset; if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset); return DW_DLV_OK; }
/* This function takes an Dwarf_Arange, and returns the offset of the CU header in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. Ensures .debug_info loaded so the cu_offset is meaningful. */ int dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, Dwarf_Off * cu_header_offset_returned, Dwarf_Error * error) { Dwarf_Debug dbg = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } dbg = arange->ar_dbg; /* This applies to debug_info only, not to debug_types. */ /* Like dwarf_get_arange_info this ensures debug_info loaded: the cu_header is in debug_info and will be used else we would not call dwarf_get_arange_cu_header_offset. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } *cu_header_offset_returned = arange->ar_info_offset; return DW_DLV_OK; }
int dwarf_formblock(Dwarf_Attribute attr, Dwarf_Block ** return_block, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; Dwarf_Unsigned length = 0; Dwarf_Small *data = 0; Dwarf_Word leb128_length = 0; Dwarf_Block *ret_block = 0; Dwarf_Small *dataptr = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } switch (attr->ar_attribute_form) { case DW_FORM_block1: length = *(Dwarf_Small *) attr->ar_debug_ptr; data = attr->ar_debug_ptr + sizeof(Dwarf_Small); break; case DW_FORM_block2: READ_UNALIGNED(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, sizeof(Dwarf_Half)); data = attr->ar_debug_ptr + sizeof(Dwarf_Half); break; case DW_FORM_block4: READ_UNALIGNED(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, sizeof(Dwarf_ufixed)); data = attr->ar_debug_ptr + sizeof(Dwarf_ufixed); break; case DW_FORM_block: length = _dwarf_decode_u_leb128(attr->ar_debug_ptr, &leb128_length); data = attr->ar_debug_ptr + leb128_length; break; default: _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } /* Check that block lies within current cu in .debug_info. */ dataptr = cu_context->cc_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; if (attr->ar_debug_ptr + length >= dataptr + cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); return (DW_DLV_ERROR); } ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); if (ret_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } ret_block->bl_len = length; ret_block->bl_data = (Dwarf_Ptr) data; ret_block->bl_from_loclist = 0; ret_block->bl_section_offset = data - dataptr; *return_block = ret_block; return (DW_DLV_OK); }