blob: 6616721d1b584892074491b292bac669c33ef104 [file] [log] [blame]
Kevin O'Connor202024a2009-01-17 10:41:28 -05001#!/usr/bin/env python
Kevin O'Connor5b8f8092009-09-20 19:47:45 -04002# Script to analyze code and arrange ld sections.
Kevin O'Connor202024a2009-01-17 10:41:28 -05003#
Kevin O'Connorab482e02014-06-11 14:00:21 -04004# Copyright (C) 2008-2014 Kevin O'Connor <kevin@koconnor.net>
Kevin O'Connor202024a2009-01-17 10:41:28 -05005#
6# This file may be distributed under the terms of the GNU GPLv3 license.
7
Johannes Krampf0a82fc72014-01-12 11:39:57 -05008import operator
Kevin O'Connor202024a2009-01-17 10:41:28 -05009import sys
10
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040011# LD script headers/trailers
12COMMONHEADER = """
Kevin O'Connorffc06872014-06-11 15:40:04 -040013/* DO NOT EDIT! This is an autogenerated file. See scripts/layoutrom.py. */
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040014OUTPUT_FORMAT("elf32-i386")
15OUTPUT_ARCH("i386")
16SECTIONS
17{
18"""
19COMMONTRAILER = """
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040020
21 /* Discard regular data sections to force a link error if
22 * code attempts to access data not marked with VAR16 (or other
23 * appropriate macro)
24 */
25 /DISCARD/ : {
26 *(.text*) *(.data*) *(.bss*) *(.rodata*)
Kevin O'Connor90ebed42012-06-21 20:54:53 -040027 *(COMMON) *(.discard*) *(.eh_frame) *(.note*)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040028 }
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040029}
30"""
31
Kevin O'Connorc0693942009-06-10 21:56:01 -040032
33######################################################################
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040034# Determine section locations
Kevin O'Connorc0693942009-06-10 21:56:01 -040035######################################################################
36
Kevin O'Connor3910de02016-02-19 21:34:16 -050037# Align 'pos' up to 'alignbytes' offset
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040038def alignpos(pos, alignbytes):
39 mask = alignbytes - 1
40 return (pos + mask) & ~mask
41
Kevin O'Connor3910de02016-02-19 21:34:16 -050042# Align 'pos' down to 'alignbytes' offset
43def aligndown(pos, alignbytes):
44 mask = alignbytes - 1
45 return pos & ~mask
46
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040047# Determine the final addresses for a list of sections that end at an
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040048# address.
Kevin O'Connor46b82622012-05-13 12:10:30 -040049def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040050 totspace = 0
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040051 for section in sections:
Kevin O'Connor3910de02016-02-19 21:34:16 -050052 minalign = max(minalign, section.align)
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040053 totspace = alignpos(totspace, section.align) + section.size
Johannes Krampf9d7d0442014-01-12 11:19:22 -050054 startaddr = int((endaddr - totspace) / minalign) * minalign
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040055 curaddr = startaddr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040056 for section in sections:
57 curaddr = alignpos(curaddr, section.align)
58 section.finalloc = curaddr
Kevin O'Connor46b82622012-05-13 12:10:30 -040059 section.finalsegloc = curaddr - segoffset
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040060 curaddr += section.size
Kevin O'Connor46b82622012-05-13 12:10:30 -040061 return startaddr, minalign
Kevin O'Connorc0693942009-06-10 21:56:01 -040062
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040063# The 16bit code can't exceed 64K of space.
64BUILD_BIOS_ADDR = 0xf0000
65BUILD_BIOS_SIZE = 0x10000
Kevin O'Connor46b82622012-05-13 12:10:30 -040066BUILD_ROM_START = 0xc0000
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -040067BUILD_LOWRAM_END = 0xa0000
Kevin O'Connor6d152642013-02-19 21:35:20 -050068# Space to reserve in f-segment for dynamic allocations
69BUILD_MIN_BIOSTABLE = 2048
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040070
71# Layout the 16bit code. This ensures sections with fixed offset
72# requirements are placed in the correct location. It also places the
73# 16bit code as high as possible in the f-segment.
74def fitSections(sections, fillsections):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040075 # fixedsections = [(addr, section), ...]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040076 fixedsections = []
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040077 for section in sections:
78 if section.name.startswith('.fixedaddr.'):
79 addr = int(section.name[11:], 16)
Kevin O'Connor46b82622012-05-13 12:10:30 -040080 section.finalloc = addr + BUILD_BIOS_ADDR
81 section.finalsegloc = addr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040082 fixedsections.append((addr, section))
83 if section.align != 1:
Johannes Krampf064fd062014-01-12 11:14:54 -050084 print("Error: Fixed section %s has non-zero alignment (%d)" % (
85 section.name, section.align))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040086 sys.exit(1)
Johannes Krampf0a82fc72014-01-12 11:39:57 -050087 fixedsections.sort(key=operator.itemgetter(0))
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040088 firstfixed = fixedsections[0][0]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040089
90 # Find freespace in fixed address area
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040091 # fixedAddr = [(freespace, section), ...]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040092 fixedAddr = []
93 for i in range(len(fixedsections)):
94 fixedsectioninfo = fixedsections[i]
95 addr, section = fixedsectioninfo
96 if i == len(fixedsections) - 1:
97 nextaddr = BUILD_BIOS_SIZE
98 else:
99 nextaddr = fixedsections[i+1][0]
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400100 avail = nextaddr - addr - section.size
101 fixedAddr.append((avail, section))
Johannes Krampf0a82fc72014-01-12 11:39:57 -0500102 fixedAddr.sort(key=operator.itemgetter(0))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400103
104 # Attempt to fit other sections into fixed area
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400105 canrelocate = [(section.size, section.align, section.name, section)
106 for section in fillsections]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400107 canrelocate.sort()
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400108 canrelocate = [section for size, align, name, section in canrelocate]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400109 totalused = 0
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400110 for freespace, fixedsection in fixedAddr:
Kevin O'Connor46b82622012-05-13 12:10:30 -0400111 addpos = fixedsection.finalsegloc + fixedsection.size
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400112 totalused += fixedsection.size
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400113 nextfixedaddr = addpos + freespace
Johannes Krampf064fd062014-01-12 11:14:54 -0500114# print("Filling section %x uses %d, next=%x, available=%d" % (
115# fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400116 while 1:
117 canfit = None
118 for fitsection in canrelocate:
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400119 if addpos + fitsection.size > nextfixedaddr:
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400120 # Can't fit and nothing else will fit.
121 break
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400122 fitnextaddr = alignpos(addpos, fitsection.align) + fitsection.size
Johannes Krampf064fd062014-01-12 11:14:54 -0500123# print("Test %s - %x vs %x" % (
124# fitsection.name, fitnextaddr, nextfixedaddr))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400125 if fitnextaddr > nextfixedaddr:
126 # This item can't fit.
127 continue
128 canfit = (fitnextaddr, fitsection)
129 if canfit is None:
130 break
131 # Found a section that can fit.
132 fitnextaddr, fitsection = canfit
133 canrelocate.remove(fitsection)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400134 fitsection.finalloc = addpos + BUILD_BIOS_ADDR
135 fitsection.finalsegloc = addpos
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400136 addpos = fitnextaddr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400137 totalused += fitsection.size
Johannes Krampf064fd062014-01-12 11:14:54 -0500138# print(" Adding %s (size %d align %d) pos=%x avail=%d" % (
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400139# fitsection[2], fitsection[0], fitsection[1]
Johannes Krampf064fd062014-01-12 11:14:54 -0500140# , fitnextaddr, nextfixedaddr - fitnextaddr))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400141
142 # Report stats
143 total = BUILD_BIOS_SIZE-firstfixed
144 slack = total - totalused
145 print ("Fixed space: 0x%x-0x%x total: %d slack: %d"
146 " Percent slack: %.1f%%" % (
147 firstfixed, BUILD_BIOS_SIZE, total, slack,
148 (float(slack) / total) * 100.0))
149
Kevin O'Connor46b82622012-05-13 12:10:30 -0400150 return firstfixed + BUILD_BIOS_ADDR
151
152# Return the subset of sections with a given category
153def getSectionsCategory(sections, category):
154 return [section for section in sections if section.category == category]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400155
Kevin O'Connor8216a472014-06-10 17:59:53 -0400156# Return the subset of sections with a given fileid
157def getSectionsFileid(sections, fileid):
158 return [section for section in sections if section.fileid == fileid]
159
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400160# Return the subset of sections with a given name prefix
Kevin O'Connor46b82622012-05-13 12:10:30 -0400161def getSectionsPrefix(sections, prefix):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400162 return [section for section in sections
Kevin O'Connor46b82622012-05-13 12:10:30 -0400163 if section.name.startswith(prefix)]
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400164
Kevin O'Connor46b82622012-05-13 12:10:30 -0400165# The sections (and associated information) to be placed in output rom
166class LayoutInfo:
Kevin O'Connor8216a472014-06-10 17:59:53 -0400167 sections = None
Vladimir Serbinenko1b911d72015-05-18 19:07:16 +0200168 config = None
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500169 genreloc = None
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400170 sec32init_start = sec32init_end = sec32init_align = None
171 sec32low_start = sec32low_end = None
172 zonelow_base = final_sec32low_start = None
Kevin O'Connor6d152642013-02-19 21:35:20 -0500173 zonefseg_start = zonefseg_end = None
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500174 final_readonly_start = None
Kevin O'Connoree952532014-06-09 14:37:23 -0400175 varlowsyms = entrysym = None
Kevin O'Connor46b82622012-05-13 12:10:30 -0400176
177# Determine final memory addresses for sections
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500178def doLayout(sections, config, genreloc):
Kevin O'Connor46b82622012-05-13 12:10:30 -0400179 li = LayoutInfo()
Vladimir Serbinenko1b911d72015-05-18 19:07:16 +0200180 li.config = config
Kevin O'Connor8216a472014-06-10 17:59:53 -0400181 li.sections = sections
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500182 li.genreloc = genreloc
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400183 # Determine 16bit positions
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400184 sections16 = getSectionsCategory(sections, '16')
185 textsections = getSectionsPrefix(sections16, '.text.')
186 rodatasections = getSectionsPrefix(sections16, '.rodata')
187 datasections = getSectionsPrefix(sections16, '.data16.')
Kevin O'Connorab482e02014-06-11 14:00:21 -0400188 fixedsections = getSectionsCategory(sections, 'fixed')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400189
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400190 firstfixed = fitSections(fixedsections, textsections)
191 remsections = [s for s in textsections+rodatasections+datasections
192 if s.finalloc is None]
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400193 sec16_start, sec16_align = setSectionsStart(
Kevin O'Connor46b82622012-05-13 12:10:30 -0400194 remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400195
196 # Determine 32seg positions
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400197 sections32seg = getSectionsCategory(sections, '32seg')
198 textsections = getSectionsPrefix(sections32seg, '.text.')
199 rodatasections = getSectionsPrefix(sections32seg, '.rodata')
200 datasections = getSectionsPrefix(sections32seg, '.data32seg.')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400201
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400202 sec32seg_start, sec32seg_align = setSectionsStart(
203 textsections + rodatasections + datasections, sec16_start
Kevin O'Connor46b82622012-05-13 12:10:30 -0400204 , segoffset=BUILD_BIOS_ADDR)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400205
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400206 # Determine 32bit "fseg memory" data positions
207 sections32textfseg = getSectionsCategory(sections, '32textfseg')
208 sec32textfseg_start, sec32textfseg_align = setSectionsStart(
209 sections32textfseg, sec32seg_start, 16)
Kevin O'Connor41953492013-02-18 23:09:01 -0500210
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400211 sections32fseg = getSectionsCategory(sections, '32fseg')
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400212 sec32fseg_start, sec32fseg_align = setSectionsStart(
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400213 sections32fseg, sec32textfseg_start, 16
Kevin O'Connor41953492013-02-18 23:09:01 -0500214 , segoffset=BUILD_BIOS_ADDR)
215
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400216 # Determine 32flat runtime positions
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400217 sections32flat = getSectionsCategory(sections, '32flat')
218 textsections = getSectionsPrefix(sections32flat, '.text.')
219 rodatasections = getSectionsPrefix(sections32flat, '.rodata')
220 datasections = getSectionsPrefix(sections32flat, '.data.')
221 bsssections = getSectionsPrefix(sections32flat, '.bss.')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400222
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400223 sec32flat_start, sec32flat_align = setSectionsStart(
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400224 textsections + rodatasections + datasections + bsssections
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400225 , sec32fseg_start, 16)
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500226
227 # Determine 32flat init positions
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400228 sections32init = getSectionsCategory(sections, '32init')
229 init32_textsections = getSectionsPrefix(sections32init, '.text.')
230 init32_rodatasections = getSectionsPrefix(sections32init, '.rodata')
231 init32_datasections = getSectionsPrefix(sections32init, '.data.')
232 init32_bsssections = getSectionsPrefix(sections32init, '.bss.')
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500233
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400234 sec32init_start, sec32init_align = setSectionsStart(
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500235 init32_textsections + init32_rodatasections
236 + init32_datasections + init32_bsssections
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400237 , sec32flat_start, 16)
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500238
239 # Determine location of ZoneFSeg memory.
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400240 zonefseg_end = sec32flat_start
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500241 if not genreloc:
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400242 zonefseg_end = sec32init_start
243 zonefseg_start = BUILD_BIOS_ADDR
244 if zonefseg_start + BUILD_MIN_BIOSTABLE > zonefseg_end:
Kevin O'Connor6d152642013-02-19 21:35:20 -0500245 # Not enough ZoneFSeg space - force a minimum space.
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400246 zonefseg_end = sec32fseg_start
247 zonefseg_start = zonefseg_end - BUILD_MIN_BIOSTABLE
248 sec32flat_start, sec32flat_align = setSectionsStart(
Kevin O'Connor6d152642013-02-19 21:35:20 -0500249 textsections + rodatasections + datasections + bsssections
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400250 , zonefseg_start, 16)
251 sec32init_start, sec32init_align = setSectionsStart(
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500252 init32_textsections + init32_rodatasections
253 + init32_datasections + init32_bsssections
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400254 , sec32flat_start, 16)
255 li.sec32init_start = sec32init_start
256 li.sec32init_end = sec32flat_start
257 li.sec32init_align = sec32init_align
258 final_readonly_start = min(BUILD_BIOS_ADDR, sec32flat_start)
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500259 if not genreloc:
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400260 final_readonly_start = min(BUILD_BIOS_ADDR, sec32init_start)
261 li.zonefseg_start = zonefseg_start
262 li.zonefseg_end = zonefseg_end
263 li.final_readonly_start = final_readonly_start
Kevin O'Connor46b82622012-05-13 12:10:30 -0400264
265 # Determine "low memory" data positions
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400266 sections32low = getSectionsCategory(sections, '32low')
267 sec32low_end = sec32init_start
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400268 if config.get('CONFIG_MALLOC_UPPERMEMORY'):
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400269 final_sec32low_end = final_readonly_start
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400270 zonelow_base = final_sec32low_end - 64*1024
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400271 zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024))
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400272 else:
273 final_sec32low_end = BUILD_LOWRAM_END
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400274 zonelow_base = final_sec32low_end - 64*1024
Kevin O'Connor3be89a12013-02-23 16:07:00 -0500275 relocdelta = final_sec32low_end - sec32low_end
Kevin O'Connor3910de02016-02-19 21:34:16 -0500276 li.sec32low_start, sec32low_align = setSectionsStart(
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400277 sections32low, sec32low_end, 16
278 , segoffset=zonelow_base - relocdelta)
279 li.sec32low_end = sec32low_end
280 li.zonelow_base = zonelow_base
Kevin O'Connorc91da7a2012-06-08 21:14:19 -0400281 li.final_sec32low_start = li.sec32low_start + relocdelta
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400282
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400283 # Print statistics
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400284 size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - sec16_start
285 size32seg = sec16_start - sec32seg_start
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400286 size32textfseg = sec32seg_start - sec32textfseg_start
287 size32fseg = sec32textfseg_start - sec32fseg_start
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400288 size32flat = sec32fseg_start - sec32flat_start
289 size32init = sec32flat_start - sec32init_start
290 sizelow = li.sec32low_end - li.sec32low_start
Johannes Krampf064fd062014-01-12 11:14:54 -0500291 print("16bit size: %d" % size16)
292 print("32bit segmented size: %d" % size32seg)
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400293 print("32bit flat size: %d" % (size32flat + size32textfseg))
Johannes Krampf064fd062014-01-12 11:14:54 -0500294 print("32bit flat init size: %d" % size32init)
295 print("Lowmem size: %d" % sizelow)
296 print("f-segment var size: %d" % size32fseg)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400297 return li
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400298
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400299
300######################################################################
301# Linker script output
302######################################################################
303
304# Write LD script includes for the given cross references
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500305def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500306 xrefs = dict([(symbol.name, symbol) for symbol in exportsyms])
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400307 out = ""
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400308 for section in sections:
309 for reloc in section.relocs:
310 symbol = reloc.symbol
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500311 if (symbol.section is not None
312 and (symbol.section.fileid != section.fileid
313 or symbol.name != reloc.symbolname)):
314 xrefs[reloc.symbolname] = symbol
315 for symbolname, symbol in xrefs.items():
316 loc = symbol.section.finalloc
317 if useseg:
318 loc = symbol.section.finalsegloc
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500319 out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400320 return out
321
Kevin O'Connore5749972014-06-07 15:55:00 -0400322# Write LD script includes for the given sections
323def outSections(sections, useseg=0):
324 out = ""
325 for section in sections:
326 loc = section.finalloc
327 if useseg:
328 loc = section.finalsegloc
329 out += "%s 0x%x : { *(%s) }\n" % (section.name, loc, section.name)
330 return out
331
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400332# Write LD script includes for the given sections using relative offsets
Kevin O'Connor46b82622012-05-13 12:10:30 -0400333def outRelSections(sections, startsym, useseg=0):
334 sections = [(section.finalloc, section) for section in sections
335 if section.finalloc is not None]
Johannes Krampf0a82fc72014-01-12 11:39:57 -0500336 sections.sort(key=operator.itemgetter(0))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400337 out = ""
Kevin O'Connor46b82622012-05-13 12:10:30 -0400338 for addr, section in sections:
339 loc = section.finalloc
340 if useseg:
341 loc = section.finalsegloc
342 out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym)
Kevin O'Connore5749972014-06-07 15:55:00 -0400343 if section.name in ('.rodata.str1.1', '.rodata'):
344 out += "_rodata%s = . ;\n" % (section.fileid,)
345 out += "*%s.*(%s)\n" % (section.fileid, section.name)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400346 return out
347
Kevin O'Connor46b82622012-05-13 12:10:30 -0400348# Build linker script output for a list of relocations.
349def strRelocs(outname, outrel, relocs):
350 relocs.sort()
351 return (" %s_start = ABSOLUTE(.) ;\n" % (outname,)
352 + "".join(["LONG(0x%x - %s)\n" % (pos, outrel)
353 for pos in relocs])
354 + " %s_end = ABSOLUTE(.) ;\n" % (outname,))
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500355
Kevin O'Connorb40016f2014-06-11 14:40:45 -0400356# Find relocations to the given sections
357def getRelocs(sections, tosection, type=None):
358 return [section.finalloc + reloc.offset
359 for section in sections
360 for reloc in section.relocs
361 if (reloc.symbol.section in tosection
362 and (type is None or reloc.type == type))]
Kevin O'Connor46b82622012-05-13 12:10:30 -0400363
Kevin O'Connor46b82622012-05-13 12:10:30 -0400364# Output the linker scripts for all required sections.
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500365def writeLinkerScripts(li, out16, out32seg, out32flat):
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400366 # Write 16bit linker script
Kevin O'Connor8216a472014-06-10 17:59:53 -0400367 filesections16 = getSectionsFileid(li.sections, '16')
368 out = outXRefs(filesections16, useseg=1) + """
Kevin O'Connorc9243442013-02-17 13:58:28 -0500369 zonelow_base = 0x%x ;
370 _zonelow_seg = 0x%x ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400371
Kevin O'Connor46b82622012-05-13 12:10:30 -0400372%s
Kevin O'Connorc9243442013-02-17 13:58:28 -0500373""" % (li.zonelow_base,
Johannes Krampf9d7d0442014-01-12 11:19:22 -0500374 int(li.zonelow_base / 16),
Kevin O'Connor8216a472014-06-10 17:59:53 -0400375 outSections(filesections16, useseg=1))
Johannes Krampf19f789b2014-01-19 16:03:49 +0100376 outfile = open(out16, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400377 outfile.write(COMMONHEADER + out + COMMONTRAILER)
378 outfile.close()
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500379
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400380 # Write 32seg linker script
Kevin O'Connor8216a472014-06-10 17:59:53 -0400381 filesections32seg = getSectionsFileid(li.sections, '32seg')
382 out = (outXRefs(filesections32seg, useseg=1)
383 + outSections(filesections32seg, useseg=1))
Johannes Krampf19f789b2014-01-19 16:03:49 +0100384 outfile = open(out32seg, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400385 outfile.write(COMMONHEADER + out + COMMONTRAILER)
386 outfile.close()
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500387
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400388 # Write 32flat linker script
Kevin O'Connor46b82622012-05-13 12:10:30 -0400389 sec32all_start = li.sec32low_start
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400390 relocstr = ""
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500391 if li.genreloc:
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400392 # Generate relocations
Kevin O'Connor8216a472014-06-10 17:59:53 -0400393 initsections = dict([
394 (s, 1) for s in getSectionsCategory(li.sections, '32init')])
395 noninitsections = dict([(s, 1) for s in li.sections
396 if s not in initsections])
Kevin O'Connorb40016f2014-06-11 14:40:45 -0400397 absrelocs = getRelocs(initsections, initsections, type='R_386_32')
398 relrelocs = getRelocs(initsections, noninitsections, type='R_386_PC32')
399 initrelocs = getRelocs(noninitsections, initsections)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400400 relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
401 + strRelocs("_reloc_rel", "code32init_start", relrelocs)
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500402 + strRelocs("_reloc_init", "code32flat_start", initrelocs))
403 numrelocs = len(absrelocs + relrelocs + initrelocs)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400404 sec32all_start -= numrelocs * 4
Kevin O'Connor8216a472014-06-10 17:59:53 -0400405 filesections32flat = getSectionsFileid(li.sections, '32flat')
406 out = outXRefs([], exportsyms=li.varlowsyms
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500407 , forcedelta=li.final_sec32low_start-li.sec32low_start)
Vladimir Serbinenko1b911d72015-05-18 19:07:16 +0200408 multiboot_header = ""
409 if li.config.get('CONFIG_MULTIBOOT'):
410 multiboot_header = "LONG(0x1BADB002) LONG(0) LONG(-0x1BADB002)"
411 sec32all_start -= 3 * 4
Kevin O'Connor3910de02016-02-19 21:34:16 -0500412 sec32all_align = max([section.align for section in li.sections])
413 sec32all_start = aligndown(sec32all_start, sec32all_align)
Kevin O'Connor8216a472014-06-10 17:59:53 -0400414 out += outXRefs(filesections32flat, exportsyms=[li.entrysym]) + """
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400415 _reloc_min_align = 0x%x ;
Kevin O'Connor6d152642013-02-19 21:35:20 -0500416 zonefseg_start = 0x%x ;
417 zonefseg_end = 0x%x ;
Kevin O'Connorc9243442013-02-17 13:58:28 -0500418 zonelow_base = 0x%x ;
419 final_varlow_start = 0x%x ;
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500420 final_readonly_start = 0x%x ;
Kevin O'Connor8216a472014-06-10 17:59:53 -0400421 varlow_start = 0x%x ;
422 varlow_end = 0x%x ;
423 code32init_start = 0x%x ;
424 code32init_end = 0x%x ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400425
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400426 code32flat_start = 0x%x ;
427 .text code32flat_start : {
Kevin O'Connor46b82622012-05-13 12:10:30 -0400428%s
Kevin O'Connor46b82622012-05-13 12:10:30 -0400429%s
Vladimir Serbinenko1b911d72015-05-18 19:07:16 +0200430%s
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400431 code32flat_end = ABSOLUTE(.) ;
432 } :text
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500433""" % (li.sec32init_align,
Kevin O'Connor6d152642013-02-19 21:35:20 -0500434 li.zonefseg_start,
435 li.zonefseg_end,
Kevin O'Connorc9243442013-02-17 13:58:28 -0500436 li.zonelow_base,
Kevin O'Connorc91da7a2012-06-08 21:14:19 -0400437 li.final_sec32low_start,
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500438 li.final_readonly_start,
Kevin O'Connor8216a472014-06-10 17:59:53 -0400439 li.sec32low_start,
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400440 li.sec32low_end,
Kevin O'Connor8216a472014-06-10 17:59:53 -0400441 li.sec32init_start,
Kevin O'Connor38729bc2014-06-11 13:39:02 -0400442 li.sec32init_end,
Kevin O'Connor46b82622012-05-13 12:10:30 -0400443 sec32all_start,
Vladimir Serbinenko1b911d72015-05-18 19:07:16 +0200444 multiboot_header,
Kevin O'Connor46b82622012-05-13 12:10:30 -0400445 relocstr,
Kevin O'Connor8216a472014-06-10 17:59:53 -0400446 outRelSections(li.sections, 'code32flat_start'))
Kevin O'Connor46b82622012-05-13 12:10:30 -0400447 out = COMMONHEADER + out + COMMONTRAILER + """
Kevin O'Connoree952532014-06-09 14:37:23 -0400448ENTRY(%s)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400449PHDRS
450{
451 text PT_LOAD AT ( code32flat_start ) ;
452}
Kevin O'Connoree952532014-06-09 14:37:23 -0400453""" % (li.entrysym.name,)
Johannes Krampf19f789b2014-01-19 16:03:49 +0100454 outfile = open(out32flat, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400455 outfile.write(out)
456 outfile.close()
Kevin O'Connorc0693942009-06-10 21:56:01 -0400457
458
459######################################################################
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400460# Detection of unused sections and init sections
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400461######################################################################
462
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400463# Visit all sections reachable from a given set of start sections
464def findReachable(anchorsections, checkreloc, data):
465 anchorsections = dict([(section, []) for section in anchorsections])
466 pending = list(anchorsections)
467 while pending:
468 section = pending.pop()
469 for reloc in section.relocs:
470 chain = anchorsections[section] + [section.name]
471 if not checkreloc(reloc, section, data, chain):
472 continue
473 nextsection = reloc.symbol.section
474 if nextsection not in anchorsections:
475 anchorsections[nextsection] = chain
476 pending.append(nextsection)
477 return anchorsections
478
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400479# Find "runtime" sections (ie, not init only sections).
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400480def checkRuntime(reloc, rsection, data, chain):
481 section = reloc.symbol.section
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400482 if section is None or '.init.' in section.name:
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400483 return 0
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500484 if '.data.varinit.' in section.name:
Johannes Krampf064fd062014-01-12 11:14:54 -0500485 print("ERROR: %s is VARVERIFY32INIT but used from %s" % (
486 section.name, chain))
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500487 sys.exit(1)
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400488 return 1
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400489
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500490# Find and keep the section associated with a symbol (if available).
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400491def checkKeepSym(reloc, syms, fileid, isxref):
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500492 symbolname = reloc.symbolname
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400493 mustbecfunc = symbolname.startswith('_cfunc')
494 if mustbecfunc:
495 symprefix = '_cfunc' + fileid + '_'
496 if not symbolname.startswith(symprefix):
497 return 0
498 symbolname = symbolname[len(symprefix):]
499 symbol = syms.get(symbolname)
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400500 if (symbol is None or symbol.section is None
501 or symbol.section.name.startswith('.discard.')):
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400502 return 0
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500503 isdestcfunc = (symbol.section.name.startswith('.text.')
504 and not symbol.section.name.startswith('.text.asm.'))
505 if ((mustbecfunc and not isdestcfunc)
506 or (not mustbecfunc and isdestcfunc and isxref)):
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400507 return 0
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500508
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400509 reloc.symbol = symbol
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400510 return 1
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500511
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400512# Resolve a relocation and check if it should be kept in the final binary.
Kevin O'Connorc228d702014-06-09 14:59:25 -0400513def checkKeep(reloc, section, symbols, chain):
514 ret = checkKeepSym(reloc, symbols[section.fileid], section.fileid, 0)
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400515 if ret:
516 return ret
517 # Not in primary sections - it may be a cross 16/32 reference
518 for fileid in ('16', '32seg', '32flat'):
519 if fileid != section.fileid:
Kevin O'Connorc228d702014-06-09 14:59:25 -0400520 ret = checkKeepSym(reloc, symbols[fileid], fileid, 1)
Kevin O'Connorcc132ab2014-06-09 12:48:13 -0400521 if ret:
522 return ret
523 return 0
Kevin O'Connorc0693942009-06-10 21:56:01 -0400524
Kevin O'Connorc0693942009-06-10 21:56:01 -0400525
526######################################################################
527# Startup and input parsing
528######################################################################
529
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400530class Section:
531 name = size = alignment = fileid = relocs = None
Kevin O'Connorc228d702014-06-09 14:59:25 -0400532 finalloc = finalsegloc = category = None
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400533class Reloc:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500534 offset = type = symbolname = symbol = None
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400535class Symbol:
536 name = offset = section = None
537
Kevin O'Connorc0693942009-06-10 21:56:01 -0400538# Read in output from objdump
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400539def parseObjDump(file, fileid):
540 # sections = [section, ...]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400541 sections = []
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400542 sectionmap = {}
543 # symbols[symbolname] = symbol
Kevin O'Connorc0693942009-06-10 21:56:01 -0400544 symbols = {}
Kevin O'Connorc0693942009-06-10 21:56:01 -0400545
546 state = None
547 for line in file.readlines():
548 line = line.rstrip()
549 if line == 'Sections:':
550 state = 'section'
551 continue
552 if line == 'SYMBOL TABLE:':
553 state = 'symbol'
554 continue
Kevin O'Connor6c2e7812010-09-13 18:04:02 -0400555 if line.startswith('RELOCATION RECORDS FOR ['):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400556 sectionname = line[24:-2]
557 if sectionname.startswith('.debug_'):
558 # Skip debugging sections (to reduce parsing time)
559 state = None
560 continue
Kevin O'Connorc0693942009-06-10 21:56:01 -0400561 state = 'reloc'
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400562 relocsection = sectionmap[sectionname]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400563 continue
564
565 if state == 'section':
566 try:
567 idx, name, size, vma, lma, fileoff, align = line.split()
568 if align[:3] != '2**':
569 continue
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400570 section = Section()
571 section.name = name
572 section.size = int(size, 16)
573 section.align = 2**int(align[3:])
574 section.fileid = fileid
575 section.relocs = []
576 sections.append(section)
577 sectionmap[name] = section
578 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400579 pass
580 continue
581 if state == 'symbol':
582 try:
Kevin O'Connor90ebed42012-06-21 20:54:53 -0400583 parts = line[17:].split()
584 if len(parts) == 3:
585 sectionname, size, name = parts
586 elif len(parts) == 4 and parts[2] == '.hidden':
587 sectionname, size, hidden, name = parts
588 else:
589 continue
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400590 symbol = Symbol()
591 symbol.size = int(size, 16)
592 symbol.offset = int(line[:8], 16)
593 symbol.name = name
594 symbol.section = sectionmap.get(sectionname)
595 symbols[name] = symbol
596 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400597 pass
598 continue
599 if state == 'reloc':
600 try:
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400601 off, type, symbolname = line.split()
602 reloc = Reloc()
603 reloc.offset = int(off, 16)
604 reloc.type = type
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500605 reloc.symbolname = symbolname
Kevin O'Connor67863be2010-12-24 10:23:10 -0500606 reloc.symbol = symbols.get(symbolname)
607 if reloc.symbol is None:
608 # Some binutils (2.20.1) give section name instead
609 # of a symbol - create a dummy symbol.
610 reloc.symbol = symbol = Symbol()
611 symbol.size = 0
612 symbol.offset = 0
613 symbol.name = symbolname
614 symbol.section = sectionmap.get(symbolname)
615 symbols[symbolname] = symbol
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400616 relocsection.relocs.append(reloc)
617 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400618 pass
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400619 return sections, symbols
Kevin O'Connorc0693942009-06-10 21:56:01 -0400620
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400621# Parser for constants in simple C header files.
622def scanconfig(file):
Johannes Krampf19f789b2014-01-19 16:03:49 +0100623 f = open(file, 'r')
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400624 opts = {}
625 for l in f.readlines():
626 parts = l.split()
627 if len(parts) != 3:
628 continue
629 if parts[0] != '#define':
630 continue
631 value = parts[2]
632 if value.isdigit() or (value.startswith('0x') and value[2:].isdigit()):
633 value = int(value, 0)
634 opts[parts[1]] = value
635 return opts
636
Kevin O'Connorc0693942009-06-10 21:56:01 -0400637def main():
638 # Get output name
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400639 in16, in32seg, in32flat, cfgfile, out16, out32seg, out32flat = sys.argv[1:]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400640
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400641 # Read in the objdump information
Johannes Krampf19f789b2014-01-19 16:03:49 +0100642 infile16 = open(in16, 'r')
643 infile32seg = open(in32seg, 'r')
644 infile32flat = open(in32flat, 'r')
Kevin O'Connorc0693942009-06-10 21:56:01 -0400645
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400646 # infoX = (sections, symbols)
647 info16 = parseObjDump(infile16, '16')
648 info32seg = parseObjDump(infile32seg, '32seg')
649 info32flat = parseObjDump(infile32flat, '32flat')
Kevin O'Connorc0693942009-06-10 21:56:01 -0400650
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400651 # Read kconfig config file
652 config = scanconfig(cfgfile)
653
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400654 # Figure out which sections to keep.
Kevin O'Connorc228d702014-06-09 14:59:25 -0400655 allsections = info16[0] + info32seg[0] + info32flat[0]
656 symbols = {'16': info16[1], '32seg': info32seg[1], '32flat': info32flat[1]}
Kevin O'Connoree952532014-06-09 14:37:23 -0400657 if config.get('CONFIG_COREBOOT'):
658 entrysym = symbols['16'].get('entry_elf')
659 elif config.get('CONFIG_CSM'):
660 entrysym = symbols['16'].get('entry_csm')
661 else:
662 entrysym = symbols['16'].get('reset_vector')
663 anchorsections = [entrysym.section] + [
Kevin O'Connorab482e02014-06-11 14:00:21 -0400664 section for section in allsections
Kevin O'Connoree952532014-06-09 14:37:23 -0400665 if section.name.startswith('.fixedaddr.')]
Kevin O'Connorc228d702014-06-09 14:59:25 -0400666 keepsections = findReachable(anchorsections, checkKeep, symbols)
667 sections = [section for section in allsections if section in keepsections]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400668
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400669 # Separate 32bit flat into runtime, init, and special variable parts
670 anchorsections = [
671 section for section in sections
672 if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name
Kevin O'Connorab482e02014-06-11 14:00:21 -0400673 or '.fixedaddr.' in section.name or '.runtime.' in section.name)]
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400674 runtimesections = findReachable(anchorsections, checkRuntime, None)
675 for section in sections:
676 if section.name.startswith('.data.varlow.'):
677 section.category = '32low'
678 elif section.name.startswith('.data.varfseg.'):
679 section.category = '32fseg'
Kevin O'Connoreb88bf72014-09-24 15:58:12 -0400680 elif section.name.startswith('.text.32fseg.'):
681 section.category = '32textfseg'
Kevin O'Connorab482e02014-06-11 14:00:21 -0400682 elif section.name.startswith('.fixedaddr.'):
683 section.category = 'fixed'
Kevin O'Connorbf70fbf2014-06-10 00:00:20 -0400684 elif section.fileid == '32flat' and section not in runtimesections:
685 section.category = '32init'
686 else:
687 section.category = section.fileid
Kevin O'Connor46b82622012-05-13 12:10:30 -0400688
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400689 # Determine the final memory locations of each kept section.
Kevin O'Connorc228d702014-06-09 14:59:25 -0400690 genreloc = '_reloc_abs_start' in symbols['32flat']
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500691 li = doLayout(sections, config, genreloc)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400692
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500693 # Exported symbols
Kevin O'Connorc228d702014-06-09 14:59:25 -0400694 li.varlowsyms = [symbol for symbol in symbols['32flat'].values()
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500695 if (symbol.section is not None
696 and symbol.section.finalloc is not None
697 and '.data.varlow.' in symbol.section.name
698 and symbol.name != symbol.section.name)]
Kevin O'Connoree952532014-06-09 14:37:23 -0400699 li.entrysym = entrysym
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500700
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400701 # Write out linker script files.
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500702 writeLinkerScripts(li, out16, out32seg, out32flat)
Kevin O'Connorc0693942009-06-10 21:56:01 -0400703
Kevin O'Connor202024a2009-01-17 10:41:28 -0500704if __name__ == '__main__':
705 main()