Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Add tools for transforming a kernel module into a guarded module
[palacios.git] / gears / guarded_modules / christo-s.pl
1 #!/usr/bin/perl -w
2
3 #
4 #
5 # Wrap a kernel module (.ko) so that all undefined functions
6 # are resolved at compile time to wrapper that have the template
7 # as given here
8 #
9 # TODO: parameterize hypercall numbers
10 # TODO: remove printk special case
11 #
12
13 use Getopt::Long;
14 use File::Basename;
15
16 $user=0;
17 $kern=0;
18
19 $V3_BORDER_OUT_CALL_NR = 0x6003;
20 $V3_BORDER_IN_RET_NR   = 0x6004;
21
22 &GetOptions("user"=>\$user, "kern"=>\$kern);
23
24 $#ARGV==0 or die "christo.pl [--user|--kern] <object-file>\n";
25
26 $of=shift; chomp($of);
27 ($ofstem) = split(/\./,fileparse($of)); 
28
29 if ($user) { 
30   
31   print "Wrapping $of to produce $ofstem-wrapped\n";
32   
33   # First, find all undefined symbols that are text
34   @funcs = ExtractUndefinedFunctions($of);
35   
36   print "Wrapping the following functions\n";
37   print join("\n", @funcs),"\n";
38   
39   print "Generating wrapper $ofstem\_wrapper.c\n";
40   
41   open(WRAPPER, ">$ofstem\_wrapper.c");
42   GenerateUserWrapper(WRAPPER, @funcs);
43   close(WRAPPER);
44
45   print "Compiling wrapper\n";
46   
47   CompileUserWrapper($ofstem);
48
49
50   print "Linking with your supplied file $of to form $ofstem\_wrapped\n";
51
52   LinkUserWrapped($of,"$ofstem\_wrapper.o","$ofstem\_wrapped",@funcs);
53
54   print "Done.\n"
55
56 } else {
57
58   print "Wrapping $of to produce $ofstem-wrapped\n";
59
60   @funcs = KernUndefFuncs($of);
61
62   
63   print "Wrapping the following functions\n";
64   print join("\n", @funcs), "\n";
65
66   print "Generating wrapper $ofstem\_wrapper.S\n";
67
68   open(WRAPPER,">$ofstem\_wrapper.S");
69   GenerateKernWrapper($ofstem, WRAPPER, @funcs);
70   close(WRAPPER);
71
72 }
73
74 sub CompileUserWrapper {
75   my $stem=shift;
76   
77   return system("gcc -c -fPIC $stem.c -o $stem.o");
78 }
79
80
81 sub LinkUserWrapped {
82   my ($of,$wrapper,$wrapped,@funcs) = @_;
83   
84   $cmd = "gcc ".join(" ", 
85                      join(" ",
86                           map {" -Xlinker --wrap=$_ "} @funcs
87                          ), 
88                      $of, $wrapper)." -o $wrapped";
89   
90   print $cmd;
91   return system $cmd;
92
93 }
94
95 sub KernUndefFuncs {
96     my $of = shift;
97     my $line;
98     my @funcs;
99     my @lines;
100     my @final_funcs;
101     my %sysmap;
102
103     print STDERR "Acquiring all undefined symbols from file\n";
104
105     open(OBJDUMP, "objdump -t $of |") or die "Cannot open file $of\n";
106
107     while ($line=<OBJDUMP>) {
108         if ($line =~ /.*\*UND\*\s+\S+\s+(\S+)$/) {
109             push @funcs, $1;
110         }
111     }
112
113     close(OBJDUMP);
114
115     print STDERR "Finding all functions listed in System.map\n";
116
117     open(MAP,"System.map") or die "Cannot open System.map\n";
118
119     while ($line=<MAP>) { 
120         chomp($line);
121         my ($addr,$type,$name) = split(/\s+/,$line);
122         if (($type eq "t") or ($type eq "T")) { 
123             $sysmap{$name}=1;
124         }
125     }
126
127     close(MAP);
128
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;
134         } else {
135             print STDERR "DISCARD $func\n";
136         }
137     }
138
139     return @final_funcs;
140 }
141
142 sub ExtractUndefinedFunctions {
143   my $of=shift;
144   my $line;
145   my @funcs;
146
147   open(OBJDUMP,"objdump -t $of |") or die "Cannot open file $of\n";
148
149   while ($line=<OBJDUMP>) { 
150     if ($line =~ /.*\*UND\*\s+\S+\s+(\S+)$/) { 
151       push @funcs, $1;
152     }
153   }
154
155   close(OBJDUMP);
156
157   return @funcs;
158
159 }
160
161 sub GenerateUserWrapper  {
162   my $file=shift;
163   
164
165   while ($func=shift) {
166     print $file <<ENDF;
167
168 int __wrap_$func(void *a1, 
169                  void *a2,
170                  void *a3,
171                  void *a4,
172                  void *a5,
173                  void *a6,
174                  void *a7,
175                  void *a8) 
176 {
177  asm volatile("vmmcall"
178         :"=a" (ret)
179         :"0" ($V3_GUARD_EXIT_HCALL_NR));
180   return __real_$func(a1,a2,a3,a4,a5,a6,a7,a8);
181  asm volatile("vmmcall"
182         :"=a" (ret)
183         :"0" ($V3_GUARD_ENTER_HCALL_NR));
184 }
185
186 ENDF
187
188   }
189 }
190
191 sub GenerateKernWrapper {
192     my $fname=shift;
193     my $file=shift;
194     my @funcs=@_;
195
196   open(MKFILE,">Makefile");
197   open(CFILE, ">wrap_impl.c");
198
199     print MKFILE "### THIS FILE IS AUTOMATICALLY GENERATED ###\n";
200     print MKFILE "EXTRA_LDFLAGS = ";
201
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;
206  
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;
212
213     foreach $func (@funcs) {
214 #__wrap_$func:
215         #nop
216         #nop
217         #nop
218         #nop
219         #nop
220         #nop
221         #nop
222         #pushq %rbp
223         #movq  %rsp, %rbp
224         #pushq %rax
225         #pushq %rbx
226         #pushq %rcx
227         #pushq %rdx
228         #pushq %rdi
229         #pushq %rsi
230         #pushq %r8
231         #pushq %r9
232         #pushq %r10
233         #pushq %r11
234         #pushq %r12
235         #pushq %r13
236         #pushq %r14
237         #pushq %r15
238         #callq __wrap_impl_$func
239         #popq %r15
240         #popq %r14
241         #popq %r13
242         #popq %r12
243         #popq %r11 
244         #popq %r10
245         #popq %r9
246         #popq %r8 
247         #popq %rsi
248         #popq %rdi
249         #popq %rdx
250         #popq %rcx
251         #popq %rbx
252         #popq %rax
253         #popq %rbp
254         #jmp __real_$func
255         #nop
256         #nop
257         #nop
258         #nop
259         #nop
260
261     print $file <<ENDF;
262
263 __wrap_$func:
264         popq  %r11
265         pushq %rax
266         movq  \$$V3_BORDER_OUT_CALL_NR, %rax
267         vmmcall
268         popq  %rax
269         callq __real_$func
270         pushq %rax
271         movq \$$V3_BORDER_IN_RET_NR, %rax
272         vmmcall
273         popq  %rax
274         pushq %r11
275         ret
276 ENDF
277
278     print MKFILE "--wrap $func ";
279
280     print CFILE <<ENDF;
281 void __wrap_impl_$func(void) {
282
283         //wrapper_count++;
284         //printk("exit: $func\\n");
285         //printk("wc: %d (%s)\\n", wrapper_count,__func__);
286 }
287
288 ENDF
289
290   }
291   print MKFILE "\n\nldflags-y := \$(EXTRA_LDFLAGS)\n";
292
293 # TODO: change this to not be hardcoded!
294   my $kerndir = "/v-test/guard_modules/gm_guest/kyle_gl/";
295   print MKFILE <<ENDF;
296 KERNDIR=$kerndir
297   
298 obj-m := $fname\_wrapped.o
299     
300 $fname\_wrapped-objs := $fname.ko $fname\_wrapper.o wrap_impl.o
301
302 $fname\_wrapped.ko: $fname.ko $fname\_wrapper.o wrap_impl.o
303 \tmake -C \$(KERNDIR) M=\$(PWD) modules
304
305 clean:
306 \tmake -C \$(KERNDIR) M=\$(PWD) clean
307
308 ENDF
309
310   close(MKFILE);
311   close(CFILE);
312
313 }