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