aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile27
-rw-r--r--src/rombios.lds.S34
-rw-r--r--src/rombios16.lds.S21
-rw-r--r--src/rombios32seg.lds.S18
-rwxr-xr-xtools/checkrom.py29
-rwxr-xr-xtools/checkstack.py2
-rwxr-xr-xtools/layoutrom.py401
7 files changed, 241 insertions, 291 deletions
diff --git a/Makefile b/Makefile
index 90d7072c..327a1bf7 100644
--- a/Makefile
+++ b/Makefile
@@ -100,6 +100,9 @@ endef
endif
endif
+%.strip.o: %.o
+ @echo " Stripping $@"
+ $(Q)$(STRIP) $< -o $@
$(OUT)%.s: %.c
@echo " Compiling to assembler $@"
@@ -135,27 +138,17 @@ $(OUT)romlayout16.lds $(OUT)romlayout32seg.lds $(OUT)romlayout32flat.lds $(OUT)c
$(Q)./tools/layoutrom.py $(OUT)code16.o.objdump $(OUT)code32seg.o.objdump $(OUT)code32flat.o.objdump $(OUT)romlayout16.lds $(OUT)romlayout32seg.lds $(OUT)romlayout32flat.lds
-$(OUT)rom16.o: $(OUT)code16.o $(OUT)rom32flat.o $(OUT)romlayout16.lds
- @echo " Linking (no relocs) $@"
- $(Q)$(LD) -r -T $(OUT)romlayout16.lds $< -o $@
+$(OUT)rom16.o: $(OUT)code16.o $(OUT)romlayout16.lds
+ @echo " Linking $@"
+ $(Q)$(LD) -T $(OUT)romlayout16.lds $< -o $@
$(OUT)rom32seg.o: $(OUT)code32seg.o $(OUT)romlayout32seg.lds
- @echo " Linking (no relocs) $@"
- $(Q)$(LD) -r -T $(OUT)romlayout32seg.lds $< -o $@
-
-$(OUT)rom32flat.o: $(OUT)code32flat.o $(OUT)romlayout32flat.lds
- @echo " Linking (no relocs) $@"
- $(Q)$(LD) -r -T $(OUT)romlayout32flat.lds $< -o $@
+ @echo " Linking $@"
+ $(Q)$(LD) -T $(OUT)romlayout32seg.lds $< -o $@
-$(OUT)rom.o: $(OUT)rom16.o $(OUT)rom32seg.o $(OUT)rom32flat.o $(OUT)rombios16.lds $(OUT)rombios32seg.lds $(OUT)rombios.lds
+$(OUT)rom.o: $(OUT)rom16.strip.o $(OUT)rom32seg.strip.o $(OUT)code32flat.o $(OUT)romlayout32flat.lds
@echo " Linking $@"
- $(Q)$(LD) -T $(OUT)rombios16.lds $(OUT)rom16.o -R $(OUT)rom32seg.o -R $(OUT)rom32flat.o -o $(OUT)rom16.reloc.o
- $(Q)$(STRIP) $(OUT)rom16.reloc.o -o $(OUT)rom16.final.o
- $(Q)$(OBJCOPY) --adjust-vma 0xf0000 $(OUT)rom16.o $(OUT)rom16.moved.o
- $(Q)$(LD) -T $(OUT)rombios32seg.lds $(OUT)rom32seg.o -R $(OUT)rom16.o -R $(OUT)rom32flat.o -o $(OUT)rom32seg.reloc.o
- $(Q)$(STRIP) $(OUT)rom32seg.reloc.o -o $(OUT)rom32seg.final.o
- $(Q)$(OBJCOPY) --adjust-vma 0xf0000 $(OUT)rom32seg.o $(OUT)rom32seg.moved.o
- $(Q)$(LD) -T $(OUT)rombios.lds $(OUT)rom16.final.o $(OUT)rom32seg.final.o $(OUT)rom32flat.o -R $(OUT)rom16.moved.o -R $(OUT)rom32seg.moved.o -o $@
+ $(Q)$(LD) -T $(OUT)romlayout32flat.lds $(OUT)rom16.strip.o $(OUT)rom32seg.strip.o $(OUT)code32flat.o -o $@
$(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o tools/checkrom.py
@echo " Prepping $@"
diff --git a/src/rombios.lds.S b/src/rombios.lds.S
deleted file mode 100644
index 4cbc15a3..00000000
--- a/src/rombios.lds.S
+++ /dev/null
@@ -1,34 +0,0 @@
-// Linker definitions for merging 16 and 32 bit code
-//
-// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "config.h" // BUILD_BIOS_ADDR
-
-OUTPUT_FORMAT("elf32-i386")
-OUTPUT_ARCH("i386")
-ENTRY(post32)
-PHDRS
-{
- text PT_LOAD AT ( code32flat_start ) ;
-}
-SECTIONS
-{
- .text code32flat_start : {
- *(.text32flat)
-
- . = code32seg_start + BUILD_BIOS_ADDR - code32flat_start ;
- *(.text32seg)
-
- . = data16_start + BUILD_BIOS_ADDR - code32flat_start ;
- *(.data16)
- . = text16_start + BUILD_BIOS_ADDR - code32flat_start ;
- *(.text16)
- final_text16_end = . ;
- } :text
- /DISCARD/ : {
- *(.text*) *(.data*) *(.bss*) *(.rodata*)
- *(COMMON) *(.discard*) *(.eh_frame)
- }
-}
diff --git a/src/rombios16.lds.S b/src/rombios16.lds.S
deleted file mode 100644
index 6d382f03..00000000
--- a/src/rombios16.lds.S
+++ /dev/null
@@ -1,21 +0,0 @@
-// Linker definitions for 16bit code
-//
-// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH("i386")
-PHDRS
-{
-}
-SECTIONS
-{
- .data16 data16_start : {
- *(.data16)
- }
- .text16 text16_start : {
- *(.text16)
- }
- /DISCARD/ : { *(.discard*) }
-}
diff --git a/src/rombios32seg.lds.S b/src/rombios32seg.lds.S
deleted file mode 100644
index 377f4e7e..00000000
--- a/src/rombios32seg.lds.S
+++ /dev/null
@@ -1,18 +0,0 @@
-// Linker definitions for 32bit segmented code
-//
-// Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH("i386")
-PHDRS
-{
-}
-SECTIONS
-{
- .text32seg code32seg_start : {
- *(.text32seg)
- }
- /DISCARD/ : { *(.discard*) }
-}
diff --git a/tools/checkrom.py b/tools/checkrom.py
index 5c9600f1..039010d2 100755
--- a/tools/checkrom.py
+++ b/tools/checkrom.py
@@ -29,34 +29,27 @@ def main():
finalsize = 128*1024
# Sanity checks
- c16e = syms['text16_end'] + 0xf0000
- f16e = syms['final_text16_end']
- if c16e != f16e:
- print "Error! 16bit code moved during linking (0x%x vs 0x%x)" % (
- c16e, f16e)
+ start = syms['code32flat_start']
+ end = syms['code32flat_end']
+ expend = layoutrom.BUILD_BIOS_ADDR + layoutrom.BUILD_BIOS_SIZE
+ if end != expend:
+ print "Error! Code does not end at 0x%x (got 0x%x)" % (
+ expend, end)
sys.exit(1)
if datasize > finalsize:
print "Error! Code is too big (0x%x vs 0x%x)" % (
datasize, finalsize)
sys.exit(1)
- actualdatasize = f16e - syms['code32flat_start']
- if datasize != actualdatasize:
+ expdatasize = end - start
+ if datasize != expdatasize:
print "Error! Unknown extra data (0x%x vs 0x%x)" % (
- datasize, actualdatasize)
+ datasize, expdatasize)
sys.exit(1)
# Print statistics
- sizefree = syms['freespace_end'] - syms['freespace_start']
- size16 = syms['text16_end'] - syms['data16_start']
- size32seg = syms['code32seg_end'] - syms['code32seg_start']
- size32flat = syms['code32flat_end'] - syms['code32flat_start']
- totalc = size16+size32seg+size32flat
- print "16bit size: %d" % size16
- print "32bit segmented size: %d" % size32seg
- print "32bit flat size: %d" % size32flat
print "Total size: %d Free space: %d Percent used: %.1f%% (%dKiB rom)" % (
- totalc, sizefree + finalsize - datasize
- , (totalc / float(finalsize)) * 100.0
+ datasize, finalsize - datasize
+ , (datasize / float(finalsize)) * 100.0
, finalsize / 1024)
# Write final file
diff --git a/tools/checkstack.py b/tools/checkstack.py
index 84bd778d..54ea3e93 100755
--- a/tools/checkstack.py
+++ b/tools/checkstack.py
@@ -7,7 +7,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
# Usage:
-# objdump -m i386 -M i8086 -M suffix -d out/rom16.reloc.o | tools/checkstack.py
+# objdump -m i386 -M i8086 -M suffix -d out/rom16.o | tools/checkstack.py
import sys
import re
diff --git a/tools/layoutrom.py b/tools/layoutrom.py
index d0ca9a65..5f8c3682 100755
--- a/tools/layoutrom.py
+++ b/tools/layoutrom.py
@@ -7,11 +7,6 @@
import sys
-# Align 'pos' to 'alignbytes' offset
-def alignpos(pos, alignbytes):
- mask = alignbytes - 1
- return (pos + mask) & ~mask
-
# LD script headers/trailers
COMMONHEADER = """
/* DO NOT EDIT! This is an autogenerated file. See tools/layoutrom.py. */
@@ -21,15 +16,29 @@ SECTIONS
{
"""
COMMONTRAILER = """
+
+ /* Discard regular data sections to force a link error if
+ * code attempts to access data not marked with VAR16 (or other
+ * appropriate macro)
+ */
+ /DISCARD/ : {
+ *(.text*) *(.data*) *(.bss*) *(.rodata*)
+ *(COMMON) *(.discard*) *(.eh_frame)
+ }
}
"""
######################################################################
-# 16bit fixed address section fitting
+# Determine section locations
######################################################################
-# Get the maximum start position for a list of sections that end at an
+# Align 'pos' to 'alignbytes' offset
+def alignpos(pos, alignbytes):
+ mask = alignbytes - 1
+ return (pos + mask) & ~mask
+
+# Determine the final addresses for a list of sections that end at an
# address.
def getSectionsStart(sections, endaddr, minalign=1):
totspace = 0
@@ -37,47 +46,46 @@ def getSectionsStart(sections, endaddr, minalign=1):
if align > minalign:
minalign = align
totspace = alignpos(totspace, align) + size
- return (endaddr - totspace) / minalign * minalign
+ startaddr = (endaddr - totspace) / minalign * minalign
+ curaddr = startaddr
+ # out = [(addr, sectioninfo), ...]
+ out = []
+ for sectioninfo in sections:
+ size, align, name = sectioninfo
+ curaddr = alignpos(curaddr, align)
+ out.append((curaddr, sectioninfo))
+ curaddr += size
+ return out, startaddr
-# Write LD script includes for the given sections
-def outSections(file, sections):
+# Return the subset of sections with a given name prefix
+def getSectionsPrefix(sections, prefix):
+ lp = len(prefix)
+ out = []
for size, align, name in sections:
- file.write("*(%s)\n" % (name,))
+ if name[:lp] == prefix:
+ out.append((size, align, name))
+ return out
# The 16bit code can't exceed 64K of space.
-MAXPOS = 64*1024
+BUILD_BIOS_ADDR = 0xf0000
+BUILD_BIOS_SIZE = 0x10000
# Layout the 16bit code. This ensures sections with fixed offset
# requirements are placed in the correct location. It also places the
# 16bit code as high as possible in the f-segment.
-def doLayout16(sections, outname):
- textsections = []
- rodatasections = []
- datasections = []
- # fixedsections = [(addr, sectioninfo, extasectionslist), ...]
+def fitSections(sections, fillsections):
+ canrelocate = list(fillsections)
+ # fixedsections = [(addr, sectioninfo), ...]
fixedsections = []
- # canrelocate = [(sectioninfo, list), ...]
- canrelocate = []
-
- # Find desired sections.
- for section in sections:
- size, align, name = section
+ for sectioninfo in sections:
+ size, align, name = sectioninfo
if name[:11] == '.fixedaddr.':
addr = int(name[11:], 16)
- fixedsections.append((addr, section, []))
+ fixedsections.append((addr, sectioninfo))
if align != 1:
print "Error: Fixed section %s has non-zero alignment (%d)" % (
name, align)
sys.exit(1)
- if name[:6] == '.text.':
- textsections.append(section)
- canrelocate.append((section, textsections))
- if name[:17] == '.rodata.__func__.' or name == '.rodata.str1.1':
- rodatasections.append(section)
- #canrelocate.append((section, rodatasections))
- if name[:8] == '.data16.':
- datasections.append(section)
- #canrelocate.append((section, datasections))
# Find freespace in fixed address area
fixedsections.sort()
@@ -85,20 +93,21 @@ def doLayout16(sections, outname):
fixedAddr = []
for i in range(len(fixedsections)):
fixedsectioninfo = fixedsections[i]
- addr, section, extrasectionslist = fixedsectioninfo
+ addr, section = fixedsectioninfo
if i == len(fixedsections) - 1:
- nextaddr = MAXPOS
+ nextaddr = BUILD_BIOS_SIZE
else:
nextaddr = fixedsections[i+1][0]
avail = nextaddr - addr - section[0]
fixedAddr.append((avail, fixedsectioninfo))
# Attempt to fit other sections into fixed area
+ extrasections = []
fixedAddr.sort()
canrelocate.sort()
totalused = 0
for freespace, fixedsectioninfo in fixedAddr:
- fixedaddr, fixedsection, extrasections = fixedsectioninfo
+ fixedaddr, fixedsection = fixedsectioninfo
addpos = fixedaddr + fixedsection[0]
totalused += fixedsection[0]
nextfixedaddr = addpos + freespace
@@ -106,8 +115,7 @@ def doLayout16(sections, outname):
# fixedaddr, fixedsection[0], nextfixedaddr, freespace)
while 1:
canfit = None
- for fixedaddrinfo in canrelocate:
- fitsection, inlist = fixedaddrinfo
+ for fitsection in canrelocate:
fitsize, fitalign, fitname = fitsection
if addpos + fitsize > nextfixedaddr:
# Can't fit and nothing else will fit.
@@ -118,15 +126,13 @@ def doLayout16(sections, outname):
if fitnextaddr > nextfixedaddr:
# This item can't fit.
continue
- canfit = (fitnextaddr, fixedaddrinfo)
+ canfit = (fitnextaddr, fitsection)
if canfit is None:
break
# Found a section that can fit.
- fitnextaddr, fixedaddrinfo = canfit
- canrelocate.remove(fixedaddrinfo)
- fitsection, inlist = fixedaddrinfo
- inlist.remove(fitsection)
- extrasections.append(fitsection)
+ fitnextaddr, fitsection = canfit
+ canrelocate.remove(fitsection)
+ extrasections.append((addpos, fitsection))
addpos = fitnextaddr
totalused += fitsection[0]
# print " Adding %s (size %d align %d) pos=%x avail=%d" % (
@@ -135,150 +141,166 @@ def doLayout16(sections, outname):
firstfixed = fixedsections[0][0]
# Report stats
- total = MAXPOS-firstfixed
+ total = BUILD_BIOS_SIZE-firstfixed
slack = total - totalused
print ("Fixed space: 0x%x-0x%x total: %d slack: %d"
" Percent slack: %.1f%%" % (
- firstfixed, MAXPOS, total, slack,
+ firstfixed, BUILD_BIOS_SIZE, total, slack,
(float(slack) / total) * 100.0))
- # Find start positions
- text16_start = getSectionsStart(textsections, firstfixed)
- data16_start = getSectionsStart(rodatasections + datasections, text16_start)
-
- # Write header and regular sections
- output = open(outname, 'wb')
- output.write(COMMONHEADER + """
- data16_start = 0x%x ;
- .data16 data16_start : {
-""" % data16_start)
- outSections(output, datasections)
- output.write("code16_rodata = . ;\n")
- outSections(output, rodatasections)
- output.write("""
- }
-
- text16_start = 0x%x ;
- .text16 text16_start : {
-""" % text16_start)
- outSections(output, textsections)
-
- # Write fixed sections
- for addr, section, extrasections in fixedsections:
- name = section[2]
- output.write(". = ( 0x%x - text16_start ) ;\n" % (addr,))
- output.write("*(%s)\n" % (name,))
- for extrasection in extrasections:
- output.write("*(%s)\n" % (extrasection[2],))
-
- # Write trailer
- output.write("""
- text16_end = ABSOLUTE(.) ;
- }
-
- /* Discard regular data sections to force a link error if
- * 16bit code attempts to access data not marked with VAR16
- */
- /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) }
-""" + COMMONTRAILER)
-
- return data16_start
+ return fixedsections + extrasections, firstfixed
+
+def doLayout(sections16, sections32seg, sections32flat):
+ # Determine 16bit positions
+ textsections = getSectionsPrefix(sections16, '.text.')
+ rodatasections = (getSectionsPrefix(sections16, '.rodata.str1.1')
+ + getSectionsPrefix(sections16, '.rodata.__func__.'))
+ datasections = getSectionsPrefix(sections16, '.data16.')
+ fixedsections = getSectionsPrefix(sections16, '.fixedaddr.')
+
+ locs16fixed, firstfixed = fitSections(fixedsections, textsections)
+ prunesections = [i[1] for i in locs16fixed]
+ remsections = [i for i in textsections+rodatasections+datasections
+ if i not in prunesections]
+ locs16, code16_start = getSectionsStart(remsections, firstfixed)
+ locs16 = locs16 + locs16fixed
+ locs16.sort()
+
+ # Determine 32seg positions
+ textsections = getSectionsPrefix(sections32seg, '.text.')
+ rodatasections = (getSectionsPrefix(sections32seg, '.rodata.str1.1')
+ + getSectionsPrefix(sections32seg, '.rodata.__func__.'))
+ datasections = getSectionsPrefix(sections32seg, '.data32seg.')
+
+ locs32seg, code32seg_start = getSectionsStart(
+ textsections + rodatasections + datasections, code16_start)
+
+ # Determine 32flat positions
+ textsections = getSectionsPrefix(sections32flat, '.text.')
+ rodatasections = getSectionsPrefix(sections32flat, '.rodata')
+ datasections = getSectionsPrefix(sections32flat, '.data.')
+ bsssections = getSectionsPrefix(sections32flat, '.bss.')
+
+ locs32flat, code32flat_start = getSectionsStart(
+ textsections + rodatasections + datasections + bsssections
+ , code32seg_start + BUILD_BIOS_ADDR, 16)
+
+ # Print statistics
+ size16 = BUILD_BIOS_SIZE - code16_start
+ size32seg = code16_start - code32seg_start
+ size32flat = code32seg_start + BUILD_BIOS_ADDR - code32flat_start
+ print "16bit size: %d" % size16
+ print "32bit segmented size: %d" % size32seg
+ print "32bit flat size: %d" % size32flat
+
+ return locs16, locs32seg, locs32flat
######################################################################
-# 32bit section outputting
+# Linker script output
######################################################################
-# Return the subset of sections with a given name prefix
-def getSectionsPrefix(sections, prefix):
- lp = len(prefix)
- out = []
- for size, align, name in sections:
- if name[:lp] == prefix:
- out.append((size, align, name))
+# Write LD script includes for the given cross references
+def outXRefs(xrefs, finallocs, delta=0):
+ out = ""
+ for symbol, (fileid, section, addr) in xrefs.items():
+ if fileid < 2:
+ addr += delta
+ out += "%s = 0x%x ;\n" % (symbol, finallocs[(fileid, section)] + addr)
+ return out
+
+# Write LD script includes for the given sections using relative offsets
+def outRelSections(locs, startsym):
+ out = ""
+ for addr, sectioninfo in locs:
+ size, align, name = sectioninfo
+ out += ". = ( 0x%x - %s ) ;\n" % (addr, startsym)
+ if name == '.rodata.str1.1':
+ out += "_rodata = . ;\n"
+ out += "*(%s)\n" % (name,)
return out
# Layout the 32bit segmented code. This places the code as high as possible.
-def doLayout32seg(sections, outname, endat):
- # Find sections to output
- textsections = getSectionsPrefix(sections, '.text.')
- rodatasections = (getSectionsPrefix(sections, '.rodata.str1.1')
- + getSectionsPrefix(sections, '.rodata.__func__.'))
- datasections = getSectionsPrefix(sections, '.data32seg.')
- startat = getSectionsStart(
- textsections + rodatasections + datasections, endat)
-
- # Write sections
- output = open(outname, 'wb')
- output.write(COMMONHEADER + """
- code32seg_start = 0x%x ;
- .text32seg code32seg_start : {
- freespace_end = . ;
-""" % startat)
-
- outSections(output, textsections)
- output.write("code32seg_rodata = . ;\n")
- outSections(output, rodatasections)
- outSections(output, datasections)
-
- output.write("""
- code32seg_end = ABSOLUTE(.) ;
- }
- /DISCARD/ : { *(.text*) *(.rodata*) *(.data*) *(.bss*) *(COMMON) }
-""" + COMMONTRAILER)
- return startat
-
-# Layout the 32bit flat code. This places the code as high as possible.
-def doLayout32flat(sections, outname, endat):
- endat += 0xf0000
- # Find sections to output
- textsections = getSectionsPrefix(sections, '.text.')
- rodatasections = getSectionsPrefix(sections, '.rodata')
- datasections = getSectionsPrefix(sections, '.data.')
- bsssections = getSectionsPrefix(sections, '.bss.')
- startat = getSectionsStart(
- textsections + rodatasections + datasections + bsssections, endat, 512)
-
- # Write sections
- output = open(outname, 'wb')
- output.write(COMMONHEADER + """
- code32flat_start = 0x%x ;
- .text32flat code32flat_start : {
-""" % startat)
-
- outSections(output, textsections)
- output.write("code32_rodata = . ;\n")
- outSections(output, rodatasections)
- outSections(output, datasections)
- outSections(output, bsssections)
-
- output.write("""
- freespace_start = . ;
- code32flat_end = ABSOLUTE(.) ;
- }
-""" + COMMONTRAILER)
- return startat
+def writeLinkerScripts(locs16, locs32seg, locs32flat
+ , xref16, xref32seg, xref32flat
+ , out16, out32seg, out32flat):
+ # Index to final location for each section
+ # finallocs[(fileid, section)] = addr
+ finallocs = {}
+ for fileid, locs in ((0, locs16), (1, locs32seg), (2, locs32flat)):
+ for addr, sectioninfo in locs:
+ finallocs[(fileid, sectioninfo[2])] = addr
+
+ # Write 16bit linker script
+ code16_start = locs16[0][0]
+ output = open(out16, 'wb')
+ output.write(COMMONHEADER + outXRefs(xref16, finallocs) + """
+ code16_start = 0x%x ;
+ .text16 code16_start : {
+""" % (code16_start)
+ + outRelSections(locs16, 'code16_start')
+ + """
+ }
+"""
+ + COMMONTRAILER)
+ output.close()
+
+ # Write 32seg linker script
+ code32seg_start = code16_start
+ if locs32seg:
+ code32seg_start = locs32seg[0][0]
+ output = open(out32seg, 'wb')
+ output.write(COMMONHEADER + outXRefs(xref32seg, finallocs) + """
+ code32seg_start = 0x%x ;
+ .text32seg code32seg_start : {
+""" % (code32seg_start)
+ + outRelSections(locs32seg, 'code32seg_start')
+ + """
+ }
+"""
+ + COMMONTRAILER)
+ output.close()
+
+ # Write 32flat linker script
+ output = open(out32flat, 'wb')
+ output.write(COMMONHEADER
+ + outXRefs(xref32flat, finallocs, BUILD_BIOS_ADDR) + """
+ code32flat_start = 0x%x ;
+ .text code32flat_start : {
+""" % (locs32flat[0][0])
+ + outRelSections(locs32flat, 'code32flat_start')
+ + """
+ . = ( 0x%x - code32flat_start ) ;
+ *(.text32seg)
+ . = ( 0x%x - code32flat_start ) ;
+ *(.text16)
+ code32flat_end = ABSOLUTE(.) ;
+ } :text
+""" % (code32seg_start + BUILD_BIOS_ADDR, code16_start + BUILD_BIOS_ADDR)
+ + COMMONTRAILER
+ + """
+ENTRY(post32)
+PHDRS
+{
+ text PT_LOAD AT ( code32flat_start ) ;
+}
+""")
+ output.close()
######################################################################
# Section garbage collection
######################################################################
-def getSectionsList(info, names):
- out = []
- for i in info[0]:
- size, align, section = i
- if section not in names:
-# print "gc", section
- continue
- out.append(i)
- return out
-
# Find and keep the section associated with a symbol (if available).
-def keepsymbol(symbol, infos, pos):
+def keepsymbol(symbol, infos, pos, callerpos=None):
addr, section = infos[pos][1].get(symbol, (None, None))
if section is None or '*' in section or section[:9] == '.discard.':
return -1
+ if callerpos is not None and symbol not in infos[callerpos][4]:
+ # This symbol reference is a cross section reference (an xref).
+ # xref[symbol] = (fileid, section, addr)
+ infos[callerpos][4][symbol] = (pos, section, addr)
keepsection(section, infos, pos)
return 0
@@ -298,29 +320,34 @@ def keepsection(name, infos, pos=0):
if not ret:
continue
# Not in primary sections - it may be a cross 16/32 reference
- ret = keepsymbol(symbol, infos, (pos+1)%3)
+ ret = keepsymbol(symbol, infos, (pos+1)%3, pos)
if not ret:
continue
- ret = keepsymbol(symbol, infos, (pos+2)%3)
+ ret = keepsymbol(symbol, infos, (pos+2)%3, pos)
if not ret:
continue
+# Return a list of kept sections.
+def getSectionsList(sections, names):
+ return [i for i in sections if i[2] in names]
+
# Determine which sections are actually referenced and need to be
# placed into the output file.
def gc(info16, info32seg, info32flat):
- # infos = ((sections, symbols, relocs, keep sections), ...)
- infos = ((info16[0], info16[1], info16[2], []),
- (info32seg[0], info32seg[1], info32seg[2], []),
- (info32flat[0], info32flat[1], info32flat[2], []))
+ # infos = ((sections, symbols, relocs, keep sections, xrefs), ...)
+ infos = ((info16[0], info16[1], info16[2], [], {}),
+ (info32seg[0], info32seg[1], info32seg[2], [], {}),
+ (info32flat[0], info32flat[1], info32flat[2], [], {}))
# Start by keeping sections that are globally visible.
for size, align, section in info16[0]:
if section[:11] == '.fixedaddr.' or '.export.' in section:
keepsection(section, infos)
+ keepsymbol('post32', infos, 0, 2)
# Return sections found.
- sections16 = getSectionsList(info16, infos[0][3])
- sections32seg = getSectionsList(info32seg, infos[1][3])
- sections32flat = getSectionsList(info32flat, infos[2][3])
- return sections16, sections32seg, sections32flat
+ keep16 = getSectionsList(info16[0], infos[0][3]), infos[0][4]
+ keep32seg = getSectionsList(info32seg[0], infos[1][3]), infos[1][4]
+ keep32flat = getSectionsList(info32flat[0], infos[2][3]), infos[2][4]
+ return keep16, keep32seg, keep32flat
######################################################################
@@ -331,7 +358,7 @@ def gc(info16, info32seg, info32flat):
def parseObjDump(file):
# sections = [(size, align, section), ...]
sections = []
- # symbols[symbol] = section
+ # symbols[symbol] = (addr, section)
symbols = {}
# relocs[section] = [symbol, ...]
relocs = {}
@@ -361,8 +388,8 @@ def parseObjDump(file):
continue
if state == 'symbol':
try:
- section, off, symbol = line[17:].split()
- off = int(off, 16)
+ section, size, symbol = line[17:].split()
+ size = int(size, 16)
addr = int(line[:8], 16)
symbols[symbol] = addr, section
except:
@@ -381,19 +408,29 @@ def main():
# Get output name
in16, in32seg, in32flat, out16, out32seg, out32flat = sys.argv[1:]
+ # Read in the objdump information
infile16 = open(in16, 'rb')
infile32seg = open(in32seg, 'rb')
infile32flat = open(in32flat, 'rb')
+ # infoX = (sections, symbols, relocs)
info16 = parseObjDump(infile16)
info32seg = parseObjDump(infile32seg)
info32flat = parseObjDump(infile32flat)
- sections16, sections32seg, sections32flat = gc(info16, info32seg, info32flat)
+ # Figure out which sections to keep.
+ # keepX = (sections, xrefs)
+ keep16, keep32seg, keep32flat = gc(info16, info32seg, info32flat)
+
+ # Determine the final memory locations of each kept section.
+ # locsX = [(addr, sectioninfo), ...]
+ locs16, locs32seg, locs32flat = doLayout(
+ keep16[0], keep32seg[0], keep32flat[0])
- start16 = doLayout16(sections16, out16)
- start32seg = doLayout32seg(sections32seg, out32seg, start16)
- doLayout32flat(sections32flat, out32flat, start32seg)
+ # Write out linker script files.
+ writeLinkerScripts(locs16, locs32seg, locs32flat
+ , keep16[1], keep32seg[1], keep32flat[1]
+ , out16, out32seg, out32flat)
if __name__ == '__main__':
main()