libbacktrace: improve XCOFF support
libbacktrace/ChangeLog: 2021-06-28 Clément Chigot <clement.chigot@atos.net> * xcoff.c (SSUBTYP_DWRNGES): New define. (xcoff_add): Use correct XCOFF DWARF section subtype for DEBUG_RANGES. Remove lineoff workaround. Adjust base_address. (xcoff_initialize_syminfo): Adapt to new base_address. (xcoff_lookup_pc): Likewise. (xcoff_initialize_fileline): Likewise.
This commit is contained in:
parent
9c93f6cc95
commit
42ff474e28
|
@ -133,6 +133,7 @@ typedef struct {
|
||||||
#define SSUBTYP_DWARNGE 0x50000 /* DWARF aranges section. */
|
#define SSUBTYP_DWARNGE 0x50000 /* DWARF aranges section. */
|
||||||
#define SSUBTYP_DWABREV 0x60000 /* DWARF abbreviation section. */
|
#define SSUBTYP_DWABREV 0x60000 /* DWARF abbreviation section. */
|
||||||
#define SSUBTYP_DWSTR 0x70000 /* DWARF strings section. */
|
#define SSUBTYP_DWSTR 0x70000 /* DWARF strings section. */
|
||||||
|
#define SSUBTYP_DWRNGES 0x80000 /* DWARF ranges section. */
|
||||||
|
|
||||||
/* XCOFF symbol. */
|
/* XCOFF symbol. */
|
||||||
|
|
||||||
|
@ -586,7 +587,6 @@ xcoff_symname (const b_xcoff_syment *asym,
|
||||||
static int
|
static int
|
||||||
xcoff_initialize_syminfo (struct backtrace_state *state,
|
xcoff_initialize_syminfo (struct backtrace_state *state,
|
||||||
uintptr_t base_address,
|
uintptr_t base_address,
|
||||||
const b_xcoff_scnhdr *sects,
|
|
||||||
const b_xcoff_syment *syms, size_t nsyms,
|
const b_xcoff_syment *syms, size_t nsyms,
|
||||||
const unsigned char *strtab, size_t strtab_size,
|
const unsigned char *strtab, size_t strtab_size,
|
||||||
backtrace_error_callback error_callback, void *data,
|
backtrace_error_callback error_callback, void *data,
|
||||||
|
@ -628,8 +628,7 @@ xcoff_initialize_syminfo (struct backtrace_state *state,
|
||||||
{
|
{
|
||||||
const b_xcoff_auxent *aux = (const b_xcoff_auxent *) (asym + 1);
|
const b_xcoff_auxent *aux = (const b_xcoff_auxent *) (asym + 1);
|
||||||
xcoff_symbols[j].name = xcoff_symname (asym, strtab, strtab_size);
|
xcoff_symbols[j].name = xcoff_symname (asym, strtab, strtab_size);
|
||||||
xcoff_symbols[j].address = base_address + asym->n_value
|
xcoff_symbols[j].address = base_address + asym->n_value;
|
||||||
- sects[asym->n_scnum - 1].s_paddr;
|
|
||||||
/* x_fsize will be 0 if there is no debug information. */
|
/* x_fsize will be 0 if there is no debug information. */
|
||||||
xcoff_symbols[j].size = aux->x_fcn.x_fsize;
|
xcoff_symbols[j].size = aux->x_fcn.x_fsize;
|
||||||
++j;
|
++j;
|
||||||
|
@ -767,7 +766,7 @@ xcoff_lookup_pc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||||
lineno = (const b_xcoff_lineno *) lineptr;
|
lineno = (const b_xcoff_lineno *) lineptr;
|
||||||
if (lineno->l_lnno == 0)
|
if (lineno->l_lnno == 0)
|
||||||
break;
|
break;
|
||||||
if (pc <= fdata->base_address + lineno->l_addr.l_paddr - fn->sect_base)
|
if (pc <= fdata->base_address + lineno->l_addr.l_paddr)
|
||||||
break;
|
break;
|
||||||
match = lnnoptr;
|
match = lnnoptr;
|
||||||
lnno = lineno->l_lnno;
|
lnno = lineno->l_lnno;
|
||||||
|
@ -1002,7 +1001,7 @@ xcoff_initialize_fileline (struct backtrace_state *state,
|
||||||
fn->name = xcoff_symname (fsym, strtab, strtab_size);
|
fn->name = xcoff_symname (fsym, strtab, strtab_size);
|
||||||
fn->filename = filename;
|
fn->filename = filename;
|
||||||
fn->sect_base = sects[fsym->n_scnum - 1].s_paddr;
|
fn->sect_base = sects[fsym->n_scnum - 1].s_paddr;
|
||||||
fn->pc = base_address + fsym->n_value - fn->sect_base;
|
fn->pc = base_address + fsym->n_value;
|
||||||
fn->size = fsize;
|
fn->size = fsize;
|
||||||
fn->lnno = lnno;
|
fn->lnno = lnno;
|
||||||
fn->lnnoptr = lnnoptr;
|
fn->lnnoptr = lnnoptr;
|
||||||
|
@ -1153,8 +1152,16 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
|
|
||||||
stext = §s[i];
|
stext = §s[i];
|
||||||
|
|
||||||
/* AIX ldinfo_textorg includes the XCOFF headers. */
|
/* base_address represents the difference between the
|
||||||
base_address = (exe ? XCOFF_AIX_TEXTBASE : base_address) + stext->s_scnptr;
|
virtual memory address of the shared object or a loaded
|
||||||
|
executable and the offset of that object in the file
|
||||||
|
from which it was loaded.
|
||||||
|
On AIX, virtual address is either fixed for executable
|
||||||
|
or given by ldinfo. This address will include the XCOFF
|
||||||
|
headers. */
|
||||||
|
base_address = ((exe ? XCOFF_AIX_TEXTBASE : base_address)
|
||||||
|
+ stext->s_scnptr
|
||||||
|
- stext->s_paddr);
|
||||||
|
|
||||||
lnnoptr = stext->s_lnnoptr;
|
lnnoptr = stext->s_lnnoptr;
|
||||||
nlnno = stext->s_nlnno;
|
nlnno = stext->s_nlnno;
|
||||||
|
@ -1212,7 +1219,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
if (sdata == NULL)
|
if (sdata == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!xcoff_initialize_syminfo (state, base_address, sects,
|
if (!xcoff_initialize_syminfo (state, base_address,
|
||||||
syms_view.data, fhdr.f_nsyms,
|
syms_view.data, fhdr.f_nsyms,
|
||||||
str_view.data, str_size,
|
str_view.data, str_size,
|
||||||
error_callback, data, sdata))
|
error_callback, data, sdata))
|
||||||
|
@ -1252,7 +1259,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
case SSUBTYP_DWABREV:
|
case SSUBTYP_DWABREV:
|
||||||
idx = DEBUG_ABBREV;
|
idx = DEBUG_ABBREV;
|
||||||
break;
|
break;
|
||||||
case SSUBTYP_DWARNGE:
|
case SSUBTYP_DWRNGES:
|
||||||
idx = DEBUG_RANGES;
|
idx = DEBUG_RANGES;
|
||||||
break;
|
break;
|
||||||
case SSUBTYP_DWSTR:
|
case SSUBTYP_DWSTR:
|
||||||
|
@ -1290,13 +1297,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
|
|
||||||
dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data;
|
dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data;
|
||||||
dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size;
|
dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size;
|
||||||
#if BACKTRACE_XCOFF_SIZE == 32
|
dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data;
|
||||||
/* XXX workaround for broken lineoff */
|
|
||||||
dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 4;
|
|
||||||
#else
|
|
||||||
/* XXX workaround for broken lineoff */
|
|
||||||
dwarf_sections.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data - 12;
|
|
||||||
#endif
|
|
||||||
dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size;
|
dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size;
|
||||||
dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data;
|
dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data;
|
||||||
dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size;
|
dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size;
|
||||||
|
@ -1305,7 +1306,7 @@ xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
|
||||||
dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data;
|
dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data;
|
||||||
dwarf_sections.size[DEBUG_STR] = dwsect[DEBUG_STR].size;
|
dwarf_sections.size[DEBUG_STR] = dwsect[DEBUG_STR].size;
|
||||||
|
|
||||||
if (!backtrace_dwarf_add (state, 0, &dwarf_sections,
|
if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
|
||||||
1, /* big endian */
|
1, /* big endian */
|
||||||
NULL, /* altlink */
|
NULL, /* altlink */
|
||||||
error_callback, data, fileline_fn,
|
error_callback, data, fileline_fn,
|
||||||
|
|
Loading…
Reference in New Issue