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; Dwarf_Unsigned strofflen = 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; { Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; fissoff = _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets, DW_SECT_STR_OFFSETS, &size); offsetintable += fissoff; } 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_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *info_data_ptr, UNUSEDARG 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) { /* DW_DLV_NO_ENTRY could be acceptable when a producer knows that the base offset will be zero. Hence DW_AT_str_offsets_base missing. DWARF5 draft as of September 2015 allows the attribute to be missing (it's up to the compilation tools to make sure that has the correct effect). */ return res; } } offsetintable = (index_to_offset_entry*cu_context->cc_length_size ) + offset_base; { Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; fissoff = _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets, DW_SECT_STR_OFFSETS, &size); offsetintable += fissoff; } end_offsetintable = offsetintable + cu_context->cc_length_size; /* The offsets table is a series of offset-size entries. The == case in the test applies when we are at the last table entry, so == is not an error, hence only test > */ 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; }