Files
foc/kernel/fiasco/tool/genoffset.py
2013-01-11 17:00:47 +01:00

231 lines
7.5 KiB
Python
Executable File

#!/usr/bin/env python
import string,re,sys
import getopt
import pdb
def gen_esc_sym(*literals):
return gen_escaped_symbols(*literals)
def gen_escaped_symbols(*literals):
return tuple(map(lambda x: re.escape(x),literals))
context_marker = "class context_t %s %s size (\d+) vtable self id \d+ %s" % \
gen_escaped_symbols("{", "/*", "*/")
d_members_context = ["_state",
"ready_next",
"ready_prev",
"kernel_sp",
"_space_context",
"_stack_link",
"_donatee",
"_lock_cnt",
"_thread_lock",
"_sched",
"_fpu_regs"]
sender_marker = "class sender_t %s %s size (\d+) vtable self id \d+ %s" % \
gen_escaped_symbols("{","/*","*/")
d_members_sender = ["_id",
"_send_partner",
"sender_next",
"sender_prev"]
receiver_marker = "class receiver_t : public context_t %s id \d+ %s %s %s size \d+ vtable class context_t %s id \d+ %s id \d+ %s" % gen_escaped_symbols("/*","*/","{","/*","/*","*/","*/")
d_members_receiver = ["_partner",
"_receive_regs",
"_pagein_request",
"_pagein_applicant",
"_sender_first",
"_timeout"]
thread_marker = "class thread_t : public receiver_t %s id \d+ %s, public sender_t %s id \d+ %s %s bitpos (\d+) %s %s %s size (\d+) vtable class context_t %s id \d+ %s id \d+ %s" % gen_escaped_symbols("/*","*/","/*", "*/", "/*","*/","{", "/*", "/*","*/","*/")
d_members_thread = ["_space",
"_thread_lock",
# "_timeout",
"_pager",
"_preempter",
"_ext_preempter",
"present_next",
"present_prev",
"_irq",
"_idt",
"_idt_limit",
"_target_desc",
"_pagein_error_code",
"_vm_window0",
"_vm_window1",
"_recover_jmpbuf",
"_pf_timeout",
"_last_pf_address",
"_last_pf_error_code",
"_magic"]
class_members = {"context" : d_members_context,
"receiver" : d_members_receiver,
"sender" : d_members_sender,
"thread" : d_members_thread}
f_members = []
verbose_output = 0
def do_print(*args):
assert len(args) > 0
if not verbose_output:
return
for i in range(len(args) -1):
print args[i],
print args[-1]
def extract_members(sections):
section_members = {}
for k , lines in sections.items():
do_print( "extract members for %s, %d members to go" % (k, len(class_members[k])))
line_nr = 0
section_members[k] = {}
for member in class_members[k]:
assert line_nr < len(lines)
p = re.compile("(?:\s|%s)(?:%s)?%s.*?; %s bitsize (\d+), bitpos (\d+) %s" % (gen_esc_sym("(","*")+ (member,) + gen_esc_sym("/*","*/")))
while 1:
try:
m = p.search(lines[line_nr])
except:
print "ERROR: member %s not found for unit %s" % (member,k)
print "use --verbose for more debug output"
sys.exit(1)
assert 0
# pdb.set_trace()
if m:
do_print( "found %s for %s %s %s @ %d" % (member, k, m.group(1), m.group(2), line_nr))
section_members[k][member] = (int(m.group(1)), int(m.group(2)))
break
line_nr = line_nr + 1
return section_members
def extract_sections(input_file):
lines = open(input_file).readlines()
section_keys = {"context" : context_marker,
"receiver" : receiver_marker,
"sender" : sender_marker,
"thread" : thread_marker}
sections = {}
line_nr = 0
while section_keys and line_nr < len(lines) :
marker_pat = []
curr_section = []
do_print( "generating new pattern, %d parts, line_nr %d (%d)" % \
(len(section_keys), line_nr, len(lines)))
for k,p in section_keys.items():
marker_pat.append("(?P<%s>%s)" % (k,p))
pat = re.compile("|".join(marker_pat))
section_finished = 0
while line_nr < len(lines) and not section_finished:
m = pat.match(lines[line_nr])
if m:
d = m.groupdict()
for k,v in d.items():
if v:
do_print("found section %s @ %d" % (k,line_nr))
curr_section.append(v)
del section_keys[k]
break
else:
assert 0
line_nr = line_nr + 1
while 1:
curr_section.append(lines[line_nr])
m = re.match("%s;" % gen_escaped_symbols("}"), lines[line_nr])
if m:
sections[k] = curr_section
curr_section = []
do_print( "finished section %s @ %d" % (k,line_nr))
section_finished = 1
break
line_nr = line_nr + 1
else:
line_nr = line_nr + 1
return sections
def dump_members(prefix, offset, members):
member_list = members.items()
member_list.sort(lambda x, y: cmp(x[1][1], y[1][1]))
for m in member_list:
member = m[0].upper()
while member[0] == "_":
member = member[1:]
name = "%s%s" % (prefix,member)
if len(name) < 40:
name = "%s%s" % (name, " " * (30 -len(name)))
print "#define %s %3d" % (name, offset / 8 + m[1][1]/ 8)
def main(input_file):
sections = extract_sections(input_file)
assert len(sections) == 4
section_members = extract_members(sections)
dump_members("OFS__THREAD__", 0, section_members["context"])
dump_members("OFS__THREAD__", 0, section_members["receiver"])
m = re.match(thread_marker, sections["thread"][0])
assert m
sender_offset = int(m.group(1))
thread_size = int(m.group(2))
print "#define CAST_thread_TO_sender " , sender_offset / 8
dump_members("OFS__THREAD__",sender_offset, section_members["sender"])
dump_members("OFS__THREAD__",0, section_members["thread"])
print "#define OFS__THREAD__MAX " , thread_size
def usage():
print "usage: %s [options]" % sys.argv[0]
print "Options:"
print " --help Display this information"
print " --verbose Verbose output for debugging"
if __name__ == "__main__":
input_file = "thread.debug"
try:
opts, args = getopt.getopt(sys.argv[1:], "", ["verbose","help","file="])
except getopt.GetoptError, err:
print err.msg
usage();
sys.exit(1)
if args:
usage()
sys.exit(1)
for o, a in opts:
if o == "--verbose":
verbose_output = 1
continue
if o == "--file":
input_file = a
continue
if o == "--help":
usage()
sys.exit(0)
main(input_file)