-# Layout the 32bit code. This places the code as high as possible.
-def doLayout32(sections, outname, start16):
- start16 += 0xf0000
- # Find sections to output
- textsections = getSectionsPrefix(sections, '.text.')
- rodatasections = getSectionsPrefix(sections, '.rodata')
- datasections = getSectionsPrefix(sections, '.data.')
- bsssections = getSectionsPrefix(sections, '.bss.')
- start32 = getSectionsStart(
- textsections + rodatasections + datasections + bsssections, start16, 512)
-
- # Write sections
- output = open(outname, 'wb')
- output.write(COMMONHEADER + """
- .text32 0x%x : {
- code32_start = ABSOLUTE(.) ;
-""" % start32)
-
- outSections(output, textsections)
- output.write("code32_rodata = . ;\n")
- outSections(output, rodatasections)
- outSections(output, datasections)
- outSections(output, bsssections)
-
- output.write("""
- freespace_start = . ;
- code32_end = ABSOLUTE(.) ;
- }
-""" + COMMONTRAILER)
+# 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()
+
+
+######################################################################
+# Detection of init code
+######################################################################
+
+# Determine init section relocations
+def genRelocs(sections):
+ absrelocs = []
+ relrelocs = []
+ initrelocs = []
+ minalign = 16
+ for section in sections:
+ if section.category == '32init' and section.align > minalign:
+ minalign = section.align
+ for reloc in section.relocs:
+ symbol = reloc.symbol
+ if symbol.section is None:
+ continue
+ relocpos = section.finalloc + reloc.offset
+ if (reloc.type == 'R_386_32' and section.category == '32init'
+ and symbol.section.category == '32init'):
+ # Absolute relocation
+ absrelocs.append(relocpos)
+ elif (reloc.type == 'R_386_PC32' and section.category == '32init'
+ and symbol.section.category != '32init'):
+ # Relative relocation
+ relrelocs.append(relocpos)
+ elif (section.category != '32init'
+ and symbol.section.category == '32init'):
+ # Relocation to the init section
+ if section.fileid in ('16', '32seg'):
+ relocpos += BUILD_BIOS_ADDR
+ initrelocs.append(relocpos)
+ absrelocs.sort()
+ relrelocs.sort()
+ initrelocs.sort()
+ out = (" _reloc_abs_start = ABSOLUTE(.) ;\n"
+ + "".join(["LONG(0x%x - code32init_start)\n" % (pos,)
+ for pos in absrelocs])
+ + " _reloc_abs_end = ABSOLUTE(.) ;\n"
+ + " _reloc_rel_start = ABSOLUTE(.) ;\n"
+ + "".join(["LONG(0x%x - code32init_start)\n" % (pos,)
+ for pos in relrelocs])
+ + " _reloc_rel_end = ABSOLUTE(.) ;\n"
+ + " _reloc_init_start = ABSOLUTE(.) ;\n"
+ + "".join(["LONG(0x%x - code32flat_start)\n" % (pos,)
+ for pos in initrelocs])
+ + " _reloc_init_end = ABSOLUTE(.) ;\n")
+ return out, len(absrelocs + relrelocs + initrelocs) * 4, minalign
+
+def markRuntime(section, sections):
+ if (section is None or not section.keep or section.category is not None
+ or '.init.' in section.name or section.fileid != '32flat'):
+ return
+ section.category = '32flat'
+ # Recursively mark all sections this section points to
+ for reloc in section.relocs:
+ markRuntime(reloc.symbol.section, sections)
+
+def findInit(sections):
+ # Recursively find and mark all "runtime" sections.
+ for section in sections:
+ if '.runtime.' in section.name or '.export.' in section.name:
+ markRuntime(section, sections)
+ for section in sections:
+ if section.category is not None:
+ continue
+ if section.fileid == '32flat':
+ section.category = '32init'
+ else:
+ section.category = section.fileid