2 # Script to arrange sections to ensure fixed offsets.
4 # Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
6 # This file may be distributed under the terms of the GNU GPLv3 license.
14 # Read in section names and sizes
15 # sections = [(size, align, name), ...]
17 for line in sys.stdin.readlines():
19 idx, name, size, vma, lma, fileoff, align = line.split()
20 if align[:3] != '2**':
22 sections.append((int(size, 16), 2**int(align[3:]), name))
26 doLayout(sections, outname)
28 def alignpos(pos, alignbytes):
30 return (pos + mask) & ~mask
32 def doLayout(sections, outname):
36 # fixedsections = [(addr, sectioninfo, extasectionslist), ...]
38 # canrelocate = [(sectioninfo, list), ...]
41 # Find desired sections.
42 for section in sections:
43 size, align, name = section
44 if name[:11] == '.fixedaddr.':
45 addr = int(name[11:], 16)
46 fixedsections.append((addr, section, []))
48 print "Error: Fixed section %s has non-zero alignment (%d)" % (
51 if name[:6] == '.text.':
52 textsections.append(section)
53 canrelocate.append((section, textsections))
54 if name[:17] == '.rodata.__func__.' or name == '.rodata.str1.1':
55 rodatasections.append(section)
56 #canrelocate.append((section, rodatasections))
57 if name[:8] == '.data16.':
58 datasections.append(section)
59 #canrelocate.append((section, datasections))
61 # Find freespace in fixed address area
63 # fixedAddr = [(freespace, sectioninfo), ...]
65 for i in range(len(fixedsections)):
66 fixedsectioninfo = fixedsections[i]
67 addr, section, extrasectionslist = fixedsectioninfo
68 if i == len(fixedsections) - 1:
71 nextaddr = fixedsections[i+1][0]
72 avail = nextaddr - addr - section[0]
73 fixedAddr.append((avail, fixedsectioninfo))
75 # Attempt to fit other sections into fixed area
78 for freespace, fixedsectioninfo in fixedAddr:
79 fixedaddr, fixedsection, extrasections = fixedsectioninfo
80 addpos = fixedaddr + fixedsection[0]
81 nextfixedaddr = addpos + freespace
82 # print "Filling section %x uses %d, next=%x, available=%d" % (
83 # fixedaddr, fixedsection[0], nextfixedaddr, freespace)
86 for fixedaddrinfo in canrelocate:
87 fitsection, inlist = fixedaddrinfo
88 fitnextaddr = alignpos(addpos, fitsection[1]) + fitsection[0]
89 # print "Test %s - %x vs %x" % (
90 # fitsection[2], fitnextaddr, nextfixedaddr)
91 if fitnextaddr > nextfixedaddr:
94 canfit = (fitnextaddr, fixedaddrinfo)
97 # Found a section that can fit.
98 fitnextaddr, fixedaddrinfo = canfit
99 canrelocate.remove(fixedaddrinfo)
100 fitsection, inlist = fixedaddrinfo
101 inlist.remove(fitsection)
102 extrasections.append(fitsection)
104 # print " Adding %s (size %d align %d)" % (
105 # fitsection[2], fitsection[0], fitsection[1])
107 # Write regular sections
108 output = open(outname, 'wb')
109 for section in textsections:
111 output.write("*(%s)\n" % (name,))
112 output.write("code16_rodata = . ;\n")
113 for section in rodatasections:
115 output.write("*(%s)\n" % (name,))
116 for section in datasections:
118 output.write("*(%s)\n" % (name,))
120 # Write fixed sections
121 output.write("freespace1_start = . ;\n")
123 for addr, section, extrasections in fixedsections:
125 output.write(". = ( 0x%x - code16_start ) ;\n" % (addr,))
128 output.write("freespace1_end = . ;\n")
129 output.write("*(%s)\n" % (name,))
130 for extrasection in extrasections:
131 name = extrasection[2]
132 output.write("*(%s)\n" % (name,))
134 if __name__ == '__main__':