diff options
| author | Roland McGrath <[email protected]> | 2006-08-15 01:37:23 +0000 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2006-08-15 01:37:23 +0000 |
| commit | a1cee0760dceaeca52aff9498b144978537d5a16 (patch) | |
| tree | 7cb36d6a21c32314cf2c7d140e2083d228cedc7b | |
| parent | 231c590fbe9d6f3a8e22796ded9c6a378628eb09 (diff) | |
libdwfl/
2006-08-14 Roland McGrath <[email protected]>
* linux-kernel-modules.c (try_kernel_name): If the call to
dwfl_standard_find_debuginfo produces no results, try it again
with NULL as DEBUGLINK_FILE to try *FNAME with .debug suffix.
* find-debuginfo.c (DEFAULT_DEBUGINFO_PATH): Macro moved ...
* libdwflP.h: ... to here.
* linux-kernel-modules.c (try_kernel_name): Skip manual open if it
repeats the first thing dwfl_standard_find_debuginfo will try.
* linux-kernel-modules.c (MODULE_SECT_NAME_LEN): New macro.
(dwfl_linux_kernel_module_section_address): If a /sys file is missing
and the section name is >= MODULE_SECT_NAME_LEN, try truncating the
section name.
| -rw-r--r-- | libdwfl/ChangeLog | 16 | ||||
| -rw-r--r-- | libdwfl/find-debuginfo.c | 5 | ||||
| -rw-r--r-- | libdwfl/libdwflP.h | 4 | ||||
| -rw-r--r-- | libdwfl/linux-kernel-modules.c | 58 |
4 files changed, 73 insertions, 10 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index dafa98c8..0e3ac136 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,19 @@ +2006-08-14 Roland McGrath <[email protected]> + + * linux-kernel-modules.c (try_kernel_name): If the call to + dwfl_standard_find_debuginfo produces no results, try it again + with NULL as DEBUGLINK_FILE to try *FNAME with .debug suffix. + + * find-debuginfo.c (DEFAULT_DEBUGINFO_PATH): Macro moved ... + * libdwflP.h: ... to here. + * linux-kernel-modules.c (try_kernel_name): Skip manual open if it + repeats the first thing dwfl_standard_find_debuginfo will try. + + * linux-kernel-modules.c (MODULE_SECT_NAME_LEN): New macro. + (dwfl_linux_kernel_module_section_address): If a /sys file is missing + and the section name is >= MODULE_SECT_NAME_LEN, try truncating the + section name. + 2006-07-12 Ulrich Drepper <[email protected]> * cu.c: Adjust for internal_function_def removal. diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 4baf5fa8..a99fd144 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -1,5 +1,5 @@ /* Standard find_debuginfo callback for libdwfl. - Copyright (C) 2005 Red Hat, Inc. + Copyright (C) 2005, 2006 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -54,9 +54,6 @@ #include "system.h" -#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug" - - /* Try to open64 [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1. On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file. */ static int diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 949e0d7e..31da938d 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -296,4 +296,8 @@ INTDECL (dwfl_module_relocate_address) #define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB); +/* The default used by dwfl_standard_find_debuginfo. */ +#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug" + + #endif /* libdwflP.h */ diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index a91d732c..4d4194a5 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 Red Hat, Inc. + Copyright (C) 2005, 2006 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -66,7 +66,8 @@ #define MODULEDIRFMT "/lib/modules/%s" #define MODULELIST "/proc/modules" -#define SECADDRFMT "/sys/module/%s/sections/%s" +#define SECADDRDIRFMT "/sys/module/%s/sections/" +#define MODULE_SECT_NAME_LEN 32 /* Minimum any linux/module.h has had. */ /* Try to open the given file as it is or under the debuginfo directory. */ @@ -76,14 +77,27 @@ try_kernel_name (Dwfl *dwfl, char **fname) if (*fname == NULL) return -1; - int fd = TEMP_FAILURE_RETRY (open64 (*fname, O_RDONLY)); + /* Don't bother trying *FNAME itself here if the path will cause it to be + tried because we give its own basename as DEBUGLINK_FILE. */ + int fd = ((((dwfl->callbacks->debuginfo_path + ? *dwfl->callbacks->debuginfo_path : NULL) + ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1 + : TEMP_FAILURE_RETRY (open64 (*fname, O_RDONLY))); 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); + if (fd < 0) + /* 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); free (*fname); *fname = debugfname; } @@ -404,7 +418,7 @@ dwfl_linux_kernel_module_section_address Dwarf_Addr *addr) { char *sysfile = NULL; - asprintf (&sysfile, SECADDRFMT, modname, secname); + asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname); if (sysfile == NULL) return ENOMEM; @@ -436,10 +450,11 @@ dwfl_linux_kernel_module_section_address behavior, and this cruft leaks out into the /sys information. The file name for ".init*" may actually look like "_init*". */ - if (!strncmp (secname, ".init", 5)) + const bool is_init = !strncmp (secname, ".init", 5); + if (is_init) { sysfile = NULL; - asprintf (&sysfile, SECADDRFMT "%s", modname, "_", &secname[1]); + asprintf (&sysfile, SECADDRDIRFMT "_%s", modname, &secname[1]); if (sysfile == NULL) return ENOMEM; f = fopen (sysfile, "r"); @@ -447,6 +462,37 @@ dwfl_linux_kernel_module_section_address if (f != NULL) goto ok; } + + /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1. + In case that size increases in the future, look for longer + truncated names first. */ + size_t namelen = strlen (secname); + if (namelen >= MODULE_SECT_NAME_LEN) + { + sysfile = NULL; + int len = asprintf (&sysfile, SECADDRDIRFMT "%s", + modname, secname); + if (sysfile == NULL) + return ENOMEM; + char *end = sysfile + len; + do + { + *--end = '\0'; + f = fopen (sysfile, "r"); + if (is_init && f == NULL && errno == ENOENT) + { + sysfile[len - namelen] = '_'; + f = fopen (sysfile, "r"); + sysfile[len - namelen] = '.'; + } + } + while (f == NULL && errno == ENOENT + && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN); + free (sysfile); + + if (f != NULL) + goto ok; + } } return DWARF_CB_ABORT; |
