#include "config.h"
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif /* HAVE_MALLOC_H */
#include "dwarf_incl.h"
#include "dwarf_alloc.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#include "memcpy_swap.h"
#include "dwarf_harmless.h"
#ifdef HAVE_LIBELF_H
#include <libelf.h>
#else
#ifdef HAVE_LIBELF_LIBELF_H
#include <libelf/libelf.h>
#endif
#endif
#ifdef HAVE_ZLIB
#include "zlib.h"
#endif
#ifndef ELFCOMPRESS_ZLIB
#define ELFCOMPRESS_ZLIB 1
#endif
#ifndef SHT_RELA
#define SHT_RELA 4
#endif
#ifndef SHT_GROUP
#define SHT_GROUP 17
#endif
#ifndef SHF_COMPRESSED
#define SHF_COMPRESSED (1 << 11)
#endif
#define DWARF_DBG_ERROR(dbg,errval,retval) \
_dwarf_error(dbg, error, errval);
return
(retval);
#define FALSE 0
#define TRUE 1
_dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr;
static
Dwarf_Small _dwarf_assume_string_in_bounds;
static
Dwarf_Small _dwarf_apply_relocs = 1;
int
dwarf_set_reloc_application(
int
apply)
{
int
oldval = _dwarf_apply_relocs;
_dwarf_apply_relocs = apply;
return
oldval;
}
int
dwarf_set_stringcheck(
int
newval)
{
int
oldval = _dwarf_assume_string_in_bounds;
_dwarf_assume_string_in_bounds = newval;
return
oldval;
}
static
int
startswith(
const
char
* input,
char
* ckfor)
{
size_t
cklen =
strlen
(ckfor);
if
(!
strncmp
(input,ckfor,cklen)) {
return
TRUE;
}
return
FALSE;
}
#if 0
static
int
endswith(
const
char
* input,
char
* ckfor)
{
size_t
inlen =
strlen
(input);
size_t
endlen =
strlen
(ckfor);
const
char
* endck = 0;
if
(endlen > inlen) {
return
FALSE;
}
endck = input+inlen - endlen;
if
(!
strcmp
(endck,ckfor) ) {
return
TRUE;
}
return
FALSE;
}
#endif
static
int
get_basic_section_data(Dwarf_Debug dbg,
struct
Dwarf_Section_s *secdata,
struct
Dwarf_Obj_Access_Section_s *doas,
Dwarf_Half section_index,
unsigned group_number,
Dwarf_Error* error,
int
duperr,
int
emptyerr )
{
if
(secdata->dss_index != 0) {
DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR);
}
if
(doas->size == 0) {
if
(emptyerr == 0 ) {
return
DW_DLV_OK;
}
DWARF_DBG_ERROR(dbg, emptyerr, DW_DLV_ERROR);
}
secdata->dss_index = section_index;
secdata->dss_size = doas->size;
secdata->dss_group_number = group_number;
secdata->dss_addr = doas->addr;
secdata->dss_link = doas->link;
secdata->dss_entrysize = doas->entrysize;
if
(_dwarf_get_elf_flags_func_ptr) {
Dwarf_Unsigned flags = 0;
Dwarf_Unsigned addralign = 0;
int
res = 0;
int
interr = 0;
struct
Dwarf_Obj_Access_Interface_s *o = 0;
o = dbg->de_obj_file;
res = _dwarf_get_elf_flags_func_ptr(
o->object, section_index,
&flags,&addralign,
&interr);
if
(res == DW_DLV_ERROR) {
DWARF_DBG_ERROR(dbg, interr, DW_DLV_ERROR);
}
if
(res == DW_DLV_NO_ENTRY) {
return
res;
}
secdata->dss_flags = flags;
secdata->dss_addralign = addralign;
if
(flags & SHF_COMPRESSED) {
secdata->dss_shf_compressed = TRUE;
}
}
return
DW_DLV_OK;
}
static
void
add_rela_data_to_secdata(
struct
Dwarf_Section_s *secdata,
struct
Dwarf_Obj_Access_Section_s *doas,
Dwarf_Half section_index)
{
secdata->dss_reloc_index = section_index;
secdata->dss_reloc_size = doas->size;
secdata->dss_reloc_entrysize = doas->entrysize;
secdata->dss_reloc_addr = doas->addr;
secdata->dss_reloc_symtab = doas->link;
secdata->dss_reloc_link = doas->link;
}
static
int
add_debug_section_info(Dwarf_Debug dbg,
const
char
*name,
const
char
*standard_section_name,
unsigned obj_sec_num,
struct
Dwarf_Section_s *secdata,
unsigned groupnum,
int
duperr,
int
emptyerr,
int
have_dwarf,
int
havezdebug,
int
*err)
{
unsigned total_entries = dbg->de_debug_sections_total_entries;
if
(secdata->dss_is_in_use) {
*err = duperr;
return
DW_DLV_ERROR;
}
if
(total_entries < DWARF_MAX_DEBUG_SECTIONS) {
struct
Dwarf_dbg_sect_s *debug_section =
&dbg->de_debug_sections[total_entries];
secdata->dss_is_in_use = TRUE;
debug_section->ds_name = name;
debug_section->ds_number = obj_sec_num;
debug_section->ds_secdata = secdata;
debug_section->ds_groupnumber = groupnum;
secdata->dss_name = name;
secdata->dss_standard_name = standard_section_name;
secdata->dss_number = obj_sec_num;
secdata->dss_zdebug_requires_decompress = havezdebug;
debug_section->ds_duperr = duperr;
debug_section->ds_emptyerr = emptyerr;
debug_section->ds_have_dwarf = have_dwarf;
debug_section->ds_have_zdebug = havezdebug;
++dbg->de_debug_sections_total_entries;
return
DW_DLV_OK;
}
*err = DW_DLE_TOO_MANY_DEBUG;
return
DW_DLV_ERROR;
}
#if 0
static
void
dump_bytes(
const
char
*msg,Dwarf_Small * start,
long
len)
{
Dwarf_Small *end = start + len;
Dwarf_Small *cur = start;
printf
(
"dump_bytes: %s "
,msg);
for
(; cur < end; cur++) {
printf
(
"%02x"
,*cur);
}
printf
(
"\n"
);
}
static
int
all_sig8_bits_zero(Dwarf_Sig8 *val)
{
unsigned u = 0;
for
( ; u <
sizeof
(*val); ++u) {
if
(val->signature[u] != 0) {
return
FALSE;
}
}
return
TRUE;
}
#endif
static
int
set_up_section(Dwarf_Debug dbg,
const
char
*secname,
const
char
*sec_standard_name,
unsigned obj_sec_num,
const
char
*targname,
unsigned groupnum_of_sec,
struct
Dwarf_Section_s *secdata,
int
duperr,
int
emptyerr,
int
have_dwarf,
int
*err)
{
#define SECNAMEMAX 30
int
secnamelen =
strlen
(secname);
#define DPREFIXLEN 7
static
const
char
*zprefix =
".zdebug_"
;
#define ZPREFIXLEN 8
int
havezdebug = FALSE;
int
namesmatch = FALSE;
if
(secnamelen >= SECNAMEMAX) {
return
DW_DLV_NO_ENTRY;
}
if
((secnamelen+1) < SECNAMEMAX &&
!
strncmp
(secname,zprefix,ZPREFIXLEN) &&
!
strcmp
(secname+ZPREFIXLEN,targname+DPREFIXLEN)) {
havezdebug = TRUE;
namesmatch = TRUE;
}
else
if
(!
strcmp
(secname,targname)) {
namesmatch = TRUE;
}
#undef ZPREFIXLEN
#undef DPREFIXLEN
#undef SECNAMEMAX
if
(!namesmatch) {
return
DW_DLV_NO_ENTRY;
}
{
int
sectionerr = 0;
sectionerr = add_debug_section_info(dbg,secname,
sec_standard_name,
obj_sec_num,
secdata,
groupnum_of_sec,
duperr,emptyerr, have_dwarf,
havezdebug,err);
if
(sectionerr != DW_DLV_OK) {
return
sectionerr;
}
}
return
DW_DLV_OK;
}
#define SET_UP_SECTION(mdbg,mname,mtarg,mgrp,minfo,me1,me2,mdw,mer) \
{ \
int
lerr = 0; \
lerr = set_up_section(mdbg, \
mname,
\
mtarg,
\
\
scn_number,mtarg,mgrp, \
minfo, \
me1,me2,mdw,mer); \
if
(lerr != DW_DLV_NO_ENTRY) { \
return
lerr; \
}
\
}
static
int
enter_section_in_de_debug_sections_array(Dwarf_Debug dbg,
const
char
*scn_name,
unsigned scn_number,
unsigned group_number,
int
*err)
{
SET_UP_SECTION(dbg,scn_name,
".debug_info"
,
group_number,
&dbg->de_debug_info,
DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_info.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_info,
DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_types"
,
group_number,
&dbg->de_debug_types,
DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_types.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_types,
DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_abbrev"
,
group_number,
&dbg->de_debug_abbrev,
DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_abbrev.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_abbrev,
DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_aranges"
,
group_number,
&dbg->de_debug_aranges,
DW_DLE_DEBUG_ARANGES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_line"
,
group_number,
&dbg->de_debug_line,
DW_DLE_DEBUG_LINE_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_line_str"
,
group_number,
&dbg->de_debug_line_str,
DW_DLE_DEBUG_LINE_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_line.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_line,
DW_DLE_DEBUG_LINE_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_frame"
,
group_number,
&dbg->de_debug_frame,
DW_DLE_DEBUG_FRAME_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".eh_frame"
,
group_number,
&dbg->de_debug_frame_eh_gnu,
DW_DLE_DEBUG_FRAME_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_loc"
,
group_number,
&dbg->de_debug_loc,
DW_DLE_DEBUG_LOC_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_loc.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_loc,
DW_DLE_DEBUG_LOC_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_pubnames"
,
group_number,
&dbg->de_debug_pubnames,
DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_str"
,
group_number,
&dbg->de_debug_str,
DW_DLE_DEBUG_STR_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_str.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_str,
DW_DLE_DEBUG_STR_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_pubtypes"
,
group_number,
&dbg->de_debug_pubtypes,
DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_names"
,
group_number,
&dbg->de_debug_names,
DW_DLE_DEBUG_NAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_loclists"
,
group_number,
&dbg->de_debug_loclists,
DW_DLE_DEBUG_LOClISTS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_loclists.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_loclists,
DW_DLE_DEBUG_LOClISTS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_rnglists"
,
group_number,
&dbg->de_debug_rnglists,
DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_rnglists.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_rnglists,
DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_str_offsets"
,
group_number,
&dbg->de_debug_str_offsets,
DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_str_offsets.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_str_offsets,
DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_funcnames"
,
group_number,
&dbg->de_debug_funcnames,
DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_typenames"
,
group_number,
&dbg->de_debug_typenames,
DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_varnames"
,
group_number,
&dbg->de_debug_varnames,
DW_DLE_DEBUG_VARNAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_weaknames"
,
group_number,
&dbg->de_debug_weaknames,
DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_macinfo"
,
group_number,
&dbg->de_debug_macinfo,
DW_DLE_DEBUG_MACINFO_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_macro"
,
group_number,
&dbg->de_debug_macro,
DW_DLE_DEBUG_MACRO_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_macro.dwo"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_macro,
DW_DLE_DEBUG_MACRO_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_ranges"
,
group_number,
&dbg->de_debug_ranges,
DW_DLE_DEBUG_RANGES_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_sup"
,
group_number,
&dbg->de_debug_sup,
DW_DLE_DEBUG_SUP_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".symtab"
,
group_number,
&dbg->de_elf_symtab,
DW_DLE_DEBUG_SYMTAB_ERR,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".strtab"
,
group_number,
&dbg->de_elf_strtab,
DW_DLE_DEBUG_STRTAB_ERR,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_addr"
,
group_number,
&dbg->de_debug_addr,
DW_DLE_DEBUG_ADDR_DUPLICATE,0,
TRUE,err);
SET_UP_SECTION(dbg,scn_name,
".gdb_index"
,
group_number,
&dbg->de_debug_gdbindex,
DW_DLE_DUPLICATE_GDB_INDEX,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_names"
,
group_number,
&dbg->de_debug_names,
DW_DLE_DEBUG_NAMES_DUPLICATE,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_cu_index"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_cu_index,
DW_DLE_DUPLICATE_CU_INDEX,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".debug_tu_index"
,
DW_GROUPNUMBER_DWO,
&dbg->de_debug_tu_index,
DW_DLE_DUPLICATE_TU_INDEX,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".gnu_debuglink"
,
DW_GROUPNUMBER_DWO,
&dbg->de_gnu_debuglink,
DW_DLE_DUPLICATE_GNU_DEBUGLINK,0,
FALSE,err);
SET_UP_SECTION(dbg,scn_name,
".note.gnu.build-id"
,
DW_GROUPNUMBER_DWO,
&dbg->de_note_gnu_buildid,
DW_DLE_DUPLICATE_GNU_DEBUGLINK,0,
FALSE,err);
return
DW_DLV_NO_ENTRY;
}
static
int
is_section_name_known_already(Dwarf_Debug dbg,
const
char
*scn_name)
{
unsigned i = 0;
for
( ; i < dbg->de_debug_sections_total_entries; ++i) {
struct
Dwarf_dbg_sect_s *section = &dbg->de_debug_sections[i];
if
(!
strcmp
(scn_name, section->ds_name)) {
return
DW_DLV_OK;
}
}
return
DW_DLV_NO_ENTRY;
}
static
int
is_a_rela_section(
const
char
*scn_name,
int
type)
{
if
(startswith(scn_name,
".rela."
)) {
return
TRUE;
}
if
(type == SHT_RELA) {
return
TRUE;
}
return
FALSE;
}
static
int
is_a_special_section_semi_dwarf(
const
char
*scn_name)
{
if
(!
strcmp
(scn_name,
".strtab"
) ||
!
strcmp
(scn_name,
".symtab"
)) {
return
TRUE;
}
return
FALSE;
}
static
int
this_section_dwarf_relevant(
const
char
*scn_name,
int
type)
{
if
(startswith(scn_name,
".zdebug_"
) ||
startswith(scn_name,
".debug_"
)) {
return
TRUE;
}
if
(!
strcmp
(scn_name,
".eh_frame"
)) {
return
TRUE;
}
if
(!
strcmp
(scn_name,
".gnu_debuglink"
)) {
return
TRUE;
}
if
(!
strcmp
(scn_name,
".note.gnu.build-id"
)) {
return
TRUE;
}
if
(!
strcmp
(scn_name,
".gdb_index"
)) {
return
TRUE;
}
if
(is_a_special_section_semi_dwarf(scn_name)) {
return
TRUE;
}
if
(is_a_rela_section(scn_name,type)) {
return
TRUE;
}
return
FALSE;
}
static
int
insert_sht_list_in_group_map(Dwarf_Debug dbg,
struct
Dwarf_Obj_Access_Section_s *doas,
unsigned comdat_group_number,
unsigned section_number,
Dwarf_Unsigned section_count,
struct
Dwarf_Obj_Access_Interface_s * obj,
unsigned *did_add_map,
Dwarf_Error *error)
{
struct
Dwarf_Section_s secdata;
Dwarf_Small * data = 0;
int
res = 0;
Dwarf_Small* secend = 0;
memset
(&secdata,0,
sizeof
(secdata));
secdata.dss_size = doas->size;
secdata.dss_entrysize = doas->entrysize;
secdata.dss_group_number = 1;
secdata.dss_index = section_number;
secdata.dss_name =
".group"
;
secdata.dss_standard_name =
".group"
;
secdata.dss_number = section_number;
secdata.dss_ignore_reloc_group_sec = TRUE;
res = _dwarf_load_section(dbg,&secdata,error);
if
(res != DW_DLV_OK) {
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
return
res;
}
if
(!secdata.dss_data) {
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
if
(doas->entrysize != 4) {
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
data = secdata.dss_data;
secend = data + secdata.dss_size;
{
unsigned i = 1;
unsigned count = doas->size/doas->entrysize;
Dwarf_Unsigned fval = 0;
if
((data+DWARF_32BIT_SIZE) > secend) {
free
(secdata.dss_data);
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
READ_UNALIGNED_CK(dbg,fval,Dwarf_Unsigned,
data,
DWARF_32BIT_SIZE,
error,
secend);
if
(fval != 1 && fval != 0x1000000) {
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
data = data + doas->entrysize;
for
(i = 1 ; i < count ; ++i) {
Dwarf_Unsigned val = 0;
if
((data+DWARF_32BIT_SIZE) > secend) {
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
READ_UNALIGNED_CK(dbg,val,Dwarf_Unsigned,
data,
DWARF_32BIT_SIZE,
error,
secend);
if
(val > section_count) {
Dwarf_Unsigned valr = 0;
_dwarf_memcpy_swap_bytes(&valr,&val,
DWARF_32BIT_SIZE);
if
(valr > section_count) {
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_ERROR;
}
val = valr;
}
{
struct
Dwarf_Obj_Access_Section_s doasx;
int
resx = DW_DLV_ERROR;
int
err = 0;
memset
(&doasx,0,
sizeof
(doasx));
resx = obj->methods->get_section_info(obj->object,
val,
&doasx, &err);
if
(resx == DW_DLV_NO_ENTRY){
continue
;
}
else
if
(resx == DW_DLV_ERROR){
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
_dwarf_error(dbg,error,err);
return
resx;
}
if
(!this_section_dwarf_relevant(doasx.name,
doasx.type) ) {
continue
;
}
data += DWARF_32BIT_SIZE;
*did_add_map = TRUE;
res = _dwarf_insert_in_group_map(dbg,
comdat_group_number,val,
doasx.name,
error);
if
(res != DW_DLV_OK) {
free
(secdata.dss_data);
return
res;
}
}
}
}
if
(secdata.dss_data_was_malloc) {
free
(secdata.dss_data);
}
return
DW_DLV_OK;
}
static
int
determine_target_group(Dwarf_Unsigned section_count,
struct
Dwarf_Obj_Access_Interface_s * obj,
unsigned *group_number_out,
Dwarf_Debug dbg,
Dwarf_Error *error)
{
unsigned obj_section_index = 0;
int
found_group_one = 0;
int
found_group_two = 0;
struct
Dwarf_Group_Data_s *grp = 0;
unsigned comdat_group_next = 3;
unsigned lowest_comdat_groupnum = 0;
grp = &dbg->de_groupnumbers;
grp->gd_number_of_groups = 0;
grp->gd_number_of_sections = section_count;
if
(grp->gd_map) {
_dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR);
return
DW_DLV_OK;
}
for
(obj_section_index = 0; obj_section_index < section_count;
++obj_section_index) {
struct
Dwarf_Obj_Access_Section_s doas;
int
res = DW_DLV_ERROR;
int
err = 0;
const
char
*scn_name = 0;
unsigned groupnumber = 0;
unsigned mapgroupnumber = 0;
memset
(&doas,0,
sizeof
(doas));
res = obj->methods->get_section_info(obj->object,
obj_section_index,
&doas, &err);
if
(res == DW_DLV_NO_ENTRY){
return
res;
}
else
if
(res == DW_DLV_ERROR){
_dwarf_error(dbg, error,err);
return
res;
}
if
(doas.type == SHT_GROUP) {
unsigned did_add_map = 0;
res = insert_sht_list_in_group_map(dbg,&doas,
comdat_group_next,
obj_section_index,
section_count,
obj,
&did_add_map,error);
if
(res != DW_DLV_OK) {
return
res;
}
if
(!lowest_comdat_groupnum) {
lowest_comdat_groupnum = comdat_group_next;
}
if
(did_add_map) {
++grp->gd_number_of_groups;
++comdat_group_next;
}
continue
;
}
scn_name = doas.name;
if
(!this_section_dwarf_relevant(scn_name,doas.type) ) {
continue
;
}
res = _dwarf_section_get_target_group_from_map(dbg,
obj_section_index,&groupnumber,error);
if
(res == DW_DLV_OK ) {
mapgroupnumber = groupnumber;
}
else
if
(res == DW_DLV_ERROR) {
return
res;
}
else
{
}
if
(!groupnumber) {
res =_dwarf_dwo_groupnumber_given_name(scn_name,
&groupnumber);
if
(res == DW_DLV_OK) {
}
else
{
groupnumber = DW_GROUPNUMBER_BASE;
}
}
if
(is_a_rela_section(scn_name,doas.type)) {
unsigned linkgroup = 0;
res = _dwarf_section_get_target_group_from_map(dbg,
doas.info,
&linkgroup,error);
if
(res == DW_DLV_OK ) {
}
else
if
(res == DW_DLV_ERROR) {
return
res;
}
else
{
res = _dwarf_insert_in_group_map(dbg,
linkgroup,obj_section_index,
scn_name,
error);
if
(res != DW_DLV_OK ) {
return
res;
}
}
continue
;
}
if
(!is_a_special_section_semi_dwarf(scn_name)) {
if
(mapgroupnumber) {
continue
;
}
res = _dwarf_insert_in_group_map(dbg,
groupnumber,obj_section_index,
scn_name,
error);
if
(res != DW_DLV_OK) {
return
res;
}
if
(groupnumber == 1) {
found_group_one++;
}
else
if
(groupnumber == 2) {
found_group_two++;
}
continue
;
}
}
if
(found_group_two) {
++grp->gd_number_of_groups;
}
if
(found_group_one) {
*group_number_out = DW_GROUPNUMBER_BASE;
++grp->gd_number_of_groups;
}
else
{
if
(found_group_two) {
*group_number_out = DW_GROUPNUMBER_DWO;
}
else
{
if
(lowest_comdat_groupnum) {
*group_number_out = lowest_comdat_groupnum;
}
else
{
*group_number_out = DW_GROUPNUMBER_BASE;
}
}
}
return
DW_DLV_OK;
}
static
int
_dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error)
{
const
char
*scn_name = 0;
struct
Dwarf_Obj_Access_Interface_s * obj = 0;
int
resn = 0;
struct
Dwarf_Section_s **sections = 0;
Dwarf_Endianness endianness;
Dwarf_Unsigned section_count = 0;
unsigned default_group_number = 0;
unsigned foundDwarf = FALSE;
unsigned obj_section_index = 0;
dbg->de_assume_string_in_bounds =
_dwarf_assume_string_in_bounds;
dbg->de_same_endian = 1;
dbg->de_copy_word = _dwarf_memcpy_noswap_bytes;
obj = dbg->de_obj_file;
endianness = obj->methods->get_byte_order(obj->object);
#ifdef WORDS_BIGENDIAN
dbg->de_big_endian_object = 1;
if
(endianness == DW_OBJECT_LSB ) {
dbg->de_same_endian = 0;
dbg->de_big_endian_object = 0;
dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
}
#else /* little endian */
dbg->de_big_endian_object = 0;
if
(endianness == DW_OBJECT_MSB ) {
dbg->de_same_endian = 0;
dbg->de_big_endian_object = 1;
dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
}
#endif /* !WORDS_BIGENDIAN */
dbg->de_length_size = obj->methods->get_length_size(obj->object);
dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object);
section_count = obj->methods->get_section_count(obj->object);
resn = determine_target_group(section_count,obj,
&default_group_number,dbg,error);
if
(resn == DW_DLV_ERROR) {
return
DW_DLV_ERROR;
}
if
(dbg->de_groupnumber == DW_GROUPNUMBER_ANY) {
dbg->de_groupnumber = default_group_number;
}
sections = (
struct
Dwarf_Section_s **)
calloc
(section_count + 1,
sizeof
(
struct
Dwarf_Section_s *));
if
(!sections) {
_dwarf_error(dbg, error, DW_DLE_SECTION_ERROR);
return
DW_DLV_ERROR;
}
for
(obj_section_index = 0; obj_section_index < section_count;
++obj_section_index) {
struct
Dwarf_Obj_Access_Section_s doas;
int
res = DW_DLV_ERROR;
int
err = 0;
unsigned groupnumber = 0;
unsigned mapgroupnumber = 0;
res = _dwarf_section_get_target_group_from_map(dbg,obj_section_index,
&groupnumber,error);
if
(res == DW_DLV_OK ) {
mapgroupnumber = groupnumber;
}
else
if
(res == DW_DLV_ERROR) {
free
(sections);
return
res;
}
else
{
}
memset
(&doas,0,
sizeof
(doas));
res = obj->methods->get_section_info(obj->object,
obj_section_index,
&doas, &err);
if
(res == DW_DLV_NO_ENTRY){
free
(sections);
return
res;
}
else
if
(res == DW_DLV_ERROR){
free
(sections);
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
scn_name = doas.name;
if
(!groupnumber) {
res = _dwarf_dwo_groupnumber_given_name(scn_name,
&groupnumber);
if
(res == DW_DLV_NO_ENTRY) {
groupnumber = DW_GROUPNUMBER_BASE;
}
}
if
(!this_section_dwarf_relevant(scn_name,doas.type) ) {
continue
;
}
if
(!is_a_rela_section(scn_name,doas.type)
&& !is_a_special_section_semi_dwarf(scn_name)) {
if
(mapgroupnumber == dbg->de_groupnumber) {
}
else
{
if
(groupnumber == 1 && dbg->de_groupnumber > 2 &&
!_dwarf_section_in_group_by_name(dbg,scn_name,
dbg->de_groupnumber)) {
}
else
{
continue
;
}
}
}
{
struct
Dwarf_dbg_sect_s *section;
int
found_match = FALSE;
res = is_section_name_known_already(dbg,scn_name);
if
(res == DW_DLV_OK) {
free
(sections);
DWARF_DBG_ERROR(dbg, DW_DLE_SECTION_DUPLICATION,
DW_DLV_ERROR);
}
else
if
(res == DW_DLV_ERROR) {
free
(sections);
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
res = enter_section_in_de_debug_sections_array(dbg,scn_name,
obj_section_index, groupnumber,&err);
if
(res == DW_DLV_OK) {
section = &dbg->de_debug_sections[
dbg->de_debug_sections_total_entries-1];
res = get_basic_section_data(dbg,
section->ds_secdata, &doas,
obj_section_index,
groupnumber,
error,
section->ds_duperr,
section->ds_emptyerr);
if
(res != DW_DLV_OK) {
free
(sections);
return
res;
}
sections[obj_section_index] = section->ds_secdata;
foundDwarf += section->ds_have_dwarf;
found_match = TRUE;
}
else
if
(res == DW_DLV_NO_ENTRY) {
}
else
{
free
(sections);
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
if
(!found_match) {
if
(is_a_rela_section(scn_name,doas.type)) {
if
( doas.info < section_count) {
if
(sections[doas.info]) {
add_rela_data_to_secdata(sections[doas.info],
&doas,
obj_section_index);
}
}
else
{
free
(sections);
DWARF_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR);
}
}
}
}
}
free
(sections);
if
(foundDwarf) {
return
DW_DLV_OK;
}
return
DW_DLV_NO_ENTRY;
}
static
int
load_debugfission_tables(Dwarf_Debug dbg,Dwarf_Error *error)
{
int
i = 0;
if
(dbg->de_debug_cu_index.dss_size ==0 &&
dbg->de_debug_tu_index.dss_size ==0) {
return
DW_DLV_NO_ENTRY;
}
for
(i = 0; i < 2; ++i) {
Dwarf_Xu_Index_Header xuptr = 0;
struct
Dwarf_Section_s* dwsect = 0;
Dwarf_Unsigned version = 0;
Dwarf_Unsigned number_of_cols
= 0;
Dwarf_Unsigned number_of_CUs
= 0;
Dwarf_Unsigned number_of_slots
= 0;
const
char
*secname = 0;
int
res = 0;
const
char
*type = 0;
if
(i == 0) {
dwsect = &dbg->de_debug_cu_index;
type =
"cu"
;
}
else
{
dwsect = &dbg->de_debug_tu_index;
type =
"tu"
;
}
if
( !dwsect->dss_size ) {
continue
;
}
res = dwarf_get_xu_index_header(dbg,type,
&xuptr,&version,&number_of_cols,
&number_of_CUs,&number_of_slots,
&secname,error);
if
(res == DW_DLV_NO_ENTRY) {
continue
;
}
if
(res != DW_DLV_OK) {
return
res;
}
if
(i == 0) {
dbg->de_cu_hashindex_data = xuptr;
}
else
{
dbg->de_tu_hashindex_data = xuptr;
}
}
return
DW_DLV_OK;
}
int
dwarf_object_init(Dwarf_Obj_Access_Interface* obj,
Dwarf_Handler errhand,
Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg,
Dwarf_Error* error)
{
return
dwarf_object_init_b(obj,errhand,errarg,
DW_GROUPNUMBER_ANY,ret_dbg,error);
}
int
dwarf_object_init_b(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand,
Dwarf_Ptr errarg,
unsigned groupnumber,
Dwarf_Debug* ret_dbg,
Dwarf_Error* error)
{
Dwarf_Debug dbg = 0;
int
setup_result = DW_DLV_OK;
dbg = _dwarf_get_debug();
if
(dbg == NULL) {
DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
}
dbg->de_errhand = errhand;
dbg->de_errarg = errarg;
dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
#ifdef HAVE_OLD_FRAME_CFA_COL
dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL;
#else
dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3;
#endif
dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL;
dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL;
dbg->de_obj_file = obj;
dbg->de_groupnumber = groupnumber;
setup_result = _dwarf_setup(dbg, error);
if
(setup_result == DW_DLV_OK) {
int
fission_result = load_debugfission_tables(dbg,error);
if
(fission_result == DW_DLV_ERROR) {
setup_result = fission_result;
}
}
if
(setup_result != DW_DLV_OK) {
int
freeresult = 0;
int
myerr = 0;
if
( (setup_result == DW_DLV_ERROR) && error ) {
myerr = dwarf_errno(*error);
dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
*error = 0;
}
freeresult = _dwarf_free_all_of_one_debug(dbg);
dbg = 0;
if
(freeresult == DW_DLV_ERROR) {
_dwarf_error(NULL,error,DW_DLE_DBG_ALLOC);
return
DW_DLV_ERROR;
}
if
(setup_result == DW_DLV_ERROR) {
_dwarf_error(NULL,error,myerr);
}
return
setup_result;
}
dwarf_harmless_init(&dbg->de_harmless_errors,
DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE);
*ret_dbg = dbg;
return
DW_DLV_OK;
}
int
dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error)
{
int
res = 0;
res = _dwarf_free_all_of_one_debug(dbg);
if
(res == DW_DLV_ERROR) {
DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
}
return
res;
}
#ifdef HAVE_ZLIB
#define ALLOWED_ZLIB_INFLATION 16
static
int
do_decompress_zlib(Dwarf_Debug dbg,
struct
Dwarf_Section_s *section,
Dwarf_Error * error)
{
Bytef *basesrc = (Bytef *)section->dss_data;
Bytef *src = (Bytef *)basesrc;
uLong srclen = section->dss_size;
Dwarf_Unsigned flags = section->dss_flags;
Dwarf_Small *endsection = 0;
int
res = 0;
Bytef *dest = 0;
uLongf destlen = 0;
Dwarf_Unsigned uncompressed_len = 0;
endsection = basesrc + srclen;
if
((src + 12) >endsection) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR);
}
section->dss_compressed_length = section->dss_size;
if
(!
strncmp
(
"ZLIB"
,(
const
char
*)src,4)) {
unsigned i = 0;
unsigned l = 8;
unsigned
char
*c = src+4;
for
( ; i < l; ++i,c++) {
uncompressed_len <<= 8;
uncompressed_len += *c;
}
src = src + 12;
srclen -= 12;
section->dss_uncompressed_length = uncompressed_len;
section->dss_ZLIB_compressed = TRUE;
}
else
if
(flags & SHF_COMPRESSED) {
Dwarf_Small *ptr = (Dwarf_Small *)src;
Dwarf_Unsigned type = 0;
Dwarf_Unsigned size = 0;
unsigned fldsize = dbg->de_pointer_size;
unsigned structsize = 3* fldsize;
READ_UNALIGNED_CK(dbg,type,Dwarf_Unsigned,ptr,
DWARF_32BIT_SIZE,
error,endsection);
ptr += fldsize;
READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,ptr,fldsize,
error,endsection);
if
(type != ELFCOMPRESS_ZLIB) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD,
DW_DLV_ERROR);
}
uncompressed_len = size;
section->dss_uncompressed_length = uncompressed_len;
src += structsize;
srclen -= structsize;
section->dss_shf_compressed = TRUE;
}
else
{
DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD,
DW_DLV_ERROR);
}
{
Dwarf_Unsigned max_inflated_len = srclen*ALLOWED_ZLIB_INFLATION;
if
(srclen > 50) {
if
(uncompressed_len < (srclen/2)) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR,
DW_DLV_ERROR);
}
}
if
(max_inflated_len < srclen) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR);
}
if
(uncompressed_len > max_inflated_len) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR);
}
}
if
( (src +srclen) > endsection) {
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR);
}
destlen = uncompressed_len;
dest =
malloc
(destlen);
if
(!dest) {
DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR);
}
res = uncompress(dest,&destlen,src,srclen);
if
(res == Z_BUF_ERROR) {
free
(dest);
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_BUF_ERROR, DW_DLV_ERROR);
}
else
if
(res == Z_MEM_ERROR) {
free
(dest);
DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR);
}
else
if
(res != Z_OK) {
free
(dest);
DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_DATA_ERROR, DW_DLV_ERROR);
}
section->dss_data = dest;
section->dss_size = destlen;
section->dss_data_was_malloc = TRUE;
section->dss_did_decompress = TRUE;
return
DW_DLV_OK;
}
#endif /* HAVE_ZLIB */
int
_dwarf_load_section(Dwarf_Debug dbg,
struct
Dwarf_Section_s *section,
Dwarf_Error * error)
{
int
res = DW_DLV_ERROR;
int
err = 0;
struct
Dwarf_Obj_Access_Interface_s *o = 0;
if
(section->dss_data != NULL) {
return
DW_DLV_OK;
}
o = dbg->de_obj_file;
res = o->methods->load_section(
o->object, section->dss_index,
§ion->dss_data, &err);
if
(res == DW_DLV_ERROR) {
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
if
(res == DW_DLV_NO_ENTRY) {
return
res;
}
if
(section->dss_ignore_reloc_group_sec) {
return
res;
}
if
((section->dss_zdebug_requires_decompress ||
section->dss_shf_compressed ||
section->dss_ZLIB_compressed) &&
!section->dss_did_decompress) {
if
(!section->dss_data) {
DWARF_DBG_ERROR(dbg, DW_DLE_COMPRESSED_EMPTY_SECTION, DW_DLV_ERROR);
}
#ifdef HAVE_ZLIB
res = do_decompress_zlib(dbg,section,error);
if
(res != DW_DLV_OK) {
return
res;
}
section->dss_did_decompress = TRUE;
#else
DWARF_DBG_ERROR(dbg,DW_DLE_ZDEBUG_REQUIRES_ZLIB, DW_DLV_ERROR);
#endif
}
if
(_dwarf_apply_relocs == 0) {
return
res;
}
if
(section->dss_reloc_size == 0) {
return
res;
}
if
(!o->methods->relocate_a_section) {
return
res;
}
res = o->methods->relocate_a_section( o->object, section->dss_index,
dbg, &err);
if
(res == DW_DLV_ERROR) {
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
return
res;
}
int
dwarf_get_section_max_offsets(Dwarf_Debug dbg,
Dwarf_Unsigned * debug_info_size,
Dwarf_Unsigned * debug_abbrev_size,
Dwarf_Unsigned * debug_line_size,
Dwarf_Unsigned * debug_loc_size,
Dwarf_Unsigned * debug_aranges_size,
Dwarf_Unsigned * debug_macinfo_size,
Dwarf_Unsigned * debug_pubnames_size,
Dwarf_Unsigned * debug_str_size,
Dwarf_Unsigned * debug_frame_size,
Dwarf_Unsigned * debug_ranges_size,
Dwarf_Unsigned * debug_typenames_size)
{
*debug_info_size = dbg->de_debug_info.dss_size;
*debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
*debug_line_size = dbg->de_debug_line.dss_size;
*debug_loc_size = dbg->de_debug_loc.dss_size;
*debug_aranges_size = dbg->de_debug_aranges.dss_size;
*debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
*debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
*debug_str_size = dbg->de_debug_str.dss_size;
*debug_frame_size = dbg->de_debug_frame.dss_size;
*debug_ranges_size = dbg->de_debug_ranges.dss_size;
*debug_typenames_size = dbg->de_debug_typenames.dss_size;
return
DW_DLV_OK;
}
int
dwarf_get_section_max_offsets_b(Dwarf_Debug dbg,
Dwarf_Unsigned * debug_info_size,
Dwarf_Unsigned * debug_abbrev_size,
Dwarf_Unsigned * debug_line_size,
Dwarf_Unsigned * debug_loc_size,
Dwarf_Unsigned * debug_aranges_size,
Dwarf_Unsigned * debug_macinfo_size,
Dwarf_Unsigned * debug_pubnames_size,
Dwarf_Unsigned * debug_str_size,
Dwarf_Unsigned * debug_frame_size,
Dwarf_Unsigned * debug_ranges_size,
Dwarf_Unsigned * debug_typenames_size,
Dwarf_Unsigned * debug_types_size)
{
*debug_info_size = dbg->de_debug_info.dss_size;
*debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
*debug_line_size = dbg->de_debug_line.dss_size;
*debug_loc_size = dbg->de_debug_loc.dss_size;
*debug_aranges_size = dbg->de_debug_aranges.dss_size;
*debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
*debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
*debug_str_size = dbg->de_debug_str.dss_size;
*debug_frame_size = dbg->de_debug_frame.dss_size;
*debug_ranges_size = dbg->de_debug_ranges.dss_size;
*debug_typenames_size = dbg->de_debug_typenames.dss_size;
*debug_types_size = dbg->de_debug_types.dss_size;
return
DW_DLV_OK;
}
int
dwarf_get_section_max_offsets_c(Dwarf_Debug dbg,
Dwarf_Unsigned * debug_info_size,
Dwarf_Unsigned * debug_abbrev_size,
Dwarf_Unsigned * debug_line_size,
Dwarf_Unsigned * debug_loc_size,
Dwarf_Unsigned * debug_aranges_size,
Dwarf_Unsigned * debug_macinfo_size,
Dwarf_Unsigned * debug_pubnames_size,
Dwarf_Unsigned * debug_str_size,
Dwarf_Unsigned * debug_frame_size,
Dwarf_Unsigned * debug_ranges_size,
Dwarf_Unsigned * debug_typenames_size,
Dwarf_Unsigned * debug_types_size,
Dwarf_Unsigned * debug_macro_size,
Dwarf_Unsigned * debug_str_offsets_size,
Dwarf_Unsigned * debug_sup_size,
Dwarf_Unsigned * debug_cu_index_size,
Dwarf_Unsigned * debug_tu_index_size)
{
*debug_info_size = dbg->de_debug_info.dss_size;
*debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
*debug_line_size = dbg->de_debug_line.dss_size;
*debug_loc_size = dbg->de_debug_loc.dss_size;
*debug_aranges_size = dbg->de_debug_aranges.dss_size;
*debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
*debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
*debug_str_size = dbg->de_debug_str.dss_size;
*debug_frame_size = dbg->de_debug_frame.dss_size;
*debug_ranges_size = dbg->de_debug_ranges.dss_size;
*debug_typenames_size = dbg->de_debug_typenames.dss_size;
*debug_types_size = dbg->de_debug_types.dss_size;
*debug_macro_size = dbg->de_debug_macro.dss_size;
*debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size;
*debug_sup_size = dbg->de_debug_sup.dss_size;
*debug_cu_index_size = dbg->de_debug_cu_index.dss_size;
*debug_tu_index_size = dbg->de_debug_tu_index.dss_size;
return
DW_DLV_OK;
}
int
dwarf_get_section_max_offsets_d(Dwarf_Debug dbg,
Dwarf_Unsigned * debug_info_size,
Dwarf_Unsigned * debug_abbrev_size,
Dwarf_Unsigned * debug_line_size,
Dwarf_Unsigned * debug_loc_size,
Dwarf_Unsigned * debug_aranges_size,
Dwarf_Unsigned * debug_macinfo_size,
Dwarf_Unsigned * debug_pubnames_size,
Dwarf_Unsigned * debug_str_size,
Dwarf_Unsigned * debug_frame_size,
Dwarf_Unsigned * debug_ranges_size,
Dwarf_Unsigned * debug_typenames_size,
Dwarf_Unsigned * debug_types_size,
Dwarf_Unsigned * debug_macro_size,
Dwarf_Unsigned * debug_str_offsets_size,
Dwarf_Unsigned * debug_sup_size,
Dwarf_Unsigned * debug_cu_index_size,
Dwarf_Unsigned * debug_tu_index_size,
Dwarf_Unsigned * debug_names_size,
Dwarf_Unsigned * debug_loclists_size,
Dwarf_Unsigned * debug_rnglists_size)
{
*debug_info_size = dbg->de_debug_info.dss_size;
*debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
*debug_line_size = dbg->de_debug_line.dss_size;
*debug_loc_size = dbg->de_debug_loc.dss_size;
*debug_aranges_size = dbg->de_debug_aranges.dss_size;
*debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
*debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
*debug_str_size = dbg->de_debug_str.dss_size;
*debug_frame_size = dbg->de_debug_frame.dss_size;
*debug_ranges_size = dbg->de_debug_ranges.dss_size;
*debug_typenames_size = dbg->de_debug_typenames.dss_size;
*debug_types_size = dbg->de_debug_types.dss_size;
*debug_macro_size = dbg->de_debug_macro.dss_size;
*debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size;
*debug_sup_size = dbg->de_debug_sup.dss_size;
*debug_cu_index_size = dbg->de_debug_cu_index.dss_size;
*debug_tu_index_size = dbg->de_debug_tu_index.dss_size;
*debug_names_size = dbg->de_debug_names.dss_size;
*debug_loclists_size = dbg->de_debug_loclists.dss_size;
*debug_rnglists_size = dbg->de_debug_rnglists.dss_size;
return
DW_DLV_OK;
}
int
dwarf_get_section_info_by_name(Dwarf_Debug dbg,
const
char
*section_name,
Dwarf_Addr *section_addr,
Dwarf_Unsigned *section_size,
Dwarf_Error * error)
{
struct
Dwarf_Obj_Access_Section_s doas;
struct
Dwarf_Obj_Access_Interface_s * obj = 0;
Dwarf_Unsigned section_count = 0;
Dwarf_Half section_index = 0;
*section_addr = 0;
*section_size = 0;
obj = dbg->de_obj_file;
if
(NULL == obj) {
return
DW_DLV_NO_ENTRY;
}
section_count = obj->methods->get_section_count(obj->object);
for
(section_index = 0; section_index < section_count;
++section_index) {
int
err = 0;
int
res = obj->methods->get_section_info(obj->object,
section_index, &doas, &err);
if
(res == DW_DLV_ERROR) {
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
if
(!
strcmp
(section_name,doas.name)) {
*section_addr = doas.addr;
*section_size = doas.size;
return
DW_DLV_OK;
}
}
return
DW_DLV_NO_ENTRY;
}
int
dwarf_get_section_info_by_index(Dwarf_Debug dbg,
int
section_index,
const
char
**section_name,
Dwarf_Addr *section_addr,
Dwarf_Unsigned *section_size,
Dwarf_Error * error)
{
*section_addr = 0;
*section_size = 0;
*section_name = NULL;
if
(section_index >= 0 && section_index < dwarf_get_section_count(dbg)) {
int
res = 0;
int
err = 0;
struct
Dwarf_Obj_Access_Section_s doas;
struct
Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file;
if
(NULL == obj) {
return
DW_DLV_NO_ENTRY;
}
res = obj->methods->get_section_info(obj->object,
section_index, &doas, &err);
if
(res == DW_DLV_ERROR){
DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
}
*section_addr = doas.addr;
*section_size = doas.size;
*section_name = doas.name;
return
DW_DLV_OK;
}
return
DW_DLV_NO_ENTRY;
}
int
dwarf_get_section_count(Dwarf_Debug dbg)
{
struct
Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file;
if
(NULL == obj) {
return
DW_DLV_NO_ENTRY;
}
return
obj->methods->get_section_count(obj->object);
}
Dwarf_Cmdline_Options dwarf_cmdline_options = {
FALSE
};
void
dwarf_record_cmdline_options(Dwarf_Cmdline_Options options)
{
dwarf_cmdline_options = options;
}