libbacktrace: support returning discriminator field

Based on patch from Andi Kleen.

	* backtrace.h (backtrace_create_state): Rewrite comment to change
	threaded parameter to flags.
	(backtrace_full_callback, backtrace_syminfo_callback): Document
	behavior change if moredata flag is set.
	(struct backtrace_moredata): Define.
	* backtrace-supported.h.in (BACKTRACE_SUPPORTS_MOREDATA): Define.
	* internal.h (struct backtrace_state): Add moredata field.
	(BACKTRACE_MOREDATA_VERSION): Define.
	* state.c (backtrace_create_state): Change threaded parameter to
	flags.  Set state moredata field based on flags.
	* dwarf.c (struct line): Add disc field.
	(struct function): Add caller_disc field.
	(call_callback): New static function.
	(add_line): Add disc parameter.  Change all callers.  Store disc
	in new line value.
	(read_line_program): Track discriminator value.
	(read_line_info): Initialize disc field in final line entry.
	(read_function_entry): Handle DW_AT_GNU_discriminator.
	(report_inlined_functions): Add disc parameter. Change all
	callers. Call call_callback rather than calling callback
	directly.
	(dwarf_lookup_pc): Handle inlined discriminators. Call
	call_callback rather than calling callback directly.
	(dwarf_fileline): Call call_callback rather than calling callback
	directly.
	* elf.c (elf_syminfo): Pass moredata if requested.
	* macho.c (macho_syminfo): Likewise.
	* pecoff.c (coff_syminfo): Likewise.
	* xcoff.c (xcoff_syminfo): Likewise.
	(xcoff_lookup_pc): Likewise.
	* backtrace.c: #include <string.h>.
	(unwind): Pass moredata if requested.
	* unknown.c: #include <string.h>.
	(unknown_fileline): Pass moredata if requested.
	* fileline.c (backtrace_syminfo_to_full_callback): Add comment
	about moredata.
	* mdtest.c: New test file.
	* Makefile.am (mdtest_SOURCES): Define.
	(mdtest_CFLAGS, mdtest_LDFLAGS, mdtest_LDADD): Define.
	(BUILDTESTS): Add mdtest.
	* Makefile.in: Regenerate.
This commit is contained in:
Ian Lance Taylor
2026-07-06 12:42:21 -07:00
parent 5f4a6d4941
commit 6f8310e238
15 changed files with 635 additions and 75 deletions
+38 -5
View File
@@ -512,6 +512,8 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
struct xcoff_syminfo_data *edata;
struct xcoff_symbol *sym = NULL;
const char *name;
void *mdata;
struct backtrace_moredata md;
if (!state->threaded)
{
@@ -547,15 +549,25 @@ xcoff_syminfo (struct backtrace_state *state ATTRIBUTE_UNUSED, uintptr_t addr,
}
}
if (!state->moredata)
mdata = data;
else
{
memset (&md, 0, sizeof md);
md.backtrace_version = 3;
md.backtrace_data = data;
mdata = (void *) &md;
}
if (sym == NULL)
callback (data, addr, NULL, 0, 0);
callback (mdata, addr, NULL, 0, 0);
else
{
name = sym->name;
/* AIX prepends a '.' to function entry points, remove it. */
if (name && *name == '.')
++name;
callback (data, addr, name, sym->address, sym->size);
callback (mdata, addr, name, sym->address, sym->size);
}
}
@@ -723,7 +735,7 @@ xcoff_incl_search (const void *vkey, const void *ventry)
0 if not. */
static int
xcoff_lookup_pc (struct backtrace_state *state ATTRIBUTE_UNUSED,
xcoff_lookup_pc (struct backtrace_state *state,
struct xcoff_fileline_data *fdata, uintptr_t pc,
backtrace_full_callback callback,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
@@ -805,7 +817,18 @@ xcoff_lookup_pc (struct backtrace_state *state ATTRIBUTE_UNUSED,
/* AIX prepends a '.' to function entry points, remove it. */
if (function != NULL && *function == '.')
++function;
return callback (data, pc, filename, lnno, function);
if (!state->moredata)
return callback (data, pc, filename, lnno, function);
else
{
struct backtrace_moredata md;
memset (&md, 0, sizeof md);
md.backtrace_version = 3;
md.backtrace_data = data;
return callback ((void *) &md, pc, filename, lnno, function);
}
}
/* Return the file/line information for a PC using the XCOFF lineno
@@ -855,7 +878,17 @@ xcoff_fileline (struct backtrace_state *state, uintptr_t pc,
/* FIXME: See if any libraries have been dlopen'ed. */
return callback (data, pc, NULL, 0, NULL);
if (!state->moredata)
return callback (data, pc, NULL, 0, NULL);
else
{
struct backtrace_moredata md;
memset (&md, 0, sizeof md);
md.backtrace_version = 3;
md.backtrace_data = data;
return callback ((void *) data, pc, NULL, 0, NULL);
}
}
/* Initialize the function vector info for xcoff_fileline. */