1 |
commit: 8d2fa4fe36cf525bc5a16ec176d0fbe79cfab8e6 |
2 |
Author: Mike Frysinger <vapier <AT> chromium <DOT> org> |
3 |
AuthorDate: Fri Apr 16 15:06:08 2021 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Apr 16 15:06:08 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=8d2fa4fe |
7 |
|
8 |
lddtree: add --cwd option |
9 |
|
10 |
Rather than rely on ambient environmental settings (the cwd), allow |
11 |
users to override the cwd explicitly when processing paths. |
12 |
|
13 |
Bug: https://bugs.gentoo.org/653586 |
14 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
15 |
|
16 |
lddtree.py | 50 ++++++++++++++++++++++++++++++-------------------- |
17 |
1 file changed, 30 insertions(+), 20 deletions(-) |
18 |
|
19 |
diff --git a/lddtree.py b/lddtree.py |
20 |
index d91e729..b8fde0c 100755 |
21 |
--- a/lddtree.py |
22 |
+++ b/lddtree.py |
23 |
@@ -277,13 +277,14 @@ def ParseLdSoConf(ldso_conf, root='/', debug=False, _first=True): |
24 |
return paths |
25 |
|
26 |
|
27 |
-def LoadLdpaths(root='/', prefix='', debug=False): |
28 |
+def LoadLdpaths(root='/', cwd=None, prefix='', debug=False): |
29 |
"""Load linker paths from common locations |
30 |
|
31 |
This parses the ld.so.conf and LD_LIBRARY_PATH env var. |
32 |
|
33 |
Args: |
34 |
root: The root tree to prepend to paths |
35 |
+ cwd: The path to resolve relative paths against |
36 |
prefix: The path under |root| to search |
37 |
debug: Enable debug output |
38 |
|
39 |
@@ -305,7 +306,7 @@ def LoadLdpaths(root='/', prefix='', debug=False): |
40 |
else: |
41 |
# XXX: If this contains $ORIGIN, we probably have to parse this |
42 |
# on a per-ELF basis so it can get turned into the right thing. |
43 |
- ldpaths['env'] = ParseLdPaths(env_ldpath, path='') |
44 |
+ ldpaths['env'] = ParseLdPaths(env_ldpath, cwd=cwd, path='') |
45 |
|
46 |
# Load up /etc/ld.so.conf. |
47 |
ldpaths['conf'] = ParseLdSoConf(root + prefix + '/etc/ld.so.conf', root=root, |
48 |
@@ -374,7 +375,8 @@ def FindLib(elf, lib, ldpaths, root='/', debug=False): |
49 |
|
50 |
# We abuse the _all_libs state. We probably shouldn't, but we do currently. |
51 |
# pylint: disable=dangerous-default-value |
52 |
-def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[]}, |
53 |
+def ParseELF(path, root='/', cwd=None, prefix='', |
54 |
+ ldpaths={'conf':[], 'env':[], 'interp':[]}, |
55 |
display=None, debug=False, _first=True, _all_libs={}): |
56 |
"""Parse the ELF dependency tree of the specified file |
57 |
|
58 |
@@ -382,6 +384,7 @@ def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[ |
59 |
path: The ELF to scan |
60 |
root: The root tree to prepend to paths; this applies to interp and rpaths |
61 |
only as |path| and |ldpaths| are expected to be prefixed already |
62 |
+ cwd: The path to resolve relative paths against. |
63 |
prefix: The path under |root| to search |
64 |
ldpaths: dict containing library paths to search; should have the keys: |
65 |
conf, env, interp |
66 |
@@ -467,9 +470,9 @@ def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[ |
67 |
|
68 |
for t in segment.iter_tags(): |
69 |
if t.entry.d_tag == 'DT_RPATH': |
70 |
- rpaths = ParseLdPaths(bstr(t.rpath), root=root, path=path) |
71 |
+ rpaths = ParseLdPaths(bstr(t.rpath), root=root, cwd=cwd, path=path) |
72 |
elif t.entry.d_tag == 'DT_RUNPATH': |
73 |
- runpaths = ParseLdPaths(bstr(t.runpath), root=root, path=path) |
74 |
+ runpaths = ParseLdPaths(bstr(t.runpath), root=root, cwd=cwd, path=path) |
75 |
elif t.entry.d_tag == 'DT_NEEDED': |
76 |
libs.append(bstr(t.needed)) |
77 |
if runpaths: |
78 |
@@ -511,7 +514,7 @@ def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[ |
79 |
} |
80 |
if fullpath: |
81 |
try: |
82 |
- lret = ParseELF(realpath, root, prefix, ldpaths, display=fullpath, |
83 |
+ lret = ParseELF(realpath, root, cwd, prefix, ldpaths, display=fullpath, |
84 |
debug=debug, _first=False, _all_libs=_all_libs) |
85 |
except exceptions.ELFError as e: |
86 |
warn('%s: %s' % (realpath, e)) |
87 |
@@ -681,18 +684,6 @@ def GetParser(): |
88 |
parser.add_argument('-a', '--all', |
89 |
action='store_true', default=False, |
90 |
help='Show all duplicated dependencies') |
91 |
- parser.add_argument('-R', '--root', |
92 |
- default=os.environ.get('ROOT', ''), type=str, |
93 |
- action=_NormalizePathAction, |
94 |
- help='Search for all files/dependencies in ROOT') |
95 |
- parser.add_argument('-P', '--prefix', |
96 |
- default=os.environ.get( |
97 |
- 'EPREFIX', '@GENTOO_PORTAGE_EPREFIX@'), type=str, |
98 |
- action=_NormalizePathAction, |
99 |
- help='Specify EPREFIX for binaries (for Gentoo Prefix)') |
100 |
- parser.add_argument('--no-auto-root', |
101 |
- dest='auto_root', action='store_false', default=True, |
102 |
- help='Do not automatically prefix input ELFs with ROOT') |
103 |
parser.add_argument('-l', '--list', |
104 |
action='store_true', default=False, |
105 |
help='Display output in a simple list (easy for copying)') |
106 |
@@ -711,6 +702,23 @@ def GetParser(): |
107 |
help='Show version information') |
108 |
parser.add_argument('path', nargs='+') |
109 |
|
110 |
+ group = parser.add_argument_group('Path options') |
111 |
+ group.add_argument('-R', '--root', |
112 |
+ default=os.environ.get('ROOT', ''), type=str, |
113 |
+ action=_NormalizePathAction, |
114 |
+ help='Search for all files/dependencies in ROOT') |
115 |
+ group.add_argument('--no-auto-root', |
116 |
+ dest='auto_root', action='store_false', default=True, |
117 |
+ help='Do not automatically prefix input ELFs with ROOT') |
118 |
+ group.add_argument('-C', '--cwd', |
119 |
+ default=os.getcwd(), type=str, action=_NormalizePathAction, |
120 |
+ help='Path to resolve relative paths against') |
121 |
+ group.add_argument('-P', '--prefix', |
122 |
+ default=os.environ.get( |
123 |
+ 'EPREFIX', '@GENTOO_PORTAGE_EPREFIX@'), type=str, |
124 |
+ action=_NormalizePathAction, |
125 |
+ help='Specify EPREFIX for binaries (for Gentoo Prefix)') |
126 |
+ |
127 |
group = parser.add_argument_group('Copying options') |
128 |
group.add_argument('--copy-to-tree', |
129 |
dest='dest', default=None, type=str, |
130 |
@@ -754,12 +762,14 @@ def main(argv): |
131 |
parser.error('pick one handler for non-ELFs: skip or copy') |
132 |
|
133 |
dbg(options.debug, 'root =', options.root) |
134 |
+ dbg(options.debug, 'cwd =', options.cwd) |
135 |
if options.dest: |
136 |
dbg(options.debug, 'dest =', options.dest) |
137 |
if not paths: |
138 |
err('missing ELF files to scan') |
139 |
|
140 |
- ldpaths = LoadLdpaths(options.root, options.prefix, debug=options.debug) |
141 |
+ ldpaths = LoadLdpaths(options.root, cwd=options.cwd, prefix=options.prefix, |
142 |
+ debug=options.debug) |
143 |
dbg(options.debug, 'ldpaths[conf] =', ldpaths['conf']) |
144 |
dbg(options.debug, 'ldpaths[env] =', ldpaths['env']) |
145 |
|
146 |
@@ -794,7 +804,7 @@ def main(argv): |
147 |
|
148 |
matched = True |
149 |
try: |
150 |
- elf = ParseELF(realpath, options.root, options.prefix, ldpaths, |
151 |
+ elf = ParseELF(realpath, options.root, options.cwd, options.prefix, ldpaths, |
152 |
display=p, debug=options.debug) |
153 |
except exceptions.ELFError as e: |
154 |
if options.skip_non_elfs: |