Mercurial > lcfOS
diff python/ppci/outstream.py @ 342:86b02c98a717 devel
Moved target directory
author | Windel Bouwman |
---|---|
date | Sat, 01 Mar 2014 15:40:31 +0100 |
parents | python/outstream.py@4d204f6f7d4e |
children | 3bb7dcfe5529 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/outstream.py Sat Mar 01 15:40:31 2014 +0100 @@ -0,0 +1,77 @@ +import binascii +from ppci.target import Instruction, DebugInfo, Alignment +from ppci.objectfile import ObjectFile + +""" + The output stream is a stream of instructions that can be output + to a file or binary or hexfile. +""" + + +class OutputStream: + def emit(self, item): + raise NotImplementedError('Abstract base class') + + def selectSection(self, sname): + raise NotImplementedError('Abstract base class') + + +class OutputStreamWriter: + def __init__(self, extra_indent=''): + self.extra_indent = extra_indent + + def dump(self, stream, f): + for s in sorted(stream.sections.keys()): + # print('.section '+ s) + self.dumpSection(stream.sections[s], f) + + def dumpSection(self, s, f): + for i in s.instructions: + if type(i) is DebugInfo: + continue + addr = i.address + insword = i.encode() + assert type(insword) is bytes + insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii') + asm = str(i) + if len(insword) == 0: + print(' {}'.format(asm), file=f) + else: + print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm), file=f) + + +class BinaryOutputStream(OutputStream): + """ Output stream that writes to object file """ + def __init__(self, obj_file): + super().__init__() + self.obj_file = obj_file + + def emit(self, item): + """ Encode instruction and add symbol and relocation information """ + assert isinstance(item, Instruction), str(item) + str(type(item)) + assert self.currentSection + section = self.currentSection + address = self.currentSection.Size + b = item.encode() + syms = item.symbols() + relocs = item.relocations() + section.add_data(b) + for sym in syms: + self.obj_file.add_symbol(sym, address, section.name) + for sym, typ in relocs: + self.obj_file.add_relocation(sym, address, typ, section.name) + # Special case for align, TODO do this different? + if type(item) is Alignment: + while section.Size % item.align != 0: + section.add_data(bytes([0])) + + def selectSection(self, sname): + self.currentSection = self.obj_file.get_section(sname) + + +class DummyOutputStream(OutputStream): + def emit(self, item): + pass + + def selectSection(self, sname): + pass