Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1726)

Side by Side Diff: third_party/codesighs/msdump2symdb.c

Issue 93155: Capture Mozilla's codesighs, for use in executable sizing.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/codesighs/maptsvdifftool.c ('k') | third_party/codesighs/msmap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is msdump2symdb.c code, released
17 * Jan 16, 2003.
18 *
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 2002
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 * Garrett Arch Blythe, 16-January-2003
26 *
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
38 *
39 * ***** END LICENSE BLOCK ***** */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45 #include <ctype.h>
46 #include <errno.h>
47
48 #define ERROR_REPORT(num, val, msg) fprintf(stderr, "error(%d):\t\"%s\"\t%s\n" , (num), (val), (msg));
49 #define CLEANUP(ptr) do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while( 0)
50
51
52 typedef struct __struct_Options
53 /*
54 ** Options to control how we perform.
55 **
56 ** mProgramName Used in help text.
57 ** mInput File to read for input.
58 ** Default is stdin.
59 ** mInputName Name of the file.
60 ** mOutput Output file, append.
61 ** Default is stdout.
62 ** mOutputName Name of the file.
63 ** mHelp Whether or not help should be shown.
64 */
65 {
66 const char* mProgramName;
67 FILE* mInput;
68 char* mInputName;
69 FILE* mOutput;
70 char* mOutputName;
71 int mHelp;
72 }
73 Options;
74
75
76 typedef struct __struct_Switch
77 /*
78 ** Command line options.
79 */
80 {
81 const char* mLongName;
82 const char* mShortName;
83 int mHasValue;
84 const char* mValue;
85 const char* mDescription;
86 }
87 Switch;
88
89 #define DESC_NEWLINE "\n\t\t"
90
91 static Switch gInputSwitch = {"--input", "-i", 1, NULL, "Specify input file." DE SC_NEWLINE "stdin is default."};
92 static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." DESC_NEWLINE "Appends if file exists." DESC_NEWLINE "stdout is default."};
93 static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."};
94
95 static Switch* gSwitches[] = {
96 &gInputSwitch,
97 &gOutputSwitch,
98 &gHelpSwitch
99 };
100
101
102 typedef struct __struct_MSDump_Symbol
103 /*
104 ** Struct to hold infomration on a symbol.
105 **
106 ** mSize Size of the symbol once all work is complete.
107 ** mOffset Offset of the symbol in the section.
108 ** mName Symbolic name.
109 */
110 {
111 unsigned mSize;
112 unsigned mOffset;
113 char* mName;
114 }
115 MSDump_Symbol;
116
117
118 typedef struct __struct_MSDump_Section
119 /*
120 ** Struct for holding information on a section.
121 **
122 ** mLength Length of the section in bytes.
123 ** mUsed Number of bytes used in the section thus far.
124 ** Should eventually match mLength after work is done.
125 ** mType Type of section, as string (.data, .text, et. al.)
126 ** mSymbols Symbols found inside the section.
127 ** mSymbolCount Number of symbols in array.
128 */
129 {
130 unsigned mLength;
131 unsigned mUsed;
132 char* mType;
133
134 MSDump_Symbol* mSymbols;
135 unsigned mSymbolCount;
136 }
137 MSDump_Section;
138
139
140 typedef struct __struct_MSDump_Object
141 /*
142 ** Struct for holding object's data.
143 */
144 {
145 char* mObject;
146
147 MSDump_Section* mSections;
148 unsigned mSectionCount;
149 }
150 MSDump_Object;
151
152
153 typedef struct __struct_MSDump_ReadState
154 /*
155 ** State flags while reading the input gives us hints on what to do.
156 **
157 ** mSkipLines Number of lines to skip without parsing.
158 ** mSectionDetails Section information next, like line length.
159 ** mCurrentObject Object file we are dealing with.
160 */
161 {
162 unsigned mSkipLines;
163 unsigned mSectionDetails;
164 MSDump_Object* mCurrentObject;
165 }
166 MSDump_ReadState;
167
168
169 typedef struct __struct_MSDump_Container
170 /*
171 ** Umbrella container for all data encountered.
172 */
173 {
174 MSDump_ReadState mReadState;
175
176 MSDump_Object* mObjects;
177 unsigned mObjectCount;
178 }
179 MSDump_Container;
180
181
182 void trimWhite(char* inString)
183 /*
184 ** Remove any whitespace from the end of the string.
185 */
186 {
187 int len = strlen(inString);
188
189 while(len)
190 {
191 len--;
192
193 if(isspace(*(inString + len)))
194 {
195 *(inString + len) = '\0';
196 }
197 else
198 {
199 break;
200 }
201 }
202 }
203
204
205 const char* skipWhite(const char* inString)
206 /*
207 ** Return pointer to first non white space character.
208 */
209 {
210 const char* retval = inString;
211
212 while('\0' != *retval && isspace(*retval))
213 {
214 retval++;
215 }
216
217 return retval;
218 }
219
220
221 const char* skipNonWhite(const char* inString)
222 /*
223 ** Return pointer to first white space character.
224 */
225 {
226 const char* retval = inString;
227
228 while('\0' != *retval && !isspace(*retval))
229 {
230 retval++;
231 }
232
233 return retval;
234 }
235
236
237 void slash2bs(char* inString)
238 /*
239 ** Change any forward slash to a backslash.
240 */
241 {
242 char* slash = inString;
243
244 while(NULL != (slash = strchr(slash, '/')))
245 {
246 *slash = '\\';
247 slash++;
248 }
249 }
250
251
252 const char* skipToArg(const char* inString, unsigned inArgIndex)
253 /*
254 ** Return pointer either to the arg or NULL.
255 ** 1 indexed.
256 */
257 {
258 const char* retval = NULL;
259
260 while(0 != inArgIndex && '\0' != *inString)
261 {
262 inArgIndex--;
263
264 inString = skipWhite(inString);
265 if(0 != inArgIndex)
266 {
267 inString = skipNonWhite(inString);
268 }
269 }
270
271 if('\0' != *inString)
272 {
273 retval = inString;
274 }
275
276 return retval;
277 }
278
279
280 const char* getLastArg(const char* inString)
281 /*
282 ** Return pointer to last arg in string.
283 */
284 {
285 const char* retval = NULL;
286 int length = 0;
287 int sawString = 0;
288
289 length = strlen(inString);
290 while(0 != length)
291 {
292 length--;
293
294 if(0 == sawString)
295 {
296 if(0 == isspace(inString[length]))
297 {
298 sawString = __LINE__;
299 }
300 }
301 else
302 {
303 if(0 != isspace(inString[length]))
304 {
305 retval = inString + length + 1;
306 }
307 }
308 }
309
310 return retval;
311 }
312
313
314 int processLine(Options* inOptions, MSDump_Container* inContainer, const char* i nLine)
315 /*
316 ** Handle one line at a time.
317 ** Looking for several different types of lines.
318 ** Ignore all other lines.
319 ** The container is the state machine.
320 ** returns 0 on no error.
321 */
322 {
323 int retval = 0;
324
325 /*
326 ** Check to see if we were expecting section details.
327 */
328 if(0 != inContainer->mReadState.mSectionDetails)
329 {
330 const char* length = NULL;
331 unsigned sectionIndex = 0;
332
333 /*
334 ** Detail is a 1 based index....
335 ** Reset.
336 */
337 sectionIndex = inContainer->mReadState.mSectionDetails - 1;
338 inContainer->mReadState.mSectionDetails = 0;
339
340 if(0 == strncmp(" Section length", inLine, 18))
341 {
342 const char* sectionLength = NULL;
343 unsigned numericLength = 0;
344 char* endScan = NULL;
345
346 sectionLength = skipWhite(inLine + 18);
347
348 errno = 0;
349 numericLength = strtoul(sectionLength, &endScan, 16);
350 if(0 == errno && endScan != sectionLength)
351 {
352 inContainer->mReadState.mCurrentObject->mSections[sectionIndex]. mLength = numericLength;
353 }
354 else
355 {
356 retval = __LINE__;
357 ERROR_REPORT(retval, inLine, "Cannot scan for section length.");
358 }
359 }
360 else
361 {
362 retval = __LINE__;
363 ERROR_REPORT(retval, inLine, "Cannot parse section line.");
364 }
365 }
366 /*
367 ** Check for switching object file symbols.
368 */
369 else if(0 == strncmp("Dump of file ", inLine, 13))
370 {
371 const char* dupMe = inLine + 13;
372 char* dup = NULL;
373
374 dup = strdup(dupMe);
375 if(NULL != dup)
376 {
377 void* growth = NULL;
378
379 trimWhite(dup);
380 slash2bs(dup);
381
382
383 growth = realloc(inContainer->mObjects, (inContainer->mObjectCount + 1) * sizeof(MSDump_Object));
384 if(NULL != growth)
385 {
386 unsigned int index = inContainer->mObjectCount;
387
388 inContainer->mObjectCount++;
389 inContainer->mObjects = growth;
390 memset(inContainer->mObjects + index, 0, sizeof(MSDump_Object));
391
392 inContainer->mObjects[index].mObject = dup;
393
394 /*
395 ** Reset the read state for this new object.
396 */
397 memset(&inContainer->mReadState, 0, sizeof(MSDump_ReadState));
398
399 /*
400 ** Record our current object file.
401 */
402 inContainer->mReadState.mCurrentObject = inContainer->mObjects + index;
403
404 /*
405 ** We can skip a few lines.
406 */
407 inContainer->mReadState.mSkipLines = 4;
408 }
409 else
410 {
411 retval = __LINE__;
412 ERROR_REPORT(retval, dup, "Unable to grow object array.");
413 free(dup);
414 }
415 }
416 else
417 {
418 retval = __LINE__;
419 ERROR_REPORT(retval, dupMe, "Unable to copy string.");
420
421 }
422 }
423 /*
424 ** Check for a symbol dump or a section header.
425 */
426 else if(isxdigit(*inLine) && isxdigit(*(inLine + 1)) && isxdigit(*(inLine + 2)))
427 {
428 const char* sectionString = NULL;
429
430 /*
431 ** Determine the section for this line.
432 ** Ignore DEBUG sections.
433 */
434 sectionString = skipToArg(inLine, 3);
435 if(NULL != sectionString)
436 {
437 if(0 != strncmp(sectionString, "DEBUG", 5) && 0 != strncmp(sectionSt ring, "ABS", 3) && 0 != strncmp(sectionString, "UNDEF", 5))
438 {
439 /*
440 ** MUST start with "SECT"
441 */
442 if(0 == strncmp(sectionString, "SECT", 4))
443 {
444 unsigned sectionIndex1 = 0;
445
446 char *endScan = NULL;
447
448 sectionString += 4;
449
450 /*
451 ** Convert the remaining string to an index.
452 ** It will be 1 based.
453 */
454 errno = 0;
455 sectionIndex1 = strtoul(sectionString, &endScan, 16);
456 if(0 == errno && endScan != sectionString && 0 != sectionInd ex1)
457 {
458 unsigned sectionIndex = sectionIndex1 - 1;
459
460 /*
461 ** Is this a new section? Assumed to be ascending.
462 ** Or is this a symbol in the section?
463 */
464 if(sectionIndex1 > inContainer->mReadState.mCurrentObjec t->mSectionCount)
465 {
466 const char* typeArg = NULL;
467
468 /*
469 ** New Section, figure out the type.
470 */
471 typeArg = skipToArg(sectionString, 5);
472 if(NULL != typeArg)
473 {
474 char* typeDup = NULL;
475
476 /*
477 ** Skip the leading period before duping.
478 */
479 if('.' == *typeArg)
480 {
481 typeArg++;
482 }
483 typeDup = strdup(typeArg);
484
485 if(NULL != typeDup)
486 {
487 void* moved = NULL;
488 char* nonWhite = NULL;
489
490 /*
491 ** Terminate the duplicate after the sectio n type.
492 */
493 nonWhite = (char*)skipNonWhite(typeDup);
494 if(NULL != nonWhite)
495 {
496 *nonWhite = '\0';
497 }
498
499 /*
500 ** Create more space for the section in the object...
501 */
502 moved = realloc(inContainer->mReadState.mCur rentObject->mSections, sizeof(MSDump_Section) * sectionIndex1);
503 if(NULL != moved)
504 {
505 unsigned oldCount = inContainer->mReadSt ate.mCurrentObject->mSectionCount;
506
507 inContainer->mReadState.mCurrentObject-> mSections = (MSDump_Section*)moved;
508 inContainer->mReadState.mCurrentObject-> mSectionCount = sectionIndex1;
509 memset(&inContainer->mReadState.mCurrent Object->mSections[oldCount], 0, sizeof(MSDump_Section) * (sectionIndex1 - oldCou nt));
510
511 /*
512 ** Other section details.
513 */
514 inContainer->mReadState.mCurrentObject-> mSections[sectionIndex].mType = typeDup;
515
516
517 /*
518 ** Mark it so that we look for the leng th on the next line.
519 ** This happens on next entry into the read state.
520 */
521 inContainer->mReadState.mSectionDetails = sectionIndex1;
522 }
523 else
524 {
525 retval = __LINE__;
526 ERROR_REPORT(retval, inLine, "Unable to grow for new section.");
527 free(typeDup);
528 }
529 }
530 else
531 {
532 retval = __LINE__;
533 ERROR_REPORT(retval, typeArg, "Unable to dup licate type.");
534 }
535 }
536 else
537 {
538 retval = __LINE__;
539 ERROR_REPORT(retval, inLine, "Unable to determin e section type.");
540 }
541
542 }
543 else
544 {
545 const char* offsetArg = NULL;
546 const char* classArg = NULL;
547 unsigned classWords = 1;
548 const char* symbolArg = NULL;
549
550 /*
551 ** This is an section we've seen before, and must l ist a symbol.
552 ** Figure out the things we want to know about the symbol, e.g. size.
553 ** We will ignore particular classes of symbols.
554 */
555
556 offsetArg = skipToArg(inLine, 2);
557
558 classArg = skipToArg(offsetArg, 4);
559 if(0 == strncmp(classArg, "()", 2))
560 {
561 classArg = skipToArg(classArg, 2);
562 }
563 if(0 == strncmp(classArg, ".bf or.ef", 9))
564 {
565 classWords = 2;
566 }
567
568 symbolArg = skipToArg(classArg, 3 + (classWords - 1) );
569
570 /*
571 ** Skip particular lines/items.
572 */
573 if(
574 0 != strncmp(classArg, "Label", 5) &&
575 0 != strncmp(symbolArg, ".bf", 3) &&
576 0 != strncmp(symbolArg, ".lf", 3) &&
577 0 != strncmp(symbolArg, ".ef", 3)
578 )
579 {
580 char* endOffsetArg = NULL;
581 unsigned offset = 0;
582
583 /*
584 ** Convert the offset to something meaninful (si ze).
585 */
586 errno = 0;
587 offset = strtoul(offsetArg, &endOffsetArg, 16);
588 if(0 == errno && endOffsetArg != offsetArg)
589 {
590 void* moved = NULL;
591
592 /*
593 ** Increase the size of the symbol array in the section.
594 ** Assumed symbols are unique within each s ection.
595 */
596 moved = realloc(inContainer->mReadState.mCur rentObject->mSections[sectionIndex].mSymbols, sizeof(MSDump_Symbol) * (inContain er->mReadState.mCurrentObject->mSections[sectionIndex].mSymbolCount + 1));
597 if(NULL != moved)
598 {
599 unsigned symIndex = 0;
600
601 /*
602 ** Record symbol details.
603 ** Assumed symbols are encountered in o rder for their section (size calc depends on it).
604 */
605 symIndex = inContainer->mReadState.mCurr entObject->mSections[sectionIndex].mSymbolCount;
606 inContainer->mReadState.mCurrentObject-> mSections[sectionIndex].mSymbolCount++;
607 inContainer->mReadState.mCurrentObject-> mSections[sectionIndex].mSymbols = (MSDump_Symbol*)moved;
608 memset(&inContainer->mReadState.mCurrent Object->mSections[sectionIndex].mSymbols[symIndex], 0, sizeof(MSDump_Symbol));
609
610 inContainer->mReadState.mCurrentObject-> mSections[sectionIndex].mSymbols[symIndex].mOffset = offset;
611
612 /*
613 ** We could allocate smarter here if it ever mattered.
614 */
615 inContainer->mReadState.mCurrentObject-> mSections[sectionIndex].mSymbols[symIndex].mName = strdup(symbolArg);
616 if(NULL != inContainer->mReadState.mCurr entObject->mSections[sectionIndex].mSymbols[symIndex].mName)
617 {
618 char* trim = NULL;
619
620 trim = (char*)skipNonWhite(inContain er->mReadState.mCurrentObject->mSections[sectionIndex].mSymbols[symIndex].mName) ;
621 if(NULL != trim)
622 {
623 *trim = '\0';
624 }
625 }
626 else
627 {
628 retval = __LINE__;
629 ERROR_REPORT(retval, inLine, "Unable to duplicate symbol name.");
630 }
631 }
632 else
633 {
634 retval = __LINE__;
635 ERROR_REPORT(retval, inLine, "Unable to grow symbol array for section.");
636 }
637 }
638 else
639 {
640 retval = __LINE__;
641 ERROR_REPORT(retval, inLine, "Unable to conv ert offset to a number.");
642 }
643 }
644 }
645 }
646 else
647 {
648 retval = __LINE__;
649 ERROR_REPORT(retval, inLine, "Unable to determine sectio n index.");
650 }
651 }
652 else
653 {
654 retval = __LINE__;
655 ERROR_REPORT(retval, inLine, "No match for section prefix.") ;
656 }
657 }
658 }
659 else
660 {
661 retval = __LINE__;
662 ERROR_REPORT(retval, inLine, "Unable to scan for section.");
663 }
664 }
665
666 return retval;
667 }
668
669
670 void dumpCleanup(MSDump_Container* inContainer)
671 /*
672 ** Attempt to be nice and free up what we have allocated.
673 */
674 {
675 unsigned objectLoop = 0;
676 unsigned sectionLoop = 0;
677 unsigned symbolLoop = 0;
678
679 for(objectLoop = 0; objectLoop < inContainer->mObjectCount; objectLoop++)
680 {
681 for(sectionLoop = 0; sectionLoop < inContainer->mObjects[objectLoop].mSe ctionCount; sectionLoop++)
682 {
683 for(symbolLoop = 0; symbolLoop < inContainer->mObjects[objectLoop].m Sections[sectionLoop].mSymbolCount; symbolLoop++)
684 {
685 CLEANUP(inContainer->mObjects[objectLoop].mSections[sectionLoop] .mSymbols[symbolLoop].mName);
686 }
687 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbolCoun t = 0;
688 CLEANUP(inContainer->mObjects[objectLoop].mSections[sectionLoop].mSy mbols);
689 CLEANUP(inContainer->mObjects[objectLoop].mSections[sectionLoop].mTy pe);
690 }
691 inContainer->mObjects[objectLoop].mSectionCount = 0;
692 CLEANUP(inContainer->mObjects[objectLoop].mSections);
693 }
694 CLEANUP(inContainer->mObjects);
695 inContainer->mObjectCount = 0;
696 }
697
698
699 int qsortSymOffset(const void* in1, const void* in2)
700 /*
701 ** qsort callback to sort the symbols by their offset.
702 */
703 {
704 MSDump_Symbol* sym1 = (MSDump_Symbol*)in1;
705 MSDump_Symbol* sym2 = (MSDump_Symbol*)in2;
706 int retval = 0;
707
708 if(sym1->mOffset < sym2->mOffset)
709 {
710 retval = 1;
711 }
712 else if(sym1->mOffset > sym2->mOffset)
713 {
714 retval = -1;
715 }
716
717 return retval;
718 }
719
720
721 int calcContainer(Options* inOptions, MSDump_Container* inContainer)
722 /*
723 ** Resposible for doing any size calculations based on the offsets known.
724 ** After this calculation, each sections mUsed will match mSize.
725 ** After this calculation, all symbols should know how big they are.
726 */
727 {
728 int retval = 0;
729 unsigned objectLoop = 0;
730 unsigned sectionLoop = 0;
731 unsigned symbolLoop = 0;
732
733
734 /*
735 ** Need to sort all symbols by their offsets.
736 */
737 for(objectLoop = 0; 0 == retval && objectLoop < inContainer->mObjectCount; o bjectLoop++)
738 {
739 for(sectionLoop = 0; 0 == retval && sectionLoop < inContainer->mObjects[ objectLoop].mSectionCount; sectionLoop++)
740 {
741 qsort(
742 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbol s,
743 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbol Count,
744 sizeof(MSDump_Symbol),
745 qsortSymOffset
746 );
747 }
748 }
749
750
751 /*
752 ** Need to go through all symbols and calculate their size.
753 */
754 for(objectLoop = 0; 0 == retval && objectLoop < inContainer->mObjectCount; o bjectLoop++)
755 {
756 for(sectionLoop = 0; 0 == retval && sectionLoop < inContainer->mObjects[ objectLoop].mSectionCount; sectionLoop++)
757 {
758 for(symbolLoop = 0; 0 == retval && symbolLoop < inContainer->mObject s[objectLoop].mSections[sectionLoop].mSymbolCount; symbolLoop++)
759 {
760 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbol s[symbolLoop].mSize =
761 inContainer->mObjects[objectLoop].mSections[sectionLoop].mLe ngth -
762 inContainer->mObjects[objectLoop].mSections[sectionLoop].mUs ed -
763 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSy mbols[symbolLoop].mOffset;
764
765 inContainer->mObjects[objectLoop].mSections[sectionLoop].mUsed + =
766 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSy mbols[symbolLoop].mSize;
767 }
768 }
769 }
770
771
772 return retval;
773 }
774
775
776 int reportContainer(Options* inOptions, MSDump_Container* inContainer)
777 /*
778 ** Display all symbols and their data.
779 ** We'll use a tsv format.
780 */
781 {
782 int retval = 0;
783 unsigned objectLoop = 0;
784 unsigned sectionLoop = 0;
785 unsigned symbolLoop = 0;
786 int printRes = 0;
787
788 for(objectLoop = 0; 0 == retval && objectLoop < inContainer->mObjectCount; o bjectLoop++)
789 {
790 for(sectionLoop = 0; 0 == retval && sectionLoop < inContainer->mObjects[ objectLoop].mSectionCount; sectionLoop++)
791 {
792 for(symbolLoop = 0; 0 == retval && symbolLoop < inContainer->mObject s[objectLoop].mSections[sectionLoop].mSymbolCount; symbolLoop++)
793 {
794 printRes = fprintf(inOptions->mOutput, "%s\t%s\t%.8X\t%s\n",
795 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSy mbols[symbolLoop].mName,
796 inContainer->mObjects[objectLoop].mSections[sectionLoop].mTy pe,
797 inContainer->mObjects[objectLoop].mSections[sectionLoop].mSy mbols[symbolLoop].mSize,
798 inContainer->mObjects[objectLoop].mObject
799 );
800
801 if(0 > printRes)
802 {
803 retval = __LINE__;
804 ERROR_REPORT(retval, inOptions->mOutputName, "Unable to writ e to file.");
805 }
806 }
807 }
808 }
809
810 return retval;
811 }
812
813
814 int dump2symdb(Options* inOptions)
815 /*
816 ** Convert the input into the output, respecting the options.
817 ** Returns 0 on success.
818 */
819 {
820 int retval = 0;
821 char lineBuffer[0x800];
822 MSDump_Container container;
823
824 memset(&container, 0, sizeof(container));
825
826 /*
827 ** Read the file line by line.
828 */
829 while(0 == retval && NULL != fgets(lineBuffer, sizeof(lineBuffer), inOptions ->mInput))
830 {
831 if(0 != container.mReadState.mSkipLines)
832 {
833 container.mReadState.mSkipLines--;
834 continue;
835 }
836 retval = processLine(inOptions, &container, lineBuffer);
837 }
838
839 /*
840 ** Perform whatever calculations desired.
841 */
842 if(0 == retval)
843 {
844 retval = calcContainer(inOptions, &container);
845 }
846
847 /*
848 ** Output what we know.
849 */
850 if(0 == retval)
851 {
852 retval = reportContainer(inOptions, &container);
853 }
854
855 /*
856 ** Cleanup what we've done.
857 */
858 dumpCleanup(&container);
859
860 return retval;
861 }
862
863
864 int initOptions(Options* outOptions, int inArgc, char** inArgv)
865 /*
866 ** returns int 0 if successful.
867 */
868 {
869 int retval = 0;
870 int loop = 0;
871 int switchLoop = 0;
872 int match = 0;
873 const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
874 Switch* current = NULL;
875
876 /*
877 ** Set any defaults.
878 */
879 memset(outOptions, 0, sizeof(Options));
880 outOptions->mProgramName = inArgv[0];
881 outOptions->mInput = stdin;
882 outOptions->mInputName = strdup("stdin");
883 outOptions->mOutput = stdout;
884 outOptions->mOutputName = strdup("stdout");
885
886 if(NULL == outOptions->mOutputName || NULL == outOptions->mInputName)
887 {
888 retval = __LINE__;
889 ERROR_REPORT(retval, "stdin/stdout", "Unable to strdup.");
890 }
891
892 /*
893 ** Go through and attempt to do the right thing.
894 */
895 for(loop = 1; loop < inArgc && 0 == retval; loop++)
896 {
897 match = 0;
898 current = NULL;
899
900 for(switchLoop = 0; switchLoop < switchCount && 0 == retval; switchLoop+ +)
901 {
902 if(0 == strcmp(gSwitches[switchLoop]->mLongName, inArgv[loop]))
903 {
904 match = __LINE__;
905 }
906 else if(0 == strcmp(gSwitches[switchLoop]->mShortName, inArgv[loop]) )
907 {
908 match = __LINE__;
909 }
910
911 if(match)
912 {
913 if(gSwitches[switchLoop]->mHasValue)
914 {
915 /*
916 ** Attempt to absorb next option to fullfill value.
917 */
918 if(loop + 1 < inArgc)
919 {
920 loop++;
921
922 current = gSwitches[switchLoop];
923 current->mValue = inArgv[loop];
924 }
925 }
926 else
927 {
928 current = gSwitches[switchLoop];
929 }
930
931 break;
932 }
933 }
934
935 if(0 == match)
936 {
937 outOptions->mHelp = __LINE__;
938 retval = __LINE__;
939 ERROR_REPORT(retval, inArgv[loop], "Unknown command line switch.");
940 }
941 else if(NULL == current)
942 {
943 outOptions->mHelp = __LINE__;
944 retval = __LINE__;
945 ERROR_REPORT(retval, inArgv[loop], "Command line switch requires a v alue.");
946 }
947 else
948 {
949 /*
950 ** Do something based on address/swtich.
951 */
952 if(current == &gInputSwitch)
953 {
954 CLEANUP(outOptions->mInputName);
955 if(NULL != outOptions->mInput && stdin != outOptions->mInput)
956 {
957 fclose(outOptions->mInput);
958 outOptions->mInput = NULL;
959 }
960
961 outOptions->mInput = fopen(current->mValue, "r");
962 if(NULL == outOptions->mInput)
963 {
964 retval = __LINE__;
965 ERROR_REPORT(retval, current->mValue, "Unable to open input file.");
966 }
967 else
968 {
969 outOptions->mInputName = strdup(current->mValue);
970 if(NULL == outOptions->mInputName)
971 {
972 retval = __LINE__;
973 ERROR_REPORT(retval, current->mValue, "Unable to strdup. ");
974 }
975 }
976 }
977 else if(current == &gOutputSwitch)
978 {
979 CLEANUP(outOptions->mOutputName);
980 if(NULL != outOptions->mOutput && stdout != outOptions->mOutput)
981 {
982 fclose(outOptions->mOutput);
983 outOptions->mOutput = NULL;
984 }
985
986 outOptions->mOutput = fopen(current->mValue, "a");
987 if(NULL == outOptions->mOutput)
988 {
989 retval = __LINE__;
990 ERROR_REPORT(retval, current->mValue, "Unable to open output file.");
991 }
992 else
993 {
994 outOptions->mOutputName = strdup(current->mValue);
995 if(NULL == outOptions->mOutputName)
996 {
997 retval = __LINE__;
998 ERROR_REPORT(retval, current->mValue, "Unable to strdup. ");
999 }
1000 }
1001 }
1002 else if(current == &gHelpSwitch)
1003 {
1004 outOptions->mHelp = __LINE__;
1005 }
1006 else
1007 {
1008 retval = __LINE__;
1009 ERROR_REPORT(retval, current->mLongName, "No handler for command line switch.");
1010 }
1011 }
1012 }
1013
1014 return retval;
1015 }
1016
1017
1018 void cleanOptions(Options* inOptions)
1019 /*
1020 ** Clean up any open handles.
1021 */
1022 {
1023 CLEANUP(inOptions->mInputName);
1024 if(NULL != inOptions->mInput && stdin != inOptions->mInput)
1025 {
1026 fclose(inOptions->mInput);
1027 }
1028 CLEANUP(inOptions->mOutputName);
1029 if(NULL != inOptions->mOutput && stdout != inOptions->mOutput)
1030 {
1031 fclose(inOptions->mOutput);
1032 }
1033
1034 memset(inOptions, 0, sizeof(Options));
1035 }
1036
1037
1038 void showHelp(Options* inOptions)
1039 /*
1040 ** Show some simple help text on usage.
1041 */
1042 {
1043 int loop = 0;
1044 const int switchCount = sizeof(gSwitches) / sizeof(gSwitches[0]);
1045 const char* valueText = NULL;
1046
1047 printf("usage:\t%s [arguments]\n", inOptions->mProgramName);
1048 printf("\n");
1049 printf("arguments:\n");
1050
1051 for(loop = 0; loop < switchCount; loop++)
1052 {
1053 if(gSwitches[loop]->mHasValue)
1054 {
1055 valueText = " <value>";
1056 }
1057 else
1058 {
1059 valueText = "";
1060 }
1061
1062 printf("\t%s%s\n", gSwitches[loop]->mLongName, valueText);
1063 printf("\t %s%s", gSwitches[loop]->mShortName, valueText);
1064 printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription);
1065 }
1066
1067 printf("This tool takes the output of \"dumpbin /symbols\" to produce a simp le\n");
1068 printf("tsv db file of symbols and their respective attributes, like size.\n ");
1069 }
1070
1071
1072 int main(int inArgc, char** inArgv)
1073 {
1074 int retval = 0;
1075 Options options;
1076
1077 retval = initOptions(&options, inArgc, inArgv);
1078 if(options.mHelp)
1079 {
1080 showHelp(&options);
1081 }
1082 else if(0 == retval)
1083 {
1084 retval = dump2symdb(&options);
1085 }
1086
1087 cleanOptions(&options);
1088 return retval;
1089 }
1090
OLDNEW
« no previous file with comments | « third_party/codesighs/maptsvdifftool.c ('k') | third_party/codesighs/msmap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698