annotate python/ppci/objectfile.py @ 384:94f5b719ad0b

Small refactor
author Windel Bouwman
date Sun, 27 Apr 2014 17:50:25 +0200
parents 0c44e494ef58
children d056b552d3f4
rev   line source
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
1
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
2 """
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
3 Object files are used to store assembled code. Information contained
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
4 is code, symbol table and relocation information.
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
5 """
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
6
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
7 import json
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
8 import binascii
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
9 from . import CompilerError, make_num
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
10
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
11 class Symbol:
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
12 def __init__(self, name, value, section):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
13 self.name = name
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
14 self.value = value
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
15 self.section = section
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
16
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
17 def __repr__(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
18 return 'SYM {}, val={} sec={}'.format(self.name, self.value, self.section)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
19
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
20 def __eq__(self, other):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
21 return (self.name, self.value, self.section) == \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
22 (other.name, other.value, other.section)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
23
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
24
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
25 class Relocation:
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 336
diff changeset
26 """ Represents a relocation entry. A relocation always has a symbol to refer to
86b02c98a717 Moved target directory
Windel Bouwman
parents: 336
diff changeset
27 and a relocation type """
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
28 def __init__(self, sym, offset, typ, section):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
29 self.sym = sym
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
30 self.offset = offset
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
31 self.typ = typ
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
32 self.section = section
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
33
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
34 def __repr__(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
35 return 'RELOC {} off={} t={} sec={}'.format(self.sym, self.offset, self.typ, self.section)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
36
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
37 def __eq__(self, other):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
38 return (self.sym, self.offset, self.typ, self.section) ==\
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
39 (other.sym, other.offset, other.typ, other.section)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
40
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
41
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
42 class Section:
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
43 def __init__(self, name):
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
44 self.name = name
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
45 self.address = 0
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
46 self.data = bytearray()
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
47
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
48 def add_data(self, data):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
49 self.data += data
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
50
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
51 @property
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
52 def Size(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
53 return len(self.data)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
54
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
55 def __repr__(self):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
56 return 'SECTION {}'.format(self.name)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
57
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
58 def __eq__(self, other):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
59 return (self.name == other.name) and (self.address == other.address) \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
60 and (self.data == other.data)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
61
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
62
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
63 class ObjectFile:
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
64 """ Container for sections with compiled code or data.
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
65 Also contains symbols and relocation entries """
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
66 def __init__(self):
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
67 self.symbols = {}
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
68 self.sections = {}
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
69 self.relocations = []
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
70
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
71 def find_symbol(self, name):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
72 return self.symbols[name]
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
73
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
74 def add_symbol(self, name, value, section):
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
75 if name in self.symbols:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
76 raise CompilerError('{} already defined'.format(name))
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
77 assert section in self.sections
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
78 sym = Symbol(name, value, section)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
79 self.symbols[name] = sym
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
80 return sym
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
81
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
82 def add_relocation(self, sym_name, offset, typ, section):
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 336
diff changeset
83 assert type(sym_name) is str, str(sym_name)
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
84 assert section in self.sections
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
85 # assert sym_name in self.symbols
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
86 reloc = Relocation(sym_name, offset, typ, section)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
87 self.relocations.append(reloc)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
88 return reloc
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
89
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
90 def get_section(self, name):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
91 if not name in self.sections:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
92 self.sections[name] = Section(name)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
93 return self.sections[name]
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
94
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
95 def __eq__(self, other):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
96 return (self.symbols == other.symbols) and \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
97 (self.sections == other.sections) and \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
98 (self.relocations == other.relocations)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
99
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
100 def save(self, f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
101 save_object(self, f)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
102
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
103
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
104 def save_object(o, f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
105 json.dump(serialize(o), f, indent=2, sort_keys=True)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
106
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
107
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
108 def load_object(f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
109 return deserialize(json.load(f))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
110
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
111
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
112 def serialize(x):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
113 res = {}
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
114 if isinstance(x, ObjectFile):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
115 res['sections'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
116 for sname in sorted(x.sections.keys()):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
117 s = x.sections[sname]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
118 res['sections'].append(serialize(s))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
119 res['symbols'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
120 for sname in sorted(x.symbols.keys()):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
121 s = x.symbols[sname]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
122 res['symbols'].append(serialize(s))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
123 res['relocations'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
124 for reloc in x.relocations:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
125 res['relocations'].append(serialize(reloc))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
126 elif isinstance(x, Section):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
127 res['name'] = x.name
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
128 res['address'] = hex(x.address)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
129 res['data'] = binascii.hexlify(x.data).decode('ascii')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
130 elif isinstance(x, Symbol):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
131 res['name'] = x.name
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
132 res['value'] = hex(x.value)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
133 res['section'] = x.section
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
134 elif isinstance(x, Relocation):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
135 res['symbol'] = x.sym
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
136 res['offset'] = hex(x.offset)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
137 res['type'] = x.typ
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
138 res['section'] = x.section
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
139 return res
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
140
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
141
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
142 def deserialize(d):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
143 obj = ObjectFile()
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
144 for section in d['sections']:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
145 so = obj.get_section(section['name'])
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
146 so.address = make_num(section['address'])
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
147 so.data = bytearray(binascii.unhexlify(section['data'].encode('ascii')))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
148 for reloc in d['relocations']:
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
149 obj.add_relocation(reloc['symbol'], make_num(reloc['offset']),
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
150 reloc['type'], reloc['section'])
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
151 for sym in d['symbols']:
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
152 obj.add_symbol(sym['name'], make_num(sym['value']), sym['section'])
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
153 return obj
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
154