blob: b3254061ab2276160bc42613318d259330949035 [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'Connor1a4885e2010-09-15 21:28:31 -04004# Copyright (C) 2008-2010 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 = """
13/* DO NOT EDIT! This is an autogenerated file. See tools/layoutrom.py. */
14OUTPUT_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'Connor9ba1dea2010-05-01 09:50:13 -040037# Align 'pos' to 'alignbytes' offset
38def alignpos(pos, alignbytes):
39 mask = alignbytes - 1
40 return (pos + mask) & ~mask
41
42# Determine the final addresses for a list of sections that end at an
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040043# address.
Kevin O'Connor46b82622012-05-13 12:10:30 -040044def setSectionsStart(sections, endaddr, minalign=1, segoffset=0):
Kevin O'Connor5b8f8092009-09-20 19:47:45 -040045 totspace = 0
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040046 for section in sections:
47 if section.align > minalign:
48 minalign = section.align
49 totspace = alignpos(totspace, section.align) + section.size
Johannes Krampf9d7d0442014-01-12 11:19:22 -050050 startaddr = int((endaddr - totspace) / minalign) * minalign
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040051 curaddr = startaddr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040052 for section in sections:
53 curaddr = alignpos(curaddr, section.align)
54 section.finalloc = curaddr
Kevin O'Connor46b82622012-05-13 12:10:30 -040055 section.finalsegloc = curaddr - segoffset
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040056 curaddr += section.size
Kevin O'Connor46b82622012-05-13 12:10:30 -040057 return startaddr, minalign
Kevin O'Connorc0693942009-06-10 21:56:01 -040058
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040059# The 16bit code can't exceed 64K of space.
60BUILD_BIOS_ADDR = 0xf0000
61BUILD_BIOS_SIZE = 0x10000
Kevin O'Connor46b82622012-05-13 12:10:30 -040062BUILD_ROM_START = 0xc0000
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -040063BUILD_LOWRAM_END = 0xa0000
Kevin O'Connor6d152642013-02-19 21:35:20 -050064# Space to reserve in f-segment for dynamic allocations
65BUILD_MIN_BIOSTABLE = 2048
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040066
67# Layout the 16bit code. This ensures sections with fixed offset
68# requirements are placed in the correct location. It also places the
69# 16bit code as high as possible in the f-segment.
70def fitSections(sections, fillsections):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040071 # fixedsections = [(addr, section), ...]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040072 fixedsections = []
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040073 for section in sections:
74 if section.name.startswith('.fixedaddr.'):
75 addr = int(section.name[11:], 16)
Kevin O'Connor46b82622012-05-13 12:10:30 -040076 section.finalloc = addr + BUILD_BIOS_ADDR
77 section.finalsegloc = addr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040078 fixedsections.append((addr, section))
79 if section.align != 1:
Johannes Krampf064fd062014-01-12 11:14:54 -050080 print("Error: Fixed section %s has non-zero alignment (%d)" % (
81 section.name, section.align))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040082 sys.exit(1)
Johannes Krampf0a82fc72014-01-12 11:39:57 -050083 fixedsections.sort(key=operator.itemgetter(0))
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040084 firstfixed = fixedsections[0][0]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040085
86 # Find freespace in fixed address area
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040087 # fixedAddr = [(freespace, section), ...]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040088 fixedAddr = []
89 for i in range(len(fixedsections)):
90 fixedsectioninfo = fixedsections[i]
91 addr, section = fixedsectioninfo
92 if i == len(fixedsections) - 1:
93 nextaddr = BUILD_BIOS_SIZE
94 else:
95 nextaddr = fixedsections[i+1][0]
Kevin O'Connor1a4885e2010-09-15 21:28:31 -040096 avail = nextaddr - addr - section.size
97 fixedAddr.append((avail, section))
Johannes Krampf0a82fc72014-01-12 11:39:57 -050098 fixedAddr.sort(key=operator.itemgetter(0))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -040099
100 # Attempt to fit other sections into fixed area
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400101 canrelocate = [(section.size, section.align, section.name, section)
102 for section in fillsections]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400103 canrelocate.sort()
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400104 canrelocate = [section for size, align, name, section in canrelocate]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400105 totalused = 0
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400106 for freespace, fixedsection in fixedAddr:
Kevin O'Connor46b82622012-05-13 12:10:30 -0400107 addpos = fixedsection.finalsegloc + fixedsection.size
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400108 totalused += fixedsection.size
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400109 nextfixedaddr = addpos + freespace
Johannes Krampf064fd062014-01-12 11:14:54 -0500110# print("Filling section %x uses %d, next=%x, available=%d" % (
111# fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400112 while 1:
113 canfit = None
114 for fitsection in canrelocate:
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400115 if addpos + fitsection.size > nextfixedaddr:
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400116 # Can't fit and nothing else will fit.
117 break
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400118 fitnextaddr = alignpos(addpos, fitsection.align) + fitsection.size
Johannes Krampf064fd062014-01-12 11:14:54 -0500119# print("Test %s - %x vs %x" % (
120# fitsection.name, fitnextaddr, nextfixedaddr))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400121 if fitnextaddr > nextfixedaddr:
122 # This item can't fit.
123 continue
124 canfit = (fitnextaddr, fitsection)
125 if canfit is None:
126 break
127 # Found a section that can fit.
128 fitnextaddr, fitsection = canfit
129 canrelocate.remove(fitsection)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400130 fitsection.finalloc = addpos + BUILD_BIOS_ADDR
131 fitsection.finalsegloc = addpos
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400132 addpos = fitnextaddr
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400133 totalused += fitsection.size
Johannes Krampf064fd062014-01-12 11:14:54 -0500134# print(" Adding %s (size %d align %d) pos=%x avail=%d" % (
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400135# fitsection[2], fitsection[0], fitsection[1]
Johannes Krampf064fd062014-01-12 11:14:54 -0500136# , fitnextaddr, nextfixedaddr - fitnextaddr))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400137
138 # Report stats
139 total = BUILD_BIOS_SIZE-firstfixed
140 slack = total - totalused
141 print ("Fixed space: 0x%x-0x%x total: %d slack: %d"
142 " Percent slack: %.1f%%" % (
143 firstfixed, BUILD_BIOS_SIZE, total, slack,
144 (float(slack) / total) * 100.0))
145
Kevin O'Connor46b82622012-05-13 12:10:30 -0400146 return firstfixed + BUILD_BIOS_ADDR
147
148# Return the subset of sections with a given category
149def getSectionsCategory(sections, category):
150 return [section for section in sections if section.category == category]
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400151
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400152# Return the subset of sections with a given name prefix
Kevin O'Connor46b82622012-05-13 12:10:30 -0400153def getSectionsPrefix(sections, prefix):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400154 return [section for section in sections
Kevin O'Connor46b82622012-05-13 12:10:30 -0400155 if section.name.startswith(prefix)]
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400156
Kevin O'Connor46b82622012-05-13 12:10:30 -0400157# The sections (and associated information) to be placed in output rom
158class LayoutInfo:
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500159 genreloc = None
Kevin O'Connor46b82622012-05-13 12:10:30 -0400160 sections16 = sec16_start = sec16_align = None
161 sections32seg = sec32seg_start = sec32seg_align = None
162 sections32flat = sec32flat_start = sec32flat_align = None
163 sections32init = sec32init_start = sec32init_align = None
164 sections32low = sec32low_start = sec32low_align = None
Kevin O'Connor41953492013-02-18 23:09:01 -0500165 sections32fseg = sec32fseg_start = sec32fseg_align = None
Kevin O'Connor6d152642013-02-19 21:35:20 -0500166 zonefseg_start = zonefseg_end = None
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500167 final_readonly_start = None
Kevin O'Connorc9243442013-02-17 13:58:28 -0500168 zonelow_base = final_sec32low_start = None
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500169 exportsyms = varlowsyms = None
Kevin O'Connor46b82622012-05-13 12:10:30 -0400170
171# Determine final memory addresses for sections
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500172def doLayout(sections, config, genreloc):
Kevin O'Connor46b82622012-05-13 12:10:30 -0400173 li = LayoutInfo()
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500174 li.genreloc = genreloc
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400175 # Determine 16bit positions
Kevin O'Connor46b82622012-05-13 12:10:30 -0400176 li.sections16 = getSectionsCategory(sections, '16')
177 textsections = getSectionsPrefix(li.sections16, '.text.')
Kevin O'Connor805ede22012-02-08 20:23:36 -0500178 rodatasections = (
Kevin O'Connor46b82622012-05-13 12:10:30 -0400179 getSectionsPrefix(li.sections16, '.rodata.str1.1')
180 + getSectionsPrefix(li.sections16, '.rodata.__func__.')
181 + getSectionsPrefix(li.sections16, '.rodata.__PRETTY_FUNCTION__.'))
182 datasections = getSectionsPrefix(li.sections16, '.data16.')
183 fixedsections = getSectionsPrefix(li.sections16, '.fixedaddr.')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400184
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400185 firstfixed = fitSections(fixedsections, textsections)
186 remsections = [s for s in textsections+rodatasections+datasections
187 if s.finalloc is None]
Kevin O'Connor46b82622012-05-13 12:10:30 -0400188 li.sec16_start, li.sec16_align = setSectionsStart(
189 remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400190
191 # Determine 32seg positions
Kevin O'Connor46b82622012-05-13 12:10:30 -0400192 li.sections32seg = getSectionsCategory(sections, '32seg')
193 textsections = getSectionsPrefix(li.sections32seg, '.text.')
Kevin O'Connor805ede22012-02-08 20:23:36 -0500194 rodatasections = (
Kevin O'Connor46b82622012-05-13 12:10:30 -0400195 getSectionsPrefix(li.sections32seg, '.rodata.str1.1')
196 + getSectionsPrefix(li.sections32seg, '.rodata.__func__.')
197 + getSectionsPrefix(li.sections32seg, '.rodata.__PRETTY_FUNCTION__.'))
198 datasections = getSectionsPrefix(li.sections32seg, '.data32seg.')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400199
Kevin O'Connor46b82622012-05-13 12:10:30 -0400200 li.sec32seg_start, li.sec32seg_align = setSectionsStart(
201 textsections + rodatasections + datasections, li.sec16_start
202 , segoffset=BUILD_BIOS_ADDR)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400203
Kevin O'Connor41953492013-02-18 23:09:01 -0500204 # Determine "fseg memory" data positions
205 li.sections32fseg = getSectionsCategory(sections, '32fseg')
206
207 li.sec32fseg_start, li.sec32fseg_align = setSectionsStart(
208 li.sections32fseg, li.sec32seg_start, 16
209 , segoffset=BUILD_BIOS_ADDR)
210
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400211 # Determine 32flat runtime positions
Kevin O'Connor46b82622012-05-13 12:10:30 -0400212 li.sections32flat = getSectionsCategory(sections, '32flat')
213 textsections = getSectionsPrefix(li.sections32flat, '.text.')
214 rodatasections = getSectionsPrefix(li.sections32flat, '.rodata')
215 datasections = getSectionsPrefix(li.sections32flat, '.data.')
216 bsssections = getSectionsPrefix(li.sections32flat, '.bss.')
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400217
Kevin O'Connor46b82622012-05-13 12:10:30 -0400218 li.sec32flat_start, li.sec32flat_align = setSectionsStart(
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400219 textsections + rodatasections + datasections + bsssections
Kevin O'Connor41953492013-02-18 23:09:01 -0500220 , li.sec32fseg_start, 16)
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500221
222 # Determine 32flat init positions
223 li.sections32init = getSectionsCategory(sections, '32init')
224 init32_textsections = getSectionsPrefix(li.sections32init, '.text.')
225 init32_rodatasections = getSectionsPrefix(li.sections32init, '.rodata')
226 init32_datasections = getSectionsPrefix(li.sections32init, '.data.')
227 init32_bsssections = getSectionsPrefix(li.sections32init, '.bss.')
228
229 li.sec32init_start, li.sec32init_align = setSectionsStart(
230 init32_textsections + init32_rodatasections
231 + init32_datasections + init32_bsssections
232 , li.sec32flat_start, 16)
233
234 # Determine location of ZoneFSeg memory.
Kevin O'Connor6d152642013-02-19 21:35:20 -0500235 li.zonefseg_end = li.sec32flat_start
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500236 if not genreloc:
237 li.zonefseg_end = li.sec32init_start
Kevin O'Connor6d152642013-02-19 21:35:20 -0500238 li.zonefseg_start = BUILD_BIOS_ADDR
239 if li.zonefseg_start + BUILD_MIN_BIOSTABLE > li.zonefseg_end:
240 # Not enough ZoneFSeg space - force a minimum space.
241 li.zonefseg_end = li.sec32fseg_start
242 li.zonefseg_start = li.zonefseg_end - BUILD_MIN_BIOSTABLE
243 li.sec32flat_start, li.sec32flat_align = setSectionsStart(
244 textsections + rodatasections + datasections + bsssections
245 , li.zonefseg_start, 16)
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500246 li.sec32init_start, li.sec32init_align = setSectionsStart(
247 init32_textsections + init32_rodatasections
248 + init32_datasections + init32_bsssections
249 , li.sec32flat_start, 16)
250 li.final_readonly_start = min(BUILD_BIOS_ADDR, li.sec32flat_start)
251 if not genreloc:
252 li.final_readonly_start = min(BUILD_BIOS_ADDR, li.sec32init_start)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400253
254 # Determine "low memory" data positions
255 li.sections32low = getSectionsCategory(sections, '32low')
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500256 sec32low_end = li.sec32init_start
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400257 if config.get('CONFIG_MALLOC_UPPERMEMORY'):
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500258 final_sec32low_end = li.final_readonly_start
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400259 zonelow_base = final_sec32low_end - 64*1024
260 li.zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024))
261 else:
262 final_sec32low_end = BUILD_LOWRAM_END
263 li.zonelow_base = final_sec32low_end - 64*1024
Kevin O'Connor3be89a12013-02-23 16:07:00 -0500264 relocdelta = final_sec32low_end - sec32low_end
Kevin O'Connor46b82622012-05-13 12:10:30 -0400265 li.sec32low_start, li.sec32low_align = setSectionsStart(
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500266 li.sections32low, sec32low_end, 16
Kevin O'Connorc9243442013-02-17 13:58:28 -0500267 , segoffset=li.zonelow_base - relocdelta)
Kevin O'Connorc91da7a2012-06-08 21:14:19 -0400268 li.final_sec32low_start = li.sec32low_start + relocdelta
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400269
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400270 # Print statistics
Kevin O'Connor46b82622012-05-13 12:10:30 -0400271 size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - li.sec16_start
272 size32seg = li.sec16_start - li.sec32seg_start
Kevin O'Connor41953492013-02-18 23:09:01 -0500273 size32fseg = li.sec32seg_start - li.sec32fseg_start
274 size32flat = li.sec32fseg_start - li.sec32flat_start
Kevin O'Connor46b82622012-05-13 12:10:30 -0400275 size32init = li.sec32flat_start - li.sec32init_start
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500276 sizelow = sec32low_end - li.sec32low_start
Johannes Krampf064fd062014-01-12 11:14:54 -0500277 print("16bit size: %d" % size16)
278 print("32bit segmented size: %d" % size32seg)
279 print("32bit flat size: %d" % size32flat)
280 print("32bit flat init size: %d" % size32init)
281 print("Lowmem size: %d" % sizelow)
282 print("f-segment var size: %d" % size32fseg)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400283 return li
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400284
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400285
286######################################################################
287# Linker script output
288######################################################################
289
290# Write LD script includes for the given cross references
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500291def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0):
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500292 xrefs = dict([(symbol.name, symbol) for symbol in exportsyms])
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400293 out = ""
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400294 for section in sections:
295 for reloc in section.relocs:
296 symbol = reloc.symbol
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500297 if (symbol.section is not None
298 and (symbol.section.fileid != section.fileid
299 or symbol.name != reloc.symbolname)):
300 xrefs[reloc.symbolname] = symbol
301 for symbolname, symbol in xrefs.items():
302 loc = symbol.section.finalloc
303 if useseg:
304 loc = symbol.section.finalsegloc
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500305 out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400306 return out
307
308# Write LD script includes for the given sections using relative offsets
Kevin O'Connor46b82622012-05-13 12:10:30 -0400309def outRelSections(sections, startsym, useseg=0):
310 sections = [(section.finalloc, section) for section in sections
311 if section.finalloc is not None]
Johannes Krampf0a82fc72014-01-12 11:39:57 -0500312 sections.sort(key=operator.itemgetter(0))
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400313 out = ""
Kevin O'Connor46b82622012-05-13 12:10:30 -0400314 for addr, section in sections:
315 loc = section.finalloc
316 if useseg:
317 loc = section.finalsegloc
318 out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym)
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400319 if section.name == '.rodata.str1.1':
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400320 out += "_rodata = . ;\n"
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400321 out += "*(%s)\n" % (section.name,)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400322 return out
323
Kevin O'Connor46b82622012-05-13 12:10:30 -0400324# Build linker script output for a list of relocations.
325def strRelocs(outname, outrel, relocs):
326 relocs.sort()
327 return (" %s_start = ABSOLUTE(.) ;\n" % (outname,)
328 + "".join(["LONG(0x%x - %s)\n" % (pos, outrel)
329 for pos in relocs])
330 + " %s_end = ABSOLUTE(.) ;\n" % (outname,))
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500331
Kevin O'Connor46b82622012-05-13 12:10:30 -0400332# Find all relocations in the given sections with the given attributes
333def getRelocs(sections, type=None, category=None, notcategory=None):
334 out = []
335 for section in sections:
336 for reloc in section.relocs:
337 if reloc.symbol.section is None:
338 continue
339 destcategory = reloc.symbol.section.category
340 if ((type is None or reloc.type == type)
341 and (category is None or destcategory == category)
342 and (notcategory is None or destcategory != notcategory)):
343 out.append(section.finalloc + reloc.offset)
344 return out
345
346# Return the start address and minimum alignment for a set of sections
347def getSectionsStart(sections, defaddr=0):
348 return min([section.finalloc for section in sections
349 if section.finalloc is not None] or [defaddr])
350
351# Output the linker scripts for all required sections.
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500352def writeLinkerScripts(li, out16, out32seg, out32flat):
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400353 # Write 16bit linker script
Kevin O'Connor46b82622012-05-13 12:10:30 -0400354 out = outXRefs(li.sections16, useseg=1) + """
Kevin O'Connorc9243442013-02-17 13:58:28 -0500355 zonelow_base = 0x%x ;
356 _zonelow_seg = 0x%x ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400357
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400358 code16_start = 0x%x ;
359 .text16 code16_start : {
Kevin O'Connor46b82622012-05-13 12:10:30 -0400360%s
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400361 }
Kevin O'Connorc9243442013-02-17 13:58:28 -0500362""" % (li.zonelow_base,
Johannes Krampf9d7d0442014-01-12 11:19:22 -0500363 int(li.zonelow_base / 16),
Kevin O'Connor46b82622012-05-13 12:10:30 -0400364 li.sec16_start - BUILD_BIOS_ADDR,
365 outRelSections(li.sections16, 'code16_start', useseg=1))
Johannes Krampf19f789b2014-01-19 16:03:49 +0100366 outfile = open(out16, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400367 outfile.write(COMMONHEADER + out + COMMONTRAILER)
368 outfile.close()
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500369
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400370 # Write 32seg linker script
Kevin O'Connor46b82622012-05-13 12:10:30 -0400371 out = outXRefs(li.sections32seg, useseg=1) + """
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400372 code32seg_start = 0x%x ;
373 .text32seg code32seg_start : {
Kevin O'Connor46b82622012-05-13 12:10:30 -0400374%s
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400375 }
Kevin O'Connor46b82622012-05-13 12:10:30 -0400376""" % (li.sec32seg_start - BUILD_BIOS_ADDR,
377 outRelSections(li.sections32seg, 'code32seg_start', useseg=1))
Johannes Krampf19f789b2014-01-19 16:03:49 +0100378 outfile = open(out32seg, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400379 outfile.write(COMMONHEADER + out + COMMONTRAILER)
380 outfile.close()
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500381
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400382 # Write 32flat linker script
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500383 sections32all = (li.sections32flat + li.sections32init + li.sections32fseg)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400384 sec32all_start = li.sec32low_start
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400385 relocstr = ""
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500386 if li.genreloc:
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400387 # Generate relocations
Kevin O'Connor46b82622012-05-13 12:10:30 -0400388 absrelocs = getRelocs(
389 li.sections32init, type='R_386_32', category='32init')
390 relrelocs = getRelocs(
391 li.sections32init, type='R_386_PC32', notcategory='32init')
392 initrelocs = getRelocs(
393 li.sections32flat + li.sections32low + li.sections16
Kevin O'Connor41953492013-02-18 23:09:01 -0500394 + li.sections32seg + li.sections32fseg, category='32init')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400395 relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
396 + strRelocs("_reloc_rel", "code32init_start", relrelocs)
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500397 + strRelocs("_reloc_init", "code32flat_start", initrelocs))
398 numrelocs = len(absrelocs + relrelocs + initrelocs)
Kevin O'Connor46b82622012-05-13 12:10:30 -0400399 sec32all_start -= numrelocs * 4
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500400 out = outXRefs(li.sections32low, exportsyms=li.varlowsyms
401 , forcedelta=li.final_sec32low_start-li.sec32low_start)
402 out += outXRefs(sections32all, exportsyms=li.exportsyms) + """
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400403 _reloc_min_align = 0x%x ;
Kevin O'Connor6d152642013-02-19 21:35:20 -0500404 zonefseg_start = 0x%x ;
405 zonefseg_end = 0x%x ;
Kevin O'Connorc9243442013-02-17 13:58:28 -0500406 zonelow_base = 0x%x ;
407 final_varlow_start = 0x%x ;
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500408 final_readonly_start = 0x%x ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400409
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400410 code32flat_start = 0x%x ;
411 .text code32flat_start : {
Kevin O'Connor46b82622012-05-13 12:10:30 -0400412%s
Kevin O'Connorc9243442013-02-17 13:58:28 -0500413 varlow_start = ABSOLUTE(.) ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400414%s
Kevin O'Connorc9243442013-02-17 13:58:28 -0500415 varlow_end = ABSOLUTE(.) ;
Kevin O'Connor402fd9c2010-09-15 00:26:19 -0400416 code32init_start = ABSOLUTE(.) ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400417%s
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400418 code32init_end = ABSOLUTE(.) ;
Kevin O'Connor46b82622012-05-13 12:10:30 -0400419%s
Kevin O'Connor41953492013-02-18 23:09:01 -0500420%s
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400421 . = ( 0x%x - code32flat_start ) ;
422 *(.text32seg)
423 . = ( 0x%x - code32flat_start ) ;
424 *(.text16)
425 code32flat_end = ABSOLUTE(.) ;
426 } :text
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500427""" % (li.sec32init_align,
Kevin O'Connor6d152642013-02-19 21:35:20 -0500428 li.zonefseg_start,
429 li.zonefseg_end,
Kevin O'Connorc9243442013-02-17 13:58:28 -0500430 li.zonelow_base,
Kevin O'Connorc91da7a2012-06-08 21:14:19 -0400431 li.final_sec32low_start,
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500432 li.final_readonly_start,
Kevin O'Connor46b82622012-05-13 12:10:30 -0400433 sec32all_start,
434 relocstr,
435 outRelSections(li.sections32low, 'code32flat_start'),
436 outRelSections(li.sections32init, 'code32flat_start'),
437 outRelSections(li.sections32flat, 'code32flat_start'),
Kevin O'Connor41953492013-02-18 23:09:01 -0500438 outRelSections(li.sections32fseg, 'code32flat_start'),
Kevin O'Connor46b82622012-05-13 12:10:30 -0400439 li.sec32seg_start,
440 li.sec16_start)
441 out = COMMONHEADER + out + COMMONTRAILER + """
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500442ENTRY(entry_elf)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400443PHDRS
444{
445 text PT_LOAD AT ( code32flat_start ) ;
446}
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500447"""
Johannes Krampf19f789b2014-01-19 16:03:49 +0100448 outfile = open(out32flat, 'w')
Kevin O'Connor46b82622012-05-13 12:10:30 -0400449 outfile.write(out)
450 outfile.close()
Kevin O'Connorc0693942009-06-10 21:56:01 -0400451
452
453######################################################################
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400454# Detection of init code
455######################################################################
456
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500457def markRuntime(section, sections, chain=[]):
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400458 if (section is None or not section.keep or section.category is not None
459 or '.init.' in section.name or section.fileid != '32flat'):
460 return
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500461 if '.data.varinit.' in section.name:
Johannes Krampf064fd062014-01-12 11:14:54 -0500462 print("ERROR: %s is VARVERIFY32INIT but used from %s" % (
463 section.name, chain))
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500464 sys.exit(1)
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400465 section.category = '32flat'
466 # Recursively mark all sections this section points to
467 for reloc in section.relocs:
Kevin O'Connor2af52da2013-03-08 19:36:28 -0500468 markRuntime(reloc.symbol.section, sections, chain + [section.name])
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400469
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500470def findInit(sections):
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400471 # Recursively find and mark all "runtime" sections.
472 for section in sections:
Kevin O'Connor41953492013-02-18 23:09:01 -0500473 if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name
474 or '.runtime.' in section.name or '.export.' in section.name):
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400475 markRuntime(section, sections)
476 for section in sections:
477 if section.category is not None:
478 continue
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500479 if section.fileid == '32flat':
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400480 section.category = '32init'
481 else:
482 section.category = section.fileid
483
484
485######################################################################
Kevin O'Connorc0693942009-06-10 21:56:01 -0400486# Section garbage collection
487######################################################################
488
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500489CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)]
490
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500491# Find and keep the section associated with a symbol (if available).
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500492def keepsymbol(reloc, infos, pos, isxref):
493 symbolname = reloc.symbolname
494 mustbecfunc = 0
495 for symprefix, needpos in CFUNCPREFIX:
496 if symbolname.startswith(symprefix):
497 if needpos != pos:
498 return -1
499 symbolname = symbolname[len(symprefix):]
500 mustbecfunc = 1
501 break
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400502 symbol = infos[pos][1].get(symbolname)
503 if (symbol is None or symbol.section is None
504 or symbol.section.name.startswith('.discard.')):
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500505 return -1
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500506 isdestcfunc = (symbol.section.name.startswith('.text.')
507 and not symbol.section.name.startswith('.text.asm.'))
508 if ((mustbecfunc and not isdestcfunc)
509 or (not mustbecfunc and isdestcfunc and isxref)):
510 return -1
511
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400512 reloc.symbol = symbol
513 keepsection(symbol.section, infos, pos)
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500514 return 0
515
Kevin O'Connor5b8f8092009-09-20 19:47:45 -0400516# Note required section, and recursively set all referenced sections
517# as required.
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400518def keepsection(section, infos, pos=0):
519 if section.keep:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400520 # Already kept - nothing to do.
521 return
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400522 section.keep = 1
Kevin O'Connorc0693942009-06-10 21:56:01 -0400523 # Keep all sections that this section points to
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400524 for reloc in section.relocs:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500525 ret = keepsymbol(reloc, infos, pos, 0)
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500526 if not ret:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400527 continue
528 # Not in primary sections - it may be a cross 16/32 reference
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500529 ret = keepsymbol(reloc, infos, (pos+1)%3, 1)
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500530 if not ret:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500531 continue
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500532 ret = keepsymbol(reloc, infos, (pos+2)%3, 1)
Kevin O'Connorfdca4182010-01-01 12:46:54 -0500533 if not ret:
534 continue
Kevin O'Connorc0693942009-06-10 21:56:01 -0400535
Kevin O'Connor5b8f8092009-09-20 19:47:45 -0400536# Determine which sections are actually referenced and need to be
537# placed into the output file.
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500538def gc(info16, info32seg, info32flat):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400539 # infos = ((sections16, symbols16), (sect32seg, sym32seg)
540 # , (sect32flat, sym32flat))
541 infos = (info16, info32seg, info32flat)
Kevin O'Connorc0693942009-06-10 21:56:01 -0400542 # Start by keeping sections that are globally visible.
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400543 for section in info16[0]:
544 if section.name.startswith('.fixedaddr.') or '.export.' in section.name:
Kevin O'Connor871e0a02009-12-30 12:14:53 -0500545 keepsection(section, infos)
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400546 return [section for section in info16[0]+info32seg[0]+info32flat[0]
547 if section.keep]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400548
549
550######################################################################
551# Startup and input parsing
552######################################################################
553
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400554class Section:
555 name = size = alignment = fileid = relocs = None
Kevin O'Connor46b82622012-05-13 12:10:30 -0400556 finalloc = finalsegloc = category = keep = None
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400557class Reloc:
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500558 offset = type = symbolname = symbol = None
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400559class Symbol:
560 name = offset = section = None
561
Kevin O'Connorc0693942009-06-10 21:56:01 -0400562# Read in output from objdump
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400563def parseObjDump(file, fileid):
564 # sections = [section, ...]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400565 sections = []
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400566 sectionmap = {}
567 # symbols[symbolname] = symbol
Kevin O'Connorc0693942009-06-10 21:56:01 -0400568 symbols = {}
Kevin O'Connorc0693942009-06-10 21:56:01 -0400569
570 state = None
571 for line in file.readlines():
572 line = line.rstrip()
573 if line == 'Sections:':
574 state = 'section'
575 continue
576 if line == 'SYMBOL TABLE:':
577 state = 'symbol'
578 continue
Kevin O'Connor6c2e7812010-09-13 18:04:02 -0400579 if line.startswith('RELOCATION RECORDS FOR ['):
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400580 sectionname = line[24:-2]
581 if sectionname.startswith('.debug_'):
582 # Skip debugging sections (to reduce parsing time)
583 state = None
584 continue
Kevin O'Connorc0693942009-06-10 21:56:01 -0400585 state = 'reloc'
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400586 relocsection = sectionmap[sectionname]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400587 continue
588
589 if state == 'section':
590 try:
591 idx, name, size, vma, lma, fileoff, align = line.split()
592 if align[:3] != '2**':
593 continue
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400594 section = Section()
595 section.name = name
596 section.size = int(size, 16)
597 section.align = 2**int(align[3:])
598 section.fileid = fileid
599 section.relocs = []
600 sections.append(section)
601 sectionmap[name] = section
602 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400603 pass
604 continue
605 if state == 'symbol':
606 try:
Kevin O'Connor90ebed42012-06-21 20:54:53 -0400607 parts = line[17:].split()
608 if len(parts) == 3:
609 sectionname, size, name = parts
610 elif len(parts) == 4 and parts[2] == '.hidden':
611 sectionname, size, hidden, name = parts
612 else:
613 continue
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400614 symbol = Symbol()
615 symbol.size = int(size, 16)
616 symbol.offset = int(line[:8], 16)
617 symbol.name = name
618 symbol.section = sectionmap.get(sectionname)
619 symbols[name] = symbol
620 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400621 pass
622 continue
623 if state == 'reloc':
624 try:
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400625 off, type, symbolname = line.split()
626 reloc = Reloc()
627 reloc.offset = int(off, 16)
628 reloc.type = type
Kevin O'Connorf3fe3aa2010-12-05 12:38:33 -0500629 reloc.symbolname = symbolname
Kevin O'Connor67863be2010-12-24 10:23:10 -0500630 reloc.symbol = symbols.get(symbolname)
631 if reloc.symbol is None:
632 # Some binutils (2.20.1) give section name instead
633 # of a symbol - create a dummy symbol.
634 reloc.symbol = symbol = Symbol()
635 symbol.size = 0
636 symbol.offset = 0
637 symbol.name = symbolname
638 symbol.section = sectionmap.get(symbolname)
639 symbols[symbolname] = symbol
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400640 relocsection.relocs.append(reloc)
641 except ValueError:
Kevin O'Connorc0693942009-06-10 21:56:01 -0400642 pass
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400643 return sections, symbols
Kevin O'Connorc0693942009-06-10 21:56:01 -0400644
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400645# Parser for constants in simple C header files.
646def scanconfig(file):
Johannes Krampf19f789b2014-01-19 16:03:49 +0100647 f = open(file, 'r')
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400648 opts = {}
649 for l in f.readlines():
650 parts = l.split()
651 if len(parts) != 3:
652 continue
653 if parts[0] != '#define':
654 continue
655 value = parts[2]
656 if value.isdigit() or (value.startswith('0x') and value[2:].isdigit()):
657 value = int(value, 0)
658 opts[parts[1]] = value
659 return opts
660
Kevin O'Connorc0693942009-06-10 21:56:01 -0400661def main():
662 # Get output name
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400663 in16, in32seg, in32flat, cfgfile, out16, out32seg, out32flat = sys.argv[1:]
Kevin O'Connorc0693942009-06-10 21:56:01 -0400664
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400665 # Read in the objdump information
Johannes Krampf19f789b2014-01-19 16:03:49 +0100666 infile16 = open(in16, 'r')
667 infile32seg = open(in32seg, 'r')
668 infile32flat = open(in32flat, 'r')
Kevin O'Connorc0693942009-06-10 21:56:01 -0400669
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400670 # infoX = (sections, symbols)
671 info16 = parseObjDump(infile16, '16')
672 info32seg = parseObjDump(infile32seg, '32seg')
673 info32flat = parseObjDump(infile32flat, '32flat')
Kevin O'Connorc0693942009-06-10 21:56:01 -0400674
Kevin O'Connor2b0fb8c2013-08-07 23:03:47 -0400675 # Read kconfig config file
676 config = scanconfig(cfgfile)
677
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400678 # Figure out which sections to keep.
Kevin O'Connor1a4885e2010-09-15 21:28:31 -0400679 sections = gc(info16, info32seg, info32flat)
Kevin O'Connorc0693942009-06-10 21:56:01 -0400680
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400681 # Separate 32bit flat into runtime and init parts
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500682 findInit(sections)
Kevin O'Connord1b4f962010-09-15 21:38:16 -0400683
Kevin O'Connor41953492013-02-18 23:09:01 -0500684 # Note "low memory" and "fseg memory" parts
Kevin O'Connorc9243442013-02-17 13:58:28 -0500685 for section in getSectionsPrefix(sections, '.data.varlow.'):
Kevin O'Connor46b82622012-05-13 12:10:30 -0400686 section.category = '32low'
Kevin O'Connor41953492013-02-18 23:09:01 -0500687 for section in getSectionsPrefix(sections, '.data.varfseg.'):
688 section.category = '32fseg'
Kevin O'Connor46b82622012-05-13 12:10:30 -0400689
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400690 # Determine the final memory locations of each kept section.
Kevin O'Connorb94170c2013-12-06 13:52:16 -0500691 genreloc = '_reloc_abs_start' in info32flat[1]
692 li = doLayout(sections, config, genreloc)
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400693
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500694 # Exported symbols
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500695 li.exportsyms = [symbol for symbol in info16[1].values()
696 if (symbol.section is not None
697 and '.export.' in symbol.section.name
698 and symbol.name != symbol.section.name)]
699 li.varlowsyms = [symbol for symbol in info32flat[1].values()
700 if (symbol.section is not None
701 and symbol.section.finalloc is not None
702 and '.data.varlow.' in symbol.section.name
703 and symbol.name != symbol.section.name)]
Kevin O'Connora3c48f52013-02-05 22:36:13 -0500704
Kevin O'Connor9ba1dea2010-05-01 09:50:13 -0400705 # Write out linker script files.
Kevin O'Connor6afc6f82013-02-19 01:02:50 -0500706 writeLinkerScripts(li, out16, out32seg, out32flat)
Kevin O'Connorc0693942009-06-10 21:56:01 -0400707
Kevin O'Connor202024a2009-01-17 10:41:28 -0500708if __name__ == '__main__':
709 main()