+IoGetTopLevelIrp()
[captive.git] / src / libcaptive / ke / captivesym.pl
1 #! /usr/bin/perl
2
3 # $Id$
4 # Generate source files based on .captivesym symbol file
5 # Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
6
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; exactly version 2 of June 1991 is required
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
21 use vars qw($VERSION);
22 $VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; };
23 use strict;
24 use warnings;
25
26
27 my %def;
28 while ($ARGV[0] && $ARGV[0]=~/[.]def$/) {
29         map({ open DEF,"<$_" or die "open(\"$_\"): $!"; } shift());
30         while (<DEF>) {
31                 s/;.*//s;
32                 next if /^\s*$/s;
33                 next if /^(?:LIBRARY|EXPORTS)\b/s;
34                 my($atsign,$symbol,$args,$isdata)=(/^\s*(\@)?(\S+?)(?:\@(\d+))?(\s+DATA)?\s*$/s);
35                 die "Invalid line" if !defined $symbol;
36                 #          popped args          doc  ntoskrnl.def
37                 # cdecl    no     stack         _f   f
38                 # stdcall  yes    stack         _f@4 f@4
39                 # fastcall yes    ecx,edx,stack @f@4 @f@4
40                 next if $isdata;
41                 die "\@funcname without \@4 suffix not recognized" if $atsign && !defined $args;
42                 die "Invalid \@$args number" if defined $args && ($args<0 || ($args%4));
43                 die "Duplicate symbol: $symbol" if exists $def{$symbol};
44                 $def{$symbol}={
45                                 "type"=>(!defined $args ? "cdecl" : (!$atsign ? "stdcall" : "fastcall")),
46                                 (!defined $args ? () : ("args4"=>$args/4)),
47                                 };
48                 }
49         close DEF or warn "close(DEF): $!";
50         }
51
52 # read source
53 my %module;     # $module{'module'}{'symbol'}=1/""
54 my %symbol;     # $symbol{'symbol'}=1/""
55 while (<>) {
56         chomp;
57         next if /^\s*$/;        # empty
58         next if /^\s*#.*/;      # comment
59         my($module,$symbol,$isundef)=(/^\s*(\S+)\s+(\S+)(\s+undef)?\s*$/);
60         die "Invalid line" if !defined $symbol;
61         die "Symbol already exists: $symbol" if exists $symbol{$symbol};
62         delete $def{$symbol} if $isundef;
63         die "Symbol not in ntoskrnl.def file: $symbol" if !$isundef && !$def{$symbol};
64         $module{$module}{$symbol}=!$isundef;
65         $symbol{$symbol}=!$isundef;
66         }
67
68 # file header
69 print <<"HERE";
70 /* File generated automatically by captivesym.pl from "$ARGV" */
71 /* DO NOT EDIT! */
72
73 #include "config.h"
74
75 #include "captive/ldr_exports.h"        /* for captive_ModuleList_add_builtin() */
76 #include <glib/gtypes.h>
77 #include <glib/gmessages.h>
78 #include <glib/gmacros.h>
79
80
81 HERE
82
83 # undefined symbol stubs
84 my $symbols_undef=0;
85 for my $symbol (sort keys(%symbol)) {
86         my $def=$def{$symbol};
87         if (!$def) {
88                 print <<"HERE";
89 static void ${symbol}_undef(void)
90 {
91         g_error("%s: Function '$symbol' NOT IMPLEMENTED",G_STRLOC);
92 }
93 HERE
94                 $symbols_undef++;
95                 }
96         elsif ("cdecl" eq $def->{"type"}) {
97                 print "void/* ==unknown */ ${symbol}(void/* ==unknown */);\n",
98                                 "#define ${symbol}_".$def->{"type"}." ${symbol}\n";
99                 }
100         else {
101                 my @args_out=map("arg$_",0..($def->{"args4"}-1));
102                 my @args_in=($def->{"type"} ne "fastcall" ? @args_out
103                                 : ("stub_eax","arg1","arg0",@args_out[2..$#args_out]));
104                 print "guint32 ${symbol}(".(join(",",map("guint32 $_",@args_out)) || "void").");\n",
105                                 "static guint32 "
106                                                                 ."__attribute__((__".(map(($_ ne "fastcall" ? $_ : "stdcall"),$def->{"type"}))[0]."__)) "
107                                                                 .($def->{"type"} ne "fastcall" ? "" : "__attribute__((__regparm__(3))) ")
108                                                                 ."${symbol}_".$def->{"type"}."(".(join(",",map("guint32 $_",@args_in)) || "void").")\n",
109                                 "{\n",
110                                 "\treturn ${symbol}(".join(",",@args_out).");\n",
111                                 "}\n";
112                 }
113         }
114
115 # export function captive_kernel_exports()
116 print <<"HERE";
117
118 gboolean captive_kernel_exports(void)
119 {
120 gboolean errbool;
121
122 HERE
123 for my $module (sort keys(%module)) {
124         my $moduleref=$module{$module};
125         print <<"HERE";
126         errbool=captive_ModuleList_add_builtin("$module",
127 HERE
128         for my $symbol (sort keys(%$moduleref)) {
129                 my $value=${$moduleref}{$symbol};
130                 print "\t\t\t\"$symbol\",&${symbol}_",
131                                 ($def{$symbol}{"type"} || "undef"),
132                                 ",\n";
133                 }
134         print <<"HERE";
135                         NULL);
136         g_return_val_if_fail(errbool,FALSE);
137
138 HERE
139         }
140 print <<"HERE";
141         return TRUE;
142 }
143 HERE
144
145 # exit
146 print STDERR "$0: Processed ".scalar(keys(%module))." modules, ".scalar(keys(%symbol))." symbols",
147                 " (".int(100*(1-$symbols_undef/scalar(keys(%symbol)))).'%'." implemented)\n";
148 print STDERR "$0: warning: $symbols_undef symbols are NOT IMPLEMENTED yet!\n" if $symbols_undef;
149 exit 0;
150
151
152 __END__
153
154 =head1 NAME
155
156 captivesym.pl - Generate source files based on .captivesym symbol file
157
158 =head1 SYNOPSIS
159
160 ./captivesym.pl path/to/ntoskrnl.def path/to/hal.def exports.captivesym E<gt>exports.c
161
162 =head1 DESCRIPTION
163
164 Source files with symbol call type definitions are identified by matching
165 pattern I<*.def>. The remaining files (I<.captivesym> ones) must
166 consist of lines with whitespace-separated
167 (B<module>,B<symbol>,[undef]) items.
168
169 =over
170
171 =item undef
172
173 Optional "undef" specifies invocation of a generated stub function displaying
174 C<g_error()> message.
175
176 =back
177
178 =begin comment
179
180         choose one:
181                 podchecker: *** WARNING: node 'http:$_' contains non-escaped | or /
182                 pod2html: cannot resolve L.lt.http:$_.gt.
183
184 =end comment
185
186 Source files I<*.def> are required to have on of three item types described at
187 L<http://msdn.microsoft.com/library/en-us/vclang/html/_core_argument_passing_and_naming_conventions.asp>
188 (B<argslength> must be dividable by B<4>):
189
190 =over
191
192 =item cdecl: functionname
193
194 =item stdcall: functionname@argslength
195
196 =item fastcall: @functionname@argslength
197
198 =back
199
200 =head1 COPYRIGHT
201
202 Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
203
204 This program is free software; you can redistribute it and/or modify
205 it under the terms of the GNU General Public License as published by
206 the Free Software Foundation; exactly version 2 of June 1991 is required
207
208 This program is distributed in the hope that it will be useful,
209 but WITHOUT ANY WARRANTY; without even the implied warranty of
210 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
211 GNU General Public License for more details.
212
213 You should have received a copy of the GNU General Public License
214 along with this program; if not, write to the Free Software
215 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
216
217 =cut