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.

Upstream-Status: Pending
[1] 
https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7
Signed-off-by: Khem Raj <raj.k...@gmail.com>
---
 lib/Makefile.am                      |  2 +-
 lib/libeu.h                          |  1 +
 lib/{libeu.h => xbasename.c}         | 31 ++++++++++------------------
 libdw/dwarf_getsrc_file.c            |  3 ++-
 libdwfl/core-file.c                  |  3 ++-
 libdwfl/dwfl_module_getsrc_file.c    |  3 ++-
 libdwfl/dwfl_segment_report_module.c |  3 ++-
 libdwfl/find-debuginfo.c             |  7 ++++---
 libdwfl/link_map.c                   |  3 ++-
 libdwfl/linux-kernel-modules.c       |  3 ++-
 src/addr2line.c                      |  5 +++--
 src/ar.c                             |  5 +++--
 src/nm.c                             |  4 ++--
 src/stack.c                          |  3 ++-
 src/strip.c                          |  2 +-
 tests/Makefile.am                    |  2 +-
 tests/show-die-info.c                |  3 ++-
 tests/varlocs.c                      |  3 ++-
 18 files changed, 45 insertions(+), 41 deletions(-)
 copy lib/{libeu.h => xbasename.c} (57%)

diff --git a/lib/Makefile.am b/lib/Makefile.am
index b3bb929f..ada51c0f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -33,7 +33,7 @@ AM_CPPFLAGS += -I$(srcdir)/../libelf
 
 noinst_LIBRARIES = libeu.a
 
-libeu_a_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \
+libeu_a_SOURCES = xasprintf.c xbasename.c xstrdup.c xstrndup.c xmalloc.c 
next_prime.c \
                  crc32.c crc32_file.c \
                  color.c error.c printversion.c
 
diff --git a/lib/libeu.h b/lib/libeu.h
index e849a79e..2a115aca 100644
--- a/lib/libeu.h
+++ b/lib/libeu.h
@@ -42,6 +42,7 @@ extern char *xstrndup (const char *, size_t) __attribute__ 
((__malloc__));
 extern char *xasprintf(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2))) __attribute__ ((__malloc__));
 
+extern const char *xbasename(const char *s);
 extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
 extern int crc32_file (int fd, uint32_t *resp);
 
diff --git a/lib/libeu.h b/lib/xbasename.c
similarity index 57%
copy from lib/libeu.h
copy to lib/xbasename.c
index e849a79e..68d51616 100644
--- a/lib/libeu.h
+++ b/lib/xbasename.c
@@ -1,5 +1,5 @@
-/* Declarations for the common library.
-   Copyright (C) 2006-2011 Red Hat, Inc.
+/* Convenience function for basename extraction.
+   Copyright (C) 2023 Khem Raj.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -26,23 +26,14 @@
    the GNU Lesser General Public License along with this program.  If
    not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef LIBEU_H
-#define LIBEU_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-extern void *xmalloc (size_t) __attribute__ ((__malloc__));
-extern void *xcalloc (size_t, size_t) __attribute__ ((__malloc__));
-extern void *xrealloc (void *, size_t) __attribute__ ((__malloc__));
-
-extern char *xstrdup (const char *) __attribute__ ((__malloc__));
-extern char *xstrndup (const char *, size_t) __attribute__ ((__malloc__));
-
-extern char *xasprintf(const char *fmt, ...)
-       __attribute__ ((format (printf, 1, 2))) __attribute__ ((__malloc__));
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
 
-extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
-extern int crc32_file (int fd, uint32_t *resp);
+#include <string.h>
 
-#endif
+const char *
+xbasename(const char *s) {
+    const char *p = strrchr(s, '/');
+    return p ? p+1 : s;
+}
diff --git a/libdw/dwarf_getsrc_file.c b/libdw/dwarf_getsrc_file.c
index 5289c7da..f75bf7bc 100644
--- a/libdw/dwarf_getsrc_file.c
+++ b/libdw/dwarf_getsrc_file.c
@@ -37,6 +37,7 @@
 #include <string.h>
 
 #include "libdwP.h"
+#include "libeu.h"
 
 
 int
@@ -98,7 +99,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;
            }
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 87c940cb..52a34b87 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -29,6 +29,7 @@
 
 #include <config.h>
 #include "libelfP.h"   /* For NOTE_ALIGN.  */
+#include "libeu.h"
 #include "libdwflP.h"
 #include <gelf.h>
 
