X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=tools%2Flayoutrom.py;h=45738a3bb5cf3306b7f0eeee6d233835d8e3ccd6;hb=refs%2Fheads%2Fcoreboot;hp=7603f3830186b405f76cf10ae0e105ff326ee4cd;hpb=6c2e7815858c7835da3de04241facf79db292fbb;p=seabios.git diff --git a/tools/layoutrom.py b/tools/layoutrom.py index 7603f38..45738a3 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Script to analyze code and arrange ld sections. # -# Copyright (C) 2008 Kevin O'Connor +# Copyright (C) 2008-2010 Kevin O'Connor # # This file may be distributed under the terms of the GNU GPLv3 license. @@ -40,30 +40,21 @@ def alignpos(pos, alignbytes): # Determine the final addresses for a list of sections that end at an # address. -def getSectionsStart(sections, endaddr, minalign=1): +def setSectionsStart(sections, endaddr, minalign=1): totspace = 0 - for size, align, name in sections: - if align > minalign: - minalign = align - totspace = alignpos(totspace, align) + size + for section in sections: + if section.align > minalign: + minalign = section.align + totspace = alignpos(totspace, section.align) + section.size 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 - -# Return the subset of sections with a given name prefix -def getSectionsPrefix(sections, prefix): - out = [] - for size, align, name in sections: - if name.startswith(prefix): - out.append((size, align, name)) - return out + for section in sections: + curaddr = alignpos(curaddr, section.align) + section.finalloc = curaddr + curaddr += section.size + return startaddr # The 16bit code can't exceed 64K of space. BUILD_BIOS_ADDR = 0xf0000 @@ -73,22 +64,22 @@ BUILD_BIOS_SIZE = 0x10000 # requirements are placed in the correct location. It also places the # 16bit code as high as possible in the f-segment. def fitSections(sections, fillsections): - canrelocate = list(fillsections) - # fixedsections = [(addr, sectioninfo), ...] + # fixedsections = [(addr, section), ...] fixedsections = [] - for sectioninfo in sections: - size, align, name = sectioninfo - if name.startswith('.fixedaddr.'): - addr = int(name[11:], 16) - fixedsections.append((addr, sectioninfo)) - if align != 1: + for section in sections: + if section.name.startswith('.fixedaddr.'): + addr = int(section.name[11:], 16) + section.finalloc = addr + fixedsections.append((addr, section)) + if section.align != 1: print "Error: Fixed section %s has non-zero alignment (%d)" % ( - name, align) + section.name, section.align) sys.exit(1) + fixedsections.sort() + firstfixed = fixedsections[0][0] # Find freespace in fixed address area - fixedsections.sort() - # fixedAddr = [(freespace, sectioninfo), ...] + # fixedAddr = [(freespace, section), ...] fixedAddr = [] for i in range(len(fixedsections)): fixedsectioninfo = fixedsections[i] @@ -97,31 +88,31 @@ def fitSections(sections, fillsections): nextaddr = BUILD_BIOS_SIZE else: nextaddr = fixedsections[i+1][0] - avail = nextaddr - addr - section[0] - fixedAddr.append((avail, fixedsectioninfo)) + avail = nextaddr - addr - section.size + fixedAddr.append((avail, section)) + fixedAddr.sort() # Attempt to fit other sections into fixed area - extrasections = [] - fixedAddr.sort() + canrelocate = [(section.size, section.align, section.name, section) + for section in fillsections] canrelocate.sort() + canrelocate = [section for size, align, name, section in canrelocate] totalused = 0 - for freespace, fixedsectioninfo in fixedAddr: - fixedaddr, fixedsection = fixedsectioninfo - addpos = fixedaddr + fixedsection[0] - totalused += fixedsection[0] + for freespace, fixedsection in fixedAddr: + addpos = fixedsection.finalloc + fixedsection.size + totalused += fixedsection.size nextfixedaddr = addpos + freespace # print "Filling section %x uses %d, next=%x, available=%d" % ( -# fixedaddr, fixedsection[0], nextfixedaddr, freespace) +# fixedsection.finalloc, fixedsection.size, nextfixedaddr, freespace) while 1: canfit = None for fitsection in canrelocate: - fitsize, fitalign, fitname = fitsection - if addpos + fitsize > nextfixedaddr: + if addpos + fitsection.size > nextfixedaddr: # Can't fit and nothing else will fit. break - fitnextaddr = alignpos(addpos, fitalign) + fitsize + fitnextaddr = alignpos(addpos, fitsection.align) + fitsection.size # print "Test %s - %x vs %x" % ( -# fitname, fitnextaddr, nextfixedaddr) +# fitsection.name, fitnextaddr, nextfixedaddr) if fitnextaddr > nextfixedaddr: # This item can't fit. continue @@ -131,13 +122,12 @@ def fitSections(sections, fillsections): # Found a section that can fit. fitnextaddr, fitsection = canfit canrelocate.remove(fitsection) - extrasections.append((addpos, fitsection)) + fitsection.finalloc = addpos addpos = fitnextaddr - totalused += fitsection[0] + totalused += fitsection.size # print " Adding %s (size %d align %d) pos=%x avail=%d" % ( # fitsection[2], fitsection[0], fitsection[1] # , fitnextaddr, nextfixedaddr - fitnextaddr) - firstfixed = fixedsections[0][0] # Report stats total = BUILD_BIOS_SIZE-firstfixed @@ -147,52 +137,64 @@ def fitSections(sections, fillsections): firstfixed, BUILD_BIOS_SIZE, total, slack, (float(slack) / total) * 100.0)) - return fixedsections + extrasections, firstfixed + return firstfixed -def doLayout(sections16, sections32seg, sections32flat): +# Return the subset of sections with a given name prefix +def getSectionsPrefix(sections, category, prefix): + return [section for section in sections + if section.category == category and section.name.startswith(prefix)] + +def doLayout(sections): # 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() + textsections = getSectionsPrefix(sections, '16', '.text.') + rodatasections = (getSectionsPrefix(sections, '16', '.rodata.str1.1') + + getSectionsPrefix(sections, '16', '.rodata.__func__.')) + datasections = getSectionsPrefix(sections, '16', '.data16.') + fixedsections = getSectionsPrefix(sections, '16', '.fixedaddr.') + + firstfixed = fitSections(fixedsections, textsections) + remsections = [s for s in textsections+rodatasections+datasections + if s.finalloc is None] + code16_start = setSectionsStart(remsections, firstfixed) # Determine 32seg positions - textsections = getSectionsPrefix(sections32seg, '.text.') - rodatasections = (getSectionsPrefix(sections32seg, '.rodata.str1.1') - + getSectionsPrefix(sections32seg, '.rodata.__func__.')) - datasections = getSectionsPrefix(sections32seg, '.data32seg.') + textsections = getSectionsPrefix(sections, '32seg', '.text.') + rodatasections = (getSectionsPrefix(sections, '32seg', '.rodata.str1.1') + +getSectionsPrefix(sections, '32seg', '.rodata.__func__.')) + datasections = getSectionsPrefix(sections, '32seg', '.data32seg.') - locs32seg, code32seg_start = getSectionsStart( + code32seg_start = setSectionsStart( textsections + rodatasections + datasections, code16_start) - # Determine 32flat positions - textsections = getSectionsPrefix(sections32flat, '.text.') - rodatasections = getSectionsPrefix(sections32flat, '.rodata') - datasections = getSectionsPrefix(sections32flat, '.data.') - bsssections = getSectionsPrefix(sections32flat, '.bss.') + # Determine 32flat runtime positions + textsections = getSectionsPrefix(sections, '32flat', '.text.') + rodatasections = getSectionsPrefix(sections, '32flat', '.rodata') + datasections = getSectionsPrefix(sections, '32flat', '.data.') + bsssections = getSectionsPrefix(sections, '32flat', '.bss.') - locs32flat, code32flat_start = getSectionsStart( + code32flat_start = setSectionsStart( textsections + rodatasections + datasections + bsssections , code32seg_start + BUILD_BIOS_ADDR, 16) + # Determine 32flat init positions + textsections = getSectionsPrefix(sections, '32init', '.text.') + rodatasections = getSectionsPrefix(sections, '32init', '.rodata') + datasections = getSectionsPrefix(sections, '32init', '.data.') + bsssections = getSectionsPrefix(sections, '32init', '.bss.') + + code32init_start = setSectionsStart( + textsections + rodatasections + datasections + bsssections + , code32flat_start, 16) + # Print statistics size16 = BUILD_BIOS_SIZE - code16_start size32seg = code16_start - code32seg_start size32flat = code32seg_start + BUILD_BIOS_ADDR - code32flat_start + size32init = code32flat_start - code32init_start print "16bit size: %d" % size16 print "32bit segmented size: %d" % size32seg print "32bit flat size: %d" % size32flat - - return locs16, locs32seg, locs32flat + print "32bit flat init size: %d" % size32init ###################################################################### @@ -200,44 +202,55 @@ def doLayout(sections16, sections32seg, sections32flat): ###################################################################### # Write LD script includes for the given cross references -def outXRefs(xrefs, finallocs, delta=0): +def outXRefs(sections): + xrefs = {} out = "" - for symbol, (fileid, section, addr) in xrefs.items(): - if fileid < 2: - addr += delta - out += "%s = 0x%x ;\n" % (symbol, finallocs[(fileid, section)] + addr) + 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(locs, startsym): +def outRelSections(sections, startsym): out = "" - for addr, sectioninfo in locs: - size, align, name = sectioninfo - out += ". = ( 0x%x - %s ) ;\n" % (addr, startsym) - if name == '.rodata.str1.1': + for section in sections: + out += ". = ( 0x%x - %s ) ;\n" % (section.finalloc, startsym) + if section.name == '.rodata.str1.1': out += "_rodata = . ;\n" - out += "*(%s)\n" % (name,) + out += "*(%s)\n" % (section.name,) return out -# Layout the 32bit segmented code. This places the code as high as possible. -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 +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 - code16_start = locs16[0][0] + sections16, code16_start = getSectionsFile(sections, '16') output = open(out16, 'wb') - output.write(COMMONHEADER + outXRefs(xref16, finallocs) + """ + output.write(COMMONHEADER + outXRefs(sections16) + """ code16_start = 0x%x ; .text16 code16_start : { """ % (code16_start) - + outRelSections(locs16, 'code16_start') + + outRelSections(sections16, 'code16_start') + """ } """ @@ -245,15 +258,14 @@ def writeLinkerScripts(locs16, locs32seg, locs32flat output.close() # Write 32seg linker script - code32seg_start = code16_start - if locs32seg: - code32seg_start = locs32seg[0][0] + sections32seg, code32seg_start = getSectionsFile( + sections, '32seg', code16_start) output = open(out32seg, 'wb') - output.write(COMMONHEADER + outXRefs(xref32seg, finallocs) + """ + output.write(COMMONHEADER + outXRefs(sections32seg) + """ code32seg_start = 0x%x ; .text32seg code32seg_start : { """ % (code32seg_start) - + outRelSections(locs32seg, 'code32seg_start') + + outRelSections(sections32seg, 'code32seg_start') + """ } """ @@ -261,13 +273,35 @@ def writeLinkerScripts(locs16, locs32seg, locs32flat 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(xref32flat, finallocs, BUILD_BIOS_ADDR) + """ + + outXRefs(sections32flat) + """ + %s = 0x%x ; + _reloc_min_align = 0x%x ; code32flat_start = 0x%x ; .text code32flat_start : { -""" % (locs32flat[0][0]) - + outRelSections(locs32flat, '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) @@ -278,89 +312,171 @@ def writeLinkerScripts(locs16, locs32seg, locs32flat """ % (code32seg_start + BUILD_BIOS_ADDR, code16_start + BUILD_BIOS_ADDR) + COMMONTRAILER + """ -ENTRY(post32) +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 + + ###################################################################### # Section garbage collection ###################################################################### +CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)] + # Find and keep the section associated with a symbol (if available). -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.startswith('.discard.'): +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 - 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) + 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 # Note required section, and recursively set all referenced sections # as required. -def keepsection(name, infos, pos=0): - if name in infos[pos][3]: +def keepsection(section, infos, pos=0): + if section.keep: # Already kept - nothing to do. return - infos[pos][3].append(name) - relocs = infos[pos][2].get(name) - if relocs is None: - return + section.keep = 1 # Keep all sections that this section points to - for symbol in relocs: - ret = keepsymbol(symbol, infos, pos) + for reloc in section.relocs: + ret = keepsymbol(reloc, 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, pos) + ret = keepsymbol(reloc, infos, (pos+1)%3, 1) if not ret: continue - ret = keepsymbol(symbol, infos, (pos+2)%3, pos) + ret = keepsymbol(reloc, infos, (pos+2)%3, 1) 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, xrefs), ...) - infos = ((info16[0], info16[1], info16[2], [], {}), - (info32seg[0], info32seg[1], info32seg[2], [], {}), - (info32flat[0], info32flat[1], info32flat[2], [], {})) + # infos = ((sections16, symbols16), (sect32seg, sym32seg) + # , (sect32flat, sym32flat)) + infos = (info16, info32seg, info32flat) # Start by keeping sections that are globally visible. - for size, align, section in info16[0]: - if section.startswith('.fixedaddr.') or '.export.' in section: + for section in info16[0]: + if section.name.startswith('.fixedaddr.') or '.export.' in section.name: keepsection(section, infos) - keepsymbol('post32', infos, 0, 2) - # Return sections found. - 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 + return [section for section in info16[0]+info32seg[0]+info32flat[0] + if section.keep] ###################################################################### # Startup and input parsing ###################################################################### +class Section: + name = size = alignment = fileid = relocs = None + finalloc = category = keep = None +class Reloc: + offset = type = symbolname = symbol = None +class Symbol: + name = offset = section = None + # Read in output from objdump -def parseObjDump(file): - # sections = [(size, align, section), ...] +def parseObjDump(file, fileid): + # sections = [section, ...] sections = [] - # symbols[symbol] = (addr, section) + sectionmap = {} + # symbols[symbolname] = symbol symbols = {} - # relocs[section] = [symbol, ...] - relocs = {} state = None for line in file.readlines(): @@ -372,8 +488,13 @@ def parseObjDump(file): state = 'symbol' continue if line.startswith('RELOCATION RECORDS FOR ['): + sectionname = line[24:-2] + if sectionname.startswith('.debug_'): + # Skip debugging sections (to reduce parsing time) + state = None + continue state = 'reloc' - relocsection = line[24:-2] + relocsection = sectionmap[sectionname] continue if state == 'section': @@ -381,27 +502,50 @@ def parseObjDump(file): idx, name, size, vma, lma, fileoff, align = line.split() if align[:3] != '2**': continue - sections.append((int(size, 16), 2**int(align[3:]), name)) - except: + section = Section() + section.name = name + section.size = int(size, 16) + section.align = 2**int(align[3:]) + section.fileid = fileid + section.relocs = [] + sections.append(section) + sectionmap[name] = section + except ValueError: pass continue if state == 'symbol': try: - section, size, symbol = line[17:].split() - size = int(size, 16) - addr = int(line[:8], 16) - symbols[symbol] = addr, section - except: + sectionname, size, name = line[17:].split() + symbol = Symbol() + symbol.size = int(size, 16) + symbol.offset = int(line[:8], 16) + symbol.name = name + symbol.section = sectionmap.get(sectionname) + symbols[name] = symbol + except ValueError: pass continue if state == 'reloc': try: - off, type, symbol = line.split() - off = int(off, 16) - relocs.setdefault(relocsection, []).append(symbol) - except: + off, type, symbolname = line.split() + reloc = Reloc() + reloc.offset = int(off, 16) + reloc.type = type + 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 - return sections, symbols, relocs + return sections, symbols def main(): # Get output name @@ -412,24 +556,24 @@ def main(): infile32seg = open(in32seg, 'rb') infile32flat = open(in32flat, 'rb') - # infoX = (sections, symbols, relocs) - info16 = parseObjDump(infile16) - info32seg = parseObjDump(infile32seg) - info32flat = parseObjDump(infile32flat) + # infoX = (sections, symbols) + info16 = parseObjDump(infile16, '16') + info32seg = parseObjDump(infile32seg, '32seg') + info32flat = parseObjDump(infile32flat, '32flat') # Figure out which sections to keep. - # keepX = (sections, xrefs) - keep16, keep32seg, keep32flat = gc(info16, info32seg, info32flat) + sections = gc(info16, info32seg, info32flat) + + # Separate 32bit flat into runtime and init parts + findInit(sections) # Determine the final memory locations of each kept section. - # locsX = [(addr, sectioninfo), ...] - locs16, locs32seg, locs32flat = doLayout( - keep16[0], keep32seg[0], keep32flat[0]) + doLayout(sections) # Write out linker script files. - writeLinkerScripts(locs16, locs32seg, locs32flat - , keep16[1], keep32seg[1], keep32flat[1] - , 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()