for reloc in section.relocs:
symbol = reloc.symbol
if (symbol.section is None
- or symbol.section.fileid == section.fileid
- or symbol.name in xrefs):
+ or (symbol.section.fileid == section.fileid
+ and symbol.name == reloc.symbolname)
+ or reloc.symbolname in xrefs):
continue
- xrefs[symbol.name] = 1
+ 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" % (symbol.name, addr)
+ out += "%s = 0x%x ;\n" % (reloc.symbolname, addr)
return out
# Write LD script includes for the given sections using relative offsets
return sections, pos
# Layout the 32bit segmented code. This places the code as high as possible.
-def writeLinkerScripts(sections, entrysym, out16, out32seg, out32flat):
+def writeLinkerScripts(sections, entrysym, genreloc, out16, out32seg, out32flat):
# Write 16bit linker script
sections16, code16_start = getSectionsFile(sections, '16')
output = open(out16, 'wb')
# 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,
- code32flat_start)
+ relocminalign, code32flat_start)
+ + relocstr
+ + """
+ code32init_start = ABSOLUTE(.) ;
+"""
+ outRelSections(getSectionsPrefix(sections32flat, '32init', '')
, 'code32flat_start')
+ """
# 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'):
# Section garbage collection
######################################################################
+CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)]
+
# Find and keep the section associated with a symbol (if available).
-def keepsymbol(reloc, infos, pos):
- symbolname = reloc.symbol.name
+def keepsymbol(reloc, infos, pos, isxref):
+ symbolname = reloc.symbolname
+ mustbecfunc = 0
+ for symprefix, needpos in CFUNCPREFIX:
+ if symbolname.startswith(symprefix):
+ if needpos != pos:
+ return -1
+ symbolname = symbolname[len(symprefix):]
+ mustbecfunc = 1
+ break
symbol = infos[pos][1].get(symbolname)
if (symbol is None or symbol.section is None
or symbol.section.name.startswith('.discard.')):
return -1
+ isdestcfunc = (symbol.section.name.startswith('.text.')
+ and not symbol.section.name.startswith('.text.asm.'))
+ if ((mustbecfunc and not isdestcfunc)
+ or (not mustbecfunc and isdestcfunc and isxref)):
+ return -1
+
reloc.symbol = symbol
keepsection(symbol.section, infos, pos)
return 0
section.keep = 1
# Keep all sections that this section points to
for reloc in section.relocs:
- ret = keepsymbol(reloc, infos, pos)
+ ret = keepsymbol(reloc, infos, pos, 0)
if not ret:
continue
# Not in primary sections - it may be a cross 16/32 reference
- ret = keepsymbol(reloc, infos, (pos+1)%3)
+ ret = keepsymbol(reloc, infos, (pos+1)%3, 1)
if not ret:
continue
- ret = keepsymbol(reloc, infos, (pos+2)%3)
+ ret = keepsymbol(reloc, infos, (pos+2)%3, 1)
if not ret:
continue
name = size = alignment = fileid = relocs = None
finalloc = category = keep = None
class Reloc:
- offset = type = symbol = None
+ offset = type = symbolname = symbol = None
class Symbol:
name = offset = section = None
reloc = Reloc()
reloc.offset = int(off, 16)
reloc.type = type
- reloc.symbol = symbols[symbolname]
+ reloc.symbolname = symbolname
+ reloc.symbol = symbols.get(symbolname)
+ if reloc.symbol is None:
+ # Some binutils (2.20.1) give section name instead
+ # of a symbol - create a dummy symbol.
+ reloc.symbol = symbol = Symbol()
+ symbol.size = 0
+ symbol.offset = 0
+ symbol.name = symbolname
+ symbol.section = sectionmap.get(symbolname)
+ symbols[symbolname] = symbol
relocsection.relocs.append(reloc)
except ValueError:
pass
findInit(sections)
# Determine the final memory locations of each kept section.
- # locsX = [(addr, sectioninfo), ...]
doLayout(sections)
# Write out linker script files.
- entrysym = info16[1]['post32']
- writeLinkerScripts(sections, entrysym, out16, out32seg, out32flat)
+ entrysym = info16[1]['entry_elf']
+ genreloc = '_reloc_abs_start' in info32flat[1]
+ writeLinkerScripts(sections, entrysym, genreloc, out16, out32seg, out32flat)
if __name__ == '__main__':
main()