crates/backtrace-sys2/src/libbacktrace/xcoff.c in pf2-0.6.0 vs crates/backtrace-sys2/src/libbacktrace/xcoff.c in pf2-0.7.0
- old
+ new
@@ -1,7 +1,7 @@
/* xcoff.c -- Get debug data from an XCOFF file for backtraces.
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
+ Copyright (C) 2012-2024 Free Software Foundation, Inc.
Adapted from elf.c.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
@@ -131,10 +131,11 @@
#define SSUBTYP_DWINFO 0x10000 /* DWARF info section. */
#define SSUBTYP_DWLINE 0x20000 /* DWARF line-number section. */
#define SSUBTYP_DWARNGE 0x50000 /* DWARF aranges section. */
#define SSUBTYP_DWABREV 0x60000 /* DWARF abbreviation section. */
#define SSUBTYP_DWSTR 0x70000 /* DWARF strings section. */
+#define SSUBTYP_DWRNGES 0x80000 /* DWARF ranges section. */
/* XCOFF symbol. */
#define SYMNMLEN 8
@@ -382,11 +383,11 @@
/* Line numbers information. */
const unsigned char *linenos;
size_t linenos_size;
uint64_t lnnoptr0;
/* Loader address. */
- uintptr_t base_address;
+ struct libbacktrace_base_address base_address;
};
/* Information we gather for the DWARF sections we care about. */
struct dwsect_info
@@ -583,12 +584,11 @@
/* Initialize the symbol table info for xcoff_syminfo. */
static int
xcoff_initialize_syminfo (struct backtrace_state *state,
- uintptr_t base_address,
- const b_xcoff_scnhdr *sects,
+ struct libbacktrace_base_address base_address,
const b_xcoff_syment *syms, size_t nsyms,
const unsigned char *strtab, size_t strtab_size,
backtrace_error_callback error_callback, void *data,
struct xcoff_syminfo_data *sdata)
{
@@ -626,12 +626,12 @@
|| asym->n_sclass == C_WEAKEXT)
&& ISFCN (asym->n_type) && asym->n_numaux > 0 && asym->n_scnum > 0)
{
const b_xcoff_auxent *aux = (const b_xcoff_auxent *) (asym + 1);
xcoff_symbols[j].name = xcoff_symname (asym, strtab, strtab_size);
- xcoff_symbols[j].address = base_address + asym->n_value
- - sects[asym->n_scnum - 1].s_paddr;
+ xcoff_symbols[j].address =
+ libbacktrace_add_base (asym->n_value, base_address);
/* x_fsize will be 0 if there is no debug information. */
xcoff_symbols[j].size = aux->x_fcn.x_fsize;
++j;
}
@@ -765,11 +765,12 @@
while (lineptr + LINESZ <= fdata->linenos + fdata->linenos_size)
{
lineno = (const b_xcoff_lineno *) lineptr;
if (lineno->l_lnno == 0)
break;
- if (pc <= fdata->base_address + lineno->l_addr.l_paddr - fn->sect_base)
+ if (pc <= libbacktrace_add_base (lineno->l_addr.l_paddr,
+ fdata->base_address))
break;
match = lnnoptr;
lnno = lineno->l_lnno;
lnnoptr += LINESZ;
@@ -859,11 +860,11 @@
/* Initialize the function vector info for xcoff_fileline. */
static int
xcoff_initialize_fileline (struct backtrace_state *state,
- uintptr_t base_address,
+ struct libbacktrace_base_address base_address,
const b_xcoff_scnhdr *sects,
const b_xcoff_syment *syms, size_t nsyms,
const unsigned char *strtab, size_t strtab_size,
const unsigned char *linenos, size_t linenos_size,
uint64_t lnnoptr0,
@@ -1000,11 +1001,11 @@
if (fn == NULL)
break;
fn->name = xcoff_symname (fsym, strtab, strtab_size);
fn->filename = filename;
fn->sect_base = sects[fsym->n_scnum - 1].s_paddr;
- fn->pc = base_address + fsym->n_value - fn->sect_base;
+ fn->pc = libbacktrace_add_base (fsym->n_value, base_address);
fn->size = fsize;
fn->lnno = lnno;
fn->lnnoptr = lnnoptr;
++fdata->func_vec.count;
break;
@@ -1069,11 +1070,12 @@
/* Add the backtrace data for one XCOFF file. Returns 1 on success,
0 on failure (in both cases descriptor is closed). */
static int
xcoff_add (struct backtrace_state *state, int descriptor, off_t offset,
- uintptr_t base_address, backtrace_error_callback error_callback,
+ struct libbacktrace_base_address base_address,
+ backtrace_error_callback error_callback,
void *data, fileline *fileline_fn, int *found_sym, int exe)
{
struct backtrace_view fhdr_view;
struct backtrace_view sects_view;
struct backtrace_view linenos_view;
@@ -1151,12 +1153,20 @@
if (i == fhdr.f_nscns)
goto fail;
stext = §s[i];
- /* AIX ldinfo_textorg includes the XCOFF headers. */
- base_address = (exe ? XCOFF_AIX_TEXTBASE : base_address) + stext->s_scnptr;
+ /* base_address represents the difference between the
+ 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.m = ((exe ? XCOFF_AIX_TEXTBASE : base_address.m)
+ + stext->s_scnptr
+ - stext->s_paddr);
lnnoptr = stext->s_lnnoptr;
nlnno = stext->s_nlnno;
#if BACKTRACE_XCOFF_SIZE == 32
@@ -1191,11 +1201,13 @@
syms_size + 4, error_callback, data,
&syms_view))
goto fail;
syms_view_valid = 1;
- memcpy (&str_size, syms_view.data + syms_size, 4);
+ memcpy (&str_size,
+ (const unsigned char *) syms_view.data + syms_size,
+ 4);
str_off = fhdr.f_symptr + syms_size;
if (str_size > 4)
{
@@ -1210,11 +1222,11 @@
sdata = ((struct xcoff_syminfo_data *)
backtrace_alloc (state, sizeof *sdata, error_callback, data));
if (sdata == NULL)
goto fail;
- if (!xcoff_initialize_syminfo (state, base_address, sects,
+ if (!xcoff_initialize_syminfo (state, base_address,
syms_view.data, fhdr.f_nsyms,
str_view.data, str_size,
error_callback, data, sdata))
{
backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
@@ -1250,11 +1262,11 @@
idx = DEBUG_LINE;
break;
case SSUBTYP_DWABREV:
idx = DEBUG_ABBREV;
break;
- case SSUBTYP_DWARNGE:
+ case SSUBTYP_DWRNGES:
idx = DEBUG_RANGES;
break;
case SSUBTYP_DWSTR:
idx = DEBUG_STR;
break;
@@ -1288,26 +1300,20 @@
memset (&dwarf_sections, 0, sizeof dwarf_sections);
dwarf_sections.data[DEBUG_INFO] = dwsect[DEBUG_INFO].data;
dwarf_sections.size[DEBUG_INFO] = dwsect[DEBUG_INFO].size;
-#if BACKTRACE_XCOFF_SIZE == 32
- /* 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.data[DEBUG_LINE] = dwsect[DEBUG_LINE].data;
dwarf_sections.size[DEBUG_LINE] = dwsect[DEBUG_LINE].size;
dwarf_sections.data[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].data;
dwarf_sections.size[DEBUG_ABBREV] = dwsect[DEBUG_ABBREV].size;
dwarf_sections.data[DEBUG_RANGES] = dwsect[DEBUG_RANGES].data;
dwarf_sections.size[DEBUG_RANGES] = dwsect[DEBUG_RANGES].size;
dwarf_sections.data[DEBUG_STR] = dwsect[DEBUG_STR].data;
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 */
NULL, /* altlink */
error_callback, data, fileline_fn,
NULL /* returned fileline_entry */))
goto fail;
@@ -1388,13 +1394,13 @@
/* Add the backtrace data for a member of an AIX big archive.
Returns 1 on success, 0 on failure. */
static int
xcoff_armem_add (struct backtrace_state *state, int descriptor,
- uintptr_t base_address, const char *member,
- backtrace_error_callback error_callback, void *data,
- fileline *fileline_fn, int *found_sym)
+ struct libbacktrace_base_address base_address,
+ const char *member, backtrace_error_callback error_callback,
+ void *data, fileline *fileline_fn, int *found_sym)
{
struct backtrace_view view;
b_ar_fl_hdr fl_hdr;
const b_ar_hdr *ar_hdr;
off_t off;
@@ -1511,10 +1517,12 @@
}
ldinfo = (const struct ld_info *) buf;
while ((const char *) ldinfo < (const char *) buf + buflen)
{
+ struct libbacktrace_base_address base_address;
+
if (*ldinfo->ldinfo_filename != '/')
goto next;
descriptor = backtrace_open (ldinfo->ldinfo_filename, error_callback,
data, &does_not_exist);
@@ -1522,20 +1530,21 @@
goto next;
/* Check if it is an archive (member name not empty). */
member = ldinfo->ldinfo_filename + strlen (ldinfo->ldinfo_filename) + 1;
+ memset (&base_address, 0, sizeof base_address);
+ base_address.m = (uintptr_t) ldinfo->ldinfo_textorg;
if (*member)
{
- xcoff_armem_add (state, descriptor,
- (uintptr_t) ldinfo->ldinfo_textorg, member,
+ xcoff_armem_add (state, descriptor, base_address, member,
error_callback, data, fileline_fn, &lib_found_sym);
}
else
{
- xcoff_add (state, descriptor, 0, (uintptr_t) ldinfo->ldinfo_textorg,
- error_callback, data, fileline_fn, &lib_found_sym, 0);
+ xcoff_add (state, descriptor, 0, base_address, error_callback, data,
+ fileline_fn, &lib_found_sym, 0);
}
if (lib_found_sym)
*found_sym = 1;
next:
@@ -1556,15 +1565,17 @@
backtrace_initialize (struct backtrace_state *state,
const char *filename ATTRIBUTE_UNUSED, int descriptor,
backtrace_error_callback error_callback,
void *data, fileline *fileline_fn)
{
+ struct libbacktrace_base_address zero_base_address;
int ret;
int found_sym;
fileline xcoff_fileline_fn = xcoff_nodebug;
- ret = xcoff_add (state, descriptor, 0, 0, error_callback, data,
- &xcoff_fileline_fn, &found_sym, 1);
+ memset (&zero_base_address, 0, sizeof zero_base_address);
+ ret = xcoff_add (state, descriptor, 0, zero_base_address,
+ error_callback, data, &xcoff_fileline_fn, &found_sym, 1);
if (!ret)
return 0;
#ifdef HAVE_LOADQUERY
xcoff_add_shared_libs (state, error_callback, data, &xcoff_fileline_fn,