Mercurial > lcfOS
comparison 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 |
comparison
equal
deleted
inserted
replaced
341:4d204f6f7d4e | 342:86b02c98a717 |
---|---|
1 import binascii | |
2 from ppci.target import Instruction, DebugInfo, Alignment | |
3 from ppci.objectfile import ObjectFile | |
4 | |
5 """ | |
6 The output stream is a stream of instructions that can be output | |
7 to a file or binary or hexfile. | |
8 """ | |
9 | |
10 | |
11 class OutputStream: | |
12 def emit(self, item): | |
13 raise NotImplementedError('Abstract base class') | |
14 | |
15 def selectSection(self, sname): | |
16 raise NotImplementedError('Abstract base class') | |
17 | |
18 | |
19 class OutputStreamWriter: | |
20 def __init__(self, extra_indent=''): | |
21 self.extra_indent = extra_indent | |
22 | |
23 def dump(self, stream, f): | |
24 for s in sorted(stream.sections.keys()): | |
25 # print('.section '+ s) | |
26 self.dumpSection(stream.sections[s], f) | |
27 | |
28 def dumpSection(self, s, f): | |
29 for i in s.instructions: | |
30 if type(i) is DebugInfo: | |
31 continue | |
32 addr = i.address | |
33 insword = i.encode() | |
34 assert type(insword) is bytes | |
35 insword = binascii.hexlify(bytes(reversed(insword))).decode('ascii') | |
36 asm = str(i) | |
37 if len(insword) == 0: | |
38 print(' {}'.format(asm), file=f) | |
39 else: | |
40 print(' 0x{0:08x} 0x{1} {2}'.format(addr, insword, asm), file=f) | |
41 | |
42 | |
43 class BinaryOutputStream(OutputStream): | |
44 """ Output stream that writes to object file """ | |
45 def __init__(self, obj_file): | |
46 super().__init__() | |
47 self.obj_file = obj_file | |
48 | |
49 def emit(self, item): | |
50 """ Encode instruction and add symbol and relocation information """ | |
51 assert isinstance(item, Instruction), str(item) + str(type(item)) | |
52 assert self.currentSection | |
53 section = self.currentSection | |
54 address = self.currentSection.Size | |
55 b = item.encode() | |
56 syms = item.symbols() | |
57 relocs = item.relocations() | |
58 section.add_data(b) | |
59 for sym in syms: | |
60 self.obj_file.add_symbol(sym, address, section.name) | |
61 for sym, typ in relocs: | |
62 self.obj_file.add_relocation(sym, address, typ, section.name) | |
63 # Special case for align, TODO do this different? | |
64 if type(item) is Alignment: | |
65 while section.Size % item.align != 0: | |
66 section.add_data(bytes([0])) | |
67 | |
68 def selectSection(self, sname): | |
69 self.currentSection = self.obj_file.get_section(sname) | |
70 | |
71 | |
72 class DummyOutputStream(OutputStream): | |
73 def emit(self, item): | |
74 pass | |
75 | |
76 def selectSection(self, sname): | |
77 pass |