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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
import copy
import os
import shutil
import subprocess
import sys
library_path = ""
for l in subprocess.run(["ldconfig", "-v"], stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True).stdout.splitlines():
if not l.startswith('\t'):
library_path += l
builddir = os.path.join(os.getcwd(), "build", "allocators")
srcdir = os.path.join(builddir, "src")
if not os.path.isdir(srcdir):
os.makedirs(srcdir)
class Allocator_Sources (object):
# indicate if this source was patched
available = False
clean = True
def __init__(self, name, retrieve_cmds=[], prepare_cmds=[], reset_cmds=[]):
self.name = name
self.dir = os.path.join(srcdir, self.name)
self.retrieve_cmds = retrieve_cmds
self.prepare_cmds = prepare_cmds
self.reset_cmds = reset_cmds
def run_cmds(self, function, verbose, cwd=srcdir):
print(function, self.name, "...")
cmds = getattr(self, function+"_cmds")
for cmd in cmds:
stdout = subprocess.PIPE if not verbose else None
stderr = subprocess.PIPE if not verbose else None
p = subprocess.run(cmd, shell=True, cwd=cwd, stderr=stderr,
stdout=stdout)
if p.returncode:
print(function, self.name, "failed with", p.returncode,
file=sys.stderr)
print(p.stderr, file=sys.stderr)
return False
return True
def prepare(self, verbose):
if not os.path.isdir(self.dir):
if (not self.run_cmds("retrieve", verbose) or
not self.run_cmds("prepare", verbose, cwd=self.dir)):
shutil.rmtree(self.dir, ignore_errors=True)
exit(1)
self.available = True
return True
def reset(self, verbose):
if not self.run_cmds("reset", verbose, cwd=self.dir):
exit(1)
self.clean = True
def patch(self, patches, verbose):
self.prepare(verbose)
stdout = subprocess.PIPE if not verbose else None
stderr = subprocess.PIPE
cwd = os.path.join(srcdir, self.name)
print("Patching", self.name, "...")
for patch in patches:
with open(patch, "rb") as f:
p = subprocess.run("patch -p1", shell=True, cwd=cwd, stderr=stderr,
stdout=stdout, input=f.read())
if p.returncode:
print("Patching of", self.name, "failed.", file=sys.stderr)
exit(1)
class Allocator (object):
allowed_attributes = ["binary_suffix", "version", "sources", "build_cmds",
"LD_PRELOAD", "cmd_prefix", "color"]
def __init__(self, name, **kwargs):
self.name = name
self.dir = os.path.join(builddir, self.name)
# Update attributes
self.__dict__.update((k, v) for k, v in kwargs.items() if k in self.allowed_attributes)
# create all unset attributes
for attr in self.allowed_attributes:
if not hasattr(self, attr):
setattr(self, attr, None)
def build(self, verbose=False):
if not os.path.isdir(self.dir):
if self.sources:
if not self.sources.available:
self.sources.prepare(verbose)
if not self.sources.clean:
self.sources.reset(verbose)
if self.build_cmds:
print("Building", self.name, "...")
for cmd in self.build_cmds:
cmd = cmd.format(**{"dir": self.dir,
"srcdir": self.sources.dir})
stdout = subprocess.PIPE if not verbose else None
stderr = subprocess.PIPE
p = subprocess.run(cmd, cwd=builddir, shell=True,
stderr=stderr, stdout=stdout)
if p.returncode:
print(cmd)
print(p.stderr)
print("Building", self.name, "failed ...")
shutil.rmtree(self.dir, ignore_errors=True)
exit(1)
for attr in ["LD_PRELOAD", "cmd_prefix"]:
try:
value = getattr(self, attr)
setattr(self, attr, value.format(**{"dir": self.dir,
"srcdir": self.sources.dir}))
except AttributeError:
setattr(self, attr, "")
return {"cmd_prefix": self.cmd_prefix,
"binary_suffix": self.binary_suffix or "",
"LD_PRELOAD": self.LD_PRELOAD,
"color": self.color}
class Allocator_Patched (object):
def __init__(self, name, alloc, patches, **kwargs):
self.name = name
self.patches = patches
self.alloc = copy.deepcopy(alloc)
self.alloc.name = self.name
self.alloc.dir = os.path.join(builddir, self.name)
self.alloc.__dict__.update((k, v) for k, v in kwargs.items() if k in self.alloc.allowed_attributes)
def build(self, verbose=False):
if not os.path.isdir(self.alloc.dir):
self.alloc.sources.patch(self.patches, verbose)
return self.alloc.build(verbose=verbose)
|