Add new OSS License
[mirror_edk2.git] / Tools / Source / TianoTools / ZeroDebugData / ZeroDebugData.c
CommitLineData
d25c4bf0 1/*++\r
2\r
cf171110 3Copyright (c) 2004-2006 Intel Corporation. All rights reserved\r
d25c4bf0 4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
d25c4bf0 12Module Name:\r
13 ZeroDebugData.c\r
14\r
15Abstract:\r
16 Zero the Debug Data Fields of Portable Executable (PE) format file.\r
17\r
18--*/\r
19\r
20#include <stdio.h>\r
21#include <string.h>\r
22#include <stdlib.h>\r
d25c4bf0 23\r
24void\r
25PrintUsage (\r
26 void\r
27 )\r
28/*++\r
29Routine Description:\r
30 print usage of ZeroDebugData command\r
31\r
32Arguments:\r
33 None\r
34\r
35Returns:\r
36 None\r
37--*/\r
38// GC_TODO: void - add argument and description to function comment\r
39{\r
40 //\r
41 // print usage of command\r
42 //\r
43 printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");\r
44}\r
45\r
46int\r
47ReadFromFile (\r
48 FILE *fp,\r
49 long offset,\r
50 void *buffer,\r
51 int size\r
52 )\r
53/*++\r
54Routine Description:\r
55 read data from a specified location of file\r
56\r
57Arguments:\r
58 fp - file pointer\r
59 offset - number of bytes from beginning of file\r
60 buffer - buffer used to store data\r
61 size - size of buffer\r
62\r
63Returns:\r
64 = 0 - Success\r
65 = -1 - Failed\r
66--*/\r
67{\r
68 //\r
69 // set file pointer to the specified location of file\r
70 //\r
71 if (fseek (fp, offset, SEEK_SET) != 0) {\r
72 printf ("Error: Cannot move the current location of the file.\n");\r
73 return -1;\r
74 }\r
75 //\r
76 // read data from the file\r
77 //\r
78 if (fread (buffer, size, 1, fp) != 1) {\r
79 printf ("Error: Cannot read data from the file.\n");\r
80 return -1;\r
81 }\r
82\r
83 return 0;\r
84}\r
85\r
86int\r
87ZeroDebugData (\r
88 FILE *fp,\r
89 FILE *fpData\r
90 )\r
91/*++\r
92\r
93Routine Description:\r
94\r
95 Zero the debug data fields of the file\r
96\r
97Arguments:\r
98\r
99 fp - file pointer\r
100 fpData - pointer to output file that ZeroDebugData progress is written to\r
101\r
102Returns:\r
103\r
104 = 0 - Success\r
105 = -1 - Failed\r
106\r
107--*/\r
108{\r
109 unsigned char header[4];\r
110 unsigned long offset;\r
111 unsigned long NumberOfRvaAndSizes;\r
112 unsigned int nvalue;\r
113 unsigned long lvalue;\r
114 unsigned long Size;\r
115 unsigned long Pointer;\r
116 unsigned char *Buffer;\r
117 unsigned long Index;\r
118\r
119 //\r
120 // read the header of file\r
121 //\r
122 if (ReadFromFile (fp, 0, header, 2) != 0) {\r
123 printf ("Error: open image file\n");\r
124 return -1;\r
125 }\r
126 //\r
127 // "MZ" -- the header of image file (PE)\r
128 //\r
129 if (strncmp ((char *) header, "MZ", 2) != 0) {\r
130 printf ("Error: Invalid Image file.\n");\r
131 return -1;\r
132 }\r
133 //\r
134 // At location 0x3C, the stub has the file offset to the\r
135 // PE signature.\r
136 //\r
137 if (ReadFromFile (fp, 0x3C, &offset, 4) != 0) {\r
138 return -1;\r
139 }\r
140 //\r
141 // read the header of optional\r
142 //\r
143 if (ReadFromFile (fp, offset, header, 4) != 0) {\r
144 return -1;\r
145 }\r
146 //\r
147 // "PE\0\0" -- the signature of optional header\r
148 //\r
149 if (strncmp ((char *) header, "PE\0\0", 4) != 0) {\r
150 printf ("Error: Invalid PE format file.\n");\r
151 return -1;\r
152 }\r
153 //\r
154 // Add 16 to skip COFF file header, and get to optional header.\r
155 //\r
156 offset += 24;\r
157\r
158 //\r
159 // Check the magic field, 0x10B for PE32 and 0x20B for PE32+\r
160 //\r
161 if (ReadFromFile (fp, offset, &nvalue, 2) != 0) {\r
162 return -1;\r
163 }\r
164 //\r
165 // If this is PE32 image file, offset of NumberOfRvaAndSizes is 92.\r
166 // Else it is 108.\r
167 //\r
168 switch (nvalue & 0xFFFF) {\r
169 case 0x10B:\r
170 offset += 92;\r
171 printf ("Info: Image is PE32. ");\r
172 break;\r
173\r
174 case 0x20B:\r
175 offset += 108;\r
176 printf ("Info: Image is PE32+. ");\r
177 break;\r
178\r
179 default:\r
180 printf ("Error: Magic value is unknown.\n");\r
181 return -1;\r
182 }\r
183 //\r
184 // get the value of NumberOfRvaAndSizes\r
185 //\r
186 if (ReadFromFile (fp, offset, &NumberOfRvaAndSizes, 4) != 0) {\r
187 printf ("Error: read NumberOfRvaAndSizes error.\n");\r
188 return -1;\r
189 }\r
190 //\r
191 // printf ("Info: NumberOfRvaAndSizes = %d\n", NumberOfRvaAndSizes);\r
192 //\r
193 //\r
194 // Finding Debug Table, offset of Debug Table\r
195 // is 4 + 6 * 8 = 52.\r
196 //\r
197 if (NumberOfRvaAndSizes >= 7) {\r
198 if (ReadFromFile (fp, offset + 52, &lvalue, 4) != 0) {\r
199 return -1;\r
200 }\r
201 //\r
202 // Read the SizeOfData(16) and PointerToRawData(24)\r
203 //\r
204 if (ReadFromFile (fp, lvalue + 16, &Size, 4) != 0) {\r
205 printf ("error: Size = %d\n", Size);\r
206 return -1;\r
207 }\r
208\r
209 printf ("Debug data: size = %xh, ", Size);\r
210 fprintf (fpData, "Debug data: size = %xh, ", Size);\r
211\r
212 if (ReadFromFile (fp, lvalue + 20, &Pointer, 4) != 0) {\r
213 printf ("error: LoadOffset = %xh\n", Pointer);\r
214 return -1;\r
215 }\r
216 //\r
217 // printf ("LoadOffset = %xh, ", Pointer);\r
218 //\r
219 fprintf (fpData, "LoadOffset = %xh, ", Pointer);\r
220\r
221 if (ReadFromFile (fp, lvalue + 24, &Pointer, 4) != 0) {\r
222 printf ("error: FileOffset = %xh\n", Pointer);\r
223 return -1;\r
224 }\r
225\r
226 printf ("FileOffset = %xh, ", Pointer);\r
227 fprintf (fpData, "FileOffset = %xh, \n", Pointer);\r
228\r
229 if ((lvalue != 0) && (Pointer != 0)) {\r
230 //\r
231 // prepare buffer\r
232 //\r
233 Buffer = malloc (Size + 1);\r
234 if (Buffer == NULL) {\r
235 printf ("Error: Cannot allocate memory.\n");\r
236 return -1;\r
237 }\r
238 //\r
239 // set file pointer to the specified location of file\r
240 //\r
241 if (fseek (fp, Pointer, SEEK_SET) != 0) {\r
242 printf ("Error: Cannot move the current location of the file.\n");\r
243 free (Buffer);\r
244 return -1;\r
245 }\r
246 //\r
247 // read data from PE file\r
248 //\r
249 if (fread (Buffer, Size, 1, fp) != 1) {\r
250 printf ("Error: Cannot read data from the file.\n");\r
251 free (Buffer);\r
252 return -1;\r
253 }\r
254 //\r
255 // write to data file\r
256 //\r
257 for (Index = 0; Index < Size;) {\r
258 fprintf (fpData, "%02x ", Buffer[Index]);\r
259\r
260 Index++;\r
261 if (Index % 8 == 0) {\r
262 fprintf (fpData, "\n");\r
263 }\r
264 }\r
265\r
266 fprintf (fpData, "\n");\r
267\r
268 //\r
269 // zero buffer and write back to PE file\r
270 //\r
271 if (fseek (fp, Pointer, SEEK_SET) != 0) {\r
272 printf ("Error: Cannot move the current location of the file.\n");\r
273 free (Buffer);\r
274 return -1;\r
275 }\r
276\r
277 memset (Buffer, 0, Size);\r
278 if (fwrite (Buffer, Size, 1, fp) != 1) {\r
279 perror ("Error: Cannot write zero to the file.\n");\r
280 free (Buffer);\r
281 return -1;\r
282 }\r
283 //\r
284 // set file pointer to the specified location of file\r
285 //\r
286 if (fseek (fp, lvalue + 4, SEEK_SET) != 0) {\r
287 printf ("Error: Cannot move the current location of the file.\n");\r
288 free (Buffer);\r
289 return -1;\r
290 }\r
291\r
292 if (fwrite (Buffer, 4, 1, fp) != 1) {\r
293 perror ("Error: Cannot write zero to the file.\n");\r
294 free (Buffer);\r
295 return -1;\r
296 }\r
297\r
298 free (Buffer);\r
299 }\r
300 }\r
301\r
302 return 0;\r
303}\r
304\r
305int\r
306main (\r
307 int argc,\r
308 char *argv[]\r
309 )\r
310/*++\r
311\r
312Routine Description:\r
313\r
314 Prints the zero debug data of the PE file to the DebugData file.\r
315 Executes the ZeroDebugData function.\r
316\r
317Arguments:\r
318\r
319 argc - Standard C argument, number of command line arguments.\r
320 argv[] - Standard C argument, array of pointers to the input files,\r
321 such as the PE and DebugData files.\r
322\r
323Returns:\r
324\r
325 zero - success\r
326 nonzero - failure\r
327\r
328--*/\r
329{\r
330 FILE *fp;\r
331 FILE *fpData;\r
332 char DataFile[1024] = "";\r
333\r
334 //\r
335 // check the number of parameters\r
336 //\r
337 if (argc < 2) {\r
338 printf ("\nUsage: ZeroDebugData <PE-File> [DebugData-File]\n");\r
339 return -1;\r
340 }\r
341 //\r
342 // open the DebugData file, if not exists, return\r
343 //\r
344 if (argc >= 3) {\r
345 strcpy (DataFile, argv[2]);\r
346 } else {\r
347 strcpy (DataFile, "DebugData.dat");\r
348 }\r
349\r
350 fpData = fopen (DataFile, "a+");\r
351 if (fpData == NULL) {\r
352 fpData = fopen (DataFile, "w");\r
353 if (fpData == NULL) {\r
354 printf ("Error: Cannot open the data file!\n");\r
355 return -1;\r
356 }\r
357 }\r
358 //\r
359 // open the PE file\r
360 //\r
361 fp = fopen (argv[1], "r+b");\r
362 if (fp == NULL) {\r
363 printf ("Error: Cannot open the PE file!\n");\r
364 return -1;\r
365 }\r
366 //\r
367 // Zero the Debug Data to the PE file\r
368 //\r
369 printf ("Zero Debug Data to file %s:\n", argv[1]);\r
370 fprintf (fpData, "\nZero Debug Data to file %s:\n", argv[1]);\r
371 if ((int *) ZeroDebugData (fp, fpData) != 0) {\r
372 printf ("Error: Zero Debug Data PE file\n");\r
373 fclose (fp);\r
374 return -1;\r
375 }\r
376\r
377 printf (" success\n");\r
378\r
379 //\r
380 // close the PE file\r
381 //\r
382 fflush (fpData);\r
383 fflush (fp);\r
384 fclose (fpData);\r
385 fclose (fp);\r
386\r
387 return 0;\r
388}\r