libdwfl: Search for Linux kernel binaries with compression file name suffixes.
authorRoland McGrath <roland@redhat.com>
Fri, 11 Feb 2011 20:29:45 +0000 (12:29 -0800)
committerRoland McGrath <roland@redhat.com>
Fri, 11 Feb 2011 20:29:45 +0000 (12:29 -0800)
libdwfl/ChangeLog
libdwfl/linux-kernel-modules.c

index 6a31f1d..0cbeb85 100644 (file)
@@ -1,3 +1,8 @@
+2011-02-11  Roland McGrath  <roland@redhat.com>
+
+       * linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz
+       suffixes if corresponding decompression support is enabled.
+
 2011-02-01  Roland McGrath  <roland@redhat.com>
 
        * dwfl_module_getdwarf.c (find_prelink_address_sync): Use the
index 2479292..f3d9af1 100644 (file)
@@ -1,5 +1,5 @@
 /* Standard libdwfl callbacks for debugging the running Linux kernel.
-   Copyright (C) 2005-2010 Red Hat, Inc.
+   Copyright (C) 2005-2011 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
 #define MODULE_SECT_NAME_LEN 32        /* Minimum any linux/module.h has had.  */
 
 
+static const char *vmlinux_suffixes[] =
+  {
+#ifdef USE_ZLIB
+    ".gz",
+#endif
+#ifdef USE_BZLIB
+    ".bz2",
+#endif
+#ifdef USE_LZMA
+    ".xz",
+#endif
+  };
+
 /* Try to open the given file as it is or under the debuginfo directory.  */
 static int
 try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
@@ -91,6 +104,7 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
               ? *dwfl->callbacks->debuginfo_path : NULL)
              ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1
            : TEMP_FAILURE_RETRY (open64 (*fname, O_RDONLY)));
+
   if (fd < 0)
     {
       char *debugfname = NULL;
@@ -106,8 +120,36 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
        fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
                                                   *fname, NULL, 0,
                                                   &debugfname);
+      if (debugfname != NULL)
+       {
+         free (*fname);
+         *fname = debugfname;
+       }
+    }
+
+  if (fd < 0)
+    for (size_t i = 0;
+        i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0];
+        ++i)
+      {
+       char *zname;
+       if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0)
+         {
+           fd = TEMP_FAILURE_RETRY (open64 (zname, O_RDONLY));
+           if (fd < 0)
+             free (zname);
+           else
+             {
+               free (*fname);
+               *fname = zname;
+             }
+         }
+      }
+
+  if (fd < 0)
+    {
       free (*fname);
-      *fname = debugfname;
+      *fname = NULL;
     }
 
   return fd;