When loading separate debug info files, also attempt to locate a file based upon the build-id.
PR 28697 * dwarf.c (load_build_id_debug_file): New function. (try_build_id_prefix): New function. (check_for_and_load_links): Call load_build_id_debug_file. (debug_displays): Add entry for .note.gnu.build-id. * dwarf.h (enum dwarf_section_display_enum): Add note_gnu_build_id. * testsuite/binutils-all/debuginfod.exp (test_fetch_debuglink): Fix regexp for loads via debuglink section.
This commit is contained in:
parent
a2b1ea81ba
commit
61ab1364c7
@ -1,3 +1,15 @@
|
|||||||
|
2021-12-16 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 28697
|
||||||
|
* dwarf.c (load_build_id_debug_file): New function.
|
||||||
|
(try_build_id_prefix): New function.
|
||||||
|
(check_for_and_load_links): Call load_build_id_debug_file.
|
||||||
|
(debug_displays): Add entry for .note.gnu.build-id.
|
||||||
|
* dwarf.h (enum dwarf_section_display_enum): Add
|
||||||
|
note_gnu_build_id.
|
||||||
|
* testsuite/binutils-all/debuginfod.exp (test_fetch_debuglink):
|
||||||
|
Fix regexp for loads via debuglink section.
|
||||||
|
|
||||||
2021-12-03 Chenghua Xu <xuchenghua@loongson.cn>
|
2021-12-03 Chenghua Xu <xuchenghua@loongson.cn>
|
||||||
|
|
||||||
* MAINTAINERS: Add myself and Zhensong Liu
|
* MAINTAINERS: Add myself and Zhensong Liu
|
||||||
|
116
binutils/dwarf.c
116
binutils/dwarf.c
@ -11292,6 +11292,117 @@ load_dwo_file (const char * main_filename, const char * name, const char * dir,
|
|||||||
return separate_handle;
|
return separate_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
try_build_id_prefix (const char * prefix, char * filename, const unsigned char * data, unsigned long id_len)
|
||||||
|
{
|
||||||
|
char * f = filename;
|
||||||
|
|
||||||
|
f += sprintf (f, prefix);
|
||||||
|
f += sprintf (f, ".build-id/%02x/", (unsigned) *data++);
|
||||||
|
id_len --;
|
||||||
|
while (id_len --)
|
||||||
|
f += sprintf (f, "%02x", (unsigned) *data++);
|
||||||
|
f += sprintf (f, ".debug");
|
||||||
|
|
||||||
|
return open_debug_file (filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to load a debug file based upon the build-id held in the .note.gnu.build-id section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_build_id_debug_file (const char * main_filename, void * main_file)
|
||||||
|
{
|
||||||
|
if (! load_debug_section (note_gnu_build_id, main_file))
|
||||||
|
return; /* No .note.gnu.build-id section. */
|
||||||
|
|
||||||
|
struct dwarf_section * section = & debug_displays [note_gnu_build_id].section;
|
||||||
|
if (section == NULL)
|
||||||
|
{
|
||||||
|
warn (_("Unable to load the .note.gnu.build-id section\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (section->start == NULL || section->size < 0x18)
|
||||||
|
{
|
||||||
|
warn (_(".note.gnu.build-id section is corrupt/empty\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In theory we should extract the contents of the section into
|
||||||
|
a note structure and then check the fields. For now though
|
||||||
|
just use hard coded offsets instead:
|
||||||
|
|
||||||
|
Field Bytes Contents
|
||||||
|
NSize 0...3 4
|
||||||
|
DSize 4...7 8+
|
||||||
|
Type 8..11 3 (NT_GNU_BUILD_ID)
|
||||||
|
Name 12.15 GNU\0
|
||||||
|
Data 16.... */
|
||||||
|
|
||||||
|
/* FIXME: Check the name size, name and type fields. */
|
||||||
|
|
||||||
|
unsigned long build_id_size;
|
||||||
|
build_id_size = byte_get (section->start + 4, 4);
|
||||||
|
if (build_id_size < 8)
|
||||||
|
{
|
||||||
|
warn (_(".note.gnu.build-id data size is too small\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build_id_size > (section->size - 16))
|
||||||
|
{
|
||||||
|
warn (_(".note.gnu.build-id data size is too bug\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * filename;
|
||||||
|
filename = xmalloc (strlen (".build-id/")
|
||||||
|
+ build_id_size * 2 + 2
|
||||||
|
+ strlen (".debug")
|
||||||
|
/* The next string should be the same as the longest
|
||||||
|
name found in the prefixes[] array below. */
|
||||||
|
+ strlen ("/usrlib64/debug/usr")
|
||||||
|
+ 1);
|
||||||
|
void * handle;
|
||||||
|
|
||||||
|
static const char * prefixes[] =
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
".debug/",
|
||||||
|
"/usr/lib/debug/",
|
||||||
|
"/usr/lib/debug/usr/",
|
||||||
|
"/usr/lib64/debug/",
|
||||||
|
"/usr/lib64/debug/usr"
|
||||||
|
};
|
||||||
|
long unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (prefixes); i++)
|
||||||
|
{
|
||||||
|
handle = try_build_id_prefix (prefixes[i], filename,
|
||||||
|
section->start + 16, build_id_size);
|
||||||
|
if (handle != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FIXME: TYhe BFD library also tries a global debugfile directory prefix. */
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
/* Failed to find a debug file associated with the build-id.
|
||||||
|
This is not an error however, rather it just means that
|
||||||
|
the debug info has probably not been loaded on the system,
|
||||||
|
or that another method is being used to link to the debug
|
||||||
|
info. */
|
||||||
|
free (filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf (_("%s: Found build-id indexed debug file: %s\n\n"),
|
||||||
|
main_filename, filename);
|
||||||
|
|
||||||
|
add_separate_debug_file (filename, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to load a debug file pointed to by the .debug_sup section. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_debug_sup_file (const char * main_filename, void * file)
|
load_debug_sup_file (const char * main_filename, void * file)
|
||||||
{
|
{
|
||||||
@ -11409,6 +11520,8 @@ check_for_and_load_links (void * file, const char * filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
load_debug_sup_file (filename, file);
|
load_debug_sup_file (filename, file);
|
||||||
|
|
||||||
|
load_build_id_debug_file (filename, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the separate debug info file(s) attached to FILE, if any exist.
|
/* Load the separate debug info file(s) attached to FILE, if any exist.
|
||||||
@ -11779,7 +11892,8 @@ struct dwarf_section_display debug_displays[] =
|
|||||||
/* Separate debug info files can containt their own .debug_str section,
|
/* Separate debug info files can containt their own .debug_str section,
|
||||||
and this might be in *addition* to a .debug_str section already present
|
and this might be in *addition* to a .debug_str section already present
|
||||||
in the main file. Hence we need to have two entries for .debug_str. */
|
in the main file. Hence we need to have two entries for .debug_str. */
|
||||||
{ { ".debug_str", ".zdebug_str", "", NO_ABBREVS }, display_debug_str, &do_debug_str, false },
|
{ { ".debug_str", ".zdebug_str", "", NO_ABBREVS }, display_debug_str, &do_debug_str, false },
|
||||||
|
{ { ".note.gnu.build-id", "", "", NO_ABBREVS }, display_debug_not_supported, NULL, false },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A static assertion. */
|
/* A static assertion. */
|
||||||
|
@ -122,6 +122,7 @@ enum dwarf_section_display_enum
|
|||||||
gnu_debugaltlink,
|
gnu_debugaltlink,
|
||||||
debug_sup,
|
debug_sup,
|
||||||
separate_debug_str,
|
separate_debug_str,
|
||||||
|
note_gnu_build_id,
|
||||||
max
|
max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,10 +161,10 @@ proc test_fetch_debuglink { prog progargs } {
|
|||||||
|
|
||||||
set got [binutils_run $prog "$progargs tmpdir/testprog"]
|
set got [binutils_run $prog "$progargs tmpdir/testprog"]
|
||||||
|
|
||||||
if { [regexp ".*Found separate debug info file.*Contents\[^\n\]*loaded from\[^\n\]*$cache.*" $got] } {
|
if { [regexp ".*Found separate debug info file.*Contents\[^\n\]*loaded from\[^\n\]*" $got] } {
|
||||||
pass "$test ($prog debuglink)"
|
pass "$test ($prog debuglink)"
|
||||||
} else {
|
} else {
|
||||||
fail "$test ($prog debuglink)"
|
fail "$test ($prog did not find debuglink to cache $cache)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ proc test_fetch_debugaltlink { prog progargs } {
|
|||||||
if { [regexp ".*Found separate debug info file\[^\n\]*$cache/$buildid" $got] } {
|
if { [regexp ".*Found separate debug info file\[^\n\]*$cache/$buildid" $got] } {
|
||||||
pass "$test ($prog debugaltlink)"
|
pass "$test ($prog debugaltlink)"
|
||||||
} else {
|
} else {
|
||||||
fail "$test ($prog debugaltlink)"
|
fail "$test ($prog could not load debugaltlink)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user