1 /* $Id: genntdll.c,v 1.1 2004/02/06 08:21:56 fireball Exp $
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 ]
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).
13 * Fixed a bug in function numbers in kernel ZwXXX stubs.
17 /* INCLUDE ******************************************************************/
23 #define PARAMETERIZED_LIBS
27 #define INPUT_BUFFER_SIZE 255
29 /* FUNCTIONS ****************************************************************/
31 void write_syscall_stub(FILE* out
, FILE* out3
, char* name
, char* name2
,
32 char* nr_args
, unsigned int sys_call_idx
)
35 int nArgBytes
= atoi(nr_args
);
36 #ifdef PARAMETERIZED_LIBS
37 fprintf(out
,"__asm__(\"\\n\\t.global _%s@%s\\n\\t\"\n",name
,nr_args
);
38 fprintf(out
,"\".global _%s@%s\\n\\t\"\n",name2
,nr_args
);
39 fprintf(out
,"\"_%s@%s:\\n\\t\"\n",name
,nr_args
);
40 fprintf(out
,"\"_%s@%s:\\n\\t\"\n",name2
,nr_args
);
42 fprintf(out
,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name
);
43 fprintf(out
,"\".global _%s\\n\\t\"\n",name2
);
44 fprintf(out
,"\"_%s:\\n\\t\"\n",name
);
45 fprintf(out
,"\"_%s:\\n\\t\"\n",name2
);
47 fprintf(out
,"\t\"pushl\t%%ebp\\n\\t\"\n");
48 fprintf(out
,"\t\"movl\t%%esp, %%ebp\\n\\t\"\n");
49 fprintf(out
,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx
);
50 fprintf(out
,"\t\"lea\t8(%%ebp),%%edx\\n\\t\"\n");
51 fprintf(out
,"\t\"int\t$0x2E\\n\\t\"\n");
52 fprintf(out
,"\t\"popl\t%%ebp\\n\\t\"\n");
53 fprintf(out
,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args
);
56 * Now write the NTOSKRNL stub for the
57 * current system call. ZwXXX does NOT
58 * alias the corresponding NtXXX call.
61 fprintf(out3
,"__asm__(\n");
62 fprintf(out3
,"\".global _%s@%s\\n\\t\"\n",name2
,nr_args
);
63 fprintf(out3
,"\"_%s@%s:\\n\\t\"\n",name2
,nr_args
);
64 fprintf(out3
,"\t\"pushl\t%%ebp\\n\\t\"\n");
65 fprintf(out3
,"\t\"movl\t%%esp, %%ebp\\n\\t\"\n");
66 fprintf(out3
,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx
);
67 fprintf(out3
,"\t\"lea\t8(%%ebp),%%edx\\n\\t\"\n");
68 fprintf(out3
,"\t\"int\t$0x2E\\n\\t\"\n");
69 fprintf(out3
,"\t\"popl\t%%ebp\\n\\t\"\n");
70 fprintf(out3
,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args
);
72 fprintf(out3
,"__declspec(naked) __stdcall\n");
73 fprintf(out3
,"%s(", name2
); // make it emit callconv, reval and full signature too
74 for (i
=0; i
*4 < nArgBytes
; ++i
) {
75 fprintf(out3
,"int dummy%d", i
);
76 if (((i
+1)*4) < nArgBytes
) fprintf(out3
,",");
78 fprintf(out3
,")\n{\n");
79 fprintf(out3
,"\t__asm {\n");
80 fprintf(out3
,"\t\tpush\tebp\n");
81 fprintf(out3
,"\t\tmov\tebp, esp\n");
82 fprintf(out3
,"\t\tmov\teax,%d\n",sys_call_idx
);
83 fprintf(out3
,"\t\tlea\tedx, 8[ebp]\n");
84 fprintf(out3
,"\t\tint\t0x2E\n");
85 fprintf(out3
,"\t\tpop\tebp\n");
86 fprintf(out3
,"\t\tret\t%s\n",nr_args
);
87 fprintf(out3
,"\t}\n");
88 fprintf(out3
,"}\n\n");
92 int makeSystemServiceTable(FILE *in
, FILE *out
)
94 char line
[INPUT_BUFFER_SIZE
];
105 fprintf(out
,"// Machine generated, don't edit\n");
109 * First we build the Main SSDT
111 fprintf(out
,"\n\n\n");
112 fprintf(out
,"SSDT MainSSDT[] = {\n");
114 for ( /* First system call has index zero */
116 /* Go on until EOF or read zero bytes */
118 && (fgets(line
, sizeof line
, in
) != NULL
)
120 /* Next system call index */
124 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
129 * Skip comments (#) and empty lines.
132 if ((*s
) != '#' && (*s
) != '\0')
134 /* Extract the NtXXX name */
135 name
= (char *)strtok(s
," \t");
136 /* Extract the ZwXXX name */
137 name2
= (char *)strtok(NULL
," \t");
138 //value = strtok(NULL," \t");
139 /* Extract the stack size */
140 nr_args
= (char *)strtok(NULL
," \t");
142 * Remove, if present, the trailing LF.
144 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
149 printf("%3d \"%s\"\n",sys_call_idx
,name
);
152 if (sys_call_idx
> 0)
157 * Now write the current system call's name
158 * in the service table.
160 fprintf(out
,"\t\t{ (ULONG)%s }",name
);
163 /* Close the service table (C syntax) */
164 fprintf(out
,"\n};\n");
167 * Now we build the Main SSPT
170 fprintf(out
,"\n\n\n");
171 fprintf(out
,"SSPT MainSSPT[] = {\n");
173 for ( /* First system call has index zero */
175 /* Go on until EOF or read zero bytes */
177 && (fgets(line
, sizeof line
, in
) != NULL
)
179 /* Next system call index */
183 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
188 * Skip comments (#) and empty lines.
191 if ((*s
) != '#' && (*s
) != '\0')
193 /* Extract the NtXXX name */
194 name
= (char *)strtok(s
," \t");
195 /* Extract the ZwXXX name */
196 name2
= (char *)strtok(NULL
," \t");
197 //value = strtok(NULL," \t");
198 /* Extract the stack size */
199 nr_args
= (char *)strtok(NULL
," \t");
201 * Remove, if present, the trailing LF.
203 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
208 printf("%3d \"%s\"\n",sys_call_idx
,name
);
211 if (sys_call_idx
> 0)
216 * Now write the current system call's ID
217 * in the service table along with its Parameters Size.
219 fprintf(out
,"\t\t{ %s }",nr_args
);
223 * Close the service table (C syntax)
225 fprintf(out
,"\n};\n");
228 * We write some useful defines
230 fprintf(out
, "\n\n#define MIN_SYSCALL_NUMBER 0\n");
231 fprintf(out
, "#define MAX_SYSCALL_NUMBER %d\n", sys_call_idx
-1);
232 fprintf(out
, "#define NUMBER_OF_SYSCALLS %d\n", sys_call_idx
);
246 char line
[INPUT_BUFFER_SIZE
];
248 char * name
; /* NtXXX name */
249 char * name2
; /* ZwXXX name */
250 int sys_call_idx
; /* NtXXX index number in the service table */
251 char * nr_args
; /* stack_size / machine_word_size */
255 * NTDLL stubs file header
257 fprintf(out
,"// Machine generated, don't edit\n");
261 * NTOSKRNL Zw functions stubs header
263 fprintf(out3
,"// Machine generated by genntdll, don't edit\n");
264 fprintf(out3
,"\n\n");
266 * Scan the database. DB is a text file; each line
267 * is a record, which contains data for one system
268 * function. Each record has three columns:
270 * NT_NAME (e.g. NtCreateProcess)
271 * ZW_NAME (e.g. ZwCreateProcess)
272 * STACK_SIZE (in machine words: for x[3456]86
273 * processors a machine word is 4 bytes)
275 for ( /* First system call has index zero */
277 /* Go on until EOF or read zero bytes */
279 && (fgets(line
, sizeof line
, in
) != NULL
)
281 /* Next system call index */
286 * Remove, if present, the trailing CR.
289 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
294 * Skip comments (#) and empty lines.
297 if ((*s
) != '#' && (*s
) != '\0')
299 /* Extract the NtXXX name */
300 name
= (char *)strtok(s
," \t");
301 /* Extract the ZwXXX name */
302 name2
= (char *)strtok(NULL
," \t");
303 //value = strtok(NULL," \t");
304 /* Extract the stack size */
305 nr_args
= (char *)strtok(NULL
," \t");
307 * Remove, if present, the trailing LF.
309 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
314 printf("%3d \"%s\"\n",sys_call_idx
,name
);
317 * Write the NTDLL stub for the current
318 * system call: NtXXX and ZwXXX symbols
321 write_syscall_stub(out
, out3
, name
, name2
,
322 nr_args
, sys_call_idx
);
329 void usage(char * argv0
)
331 printf("Usage: %s sysfuncs.lst napi.c napi.h zw.c\n"
332 " sysfuncs.lst system functions database\n"
333 " napi.c NTDLL stubs\n"
334 " napi.h NTOSKRNL service table\n"
335 " zw.c NTOSKRNL Zw stubs\n",
340 int main(int argc
, char* argv
[])
342 FILE * in
; /* System calls database */
343 FILE * out1
; /* NTDLL stubs */
344 FILE * out2
; /* SERVICE_TABLE */
345 FILE * out3
; /* NTOSKRNL Zw stubs */
354 in
= fopen(argv
[1],"rb");
357 perror("Failed to open input file (system calls database)");
361 out1
= fopen(argv
[2],"wb");
364 perror("Failed to open output file (NTDLL stubs)");
368 out2
= fopen(argv
[3],"wb");
371 perror("Failed to open output file (NTOSKRNL service table)");
375 out3
= fopen(argv
[4],"wb");
378 perror("Failed to open output file (NTOSKRNL Zw stubs)");
382 ret
= process(in
,out1
,out2
,out3
);
384 ret
= makeSystemServiceTable(in
, out2
);