Skip to content

Commit

Permalink
Run Pylint over remaining code (gh-14).
Browse files Browse the repository at this point in the history
  • Loading branch information
yugr committed Jan 30, 2022
1 parent a2f696f commit 17d3847
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 29 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ jobs:
- name: flake8
run: pipenv run flake8
- name: pylint
run: pipenv run pylint src
run: |
pipenv run pylint src test
pipenv run pylint -d duplicate-code,invalid-name test/templates/*.py
Coverage:
needs: [Lint, Baseline]
runs-on: ubuntu-latest
Expand Down
23 changes: 13 additions & 10 deletions test/templates/common.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
"""
Common code shared by all generators
"""

import subprocess
import sys
import re
import os

_me = os.path.basename(__file__)
verbose = 0
_ME = os.path.basename(__file__)


def set_basename(file):
global _me
_me = file
global _ME # pylint: disable=global-statement
_ME = file


def error(msg):
"""
Print nicely-formatted error message and exit.
"""
sys.stderr.write(f'{_me}: error: {msg}\n')
sys.stderr.write(f'{_ME}: error: {msg}\n')
sys.exit(1)


def _run(cmd, stdin=None):
def _run(cmd, stdin=None, verbose=0):
"""
Run process and abort on error.
"""
if verbose:
print(f"{_me}: running command: {' '.join(cmd)}")
print(f"{_ME}: running command: {' '.join(cmd)}")
with subprocess.Popen(cmd, stdin=stdin, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) as process:
out, err = process.communicate()
Expand Down Expand Up @@ -65,15 +68,15 @@ def strip_binary(file):
_run(['strip', '-s', file])


def grep(s, regex):
lines = s.split('\n')
def grep(text, regex):
lines = text.split('\n')
return list(filter(lambda s: re.search(regex, s), lines))


def find_address(file, name):
out = _run(['readelf', '-sW', file])
lines = grep(out, fr'{name}$')
assert len(lines) >= 1, f"failed to locate symbol {name} in\n{out}"
assert len(lines) >= 1, f'failed to locate symbol {name} in\n{out}'
line = lines[0]
# Num: Value Size Type Bind Vis Ndx Name
# 27: 0000000000001030 11 FUNC GLOBAL DEFAULT 9 foo
Expand Down
2 changes: 1 addition & 1 deletion test/templates/gen_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
call_type = 'Non-PIC-call' if direct else 'PIC-call'
strip_type = 'stripped' if strip else 'UNstripped'
plt_type = 'PLT' if plt else 'PLT-less'
print(f"Checking {disasm_type} {pic_type} {plt_type} {call_type} {strip_type}")
print(f'Checking {disasm_type} {pic_type} {plt_type} {call_type} {strip_type}')

# Generate object code

Expand Down
2 changes: 1 addition & 1 deletion test/templates/gen_funtable.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
disasm_type = 'GDB' if gdb else 'objdump'
pic_type = 'position-INdependent' if pic else 'position-dependent'
stripped = 'stripped' if strip else 'UNstripped'
print(f"Checking {disasm_type} {pic_type} {stripped}")
print(f'Checking {disasm_type} {pic_type} {stripped}')

# Generate object code

Expand Down
2 changes: 1 addition & 1 deletion test/templates/gen_jumps.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
pic_type = 'position-INdependent' if pic else 'position-dependent'
opt_type = 'optimized' if opt else 'UNoptimized'
stripped = 'stripped' if strip else 'UNstripped'
print(f"Checking {disasm_type} {pic_type} {opt_type} {stripped}")
print(f'Checking {disasm_type} {pic_type} {opt_type} {stripped}')

# Generate object code

Expand Down
2 changes: 1 addition & 1 deletion test/templates/gen_jumptable.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
disasm_type = 'GDB' if gdb else 'objdump'
pic_type = 'position-INdependent' if pic else 'position-dependent'
stripped = 'stripped' if strip else 'UNstripped'
print(f"Checking {disasm_type} {pic_type} {stripped}")
print(f'Checking {disasm_type} {pic_type} {stripped}')

# Generate object code

Expand Down
34 changes: 20 additions & 14 deletions test/test_parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
Unittests of asm2cfg's assembly parser
"""

import unittest

from src.asm2cfg import asm2cfg
Expand All @@ -9,6 +13,10 @@ def _get_the_source_block(blocks):


class ParseLineTestCase(unittest.TestCase):
"""
Tests of parse_line function
"""

@unittest.expectedFailure
def test_linear_sequence(self):
lines = '''\
Expand Down Expand Up @@ -79,10 +87,10 @@ def test_conditional(self):
self.assertEqual(len(dst_block.instructions), 2)

@unittest.expectedFailure
def test_jumptables():
def test_jumptables(self):
lines = '''\
Dump of assembler code for function bar:
0x0000000000001070 <+0>: endbr64
0x0000000000001070 <+0>: endbr64
0x0000000000001074 <+4>: cmp $0x9,%edi
0x0000000000001077 <+7>: ja 0x1120 <bar+176>
0x000000000000107d <+13>: lea 0xf80(%rip),%rdx # 0x2004
Expand All @@ -96,44 +104,42 @@ def test_jumptables():
0x000000000000109a <+42>: callq 0x1040 <foo@plt>
0x000000000000109f <+47>: mov $0xc,%eax
0x00000000000010a4 <+52>: add $0x8,%rsp
0x00000000000010a8 <+56>: retq
0x00000000000010a8 <+56>: retq
0x00000000000010a9 <+57>: nopl 0x0(%rax)
0x00000000000010b0 <+64>: lea 0xf49(%rip),%rdi # 0x2000
0x00000000000010b7 <+71>: xor %eax,%eax
0x00000000000010b9 <+73>: callq 0x1030 <baz@plt>
0x00000000000010be <+78>: mov $0xffffffe7,%eax
0x00000000000010c3 <+83>: add $0x8,%rsp
0x00000000000010c7 <+87>: retq
0x00000000000010c7 <+87>: retq
0x00000000000010c8 <+88>: nopl 0x0(%rax,%rax,1)
0x00000000000010d0 <+96>: mov $0xffffffe5,%eax
0x00000000000010d5 <+101>: add $0x8,%rsp
0x00000000000010d9 <+105>: retq
0x00000000000010d9 <+105>: retq
0x00000000000010da <+106>: nopw 0x0(%rax,%rax,1)
0x00000000000010e0 <+112>: mov $0x21,%eax
0x00000000000010e5 <+117>: add $0x8,%rsp
0x00000000000010e9 <+121>: retq
0x00000000000010e9 <+121>: retq
0x00000000000010ea <+122>: nopw 0x0(%rax,%rax,1)
0x00000000000010f0 <+128>: mov $0x23,%eax
0x00000000000010f5 <+133>: add $0x8,%rsp
0x00000000000010f9 <+137>: retq
0x00000000000010f9 <+137>: retq
0x00000000000010fa <+138>: nopw 0x0(%rax,%rax,1)
0x0000000000001100 <+144>: mov $0x63,%eax
0x0000000000001105 <+149>: add $0x8,%rsp
0x0000000000001109 <+153>: retq
0x0000000000001109 <+153>: retq
0x000000000000110a <+154>: nopw 0x0(%rax,%rax,1)
0x0000000000001110 <+160>: mov $0xa,%eax
0x0000000000001115 <+165>: add $0x8,%rsp
0x0000000000001119 <+169>: retq
0x0000000000001119 <+169>: retq
0x000000000000111a <+170>: nopw 0x0(%rax,%rax,1)
0x0000000000001120 <+176>: retq
'''
0x0000000000001120 <+176>: retq
'''.split('\n')
_, blocks = asm2cfg.parse_lines(lines, False)

# TODO: special block for indirect jumps
self.assertEqual(len(blocks), 2)

self.assertEqual(len(blocks), 4)

# TODO:
# - functions (with and w/o calls)
# - jumptables
# - skip calls
16 changes: 16 additions & 0 deletions test/test_regex.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
"""
Unittests of asm2cfg's regexes
"""

import unittest

from src.asm2cfg import asm2cfg


class FunctionHeaderTestCase(unittest.TestCase):
"""
Tests of function header regex
"""

def test_gdb_unstripped(self):
line = 'Dump of assembler code for function test_function:'
strip, fun = asm2cfg.get_stripped_and_function_name(line)
Expand All @@ -28,6 +36,10 @@ def test_objdump(self):


class CallPatternTestCase(unittest.TestCase):
"""
Tests of call instruction regex
"""

def setUp(self):
self.strip_regex = asm2cfg.get_call_pattern(True)
self.unstrip_regex = asm2cfg.get_call_pattern(False)
Expand Down Expand Up @@ -144,6 +156,10 @@ def test_objdump_indirect_call(self):


class JumpPatternTestCase(unittest.TestCase):
"""
Tests of jump instruction regex
"""

def test_gdb_stripped(self):
line = '0x000055555555600f: jmp 0x55555555603d'
pattern = asm2cfg.get_jump_pattern(True, 'does_not_matter')
Expand Down

0 comments on commit 17d3847

Please sign in to comment.