5 # Wrap a kernel module (.ko) so that all undefined functions
6 # are resolved at compile time to wrapper that have the template
9 # TODO: parameterize hypercall numbers
10 # TODO: remove printk special case
19 $V3_BORDER_OUT_CALL_NR = 0x6003;
20 $V3_BORDER_IN_RET_NR = 0x6004;
22 &GetOptions("user"=>\$user, "kern"=>\$kern);
24 $#ARGV==0 or die "christo.pl [--user|--kern] <object-file>\n";
26 $of=shift; chomp($of);
27 ($ofstem) = split(/\./,fileparse($of));
31 print "Wrapping $of to produce $ofstem-wrapped\n";
33 # First, find all undefined symbols that are text
34 @funcs = ExtractUndefinedFunctions($of);
36 print "Wrapping the following functions\n";
37 print join("\n", @funcs),"\n";
39 print "Generating wrapper $ofstem\_wrapper.c\n";
41 open(WRAPPER, ">$ofstem\_wrapper.c");
42 GenerateUserWrapper(WRAPPER, @funcs);
45 print "Compiling wrapper\n";
47 CompileUserWrapper($ofstem);
50 print "Linking with your supplied file $of to form $ofstem\_wrapped\n";
52 LinkUserWrapped($of,"$ofstem\_wrapper.o","$ofstem\_wrapped",@funcs);
58 print "Wrapping $of to produce $ofstem-wrapped\n";
60 @funcs = KernUndefFuncs($of);
63 print "Wrapping the following functions\n";
64 print join("\n", @funcs), "\n";
66 print "Generating wrapper $ofstem\_wrapper.S\n";
68 open(WRAPPER,">$ofstem\_wrapper.S");
69 GenerateKernWrapper($ofstem, WRAPPER, @funcs);
74 sub CompileUserWrapper {
77 return system("gcc -c -fPIC $stem.c -o $stem.o");
82 my ($of,$wrapper,$wrapped,@funcs) = @_;
84 $cmd = "gcc ".join(" ",
86 map {" -Xlinker --wrap=$_ "} @funcs
88 $of, $wrapper)." -o $wrapped";
103 print STDERR "Acquiring all undefined symbols from file\n";
105 open(OBJDUMP, "objdump -t $of |") or die "Cannot open file $of\n";
107 while ($line=<OBJDUMP>) {
108 if ($line =~ /.*\*UND\*\s+\S+\s+(\S+)$/) {
115 print STDERR "Finding all functions listed in System.map\n";
117 open(MAP,"System.map") or die "Cannot open System.map\n";
119 while ($line=<MAP>) {
121 my ($addr,$type,$name) = split(/\s+/,$line);
122 if (($type eq "t") or ($type eq "T")) {
129 foreach $func (@funcs) {
130 if (defined($sysmap{$func}) and ($func ne "printk") and ($func ne "mcount")
131 and ($func ne "__cyg_profile_func_enter") and ($func ne "__cyg_profile_func_exit")) {
132 print STDERR "ACCEPT $func\n";
133 push @final_funcs, $func;
135 print STDERR "DISCARD $func\n";
142 sub ExtractUndefinedFunctions {
147 open(OBJDUMP,"objdump -t $of |") or die "Cannot open file $of\n";
149 while ($line=<OBJDUMP>) {
150 if ($line =~ /.*\*UND\*\s+\S+\s+(\S+)$/) {
161 sub GenerateUserWrapper {
165 while ($func=shift) {
168 int __wrap_$func(void *a1,
177 asm volatile("vmmcall"
179 :"0" ($V3_GUARD_EXIT_HCALL_NR));
180 return __real_$func(a1,a2,a3,a4,a5,a6,a7,a8);
181 asm volatile("vmmcall"
183 :"0" ($V3_GUARD_ENTER_HCALL_NR));
191 sub GenerateKernWrapper {
196 open(MKFILE,">Makefile");
197 open(CFILE, ">wrap_impl.c");
199 print MKFILE "### THIS FILE IS AUTOMATICALLY GENERATED ###\n";
200 print MKFILE "EXTRA_LDFLAGS = ";
202 print $file "/* THIS FILE IS AUTOMATICALLY GENERATED */\n";
203 print $file ".text\n.align 4\n";
204 print $file map { ".globl __wrap_$_\n" } @funcs;
205 print $file map { ".globl __wrap_impl_$_\n" } @funcs;
207 print CFILE "/* THIS FILE IS AUTOMATICALLY GENERATED */\n";
208 print CFILE "#include <linux/kernel.h>\n\n";
209 #print CFILE "extern int wrapper_count;\n\n";
210 #print CFILE "static int border_count = 0;\n\n";
211 print CFILE map { "void __wrap_impl_$_(void);\n\n" } @funcs;
213 foreach $func (@funcs) {
238 #callq __wrap_impl_$func
266 movq \$$V3_BORDER_OUT_CALL_NR, %rax
271 movq \$$V3_BORDER_IN_RET_NR, %rax
278 print MKFILE "--wrap $func ";
281 void __wrap_impl_$func(void) {
284 //printk("exit: $func\\n");
285 //printk("wc: %d (%s)\\n", wrapper_count,__func__);
291 print MKFILE "\n\nldflags-y := \$(EXTRA_LDFLAGS)\n";
293 # TODO: change this to not be hardcoded!
294 my $kerndir = "/v-test/guard_modules/gm_guest/kyle_gl/";
298 obj-m := $fname\_wrapped.o
300 $fname\_wrapped-objs := $fname.ko $fname\_wrapper.o wrap_impl.o
302 $fname\_wrapped.ko: $fname.ko $fname\_wrapper.o wrap_impl.o
303 \tmake -C \$(KERNDIR) M=\$(PWD) modules
306 \tmake -C \$(KERNDIR) M=\$(PWD) clean