-
Notifications
You must be signed in to change notification settings - Fork 0
/
ld.py
88 lines (75 loc) · 2.68 KB
/
ld.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022, Vanessa Sochat"
__license__ = "GPL-3.0"
import elfcall.utils as utils
from glob import glob
import os
class LibraryParser:
def __init__(self):
"""Return a list of parsed paths"""
self.library_paths = []
self.conf_paths = []
# Keep lookup of where each came from
self.sources = []
def parse(self):
self.conf_paths = self.parse_ld_so_conf()
self.library_paths = self.parse_ld_library_path()
def find_source(self, name):
"""
Given a source directory (usually something from ld paths) return source
"""
for item in self.sources:
if item["lib"] == name:
return item["source"]
def parse_ld_so_conf(self):
paths = []
for filename in ["/etc/ld.so.conf", "/etc/ld-elf.so.conf"]:
if os.path.exists(filename):
paths += self._parse_ld_config_file(filename)
return paths
def _parse_ld_config_file(self, filename):
"""
Recursively parse an ld config file
"""
paths = []
for line in utils.read_file(filename).split("\n"):
line = line.strip()
if not line:
continue
if line.startswith("#"):
continue
if line.startswith("include"):
line = line.replace("include", "").strip()
for filename in glob(line):
paths += self._parse_ld_config_file(filename)
continue
# If we get here, append the line
paths.append(line)
# Remember where it came from
self.sources.append({"lib": line, "source": filename})
return paths
def parse_ld_library_path(self):
"""
Get LD_LIBRARY_PATH from the environment
"""
path = os.environ.get("LD_LIBRARY_PATH")
if not path:
return []
# TODO we might want to add PWD here if the last one is empty
# it's technically valid (but is it common? should we leave out?)
#
paths = [x for x in path.split(":") if x]
for path in paths:
self.sources.append({"lib": path, "source": "LD_LIBRARY_PATH"})
return paths
@property
def default_paths(self):
return ["/lib", "/lib64", "/usr/lib", "/usr/lib64"]
def set_default_paths(self):
"""
Add to sources, but don't add to paths list, because default paths
come after the DT_RUNTIME and/or DT_RPATH.
"""
for path in self.default_paths:
self.sources.append({"lib": path, "source": "default"})
return []