diff options
| author | Mark Wielaard <[email protected]> | 2014-05-01 14:48:27 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2014-05-02 17:00:48 +0200 |
| commit | df85bf99021119fcbb2ced66dd69f1cceafb180c (patch) | |
| tree | a0ee033052e69b9b00e87ee31bf4962dac3cec17 /libdwfl | |
| parent | d81d32d2a4f92355e4c677b578147dfe819251b9 (diff) | |
libdwfl: Move dwz alt multi file searching to find_debuginfo callback.
Don't hard code the Dwarf dwz alt multi file search but allow the user
to override it through the standard Dwfl_Callbacks. Also move ownership
completely to the user of dwarf_setalt by removing free_alt from Dwarf
and adding alt, fd and elf fields to Dwfl_Module. Add a relative .dwz
file test case.
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdwfl')
| -rw-r--r-- | libdwfl/ChangeLog | 33 | ||||
| -rw-r--r-- | libdwfl/dwfl_build_id_find_debuginfo.c | 55 | ||||
| -rw-r--r-- | libdwfl/dwfl_build_id_find_elf.c | 32 | ||||
| -rw-r--r-- | libdwfl/dwfl_module.c | 14 | ||||
| -rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 208 | ||||
| -rw-r--r-- | libdwfl/find-debuginfo.c | 98 | ||||
| -rw-r--r-- | libdwfl/libdwflP.h | 10 | ||||
| -rw-r--r-- | libdwfl/linux-kernel-modules.c | 11 |
8 files changed, 314 insertions, 147 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 7e4234db..a33bd25a 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,36 @@ +2014-05-01 Mark Wielaard <[email protected]> + + * libdwflP.h (struct Dwfl_Module): Add alt, alt_fd and alt_elf fields. + (__libdwfl_open_mod_by_build_id): Renamed __libdwfl_open_by_build_id. + (__libdwfl_open_by_build_id): New declaration that takes an explicit + build-id. + * dwfl_build_id_find_debuginfo.c (dwfl_build_id_find_debuginfo): If + we already have the Dwarf then look for the alt dwz multi file by + build-id. + * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Add the + build-id we are looking for as argument. + (__libdwfl_open_mod_by_build_id): New function, calls + __libdwfl_open_by_build_id. + (dwfl_build_id_find_elf): Call __libdwfl_open_mod_by_build_id. + * dwfl_module.c (__libdwfl_module_free): Release alt, alt_elf and + close alt_fd if necessary. + * dwfl_module_getdwarf.c (__check_build_id): Removed. + (try_debugaltlink): Removed. + (open_debugaltlink): Removed. + (open_elf_file): First half of open_elf that just opens the elf + file but doesn't setup the load address. + (open_elf): Call open_elf_file. + (find_debug_altlink): New function. + (load_dw): Remove loading of dwz multifile. + (find_dw): Call find_debug_altlink. + * find-debuginfo.c (validate): Handle alt debug case using + dwelf_dwarf_gnu_debugaltlink and mod->alt_elf. + (find_debuginfo_in_path): Handle alt debug files possibly in .dwz + subdirs. + * linux-kernel-modules.c (try_kernel_name): Use fakemod.debug.name + to store name to find by dwfl_standard_find_debuginfo instead of + allocating an extra variable on stack. + 2014-04-30 Mark Wielaard <[email protected]> * dwfl_module_build_id.c (__libdwfl_find_elf_build_id): Moved to diff --git a/libdwfl/dwfl_build_id_find_debuginfo.c b/libdwfl/dwfl_build_id_find_debuginfo.c index a955735c..f1c64bcd 100644 --- a/libdwfl/dwfl_build_id_find_debuginfo.c +++ b/libdwfl/dwfl_build_id_find_debuginfo.c @@ -1,5 +1,5 @@ /* Find the debuginfo file for a module from its build ID. - Copyright (C) 2007, 2009 Red Hat, Inc. + Copyright (C) 2007, 2009, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -41,10 +41,61 @@ dwfl_build_id_find_debuginfo (Dwfl_Module *mod, char **debuginfo_file_name) { int fd = -1; + + /* Are we looking for a separate debug file for the main file or for + an alternate (dwz multi) debug file? Alternatively we could check + whether the dwbias == -1. */ + if (mod->dw != NULL) + { + const void *build_id; + const char *altname; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + if (build_id_len > 0) + fd = __libdwfl_open_by_build_id (mod, true, debuginfo_file_name, + build_id_len, build_id); + + if (fd >= 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. */ + Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf, + true, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else + { + const void *alt_build_id; + ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf, + &alt_build_id); + if (alt_len > 0 && alt_len == build_id_len + && memcmp (build_id, alt_build_id, alt_len) == 0) + return fd; + else + { + /* A mismatch! */ + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (fd); + fd = -1; + } + free (*debuginfo_file_name); + *debuginfo_file_name = NULL; + errno = 0; + } + } + return fd; + } + + /* We don't even have the Dwarf yet and it isn't in the main file. + Try to find separate debug file now using the module build id. */ const unsigned char *bits; GElf_Addr vaddr; + if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0) - fd = __libdwfl_open_by_build_id (mod, true, debuginfo_file_name); + fd = __libdwfl_open_mod_by_build_id (mod, true, debuginfo_file_name); if (fd >= 0) { /* We need to open an Elf handle on the file so we can check its diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c index a4f03263..15550082 100644 --- a/libdwfl/dwfl_build_id_find_elf.c +++ b/libdwfl/dwfl_build_id_find_elf.c @@ -1,5 +1,5 @@ /* Find an ELF file for a module from its build ID. - Copyright (C) 2007-2010 Red Hat, Inc. + Copyright (C) 2007-2010, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -34,17 +34,9 @@ int internal_function -__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name) +__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name, + const size_t id_len, const uint8_t *id) { - /* If *FILE_NAME was primed into the module, leave it there - as the fallback when we have nothing to offer. */ - errno = 0; - if (mod->build_id_len <= 0) - return -1; - - const size_t id_len = mod->build_id_len; - const uint8_t *id = mod->build_id_bits; - /* Search debuginfo_path directories' .build-id/ subdirectories. */ char id_name[sizeof "/.build-id/" + 1 + id_len * 2 + sizeof ".debug" - 1]; @@ -109,6 +101,22 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name) } int +internal_function +__libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, char **file_name) +{ + /* If *FILE_NAME was primed into the module, leave it there + as the fallback when we have nothing to offer. */ + errno = 0; + if (mod->build_id_len <= 0) + return -1; + + const size_t id_len = mod->build_id_len; + const uint8_t *id = mod->build_id_bits; + + return __libdwfl_open_by_build_id (mod, debug, file_name, id_len, id); +} + +int dwfl_build_id_find_elf (Dwfl_Module *mod, void **userdata __attribute__ ((unused)), const char *modname __attribute__ ((unused)), @@ -133,7 +141,7 @@ dwfl_build_id_find_elf (Dwfl_Module *mod, close (fd); } } - int fd = __libdwfl_open_by_build_id (mod, false, file_name); + int fd = __libdwfl_open_mod_by_build_id (mod, false, file_name); if (fd >= 0) { Dwfl_Error error = __libdw_open_file (&fd, elfp, true, false); diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c index bb167ab2..8efcfaa5 100644 --- a/libdwfl/dwfl_module.c +++ b/libdwfl/dwfl_module.c @@ -1,5 +1,5 @@ /* Maintenance of module list in libdwfl. - Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc. + Copyright (C) 2005, 2006, 2007, 2008, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -71,7 +71,17 @@ __libdwfl_module_free (Dwfl_Module *mod) } if (mod->dw != NULL) - INTUSE(dwarf_end) (mod->dw); + { + INTUSE(dwarf_end) (mod->dw); + if (mod->alt != NULL) + { + INTUSE(dwarf_end) (mod->alt); + if (mod->alt_elf != NULL) + elf_end (mod->alt_elf); + if (mod->alt_fd != -1) + close (mod->alt_fd); + } + } if (mod->ebl != NULL) ebl_closebackend (mod->ebl); diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index e8087bfb..293e8e75 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -34,99 +34,10 @@ #include "../libdw/libdwP.h" /* DWARF_E_* values are here. */ #include "../libelf/libelfP.h" -#ifdef ENABLE_DWZ -internal_function int -__check_build_id (Dwarf *dw, const uint8_t *build_id, const size_t id_len) -{ - if (dw == NULL) - return -1; - - Elf *elf = dw->elf; - const void *elf_build_id; - ssize_t elf_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id); - if (elf_id_len < 0) - return -1; - - return (id_len == (size_t) elf_id_len - && memcmp (build_id, elf_build_id, id_len) == 0) ? 0 : 1; -} - -/* Try to open an debug alt link by name, checking build_id. - Marks free_alt on success, return NULL on failure. */ -static Dwarf * -try_debugaltlink (Dwarf *result, const char *try_name, - const uint8_t *build_id, const size_t id_len) -{ - int fd = open (try_name, O_RDONLY); - if (fd > 0) - { - Dwarf *alt_dwarf = INTUSE (dwarf_begin) (fd, DWARF_C_READ); - if (alt_dwarf != NULL) - { - Elf *elf = alt_dwarf->elf; - if (__check_build_id (alt_dwarf, build_id, id_len) == 0 - && elf_cntl (elf, ELF_C_FDREAD) == 0) - { - close (fd); - INTUSE (dwarf_setalt) (result, alt_dwarf); - result->free_alt = true; - return result; - } - INTUSE (dwarf_end) (result->alt_dwarf); - } - close (fd); - } - return NULL; -} - -/* For dwz multifile support, ignore if it looks wrong. */ -static Dwarf * -open_debugaltlink (Dwarf *result, const char *alt_name, - const uint8_t *build_id, const size_t id_len) -{ - /* First try the name itself, it is either an absolute path or - a relative one. Sadly we don't know relative from where at - this point. */ - if (try_debugaltlink (result, alt_name, build_id, id_len) != NULL) - return result; - - /* Lets try based on the build-id. This is somewhat distro specific, - we are following the Fedora implementation described at - https://fedoraproject.org/wiki/Releases/FeatureBuildId#Find_files_by_build_ID - */ -#define DEBUG_PREFIX "/usr/lib/debug/.build-id/" -#define PREFIX_LEN sizeof (DEBUG_PREFIX) - char id_name[PREFIX_LEN + 1 + id_len * 2 + sizeof ".debug" - 1]; - strcpy (id_name, DEBUG_PREFIX); - int n = snprintf (&id_name[PREFIX_LEN - 1], - 4, "%02" PRIx8 "/", (uint8_t) build_id[0]); - assert (n == 3); - for (size_t i = 1; i < id_len; ++i) - { - n = snprintf (&id_name[PREFIX_LEN - 1 + 3 + (i - 1) * 2], - 3, "%02" PRIx8, (uint8_t) build_id[i]); - assert (n == 2); - } - strcpy (&id_name[PREFIX_LEN - 1 + 3 + (id_len - 1) * 2], - ".debug"); - - if (try_debugaltlink (result, id_name, build_id, id_len)) - return result; - - /* Everything failed, mark this Dwarf as not having an alternate, - but don't fail the load. The user may want to set it by hand - before usage. */ - result->alt_dwarf = NULL; - return result; -} -#endif /* ENABLE_DWZ */ - -/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD. - When we return success, FILE->elf and FILE->vaddr are set up. */ static inline Dwfl_Error -open_elf (Dwfl_Module *mod, struct dwfl_file *file) +open_elf_file (Elf **elf, int *fd, char **name) { - if (file->elf == NULL) + if (*elf == NULL) { /* CBFAIL uses errno if it's set, so clear it first in case we don't set it with an open failure below. */ @@ -134,25 +45,36 @@ open_elf (Dwfl_Module *mod, struct dwfl_file *file) /* If there was a pre-primed file name left that the callback left behind, try to open that file name. */ - if (file->fd < 0 && file->name != NULL) - file->fd = TEMP_FAILURE_RETRY (open64 (file->name, O_RDONLY)); + if (*fd < 0 && *name != NULL) + *fd = TEMP_FAILURE_RETRY (open64 (*name, O_RDONLY)); - if (file->fd < 0) + if (*fd < 0) return CBFAIL; - Dwfl_Error error = __libdw_open_file (&file->fd, &file->elf, true, false); - if (error != DWFL_E_NOERROR) - return error; + return __libdw_open_file (fd, elf, true, false); } - else if (unlikely (elf_kind (file->elf) != ELF_K_ELF)) + else if (unlikely (elf_kind (*elf) != ELF_K_ELF)) { - elf_end (file->elf); - file->elf = NULL; - close (file->fd); - file->fd = -1; + elf_end (*elf); + *elf = NULL; + close (*fd); + *fd = -1; return DWFL_E_BADELF; } + /* Elf file already open and looks fine. */ + return DWFL_E_NOERROR; +} + +/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD. + When we return success, FILE->elf and FILE->vaddr are set up. */ +static inline Dwfl_Error +open_elf (Dwfl_Module *mod, struct dwfl_file *file) +{ + Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name); + if (error != DWFL_E_NOERROR) + return error; + GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem); if (ehdr == NULL) { @@ -586,6 +508,57 @@ find_debuginfo (Dwfl_Module *mod) return result; } +#ifdef ENABLE_DWZ +/* Try to find the alternative debug link for the given DWARF and set + it if found. Only called when mod->dw is already setup but still + might need an alternative (dwz multi) debug file. filename is either + the main or debug name from which the Dwarf was created. */ +static void +find_debug_altlink (Dwfl_Module *mod, const char *filename) +{ + assert (mod->dw != NULL); + + const char *altname; + const void *build_id; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + + if (build_id_len > 0) + { + /* We could store altfile in the module, but don't really need it. */ + char *altfile = NULL; + mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod), + filename, + altname, + 0, + &altfile); + + /* The (internal) callbacks might just set mod->alt_elf directly + because they open the Elf anyway for sanity checking. + Otherwise open either the given file name or use the fd + returned. */ + Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd, + &altfile); + if (error == DWFL_E_NOERROR) + { + mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf, + DWARF_C_READ, NULL); + if (mod->alt == NULL) + { + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (mod->alt_fd); + mod->alt_fd = -1; + } + else + dwarf_setalt (mod->dw, mod->alt); + } + + free (altfile); /* See above, we don't really need it. */ + } +} +#endif /* ENABLE_DWZ */ /* Try to find a symbol table in FILE. Returns DWFL_E_NOERROR if a proper one is found. @@ -1209,19 +1182,6 @@ load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile) return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err); } -#ifdef ENABLE_DWZ - /* For dwz multifile support, ignore if it looks wrong. */ - { - const void *build_id; - const char *alt_name; - size_t id_len = INTUSE (dwelf_dwarf_gnu_debugaltlink) (mod->dw, - &alt_name, - &build_id); - if (id_len > 0) - open_debugaltlink (mod->dw, alt_name, build_id, id_len); - } -#endif /* ENABLE_DWZ */ - /* Until we have iterated through all CU's, we might do lazy lookups. */ mod->lazycu = 1; @@ -1248,6 +1208,13 @@ find_dw (Dwfl_Module *mod) case DWFL_E_NOERROR: mod->debug.elf = mod->main.elf; mod->debug.address_sync = mod->main.address_sync; + +#ifdef ENABLE_DWZ + /* The Dwarf might need an alt debug file, find that now after + everything about the debug file has been setup (the + find_debuginfo callback might need it). */ + find_debug_altlink (mod, mod->main.name); +#endif /* ENABLE_DWZ */ return; case DWFL_E_NO_DWARF: @@ -1263,6 +1230,17 @@ find_dw (Dwfl_Module *mod) { case DWFL_E_NOERROR: mod->dwerr = load_dw (mod, &mod->debug); + if (mod->dwerr == DWFL_E_NOERROR) + { +#ifdef ENABLE_DWZ + /* The Dwarf might need an alt debug file, find that now after + everything about the debug file has been setup (the + find_debuginfo callback might need it). */ + find_debug_altlink (mod, mod->debug.name); +#endif /* ENABLE_DWZ */ + return; + } + break; case DWFL_E_CB: /* The find_debuginfo hook failed. */ diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 21db91a4..3f5314ad 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -1,5 +1,5 @@ /* Standard find_debuginfo callback for libdwfl. - Copyright (C) 2005-2010 Red Hat, Inc. + Copyright (C) 2005-2010, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -84,6 +84,45 @@ check_crc (int fd, GElf_Word debuglink_crc) static bool validate (Dwfl_Module *mod, int fd, bool check, GElf_Word debuglink_crc) { + /* For alt debug files always check the build-id from the Dwarf and alt. */ + if (mod->dw != NULL) + { + bool valid = false; + const void *build_id; + const char *altname; + ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw, + &altname, + &build_id); + if (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. */ + Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf, + false, false); + if (error != DWFL_E_NOERROR) + __libdwfl_seterrno (error); + else + { + const void *alt_build_id; + ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf, + &alt_build_id); + if (alt_len > 0 && alt_len == build_id_len + && memcmp (build_id, alt_build_id, alt_len) == 0) + valid = true; + else + { + /* A mismatch! */ + elf_end (mod->alt_elf); + mod->alt_elf = NULL; + close (fd); + fd = -1; + } + } + } + return valid; + } + /* If we have a build ID, check only that. */ if (mod->build_id_len > 0) { @@ -124,7 +163,9 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, const char *file_basename = file_name == NULL ? NULL : basename (file_name); if (debuglink_file == NULL) { - if (file_basename == NULL) + /* For a alt debug multi file we need a name, for a separate debug + name we may be able to fall back on file_basename.debug. */ + if (file_basename == NULL || mod->dw != NULL) { errno = 0; return -1; @@ -174,38 +215,67 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, check = *p++ == '+'; check = check && cancheck; - const char *dir, *subdir; + const char *dir, *subdir, *file; switch (p[0]) { case '\0': /* An empty entry says to try the main file's directory. */ dir = file_dirname; subdir = NULL; + file = debuglink_file; break; case '/': /* An absolute path says to look there for a subdirectory - named by the main file's absolute directory. - This cannot be applied to a relative file name. */ - if (file_dirname == NULL || file_dirname[0] != '/') + named by the main file's absolute directory. This cannot + be applied to a relative file name. For alt debug files + it means to look for the basename file in that dir or the + .dwz subdir (see below). */ + if (mod->dw == NULL + && (file_dirname == NULL || file_dirname[0] != '/')) continue; dir = p; - subdir = file_dirname + 1; + if (mod->dw == NULL) + { + subdir = file_dirname + 1; + file = debuglink_file; + } + else + { + subdir = NULL; + file = basename (debuglink_file); + } break; default: /* A relative path says to try a subdirectory of that name in the main file's directory. */ dir = file_dirname; subdir = p; + file = debuglink_file; break; } char *fname = NULL; - int fd = try_open (&main_stat, dir, subdir, debuglink_file, &fname); + int fd = try_open (&main_stat, dir, subdir, file, &fname); if (fd < 0) switch (errno) { case ENOENT: case ENOTDIR: + /* If we are looking for the alt file also try the .dwz subdir. + But only if this is the empty or absolute path. */ + if (mod->dw != NULL && (p[0] == '\0' || p[0] == '/')) + { + fd = try_open (&main_stat, dir, ".dwz", + basename (file), &fname); + if (fd < 0) + { + if (errno != ENOENT && errno != ENOTDIR) + return -1; + else + continue; + } + break; + } continue; default: return -1; @@ -240,11 +310,21 @@ dwfl_standard_find_debuginfo (Dwfl_Module *mod, GElf_Addr vaddr; if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0) { + /* Dropping most arguments means we cannot rely on them in + dwfl_build_id_find_debuginfo. But leave it that way since + some user code out there also does this, so we'll have to + handle it anyway. */ int fd = INTUSE(dwfl_build_id_find_debuginfo) (mod, NULL, NULL, 0, NULL, NULL, 0, debuginfo_file_name); - if (fd >= 0 || mod->debug.elf != NULL || errno != 0) + + /* Did the build_id callback find something or report an error? + Then we are done. Otherwise fallback on path based search. */ + if (fd >= 0 + || (mod->dw == NULL && mod->debug.elf != NULL) + || (mod->dw != NULL && mod->alt_elf != NULL) + || errno != 0) return fd; } diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index e4ab60e1..9b03d8a7 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -182,6 +182,9 @@ struct Dwfl_Module Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */ Dwarf *dw; /* libdw handle for its debugging info. */ + Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */ + int alt_fd; /* descriptor, only valid when alt != NULL. */ + Elf *alt_elf; /* Elf for alt Dwarf. */ Dwfl_Error symerr; /* Previous failure to load symbols. */ Dwfl_Error dwerr; /* Previous failure to load DWARF. */ @@ -518,8 +521,13 @@ extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) internal_function; /* Open a main or debuginfo file by its build ID, returns the fd. */ +extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, + char **file_name) internal_function; + +/* Same, but takes an explicit build_id, can also be used for alt debug. */ extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, - char **file_name) internal_function; + char **file_name, const size_t id_len, + const uint8_t *id) internal_function; extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len) attribute_hidden; diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 53075183..1ad7d2f6 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -1,5 +1,5 @@ /* Standard libdwfl callbacks for debugging the running Linux kernel. - Copyright (C) 2005-2011, 2013 Red Hat, Inc. + Copyright (C) 2005-2011, 2013, 2014 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -88,23 +88,22 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug) if (fd < 0) { - char *debugfname = NULL; Dwfl_Module fakemod = { .dwfl = dwfl }; /* First try the file's unadorned basename as DEBUGLINK_FILE, to look for "vmlinux" files. */ fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0, *fname, basename (*fname), 0, - &debugfname); + &fakemod.debug.name); if (fd < 0 && try_debug) /* Next, let the call use the default of basename + ".debug", to look for "vmlinux.debug" files. */ fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0, *fname, NULL, 0, - &debugfname); - if (debugfname != NULL) + &fakemod.debug.name); + if (fakemod.debug.name != NULL) { free (*fname); - *fname = debugfname; + *fname = fakemod.debug.name; } } |
