[binutils-gdb] ld/Linux: determine program name in a more reliable manner

Jan Beulich jbeulich@sourceware.org
Fri Dec 12 07:04:52 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d95258ac4b268c09a2ee6d01cec7dcbe62bfc070

commit d95258ac4b268c09a2ee6d01cec7dcbe62bfc070
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Dec 12 08:01:53 2025 +0100

    ld/Linux: determine program name in a more reliable manner
    
    What argv[0] holds can be pretty arbitrary. As long as it's used for just
    diagnostics, that may be pretty okay to go from, but ld also uses it to
    find linker scripts. For that we want to be sure we start from the real
    executable name. Which on Linux we can determine from the /proc/self/exe
    symbolic link target (provided of course procfs is mounted).
    
    While there constify program_name as well.

Diff:
---
 ld/ldmain.c | 17 +++++++++++++++--
 ld/ldmain.h |  2 +-
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/ld/ldmain.c b/ld/ldmain.c
index 157f205671e..afffdd2e43d 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -67,7 +67,7 @@ char *default_target;
 const char *output_filename = "a.out";
 
 /* Name this program was invoked by.  */
-char *program_name;
+const char *program_name;
 
 /* The prefix for system library directories.  */
 const char *ld_sysroot;
@@ -567,6 +567,19 @@ report_phases (FILE * file, time_t * start, char ** argv)
   fflush (file);
 }
 
+static void
+set_program_name (const char *argv0)
+{
+  program_name = argv0;
+
+#if defined (__linux__) && _POSIX_VERSION >= 200112L
+  char name[PATH_MAX];
+  ssize_t len = readlink ("/proc/self/exe", name, ARRAY_SIZE (name));
+  if (len > 0 && (size_t)len < ARRAY_SIZE (name))
+    program_name = xmemdup (name, len, len + 1);
+#endif
+}
+
 int
 main (int argc, char **argv)
 {
@@ -581,7 +594,7 @@ main (int argc, char **argv)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
-  program_name = argv[0];
+  set_program_name (argv[0]);
   xmalloc_set_program_name (program_name);
 
   /* Check the LD_STATS environment variable before parsing the command line
diff --git a/ld/ldmain.h b/ld/ldmain.h
index 0baa3c305c3..ec33b496f86 100644
--- a/ld/ldmain.h
+++ b/ld/ldmain.h
@@ -21,7 +21,7 @@
 #ifndef LDMAIN_H
 #define LDMAIN_H
 
-extern char *program_name;
+extern const char *program_name;
 extern const char *ld_sysroot;
 extern char *ld_canon_sysroot;
 extern int ld_canon_sysroot_len;


More information about the Binutils-cvs mailing list