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