summaryrefslogtreecommitdiffstats
path: root/libdwfl/find-debuginfo.c
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2007-10-04 08:50:09 +0000
committerRoland McGrath <[email protected]>2007-10-04 08:50:09 +0000
commit59ea7f33f781e6e3f8c9d81d457e5d99eee8f1ce (patch)
tree10a3dd35d3b568876f0edc6dd903fe8715a507e1 /libdwfl/find-debuginfo.c
parent057ec6b35ef97bd1cf6c1e96da3da399237e5224 (diff)
src/
2007-10-04 Roland McGrath <[email protected]> * readelf.c (print_archive_index): New variable. (options, parse_opt): Accept -c/--archive-index to set it. (dump_archive_index): New function. (process_file): Take new arg WILL_PRINT_ARCHIVE_INDEX. Call dump_archive_index on archives if set. (main): Update caller. (any_control_option): Give it file scope, moved out of ... (parse_opt): ... here. tests/ 2007-10-04 Roland McGrath <[email protected]> * run-readelf-test4.sh: New file. * Makefile.am (TESTS, EXTRA_DIST): Add it.
Diffstat (limited to 'libdwfl/find-debuginfo.c')
-rw-r--r--libdwfl/find-debuginfo.c71
1 files changed, 61 insertions, 10 deletions
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index ca1fadcb..f1ff3a4b 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -90,15 +90,37 @@ check_crc (int fd, GElf_Word debuglink_crc)
&& file_crc == debuglink_crc);
}
-int
-dwfl_standard_find_debuginfo (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *modname __attribute__ ((unused)),
- GElf_Addr base __attribute__ ((unused)),
- const char *file_name,
- const char *debuglink_file,
- GElf_Word debuglink_crc,
- char **debuginfo_file_name)
+static bool
+validate (Dwfl_Module *mod, int fd, bool check, GElf_Word debuglink_crc)
+{
+ /* If we have a build ID, check only that. */
+ if (mod->build_id_len > 0)
+ {
+ /* We need to open an Elf handle on the file so we can check its
+ build ID note for validation. Backdoor the handle into the
+ module data structure since we had to open it early anyway. */
+ mod->debug.elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+ if (likely (__libdwfl_find_build_id (mod, false, mod->debug.elf) == 2))
+ /* Also backdoor the gratuitous flag. */
+ mod->debug.valid = true;
+ else
+ {
+ /* A mismatch! */
+ elf_end (mod->debug.elf);
+ mod->debug.elf = NULL;
+ mod->debug.valid = false;
+ }
+
+ return mod->debug.valid;
+ }
+
+ return !check || check_crc (fd, debuglink_crc);
+}
+
+static int
+find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
+ const char *debuglink_file, GElf_Word debuglink_crc,
+ char **debuginfo_file_name)
{
bool cancheck = debuglink_crc != (GElf_Word) 0;
@@ -181,7 +203,7 @@ dwfl_standard_find_debuginfo (Dwfl_Module *mod,
default:
return -1;
}
- if (!check || check_crc (fd, debuglink_crc))
+ if (validate (mod, fd, check, debuglink_crc))
{
*debuginfo_file_name = fname;
return fd;
@@ -194,4 +216,33 @@ dwfl_standard_find_debuginfo (Dwfl_Module *mod,
errno = 0;
return -1;
}
+
+int
+dwfl_standard_find_debuginfo (Dwfl_Module *mod,
+ void **userdata __attribute__ ((unused)),
+ const char *modname __attribute__ ((unused)),
+ GElf_Addr base __attribute__ ((unused)),
+ const char *file_name,
+ const char *debuglink_file,
+ GElf_Word debuglink_crc,
+ char **debuginfo_file_name)
+{
+ /* First try by build ID if we have one. If that succeeds or fails
+ other than just by finding nothing, that's all we do. */
+ const unsigned char *bits;
+ GElf_Addr vaddr;
+ if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
+ {
+ int fd = INTUSE(dwfl_build_id_find_debuginfo) (mod,
+ NULL, NULL, 0,
+ NULL, NULL, 0,
+ debuginfo_file_name);
+ if (fd >= 0 || errno != 0)
+ return fd;
+ }
+
+ /* Failing that, search the path by name. */
+ return find_debuginfo_in_path (mod, file_name, debuglink_file, debuglink_crc,
+ debuginfo_file_name);
+}
INTDEF (dwfl_standard_find_debuginfo)