]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Add helper function for basename
authorKhem Raj <raj.khem@gmail.com>
Sun, 10 Dec 2023 20:20:33 +0000 (12:20 -0800)
committerMark Wielaard <mark@klomp.org>
Thu, 21 Dec 2023 00:45:05 +0000 (01:45 +0100)
musl does not provide GNU version of basename and lately have removed
the definiton from string.h [1] which exposes this problem. It can be
made to work by providing a local implementation of basename which
implements the GNU basename behavior, this makes it work across C
libraries which have POSIX implementation only.

[1] https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7

    * lib/system.h (xbasename): New static inline functions.
    Poison basename.
    * libdw/dwarf_getsrc_file.c (dwarf_getsrc_file): Use xbasename.
    * libdwfl/core-file.c (dwfl_core_file_report): Likewise.
    * libdwfl/dwfl_module_getsrc_file.c (dwfl_module_getsrc_file):
    Likewise.
    * libdwfl/dwfl_segment_report_module.c (dwfl_segment_report_module):
    Likewise.
    * libdwfl/find-debuginfo.c (find_debuginfo_in_path): Likewise.
    * libdwfl/link_map.c (report_r_debug): Likewise.
    * libdwfl/linux-kernel-modules.c (try_kernel_name): Likewise.
    * src/addr2line.c (print_dwarf_function): Likewise.
    (print_src): Likewise.
    * src/ar.c (do_oper_insert): Likewise.
    And cast away const in entry.key assignment.
    * src/nm.c (show_symbols): Use xbasename.
    * src/stack.c (module_callback): Likewise.
    * src/strip.c (handle_elf): Likewise.
    * tests/show-die-info.c: Include system.h.
    (dwarf_tag_string): Use xbasename.
    * tests/varlocs.c: Likewise.
    * debuginfod/debuginfod.cxx: Move include system.h to the end.
    (register_file_name): Rename basename to filename.

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Mark Wielaard <mark@klomp.org>
16 files changed:
debuginfod/debuginfod.cxx
lib/system.h
libdw/dwarf_getsrc_file.c
libdwfl/core-file.c
libdwfl/dwfl_module_getsrc_file.c
libdwfl/dwfl_segment_report_module.c
libdwfl/find-debuginfo.c
libdwfl/link_map.c
libdwfl/linux-kernel-modules.c
src/addr2line.c
src/ar.c
src/nm.c
src/stack.c
src/strip.c
tests/show-die-info.c
tests/varlocs.c

index c11aeda1a3afa7d9bfef87e53cd678bad7647c9e..524be9482e150a632375680f5b6705683e2142ca 100644 (file)
@@ -50,11 +50,6 @@ extern "C" {
 }
 #endif
 
-extern "C" {
-#include "printversion.h"
-#include "system.h"
-}
-
 #include "debuginfod.h"
 #include <dwarf.h>
 
@@ -135,6 +130,11 @@ using namespace std;
 #define tid() pthread_self()
 #endif
 
+extern "C" {
+#include "printversion.h"
+#include "system.h"
+}
+
 
 inline bool
 string_endswith(const string& haystack, const string& needle)
