fix some warnings
[reactos.git] / reactos / iface / native / genntdll.c
1 /* $Id: genntdll.c,v 1.12 2003/01/03 00:28:07 guido Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS version of ntdll
5 * FILE: iface/native/genntdll.c
6 * PURPOSE: Generates the system call stubs in ntdll
7 * CHANGE HISTORY: Added a '@xx' to deal with stdcall [ Ariadne ]
8 * 19990616 (ea)
9 * Four arguments now required; 4th is the file
10 * for ntoskrnl ZwXXX functions (which are merely calls
11 * to twin NtXXX calls, via int 0x2e (x86).
12 * 19990617 (ea)
13 * Fixed a bug in function numbers in kernel ZwXXX stubs.
14 *
15 */
16
17 /* INCLUDE ******************************************************************/
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #define PARAMETERIZED_LIBS
24
25 #define VERBOSE
26
27 #define INPUT_BUFFER_SIZE 255
28
29 /* FUNCTIONS ****************************************************************/
30
31 void write_syscall_stub(FILE* out, FILE* out3, char* name, char* name2,
32 char* nr_args, unsigned int sys_call_idx)
33 {
34 #ifdef PARAMETERIZED_LIBS
35 fprintf(out,"__asm__(\"\\n\\t.global _%s@%s\\n\\t\"\n",name,nr_args);
36 fprintf(out,"\".global _%s@%s\\n\\t\"\n",name2,nr_args);
37 fprintf(out,"\"_%s@%s:\\n\\t\"\n",name,nr_args);
38 fprintf(out,"\"_%s@%s:\\n\\t\"\n",name2,nr_args);
39 #else
40 fprintf(out,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
41 fprintf(out,"\".global _%s\\n\\t\"\n",name2);
42 fprintf(out,"\"_%s:\\n\\t\"\n",name);
43 fprintf(out,"\"_%s:\\n\\t\"\n",name2);
44 #endif
45 fprintf(out,"\t\"pushl\t%%ebp\\n\\t\"\n");
46 fprintf(out,"\t\"movl\t%%esp, %%ebp\\n\\t\"\n");
47 fprintf(out,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx);
48 fprintf(out,"\t\"lea\t8(%%ebp),%%edx\\n\\t\"\n");
49 fprintf(out,"\t\"int\t$0x2E\\n\\t\"\n");
50 fprintf(out,"\t\"popl\t%%ebp\\n\\t\"\n");
51 fprintf(out,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args);
52
53 /*
54 * Now write the NTOSKRNL stub for the
55 * current system call. ZwXXX does NOT
56 * alias the corresponding NtXXX call.
57 */
58 fprintf(out3,"__asm__(\n");
59 fprintf(out3,"\".global _%s@%s\\n\\t\"\n",name2,nr_args);
60 fprintf(out3,"\"_%s@%s:\\n\\t\"\n",name2,nr_args);
61 fprintf(out3,"\t\"pushl\t%%ebp\\n\\t\"\n");
62 fprintf(out3,"\t\"movl\t%%esp, %%ebp\\n\\t\"\n");
63 fprintf(out3,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx);
64 fprintf(out3,"\t\"lea\t8(%%ebp),%%edx\\n\\t\"\n");
65 fprintf(out3,"\t\"int\t$0x2E\\n\\t\"\n");
66 fprintf(out3,"\t\"popl\t%%ebp\\n\\t\"\n");
67 fprintf(out3,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args);
68 }
69
70 int makeSystemServiceTable(FILE *in, FILE *out)
71 {
72 char line [INPUT_BUFFER_SIZE];
73 char *s;
74 char *name;
75 char *name2;
76 int sys_call_idx;
77 char *nr_args;
78 char *stmp;
79
80 /*
81 * Main SSDT Header
82 */
83 fprintf(out,"// Machine generated, don't edit\n");
84 fprintf(out,"\n\n");
85
86 /*
87 * First we build the Main SSDT
88 */
89 fprintf(out,"\n\n\n");
90 fprintf(out,"SSDT MainSSDT[] = {\n");
91
92 for ( /* First system call has index zero */
93 sys_call_idx = 0;
94 /* Go on until EOF or read zero bytes */
95 ( (!feof(in))
96 && (fgets(line, sizeof line, in) != NULL)
97 );
98 /* Next system call index */
99 sys_call_idx++
100 )
101 {
102 if ((s = (char *) strchr(line,'\r')) != NULL)
103 {
104 *s = '\0';
105 }
106 /*
107 * Skip comments (#) and empty lines.
108 */
109 s = & line[0];
110 if ((*s) != '#' && (*s) != '\0')
111 {
112 /* Extract the NtXXX name */
113 name = (char *)strtok(s," \t");
114 /* Extract the ZwXXX name */
115 name2 = (char *)strtok(NULL," \t");
116 //value = strtok(NULL," \t");
117 /* Extract the stack size */
118 nr_args = (char *)strtok(NULL," \t");
119 /*
120 * Remove, if present, the trailing LF.
121 */
122 if ((stmp = strchr(nr_args, '\n')) != NULL)
123 {
124 *stmp = '\0';
125 }
126 #ifdef VERBOSE
127 printf("%3d \"%s\"\n",sys_call_idx,name);
128 #endif
129
130 if (sys_call_idx > 0)
131 {
132 fprintf(out,",\n");
133 }
134 /*
135 * Now write the current system call's name
136 * in the service table.
137 */
138 fprintf(out,"\t\t{ (ULONG)%s }",name);
139 }
140 }
141 /* Close the service table (C syntax) */
142 fprintf(out,"\n};\n");
143
144 /*
145 * Now we build the Main SSPT
146 */
147 rewind(in);
148 fprintf(out,"\n\n\n");
149 fprintf(out,"SSPT MainSSPT[] = {\n");
150
151 for ( /* First system call has index zero */
152 sys_call_idx = 0;
153 /* Go on until EOF or read zero bytes */
154 ( (!feof(in))
155 && (fgets(line, sizeof line, in) != NULL)
156 );
157 /* Next system call index */
158 sys_call_idx++
159 )
160 {
161 if ((s = (char *) strchr(line,'\r')) != NULL)
162 {
163 *s = '\0';
164 }
165 /*
166 * Skip comments (#) and empty lines.
167 */
168 s = & line[0];
169 if ((*s) != '#' && (*s) != '\0')
170 {
171 /* Extract the NtXXX name */
172 name = (char *)strtok(s," \t");
173 /* Extract the ZwXXX name */
174 name2 = (char *)strtok(NULL," \t");
175 //value = strtok(NULL," \t");
176 /* Extract the stack size */
177 nr_args = (char *)strtok(NULL," \t");
178 /*
179 * Remove, if present, the trailing LF.
180 */
181 if ((stmp = strchr(nr_args, '\n')) != NULL)
182 {
183 *stmp = '\0';
184 }
185 #ifdef VERBOSE
186 printf("%3d \"%s\"\n",sys_call_idx,name);
187 #endif
188
189 if (sys_call_idx > 0)
190 {
191 fprintf(out,",\n");
192 }
193 /*
194 * Now write the current system call's ID
195 * in the service table along with its Parameters Size.
196 */
197 fprintf(out,"\t\t{ %s }",nr_args);
198 }
199 }
200 /*
201 * Close the service table (C syntax)
202 */
203 fprintf(out,"\n};\n");
204
205 /*
206 * We write some useful defines
207 */
208 fprintf(out, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
209 fprintf(out, "#define MAX_SYSCALL_NUMBER %d\n", sys_call_idx-1);
210 fprintf(out, "#define NUMBER_OF_SYSCALLS %d\n", sys_call_idx);
211
212 return(0);
213 }
214
215
216 int
217 process(
218 FILE * in,
219 FILE * out,
220 FILE * out2,
221 FILE * out3
222 )
223 {
224 char line [INPUT_BUFFER_SIZE];
225 char * s;
226 char * name; /* NtXXX name */
227 char * name2; /* ZwXXX name */
228 int sys_call_idx; /* NtXXX index number in the service table */
229 char * nr_args; /* stack_size / machine_word_size */
230 char * stmp;
231
232 /*
233 * NTDLL stubs file header
234 */
235 fprintf(out,"// Machine generated, don't edit\n");
236 fprintf(out,"\n\n");
237
238 /*
239 * NTOSKRNL Zw functions stubs header
240 */
241 fprintf(out3,"// Machine generated, don't edit\n");
242 fprintf(out3,"\n\n");
243 /*
244 * Scan the database. DB is a text file; each line
245 * is a record, which contains data for one system
246 * function. Each record has three columns:
247 *
248 * NT_NAME (e.g. NtCreateProcess)
249 * ZW_NAME (e.g. ZwCreateProcess)
250 * STACK_SIZE (in machine words: for x[3456]86
251 * processors a machine word is 4 bytes)
252 */
253 for ( /* First system call has index zero */
254 sys_call_idx = 0;
255 /* Go on until EOF or read zero bytes */
256 ( (!feof(in))
257 && (fgets(line, sizeof line, in) != NULL)
258 );
259 /* Next system call index */
260 sys_call_idx++
261 )
262 {
263 /*
264 * Remove, if present, the trailing CR.
265 * (os specific?)
266 */
267 if ((s = (char *) strchr(line,'\r')) != NULL)
268 {
269 *s = '\0';
270 }
271 /*
272 * Skip comments (#) and empty lines.
273 */
274 s = & line[0];
275 if ((*s) != '#' && (*s) != '\0')
276 {
277 /* Extract the NtXXX name */
278 name = (char *)strtok(s," \t");
279 /* Extract the ZwXXX name */
280 name2 = (char *)strtok(NULL," \t");
281 //value = strtok(NULL," \t");
282 /* Extract the stack size */
283 nr_args = (char *)strtok(NULL," \t");
284 /*
285 * Remove, if present, the trailing LF.
286 */
287 if ((stmp = strchr(nr_args, '\n')) != NULL)
288 {
289 *stmp = '\0';
290 }
291 #ifdef VERBOSE
292 printf("%3d \"%s\"\n",sys_call_idx,name);
293 #endif
294 /*
295 * Write the NTDLL stub for the current
296 * system call: NtXXX and ZwXXX symbols
297 * are aliases.
298 */
299 write_syscall_stub(out, out3, name, name2,
300 nr_args, sys_call_idx);
301 }
302 }
303
304 return(0);
305 }
306
307 void usage(char * argv0)
308 {
309 printf("Usage: %s sysfuncs.lst napi.c napi.h zw.c\n"
310 " sysfuncs.lst system functions database\n"
311 " napi.c NTDLL stubs\n"
312 " napi.h NTOSKRNL service table\n"
313 " zw.c NTOSKRNL Zw stubs\n",
314 argv0
315 );
316 }
317
318 int main(int argc, char* argv[])
319 {
320 FILE * in; /* System calls database */
321 FILE * out1; /* NTDLL stubs */
322 FILE * out2; /* SERVICE_TABLE */
323 FILE * out3; /* NTOSKRNL Zw stubs */
324 int ret;
325
326 if (argc != 5)
327 {
328 usage(argv[0]);
329 return(1);
330 }
331
332 in = fopen(argv[1],"rb");
333 if (in == NULL)
334 {
335 perror("Failed to open input file (system calls database)");
336 return(1);
337 }
338
339 out1 = fopen(argv[2],"wb");
340 if (out1 == NULL)
341 {
342 perror("Failed to open output file (NTDLL stubs)");
343 return(1);
344 }
345
346 out2 = fopen(argv[3],"wb");
347 if (out2 == NULL)
348 {
349 perror("Failed to open output file (NTOSKRNL service table)");
350 return(1);
351 }
352
353 out3 = fopen(argv[4],"wb");
354 if (out3 == NULL)
355 {
356 perror("Failed to open output file (NTOSKRNL Zw stubs)");
357 return(1);
358 }
359
360 ret = process(in,out1,out2,out3);
361 rewind(in);
362 ret = makeSystemServiceTable(in, out2);
363
364 fclose(in);
365 fclose(out1);
366 fclose(out2);
367 fclose(out3);
368
369 return(ret);
370 }