Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/ppci/objectfile.py Tue Mar 25 19:36:51 2014 +0100 +++ b/python/ppci/objectfile.py Fri Apr 11 15:47:50 2014 +0200 @@ -4,6 +4,8 @@ is code, symbol table and relocation information. """ +import json +import binascii from . import CompilerError class Symbol: @@ -15,6 +17,10 @@ def __repr__(self): return 'SYM {}, val={} sec={}'.format(self.name, self.value, self.section) + def __eq__(self, other): + return (self.name, self.value, self.section) == \ + (other.name, other.value, other.section) + class Relocation: """ Represents a relocation entry. A relocation always has a symbol to refer to @@ -28,6 +34,10 @@ def __repr__(self): return 'RELOC {} off={} t={} sec={}'.format(self.sym, self.offset, self.typ, self.section) + def __eq__(self, other): + return (self.sym, self.offset, self.typ, self.section) ==\ + (other.sym, other.offset, other.typ, other.section) + class Section: def __init__(self, name): @@ -45,6 +55,10 @@ def __repr__(self): return 'SECTION {}'.format(self.name) + def __eq__(self, other): + return (self.name == other.name) and (self.address == other.address) \ + and (self.data == other.data) + class ObjectFile: """ Container for sections with compiled code or data. @@ -68,6 +82,7 @@ def add_relocation(self, sym_name, offset, typ, section): assert type(sym_name) is str, str(sym_name) assert section in self.sections + # assert sym_name in self.symbols reloc = Relocation(sym_name, offset, typ, section) self.relocations.append(reloc) return reloc @@ -76,3 +91,64 @@ if not name in self.sections: self.sections[name] = Section(name) return self.sections[name] + + def __eq__(self, other): + return (self.symbols == other.symbols) and \ + (self.sections == other.sections) and \ + (self.relocations == other.relocations) + + def save(self, f): + save_object(self, f) + + +def save_object(o, f): + json.dump(serialize(o), f, indent=2, sort_keys=True) + + +def load_object(f): + return deserialize(json.load(f)) + + +def serialize(x): + res = {} + if isinstance(x, ObjectFile): + res['sections'] = [] + for sname in sorted(x.sections.keys()): + s = x.sections[sname] + res['sections'].append(serialize(s)) + res['symbols'] = [] + for sname in sorted(x.symbols.keys()): + s = x.symbols[sname] + res['symbols'].append(serialize(s)) + res['relocations'] = [] + for reloc in x.relocations: + res['relocations'].append(serialize(reloc)) + elif isinstance(x, Section): + res['name'] = x.name + res['address'] = hex(x.address) + res['data'] = binascii.hexlify(x.data).decode('ascii') + elif isinstance(x, Symbol): + res['name'] = x.name + res['value'] = hex(x.value) + res['section'] = x.section + elif isinstance(x, Relocation): + res['symbol'] = x.sym + res['offset'] = hex(x.offset) + res['type'] = x.typ + res['section'] = x.section + return res + + +def deserialize(d): + obj = ObjectFile() + for section in d['sections']: + so = obj.get_section(section['name']) + so.address = int(section['address'][2:], 16) + so.data = bytearray(binascii.unhexlify(section['data'].encode('ascii'))) + for reloc in d['relocations']: + obj.add_relocation(reloc['symbol'], int(reloc['offset'][2:], 16), + reloc['type'], reloc['section']) + for sym in d['symbols']: + obj.add_symbol(sym['name'], int(sym['value'][2:], 16), sym['section']) + return obj +