03827fded7eb9e13565a33f6c2755ec7f7880c7b
[reactos.git] / reactos / iface / native / genntdll.c
1 /* $Id: genntdll.c,v 1.7 1999/06/17 18:09:27 ea 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 int
32 process(
33 FILE * in,
34 FILE * out,
35 FILE * out2,
36 FILE * out3
37 )
38 {
39 char line [INPUT_BUFFER_SIZE];
40 char * s;
41 char * name; /* NtXXX name */
42 char * name2; /* ZwXXX name */
43 int sys_call_idx; /* NtXXX index number in the service table */
44 char * nr_args; /* stack_size / machine_word_size */
45 char * stmp;
46
47 /*
48 * NTDLL stubs file header
49 */
50 fprintf(out,"// Machine generated, don't edit\n");
51 fprintf(out,"\n\n");
52 /*
53 * Service table header
54 */
55 fprintf(out2,"// Machine generated, don't edit\n");
56 fprintf(out2,"\n\n");
57 //fprintf(out2,"#include <ntddk.h>");
58 fprintf(out2,"\n\n\n");
59 fprintf(out2,"SERVICE_TABLE _SystemServiceTable[256] = {\n");
60 /*
61 * NTOSKRNL Zw functions stubs header
62 */
63 fprintf(out3,"// Machine generated, don't edit\n");
64 fprintf(out3,"\n\n");
65 /*
66 * Scan the database. DB is a text file; each line
67 * is a record, which contains data for one system
68 * function. Each record has three columns:
69 *
70 * NT_NAME (e.g. NtCreateProcess)
71 * ZW_NAME (e.g. ZwCreateProcess)
72 * STACK_SIZE (in machine words: for x[3456]86
73 * processors a machine word is 4 bytes)
74 */
75 for ( /* First system call has index zero */
76 sys_call_idx = 0;
77 /* Go on until EOF or read zero bytes */
78 ( (!feof(in))
79 && (fgets(line, sizeof line, in) != NULL)
80 );
81 /* Next system call index */
82 sys_call_idx++
83 )
84 {
85 //fgets(line,255,in);
86 /*
87 * Remove, if present, the trailing CR.
88 * (os specific?)
89 */
90 if ((s = (char *) strchr(line,'\r')) != NULL)
91 {
92 *s = '\0';
93 }
94 /*
95 * Skip comments (#) and empty lines.
96 */
97 s = & line[0];
98 if ((*s) != '#' && (*s) != '\0')
99 {
100 /* Extract the NtXXX name */
101 name = (char *)strtok(s," \t");
102 /* Extract the ZwXXX name */
103 name2 = (char *)strtok(NULL," \t");
104 //value = strtok(NULL," \t");
105 /* Extract the stack size */
106 nr_args = (char *)strtok(NULL," \t");
107 /*
108 * Remove, if present, the trailing LF.
109 */
110 if ((stmp = strchr(nr_args, '\n')) != NULL)
111 {
112 *stmp = '\0';
113 }
114 #ifdef VERBOSE
115 printf("name = \"%s\" value = %d\n",name,sys_call_idx);
116 #endif
117 /*
118 * Write the NTDLL stub for the current
119 * system call: NtXXX and ZwXXX symbols
120 * are aliases.
121 */
122 #ifdef PARAMETERIZED_LIBS
123 fprintf(out,"__asm__(\"\\n\\t.global _%s@%s\\n\\t\"\n",name,nr_args);
124 fprintf(out,"\".global _%s@%s\\n\\t\"\n",name2,nr_args);
125 fprintf(out,"\"_%s@%s:\\n\\t\"\n",name,nr_args);
126 fprintf(out,"\"_%s@%s:\\n\\t\"\n",name2,nr_args);
127 #else
128 fprintf(out,"__asm__(\"\\n\\t.global _%s\\n\\t\"\n",name);
129 fprintf(out,"\".global _%s\\n\\t\"\n",name2);
130 fprintf(out,"\"_%s:\\n\\t\"\n",name);
131 fprintf(out,"\"_%s:\\n\\t\"\n",name2);
132 #endif
133 fprintf(out,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx);
134 fprintf(out,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
135 fprintf(out,"\t\"int\t$0x2E\\n\\t\"\n");
136 fprintf(out,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args);
137 /*
138 * Mark the end of the previous service
139 * table's element (C array syntax). When
140 * the current function is the n-th, we
141 * close the (n - 1)-th entry.
142 */
143 if (sys_call_idx > 0)
144 {
145 fprintf(out2,",\n");
146 }
147 /*
148 * Now write the current system call's name
149 * in the service table.
150 */
151 fprintf(out2,"\t\t{ %s, (ULONG)%s }",nr_args,name);
152 /*
153 * Now write the NTOSKRNL stub for the
154 * current system call. ZwXXX does NOT
155 * alias the corresponding NtXXX call.
156 */
157 fprintf(out3,"__asm__(\n");
158 fprintf(out3,"\".global _%s@%s\\n\\t\"\n",name2,nr_args);
159 fprintf(out3,"\"_%s@%s:\\n\\t\"\n",name2,nr_args);
160 fprintf(out3,"\t\"mov\t$%d,%%eax\\n\\t\"\n",sys_call_idx);
161 fprintf(out3,"\t\"lea\t4(%%esp),%%edx\\n\\t\"\n");
162 fprintf(out3,"\t\"int\t$0x2E\\n\\t\"\n");
163 fprintf(out3,"\t\"ret\t$%s\\n\\t\");\n\n",nr_args);
164 }
165 }
166 /* Close the service table (C syntax) */
167 fprintf(out2,"\n};\n");
168
169 return(0);
170 }
171
172 void usage(char * argv0)
173 {
174 printf("\
175 Usage: %s sysfuncs.lst napi.c napi.h zw.c\n\
176 sysfuncs.lst system functions database\n\
177 napi.c NTDLL stubs\n\
178 napi.h NTOSKRNL service table\n\
179 zw.c NTOSKRNL Zw stubs\n",
180 argv0
181 );
182 }
183
184 int main(int argc, char* argv[])
185 {
186 FILE * in; /* System calls database */
187 FILE * out; /* NTDLL stubs */
188 FILE * out2; /* SERVICE_TABLE */
189 FILE * out3; /* NTOSKRNL Zw stubs */
190 int ret;
191
192 if (argc != 5)
193 {
194 usage(argv[0]);
195 return(1);
196 }
197
198 in = fopen(argv[1],"rb");
199 if (in == NULL)
200 {
201 perror("Failed to open input file (system calls database)");
202 return(1);
203 }
204
205 out = fopen(argv[2],"wb");
206 if (out == NULL)
207 {
208 perror("Failed to open output file (NTDLL stubs)");
209 return(1);
210 }
211 out2 = fopen(argv[3],"wb");
212 if (out2 == NULL)
213 {
214 perror("Failed to open output file (NTOSKRNL service table)");
215 return(1);
216 }
217 out3 = fopen(argv[4],"wb");
218 if (out3 == NULL)
219 {
220 perror("Failed to open output file (NTOSKRNL Zw stubs)");
221 return(1);
222 }
223
224 ret = process(in,out,out2,out3);
225
226 fclose(in);
227 fclose(out);
228 fclose(out2);
229 fclose(out3);
230
231 return(ret);
232 }