elf: Install a symbolic link to ld.so as /usr/bin/ld.so

Message ID 87ilwtff5n.fsf@oldenburg.str.redhat.com
State Superseded
Headers
Series elf: Install a symbolic link to ld.so as /usr/bin/ld.so |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Florian Weimer Nov. 15, 2021, 6:27 p.m. UTC
  This makes ld.so features such as --preload, --audit,
and --list-diagnostics more accessible to end users because they
do not need to know the ABI name of the dynamic loader.

A Python helper script is used to compute the symbolic link target
instead of relying on ln -rs, which was added in coreutils 8.16
(released in 2012).

Tested on i686-linux-gnu and x86_64-linux-gnu.  Manually checked that
the relative symbolic links work.

---
 NEWS                         |  4 ++++
 elf/Makefile                 |  8 ++++++-
 elf/install-ld.so-symlink.py | 57 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 1 deletion(-)
  

Comments

Andreas Schwab Nov. 15, 2021, 6:37 p.m. UTC | #1
On Nov 15 2021, Florian Weimer via Libc-alpha wrote:

> A Python helper script is used to compute the symbolic link target
> instead of relying on ln -rs, which was added in coreutils 8.16
> (released in 2012).

What's wrong with $(make-link)?

Andreas.
  
Florian Weimer Nov. 15, 2021, 7:08 p.m. UTC | #2
* Andreas Schwab:

> On Nov 15 2021, Florian Weimer via Libc-alpha wrote:
>
>> A Python helper script is used to compute the symbolic link target
>> instead of relying on ln -rs, which was added in coreutils 8.16
>> (released in 2012).
>
> What's wrong with $(make-link)?

Uhm, I had forgotten about it.  I posted a v2.

Thanks,
Florian
  

Patch

diff --git a/NEWS b/NEWS
index f10971b180..2f56f3db28 100644
--- a/NEWS
+++ b/NEWS
@@ -68,6 +68,10 @@  Major new features:
   to be used by compilers for optimizing usage of 'memcmp' when its
   return value is only used for its boolean status.
 
+* A symbolic link to the dynamic linker is now installed under
+  /usr/bin/ld.so (or ${bindir}/ld.so if glibc is not configured with
+  --prefix=/usr).
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The r_version update in the debugger interface makes the glibc binary
diff --git a/elf/Makefile b/elf/Makefile
index 72004484db..99038adb6d 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -110,7 +110,7 @@  endif
 ifeq (yes,$(build-shared))
 extra-objs	= $(all-rtld-routines:%=%.os) sofini.os interp.os
 generated	+= librtld.os dl-allobjs.os ld.so ldd
-install-others	= $(inst_rtlddir)/$(rtld-installed-name)
+install-others	= $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
 install-bin-script = ldd
 endif
 
@@ -682,6 +682,12 @@  $(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force)
 	$(make-target-directory)
 	$(do-install-program)
 
+# Creates the relative /usr/bin/ld.so symbolic link.
+$(inst_bindir)/ld.so: install-ld.so-symlink.py $(+force)
+	$(make-target-directory)
+	$(PYTHON) $< --create-at=$@ --bindir=$(bindir) \
+	  --rtlddir=$(rtlddir) --rtld-installed-name=$(rtld-installed-name)
+
 # Special target called by parent to install just the dynamic linker.
 .PHONY: ldso_install
 ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
diff --git a/elf/install-ld.so-symlink.py b/elf/install-ld.so-symlink.py
new file mode 100644
index 0000000000..7c1b52d463
--- /dev/null
+++ b/elf/install-ld.so-symlink.py
@@ -0,0 +1,57 @@ 
+#!/usr/bin/python
+# Installs the relative symbolic link for /usr/bin/ld.so.
+# Copyright (C) 2021 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+"""
+Create a relative symbolic link for ld.so.
+"""
+
+def main():
+    """Entry point when called as the main program."""
+
+    import argparse
+    import os.path
+    import sys
+
+    def get_parser():
+        parser = argparse.ArgumentParser(description=__doc__)
+        parser.add_argument('--create-at', required=True,
+                            help='pathname of the symbolic link to create')
+        parser.add_argument('--bindir', required=True,
+                            help='Installation bindir variable')
+        parser.add_argument('--rtlddir', required=True,
+                            help='ld.so installation directory')
+        parser.add_argument('--rtld-installed-name', required=True,
+                            help='ld.so file name')
+        return parser
+    parser = get_parser()
+    args = parser.parse_args()
+
+    symlink_path = os.path.join(args.bindir, 'ld.so')
+    symlink_target = os.path.join(args.rtlddir, args.rtld_installed_name)
+    relative_target = os.path.relpath(symlink_target, args.bindir)
+    print('{}: {} symbolic link pointing to {} (absolute {})'.format(
+        args.create_at, symlink_path, relative_target, symlink_target))
+    try:
+        os.unlink(args.create_at)
+    except:
+        pass
+    os.symlink(relative_target, args.create_at)
+
+if __name__ == '__main__':
+    main()