@@ -595,7 +596,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);
diff --git a/libdwfl/dwfl_module_getsrc_file.c 
b/libdwfl/dwfl_module_getsrc_file.c
index 513af6b8..0418a267 100644
--- a/libdwfl/dwfl_module_getsrc_file.c
+++ b/libdwfl/dwfl_module_getsrc_file.c
@@ -31,6 +31,7 @@
 #endif
 
 #include "libdwflP.h"
+#include "libeu.h"
 #include "libdwP.h"
 
 
@@ -103,7 +104,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);
                }
            }
diff --git a/libdwfl/dwfl_segment_report_module.c 
b/libdwfl/dwfl_segment_report_module.c
index 09ee37b3..8a1782ad 100644
--- a/libdwfl/dwfl_segment_report_module.c
+++ b/libdwfl/dwfl_segment_report_module.c
@@ -29,6 +29,7 @@
 
 #include <config.h>
 #include "libelfP.h"   /* For NOTE_ALIGN4 and NOTE_ALIGN8.  */
+#include "libeu.h"
 #include "libdwflP.h"
 #include "common.h"
 
@@ -718,7 +719,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;
diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c
index 7f7ab632..6aab1a48 100644
--- a/libdwfl/find-debuginfo.c
+++ b/libdwfl/find-debuginfo.c
@@ -31,6 +31,7 @@
 #endif
 
 #include "libdwflP.h"
+#include "libeu.h"
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -164,7 +165,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 +279,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 +307,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)
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 76f23354..cdaa7ed0 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -29,6 +29,7 @@
 
 #include <config.h>
 #include "libdwflP.h"
+#include "libeu.h"
 #include "memory-access.h"
 #include "system.h"
 
@@ -475,7 +476,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)
diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 58c0c417..bdbde83a 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -40,6 +40,7 @@
 #include <system.h>
 
 #include "libelfP.h"
+#include "libeu.h"
 #include "libdwflP.h"
 #include <inttypes.h>
 #include <errno.h>
@@ -116,7 +117,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)
diff --git a/src/addr2line.c b/src/addr2line.c
index d902d791..5345189b 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -38,6 +38,7 @@
 
 #include <system.h>
 #include <printversion.h>
+#include "libeu.h"
 
 
 /* Name and version of program.  */
@@ -385,7 +386,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 +569,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;
diff --git a/src/ar.c b/src/ar.c
index 3bcb18fe..8f2dcd0d 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -42,6 +42,7 @@
 #include <printversion.h>
 
 #include "arlib.h"
+#include "libeu.h"
 
 
 /* Name and version of program.  */
@@ -1133,7 +1134,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 +1243,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)
            {
diff --git a/src/nm.c b/src/nm.c
index fbdee8e1..3675f59b 100644
--- 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);
diff --git a/src/stack.c b/src/stack.c
index 534aa93c..3abef98f 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -31,6 +31,7 @@
 #include <system.h>
 #include <printversion.h>
 
+#include "libeu.h"
 /* Name and version of program.  */
 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
 
@@ -152,7 +153,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;
diff --git a/src/strip.c b/src/strip.c
index 7f4788b3..6436443d 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -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;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2373c980..22d66e29 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -707,7 +707,7 @@ update1_LDADD = $(libelf)
 update2_LDADD = $(libelf)
 update3_LDADD = $(libdw) $(libelf)
 update4_LDADD = $(libdw) $(libelf)
-show_die_info_LDADD = $(libdw) $(libelf)
+show_die_info_LDADD = $(libeu) $(libdw) $(libelf)
 get_pubnames_LDADD = $(libdw) $(libelf)
 show_abbrev_LDADD = $(libdw) $(libelf)
 get_lines_LDADD = $(libdw) $(libelf)
diff --git a/tests/show-die-info.c b/tests/show-die-info.c
index 1a3191cd..00a66575 100644
--- a/tests/show-die-info.c
+++ b/tests/show-die-info.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "../lib/libeu.h"
 #include "../libdw/known-dwarf.h"
 
 static const char *
@@ -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)
diff --git a/tests/varlocs.c b/tests/varlocs.c
index 8e563fd3..72c64e25 100644
--- a/tests/varlocs.c
+++ b/tests/varlocs.c
@@ -33,6 +33,7 @@
 
 #include "system.h"
 #include "../libdw/known-dwarf.h"
+#include "../lib/libeu.h"
 
 // The Dwarf, Dwarf_CFIs and address bias of
 // cfi table to adjust DWARF addresses against.
@@ -1120,7 +1121,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);
 
-- 
2.43.0

Reply via email to