1 /* $Id: genntdll.c,v 1.12 2003/01/03 00:28:07 guido 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
)
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
);
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
);
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
);
54 * Now write the NTOSKRNL stub for the
55 * current system call. ZwXXX does NOT
56 * alias the corresponding NtXXX call.
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
);
70 int makeSystemServiceTable(FILE *in
, FILE *out
)
72 char line
[INPUT_BUFFER_SIZE
];
83 fprintf(out
,"// Machine generated, don't edit\n");
87 * First we build the Main SSDT
89 fprintf(out
,"\n\n\n");
90 fprintf(out
,"SSDT MainSSDT[] = {\n");
92 for ( /* First system call has index zero */
94 /* Go on until EOF or read zero bytes */
96 && (fgets(line
, sizeof line
, in
) != NULL
)
98 /* Next system call index */
102 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
107 * Skip comments (#) and empty lines.
110 if ((*s
) != '#' && (*s
) != '\0')
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");
120 * Remove, if present, the trailing LF.
122 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
127 printf("%3d \"%s\"\n",sys_call_idx
,name
);
130 if (sys_call_idx
> 0)
135 * Now write the current system call's name
136 * in the service table.
138 fprintf(out
,"\t\t{ (ULONG)%s }",name
);
141 /* Close the service table (C syntax) */
142 fprintf(out
,"\n};\n");
145 * Now we build the Main SSPT
148 fprintf(out
,"\n\n\n");
149 fprintf(out
,"SSPT MainSSPT[] = {\n");
151 for ( /* First system call has index zero */
153 /* Go on until EOF or read zero bytes */
155 && (fgets(line
, sizeof line
, in
) != NULL
)
157 /* Next system call index */
161 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
166 * Skip comments (#) and empty lines.
169 if ((*s
) != '#' && (*s
) != '\0')
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");
179 * Remove, if present, the trailing LF.
181 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
186 printf("%3d \"%s\"\n",sys_call_idx
,name
);
189 if (sys_call_idx
> 0)
194 * Now write the current system call's ID
195 * in the service table along with its Parameters Size.
197 fprintf(out
,"\t\t{ %s }",nr_args
);
201 * Close the service table (C syntax)
203 fprintf(out
,"\n};\n");
206 * We write some useful defines
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
);
224 char line
[INPUT_BUFFER_SIZE
];
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 */
233 * NTDLL stubs file header
235 fprintf(out
,"// Machine generated, don't edit\n");
239 * NTOSKRNL Zw functions stubs header
241 fprintf(out3
,"// Machine generated, don't edit\n");
242 fprintf(out3
,"\n\n");
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:
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)
253 for ( /* First system call has index zero */
255 /* Go on until EOF or read zero bytes */
257 && (fgets(line
, sizeof line
, in
) != NULL
)
259 /* Next system call index */
264 * Remove, if present, the trailing CR.
267 if ((s
= (char *) strchr(line
,'\r')) != NULL
)
272 * Skip comments (#) and empty lines.
275 if ((*s
) != '#' && (*s
) != '\0')
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");
285 * Remove, if present, the trailing LF.
287 if ((stmp
= strchr(nr_args
, '\n')) != NULL
)
292 printf("%3d \"%s\"\n",sys_call_idx
,name
);
295 * Write the NTDLL stub for the current
296 * system call: NtXXX and ZwXXX symbols
299 write_syscall_stub(out
, out3
, name
, name2
,
300 nr_args
, sys_call_idx
);
307 void usage(char * argv0
)
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",
318 int main(int argc
, char* argv
[])
320 FILE * in
; /* System calls database */
321 FILE * out1
; /* NTDLL stubs */
322 FILE * out2
; /* SERVICE_TABLE */
323 FILE * out3
; /* NTOSKRNL Zw stubs */
332 in
= fopen(argv
[1],"rb");
335 perror("Failed to open input file (system calls database)");
339 out1
= fopen(argv
[2],"wb");
342 perror("Failed to open output file (NTDLL stubs)");
346 out2
= fopen(argv
[3],"wb");
349 perror("Failed to open output file (NTOSKRNL service table)");
353 out3
= fopen(argv
[4],"wb");
356 perror("Failed to open output file (NTOSKRNL Zw stubs)");
360 ret
= process(in
,out1
,out2
,out3
);
362 ret
= makeSystemServiceTable(in
, out2
);