diff options
Diffstat (limited to 'web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py')
-rw-r--r-- | web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py b/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py deleted file mode 100644 index d2c456fef..000000000 --- a/web/server/h2o/libh2o/deps/picotls/deps/cifra/src/arm/analyse.py +++ /dev/null @@ -1,207 +0,0 @@ -import subprocess -import sys -import re - -function_intro_re = re.compile(r'^(?P<addr>[0-9a-fA-F]{8}) <(?P<name>[a-zA-Z0-9\._]+)>:$') -insn_re = re.compile(r'^\s+(?P<addr>[0-9a-fA-F]+):\s+(?P<insn>[0-9a-fA-F ]+)\s+\t(?P<op>.*)$') - -class Instruction: - def __init__(self, addr, insn, op): - self.addr = long(addr, 16) - self.insn = insn - - args = op.split('\t', 1) - - self.op = args[0].strip() - if len(args) == 2: - comment = args[1].strip().split(';', 1) - else: - comment = args - - self.args = comment[0].strip() - - if len(comment) == 2: - self.comment = comment[1].strip() - else: - self.comment = '' - - def __repr__(self): - return '<insn %r>' % (self.__dict__) - - -def literal_branch_target(t): - return ' <' in t - -class Function: - def __init__(self, addr, name): - self.name = name - self.addr = long(addr, 16) - self.insns = [] - self.calls = [] - - def __repr__(self): - return '<%s %d instructions>' % (self.name, len(self.insns)) - - def add_insn(self, insn): - self.insns.append(Instruction(**insn)) - - def contains_addr(self, addr): - if self.insns: - return addr >= self.addr and addr <= self.insns[-1].addr - else: - return addr == self.addr - - def dump(self): - print self.name + ':' - for insn in self.insns: - print ' ', '%04x' % insn.addr + ':', insn.op, insn.args, '\t;', insn.comment - - def get_literal_word(self, addr): - for insn in self.insns: - if insn.addr == addr and insn.op == '.word': - w = int(insn.args, 16) - if w & 0x80000000: - w = -(w ^ 0xffffffff) + 1 - return w - return None - - def analyse(self, prog): - self.stack_guess = None - regs = {} - - for insn in self.insns: - # stack adjustment with literal - if insn.op == 'sub' and insn.args.startswith('sp, ') and self.stack_guess is None: - sz = int(insn.args.split('#', 1)[1]) - self.stack_guess = sz - - # literal pool loads - if insn.op == 'ldr' and ', [pc, #' in insn.args: - reg, offset = insn.args.split(', [pc, #') - offset = int(offset.replace(']', '')) - word = self.get_literal_word(insn.addr + offset + 2) - if word is not None: - regs[reg] = word - - if insn.op == 'add' and insn.args.startswith('sp, r') and self.stack_guess is None: - reg = insn.args.split(', ')[1] - if reg in regs: - self.stack_guess = regs[reg] - - # static branches - if insn.op[0] == 'b' and literal_branch_target(insn.args): - target = long(insn.args.split(' <', 1)[0], 16) - - targetf = prog.function_at_addr(target) - - if targetf and targetf != self: - self.calls.append(targetf) - - if self.stack_guess is None: - self.stack_guess = 0 - - def stack_usage(self, hints, warns, prog, depth = 0): - hinted_calls = [] - if self.stack_guess: - print ' ' * depth, 'stack:', self.name, self.stack_guess, 'bytes' - - our_hints = [h for h in hints if h and h[0] == self.name] - if our_hints: - hints = [h[1:] for h in our_hints] - hinted_calls = [prog.function_by_name(h[0]) for h in hints if h] - else: - if self.name in warns: - print ' WARN: no calls hints for fn-ptr caller', self.name - - if self.calls + hinted_calls: - call_usage = max([f.stack_usage(hints, warns, prog, depth + 1) for f in self.calls + hinted_calls]) - else: - call_usage = 0 - return self.stack_guess + call_usage - -class Program: - def __init__(self): - self.functions = [] - - # sequence of tuples naming a call sequence known to occur - # this allows working out calls through pointers - self.call_hints = [] - - # function names to warn on if we don't have callees - self.call_warns = set() - - def read_elf(self, elf): - current_fn = None - - for x in subprocess.Popen(['arm-none-eabi-objdump', '-d', elf], - stdout = subprocess.PIPE).stdout: - x = x.rstrip('\n') - m = function_intro_re.match(x) - if m: - fn = Function(**m.groupdict()) - current_fn = fn - self.functions.append(fn) - - m = insn_re.match(x) - if m: - assert current_fn - current_fn.add_insn(m.groupdict()) - - def analyse(self): - for f in self.functions: - f.analyse(self) - - def function_by_name(self, name): - fns = [fn for fn in self.functions if fn.name == name] - if len(fns) == 0: - return None - elif len(fns) == 1: - return fns[0] - else: - print 'warn: more than one function named', name - return None - - def function_at_addr(self, addr): - for f in self.functions: - if f.addr == addr: - return f - return None - - def add_call_hint(self, *seq): - self.call_hints.append(seq) - - def add_call_warn(self, fn): - self.call_warns.add(fn) - - def measure_stack(self, name): - fn = self.function_by_name(name) - if fn is None: - return 0 - - return fn.stack_usage(self.call_hints, self.call_warns, self) - -_, exe, fn = sys.argv - -p = Program() -p.read_elf(exe) - -p.analyse() - -# calls which indirect through fn ptrs -p.add_call_warn('cf_blockwise_accumulate') -p.add_call_warn('cf_blockwise_accumulate_final') - -# hints to resolve those -p.add_call_hint('cf_sha224_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha256_update_block') -p.add_call_hint('cf_sha256_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha256_update_block') -p.add_call_hint('cf_sha384_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha512_update_block') -p.add_call_hint('cf_sha512_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'sha512_update_block') -p.add_call_hint('cf_norx32_encrypt', 'input', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'input_block') -p.add_call_hint('cf_norx32_decrypt', 'input', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'input_block') -p.add_call_hint('cf_cbcmac_stream_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'cbcmac_process') -p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate', 'cf_blockwise_accumulate_final', 'cmac_process_final_pad') -p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate_final', 'cmac_process') -p.add_call_hint('cf_cmac_stream_update', 'cf_blockwise_accumulate_final', 'cmac_process_final_nopad') - - -print 'stack', fn, '=', p.measure_stack(fn) |