PageRenderTime 32ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/SN-NG2/tk/win/winDumpExts.c

https://gitlab.com/OpenSourceMirror/sourcenav
C | 503 lines | 337 code | 42 blank | 124 comment | 104 complexity | 1e6f43ca4fa47b49813d24e66c245d1c MD5 | raw file
  1. /*
  2. * winDumpExts.c --
  3. * Author: Gordon Chaffee, Scott Stanton
  4. *
  5. * History: The real functionality of this file was written by
  6. * Matt Pietrek in 1993 in his pedump utility. I've
  7. * modified it to dump the externals in a bunch of object
  8. * files to create a .def file.
  9. *
  10. * 10/12/95 Modified by Scott Stanton to support Relocatable Object Module
  11. * Format files for Borland C++ 4.5.
  12. *
  13. * Notes: Visual C++ puts an underscore before each exported symbol.
  14. * This file removes them. I don't know if this is a problem
  15. * this other compilers. If _MSC_VER is defined,
  16. * the underscore is removed. If not, it isn't. To get a
  17. * full dump of an object file, use the -f option. This can
  18. * help determine the something that may be different with a
  19. * compiler other than Visual C++.
  20. *----------------------------------------------------------------------
  21. *
  22. * SCCS: @(#) winDumpExts.c 1.11 96/09/18 15:25:11
  23. */
  24. #include <windows.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <process.h>
  28. #ifdef _ALPHA_
  29. #define e_magic_number IMAGE_FILE_MACHINE_ALPHA
  30. #else
  31. #define e_magic_number IMAGE_FILE_MACHINE_I386
  32. #endif
  33. /*
  34. *----------------------------------------------------------------------
  35. * GetArgcArgv --
  36. *
  37. * Break up a line into argc argv
  38. *----------------------------------------------------------------------
  39. */
  40. int
  41. GetArgcArgv(char *s, char **argv)
  42. {
  43. int quote = 0;
  44. int argc = 0;
  45. char *bp;
  46. bp = s;
  47. while (1) {
  48. while (isspace(*bp)) {
  49. bp++;
  50. }
  51. if (*bp == '\n' || *bp == '\0') {
  52. *bp = '\0';
  53. return argc;
  54. }
  55. if (*bp == '\"') {
  56. quote = 1;
  57. bp++;
  58. }
  59. argv[argc++] = bp;
  60. while (*bp != '\0') {
  61. if (quote) {
  62. if (*bp == '\"') {
  63. quote = 0;
  64. *bp = '\0';
  65. bp++;
  66. break;
  67. }
  68. bp++;
  69. continue;
  70. }
  71. if (isspace(*bp)) {
  72. *bp = '\0';
  73. bp++;
  74. break;
  75. }
  76. bp++;
  77. }
  78. }
  79. }
  80. /*
  81. * The names of the first group of possible symbol table storage classes
  82. */
  83. char * SzStorageClass1[] = {
  84. "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
  85. "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
  86. "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
  87. "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
  88. };
  89. /*
  90. * The names of the second group of possible symbol table storage classes
  91. */
  92. char * SzStorageClass2[] = {
  93. "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
  94. };
  95. /*
  96. *----------------------------------------------------------------------
  97. * GetSZStorageClass --
  98. *
  99. * Given a symbol storage class value, return a descriptive
  100. * ASCII string
  101. *----------------------------------------------------------------------
  102. */
  103. PSTR
  104. GetSZStorageClass(BYTE storageClass)
  105. {
  106. if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
  107. return SzStorageClass1[storageClass];
  108. else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
  109. && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
  110. return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
  111. else
  112. return "???";
  113. }
  114. /*
  115. *----------------------------------------------------------------------
  116. * GetSectionName --
  117. *
  118. * Used by DumpSymbolTable, it gives meaningful names to
  119. * the non-normal section number.
  120. *
  121. * Results:
  122. * A name is returned in buffer
  123. *----------------------------------------------------------------------
  124. */
  125. void
  126. GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
  127. {
  128. char tempbuffer[10];
  129. switch ( (SHORT)section )
  130. {
  131. case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
  132. case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
  133. case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
  134. default: wsprintf(tempbuffer, "%-5X", section);
  135. }
  136. strncpy(buffer, tempbuffer, cbBuffer-1);
  137. }
  138. /*
  139. *----------------------------------------------------------------------
  140. * DumpSymbolTable --
  141. *
  142. * Dumps a COFF symbol table from an EXE or OBJ. We only use
  143. * it to dump tables from OBJs.
  144. *----------------------------------------------------------------------
  145. */
  146. void
  147. DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
  148. {
  149. unsigned i;
  150. PSTR stringTable;
  151. char sectionName[10];
  152. fprintf(fout, "Symbol Table - %X entries (* = auxillary symbol)\n",
  153. cSymbols);
  154. fprintf(fout,
  155. "Indx Name Value Section cAux Type Storage\n"
  156. "---- -------------------- -------- ---------- ----- ------- --------\n");
  157. /*
  158. * The string table apparently starts right after the symbol table
  159. */
  160. stringTable = (PSTR)&pSymbolTable[cSymbols];
  161. for ( i=0; i < cSymbols; i++ ) {
  162. fprintf(fout, "%04X ", i);
  163. if ( pSymbolTable->N.Name.Short != 0 )
  164. fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
  165. else
  166. fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
  167. fprintf(fout, " %08X", pSymbolTable->Value);
  168. GetSectionName(pSymbolTable->SectionNumber, sectionName,
  169. sizeof(sectionName));
  170. fprintf(fout, " sect:%s aux:%X type:%02X st:%s\n",
  171. sectionName,
  172. pSymbolTable->NumberOfAuxSymbols,
  173. pSymbolTable->Type,
  174. GetSZStorageClass(pSymbolTable->StorageClass) );
  175. #if 0
  176. if ( pSymbolTable->NumberOfAuxSymbols )
  177. DumpAuxSymbols(pSymbolTable);
  178. #endif
  179. /*
  180. * Take into account any aux symbols
  181. */
  182. i += pSymbolTable->NumberOfAuxSymbols;
  183. pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
  184. pSymbolTable++;
  185. }
  186. }
  187. /*
  188. *----------------------------------------------------------------------
  189. * DumpExternals --
  190. *
  191. * Dumps a COFF symbol table from an EXE or OBJ. We only use
  192. * it to dump tables from OBJs.
  193. *----------------------------------------------------------------------
  194. */
  195. void
  196. DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
  197. {
  198. unsigned i;
  199. PSTR stringTable;
  200. char *s, *f;
  201. char symbol[1024];
  202. /*
  203. * The string table apparently starts right after the symbol table
  204. */
  205. stringTable = (PSTR)&pSymbolTable[cSymbols];
  206. for ( i=0; i < cSymbols; i++ ) {
  207. if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
  208. if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
  209. if (pSymbolTable->N.Name.Short != 0) {
  210. strncpy(symbol, pSymbolTable->N.ShortName, 8);
  211. symbol[8] = 0;
  212. } else {
  213. s = stringTable + pSymbolTable->N.Name.Long;
  214. strcpy(symbol, s);
  215. }
  216. s = symbol;
  217. f = strchr(s, '@');
  218. if (f) {
  219. *f = 0;
  220. }
  221. #if defined(_MSC_VER) && defined(_X86_)
  222. if (symbol[0] == '_') {
  223. s = &symbol[1];
  224. }
  225. #endif
  226. if ((stricmp(s, "DllEntryPoint") != 0)
  227. && (stricmp(s, "DllMain") != 0)) {
  228. fprintf(fout, "\t%s\n", s);
  229. }
  230. }
  231. }
  232. /*
  233. * Take into account any aux symbols
  234. */
  235. i += pSymbolTable->NumberOfAuxSymbols;
  236. pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
  237. pSymbolTable++;
  238. }
  239. }
  240. /*
  241. *----------------------------------------------------------------------
  242. * DumpObjFile --
  243. *
  244. * Dump an object file--either a full listing or just the exported
  245. * symbols.
  246. *----------------------------------------------------------------------
  247. */
  248. void
  249. DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full)
  250. {
  251. PIMAGE_SYMBOL PCOFFSymbolTable;
  252. DWORD COFFSymbolCount;
  253. PCOFFSymbolTable = (PIMAGE_SYMBOL)
  254. ((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
  255. COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
  256. if (full) {
  257. DumpSymbolTable(PCOFFSymbolTable, fout, COFFSymbolCount);
  258. } else {
  259. DumpExternals(PCOFFSymbolTable, fout, COFFSymbolCount);
  260. }
  261. }
  262. /*
  263. *----------------------------------------------------------------------
  264. * SkipToNextRecord --
  265. *
  266. * Skip over the current ROMF record and return the type of the
  267. * next record.
  268. *----------------------------------------------------------------------
  269. */
  270. BYTE
  271. SkipToNextRecord(BYTE **ppBuffer)
  272. {
  273. int length;
  274. (*ppBuffer)++; /* Skip over the type.*/
  275. length = *((WORD*)(*ppBuffer))++; /* Retrieve the length. */
  276. *ppBuffer += length; /* Skip over the rest. */
  277. return **ppBuffer; /* Return the type. */
  278. }
  279. /*
  280. *----------------------------------------------------------------------
  281. * DumpROMFObjFile --
  282. *
  283. * Dump a Relocatable Object Module Format file, displaying only
  284. * the exported symbols.
  285. *----------------------------------------------------------------------
  286. */
  287. void
  288. DumpROMFObjFile(LPVOID pBuffer, FILE *fout)
  289. {
  290. BYTE type, length;
  291. char symbol[1024], *s;
  292. while (1) {
  293. type = SkipToNextRecord(&(BYTE*)pBuffer);
  294. if (type == 0x90) { /* PUBDEF */
  295. if (((BYTE*)pBuffer)[4] != 0) {
  296. length = ((BYTE*)pBuffer)[5];
  297. strncpy(symbol, ((char*)pBuffer) + 6, length);
  298. symbol[length] = '\0';
  299. s = symbol;
  300. if ((stricmp(s, "DllEntryPoint") != 0)
  301. && (stricmp(s, "DllMain") != 0)) {
  302. if (s[0] == '_') {
  303. s++;
  304. fprintf(fout, "\t_%s\n\t%s=_%s\n", s, s, s);
  305. } else {
  306. fprintf(fout, "\t%s\n", s);
  307. }
  308. }
  309. }
  310. } else if (type == 0x8B || type == 0x8A) { /* MODEND */
  311. break;
  312. }
  313. }
  314. }
  315. /*
  316. *----------------------------------------------------------------------
  317. * DumpFile --
  318. *
  319. * Open up a file, memory map it, and call the appropriate
  320. * dumping routine
  321. *----------------------------------------------------------------------
  322. */
  323. void
  324. DumpFile(LPSTR filename, FILE *fout, int full)
  325. {
  326. HANDLE hFile;
  327. HANDLE hFileMapping;
  328. LPVOID lpFileBase;
  329. PIMAGE_DOS_HEADER dosHeader;
  330. hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
  331. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  332. if (hFile == INVALID_HANDLE_VALUE) {
  333. fprintf(stderr, "Couldn't open file with CreateFile()\n");
  334. return;
  335. }
  336. hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  337. if (hFileMapping == 0) {
  338. CloseHandle(hFile);
  339. fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
  340. return;
  341. }
  342. lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  343. if (lpFileBase == 0) {
  344. CloseHandle(hFileMapping);
  345. CloseHandle(hFile);
  346. fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
  347. return;
  348. }
  349. dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
  350. if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
  351. #if 0
  352. DumpExeFile( dosHeader );
  353. #else
  354. fprintf(stderr, "File is an executable. I don't dump those.\n");
  355. return;
  356. #endif
  357. }
  358. /* Does it look like a i386 COFF OBJ file??? */
  359. else if ((dosHeader->e_magic == e_magic_number)
  360. && (dosHeader->e_sp == 0)) {
  361. /*
  362. * The two tests above aren't what they look like. They're
  363. * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
  364. * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
  365. */
  366. DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full);
  367. } else if (*((BYTE *)lpFileBase) == 0x80) {
  368. /*
  369. * This file looks like it might be a ROMF file.
  370. */
  371. DumpROMFObjFile(lpFileBase, fout);
  372. } else {
  373. printf("unrecognized file format\n");
  374. }
  375. UnmapViewOfFile(lpFileBase);
  376. CloseHandle(hFileMapping);
  377. CloseHandle(hFile);
  378. }
  379. void
  380. main(int argc, char **argv)
  381. {
  382. char *fargv[1000];
  383. char cmdline[10000];
  384. int i, arg;
  385. FILE *fout;
  386. int pos;
  387. int full = 0;
  388. char *outfile = NULL;
  389. if (argc < 3) {
  390. Usage:
  391. fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
  392. exit(1);
  393. }
  394. arg = 1;
  395. while (argv[arg][0] == '-') {
  396. if (strcmp(argv[arg], "--") == 0) {
  397. arg++;
  398. break;
  399. } else if (strcmp(argv[arg], "-f") == 0) {
  400. full = 1;
  401. } else if (strcmp(argv[arg], "-o") == 0) {
  402. arg++;
  403. if (arg == argc) {
  404. goto Usage;
  405. }
  406. outfile = argv[arg];
  407. }
  408. arg++;
  409. }
  410. if (arg == argc) {
  411. goto Usage;
  412. }
  413. if (outfile) {
  414. fout = fopen(outfile, "w+");
  415. if (fout == NULL) {
  416. fprintf(stderr, "Unable to open \'%s\' for writing:\n",
  417. argv[arg]);
  418. perror("");
  419. exit(1);
  420. }
  421. } else {
  422. fout = stdout;
  423. }
  424. if (! full) {
  425. char *dllname = argv[arg];
  426. arg++;
  427. if (arg == argc) {
  428. goto Usage;
  429. }
  430. fprintf(fout, "LIBRARY %s\n", dllname);
  431. fprintf(fout, "EXETYPE WINDOWS\n");
  432. fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
  433. fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
  434. fprintf(fout, "EXPORTS\n");
  435. }
  436. for (; arg < argc; arg++) {
  437. if (argv[arg][0] == '@') {
  438. FILE *fargs = fopen(&argv[arg][1], "r");
  439. if (fargs == NULL) {
  440. fprintf(stderr, "Unable to open \'%s\' for reading:\n",
  441. argv[arg]);
  442. perror("");
  443. exit(1);
  444. }
  445. pos = 0;
  446. for (i = 0; i < arg; i++) {
  447. strcpy(&cmdline[pos], argv[i]);
  448. pos += strlen(&cmdline[pos]) + 1;
  449. fargv[i] = argv[i];
  450. }
  451. fgets(&cmdline[pos], sizeof(cmdline), fargs);
  452. fprintf(stderr, "%s\n", &cmdline[pos]);
  453. fclose(fargs);
  454. i += GetArgcArgv(&cmdline[pos], &fargv[i]);
  455. argc = i;
  456. argv = fargv;
  457. }
  458. DumpFile(argv[arg], fout, full);
  459. }
  460. exit(0);
  461. }