-
Notifications
You must be signed in to change notification settings - Fork 0
/
instrument.py
52 lines (39 loc) · 1.38 KB
/
instrument.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
# Returns the last instruction in the basic block, along with
# its index. Note: the last instruction in a basic block is not
# necessarily the last item in the instr_list.
def get_last_instruction(instr_list):
for i, line in enumerate(reversed(instr_list)):
if line.startswith(".") \
or line.startswith("_") \
or line.startswith("#"):
continue
return len(instr_list) - i - 1, line
# Return true iff an instruction is a CTI.
def is_cti(instr):
if "call" in instr or "ret" in instr:
return True
elif instr.startswith("j"):
return True
return False
# Add some instructions to the beginning of a basic block
def add_to_beginning(instr_list, *instrs):
for instr in reversed(instrs):
instr_list.insert(0, instr)
# Add some instructions to the end of a basic block (before any
# CTI that ends the basic block).
def add_to_end(instr_list, *instrs):
i, last = get_last_instruction(instr_list)
if not is_cti(last):
i += 1
for instr in reversed(instrs):
instr_list.insert(i, instr)
# Visit the instructions of a basic block. This needs to return a
# list of instructions in the instrumented block.
def visit_basic_block(instr_list):
add_to_beginning(instr_list,
"push %rax",
"pop %rax")
add_to_end(instr_list,
"push %rbp",
"pop %rbp")
return instr_list