blob: 7848957962e564241f539b75147163528340ed09 [file] [log] [blame]
Kevin O'Connor202024a2009-01-17 10:41:28 -05001#!/usr/bin/env python
2# Script to arrange sections to ensure fixed offsets.
3#
4# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
5#
6# This file may be distributed under the terms of the GNU GPLv3 license.
7
8import sys
9
10def main():
Kevin O'Connor711ddc62009-01-17 15:17:34 -050011 # Get output name
12 outname = sys.argv[1]
Kevin O'Connor202024a2009-01-17 10:41:28 -050013
Kevin O'Connor711ddc62009-01-17 15:17:34 -050014 # Read in section names and sizes
15 # sections = [(size, align, name), ...]
Kevin O'Connor202024a2009-01-17 10:41:28 -050016 sections = []
17 for line in sys.stdin.readlines():
18 try:
19 idx, name, size, vma, lma, fileoff, align = line.split()
20 if align[:3] != '2**':
21 continue
Kevin O'Connor711ddc62009-01-17 15:17:34 -050022 sections.append((int(size, 16), 2**int(align[3:]), name))
Kevin O'Connor202024a2009-01-17 10:41:28 -050023 except:
24 pass
25
Kevin O'Connor711ddc62009-01-17 15:17:34 -050026 doLayout(sections, outname)
27
28def alignpos(pos, alignbytes):
29 mask = alignbytes - 1
30 return (pos + mask) & ~mask
31
Kevin O'Connordb802ad2009-01-17 19:35:10 -050032MAXPOS = 0x10000
33
Kevin O'Connor711ddc62009-01-17 15:17:34 -050034def doLayout(sections, outname):
Kevin O'Connor202024a2009-01-17 10:41:28 -050035 textsections = []
36 rodatasections = []
37 datasections = []
Kevin O'Connor711ddc62009-01-17 15:17:34 -050038 # fixedsections = [(addr, sectioninfo, extasectionslist), ...]
39 fixedsections = []
40 # canrelocate = [(sectioninfo, list), ...]
41 canrelocate = []
Kevin O'Connor202024a2009-01-17 10:41:28 -050042
43 # Find desired sections.
44 for section in sections:
Kevin O'Connor711ddc62009-01-17 15:17:34 -050045 size, align, name = section
Kevin O'Connor202024a2009-01-17 10:41:28 -050046 if name[:11] == '.fixedaddr.':
47 addr = int(name[11:], 16)
Kevin O'Connor711ddc62009-01-17 15:17:34 -050048 fixedsections.append((addr, section, []))
49 if align != 1:
50 print "Error: Fixed section %s has non-zero alignment (%d)" % (
51 name, align)
52 sys.exit(1)
Kevin O'Connor202024a2009-01-17 10:41:28 -050053 if name[:6] == '.text.':
54 textsections.append(section)
Kevin O'Connor711ddc62009-01-17 15:17:34 -050055 canrelocate.append((section, textsections))
Kevin O'Connor202024a2009-01-17 10:41:28 -050056 if name[:17] == '.rodata.__func__.' or name == '.rodata.str1.1':
57 rodatasections.append(section)
Kevin O'Connor711ddc62009-01-17 15:17:34 -050058 #canrelocate.append((section, rodatasections))
Kevin O'Connor202024a2009-01-17 10:41:28 -050059 if name[:8] == '.data16.':
60 datasections.append(section)
Kevin O'Connor711ddc62009-01-17 15:17:34 -050061 #canrelocate.append((section, datasections))
62
63 # Find freespace in fixed address area
64 fixedsections.sort()
65 # fixedAddr = [(freespace, sectioninfo), ...]
66 fixedAddr = []
67 for i in range(len(fixedsections)):
68 fixedsectioninfo = fixedsections[i]
69 addr, section, extrasectionslist = fixedsectioninfo
70 if i == len(fixedsections) - 1:
Kevin O'Connordb802ad2009-01-17 19:35:10 -050071 nextaddr = MAXPOS
Kevin O'Connor711ddc62009-01-17 15:17:34 -050072 else:
73 nextaddr = fixedsections[i+1][0]
74 avail = nextaddr - addr - section[0]
75 fixedAddr.append((avail, fixedsectioninfo))
76
77 # Attempt to fit other sections into fixed area
78 fixedAddr.sort()
79 canrelocate.sort()
Kevin O'Connordb802ad2009-01-17 19:35:10 -050080 unused = 0
Kevin O'Connor711ddc62009-01-17 15:17:34 -050081 for freespace, fixedsectioninfo in fixedAddr:
82 fixedaddr, fixedsection, extrasections = fixedsectioninfo
83 addpos = fixedaddr + fixedsection[0]
84 nextfixedaddr = addpos + freespace
85# print "Filling section %x uses %d, next=%x, available=%d" % (
86# fixedaddr, fixedsection[0], nextfixedaddr, freespace)
87 while 1:
88 canfit = None
89 for fixedaddrinfo in canrelocate:
90 fitsection, inlist = fixedaddrinfo
Kevin O'Connordb802ad2009-01-17 19:35:10 -050091 fitsize, fitalign, fitname = fitsection
92 if addpos + fitsize > nextfixedaddr:
93 # Can't fit and nothing else will fit.
Kevin O'Connor711ddc62009-01-17 15:17:34 -050094 break
Kevin O'Connordb802ad2009-01-17 19:35:10 -050095 fitnextaddr = alignpos(addpos, fitalign) + fitsize
96# print "Test %s - %x vs %x" % (
97# fitname, fitnextaddr, nextfixedaddr)
98 if fitnextaddr > nextfixedaddr:
99 # This item can't fit.
100 continue
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500101 canfit = (fitnextaddr, fixedaddrinfo)
102 if canfit is None:
Kevin O'Connordb802ad2009-01-17 19:35:10 -0500103 unused += nextfixedaddr - addpos
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500104 break
105 # Found a section that can fit.
106 fitnextaddr, fixedaddrinfo = canfit
107 canrelocate.remove(fixedaddrinfo)
108 fitsection, inlist = fixedaddrinfo
109 inlist.remove(fitsection)
110 extrasections.append(fitsection)
111 addpos = fitnextaddr
Kevin O'Connordb802ad2009-01-17 19:35:10 -0500112 unused += alignpos(addpos, fitsection[1]) - addpos
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500113# print " Adding %s (size %d align %d)" % (
114# fitsection[2], fitsection[0], fitsection[1])
Kevin O'Connor202024a2009-01-17 10:41:28 -0500115
Kevin O'Connordb802ad2009-01-17 19:35:10 -0500116 firstfixed = fixedsections[0][0]
117 total = MAXPOS-firstfixed
118 totalused = total - unused
119 print "Fixed space: 0x%x-0x%x total: %d used: %d Percent used: %.1f%%" % (
120 firstfixed, MAXPOS, total, totalused,
121 (float(totalused) / total) * 100.0)
122
Kevin O'Connor202024a2009-01-17 10:41:28 -0500123 # Write regular sections
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500124 output = open(outname, 'wb')
Kevin O'Connor202024a2009-01-17 10:41:28 -0500125 for section in textsections:
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500126 name = section[2]
127 output.write("*(%s)\n" % (name,))
128 output.write("code16_rodata = . ;\n")
Kevin O'Connor202024a2009-01-17 10:41:28 -0500129 for section in rodatasections:
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500130 name = section[2]
131 output.write("*(%s)\n" % (name,))
Kevin O'Connor202024a2009-01-17 10:41:28 -0500132 for section in datasections:
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500133 name = section[2]
134 output.write("*(%s)\n" % (name,))
Kevin O'Connor202024a2009-01-17 10:41:28 -0500135
136 # Write fixed sections
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500137 output.write("freespace1_start = . ;\n")
Kevin O'Connor202024a2009-01-17 10:41:28 -0500138 first = 1
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500139 for addr, section, extrasections in fixedsections:
140 name = section[2]
141 output.write(". = ( 0x%x - code16_start ) ;\n" % (addr,))
Kevin O'Connor202024a2009-01-17 10:41:28 -0500142 if first:
143 first = 0
Kevin O'Connor711ddc62009-01-17 15:17:34 -0500144 output.write("freespace1_end = . ;\n")
145 output.write("*(%s)\n" % (name,))
146 for extrasection in extrasections:
147 name = extrasection[2]
148 output.write("*(%s)\n" % (name,))
Kevin O'Connor202024a2009-01-17 10:41:28 -0500149
150if __name__ == '__main__':
151 main()