1 |
commit: 816065b7964ef8ad5a65f1a92190a2f5ff4b3744 |
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=816065b7 |
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 | 27 +++++++++++++++++++++------ |
18 |
1 file changed, 21 insertions(+), 6 deletions(-) |
19 |
|
20 |
diff --git a/lddtree.py b/lddtree.py |
21 |
index 7ec04fa..6be4fdd 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,18 @@ 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 |
+ print(interp) |
43 |
+ with open(interp, 'rb') as fp: |
44 |
+ with mmap.mmap(fp.fileno(), 0, prot=mmap.PROT_READ) as mm: |
45 |
+ return mm.find(b'--argv0') >= 0 |
46 |
+ |
47 |
+ |
48 |
def GenerateLdsoWrapper(root, path, interp, libpaths=()): |
49 |
"""Generate a shell script wrapper which uses local ldso to run the ELF |
50 |
|
51 |
@@ -145,6 +158,7 @@ def GenerateLdsoWrapper(root, path, interp, libpaths=()): |
52 |
interp_name), |
53 |
'libpaths': ':'.join(['${basedir}/' + os.path.relpath(p, basedir) |
54 |
for p in libpaths]), |
55 |
+ 'argv0_arg': '--argv0 "$0"' if interp_supports_argv0(interp) else '', |
56 |
} |
57 |
wrapper = """#!/bin/sh |
58 |
if ! base=$(realpath "$0" 2>/dev/null); then |
59 |
@@ -154,12 +168,13 @@ if ! base=$(realpath "$0" 2>/dev/null); then |
60 |
esac |
61 |
fi |
62 |
basedir=${base%%/*} |
63 |
-exec \ |
64 |
- "${basedir}/%(interp)s" \ |
65 |
- --library-path "%(libpaths)s" \ |
66 |
- --inhibit-cache \ |
67 |
- --inhibit-rpath '' \ |
68 |
- "${base}.elf" \ |
69 |
+exec \\ |
70 |
+ "${basedir}/%(interp)s" \\ |
71 |
+ %(argv0_arg)s \\ |
72 |
+ --library-path "%(libpaths)s" \\ |
73 |
+ --inhibit-cache \\ |
74 |
+ --inhibit-rpath '' \\ |
75 |
+ "${base}.elf" \\ |
76 |
"$@" |
77 |
""" |
78 |
wrappath = root + path |