Created
July 23, 2016 12:26
-
-
Save hannesweisbach/4a04f8557dd1ad00723e7f3e2a1d8238 to your computer and use it in GitHub Desktop.
Wrapper script for Fail*/L4Re
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'fileutils' | |
require 'open3' | |
require 'optparse' | |
require 'pathname' | |
module ResComp | |
class Config | |
@@config = {} | |
def self.set(key, value) | |
@@config[key] = value | |
end | |
def self.get(key) | |
@@config[key] | |
end | |
end | |
class Experiment | |
attr_reader :id, :binary, :type, :entry, :exit | |
def initialize(id, binary, type = nil) | |
@id = id | |
@binary = binary | |
@type = type | |
end | |
def name() | |
if type | |
return id + '-' + type | |
end | |
id | |
end | |
def target() | |
'ResComp-' + @id | |
end | |
def iso() | |
'rescomp-' + @id + '.iso' | |
end | |
def entry_ip() | |
# objdump -hS ex_uirq |awk '/asm volatile\(\"nop\"\)/ { getline; print }' | ack -io [0-9a-f]{7} | |
Open3.pipeline_r("objdump -hS #{Config.get('l4::bindir') + @binary}", | |
"awk '/asm volatile\\(\\\"nop\\\"\\)/ { getline; print }'", | |
"ack -io [0-9a-f]{7}") { |o, _| | |
output = o.read.lines | |
if type == 's' | |
@entry = output[1] | |
@exit = output[0] | |
else | |
@entry = output[0] | |
@exit = output[1] | |
end | |
} | |
end | |
end | |
$experiment_conf = " | |
func_entry=%{entry} | |
func_exit=%{exit} | |
#default config | |
emul_ips=5000000 | |
max_instr_bytes=15 | |
campain_server=localhost | |
#default files | |
state_folder=l4sys.state | |
instruction_list=ip.list | |
golden_run=golden.out | |
filter=filter.list | |
trace=trace.bp | |
numinstr=0 | |
totinstr=0 | |
" | |
class Run | |
def initialize(prefix, experiments, kernels) | |
@prefix = prefix | |
@experiments = experiments | |
@kernels = kernels | |
end | |
def setup() | |
p "Creating directory structure" | |
inst_filter = @prefix + "filter.list" | |
if not inst_filter.exist? | |
File.open(inst_filter, 'w') { |file| | |
file.write("0xc0000000 0xffffffff") | |
} | |
end | |
mem_filter = @prefix + "mem_filter.list" | |
if not mem_filter.exist? | |
File.open(mem_filter, 'w') { |file| | |
file.write("0xeac00000 0xeac02000\n") | |
file.write("0xf04b8000 0xf04c0000") | |
} | |
end | |
bochsrc = @prefix + 'bochsrc-bd' | |
if not bochsrc.symlink? | |
bochsrc.make_symlink('../bochsrc-bd') | |
end | |
@experiments.each { |e| e.entry_ip } | |
@experiments.product(@kernels).collect{ |e, k| | |
p " #{e.name}/#{k[:name]}" | |
dir = @prefix + e.name + k[:name] | |
FileUtils.mkpath dir | |
system({ 'MODULE_SEARCH_PATH' => "#{k[:path]}" }, | |
"make -C #{Config.get('l4::srcdir')} grub2iso E=#{e.target}", | |
{ [:err, :out] => Config.get(:log) }) | |
FileUtils.copy(Config.get('l4::imgdir') + e.iso, dir + 'image.iso') | |
FileUtils.copy(k[:path] + 'fiasco.image', dir + 'fiasco.image') | |
File.open(dir + 'experiment.conf', 'w') { |file| | |
file.write($experiment_conf % { :entry => e.entry, :exit => e.exit }) | |
} | |
filter_link = dir + 'filter.list' | |
if not filter_link.symlink? | |
filter_link.make_symlink('../../filter.list') | |
end | |
filter_link = dir + 'mem_filter.list' | |
if not filter_link.symlink? | |
filter_link.make_symlink('../../mem_filter.list') | |
end | |
} | |
# puts "Launching objdump ..." | |
# pids = [] | |
# do_foreach { |dir| | |
# pids << Process.spawn("objdump -hS #{dir + 'fiasco.image'}", | |
# { :out => [dir + 'fiasco.lss', 'w'] }) | |
# } | |
# puts "Waiting for objdump to finish ..." | |
# pids.each{ |pid| Process.wait(pid) } | |
end | |
def prepare() | |
pids = [] | |
do_foreach { |dir| | |
pid = Process.spawn({ 'BXIMAGE' => 'image.iso', 'BXSHARE' => "#{Config.get('fail::share')}" }, | |
"#{Config.get('fail::bindir') + 'fail-client'} " + | |
"-Wf,--step=all -f ../../bochsrc-bd -q ", | |
{ :chdir => dir, [:err, :out] => [dir + 'preparation.log', 'w'] }) | |
pids << pid | |
} | |
puts "Waiting for preparation to finish ..." | |
pids.each{ |pid| Process.wait(pid) } | |
end | |
def postproc() | |
do_foreach { |dir| | |
locs = {} | |
s = "" | |
IO.binread(dir + 'ip.list').unpack('Q*').each_slice(2){ |i, c| s += "#{i.to_s(16)}\n"} | |
stdout, status = Open3.capture2("addr2line -e #{dir + 'fiasco.image'}", :stdin_data => s) | |
stdout.each_line { |loc| | |
loc.chomp! | |
if locs[loc] | |
locs[loc] += 1 | |
else | |
locs[loc] = 1 | |
end | |
} | |
File.open(dir + 'inst', 'w') { |file| | |
locs.each{ |key, value| | |
file.write "%12d #{key}\n" % value | |
} | |
} | |
} | |
end | |
def postproc2() | |
do_foreach { |dir| | |
do_load(dir) | |
counts = [] | |
addrs = "" | |
locs = {} | |
Open3.popen2("mysql -N") { |stdin, stdout, wait| | |
stdin.print "SELECT injection_instr_absolute, tr.time1, tr.time2, tr.width "+ | |
"FROM fsppilot pil " + | |
"JOIN trace tr ON pil.variant_id = tr.variant_id " + | |
"AND pil.instr2 = tr.instr2 AND pil.data_address = tr.data_address "+ | |
";" | |
stdin.close | |
stdout.each_line{ |line| | |
result = line.scan(/\d+/).map { |x| x.to_i } | |
counts << (result[2] - result[1] + 1) * result[3] * 8 | |
addrs += "#{result[0].to_s(16)}\n" | |
} | |
} | |
stdout, status = Open3.capture2("addr2line -e #{dir + 'fiasco.image'}", :stdin_data => addrs) | |
stdout.each_line { |loc| | |
loc.chomp! | |
if locs[loc] | |
locs[loc] += counts.shift | |
else | |
locs[loc] = counts.shift | |
end | |
} | |
File.open(dir + 'hist', 'w') { |file| | |
locs.each{ |key, value| | |
file.write "%12d #{key}\n" % value | |
} | |
} | |
} | |
end | |
def do_load(trace) | |
tracefile = trace + 'trace.bp' | |
cmd = "#{Config.get('fail::bindir') + 'import-trace'} --importer MemoryImporter " + | |
"-d #{Config.get('db')} " + | |
"-t #{tracefile} " | |
system(cmd, { [:err, :out] => Config.get(:log) }) | |
system("#{Config.get('fail::bindir') + 'prune-trace'} -d #{Config.get('db')} --overwrite", | |
{ [:err, :out] => Config.get(:log) }) | |
end | |
def load() | |
do_foreach { |trace| do_load(trace) } | |
end | |
def number_of_experiments() | |
do_foreach { |trace| | |
sum = 0 | |
do_load(trace) | |
Open3.popen2("mysql -N") { |stdin, stdout, wait| | |
stdin.print "SELECT tr.time1, tr.time2, tr.width FROM fsppilot pil " + | |
"JOIN trace tr ON pil.variant_id = tr.variant_id " + | |
"AND pil.instr2 = tr.instr2 AND pil.data_address = tr.data_address;" | |
stdin.close | |
stdout.each_line{ |line| | |
result = line.scan(/\d+/).map { |x| x.to_i } | |
sum += (result[1] - result[0] + 1) * result[2] * 8 | |
} | |
} | |
puts "%-25s: %15s" % [ trace, sum.to_s.reverse.gsub(/...(?=.)/,'\& ').reverse ] | |
} | |
end | |
def do_foreach(&block) | |
@experiments.product(@kernels).collect{ |e, k| | |
block.call(@prefix + e.name + k[:name]) | |
} | |
end | |
def fi() | |
server = Process.spawn("#{Config.get('fail::bindir') + 'l4-sys-server'} --type mem") | |
#launch clients | |
Process.wait(server) | |
#tell clients to quit | |
@kernels.each{ |name, path| | |
#make_image(name, path) | |
#trace(name) | |
import(name) | |
} | |
prune() | |
end | |
end | |
def run_fi(experiments) | |
dbname='failhannes' | |
#$BUILDDIR/import-trace --importer $IMPORTER -e $ELF -d $DBNAME -t trace.pb | |
#$BUILDDIR/prune-trace -d $DBNAME --overwrite | |
#l4sys-server | |
#launch clients on taurus | |
end | |
end | |
ResComp::Config.set('l4::srcdir', Pathname.new('~/L4/src')) | |
ResComp::Config.set('l4::objdir', Pathname.new('/home/weisbach/L4/build/l4re32')) | |
ResComp::Config.set('l4::bindir', ResComp::Config.get('l4::objdir') + 'bin' + 'x86_586' + 'l4f') | |
ResComp::Config.set('l4::imgdir', ResComp::Config.get('l4::objdir') + 'images') | |
ResComp::Config.set('fail::dir', Pathname.new('/home/weisbach/ResComp/fail')) | |
ResComp::Config.set('fail::bindir', ResComp::Config.get('fail::dir') + 'build' + 'bin') | |
ResComp::Config.set('fail::share', ResComp::Config.get('fail::dir') + 'simulators' + 'bochs' + 'bios') | |
ResComp::Config.set('db', 'failhannes') | |
ResComp::Config.set(:log, File.open('fi.log', 'w')) | |
experiments = [] | |
experiments << ResComp::Experiment.new('hello', 'hello') | |
experiments << ResComp::Experiment.new('ipc', 'ex_ipc1') | |
experiments << ResComp::Experiment.new('utcb-ipc', 'ex_utcb_ipc') | |
experiments << ResComp::Experiment.new('uirq', 'ex_uirq') | |
experiments << ResComp::Experiment.new('map-irq', 'ex_map_irq_server', 's') # vertauscht | |
experiments << ResComp::Experiment.new('map-irq', 'ex_map_irq_client', 'c') | |
experiments << ResComp::Experiment.new('clntsrv', 'ex_clntsrv-server', 's') # vertauscht | |
experiments << ResComp::Experiment.new('clntsrv', 'ex_clntsrv-client', 'c') | |
experiments << ResComp::Experiment.new('streammap', 'ex_smap-server', 's') # vertauscht | |
experiments << ResComp::Experiment.new('streammap', 'ex_smap-client', 'c') | |
experiments << ResComp::Experiment.new('shared-ds', 'ex_l4re_ds_srv', 's') # vertauscht | |
experiments << ResComp::Experiment.new('shared-ds', 'ex_l4re_ds_clnt', 'c') | |
#prefix = Pathname.new(ARGV[0]) | |
#l4dir = Pathname.new(ARGV[1]) | |
kernels = [] | |
kernels << { :name => 'baseline', :path => Pathname.new('/home/weisbach/L4/build/fiasco32') } | |
kernels << { :name => 'v', :path => Pathname.new('/home/weisbach/L4/build/fiasco32-v') } | |
kernels << { :name => 'vp', :path => Pathname.new('/home/weisbach/L4/build/fiasco32-vptrparam') } | |
prefix = Pathname.new('data') | |
options = {} | |
OptionParser.new do |opts| | |
opts.banner = "Usage: fi.rb [options]" | |
options[:experiment] = ['hello', 'ipc', 'utcb-ipc', 'uirq', | |
'map-irq-c', 'map-irq-s', 'clntsrv-c', 'clntsrv-s', | |
'streammap-s', 'streammap-c', 'shared-ds-s', 'shared-ds-c'] | |
options[:variant] = ['baseline', 'v', 'vp'] | |
opts.on("-e", "--experiment Experiments", Array, "Experiment to process") do |e| | |
options[:experiment] = e | |
end | |
opts.on("-v", "--variant Variants", Array, "Experiment variant to run") do |v| | |
options[:variant] = v | |
end | |
opts.on("-s", "--setup", "(Re-)generate tree, iso-images, etc") do |s| | |
options[:setup] = s | |
end | |
opts.on("-p", "--prepare", "(Re-)generate traces") do |p| | |
options[:prepare] = p | |
end | |
opts.on("-d", "--debug", "Run debug post-processing") do |d| | |
options[:debug] = d | |
end | |
opts.on("-l", "--load", "Load Benchmark/Variant into mysql database") do |l| | |
options[:load] = l | |
end | |
opts.on("-n", "--number", "Number of experiments") do |n| | |
options[:number] = n | |
end | |
end.parse! | |
benchmarks = experiments.select { |experiment| options[:experiment].include? experiment.name } | |
variants = kernels.select { |variant| options[:variant].include? variant[:name] } | |
run = ResComp::Run.new(prefix, benchmarks, variants) | |
if options[:setup] | |
run.setup() | |
end | |
if options[:prepare] | |
run.prepare() | |
end | |
if options[:debug] | |
run.postproc() | |
run.postproc2() | |
end | |
if options[:load] | |
run.load() | |
end | |
if options[:number] | |
run.number_of_experiments() | |
end | |
#prepare(prefix, experiments) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment