[TOOLS]
[reactos.git] / reactos / tools / geninc / geninc.c
1 /*
2 * Generates assembly definitions from the target headers.
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #define IMAGE_FILE_MACHINE_I386 0x014c
10 #define IMAGE_FILE_MACHINE_AMD64 0x8664
11 #define IMAGE_FILE_MACHINE_ARMNT 0x01c4
12
13 #ifdef _WIN32
14 #define PRIx64 "I64x"
15 typedef unsigned __int16 uint16_t;
16 typedef unsigned __int32 uint32_t;
17 typedef unsigned __int64 uint64_t;
18 #else
19 #include <stdint.h>
20 #define PRIx64 "llx"
21 #define _stricmp strcasecmp
22 #endif
23
24 typedef struct
25 {
26 char Type;
27 char Name[55];
28 uint64_t Value;
29 } ASMGENDATA;
30
31 #define TYPE_END 0
32 #define TYPE_RAW 1
33 #define TYPE_CONSTANT 2
34 #define TYPE_HEADER 3
35
36 int main(int argc, char* argv[])
37 {
38 FILE *input, *output;
39 ASMGENDATA data;
40 int i, result = -1;
41 int ms_format = 0;
42 char header[20];
43 uint32_t e_lfanew, signature;
44 uint16_t Machine, NumberOfSections, SizeOfOptionalHeader;
45 typedef struct
46 {
47 char Name[8];
48 uint32_t VirtualSize;
49 uint32_t VirtualAddress;
50 uint32_t RawSize;
51 uint32_t RawAddress;
52 uint32_t RelocAddress;
53 uint32_t LineNumbers;
54 uint16_t RelocationsNumber;
55 uint16_t LineNumbersNumber;
56 uint32_t Characteristics;
57 } SECTION;
58 SECTION section;
59
60 if (argc >= 4 && _stricmp(argv[3], "-ms") == 0) ms_format = 1;
61
62 /* Open the input file */
63 input = fopen(argv[1], "rb");
64 if (!input)
65 {
66 fprintf(stderr, "Could not open input file '%s'\n", argv[1]);
67 return -1;
68 }
69
70 /* Open the output file */
71 output = fopen(argv[2], "w");
72 if (!output)
73 {
74 fclose(input);
75 fprintf(stderr, "Could not open output file '%s'\n", argv[2]);
76 return -1;
77 }
78
79 /* Read the DOS header */
80 if (fread(&header, 1, 2, input) != 2)
81 {
82 fprintf(stderr, "Error reading header.\n");
83 goto quit;
84 }
85
86 if (header[0] != 0x4d || header[1] != 0x5a)
87 {
88 fprintf(stderr, "Not a PE file.\n");
89 goto quit;
90 }
91
92 fseek(input, 0x3C, SEEK_SET);
93 if (fread(&e_lfanew, 1, 4, input) != 4)
94 {
95 fprintf(stderr, "Could not read e_lfanew.\n");
96 goto quit;
97 }
98
99 fseek(input, e_lfanew, SEEK_SET);
100 if (fread(&signature, 1, 4, input) != 4)
101 {
102 fprintf(stderr, "Could not read signature.\n");
103 goto quit;
104 }
105
106 /* Verify the PE signature */
107 if (signature != 0x4550)
108 {
109 fprintf(stderr, "Invalid signature: 0x%x.\n", signature);
110 goto quit;
111 }
112
113 /* Read Machine */
114 fseek(input, e_lfanew + 4, SEEK_SET);
115 if (fread(&Machine, 1, 2, input) != 2)
116 {
117 fprintf(stderr, "Could not read ExportDirectoryRVA.\n");
118 goto quit;
119 }
120
121 if ((Machine != IMAGE_FILE_MACHINE_I386) &&
122 (Machine != IMAGE_FILE_MACHINE_AMD64) &&
123 (Machine != IMAGE_FILE_MACHINE_ARMNT))
124 {
125 fprintf(stderr, "Invalid Machine: 0x%x.\n", Machine);
126 goto quit;
127 }
128
129 /* Read NumberOfSections */
130 if (fread(&NumberOfSections, 1, 2, input) != 2)
131 {
132 fprintf(stderr, "Could not read NumberOfSections.\n");
133 goto quit;
134 }
135
136 fseek(input, e_lfanew + 0x14, SEEK_SET);
137 if (fread(&SizeOfOptionalHeader, 1, 2, input) != 2)
138 {
139 fprintf(stderr, "Could not read SizeOfOptionalHeader.\n");
140 goto quit;
141 }
142
143 /* Read the section table */
144 fseek(input, e_lfanew + 0x18 + SizeOfOptionalHeader, SEEK_SET);
145
146 /* Search for the .asmdef section */
147 for (i = 0; i < NumberOfSections; i++)
148 {
149 if (fread(&section, 1, sizeof(SECTION), input) != sizeof(SECTION))
150 {
151 fprintf(stderr, "Could not read section.\n");
152 goto quit;
153 }
154
155 if (strcmp(section.Name, ".asmdef") == 0)
156 {
157 break;
158 }
159 }
160
161 if (i == NumberOfSections)
162 {
163 fprintf(stderr, "Could not find section.\n");
164 goto quit;
165 }
166
167 /* Read the section table */
168 fseek(input, section.RawAddress, SEEK_SET);
169
170 while (1)
171 {
172 /* Read one entry */
173 if (fread(&data, 1, sizeof(data), input) != sizeof(data))
174 {
175 fprintf(stderr, "Error reading input file.\n");
176 goto quit;
177 }
178
179 switch(data.Type)
180 {
181 case TYPE_END:
182 break;
183
184 case TYPE_RAW:
185 fprintf(output, "%s\n", data.Name);
186 continue;
187
188 case TYPE_CONSTANT:
189 if (ms_format)
190 {
191 fprintf(output, "%s equ 0%"PRIx64"h\n", data.Name, data.Value);
192 }
193 else
194 {
195 fprintf(output, "%s = 0x%"PRIx64"\n", data.Name, data.Value);
196 }
197 continue;
198
199 case TYPE_HEADER:
200 if (ms_format)
201 {
202 fprintf(output, "\n; %s\n", data.Name);
203 }
204 else
205 {
206 fprintf(output, "\n/* %s */\n", data.Name);
207 }
208 continue;
209 }
210
211 break;
212 }
213
214 result = 0;
215
216 quit:
217 /* Close files */
218 fclose(input);
219 fclose(output);
220
221 return result;
222 }