def test_normal_use(self): arch = get_arch('example') obj = ObjectFile(arch) o = BinaryOutputStream(obj) o.select_section('.text') o.emit(Label('a')) self.assertSequenceEqual(bytes(), obj.get_section('.text').data)
def test_save(self): """ Test the generation of a windows exe file """ arch = get_arch('x86_64') obj = ObjectFile(arch) obj.get_section('code', create=True) obj.get_section('data', create=True) f = io.BytesIO() # TODO: ExeWriter().write(obj, f)
def setUp(self): self.source = io.StringIO() self.as_args = [] arch = get_arch(self.march) self.obj = ObjectFile(arch) self.ostream = BinaryOutputStream(self.obj) self.ostream.select_section('code') self.diag = DiagnosticsManager() # Prep assembler! self.assembler = arch.assembler self.assembler.prepare()
def test_undefined_reference(self): arch = get_arch('arm') object1 = ObjectFile(arch) object1.get_section('.text', create=True) object1.add_symbol(0, 'undef', 'global', None, None, 'object', 0) object1.gen_relocation('rel8', 0, '.text', 0) object2 = ObjectFile(arch) with self.assertRaises(CompilerError): link([object1, object2])
def test_code_exceeds_memory(self): """ Check the error that is given when code exceeds memory size """ arch = ExampleArch() layout2 = layout.Layout() m = layout.Memory('flash') m.location = 0x0 m.size = 0x10 m.add_input(layout.Section('code')) layout2.add_memory(m) object1 = ObjectFile(arch) object1.get_section('code', create=True).add_data(bytes([0] * 22)) with self.assertRaisesRegex(CompilerError, 'exceeds'): link([object1], layout2)
def test_save_and_load(self): object1, object2 = self.make_twins() f1 = io.StringIO() object1.save(f1) f2 = io.StringIO(f1.getvalue()) object3 = ObjectFile.load(f2) self.assertEqual(object3, object1)
class AsmTestCaseBase(unittest.TestCase): """ Base testcase for assembly """ def setUp(self): self.source = io.StringIO() self.as_args = [] arch = get_arch(self.march) self.obj = ObjectFile(arch) self.ostream = BinaryOutputStream(self.obj) self.ostream.select_section('code') self.diag = DiagnosticsManager() # Prep assembler! self.assembler = arch.assembler self.assembler.prepare() def feed(self, line): self.assembler.assemble(line, self.ostream, self.diag) print(line, file=self.source) def check(self, hexstr, layout=Layout()): self.assembler.flush() self.obj = link([self.obj], layout) data = bytes(self.obj.get_section('code').data) if hexstr is None: gnu_assemble(self.source.getvalue(), as_args=self.as_args) self.fail('Implement this test-case') else: self.assertSequenceEqual(bytes.fromhex(hexstr), data)
def test_save_load(self): arch = get_arch('arm') ef1 = ElfFile() f = io.BytesIO() ef1.save(f, ObjectFile(arch)) f2 = io.BytesIO(f.getvalue()) ElfFile.load(f2)
def test_parse_failure(self): """ Check the error reporting of the assembler """ arch = get_arch('example') obj = ObjectFile(arch) ostream = BinaryOutputStream(obj) ostream.select_section('code') diag = DiagnosticsManager() assembler = BaseAssembler() with self.assertRaises(CompilerError): assembler.assemble('abc def', ostream, diag)
def test_command(self, mock_stdout, mock_stderr): obj_file = new_temp_file('.obj') bin_file = new_temp_file('.bin') arch = api.get_arch('arm') obj = ObjectFile(arch) data = bytes(range(100)) section = Section('.text') section.add_data(data) image = Image('code2', 0) image.sections.append(section) obj.add_section(section) obj.add_image(image) with open(obj_file, 'w') as f: obj.save(f) objcopy(['-O', 'bin', '-S', 'code2', obj_file, bin_file]) with open(bin_file, 'rb') as f: exported_data = f.read() self.assertEqual(data, exported_data)
def test_memory_layout(self): spec = """ MEMORY flash LOCATION=0x08000000 SIZE=0x3000 { DEFINESYMBOL(codestart) SECTION(code) DEFINESYMBOL(codeend) } MEMORY flash LOCATION=0x20000000 SIZE=0x3000 { SECTION(data) } """ memory_layout = layout.Layout.load(io.StringIO(spec)) arch = ExampleArch() object1 = ObjectFile(arch) object1.get_section('code', create=True).add_data(bytes([0] * 108)) object1.add_symbol(0, 'b', 'global', 24, 'code', 'object', 0) object2 = ObjectFile(arch) object2.get_section('code', create=True).add_data(bytes([0] * 100)) object2.get_section('data', create=True).add_data(bytes([0] * 100)) object2.add_symbol(0, 'a', 'global', 2, 'data', 'object', 0) object2.add_symbol(1, 'c', 'global', 2, 'code', 'object', 0) object3 = link([object1, object2], memory_layout) self.assertEqual(0x20000000 + 2, object3.get_symbol_value('a')) self.assertEqual(0x08000000 + 24, object3.get_symbol_value('b')) self.assertEqual(0x08000000 + 110, object3.get_symbol_value('c')) self.assertEqual(208, object3.get_section('code').size) self.assertEqual(100, object3.get_section('data').size) self.assertEqual(0x08000000, object3.get_symbol_value('codestart')) self.assertEqual(0x08000000 + 208, object3.get_symbol_value('codeend'))
def test_symbol_values(self): """ Check if values are correctly resolved """ arch = get_arch('arm') object1 = ObjectFile(arch) object1.get_section('.text', create=True).add_data(bytes([0] * 108)) object1.add_symbol(0, 'b', 'global', 24, '.text', 'object', 0) object2 = ObjectFile(arch) object2.get_section('.text', create=True).add_data(bytes([0] * 100)) object2.add_symbol(0, 'a', 'global', 2, '.text', 'object', 0) layout1 = layout.Layout() flash_mem = layout.Memory('flash') flash_mem.location = 0x0 flash_mem.size = 0x1000 flash_mem.add_input(layout.SymbolDefinition('code_start')) flash_mem.add_input(layout.Section('.text')) flash_mem.add_input(layout.SymbolDefinition('code_end')) layout1.add_memory(flash_mem) object3 = link([object1, object2], layout1) self.assertEqual(110, object3.get_symbol_value('a')) self.assertEqual(24, object3.get_symbol_value('b')) self.assertEqual(208, object3.get_section('.text').size) self.assertEqual(0, object3.get_symbol_value('code_start')) self.assertEqual(208, object3.get_symbol_value('code_end'))
def test_rel8_relocation(self): arch = get_arch('arm') object1 = ObjectFile(arch) object1.get_section('.text', create=True).add_data(bytes([0] * 100)) object1.add_symbol(10, 'a', 'global', None, None, 'object', 0) object1.gen_relocation('rel8', 10, '.text', 0) object2 = ObjectFile(arch) object2.get_section('.text', create=True).add_data(bytes([0] * 100)) object2.add_symbol(0, 'a', 'global', 24, '.text', 'object', 0) link([object1, object2])
def test_duplicate_symbol(self): arch = get_arch('arm') object1 = ObjectFile(arch) object1.get_section('.text', create=True) object1.add_symbol(0, 'a', 'global', 0, '.text', 'object', 0) object2 = ObjectFile(arch) object2.get_section('.text', create=True) object2.add_symbol(0, 'a', 'global', 0, '.text', 'object', 0) with self.assertRaises(CompilerError): link([object1, object2])
def test_binary_and_logstream(self): arch = ExampleArch() object1 = ObjectFile(arch) stream = binary_and_logging_stream(object1) stream.select_section('code') stream.emit(Mov(R1, R0))
def test_overlapping_sections(self): """ Check that overlapping sections are detected """ obj = ObjectFile(get_arch('msp430')) obj.get_section('s1', create=True).add_data(bytes(range(100))) obj.get_section('s2', create=True).add_data(bytes(range(100))) obj.add_image(Image('x', 0)) obj.get_image('x').add_section(obj.get_section('s1')) obj.get_image('x').add_section(obj.get_section('s2')) with self.assertRaisesRegex(ValueError, 'overlap'): obj.get_image('x').data
def make_twins(self): """ Make two object files that have equal contents """ arch = get_arch('arm') object1 = ObjectFile(arch) object2 = ObjectFile(arch) object2.get_section('code', create=True).add_data(bytes(range(55))) object1.get_section('code', create=True).add_data(bytes(range(55))) object1.add_symbol(10, 'A', 'global', None, None, 'object', 0) object2.add_symbol(10, 'A', 'global', None, None, 'object', 0) object1.gen_relocation('rel8', 10, 'code', 0x2) object2.gen_relocation('rel8', 10, 'code', 0x2) object1.add_symbol(0, 'A2', 'global', 0x90, 'code', 'object', 0) object2.add_symbol(0, 'A2', 'global', 0x90, 'code', 'object', 0) object1.add_symbol(1, 'A3', 'global', 0x90, 'code', 'object', 0) object2.add_symbol(1, 'A3', 'global', 0x90, 'code', 'object', 0) object1.add_image(Image('a', 0x0)) object1.get_image('a').add_section(object1.get_section('code')) object2.add_image(Image('a', 0x0)) object2.get_image('a').add_section(object2.get_section('code')) return object1, object2
def test_save_load(self): arch = get_arch('arm') f = io.BytesIO() write_elf(ObjectFile(arch), f) f2 = io.BytesIO(f.getvalue()) ElfFile.load(f2)
def test_linking(self): """ Test pull in of undefined symbols from libraries. """ arch = get_arch('msp430') obj1 = ObjectFile(arch) obj1.create_section('foo') obj1.add_symbol(0, 'printf', 'global', None, None, 'func', 0) # undefined obj2 = ObjectFile(arch) obj3 = ObjectFile(arch) obj3.create_section('foo') obj3.add_symbol(0, 'syscall', 'global', 0, 'foo', 'func', 0) # defined lib1 = archive([obj2, obj3]) obj4 = ObjectFile(arch) obj4.create_section('foo') obj4.add_symbol(0, 'putc', 'global', 0, 'foo', 'func', 0) # defined obj4.add_symbol(1, 'syscall', 'global', None, None, 'func', 0) # undefined obj5 = ObjectFile(arch) obj5.create_section('foo') obj5.add_symbol(0, 'printf', 'global', 0, 'foo', 'func', 0) # defined obj5.add_symbol(1, 'putc', 'global', None, None, 'func', 0) # undefined lib2 = archive([obj4, obj5]) obj = link([obj1], libraries=[lib1, lib2])
def test_offset_adjustment(self): """ Test if offsets are correctly modified when linking debug info """ arch = get_arch('arm') obj1 = ObjectFile(arch) obj1.get_section('code', create=True).add_data(bytes(59)) obj2 = ObjectFile(arch) obj2.get_section('code', create=True).add_data(bytes(59)) obj2.add_symbol(1, 'x', 'local', 5, 'code') obj2.debug_info = debuginfo.DebugInfo() loc = SourceLocation('a.txt', 1, 1, 22) obj2.debug_info.add( debuginfo.DebugLocation(loc, address=debuginfo.DebugAddress(1))) obj = link([obj1, obj2], debug=True) # Take into account alignment! So 60 + 5 = 65. self.assertEqual(0, obj.debug_info.locations[0].address.symbol_id) self.assertEqual(65, obj.get_symbol_id_value(0))
def test_load_obj_without_dbg(self): obj = ObjectFile(self.arch) self.debugger.load_symbols(obj)