1#!/usr/bin/env python
2#
3# Mark functions in an arm assembly file. This is done by surrounding the
4# function with "# -- Begin Name" and "# -- End Name"
5# (This script is designed for aarch64 ios assembly syntax)
6import sys
7import re
8
9inp = open(sys.argv[1], "r").readlines()
10
11# First pass
12linenum = 0
13INVALID=-100
14last_align = INVALID
15last_code = INVALID
16last_globl = INVALID
17last_globl_name = None
18begin = INVALID
19in_text_section = False
20begins = dict()
21for line in inp:
22    linenum += 1
23    if re.search(r'.section\s+__TEXT,__text,regular,pure_instructions', line):
24        in_text_section = True
25        continue
26    elif ".section" in line:
27        in_text_section = False
28        continue
29
30    if not in_text_section:
31        continue
32
33    if ".align" in line:
34        last_align = linenum
35    gl = re.search(r'.globl\s+(\w+)', line)
36    if gl:
37        last_globl_name = gl.group(1)
38        last_globl = linenum
39    m = re.search(r'^(\w+):', line)
40    if m and begin == INVALID:
41        labelname = m.group(1)
42        if last_globl+2 == linenum and last_globl_name == labelname:
43            begin = last_globl
44            funcname = labelname
45    if line == "\n" and begin != INVALID:
46        end = linenum
47        triple = (funcname, begin, end)
48        begins[begin] = triple
49        begin = INVALID
50
51# Second pass: Mark
52out = open(sys.argv[1], "w")
53in_func = None
54linenum = 0
55for line in inp:
56    linenum += 1
57    if in_func is not None and linenum == end:
58        out.write("# -- End  %s\n" % in_func)
59        in_func = None
60
61    triple = begins.get(linenum)
62    if triple is not None:
63        in_func, begin, end = triple
64        out.write("# -- Begin  %s\n" % in_func)
65    out.write(line)
66