summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2006-08-15 01:37:23 +0000
committerRoland McGrath <[email protected]>2006-08-15 01:37:23 +0000
commita1cee0760dceaeca52aff9498b144978537d5a16 (patch)
tree7cb36d6a21c32314cf2c7d140e2083d228cedc7b
parent231c590fbe9d6f3a8e22796ded9c6a378628eb09 (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/ChangeLog16
-rw-r--r--libdwfl/find-debuginfo.c5
-rw-r--r--libdwfl/libdwflP.h4
-rw-r--r--libdwfl/linux-kernel-modules.c58
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;