From a2194f6b305bf0d0b9dd49dccd0a5c21994c8eea Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sun, 10 Dec 2023 12:20:33 -0800 Subject: 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. [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 Signed-off-by: Mark Wielaard --- debuginfod/debuginfod.cxx | 22 +++++++++++----------- lib/system.h | 14 ++++++++++++++ libdw/dwarf_getsrc_file.c | 2 +- libdwfl/core-file.c | 2 +- libdwfl/dwfl_module_getsrc_file.c | 2 +- libdwfl/dwfl_segment_report_module.c | 4 ++-- libdwfl/find-debuginfo.c | 6 +++--- libdwfl/link_map.c | 2 +- libdwfl/linux-kernel-modules.c | 2 +- src/addr2line.c | 4 ++-- src/ar.c | 4 ++-- src/nm.c | 4 ++-- src/stack.c | 2 +- src/strip.c | 2 +- tests/show-die-info.c | 3 ++- tests/varlocs.c | 2 +- 16 files changed, 46 insertions(+), 31 deletions(-) diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx index c11aeda1..524be948 100644 --- a/debuginfod/debuginfod.cxx +++ b/debuginfod/debuginfod.cxx @@ -50,11 +50,6 @@ extern "C" { } #endif -extern "C" { -#include "printversion.h" -#include "system.h" -} - #include "debuginfod.h" #include @@ -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"); diff --git a/lib/system.h b/lib/system.h index 1c914efc..0db12d99 100644 --- a/lib/system.h +++ b/lib/system.h @@ -1,6 +1,7 @@ /* Declarations for common convenience functions. Copyright (C) 2006-2011 Red Hat, Inc. Copyright (C) 2022 Mark J. Wielaard + 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 */ diff --git a/libdw/dwarf_getsrc_file.c b/libdw/dwarf_getsrc_file.c index 5289c7da..03da431c 100644 --- a/libdw/dwarf_getsrc_file.c +++ b/libdw/dwarf_getsrc_file.c @@ -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; } diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c index 87c940cb..89527d23 100644 --- a/libdwfl/core-file.c +++ b/libdwfl/core-file.c @@ -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); diff --git a/libdwfl/dwfl_module_getsrc_file.c b/libdwfl/dwfl_module_getsrc_file.c index 513af6b8..fc144225 100644 --- a/libdwfl/dwfl_module_getsrc_file.c +++ b/libdwfl/dwfl_module_getsrc_file.c @@ -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); } } diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 09ee37b3..dc34e0ae 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -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); diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 7f7ab632..b358c774 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -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) diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 76f23354..a6c66c78 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -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) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 58c0c417..e9faba26 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -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) diff --git a/src/addr2line.c b/src/addr2line.c index d902d791..d87e5b45 100644 --- a/src/addr2line.c +++ b/src/addr2line.c @@ -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; diff --git a/src/ar.c b/src/ar.c index 3bcb18fe..e6d6d58f 100644 --- 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) { 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..f4c5ba8c 100644 --- a/src/stack.c +++ b/src/stack.c @@ -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; 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/show-die-info.c b/tests/show-die-info.c index 1a3191cd..bda459a5 100644 --- a/tests/show-die-info.c +++ b/tests/show-die-info.c @@ -27,6 +27,7 @@ #include #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) diff --git a/tests/varlocs.c b/tests/varlocs.c index 8e563fd3..1004f969 100644 --- a/tests/varlocs.c +++ b/tests/varlocs.c @@ -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); -- cgit v1.2.3