]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl/
authorRoland McGrath <roland@redhat.com>
Tue, 15 Aug 2006 01:37:23 +0000 (01:37 +0000)
committerRoland McGrath <roland@redhat.com>
Tue, 15 Aug 2006 01:37:23 +0000 (01:37 +0000)
2006-08-14  Roland McGrath  <roland@redhat.com>

* 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.

libdwfl/ChangeLog
libdwfl/find-debuginfo.c
libdwfl/libdwflP.h
libdwfl/linux-kernel-modules.c

index dafa98c857e97149e1da4726975d64a7d244c97e..0e3ac13678021fccd6024ad06f1baada1814d0d0 100644 (file)
@@ -1,3 +1,19 @@
+2006-08-14  Roland McGrath  <roland@redhat.com>
+
+       * 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  <drepper@redhat.com>
 
        * cu.c: Adjust for internal_function_def removal.
index 4baf5fa87ff71797e8dbb090ea5b543f5e5285a7..a99fd1441f206bd5b103e434924707e8dda5129d 100644 (file)
@@ -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
index 949e0d7e199767fb6a9e8b9313fd48578e343f0e..31da938db982db956d9290480ace9aff7b304884 100644 (file)
@@ -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 */
index a91d732c4b0bee4744154420b610a200137f2a37..4d4194a5d6679e2e211df10c2866792a7264fe8d 100644 (file)
@@ -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;