@@ -3194,16 +3194,16 @@ register_file_name(sqlite_ps& ps_upsert_fileparts,
                    const string& name)
 {
   std::size_t slash = name.rfind('/');
-  string dirname, basename;
+  string dirname, filename;
   if (slash == std::string::npos)
     {
       dirname = "";
-      basename = name;
+      filename = name;
     }
   else
     {
       dirname = name.substr(0, slash);
-      basename = name.substr(slash+1);
+      filename = name.substr(slash+1);
     }
 
   // intern the two substrings
@@ -3213,21 +3213,21 @@ register_file_name(sqlite_ps& ps_upsert_fileparts,
     .step_ok_done();
   ps_upsert_fileparts
     .reset()
-    .bind(1, basename)
+    .bind(1, filename)
     .step_ok_done();
 
   // intern the tuple
   ps_upsert_file
     .reset()
     .bind(1, dirname)
-    .bind(2, basename)
+    .bind(2, filename)
     .step_ok_done();
 
   // look up the tuple's id
   ps_lookup_file
     .reset()
     .bind(1, dirname)
-    .bind(2, basename);
+    .bind(2, filename);
   int rc = ps_lookup_file.step();
   if (rc != SQLITE_ROW) throw sqlite_exception(rc, "step");
   
index 1c914efc066fe858d156996c10e70fe62984113a..0db12d991a52eaade70a99deec30ea9fbc2351ac 100644 (file)
@@ -1,6 +1,7 @@
 /* Declarations for common convenience functions.
    Copyright (C) 2006-2011 Red Hat, Inc.
    Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
+   Copyright (C) 2023 Khem Raj.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -211,4 +212,17 @@ extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
   extern int never_defined_just_used_for_checking[(expr) ? 1 : -1]     \
     __attribute__ ((unused))
 
+/* We really want a basename implementation that doesn't modify the
+   input argument.  Normally you get that from string.h with _GNU_SOURCE
+   define.  But some libc implementations don't define it and other
+   define it, but provide an implementation that still modifies the
+   argument.  So define our own and poison a bare basename symbol.  */
+static inline const char *
+xbasename(const char *s)
+{
+  const char *p = strrchr(s, '/');
+  return p ? p+1 : s;
+}
+#pragma GCC poison basename
+
 #endif /* system.h */
index 5289c7da48fd643c2d0472cfe86242a1c3a43fd3..03da431c44f123ecf80e233982430397e2e5962b 100644 (file)
@@ -98,7 +98,7 @@ dwarf_getsrc_file (Dwarf *dbg, const char *fname, int lineno, int column,
              /* Match the name with the name the user provided.  */
              const char *fname2 = line->files->info[lastfile].name;
              if (is_basename)
-               lastmatch = strcmp (basename (fname2), fname) == 0;
+               lastmatch = strcmp (xbasename (fname2), fname) == 0;
              else
                lastmatch = strcmp (fname2, fname) == 0;
            }
index 87c940cb569d97cc6800044d51ddd72341bfdb70..89527d233e17326c8ca32fff3dfa9d0af3ca336f 100644 (file)
@@ -595,7 +595,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
       if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
        continue;
       Dwfl_Module *mod;
-      mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
+      mod = __libdwfl_report_elf (dwfl, xbasename (module->name), module->name,
                                  module->fd, module->elf,
                                  module->l_ld - file_dynamic_vaddr,
                                  true, true);
index 513af6b8d067a22f3ccfd1c17a38ca96a3126e82..fc144225b50630d4d7c7877a495701884252baf9 100644 (file)
@@ -103,7 +103,7 @@ dwfl_module_getsrc_file (Dwfl_Module *mod,
                {
                  /* Match the name with the name the user provided.  */
                  lastfile = file;
-                 lastmatch = !strcmp (is_basename ? basename (file) : file,
+                 lastmatch = !strcmp (is_basename ? xbasename (file) : file,
                                       fname);
                }
            }
index 09ee37b30428c794afbac380386953f059dbefcd..dc34e0aefdf9bdd89eb5a1f889d5057430e960b0 100644 (file)
@@ -718,7 +718,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
              bias += fixup;
              if (module->name[0] != '\0')
                {
-                 name = basename (module->name);
+                 name = xbasename (module->name);
                  name_is_final = true;
                }
              break;
@@ -743,7 +743,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
                   prevents premature closure of the correct ELF in cases
                   where segments of a module are non-contiguous in memory.  */
                if (name != NULL && module->name[0] != '\0'
-                   && strcmp (basename (module->name), basename (name)) == 0)
+                   && strcmp (xbasename (module->name), xbasename (name)) == 0)
                  {
                    elf_end (module->elf);
                    close (module->fd);
index 7f7ab632dac835f40b4f2c7010623cfa7a24c905..b358c7744857b7909a0e2775399fb3c9192cd08f 100644 (file)
@@ -164,7 +164,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
 {
   bool cancheck = debuglink_crc != (GElf_Word) 0;
 
-  const char *file_basename = file_name == NULL ? NULL : basename (file_name);
+  const char *file_basename = file_name == NULL ? NULL : xbasename (file_name);
   char *localname = NULL;
 
   /* We invent a debuglink .debug name if NULL, but then want to try the
@@ -278,7 +278,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
          else
            {
              subdir = NULL;
-             file = basename (debuglink_file);
+             file = xbasename (debuglink_file);
            }
          try_file_basename = debuglink_null;
          break;
@@ -306,7 +306,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
            if (mod->dw != NULL && (p[0] == '\0' || p[0] == '/'))
              {
                fd = try_open (&main_stat, dir, ".dwz",
-                              basename (file), &fname);
+                              xbasename (file), &fname);
                if (fd < 0)
                  {
                    if (errno != ENOENT && errno != ENOTDIR)
index 76f2335462a7d493cdc8ba91371df969c97925ef..a6c66c789643372d31076db30dc251923e6b1128 100644 (file)
@@ -475,7 +475,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
                      if (r_debug_info_module == NULL)
                        {
                          // XXX hook for sysroot
-                         mod = __libdwfl_report_elf (dwfl, basename (name),
+                         mod = __libdwfl_report_elf (dwfl, xbasename (name),
                                                      name, fd, elf, base,
                                                      true, true);
                          if (mod != NULL)
index 58c0c417a59721d865cf88dfb9c4211df70a72e3..e9faba26a720d56161e8ae76403d3c6cb769adea 100644 (file)
@@ -116,7 +116,7 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
        /* Try the file's unadorned basename as DEBUGLINK_FILE,
           to look only for "vmlinux" files.  */
        fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
-                                                  *fname, basename (*fname),
+                                                  *fname, xbasename (*fname),
                                                   0, &fakemod.debug.name);
 
       if (fakemod.debug.name != NULL)
index d902d791c2391ed3b6b85300cf5db3a6b6e5c26d..d87e5b45e0a97bc1bb1e7b52981b9424fc0997dc 100644 (file)
@@ -385,7 +385,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
                  if (file == NULL)
                    file = "???";
                  else if (only_basenames)
-                   file = basename (file);
+                   file = xbasename (file);
                  else if (use_comp_dir && file[0] != '/')
                    {
                      const char *const *dirs;
@@ -568,7 +568,7 @@ print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu)
   const char *comp_dir_sep = "";
 
   if (only_basenames)
-    src = basename (src);
+    src = xbasename (src);
   else if (use_comp_dir && src[0] != '/')
     {
       Dwarf_Attribute attr;
index 3bcb18fe827b6c01c6b088c6e20b7680cf4e72e7..e6d6d58f2b3bc84b4728203e7e3bba708a443963 100644 (file)
--- a/src/ar.c
+++ b/src/ar.c
@@ -1133,7 +1133,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
       for (int cnt = 0; cnt < argc; ++cnt)
        {
          ENTRY entry;
-         entry.key = full_path ? argv[cnt] : basename (argv[cnt]);
+         entry.key = full_path ? argv[cnt] : (char*)xbasename (argv[cnt]);
          entry.data = &argv[cnt];
          if (hsearch (entry, ENTER) == NULL)
            error_exit (errno, _("cannot insert into hash table"));
@@ -1242,7 +1242,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
       /* Open all the new files, get their sizes and add all symbols.  */
       for (int cnt = 0; cnt < argc; ++cnt)
        {
-         const char *bname = basename (argv[cnt]);
+         const char *bname = xbasename (argv[cnt]);
          size_t bnamelen = strlen (bname);
          if (found[cnt] == NULL)
            {
index fbdee8e100b569e4d8a44e2e2112af8cb4b39b72..3675f59b52974b437eaee4996368cd116b7eaa85 100644 (file)
--- a/src/nm.c
+++ b/src/nm.c
@@ -1417,7 +1417,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr,
                          int lineno;
                          (void) dwarf_lineno (line, &lineno);
                          const char *file = dwarf_linesrc (line, NULL, NULL);
-                         file = (file != NULL) ? basename (file) : "???";
+                         file = (file != NULL) ? xbasename (file) : "???";
                          int n;
                          n = obstack_printf (&whereob, "%s:%d%c", file,
                                              lineno, '\0');
@@ -1448,7 +1448,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr,
                {
                  /* We found the line.  */
                  int n = obstack_printf (&whereob, "%s:%" PRIu64 "%c",
-                                         basename ((*found)->file),
+                                         xbasename ((*found)->file),
                                          (*found)->lineno,
                                          '\0');
                  sym_mem[nentries_used].where = obstack_finish (&whereob);
index 534aa93c433551896b67b65845ab4891fd175066..f4c5ba8c4df9042c3ca747e86914c02c43d8d9bf 100644 (file)
@@ -152,7 +152,7 @@ module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
 
   int width = get_addr_width (mod);
   printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
-         width, start, width, end, basename (name));
+         width, start, width, end, xbasename (name));
 
   const unsigned char *id;
   GElf_Addr id_vaddr;
index 7f4788b331f71a60bd15bb673a94c78265d8e50d..6436443dcceedcdc31d6b21ba51d310f7dea8322 100644 (file)
@@ -1800,7 +1800,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
                      elf_errmsg (-1));
        }
 
-      char *debug_basename = basename (debug_fname_embed ?: debug_fname);
+      const char *debug_basename = xbasename (debug_fname_embed ?: debug_fname);
       off_t crc_offset = strlen (debug_basename) + 1;
       /* Align to 4 byte boundary */
       crc_offset = ((crc_offset - 1) & ~3) + 4;
index 1a3191cd5eb73519e0c729f95e1a1b49161e772f..bda459a5c084faf14388816ab0bd27243f6f1ee5 100644 (file)
@@ -27,6 +27,7 @@
 #include <unistd.h>
 
 #include "../libdw/known-dwarf.h"
+#include "../lib/system.h"
 
 static const char *
 dwarf_tag_string (unsigned int tag)
@@ -318,7 +319,7 @@ main (int argc, char *argv[])
       int fd = open (argv[cnt], O_RDONLY);
       Dwarf *dbg;
 
-      printf ("file: %s\n", basename (argv[cnt]));
+      printf ("file: %s\n", xbasename (argv[cnt]));
 
       dbg = dwarf_begin (fd, DWARF_C_READ);
       if (dbg == NULL)
index 8e563fd32152f92ccdca3fd648d231e821c4d2e9..1004f96945f37484e3c35b140f58e5d2b1dc8d13 100644 (file)
@@ -1120,7 +1120,7 @@ main (int argc, char *argv[])
 
          const char *name = (modname[0] != '\0'
                              ? modname
-                             :  basename (mainfile));
+                             :  xbasename (mainfile));
          printf ("module '%s'\n", name);
          print_die (&cudie, "CU", 0);