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_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_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_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_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_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) # undefined obj2 = ObjectFile(arch) obj3 = ObjectFile(arch) obj3.create_section('foo') obj3.add_symbol(0, 'syscall', 'global', 0, 'foo') # defined lib1 = archive([obj2, obj3]) obj4 = ObjectFile(arch) obj4.create_section('foo') obj4.add_symbol(0, 'putc', 'global', 0, 'foo') # defined obj4.add_symbol(1, 'syscall', 'global', None, None) # undefined obj5 = ObjectFile(arch) obj5.create_section('foo') obj5.add_symbol(0, 'printf', 'global', 0, 'foo') # defined obj5.add_symbol(1, 'putc', 'global', None, None) # undefined lib2 = archive([obj4, obj5]) obj = link([obj1], libraries=[lib1, lib2])
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