| From 666372a5d8d5a23203c70d583904097c9e49c5a0 Mon Sep 17 00:00:00 2001 |
| From: Khem Raj <raj.khem@gmail.com> |
| Date: Sat, 9 Dec 2023 18:23:03 -0800 |
| Subject: [PATCH] Add helper function for basename |
| |
| 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: Submitted [https://sourceware.org/pipermail/elfutils-devel/2023q4/006727.html] |
| [1] https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7 |
| Signed-off-by: Khem Raj <raj.khem@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/show-die-info.c | 2 +- |
| tests/varlocs.c | 2 +- |
| 17 files changed, 42 insertions(+), 40 deletions(-) |
| copy lib/{libeu.h => xbasename.c} (57%) |
| |
| --- 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 |
| |
| --- a/lib/libeu.h |
| +++ b/lib/libeu.h |
| @@ -42,6 +42,7 @@ extern char *xstrndup (const char *, siz |
| 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); |
| |
| --- /dev/null |
| +++ b/lib/xbasename.c |
| @@ -0,0 +1,39 @@ |
| +/* 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 |
| + it under the terms of either |
| + |
| + * the GNU Lesser General Public License as published by the Free |
| + Software Foundation; either version 3 of the License, or (at |
| + your option) any later version |
| + |
| + or |
| + |
| + * the GNU General Public License as published by the Free |
| + Software Foundation; either version 2 of the License, or (at |
| + your option) any later version |
| + |
| + or both in parallel, as here. |
| + |
| + elfutils is distributed in the hope that it will be useful, but |
| + WITHOUT ANY WARRANTY; without even the implied warranty of |
| + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| + General Public License for more details. |
| + |
| + You should have received copies of the GNU General Public License and |
| + the GNU Lesser General Public License along with this program. If |
| + not, see <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifdef HAVE_CONFIG_H |
| +# include <config.h> |
| +#endif |
| + |
| +#include <string.h> |
| + |
| +const char * |
| +xbasename(const char *s) { |
| + const char *p = strrchr(s, '/'); |
| + return p ? p+1 : s; |
| +} |
| --- 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 cha |
| /* 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; |
| } |
| --- 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 * |
| 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); |
| --- 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 *mo |
| { |
| /* 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); |
| } |
| } |
| --- 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, |
| bias += fixup; |
| if (module->name[0] != '\0') |
| { |
| - name = basename (module->name); |
| + name = xbasename (module->name); |
| name_is_final = true; |
| } |
| break; |
| --- 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 |
| { |
| 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 |
| 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 |
| 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) |
| --- 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" |
| |
| @@ -469,7 +470,7 @@ report_r_debug (uint_fast8_t elfclass, u |
| 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) |
| --- 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 **fnam |
| /* 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) |
| --- 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, |
| 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, |
| const char *comp_dir_sep = ""; |
| |
| if (only_basenames) |
| - src = basename (src); |
| + src = xbasename (src); |
| else if (use_comp_dir && src[0] != '/') |
| { |
| Dwarf_Attribute attr; |
| --- 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 *ar |
| 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 *ar |
| /* 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) |
| { |
| --- a/src/nm.c |
| +++ b/src/nm.c |
| @@ -1417,7 +1417,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehd |
| 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_Ehd |
| { |
| /* 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); |
| --- 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 |
| |
| 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; |
| --- a/src/strip.c |
| +++ b/src/strip.c |
| @@ -1807,7 +1807,7 @@ handle_elf (int fd, Elf *elf, const char |
| 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; |
| --- 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) |
| --- 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); |
| |
| --- a/tests/Makefile.am |
| +++ b/tests/Makefile.am |
| @@ -692,7 +692,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) |