summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/seabios/scripts')
-rwxr-xr-xqemu/roms/seabios/scripts/buildversion.py134
-rwxr-xr-xqemu/roms/seabios/scripts/buildversion.sh31
-rwxr-xr-xqemu/roms/seabios/scripts/checkrom.py2
-rwxr-xr-xqemu/roms/seabios/scripts/checkstack.py270
-rw-r--r--qemu/roms/seabios/scripts/kconfig/lxdialog/util.c2
-rwxr-xr-xqemu/roms/seabios/scripts/layoutrom.py8
6 files changed, 276 insertions, 171 deletions
diff --git a/qemu/roms/seabios/scripts/buildversion.py b/qemu/roms/seabios/scripts/buildversion.py
new file mode 100755
index 000000000..46928984e
--- /dev/null
+++ b/qemu/roms/seabios/scripts/buildversion.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+# Generate version information for a program
+#
+# Copyright (C) 2015 Kevin O'Connor <kevin@koconnor.net>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+import sys, os, subprocess, shlex, time, socket, optparse, logging, traceback
+
+VERSION_FORMAT = """
+/* DO NOT EDIT! This is an autogenerated file. See scripts/buildversion.py. */
+#define BUILD_VERSION "%s"
+#define BUILD_TOOLS "%s"
+"""
+
+# Run program and return the specified output
+def check_output(prog):
+ logging.debug("Running %s" % (repr(prog),))
+ try:
+ process = subprocess.Popen(shlex.split(prog), stdout=subprocess.PIPE)
+ output = process.communicate()[0]
+ retcode = process.poll()
+ except OSError:
+ logging.debug("Exception on run: %s" % (traceback.format_exc(),))
+ return ""
+ logging.debug("Got (code=%s): %s" % (retcode, repr(output)))
+ if retcode:
+ return ""
+ try:
+ return output.decode()
+ except UnicodeError:
+ logging.debug("Exception on decode: %s" % (traceback.format_exc(),))
+ return ""
+
+# Obtain version info from "git" program
+def git_version():
+ if not os.path.exists('.git'):
+ logging.debug("No '.git' file/directory found")
+ return ""
+ ver = check_output("git describe --tags --long --dirty").strip()
+ logging.debug("Got git version: %s" % (repr(ver),))
+ return ver
+
+# Look for version in a ".version" file. Official release tarballs
+# have this file (see scripts/tarball.sh).
+def file_version():
+ if not os.path.isfile('.version'):
+ logging.debug("No '.version' file found")
+ return ""
+ try:
+ f = open('.version', 'r')
+ ver = f.readline().strip()
+ f.close()
+ except OSError:
+ logging.debug("Exception on read: %s" % (traceback.format_exc(),))
+ return ""
+ logging.debug("Got .version: %s" % (repr(ver),))
+ return ver
+
+# Generate an output file with the version information
+def write_version(outfile, version, toolstr):
+ logging.debug("Write file %s and %s" % (repr(version), repr(toolstr)))
+ sys.stdout.write("Version: %s\n" % (version,))
+ f = open(outfile, 'w')
+ f.write(VERSION_FORMAT % (version, toolstr))
+ f.close()
+
+# Run "tool --version" for each specified tool and extract versions
+def tool_versions(tools):
+ tools = [t.strip() for t in tools.split(';')]
+ versions = ['', '']
+ success = 0
+ for tool in tools:
+ # Extract first line from "tool --version" output
+ verstr = check_output("%s --version" % (tool,)).split('\n')[0]
+ # Check if this tool looks like a binutils program
+ isbinutils = 0
+ if verstr.startswith('GNU '):
+ isbinutils = 1
+ verstr = verstr[4:]
+ # Extract version information and exclude program name
+ if ' ' not in verstr:
+ continue
+ prog, ver = verstr.split(' ', 1)
+ if not prog or not ver:
+ continue
+ # Check for any version conflicts
+ if versions[isbinutils] and versions[isbinutils] != ver:
+ logging.debug("Mixed version %s vs %s" % (
+ repr(versions[isbinutils]), repr(ver)))
+ versions[isbinutils] = "mixed"
+ continue
+ versions[isbinutils] = ver
+ success += 1
+ cleanbuild = versions[0] and versions[1] and success == len(tools)
+ return cleanbuild, "gcc: %s binutils: %s" % (versions[0], versions[1])
+
+def main():
+ usage = "%prog [options] <outputheader.h>"
+ opts = optparse.OptionParser(usage)
+ opts.add_option("-e", "--extra", dest="extra", default="",
+ help="extra version string to append to version")
+ opts.add_option("-t", "--tools", dest="tools", default="",
+ help="list of build programs to extract version from")
+ opts.add_option("-v", action="store_true", dest="verbose",
+ help="enable debug messages")
+
+ options, args = opts.parse_args()
+ if len(args) != 1:
+ opts.error("Incorrect arguments")
+ outfile = args[0]
+ if options.verbose:
+ logging.basicConfig(level=logging.DEBUG)
+
+ cleanbuild, toolstr = tool_versions(options.tools)
+
+ ver = git_version()
+ cleanbuild = cleanbuild and 'dirty' not in ver
+ if not ver:
+ ver = file_version()
+ # We expect the "extra version" to contain information on the
+ # distributor and distribution package version (if
+ # applicable). It is a "clean" build if this is a build from
+ # an official release tarball and the above info is present.
+ cleanbuild = cleanbuild and ver and options.extra != ""
+ if not ver:
+ ver = "?"
+ if not cleanbuild:
+ btime = time.strftime("%Y%m%d_%H%M%S")
+ hostname = socket.gethostname()
+ ver = "%s-%s-%s" % (ver, btime, hostname)
+ write_version(outfile, ver + options.extra, toolstr)
+
+if __name__ == '__main__':
+ main()
diff --git a/qemu/roms/seabios/scripts/buildversion.sh b/qemu/roms/seabios/scripts/buildversion.sh
deleted file mode 100755
index 516aff5b2..000000000
--- a/qemu/roms/seabios/scripts/buildversion.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-# Script to generate a C file with version information.
-OUTFILE="$1"
-VAR16MODE="$2"
-
-# Extract version info
-if [ -z "$BUILD_VERSION" ]; then
- if [ -d .git -o -f .git ]; then
- VERSION="`git describe --tags --long --dirty`"
- elif [ -f .version ]; then
- VERSION="`cat .version`"
- else
- VERSION="?"
- fi
- VERSION="${VERSION}-`date +"%Y%m%d_%H%M%S"`-`hostname`"
-else
- VERSION="$BUILD_VERSION"
-fi
-echo "Version: ${VERSION}"
-
-# Build header file
-if [ "$VAR16MODE" = "VAR16" ]; then
- cat > ${OUTFILE} <<EOF
-#include "types.h"
-char VERSION[] VAR16 = "${VERSION}";
-EOF
-else
- cat > ${OUTFILE} <<EOF
-char VERSION[] = "${VERSION}";
-EOF
-fi
diff --git a/qemu/roms/seabios/scripts/checkrom.py b/qemu/roms/seabios/scripts/checkrom.py
index 377277db5..aced5e2cf 100755
--- a/qemu/roms/seabios/scripts/checkrom.py
+++ b/qemu/roms/seabios/scripts/checkrom.py
@@ -39,7 +39,7 @@ def main():
finalsize = 256*1024
if datasize > finalsize:
print("Error! ROM doesn't fit (%d > %d)" % (datasize, finalsize))
- print(" You have to either increate the size (CONFIG_ROM_SIZE)")
+ print(" You have to either increase the size (CONFIG_ROM_SIZE)")
print(" or turn off some features (such as hardware support not")
print(" needed) to make it fit. Trying a more recent gcc version")
print(" might work too.")
diff --git a/qemu/roms/seabios/scripts/checkstack.py b/qemu/roms/seabios/scripts/checkstack.py
index b49b6c8cc..5d9b0bfaf 100755
--- a/qemu/roms/seabios/scripts/checkstack.py
+++ b/qemu/roms/seabios/scripts/checkstack.py
@@ -2,7 +2,7 @@
# Script that tries to find how much stack space each function in an
# object is using.
#
-# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+# Copyright (C) 2008-2015 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
@@ -26,85 +26,84 @@ OUTPUTDESC = """
# insn_addr:called_function [u+c,t,usage_to_yield_point]
"""
+class function:
+ def __init__(self, funcaddr, funcname):
+ self.funcaddr = funcaddr
+ self.funcname = funcname
+ self.basic_stack_usage = 0
+ self.max_stack_usage = None
+ self.yield_usage = -1
+ self.max_yield_usage = None
+ self.total_calls = 0
+ # called_funcs = [(insnaddr, calladdr, stackusage), ...]
+ self.called_funcs = []
+ self.subfuncs = {}
+ # Update function info with a found "yield" point.
+ def noteYield(self, stackusage):
+ if self.yield_usage < stackusage:
+ self.yield_usage = stackusage
+ # Update function info with a found "call" point.
+ def noteCall(self, insnaddr, calladdr, stackusage):
+ if (calladdr, stackusage) in self.subfuncs:
+ # Already noted a nearly identical call - ignore this one.
+ return
+ self.called_funcs.append((insnaddr, calladdr, stackusage))
+ self.subfuncs[(calladdr, stackusage)] = 1
+
# Find out maximum stack usage for a function
-def calcmaxstack(funcs, funcaddr):
- info = funcs[funcaddr]
- # Find max of all nested calls.
- maxusage = info[1]
- maxyieldusage = doesyield = 0
- if info[3] is not None:
- maxyieldusage = info[3]
- doesyield = 1
- info[2] = maxusage
- info[4] = info[3]
+def calcmaxstack(info, funcs):
+ if info.max_stack_usage is not None:
+ return
+ info.max_stack_usage = max_stack_usage = info.basic_stack_usage
+ info.max_yield_usage = max_yield_usage = info.yield_usage
+ total_calls = 0
seenbefore = {}
- totcalls = 0
- for insnaddr, calladdr, usage in info[6]:
+ # Find max of all nested calls.
+ for insnaddr, calladdr, usage in info.called_funcs:
callinfo = funcs.get(calladdr)
if callinfo is None:
continue
- if callinfo[2] is None:
- calcmaxstack(funcs, calladdr)
- if callinfo[0] not in seenbefore:
- seenbefore[callinfo[0]] = 1
- totcalls += 1 + callinfo[5]
- funcnameroot = callinfo[0].split('.')[0]
+ calcmaxstack(callinfo, funcs)
+ if callinfo.funcname not in seenbefore:
+ seenbefore[callinfo.funcname] = 1
+ total_calls += callinfo.total_calls + 1
+ funcnameroot = callinfo.funcname.split('.')[0]
if funcnameroot in IGNORE:
# This called function is ignored - don't contribute it to
# the max stack.
continue
+ totusage = usage + callinfo.max_stack_usage
+ totyieldusage = usage + callinfo.max_yield_usage
if funcnameroot in STACKHOP:
- if usage > maxusage:
- maxusage = usage
- if callinfo[4] is not None:
- doesyield = 1
- if usage > maxyieldusage:
- maxyieldusage = usage
- continue
- totusage = usage + callinfo[2]
- if totusage > maxusage:
- maxusage = totusage
- if callinfo[4] is not None:
- doesyield = 1
- totyieldusage = usage + callinfo[4]
- if totyieldusage > maxyieldusage:
- maxyieldusage = totyieldusage
- info[2] = maxusage
- if doesyield:
- info[4] = maxyieldusage
- info[5] = totcalls
+ # Don't count children of this function
+ totusage = totyieldusage = usage
+ if totusage > max_stack_usage:
+ max_stack_usage = totusage
+ if callinfo.max_yield_usage >= 0 and totyieldusage > max_yield_usage:
+ max_yield_usage = totyieldusage
+ info.max_stack_usage = max_stack_usage
+ info.max_yield_usage = max_yield_usage
+ info.total_calls = total_calls
# Try to arrange output so that functions that call each other are
# near each other.
def orderfuncs(funcaddrs, availfuncs):
- l = [(availfuncs[funcaddr][5], availfuncs[funcaddr][0], funcaddr)
+ l = [(availfuncs[funcaddr].total_calls
+ , availfuncs[funcaddr].funcname, funcaddr)
for funcaddr in funcaddrs if funcaddr in availfuncs]
l.sort()
l.reverse()
out = []
while l:
count, name, funcaddr = l.pop(0)
- if funcaddr not in availfuncs:
+ info = availfuncs.get(funcaddr)
+ if info is None:
continue
- calladdrs = [calls[1] for calls in availfuncs[funcaddr][6]]
+ calladdrs = [calls[1] for calls in info.called_funcs]
del availfuncs[funcaddr]
- out = out + orderfuncs(calladdrs, availfuncs) + [funcaddr]
+ out = out + orderfuncs(calladdrs, availfuncs) + [info]
return out
-# Update function info with a found "yield" point.
-def noteYield(info, stackusage):
- prevyield = info[3]
- if prevyield is None or prevyield < stackusage:
- info[3] = stackusage
-
-# Update function info with a found "call" point.
-def noteCall(info, subfuncs, insnaddr, calladdr, stackusage):
- if (calladdr, stackusage) in subfuncs:
- # Already noted a nearly identical call - ignore this one.
- return
- info[6].append((insnaddr, calladdr, stackusage))
- subfuncs[(calladdr, stackusage)] = 1
-
hex_s = r'[0-9a-f]+'
re_func = re.compile(r'^(?P<funcaddr>' + hex_s + r') <(?P<func>.*)>:$')
re_asm = re.compile(
@@ -114,11 +113,12 @@ re_asm = re.compile(
re_usestack = re.compile(
r'^(push[f]?[lw])|(sub.* [$](?P<num>0x' + hex_s + r'),%esp)$')
-def calc():
- # funcs[funcaddr] = [funcname, basicstackusage, maxstackusage
- # , yieldusage, maxyieldusage, totalcalls
- # , [(insnaddr, calladdr, stackusage), ...]]
- funcs = {-1: ['<indirect>', 0, 0, None, None, 0, []]}
+def main():
+ unknownfunc = function(None, "<unknown>")
+ indirectfunc = function(-1, '<indirect>')
+ unknownfunc.max_stack_usage = indirectfunc.max_stack_usage = 0
+ unknownfunc.max_yield_usage = indirectfunc.max_yield_usage = -1
+ funcs = {-1: indirectfunc}
cur = None
atstart = 0
stackusage = 0
@@ -129,99 +129,93 @@ def calc():
if m is not None:
# Found function
funcaddr = int(m.group('funcaddr'), 16)
- funcs[funcaddr] = cur = [m.group('func'), 0, None, None, None, 0, []]
+ funcs[funcaddr] = cur = function(funcaddr, m.group('func'))
stackusage = 0
atstart = 1
- subfuncs = {}
continue
m = re_asm.match(line)
- if m is not None:
- insn = m.group('insn')
-
- im = re_usestack.match(insn)
- if im is not None:
- if insn.startswith('pushl') or insn.startswith('pushfl'):
- stackusage += 4
- continue
- elif insn.startswith('pushw') or insn.startswith('pushfw'):
- stackusage += 2
- continue
- stackusage += int(im.group('num'), 16)
-
- if atstart:
- if '%esp' in insn or insn.startswith('leal'):
- # Still part of initial header
- continue
- cur[1] = stackusage
- atstart = 0
-
- insnaddr = m.group('insnaddr')
- calladdr = m.group('calladdr')
- if calladdr is None:
- if insn.startswith('lcallw'):
- noteCall(cur, subfuncs, insnaddr, -1, stackusage + 4)
- noteYield(cur, stackusage + 4)
- elif insn.startswith('int'):
- noteCall(cur, subfuncs, insnaddr, -1, stackusage + 6)
- noteYield(cur, stackusage + 6)
- elif insn.startswith('sti'):
- noteYield(cur, stackusage)
- else:
- # misc instruction
- continue
+ if m is None:
+ #print("other", repr(line))
+ continue
+ insn = m.group('insn')
+
+ im = re_usestack.match(insn)
+ if im is not None:
+ if insn.startswith('pushl') or insn.startswith('pushfl'):
+ stackusage += 4
+ continue
+ elif insn.startswith('pushw') or insn.startswith('pushfw'):
+ stackusage += 2
+ continue
+ stackusage += int(im.group('num'), 16)
+
+ if atstart:
+ if '%esp' in insn or insn.startswith('leal'):
+ # Still part of initial header
+ continue
+ cur.basic_stack_usage = stackusage
+ atstart = 0
+
+ insnaddr = m.group('insnaddr')
+ calladdr = m.group('calladdr')
+ if calladdr is None:
+ if insn.startswith('lcallw'):
+ cur.noteCall(insnaddr, -1, stackusage + 4)
+ cur.noteYield(stackusage + 4)
+ elif insn.startswith('int'):
+ cur.noteCall(insnaddr, -1, stackusage + 6)
+ cur.noteYield(stackusage + 6)
+ elif insn.startswith('sti'):
+ cur.noteYield(stackusage)
+ else:
+ # misc instruction
+ continue
+ else:
+ # Jump or call insn
+ calladdr = int(calladdr, 16)
+ ref = m.group('ref')
+ if '+' in ref:
+ # Inter-function jump.
+ pass
+ elif insn.startswith('j'):
+ # Tail call
+ cur.noteCall(insnaddr, calladdr, 0)
+ elif insn.startswith('calll'):
+ cur.noteCall(insnaddr, calladdr, stackusage + 4)
+ elif insn.startswith('callw'):
+ cur.noteCall(insnaddr, calladdr, stackusage + 2)
else:
- # Jump or call insn
- calladdr = int(calladdr, 16)
- ref = m.group('ref')
- if '+' in ref:
- # Inter-function jump.
- pass
- elif insn.startswith('j'):
- # Tail call
- noteCall(cur, subfuncs, insnaddr, calladdr, 0)
- elif insn.startswith('calll'):
- noteCall(cur, subfuncs, insnaddr, calladdr, stackusage + 4)
- elif insn.startswith('callw'):
- noteCall(cur, subfuncs, insnaddr, calladdr, stackusage + 2)
- else:
- print("unknown call", ref)
- noteCall(cur, subfuncs, insnaddr, calladdr, stackusage)
- # Reset stack usage to preamble usage
- stackusage = cur[1]
-
- #print("other", repr(line))
+ print("unknown call", ref)
+ cur.noteCall(insnaddr, calladdr, stackusage)
+ # Reset stack usage to preamble usage
+ stackusage = cur.basic_stack_usage
# Calculate maxstackusage
- for funcaddr, info in funcs.items():
- if info[2] is not None:
- continue
- calcmaxstack(funcs, funcaddr)
+ for info in funcs.values():
+ calcmaxstack(info, funcs)
# Sort functions for output
- funcaddrs = orderfuncs(funcs.keys(), funcs.copy())
+ funcinfos = orderfuncs(funcs.keys(), funcs.copy())
# Show all functions
print(OUTPUTDESC)
- for funcaddr in funcaddrs:
- name, basicusage, maxusage, yieldusage, maxyieldusage, count, calls = \
- funcs[funcaddr]
- if maxusage == 0 and maxyieldusage is None:
+ for info in funcinfos:
+ if info.max_stack_usage == 0 and info.max_yield_usage < 0:
continue
yieldstr = ""
- if maxyieldusage is not None:
- yieldstr = ",%d" % maxyieldusage
- print("\n%s[%d,%d%s]:" % (name, basicusage, maxusage, yieldstr))
- for insnaddr, calladdr, stackusage in calls:
- callinfo = funcs.get(calladdr, ("<unknown>", 0, 0, 0, None))
+ if info.max_yield_usage >= 0:
+ yieldstr = ",%d" % info.max_yield_usage
+ print("\n%s[%d,%d%s]:" % (info.funcname, info.basic_stack_usage
+ , info.max_stack_usage, yieldstr))
+ for insnaddr, calladdr, stackusage in info.called_funcs:
+ callinfo = funcs.get(calladdr, unknownfunc)
yieldstr = ""
- if callinfo[4] is not None:
- yieldstr = ",%d" % (stackusage + callinfo[4])
+ if callinfo.max_yield_usage >= 0:
+ yieldstr = ",%d" % (stackusage + callinfo.max_yield_usage)
print(" %04s:%-40s [%d+%d,%d%s]" % (
- insnaddr, callinfo[0], stackusage, callinfo[1]
- , stackusage+callinfo[2], yieldstr))
-
-def main():
- calc()
+ insnaddr, callinfo.funcname, stackusage
+ , callinfo.basic_stack_usage
+ , stackusage+callinfo.max_stack_usage, yieldstr))
if __name__ == '__main__':
main()
diff --git a/qemu/roms/seabios/scripts/kconfig/lxdialog/util.c b/qemu/roms/seabios/scripts/kconfig/lxdialog/util.c
index f7abdeb92..2a0d182e8 100644
--- a/qemu/roms/seabios/scripts/kconfig/lxdialog/util.c
+++ b/qemu/roms/seabios/scripts/kconfig/lxdialog/util.c
@@ -376,7 +376,7 @@ void print_title(WINDOW *dialog, const char *title, int width)
/*
* Print a string of text in a window, automatically wrap around to the
* next line if the string is too long to fit on one line. Newline
- * characters '\n' are propperly processed. We start on a new line
+ * characters '\n' are properly processed. We start on a new line
* if there is no room for at least 4 nonblanks following a double-space.
*/
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
diff --git a/qemu/roms/seabios/scripts/layoutrom.py b/qemu/roms/seabios/scripts/layoutrom.py
index dd770fe49..b976fb056 100755
--- a/qemu/roms/seabios/scripts/layoutrom.py
+++ b/qemu/roms/seabios/scripts/layoutrom.py
@@ -161,6 +161,7 @@ def getSectionsPrefix(sections, prefix):
# The sections (and associated information) to be placed in output rom
class LayoutInfo:
sections = None
+ config = None
genreloc = None
sec32init_start = sec32init_end = sec32init_align = None
sec32low_start = sec32low_end = None
@@ -172,6 +173,7 @@ class LayoutInfo:
# Determine final memory addresses for sections
def doLayout(sections, config, genreloc):
li = LayoutInfo()
+ li.config = config
li.sections = sections
li.genreloc = genreloc
# Determine 16bit positions
@@ -399,6 +401,10 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
filesections32flat = getSectionsFileid(li.sections, '32flat')
out = outXRefs([], exportsyms=li.varlowsyms
, forcedelta=li.final_sec32low_start-li.sec32low_start)
+ multiboot_header = ""
+ if li.config.get('CONFIG_MULTIBOOT'):
+ multiboot_header = "LONG(0x1BADB002) LONG(0) LONG(-0x1BADB002)"
+ sec32all_start -= 3 * 4
out += outXRefs(filesections32flat, exportsyms=[li.entrysym]) + """
_reloc_min_align = 0x%x ;
zonefseg_start = 0x%x ;
@@ -415,6 +421,7 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
.text code32flat_start : {
%s
%s
+%s
code32flat_end = ABSOLUTE(.) ;
} :text
""" % (li.sec32init_align,
@@ -428,6 +435,7 @@ def writeLinkerScripts(li, out16, out32seg, out32flat):
li.sec32init_start,
li.sec32init_end,
sec32all_start,
+ multiboot_header,
relocstr,
outRelSections(li.sections, 'code32flat_start'))
out = COMMONHEADER + out + COMMONTRAILER + """