#include "config.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "dwarf_incl.h"
#include "dwarf_alloc.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#include "dwarf_xu_index.h"
#include "dwarfstring.h"
#define HASHSIGNATURELEN 8
#define LEN32BIT 4
#define TRUE 1
#define FALSE 0
#ifdef WORDS_BIGENDIAN
#define ASNAR(t,s,l) \
do { \
unsigned tbyte = sizeof(t) - l; \
if (sizeof(t) < l) { \
_dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \
return DW_DLV_ERROR; \
} \
t = 0; \
dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\
} while (0)
#else
#define ASNAR(t,s,l) \
do { \
t = 0; \
if (sizeof(t) < l) { \
_dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \
return DW_DLV_ERROR; \
} \
dbg->de_copy_word(&t,&s[0],l); \
} while (0)
#endif
static const Dwarf_Sig8 zerohashkey;
#if 0
static void
dump_bytes(char * msg,Dwarf_Small * start, long len)
{
Dwarf_Small *end = start + len;
Dwarf_Small *cur = start;
printf("%s ",msg);
for (; cur < end; cur++) {
printf("%02x ", *cur);
}
printf("\n");
}
#endif
static int
fill_in_offsets_headerline(Dwarf_Debug dbg,
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned headerline_offset,
Dwarf_Unsigned num_sects,
Dwarf_Error *err)
{
Dwarf_Small *section_start = xuhdr->gx_section_data;
Dwarf_Small *section_end = xuhdr->gx_section_data+
xuhdr->gx_section_length;
Dwarf_Small *data = 0;
unsigned i = 0;
data = section_start +headerline_offset;
for( ; i < num_sects ; ++i) {
Dwarf_Unsigned v = 0;
READ_UNALIGNED_CK(dbg,v, Dwarf_Unsigned,
data,LEN32BIT,
err,section_end);
data += LEN32BIT;
if (v > DW_SECT_RNGLISTS) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR The "
"section number of %u ",v);
dwarfstring_append(&s," is too high. "
"There sections 1-8 are listed in "
"DWARF5 table 7.1.");
_dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
xuhdr->gx_section_id[i] = v;
}
return DW_DLV_OK;
}
int
dwarf_get_xu_index_header(Dwarf_Debug dbg,
const char * section_type,
Dwarf_Xu_Index_Header * xuptr,
Dwarf_Unsigned * version,
Dwarf_Unsigned * number_of_columns,
Dwarf_Unsigned * number_of_CUs,
Dwarf_Unsigned * number_of_slots,
const char ** section_name,
Dwarf_Error * error)
{
Dwarf_Xu_Index_Header indexptr = 0;
int res = DW_DLV_ERROR;
struct Dwarf_Section_s *sect = 0;
Dwarf_Unsigned local_version = 0;
Dwarf_Unsigned num_secs = 0;
Dwarf_Unsigned num_CUs = 0;
Dwarf_Unsigned num_slots = 0;
Dwarf_Small *data = 0;
Dwarf_Unsigned tables_end_offset = 0;
Dwarf_Unsigned hash_tab_offset = 0;
Dwarf_Unsigned indexes_tab_offset = 0;
Dwarf_Unsigned section_offsets_tab_offset = 0;
Dwarf_Unsigned section_offsets_headerline_offset = 0;
Dwarf_Unsigned section_sizes_tab_offset = 0;
unsigned datalen32 = LEN32BIT;
Dwarf_Small *section_end = 0;
if (!strcmp(section_type,"cu") ) {
sect = &dbg->de_debug_cu_index;
} else if (!strcmp(section_type,"tu") ) {
sect = &dbg->de_debug_tu_index;
} else {
_dwarf_error(dbg, error, DW_DLE_XU_TYPE_ARG_ERROR);
return DW_DLV_ERROR;
}
if (!sect->dss_size) {
return DW_DLV_NO_ENTRY;
}
if (!sect->dss_data) {
res = _dwarf_load_section(dbg, sect,error);
if (res != DW_DLV_OK) {
return res;
}
}
data = sect->dss_data;
section_end = data + sect->dss_size;
if (sect->dss_size < (4*datalen32) ) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
"The size of the %s ",(char *)section_type);
dwarfstring_append_printf_u(&m,
" is just %u bytes, much to small to be "
" a correct section",sect->dss_size);
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
READ_UNALIGNED_CK(dbg,local_version, Dwarf_Unsigned,
data,datalen32,
error,section_end);
data += datalen32;
READ_UNALIGNED_CK(dbg,num_secs, Dwarf_Unsigned,
data,datalen32,
error,section_end);
data += datalen32;
READ_UNALIGNED_CK(dbg,num_CUs, Dwarf_Unsigned,
data,datalen32,
error,section_end);
data += datalen32;
READ_UNALIGNED_CK(dbg,num_slots, Dwarf_Unsigned,
data,datalen32,
error,section_end);
hash_tab_offset = datalen32*4;
indexes_tab_offset = hash_tab_offset +
(num_slots * HASHSIGNATURELEN);
if (num_slots > sect->dss_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
"The size of the %s ",(char *)section_type);
dwarfstring_append_printf_u(&m,
" is just %u bytes,",sect->dss_size);
dwarfstring_append_printf_u(&m,
"while the number of slots (S) is %u. "
"which is clearly wrong",num_slots );
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
if ( (4*num_slots) > sect->dss_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
"The size of the %s ",(char *)section_type);
dwarfstring_append_printf_u(&m,
" is just %u bytes,",sect->dss_size);
dwarfstring_append_printf_u(&m,
"while the number of slots bytes (S) is at least %u. "
"which is clearly wrong",num_slots*4);
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
section_offsets_headerline_offset = indexes_tab_offset +
(num_slots *datalen32);
section_offsets_tab_offset = section_offsets_headerline_offset
+ (num_secs*datalen32);
if ( num_secs > sect->dss_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
"The size of the %s ",(char *)section_type);
dwarfstring_append_printf_u(&m,
" is just %u bytes,",sect->dss_size);
dwarfstring_append_printf_u(&m,
"while the number of sections/columns (S) is %u. "
"which is clearly wrong",num_secs );
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
if ( (datalen32*num_secs) > sect->dss_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_s(&m,
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION: "
"The size of the %s ",(char *)section_type);
dwarfstring_append_printf_u(&m,
" is just %u bytes,",sect->dss_size);
dwarfstring_append_printf_u(&m,
"while the number of sections/columns bytes (S)"
" is at least %u. "
"which is clearly wrong",num_secs*4);
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
section_sizes_tab_offset = section_offsets_tab_offset +
(num_CUs *num_secs* datalen32) ;
tables_end_offset = section_sizes_tab_offset +
(num_CUs * num_secs * datalen32);
if ( tables_end_offset > sect->dss_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,"ERROR: "
"DW_DLE_ERRONEOUS_XU_INDEX_SECTION as the end offset "
"0x%lx is greater than ",tables_end_offset);
dwarfstring_append_printf_u(&m,"the section size "
"0x%lx.",sect->dss_size);
_dwarf_error_string(dbg, error,
DW_DLE_ERRONEOUS_XU_INDEX_SECTION,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
indexptr = (Dwarf_Xu_Index_Header)
_dwarf_get_alloc(dbg,DW_DLA_XU_INDEX,1);
if (indexptr == NULL) {
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (DW_DLV_ERROR);
}
indexptr->gx_type[0] = section_type[0];
indexptr->gx_type[1] = section_type[1];
indexptr->gx_type[2] = 0;
indexptr->gx_dbg = dbg;
indexptr->gx_section_length = sect->dss_size;
indexptr->gx_section_data = sect->dss_data;
indexptr->gx_section_name = sect->dss_name;
indexptr->gx_version = local_version;
indexptr->gx_column_count_sections = num_secs;
indexptr->gx_units_in_index = num_CUs;
indexptr->gx_slots_in_hash = num_slots;
indexptr->gx_hash_table_offset = hash_tab_offset;
indexptr->gx_index_table_offset = indexes_tab_offset;
indexptr->gx_section_offsets_headerline_offset=
section_offsets_headerline_offset;
indexptr->gx_section_offsets_offset= section_offsets_tab_offset;
indexptr->gx_section_sizes_offset = section_sizes_tab_offset;
res = fill_in_offsets_headerline(dbg,indexptr,
section_offsets_headerline_offset,
num_secs,error);
if (res != DW_DLV_OK) {
return res;
}
*xuptr = indexptr;
*version = indexptr->gx_version;
*number_of_columns = indexptr->gx_column_count_sections;
*number_of_CUs = indexptr->gx_units_in_index;
*number_of_slots = indexptr->gx_slots_in_hash;
*section_name = indexptr->gx_section_name;
return DW_DLV_OK;
}
int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header xuhdr,
const char ** typename,
const char ** sectionname,
UNUSEDARG Dwarf_Error * err)
{
*typename = &xuhdr->gx_type[0];
*sectionname = xuhdr->gx_section_name;
return DW_DLV_OK;
}
int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned index,
Dwarf_Sig8 * hash_value,
Dwarf_Unsigned * index_to_sections,
Dwarf_Error * err)
{
Dwarf_Debug dbg = xuhdr->gx_dbg;
Dwarf_Small *hashtab = xuhdr->gx_section_data +
xuhdr->gx_hash_table_offset;
Dwarf_Small *indextab = xuhdr->gx_section_data +
xuhdr->gx_index_table_offset;
Dwarf_Small *indexentry = 0;
Dwarf_Small *hashentry = 0;
Dwarf_Sig8 hashval;
Dwarf_Unsigned indexval = 0;
Dwarf_Small *section_end = xuhdr->gx_section_data +
xuhdr->gx_section_length;
hashval = zerohashkey;
if (xuhdr->gx_slots_in_hash > 0) {
if (index >= xuhdr->gx_slots_in_hash) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_XU_HASH_ROW_ERROR the index passed in, "
" %u, is greater than the number of slots "
" in the hash table.",index);
_dwarf_error_string(dbg, err, DW_DLE_XU_HASH_ROW_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
hashentry = hashtab + (index * HASHSIGNATURELEN);
memcpy(&hashval,hashentry,sizeof(hashval));
} else {
_dwarf_error_string(dbg, err, DW_DLE_XU_HASH_ROW_ERROR,
"DW_DLE_XU_HASH_ROW_ERROR the number of slots is zero"
" which seems wrong.");
return DW_DLV_ERROR;
}
indexentry = indextab + (index * LEN32BIT);
memcpy(hash_value,&hashval,sizeof(hashval));
READ_UNALIGNED_CK(dbg,indexval,Dwarf_Unsigned, indexentry,
LEN32BIT,
err,section_end);
indexentry += LEN32BIT;
if (indexval > xuhdr->gx_units_in_index) {
_dwarf_error(dbg, err, DW_DLE_XU_HASH_INDEX_ERROR);
return DW_DLV_ERROR;
}
*index_to_sections = indexval;
return DW_DLV_OK;
}
static const char * dwp_secnames[] = {
"No name for zero",
"DW_SECT_INFO" ,
"DW_SECT_TYPES" ,
"DW_SECT_ABBREV" ,
"DW_SECT_LINE" ,
"DW_SECT_LOC" ,
"DW_SECT_STR_OFFSETS" ,
"DW_SECT_MACRO" ,
"DW_SECT_RNGLISTS" ,
"No name > 8",
};
int
dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned column_index,
Dwarf_Unsigned* number,
const char ** name,
Dwarf_Error * err)
{
Dwarf_Unsigned sec_num = 0;
Dwarf_Debug dbg = xuhdr->gx_dbg;
if( column_index >= xuhdr->gx_column_count_sections) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
"column index of %u ",column_index);
dwarfstring_append_printf_u(&s," is too high. "
"There are %u sections.",
xuhdr->gx_column_count_sections);
_dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
sec_num = xuhdr->gx_section_id[column_index];
if (sec_num < 1) {
return DW_DLV_NO_ENTRY;
}
*number = sec_num;
*name = dwp_secnames[sec_num];
return DW_DLV_OK;
}
int
dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned irow_index,
Dwarf_Unsigned column_index,
Dwarf_Unsigned* sec_offset,
Dwarf_Unsigned* sec_size,
Dwarf_Error * err)
{
Dwarf_Debug dbg = xuhdr->gx_dbg;
Dwarf_Small *offsetrow = xuhdr->gx_section_offsets_offset +
xuhdr->gx_section_data;
Dwarf_Small *sizerow = xuhdr->gx_section_sizes_offset +
xuhdr->gx_section_data;
Dwarf_Small *offsetentry = 0;
Dwarf_Small *sizeentry = 0;
Dwarf_Unsigned offset = 0;
Dwarf_Unsigned size = 0;
Dwarf_Unsigned column_count = xuhdr->gx_column_count_sections;
Dwarf_Small *section_end = xuhdr->gx_section_data +
xuhdr->gx_section_length;
Dwarf_Unsigned row_index = irow_index-1;
if(!irow_index) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append(&s,
"ERROR: DW_DLE_ERRONEOUS_XU_INDEX_SECTION "
"The row index passed to dwarf_get_xu_section_offset() "
"is zero, which is not a valid row in "
" the offset-table or the size table as we think"
" of them as 1-origin.");
_dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
if( row_index >= xuhdr->gx_units_in_index) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
"row index of %u ",row_index);
dwarfstring_append_printf_u(&s," is too high. "
"Valid units must be < %u ",xuhdr->gx_units_in_index);
_dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
if( column_index >= xuhdr->gx_column_count_sections) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
"column index of %u ",column_index);
dwarfstring_append_printf_u(&s," is too high. "
"Valid column indexes must be < %u ",
xuhdr->gx_column_count_sections);
_dwarf_error_string(dbg, err, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
offsetrow = offsetrow + (row_index*column_count * LEN32BIT);
offsetentry = offsetrow + (column_index * LEN32BIT);
sizerow = sizerow + (row_index*column_count * LEN32BIT);
sizeentry = sizerow + (column_index * LEN32BIT);
{
READ_UNALIGNED_CK(dbg,offset,Dwarf_Unsigned,
offsetentry,
LEN32BIT,err,section_end);
offsetentry += LEN32BIT;
READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,
sizeentry,
LEN32BIT,err,section_end);
sizeentry += LEN32BIT;
}
*sec_offset = offset;
*sec_size = size;
return DW_DLV_OK;
}
static int
_dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg,
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Sig8 *key_in,
Dwarf_Unsigned * percu_index_out,
Dwarf_Error *error)
{
Dwarf_Unsigned key = 0;
Dwarf_Unsigned primary_hash = 0;
Dwarf_Unsigned hashprime = 0;
Dwarf_Unsigned slots = xuhdr->gx_slots_in_hash;
Dwarf_Unsigned mask = slots -1;
Dwarf_Sig8 hashentry_key;
Dwarf_Unsigned percu_index = 0;
hashentry_key = zerohashkey;
if (slots > xuhdr->gx_section_length) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
"slots count of %u ",slots);
dwarfstring_append_printf_u(&s," is too high. "
"given the section length of %u\n",
xuhdr->gx_section_length);
_dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
if ( (4*slots) > xuhdr->gx_section_length) {
dwarfstring s;
dwarfstring_constructor(&s);
dwarfstring_append_printf_u(&s,
"ERROR: DW_DLE_XU_NAME_COL_ERROR as the "
"slots count *4 of %u ",slots*4);
dwarfstring_append_printf_u(&s," is too high. "
"given the section length of %u\n",
xuhdr->gx_section_length);
_dwarf_error_string(dbg, error, DW_DLE_XU_NAME_COL_ERROR,
dwarfstring_string(&s));
dwarfstring_destructor(&s);
return DW_DLV_ERROR;
}
if (sizeof (key) != sizeof(key_in)) {
_dwarf_error(dbg, error, DW_DLE_XU_HASH_ROW_ERROR);
}
ASNAR(key,key_in,sizeof(*key_in));
primary_hash = key & mask;
hashprime = (((key >>32) &mask) |1);
while (1) {
int res = 0;
res = dwarf_get_xu_hash_entry(xuhdr,
primary_hash,&hashentry_key,
&percu_index,error);
if (res != DW_DLV_OK) {
return res;
}
if (percu_index == 0 &&
!memcmp(&hashentry_key,&zerohashkey,sizeof(Dwarf_Sig8))) {
return DW_DLV_NO_ENTRY;
}
if (!memcmp(key_in,&hashentry_key,sizeof(Dwarf_Sig8))) {
*percu_index_out = percu_index;
return DW_DLV_OK;
}
primary_hash = (primary_hash + hashprime) % slots;
}
return DW_DLV_NO_ENTRY;
}
static int
_dwarf_search_fission_for_offset(Dwarf_Debug dbg,
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned offset,
Dwarf_Unsigned dfp_sect_num,
Dwarf_Unsigned * percu_index_out,
Dwarf_Sig8 * key_out,
Dwarf_Error *error)
{
Dwarf_Unsigned i = 0;
Dwarf_Unsigned m = 0;
int secnum_index = -1;
int res = 0;
for ( i = 0; i< xuhdr->gx_column_count_sections; i++) {
const char *name = 0;
Dwarf_Unsigned num = 0;
res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error);
if (res != DW_DLV_OK) {
return res;
}
if (num == dfp_sect_num) {
secnum_index = i;
break;
}
}
if (secnum_index == -1) {
_dwarf_error(dbg,error,DW_DLE_FISSION_SECNUM_ERR);
return DW_DLV_ERROR;
}
for ( m = 0; m < xuhdr->gx_slots_in_hash; ++m) {
Dwarf_Sig8 hash;
Dwarf_Unsigned indexn = 0;
Dwarf_Unsigned sec_offset = 0;
Dwarf_Unsigned sec_size = 0;
res = dwarf_get_xu_hash_entry(xuhdr,m,&hash,&indexn,error);
if (res != DW_DLV_OK) {
return res;
}
if (indexn == 0 &&
!memcmp(&hash,&zerohashkey,sizeof(Dwarf_Sig8))) {
continue;
}
res = dwarf_get_xu_section_offset(xuhdr,
indexn,secnum_index,&sec_offset,&sec_size,error);
if (res != DW_DLV_OK) {
return res;
}
if (sec_offset != offset) {
continue;
}
*percu_index_out = indexn;
*key_out = hash;
return DW_DLV_OK;
}
return DW_DLV_NO_ENTRY;
}
static int
_dwarf_get_xuhdr(Dwarf_Debug dbg,
const char *sigtype,
Dwarf_Xu_Index_Header *xuout,
Dwarf_Error *error)
{
if (!strcmp(sigtype,"tu")) {
if (!dbg->de_tu_hashindex_data) {
return DW_DLV_NO_ENTRY;
}
*xuout = dbg->de_tu_hashindex_data;
} else if (!strcmp(sigtype,"cu")) {
if (!dbg->de_cu_hashindex_data) {
return DW_DLV_NO_ENTRY;
}
*xuout = dbg->de_cu_hashindex_data;
} else {
_dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING);
return DW_DLV_ERROR;
}
return DW_DLV_OK;
}
static int
transform_xu_to_dfp(Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned percu_index,
Dwarf_Sig8 *key,
const char *sig_type,
Dwarf_Debug_Fission_Per_CU * percu_out,
Dwarf_Error *error)
{
unsigned i = 0;
unsigned l = 0;
unsigned n = 1;
unsigned max_cols = xuhdr->gx_column_count_sections;
unsigned secnums[DW_FISSION_SECT_COUNT];
int res;
for ( i = 0; i< max_cols; i++) {
const char *name = 0;
Dwarf_Unsigned num = 0;
res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error);
if (res != DW_DLV_OK) {
return res;
}
secnums[i] = num;
}
n = percu_index;
for(l = 0; l < max_cols; ++l) {
Dwarf_Unsigned sec_off = 0;
Dwarf_Unsigned sec_size = 0;
unsigned l_as_sect = secnums[l];
res = dwarf_get_xu_section_offset(xuhdr,n,l,
&sec_off,&sec_size,error);
if (res != DW_DLV_OK) {
return res;
}
percu_out->pcu_offset[l_as_sect] = sec_off;
percu_out->pcu_size[l_as_sect] = sec_size;
}
percu_out->pcu_type = sig_type;
percu_out->pcu_index = percu_index;
percu_out->pcu_hash = *key;
return DW_DLV_OK;
}
int
_dwarf_get_debugfission_for_offset(Dwarf_Debug dbg,
Dwarf_Off offset_wanted,
const char * key_type,
struct Dwarf_Debug_Fission_Per_CU_s * percu_out,
Dwarf_Error *error)
{
Dwarf_Xu_Index_Header xuhdr = 0;
int sres = 0;
Dwarf_Unsigned percu_index = 0;
Dwarf_Unsigned sect_index_base = 0;
Dwarf_Sig8 key;
sect_index_base = DW_SECT_INFO;
key = zerohashkey;
sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error);
if (sres != DW_DLV_OK) {
return sres;
}
sres = _dwarf_search_fission_for_offset(dbg,
xuhdr,offset_wanted, sect_index_base, &percu_index,
&key,
error);
if (sres != DW_DLV_OK) {
return sres;
}
sres = transform_xu_to_dfp(xuhdr,percu_index,&key,
key_type,percu_out, error);
return sres;
}
int
dwarf_get_debugfission_for_key(Dwarf_Debug dbg,
Dwarf_Sig8 * key ,
const char * key_type ,
Dwarf_Debug_Fission_Per_CU * percu_out,
Dwarf_Error * error )
{
int sres = 0;
Dwarf_Unsigned percu_index = 0;
Dwarf_Xu_Index_Header xuhdr = 0;
sres = _dwarf_load_debug_info(dbg,error);
if (sres == DW_DLV_ERROR) {
return sres;
}
sres = _dwarf_load_debug_types(dbg,error);
if (sres == DW_DLV_ERROR) {
return sres;
}
sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error);
if (sres != DW_DLV_OK) {
return sres;
}
sres = _dwarf_search_fission_for_key(dbg,
xuhdr,key,&percu_index,error);
if (sres != DW_DLV_OK) {
return sres;
}
sres = transform_xu_to_dfp(xuhdr,percu_index,key,
key_type,percu_out,error);
return sres;
}
void
dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr)
{
if(indexptr) {
Dwarf_Debug dbg = indexptr->gx_dbg;
dwarf_dealloc(dbg,indexptr,DW_DLA_XU_INDEX);
}
}