+# Write LD script includes for the given cross references
+def outXRefs(sections):
+ xrefs = {}
+ out = ""
+ for section in sections:
+ for reloc in section.relocs:
+ symbol = reloc.symbol
+ if (symbol.section is None
+ or (symbol.section.fileid == section.fileid
+ and symbol.name == reloc.symbolname)
+ or reloc.symbolname in xrefs):
+ continue
+ xrefs[reloc.symbolname] = 1
+ addr = symbol.section.finalloc + symbol.offset
+ if (section.fileid == '32flat'
+ and symbol.section.fileid in ('16', '32seg')):
+ addr += BUILD_BIOS_ADDR
+ out += "%s = 0x%x ;\n" % (reloc.symbolname, addr)
+ return out
+
+# Write LD script includes for the given sections using relative offsets
+def outRelSections(sections, startsym):
+ out = ""
+ for section in sections:
+ out += ". = ( 0x%x - %s ) ;\n" % (section.finalloc, startsym)
+ if section.name == '.rodata.str1.1':
+ out += "_rodata = . ;\n"
+ out += "*(%s)\n" % (section.name,)
+ return out
+
+def getSectionsFile(sections, fileid, defaddr=0):
+ sections = [(section.finalloc, section)
+ for section in sections if section.fileid == fileid]
+ sections.sort()
+ sections = [section for addr, section in sections]
+ pos = defaddr
+ if sections:
+ pos = sections[0].finalloc
+ return sections, pos
+
+# Layout the 32bit segmented code. This places the code as high as possible.
+def writeLinkerScripts(sections, entrysym, genreloc, out16, out32seg, out32flat):
+ # Write 16bit linker script
+ sections16, code16_start = getSectionsFile(sections, '16')
+ output = open(out16, 'wb')
+ output.write(COMMONHEADER + outXRefs(sections16) + """
+ code16_start = 0x%x ;
+ .text16 code16_start : {
+""" % (code16_start)
+ + outRelSections(sections16, 'code16_start')
+ + """
+ }
+"""
+ + COMMONTRAILER)
+ output.close()
+
+ # Write 32seg linker script
+ sections32seg, code32seg_start = getSectionsFile(
+ sections, '32seg', code16_start)
+ output = open(out32seg, 'wb')
+ output.write(COMMONHEADER + outXRefs(sections32seg) + """
+ code32seg_start = 0x%x ;
+ .text32seg code32seg_start : {
+""" % (code32seg_start)
+ + outRelSections(sections32seg, 'code32seg_start')
+ + """
+ }
+"""
+ + COMMONTRAILER)
+ output.close()
+
+ # Write 32flat linker script
+ sections32flat, code32flat_start = getSectionsFile(
+ sections, '32flat', code32seg_start)
+ relocstr = ""
+ relocminalign = 0
+ if genreloc:
+ # Generate relocations
+ relocstr, size, relocminalign = genRelocs(sections)
+ code32flat_start -= size
+ output = open(out32flat, 'wb')
+ output.write(COMMONHEADER
+ + outXRefs(sections32flat) + """
+ %s = 0x%x ;
+ _reloc_min_align = 0x%x ;
+ code32flat_start = 0x%x ;
+ .text code32flat_start : {
+""" % (entrysym.name,
+ entrysym.section.finalloc + entrysym.offset + BUILD_BIOS_ADDR,
+ relocminalign, code32flat_start)
+ + relocstr
+ + """
+ code32init_start = ABSOLUTE(.) ;
+"""
+ + outRelSections(getSectionsPrefix(sections32flat, '32init', '')
+ , 'code32flat_start')
+ + """
+ code32init_end = ABSOLUTE(.) ;
+"""
+ + outRelSections(getSectionsPrefix(sections32flat, '32flat', '')
+ , '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(%s)
+PHDRS
+{
+ text PT_LOAD AT ( code32flat_start ) ;
+}
+""" % (entrysym.name,))
+ output.close()