annotate python/ppci/linker.py @ 383:173e20a47fda

Added linker description loader
author Windel Bouwman
date Sun, 27 Apr 2014 17:40:39 +0200
parents 6df89163e114
children d056b552d3f4
rev   line source
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 345
diff changeset
1 import logging
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
2 import struct
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
3 from .objectfile import ObjectFile
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
4 from . import CompilerError
365
98ff43cfdd36 Nasty bug in adr instruction
Windel Bouwman
parents: 364
diff changeset
5 from .bitfun import encode_imm32
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
6 from .layout import Layout, Section
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
7
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
8
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
9 def align(x, m):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
10 while ((x % m) != 0):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
11 x = x + 1
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
12 return x
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
13
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
14 def wrap_negative(x, bits):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
15 b = struct.unpack('<I', struct.pack('<i', x))[0]
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
16 mask = (1 << bits) - 1
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
17 return b & mask
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
18
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
19 reloc_map = {}
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
20
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
21 def reloc(t):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
22 def f(c):
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
23 reloc_map[t] = c
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
24 return f
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
25
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
26
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
27 @reloc('lit_add_8')
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
28 def apply_lit8(reloc, sym, section, reloc_value):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
29 assert sym.value % 4 == 0
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
30 offset = (sym.value - (align(reloc_value + 2, 4)))
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
31 assert offset in range(0, 1024, 4), str(offset)+str( self.dst.sections)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
32 rel8 = offset >> 2
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
33 section.data[reloc.offset] = rel8
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
34
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
35
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
36 @reloc('wrap_new11')
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
37 def apply_wrap_new11(reloc, sym, section, reloc_value):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
38 offset = sym.value - (align(reloc_value, 2) + 4)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
39 assert offset in range(-2048, 2046, 2)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
40 imm11 = wrap_negative(offset >> 1, 11)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
41 section.data[reloc.offset] = (imm11 & 0xff)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
42 section.data[reloc.offset + 1] |= (imm11 >> 8) & 0x7
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
43
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
44
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
45 @reloc('rel8')
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
46 def apply_rel8(reloc, sym, section, reloc_value):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
47 assert sym.value % 2 == 0
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
48 offset = sym.value - (align(reloc_value, 2) + 4)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
49 assert offset in range(-256, 254, 2), str(offset) + str(reloc)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
50 imm8 = wrap_negative(offset >> 1, 8)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
51 section.data[reloc.offset] = imm8
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
52
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
53
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
54 @reloc('bl_imm11_imm10')
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
55 def apply_bl_imm11(reloc, sym, section, reloc_value):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
56 assert sym.value % 2 == 0
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
57 offset = sym.value - (align(reloc_value, 2) + 4)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
58 assert offset in range(-16777216, 16777214, 2), str(offset)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
59 imm32 = wrap_negative(offset >> 1, 32)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
60 imm11 = imm32 & 0x7FF
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
61 imm10 = (imm32 >> 11) & 0x3FF
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
62 s = (imm32 >> 24) & 0x1
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
63 section.data[reloc.offset + 2] = imm11 & 0xFF
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
64 section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
65 section.data[reloc.offset] = imm10 & 0xff
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
66 section.data[reloc.offset + 1] |= ((imm10 >> 8) & 0x3) | (s << 2)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
67
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
68 @reloc('b_imm11_imm6')
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
69 def apply_b_imm11_imm6(reloc, sym, section, reloc_value):
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
70 assert sym.value % 2 == 0
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
71 offset = sym.value - (align(reloc_value, 2) + 4)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
72 assert offset in range(-1048576, 1048574, 2), str(offset)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
73 imm32 = wrap_negative(offset >> 1, 32)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
74 imm11 = imm32 & 0x7FF
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
75 imm6 = (imm32 >> 11) & 0x3F
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
76 s = (imm32 >> 24) & 0x1
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
77 section.data[reloc.offset + 2] = imm11 & 0xFF
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
78 section.data[reloc.offset + 3] |= (imm11 >> 8) & 0x7
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
79 section.data[reloc.offset] |= imm6
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
80 section.data[reloc.offset + 1] |= (s << 2)
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
81
345
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
82 # ARM reloc!!
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
83 # TODO: move to target classes???
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
84 @reloc('b_imm24')
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
85 def apply_b_imm24(reloc, sym, section, reloc_value):
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
86 assert sym.value % 4 == 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
87 assert reloc_value % 4 == 0
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
88 offset = (sym.value - (reloc_value + 8))
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
89 rel24 = wrap_negative(offset >> 2, 24)
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
90 section.data[reloc.offset+2] = (rel24 >> 16) & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
91 section.data[reloc.offset+1] = (rel24 >> 8) & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
92 section.data[reloc.offset+0] = rel24 & 0xFF
b4882ff0ed06 Added more arm isa tests
Windel Bouwman
parents: 336
diff changeset
93
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
94
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
95 @reloc('ldr_imm12')
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
96 def apply_ldr_imm12(reloc, sym, section, reloc_value):
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
97 assert sym.value % 4 == 0
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
98 assert reloc_value % 4 == 0
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
99 offset = (sym.value - (reloc_value + 8))
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
100 U = 1
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
101 if offset < 0:
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
102 offset = -offset
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
103 U = 0
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
104 assert offset < 4096, str(sym) + str(section) + str(reloc)
365
98ff43cfdd36 Nasty bug in adr instruction
Windel Bouwman
parents: 364
diff changeset
105 section.data[reloc.offset+2] |= (U << 7)
350
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
106 section.data[reloc.offset+1] |= (offset >> 8) & 0xF
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
107 section.data[reloc.offset+0] = offset & 0xFF
2b02bd286fe9 Fixed A9 hello worle
Windel Bouwman
parents: 348
diff changeset
108
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
109 @reloc('adr_imm12')
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
110 def apply_adr_imm12(reloc, sym, section, reloc_value):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
111 assert sym.value % 4 == 0
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
112 assert reloc_value % 4 == 0
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
113 offset = (sym.value - (reloc_value + 8))
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
114 U = 2
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
115 if offset < 0:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
116 offset = -offset
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
117 U = 1
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
118 assert offset < 4096
365
98ff43cfdd36 Nasty bug in adr instruction
Windel Bouwman
parents: 364
diff changeset
119 offset = encode_imm32(offset)
364
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
120 section.data[reloc.offset+2] |= (U << 6)
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
121 section.data[reloc.offset+1] |= (offset >> 8) & 0xF
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
122 section.data[reloc.offset+0] = offset & 0xFF
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
123
364
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
124 @reloc('absaddr32')
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
125 def apply_absaddr32(reloc, sym, section, reloc_value):
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
126 assert sym.value % 4 == 0
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
127 assert reloc_value % 4 == 0
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
128 offset = sym.value
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
129 section.data[reloc.offset+3] = (offset >> 24) & 0xFF
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
130 section.data[reloc.offset+2] = (offset >> 16) & 0xFF
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
131 section.data[reloc.offset+1] = (offset >> 8) & 0xFF
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
132 section.data[reloc.offset+0] = offset & 0xFF
c49459768aaa Work on globals
Windel Bouwman
parents: 363
diff changeset
133
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 350
diff changeset
134
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
135 class Linker:
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
136 """ Merges the sections of several object files and
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
137 performs relocation """
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 345
diff changeset
138 def __init__(self):
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 345
diff changeset
139 self.logger = logging.getLogger('Linker')
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 345
diff changeset
140
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
141 def link(self, objs, layout):
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents: 365
diff changeset
142 assert type(objs) is list
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
143 assert type(layout) is Layout
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
144 # Create new object file to store output:
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
145 self.dst = ObjectFile()
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
146
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
147 # Create sections with address:
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
148 for mem in layout.mems:
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
149 for inp in mem.inputs:
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
150 if type(inp) is Section:
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
151 self.dst.get_section(inp.section_name).address = mem.location
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
152
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
153 # First copy all sections into output sections:
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
154 for iobj in objs:
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
155 offsets = {}
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
156 # Merge sections:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
157 for in_s in iobj.sections.values():
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
158 out_s = self.dst.get_section(in_s.name)
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
159 # TODO: align section in other way:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
160 while out_s.Size % 4 != 0:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
161 out_s.add_data(bytes([0]))
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
162
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
163 # Add new section:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
164 offsets[in_s.name] = out_s.Size
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
165 out_s.add_data(in_s.data)
348
442fb043d149 Added log option to zcc
Windel Bouwman
parents: 345
diff changeset
166 self.logger.debug('{} {}({})'.format(offsets[in_s.name], iobj, in_s.name))
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
167
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
168 # Merge symbols:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
169 for sym in iobj.symbols.values():
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
170 out_s = self.dst.get_section(sym.section)
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
171 value = offsets[sym.section] + out_s.address + sym.value
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
172 self.dst.add_symbol(sym.name, value, sym.section)
363
396e5cefba13 Removed debuginfo instruction
Windel Bouwman
parents: 354
diff changeset
173 self.logger.debug('{} at 0x{:08X} in section {}'.format(sym.name, value, sym.section))
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
174
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
175 # Merge relocations:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
176 for reloc in iobj.relocations:
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
177 offset = offsets[reloc.section] + reloc.offset
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
178 self.dst.add_relocation(reloc.sym, offset, reloc.typ, reloc.section)
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
179
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
180 # Apply layout rules:
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
181 # TODO
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
182
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
183 # Perform relocations:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
184 for reloc in self.dst.relocations:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
185 # Lookup symbol:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
186 if reloc.sym not in self.dst.symbols:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
187 raise CompilerError('Undefined reference "{}"'.format(reloc.sym))
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
188 sym = self.dst.symbols[reloc.sym]
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
189 # patch up:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
190 section = self.dst.get_section(reloc.section)
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
191
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
192 # Determine location in memory of reloc patchup position:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
193 reloc_value = section.address + reloc.offset
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
194
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
195 if reloc.typ in reloc_map:
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
196 f = reloc_map[reloc.typ]
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 335
diff changeset
197 f(reloc, sym, section, reloc_value)
335
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
198 else:
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
199 raise NotImplementedError('Unknown relocation type {}'.format(reloc.typ))
582a1aaa3983 Added long branch format
Windel Bouwman
parents: 334
diff changeset
200
334
6f4753202b9a Added more recipes
Windel Bouwman
parents:
diff changeset
201 return self.dst