+######################################################################
+# 32bit section outputting
+######################################################################
+
+def outsections(file, sections, prefix):
+ lp = len(prefix)
+ for size, align, name in sections:
+ if name[:lp] == prefix:
+ file.write("*(%s)\n" % (name,))
+
+def doLayout32(sections, outname):
+ output = open(outname, 'wb')
+ outsections(output, sections, '.text.')
+ output.write("code32_rodata = . ;\n")
+ outsections(output, sections, '.rodata')
+ outsections(output, sections, '.data.')
+ outsections(output, sections, '.bss.')
+
+
+######################################################################
+# Section garbage collection
+######################################################################
+
+def keepsection(name, pri, alt):
+ if name in pri[3]:
+ # Already kept - nothing to do.
+ return
+ pri[3].append(name)
+ relocs = pri[2].get(name)
+ if relocs is None:
+ return
+ # Keep all sections that this section points to
+ for symbol in relocs:
+ section = pri[1].get(symbol)
+ if section is not None and section[:9] != '.discard.':
+ keepsection(section, pri, alt)
+ continue
+ # Not in primary sections - it may be a cross 16/32 reference
+ section = alt[1].get(symbol)
+ if section is not None:
+ keepsection(section, alt, pri)
+
+def gc(info16, info32):
+ # pri = (sections, symbols, relocs, keep sections)
+ pri = (info16[0], info16[1], info16[2], [])
+ alt = (info32[0], info32[1], info32[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, pri, alt)
+ # Return sections found.
+ sections16 = []
+ for info in info16[0]:
+ size, align, section = info
+ if section not in pri[3]:
+# print "gc16", section
+ continue
+ sections16.append(info)
+ sections32 = []
+ for info in info32[0]:
+ size, align, section = info
+ if section not in alt[3]:
+# print "gc32", section
+ continue
+ sections32.append(info)
+ return sections16, sections32
+
+
+######################################################################
+# Startup and input parsing
+######################################################################
+
+# Read in output from objdump
+def parseObjDump(file):
+ # sections = [(size, align, section), ...]
+ sections = []
+ # symbols[symbol] = section
+ symbols = {}
+ # relocs[section] = [symbol, ...]
+ relocs = {}
+
+ state = None
+ for line in file.readlines():
+ line = line.rstrip()
+ if line == 'Sections:':
+ state = 'section'
+ continue
+ if line == 'SYMBOL TABLE:':
+ state = 'symbol'
+ continue
+ if line[:24] == 'RELOCATION RECORDS FOR [':
+ state = 'reloc'
+ relocsection = line[24:-2]
+ continue
+
+ if state == 'section':
+ try:
+ 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:
+ pass
+ continue
+ if state == 'symbol':
+ try:
+ section, off, symbol = line[17:].split()
+ off = int(off, 16)
+ if '*' not in section:
+ symbols[symbol] = section
+ except:
+ pass
+ continue
+ if state == 'reloc':
+ try:
+ off, type, symbol = line.split()
+ off = int(off, 16)
+ relocs.setdefault(relocsection, []).append(symbol)
+ except:
+ pass
+ return sections, symbols, relocs
+
+def main():
+ # Get output name
+ in16, in32, out16, out32 = sys.argv[1:]
+
+ infile16 = open(in16, 'rb')
+ infile32 = open(in32, 'rb')
+
+ info16 = parseObjDump(infile16)
+ info32 = parseObjDump(infile32)
+
+ sections16, sections32 = gc(info16, info32)
+
+ doLayout16(sections16, out16)
+ doLayout32(sections32, out32)
+