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 = &sects[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,