annotate python/ppci/objectfile.py @ 385:d056b552d3f4

Made better use of layout
author Windel Bouwman
date Thu, 01 May 2014 14:03:12 +0200
parents 94f5b719ad0b
children
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 = []
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
70 self.images = {}
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
71
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
72 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
73 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
74
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
75 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
76 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
77 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
78 assert section in self.sections
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
79 sym = Symbol(name, value, section)
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
80 self.symbols[name] = sym
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
81 return sym
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
82
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
83 def add_relocation(self, sym_name, offset, typ, section):
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 336
diff changeset
84 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
85 assert section in self.sections
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
86 # assert sym_name in self.symbols
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
87 reloc = Relocation(sym_name, offset, typ, section)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
88 self.relocations.append(reloc)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
89 return reloc
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
90
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
91 def get_section(self, name):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
92 if not name in self.sections:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
93 self.sections[name] = Section(name)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
94 return self.sections[name]
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
95
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
96 def get_image(self, name):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
97 return self.images[name]
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
98
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
99 def get_symbol_value(self, name):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
100 symbol = self.find_symbol(name)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
101 section = self.get_section(symbol.section)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
102 return symbol.value + section.address
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
103
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
104 def __eq__(self, other):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
105 return (self.symbols == other.symbols) and \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
106 (self.sections == other.sections) and \
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
107 (self.relocations == other.relocations)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
108
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
109 def save(self, f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
110 save_object(self, f)
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
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
113 def save_object(o, f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
114 json.dump(serialize(o), f, indent=2, sort_keys=True)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
115
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
116
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
117 def load_object(f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
118 return deserialize(json.load(f))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
119
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
120
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
121 def bin2asc(data):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
122 return binascii.hexlify(data).decode('ascii')
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
123
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
124 def asc2bin(data):
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
125 return bytearray(binascii.unhexlify(data.encode('ascii')))
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
126
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
127
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
128 def serialize(x):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
129 res = {}
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
130 if isinstance(x, ObjectFile):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
131 res['sections'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
132 for sname in sorted(x.sections.keys()):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
133 s = x.sections[sname]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
134 res['sections'].append(serialize(s))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
135 res['symbols'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
136 for sname in sorted(x.symbols.keys()):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
137 s = x.symbols[sname]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
138 res['symbols'].append(serialize(s))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
139 res['relocations'] = []
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
140 for reloc in x.relocations:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
141 res['relocations'].append(serialize(reloc))
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
142 res['images'] = {}
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
143 for image_name in x.images:
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
144 res['images'][image_name] = bin2asc(x.images[image_name])
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
145 elif isinstance(x, Section):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
146 res['name'] = x.name
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
147 res['address'] = hex(x.address)
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
148 res['data'] = bin2asc(x.data)
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
149 elif isinstance(x, Symbol):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
150 res['name'] = x.name
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
151 res['value'] = hex(x.value)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
152 res['section'] = x.section
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
153 elif isinstance(x, Relocation):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
154 res['symbol'] = x.sym
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
155 res['offset'] = hex(x.offset)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
156 res['type'] = x.typ
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
157 res['section'] = x.section
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
158 return res
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
159
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
160
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
161 def deserialize(d):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
162 obj = ObjectFile()
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
163 for section in d['sections']:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
164 so = obj.get_section(section['name'])
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
165 so.address = make_num(section['address'])
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
166 so.data = asc2bin(section['data'])
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
167 for reloc in d['relocations']:
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
168 obj.add_relocation(reloc['symbol'], make_num(reloc['offset']),
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
169 reloc['type'], reloc['section'])
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
170 for sym in d['symbols']:
384
94f5b719ad0b Small refactor
Windel Bouwman
parents: 382
diff changeset
171 obj.add_symbol(sym['name'], make_num(sym['value']), sym['section'])
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
172 for image_name in d['images']:
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 384
diff changeset
173 obj.images[image_name] = asc2bin(d['images'][image_name])
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
174 return obj
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 342
diff changeset
175