summaryrefslogtreecommitdiff
path: root/progress.py
diff options
context:
space:
mode:
authoroctorock <79596758+octorock@users.noreply.github.com>2021-05-13 00:51:20 +0200
committeroctorock <79596758+octorock@users.noreply.github.com>2021-05-13 00:51:20 +0200
commitcf4cfc9b6cf52c25c2f4e188f73c70b19fd528ba (patch)
tree0e2f15a97bae09be185f301e38019bcedd7feccb /progress.py
parentf3132cb6821217cbd73989058c7acfe2e17f60d3 (diff)
Rebuild progress script
Diffstat (limited to 'progress.py')
-rw-r--r--progress.py226
1 files changed, 111 insertions, 115 deletions
diff --git a/progress.py b/progress.py
index 7035cc35..f0288333 100644
--- a/progress.py
+++ b/progress.py
@@ -1,118 +1,114 @@
+import argparse
+import git
+import os
-import csv, git, re, argparse, os
-from itertools import chain
-map = open("tmc.map", "r")
-src = 0
-asm = 0
-srcData = 0
-data = 0
-
-parser = argparse.ArgumentParser()
-parser.add_argument("-m", "--matching", dest='matching', action='store_true', help="Output matching progress instead of decompilation progress")
-args = parser.parse_args()
-matching = args.matching
-
-NON_MATCHING_PATTERN = r'((?<=NONMATCH\(")asm/non_matching/.*\.inc)|((?<=NONMATCH\(")asm/non_matching/.*\.s)'
-NON_ASM_PATTERN = r'(^\w+:)|(^\s@)|(^\s*\.)|(^\s*thumb_func_start)'
-
-#def remInvalid(x):
-
-def GetNonMatchingFunctions(files):
- functions = []
-
- for file in files:
- with open(file) as f:
- functions += re.findall(NON_MATCHING_PATTERN, f.read())
-
- #functions = map(lambda x: x != "", functions)
- return functions
-
-def ReadAllLines(fileName):
- lineList = list()
- with open(fileName) as f:
- lineList = f.readlines()
-
- return lineList
-
-def GetFiles(path, ext):
- files = []
- for r, d, f in os.walk(path):
+def collect_non_matching_funcs():
+ result = []
+ for r, d, f in os.walk('asm/non_matching'):
for file in f:
- if file.endswith(ext):
- files.append(os.path.join(r, file))
-
- return files
-
-nonMatchingFunctions = GetNonMatchingFunctions(GetFiles("src", ".c")) if not args.matching else []
-
-# this is actually the size of all non matching asm, not (total - non matching)
-def GetNonMatchingSize(path):
- size = 0
-
- asmFiles = GetFiles(path, ".s") + GetFiles(path, ".inc")
-
- for asmFilePath in asmFiles:
- for x in nonMatchingFunctions: # stupid tuple
- if asmFilePath in x:
- asmLines = ReadAllLines(asmFilePath)
-
- for asmLine in asmLines:
- if len(re.findall(NON_ASM_PATTERN, asmLine, re.DOTALL)) == 0:
- size += 2
-
- return size
-
-nonMatchingASM = GetNonMatchingSize("asm/non_matching")
-
-for line in map:
- reg = re.compile(r"^ \.(\w+)\s+0x[0-9a-f]+\s+(0x[0-9a-f]+) (\w+)\/(.+)\.o")
- matches = reg.split(line)
-
- if (len(matches) < 5):
- continue
-
- section = matches[1]
- size = int(matches[2], 16)
- direc = matches[3]
- basename = matches[4]
-
- # alignment? idk
- if (size & 3):
- size += 4 - (size % 3)
-
- if (section == "text"):
- if (direc == "src"):
- src += size
- elif (direc == "asm"):
- asm += size
- elif (section == "rodata"):
- if (direc == "src"):
- srcData += size
- elif (direc == "data"):
- data += size
-
-total = src + asm
-dataTotal = srcData + data
-
-if matching:
- srcPct = "%.4f" % (100 * (src) / total)
- asmPct = "%.4f" % (100 * (asm) / total)
-else:
- srcPct = "%.4f" % (100 * (src + nonMatchingASM) / total)
- asmPct = "%.4f" % (100 * (asm - nonMatchingASM) / total)
-
-
-srcDataPct = "%.4f" % (100 * srcData / dataTotal)
-dataPct = "%.4f" % (100 * data / dataTotal)
-
-version = 1
-git_object = git.Repo().head.object
-timestamp = str(git_object.committed_date)
-git_hash = git_object.hexsha
-
-####################################################
-
-csv_list = [str(version), timestamp, git_hash, str(srcPct), str(asmPct), str(srcDataPct), str(dataPct)]
-
-print(",".join(csv_list))
+ if file.endswith('.inc'):
+ # Assume that the filename is the function name
+ result.append(file[0:-4])
+ else:
+ print(r,file)
+ return result
+
+
+def parse_map(non_matching_funcs):
+ src = 0
+ asm = 0
+ src_data = 0
+ data = 0
+ non_matching = 0
+
+ with open('tmc.map', 'r') as map:
+ # Skip to the linker script section
+ line = map.readline()
+ while not line.startswith('Linker script and memory map'):
+ line = map.readline()
+ while not line.startswith('rom'):
+ line = map.readline()
+
+ prev_symbol = None
+ prev_addr = 0
+ for line in map:
+ if line.startswith(' .'):
+ arr = line.split()
+ section = arr[0]
+ size = int(arr[2], 16)
+ filepath = arr[3]
+ dir = filepath.split('/')[0]
+
+ if section == '.text':
+ if dir == 'src':
+ src += size
+ elif dir == 'asm':
+ asm += size
+ elif dir == 'data':
+ # scripts
+ data += size
+ elif dir == '..':
+ # libc
+ src += size
+ elif section == '.rodata':
+ if dir == 'src':
+ src_data += size
+ elif dir == 'data':
+ data += size
+
+ elif line.startswith(' '):
+ arr = line.split()
+ if len(arr) == 2 and arr[1] != '': # It is actually a symbol
+
+ if prev_symbol in non_matching_funcs:
+ # Calculate the length for non matching function
+ non_matching += int(arr[0], 16) - prev_addr
+
+ prev_symbol = arr[1]
+ prev_addr = int(arr[0], 16)
+ elif line.strip() == '':
+ # End of linker script section
+ break
+
+ src -= non_matching
+ asm += non_matching
+
+ return (src, asm, src_data, data)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-m', '--matching', dest='matching', action='store_true',
+ help='Output matching progress instead of decompilation progress')
+ args = parser.parse_args()
+ matching = args.matching
+
+ non_matching_funcs = []
+ if matching:
+ non_matching_funcs = collect_non_matching_funcs()
+
+ (src, asm, src_data, data) = parse_map(non_matching_funcs)
+
+ total = src + asm
+ data_total = src_data + data
+
+ src_pct = '%.4f' % (100 * src / total)
+ asm_pct = '%.4f' % (100 * asm / total)
+
+ src_data_pct = '%.4f' % (100 * src_data / data_total)
+ data_pct = '%.4f' % (100 * data / data_total)
+
+ version = 1
+ git_object = git.Repo().head.object
+ timestamp = str(git_object.committed_date)
+ git_hash = git_object.hexsha
+
+ csv_list = [str(version), timestamp, git_hash, str(src_pct),
+ str(asm_pct), str(src_data_pct), str(data_pct)]
+
+ print(','.join(csv_list))
+
+
+if __name__ == '__main__':
+ main()