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