#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
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include "dwarf_incl.h"
#include "dwarf_alloc.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#include "memcpy_swap.h"
#include "dwarf_harmless.h"
#include "dwarfstring.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_REL
#define SHT_REL 9
# 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_relx_data_to_secdata( struct Dwarf_Section_s *secdata,
struct Dwarf_Obj_Access_Section_s *doas,
Dwarf_Half section_index,int is_rela)
{
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;
secdata->dss_is_rela = is_rela;
}
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;
}
int
_dwarf_ignorethissection(const char *scn_name) {
if(!strcmp(scn_name,".bss")) {
return TRUE;
}
if(!strcmp(scn_name,".comment")) {
return TRUE;
}
if(!strcmp(scn_name,".sbss")) {
return TRUE;
}
if(!strcmp(scn_name,".jcr")) {
return TRUE;
}
if(!strcmp(scn_name,".init")) {
return TRUE;
}
if(!strcmp(scn_name,".fini_array")) {
return TRUE;
}
if(!strcmp(scn_name,".fini")) {
return TRUE;
}
if(!strcmp(scn_name,".fini_array")) {
return TRUE;
}
if(!strcmp(scn_name,".interp")) {
return TRUE;
}
if(!strcmp(scn_name,".text")) {
return TRUE;
}
if(!strcmp(scn_name,".rela.text")) {
return TRUE;
}
if(!strcmp(scn_name,".rel.text")) {
return TRUE;
}
if(!strcmp(scn_name,".plt")) {
return TRUE;
}
if(!strcmp(scn_name,".rela.plt")) {
return TRUE;
}
if(!strcmp(scn_name,".rel.plt")) {
return TRUE;
}
if(!strcmp(scn_name,".data")) {
return TRUE;
}
if(!strcmp(scn_name,".rel.data")) {
return TRUE;
}
if(!strcmp(scn_name,".rela.data")) {
return TRUE;
}
if(!strcmp(scn_name,".got")) {
return TRUE;
}
if(!strcmp(scn_name,".rela.got")) {
return TRUE;
}
if(!strcmp(scn_name,".rel.got")) {
return TRUE;
}
return FALSE;
}
static int
is_a_relx_section(const char *scn_name,int type,int *is_rela)
{
if(startswith(scn_name,".rela.")) {
*is_rela = TRUE;
return TRUE;
}
if(startswith(scn_name,".rel.")) {
*is_rela = FALSE;
return TRUE;
}
if (type == SHT_RELA) {
*is_rela = TRUE;
return TRUE;
}
if (type == SHT_REL) {
*is_rela = FALSE;
return TRUE;
}
*is_rela = FALSE;
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, int *is_rela)
{
if (startswith(scn_name, ".zdebug_") ||
startswith(scn_name, ".debug_")) {
return TRUE;
}
if (_dwarf_ignorethissection(scn_name)) {
return FALSE;
}
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_relx_section(scn_name,type,is_rela)) {
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;
int is_rela = FALSE;
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,&is_rela) ) {
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;
int is_rela = FALSE;
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,&is_rela) ) {
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_relx_section(scn_name,doas.type,&is_rela)) {
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
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
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;
int is_rela = FALSE;
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,&is_rela) ) {
continue;
}
if (!is_a_relx_section(scn_name,doas.type,&is_rela)
&& !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_relx_section(scn_name,doas.type,&is_rela)) {
if ( doas.info < section_count) {
if (sections[doas.info]) {
add_relx_data_to_secdata(sections[doas.info],
&doas,
obj_section_index,is_rela);
}
} 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;
dwarfstring msg;
dwarfstring_constructor(&msg);
if ( (setup_result == DW_DLV_ERROR) && *error ) {
myerr = dwarf_errno(*error);
dwarfstring_append(&msg,dwarf_errmsg(*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_string(dbg,error,DW_DLE_DBG_ALLOC,
dwarfstring_string(&msg));
dwarfstring_destructor(&msg);
return DW_DLV_ERROR;
}
if (setup_result == DW_DLV_ERROR) {
_dwarf_error_string(dbg,error,myerr,
dwarfstring_string(&msg));
}
dwarfstring_destructor(&msg);
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
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, res);
}
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;
}