1 |
commit: cb5da5f0f8ca714a552b70f201ace2eb24f0d2b1 |
2 |
Author: Mike Frysinger <vapier <AT> chromium <DOT> org> |
3 |
AuthorDate: Fri Apr 16 03:24:07 2021 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Apr 16 03:24:07 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=cb5da5f0 |
7 |
|
8 |
lddtree: use ldso's --argv0 when available |
9 |
|
10 |
Newer glibc has a --argv0 option in current releases to explicitly |
11 |
set argv[0]. This is useful for the generated shell wrappers as we |
12 |
need to rename it (with an .elf suffix) and that can either confuse |
13 |
the output or break tools that inspect their argv[0] strictly. |
14 |
|
15 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
16 |
|
17 |
lddtree.py | 26 ++++++++++++++++++++------ |
18 |
1 file changed, 20 insertions(+), 6 deletions(-) |
19 |
|
20 |
diff --git a/lddtree.py b/lddtree.py |
21 |
index 7ec04fa..fae39e0 100755 |
22 |
--- a/lddtree.py |
23 |
+++ b/lddtree.py |
24 |
@@ -43,6 +43,7 @@ import argparse |
25 |
import functools |
26 |
import glob |
27 |
import errno |
28 |
+import mmap |
29 |
import os |
30 |
import shutil |
31 |
import sys |
32 |
@@ -123,6 +124,17 @@ def dedupe(items): |
33 |
return [seen.setdefault(x, x) for x in items if x not in seen] |
34 |
|
35 |
|
36 |
+@×××××××××.lru_cache(maxsize=None) |
37 |
+def interp_supports_argv0(interp) -> bool: |
38 |
+ """See whether |interp| supports the --argv0 option. |
39 |
+ |
40 |
+ Starting with glibc-2.33, the ldso supports --argv0 to override argv[0]. |
41 |
+ """ |
42 |
+ with open(interp, 'rb') as fp: |
43 |
+ with mmap.mmap(fp.fileno(), 0, prot=mmap.PROT_READ) as mm: |
44 |
+ return mm.find(b'--argv0') >= 0 |
45 |
+ |
46 |
+ |
47 |
def GenerateLdsoWrapper(root, path, interp, libpaths=()): |
48 |
"""Generate a shell script wrapper which uses local ldso to run the ELF |
49 |
|
50 |
@@ -145,6 +157,7 @@ def GenerateLdsoWrapper(root, path, interp, libpaths=()): |
51 |
interp_name), |
52 |
'libpaths': ':'.join(['${basedir}/' + os.path.relpath(p, basedir) |
53 |
for p in libpaths]), |
54 |
+ 'argv0_arg': '--argv0 "$0"' if interp_supports_argv0(interp) else '', |
55 |
} |
56 |
wrapper = """#!/bin/sh |
57 |
if ! base=$(realpath "$0" 2>/dev/null); then |
58 |
@@ -154,12 +167,13 @@ if ! base=$(realpath "$0" 2>/dev/null); then |
59 |
esac |
60 |
fi |
61 |
basedir=${base%%/*} |
62 |
-exec \ |
63 |
- "${basedir}/%(interp)s" \ |
64 |
- --library-path "%(libpaths)s" \ |
65 |
- --inhibit-cache \ |
66 |
- --inhibit-rpath '' \ |
67 |
- "${base}.elf" \ |
68 |
+exec \\ |
69 |
+ "${basedir}/%(interp)s" \\ |
70 |
+ %(argv0_arg)s \\ |
71 |
+ --library-path "%(libpaths)s" \\ |
72 |
+ --inhibit-cache \\ |
73 |
+ --inhibit-rpath '' \\ |
74 |
+ "${base}.elf" \\ |
75 |
"$@" |
76 |
""" |
77 |
wrappath = root + path |