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