Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1184 lines
30 KiB

4 years ago
  1. /***********************************************************************
  2. * Microsoft (R) 32-Bit Incremental Linker
  3. *
  4. * Copyright (C) Microsoft Corp 1992-95. All rights reserved.
  5. *
  6. * File: mppcdbg.cpp
  7. *
  8. * File Comments:
  9. *
  10. * This module contains all ppc debugging specific code.
  11. *
  12. ***********************************************************************/
  13. #include "link.h"
  14. #define MAX_INSTR_CACHED 16
  15. // Code for MppcPefDisasmSection is in disasm.c
  16. // in the disasm subdirectory
  17. VOID
  18. MppcPefDisasmSection(
  19. DWORD dwRawDataSize,
  20. DWORD dwRawDataPtr,
  21. FILE *InfoStream);
  22. DWORD
  23. MapMsFile
  24. (
  25. const char *msName
  26. )
  27. /*++
  28. Routine Description:
  29. Map the pef file for the dumper
  30. Arguments:
  31. msName name of the pef file
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. BYTE *filePtr;
  37. HANDLE hFile;
  38. HANDLE hMappedFile;
  39. hFile = CreateFile(msName, GENERIC_READ, FILE_SHARE_READ,
  40. NULL, OPEN_EXISTING, 0, NULL );
  41. if (hFile == NULL) {
  42. fprintf(stderr,"File Map to %s failed\n", msName);
  43. exit(1);
  44. }
  45. hMappedFile = CreateFileMapping(hFile, NULL, PAGE_READONLY,
  46. 0, 0, NULL );
  47. if (!hMappedFile) {
  48. fprintf(stderr,"Create map of %s failed \n", msName);
  49. CloseHandle(hFile);
  50. exit(1);
  51. }
  52. filePtr = (BYTE *) MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
  53. CloseHandle(hMappedFile);
  54. if (!filePtr) {
  55. fprintf(stderr,"Map of %s failed\n", msName);
  56. CloseHandle(hFile);
  57. exit(1);
  58. }
  59. return (DWORD) filePtr;
  60. }
  61. STATIC
  62. INT
  63. PrintPpcHeader
  64. (
  65. DWORD filePtr
  66. )
  67. /*++
  68. Routine Description:
  69. PrintPpcHeader
  70. Arguments:
  71. filePtr mapped file pointer
  72. Return Value:
  73. None.
  74. --*/
  75. {
  76. PPC_FILE_HEADER P;
  77. printf("\n Ppc Header:\n\n");
  78. memcpy(&P, (PVOID)filePtr, sizeof(PPC_FILE_HEADER));
  79. SwapBytes((BYTE *) &P.magic1, 2);
  80. SwapBytes((BYTE *) &P.magic2, 2);
  81. SwapBytes((BYTE *) &P.containerId, 4);
  82. SwapBytes((BYTE *) &P.architectureId, 4);
  83. SwapBytes((BYTE *) &P.version, 4);
  84. SwapBytes((BYTE *) &P.timestamp, 4);
  85. SwapBytes((BYTE *) &P.oldDefVersion, 4);
  86. SwapBytes((BYTE *) &P.oldImpVersion, 4);
  87. SwapBytes((BYTE *) &P.currentVersion, 4);
  88. SwapBytes((BYTE *) &P.nSections, 2);
  89. SwapBytes((BYTE *) &P.nLoadableSections, 2);
  90. SwapBytes((BYTE *) &P.memoryAddress, 4);
  91. printf(" magic1 = 0x%04x\n", P.magic1);
  92. printf(" magic2 = 0x%04x\n", P.magic2);
  93. printf(" containerId = 0x%08x\n", P.containerId);
  94. printf(" architectureId = 0x%08x\n", P.architectureId);
  95. printf(" version = 0x%08x\n", P.version);
  96. printf(" timeStamp = 0x%08x\n", P.timestamp);
  97. printf(" oldDefVersion = 0x%08x\n", P.oldDefVersion);
  98. printf(" oldImpVersion = 0x%08x\n", P.oldImpVersion);
  99. printf(" currentVersion = 0x%08x\n", P.currentVersion);
  100. printf(" nSections = %d\n", P.nSections);
  101. printf(" nLoadableSect = %d\n", P.nLoadableSections);
  102. printf(" memoryAddress = 0x%08x\n", P.memoryAddress);
  103. return P.nSections;
  104. }
  105. STATIC
  106. VOID
  107. PrintRawSection
  108. (
  109. const char *name,
  110. DWORD filePtr,
  111. LONG numOfBytes
  112. )
  113. /*++
  114. Routine Description:
  115. PrintRawSection - prints raw data sections in the same
  116. format as the dumper
  117. Arguments:
  118. name of the section
  119. filePtr
  120. numOfBytes in the section
  121. Return Value:
  122. None.
  123. --*/
  124. {
  125. DWORD start;
  126. DWORD pos = 0;
  127. char str[18];
  128. DWORD strPos = 0;
  129. if (!numOfBytes) {
  130. return;
  131. }
  132. printf("\n %s Section Raw Data:\n", name);
  133. start = filePtr;
  134. str[0] = '\0';
  135. while (filePtr < (numOfBytes + start)) {
  136. union {
  137. DWORD l;
  138. char c[4];
  139. } x;
  140. if (!(pos % 16)) {
  141. printf(" %s\n%08x ", str, pos);
  142. strPos = 0;
  143. } else if (pos && !(pos % 8)) {
  144. printf("| ");
  145. str[strPos] = '|';
  146. strPos++;
  147. }
  148. x.l = *((DWORD *)filePtr);
  149. printf("%02x %02x %02x %02x ",
  150. x.c[0] & 0xFF, x.c[1] & 0xFF, x.c[2] & 0xFF, x.c[3] & 0xFF);
  151. str[strPos] = isprint(x.c[0]) ? x.c[0] : '.';
  152. str[strPos+1] = isprint(x.c[1]) ? x.c[1] : '.';
  153. str[strPos+2] = isprint(x.c[2]) ? x.c[2] : '.';
  154. str[strPos+3] = isprint(x.c[3]) ? x.c[3] : '.';
  155. str[strPos+4] = '\0';
  156. filePtr += 4;
  157. pos += 4;
  158. strPos += 4;
  159. }
  160. printf(" %s\n", str);
  161. }
  162. STATIC
  163. VOID
  164. PrintImportTable
  165. (
  166. DWORD loaderOffset,
  167. LOADER_HEADER_PTR loaderHdr
  168. )
  169. /*++
  170. Routine Description:
  171. PrintImportTable
  172. Arguments:
  173. loaderOffset includes filePtr
  174. loaderHdr
  175. Return Value:
  176. None.
  177. --*/
  178. {
  179. INT i;
  180. IMPORT_TABLE_PTR importPtr;
  181. DWORD strTableOffset;
  182. if (!loaderHdr->nImportSymTableEntries) {
  183. return;
  184. }
  185. printf("\n Import Symbol Table:\n\n");
  186. importPtr = (IMPORT_TABLE_PTR)
  187. (loaderOffset + sizeof(LOADER_HEADER) +
  188. (loaderHdr->nImportIdTableEntries *
  189. sizeof(CONTAINER_TABLE)));
  190. strTableOffset = loaderOffset + loaderHdr->stringTableOffset;
  191. for (i = 0; i < (INT)loaderHdr->nImportSymTableEntries; i++) {
  192. union
  193. {
  194. DWORD l;
  195. char c[4];
  196. } x;
  197. const char *namePtr;
  198. DWORD nameOffset;
  199. BYTE symClass;
  200. memcpy(&x, importPtr, sizeof(IMPORT_TABLE));
  201. SwapBytes((BYTE *) &x, 4);
  202. nameOffset = x.l & 0xFFFFFF;
  203. symClass = x.c[3];
  204. namePtr = (char *) strTableOffset + nameOffset;
  205. printf(" Imp %3d %02d \"%s\"\n", i, symClass, namePtr);
  206. importPtr++;
  207. }
  208. }
  209. STATIC
  210. VOID
  211. PrintImportContainers
  212. (
  213. DWORD loaderOffset,
  214. LOADER_HEADER_PTR loaderHdr
  215. )
  216. /*++
  217. Routine Description:
  218. PrintImportContainers
  219. Arguments:
  220. loaderOffset includes filePtr
  221. loaderHdr
  222. Return Value:
  223. None.
  224. --*/
  225. {
  226. CONTAINER_TABLE_PTR containerPtr;
  227. CONTAINER_TABLE container;
  228. DWORD strTableOffset;
  229. INT i;
  230. if (!loaderHdr->nImportIdTableEntries) {
  231. return;
  232. }
  233. printf("\n Import Container Id Table:\n\n");
  234. containerPtr = (CONTAINER_TABLE_PTR)
  235. (loaderOffset + sizeof(LOADER_HEADER));
  236. strTableOffset = loaderOffset + loaderHdr->stringTableOffset;
  237. for (i = 0; i < (INT)loaderHdr->nImportIdTableEntries; i++) {
  238. const char *namePtr;
  239. memcpy(&container, containerPtr, sizeof(CONTAINER_TABLE));
  240. SwapBytes((BYTE *) &container.nameOffset, 4);
  241. SwapBytes((BYTE *) &container.oldDefVersion, 4);
  242. SwapBytes((BYTE *) &container.currentVersion, 4);
  243. SwapBytes((BYTE *) &container.numImports, 4);
  244. SwapBytes((BYTE *) &container.impFirst, 4);
  245. namePtr = (char *) strTableOffset + container.nameOffset;
  246. printf(" Import File %d: \"%s\"\n", i, namePtr);
  247. printf(" oldDefVersion = 0x%08x\n", container.oldDefVersion);
  248. printf(" currentVersion = 0x%08x\n", container.currentVersion);
  249. printf(" numImports = %d\n", container.numImports);
  250. printf(" impFirst = %d\n", container.impFirst);
  251. printf(" initBefore = 0x%02x\n", container.initBefore);
  252. printf(" reservedB = 0x%02x\n", 0); /* FIX later */
  253. printf(" reservedH = 0x%04x\n", 0); /* FIX later */
  254. containerPtr++;
  255. }
  256. }
  257. STATIC
  258. VOID
  259. PrintLoaderHeader
  260. (
  261. DWORD loaderOffset,
  262. LOADER_HEADER_PTR loaderHdr
  263. )
  264. /*++
  265. Routine Description:
  266. PrintLoaderHeader
  267. Arguments:
  268. loaderOffset includes filePtr
  269. loaderHdr
  270. Return Value:
  271. None.
  272. --*/
  273. {
  274. LOADER_HEADER_PTR loaderPtr;
  275. printf("\n Loader Section Header:\n\n");
  276. loaderPtr = (LOADER_HEADER_PTR) loaderOffset;
  277. memcpy(loaderHdr, (PVOID)loaderPtr, sizeof(LOADER_HEADER));
  278. SwapBytes((BYTE *) &loaderHdr->entryPointSectionNumber, 4);
  279. SwapBytes((BYTE *) &loaderHdr->entryPointDescrOffset, 4);
  280. SwapBytes((BYTE *) &loaderHdr->initRoutineSectionNumber, 4);
  281. SwapBytes((BYTE *) &loaderHdr->initRoutineDescrOffset, 4);
  282. SwapBytes((BYTE *) &loaderHdr->termRoutineSectionNumber, 4);
  283. SwapBytes((BYTE *) &loaderHdr->termRoutineDescrOffset, 4);
  284. SwapBytes((BYTE *) &loaderHdr->nImportIdTableEntries, 4);
  285. SwapBytes((BYTE *) &loaderHdr->nImportSymTableEntries, 4);
  286. SwapBytes((BYTE *) &loaderHdr->nSectionsWithRelocs, 4);
  287. SwapBytes((BYTE *) &loaderHdr->relocTableOffset, 4);
  288. SwapBytes((BYTE *) &loaderHdr->stringTableOffset, 4);
  289. SwapBytes((BYTE *) &loaderHdr->hashSlotTableOffset, 4);
  290. SwapBytes((BYTE *) &loaderHdr->hashSlotCount, 4);
  291. SwapBytes((BYTE *) &loaderHdr->nExportedSymbols, 4);
  292. printf(" ");
  293. printf("entryPointSection = %d\n", loaderHdr->entryPointSectionNumber);
  294. printf(" ");
  295. printf("entryPointOffset = %08lx\n", loaderHdr->entryPointDescrOffset);
  296. printf(" ");
  297. printf("initPointSection = %d\n", loaderHdr->initRoutineSectionNumber);
  298. printf(" ");
  299. printf("initPointOffset = %08lx\n", loaderHdr->initRoutineDescrOffset);
  300. printf(" ");
  301. printf("termPointSection = %d\n", loaderHdr->termRoutineSectionNumber);
  302. printf(" ");
  303. printf("termPointOffset = %08lx\n", loaderHdr->termRoutineDescrOffset);
  304. printf(" ");
  305. printf("numImportFiles = %08lx\n", loaderHdr->nImportIdTableEntries);
  306. printf(" ");
  307. printf("numImportSyms = %08lx\n", loaderHdr->nImportSymTableEntries);
  308. printf(" ");
  309. printf("numSections = %d\n", loaderHdr->nSectionsWithRelocs);
  310. printf(" ");
  311. printf("relocationsOffset = %08lx\n", loaderHdr->relocTableOffset);
  312. printf(" ");
  313. printf("stringsOffset = %08lx\n", loaderHdr->stringTableOffset);
  314. printf(" ");
  315. printf("hashSlotTable = %08lx\n", loaderHdr->hashSlotTableOffset);
  316. printf(" ");
  317. printf("hashSlotTabSize = %d (%d)\n", loaderHdr->hashSlotCount,
  318. (1 << loaderHdr->hashSlotCount));
  319. printf(" ");
  320. printf("numExportedSyms = %08lx\n", loaderHdr->nExportedSymbols);
  321. }
  322. STATIC
  323. VOID
  324. PrintRelocHeaders
  325. (
  326. DWORD loaderOffset,
  327. LOADER_HEADER_PTR loaderHdr
  328. )
  329. /*++
  330. Routine Description:
  331. PrintRelocHeaders
  332. Arguments:
  333. loaderOffset includes filePtr
  334. loaderHdr
  335. Return Value:
  336. None.
  337. --*/
  338. {
  339. RELOCATION_HEADER_PTR relocPtr;
  340. RELOCATION_HEADER relocHdr;
  341. DWORD i;
  342. if (!loaderHdr->nSectionsWithRelocs) {
  343. return;
  344. }
  345. printf("\n Relocation Header:\n\n");
  346. relocPtr = (RELOCATION_HEADER_PTR)
  347. (loaderOffset + sizeof(LOADER_HEADER) +
  348. (loaderHdr->nImportIdTableEntries *
  349. sizeof(CONTAINER_TABLE)) +
  350. (loaderHdr->nImportSymTableEntries *
  351. sizeof(IMPORT_TABLE)));
  352. for (i = 0; i < loaderHdr->nSectionsWithRelocs; i++) {
  353. memcpy(&relocHdr, (PVOID)relocPtr, sizeof(RELOCATION_HEADER));
  354. SwapBytes((BYTE *) &relocHdr.sectionNumber, 2);
  355. SwapBytes((BYTE *) &relocHdr.nRelocations, 4);
  356. SwapBytes((BYTE *) &relocHdr.firstRelocationOffset, 4);
  357. printf(" sectionNumber = %d\n", relocHdr.sectionNumber);
  358. printf(" numRelocations = %d\n", relocHdr.nRelocations);
  359. printf(" relocOffset = 0x%08x\n", relocHdr.firstRelocationOffset);
  360. relocPtr++;
  361. }
  362. }
  363. STATIC
  364. VOID
  365. PrintRelocationInstructions
  366. (
  367. DWORD loaderOffset,
  368. LOADER_HEADER_PTR loaderHdr
  369. )
  370. /*++
  371. Routine Description:
  372. PrintRelocationInstructions
  373. Arguments:
  374. loaderOffset includes filePtr
  375. loaderHdr
  376. Return Value:
  377. None.
  378. --*/
  379. {
  380. RELOCATION_HEADER_PTR relocHdrPtr;
  381. RELOCATION_HEADER relocHdr;
  382. DWORD relocOffset;
  383. WORD relocInstr;
  384. DWORD byteOffset = 0;
  385. DWORD i;
  386. DWORD rgCacheOffsets[MAX_INSTR_CACHED];
  387. INT cacheIndex = 0;
  388. if (!loaderHdr->nSectionsWithRelocs) {
  389. return;
  390. }
  391. relocHdrPtr = (RELOCATION_HEADER_PTR)
  392. (loaderOffset + sizeof(LOADER_HEADER) +
  393. (loaderHdr->nImportIdTableEntries *
  394. sizeof(CONTAINER_TABLE)) +
  395. (loaderHdr->nImportSymTableEntries *
  396. sizeof(IMPORT_TABLE)));
  397. printf("\n Relocation Instructions:\n\n");
  398. relocOffset = (loaderOffset + sizeof(LOADER_HEADER) +
  399. (loaderHdr->nImportIdTableEntries *
  400. sizeof(CONTAINER_TABLE)) +
  401. (loaderHdr->nImportSymTableEntries *
  402. sizeof(IMPORT_TABLE)) +
  403. (loaderHdr->nSectionsWithRelocs *
  404. sizeof(RELOCATION_HEADER)));
  405. for (i = 0; i < loaderHdr->nSectionsWithRelocs; i++, relocHdrPtr++) {
  406. INT relocType;
  407. DWORD j;
  408. memcpy(&relocHdr, (PVOID)relocHdrPtr, sizeof(RELOCATION_HEADER));
  409. SwapBytes((BYTE *) &relocHdr.sectionNumber, 2);
  410. SwapBytes((BYTE *) &relocHdr.nRelocations, 4);
  411. SwapBytes((BYTE *) &relocHdr.firstRelocationOffset, 4);
  412. for (j = 0; j < relocHdr.nRelocations; j++) {
  413. INT count;
  414. INT words;
  415. INT subOp;
  416. INT loop;
  417. DWORD tempByteOffset;
  418. memcpy(&relocInstr, (PVOID)relocOffset, sizeof(WORD));
  419. SwapBytes((BYTE *) &relocInstr, 2);
  420. if (relocInstr >> 15) {
  421. relocType = (relocInstr >> (16 - 4));
  422. } else if ((relocInstr >> 14) == 0) {
  423. relocType = (relocInstr >> (16 - 2));
  424. } else {
  425. relocType = (relocInstr >> (16 - 3));
  426. }
  427. switch (relocType) {
  428. case 0:
  429. // DDAT
  430. words = (relocInstr & ~0xC000) >> 6;
  431. count = relocInstr & 0x3F;
  432. byteOffset += words * 4;
  433. rgCacheOffsets[cacheIndex] = words * 4;
  434. printf(" (%04x) DDAT %3d,%d\n",
  435. byteOffset, words * 4, count);
  436. byteOffset += count * 4;
  437. rgCacheOffsets[cacheIndex] += count * 4;
  438. break;
  439. case 2:
  440. subOp = ((relocInstr >> 9) & 0xF);
  441. switch (subOp)
  442. {
  443. case 0:
  444. // CODE
  445. count = (relocInstr & 0x3FF);
  446. printf(" (%04x) CODE %3d\n",
  447. byteOffset, (count + 1));
  448. byteOffset += (count + 1) * 4;
  449. rgCacheOffsets[cacheIndex] = (count + 1) * 4;
  450. break;
  451. case 2:
  452. // DESC
  453. count = (relocInstr & 0x3FF);
  454. printf(" (%04x) DESC %3d\n",
  455. byteOffset, (count + 1));
  456. byteOffset += (count + 1) * 3 * 4;
  457. rgCacheOffsets[cacheIndex] = (count + 1) * 3 * 4;
  458. break;
  459. case 5:
  460. // SYMR
  461. count = (relocInstr & 0x1FF);
  462. printf(" (%04x) SYMR %3d\n",
  463. byteOffset, (count + 1));
  464. byteOffset += (count + 1) * 4;
  465. rgCacheOffsets[cacheIndex] = (count + 1) * 4;
  466. break;
  467. default:
  468. printf("Bad Relocation found\n");
  469. break;
  470. }
  471. break;
  472. case 3:
  473. subOp = ((relocInstr >> 9) & 0xF);
  474. if (subOp == 0) {
  475. // SYMB
  476. count = (relocInstr & 0x3FF);
  477. printf(" (%04x) SYMB %3d\n", byteOffset, count);
  478. byteOffset += 4;
  479. rgCacheOffsets[cacheIndex] = 4;
  480. } else {
  481. printf("Bad Relocation found\n");
  482. }
  483. break;
  484. case 8:
  485. // DELTA
  486. count = (relocInstr & 0xFFF);
  487. printf(" (%04x) DELTA %3d\n", byteOffset, (count + 1));
  488. byteOffset += count + 1;
  489. rgCacheOffsets[cacheIndex] = count + 1;
  490. break;
  491. case 9:
  492. // RPT
  493. subOp = ((relocInstr >> 8) & 0xF);
  494. count = (relocInstr & 0xFF);
  495. printf(" (%04x) RPT %3d,%d\n",
  496. byteOffset, subOp + 1, (count + 1));
  497. // Calculating new byte Offsets
  498. for (loop = subOp + 1, tempByteOffset = 0; loop > 0; loop--) {
  499. tempByteOffset += rgCacheOffsets[(cacheIndex + MAX_INSTR_CACHED - loop) % MAX_INSTR_CACHED];
  500. }
  501. byteOffset += (count + 1) * tempByteOffset;
  502. rgCacheOffsets[cacheIndex] = 0;
  503. break;
  504. case 10:
  505. // LSYM
  506. subOp = ((relocInstr >> 10) & 0x3);
  507. count = (relocInstr & 0x3FF);
  508. relocOffset += 2; j++;
  509. memcpy(&relocInstr, (PVOID)relocOffset, sizeof(WORD));
  510. SwapBytes((BYTE *) &relocInstr, 2);
  511. printf(" (%04x) LSYM %3d,%d\n",
  512. byteOffset, count, relocInstr);
  513. byteOffset += 4;
  514. rgCacheOffsets[cacheIndex] = 4;
  515. cacheIndex = (cacheIndex+1) % MAX_INSTR_CACHED;
  516. rgCacheOffsets[cacheIndex] = 0;
  517. break;
  518. case 11:
  519. // LRPT
  520. DWORD dwCount;
  521. if ((relocInstr >> 10) & 0x3 != 0 ) {
  522. // It could be for LSEC
  523. printf("Bad Relocation found\n");
  524. break;
  525. }
  526. subOp = ((relocInstr >> 6) & 0xF);
  527. dwCount = (relocInstr & 0x3F) << 16;
  528. relocOffset += 2; j++;
  529. memcpy(&relocInstr, (PVOID)relocOffset, sizeof(WORD));
  530. SwapBytes((BYTE *) &relocInstr, 2);
  531. dwCount |= relocInstr;
  532. printf(" (%04x) LRPT %3d,%d\n",
  533. byteOffset, subOp + 1, dwCount);
  534. // Calculating new byte Offsets
  535. for (loop = subOp + 1, tempByteOffset = 0; loop > 0; loop--) {
  536. tempByteOffset += rgCacheOffsets[(cacheIndex + MAX_INSTR_CACHED - loop) % MAX_INSTR_CACHED];
  537. }
  538. byteOffset += dwCount * tempByteOffset;
  539. rgCacheOffsets[cacheIndex] = 0;
  540. break;
  541. default:
  542. printf("Bad Relocation found %x\n", relocInstr);
  543. break;
  544. }
  545. relocOffset += 2;
  546. cacheIndex = (cacheIndex+1) % MAX_INSTR_CACHED;
  547. }
  548. }
  549. }
  550. STATIC
  551. VOID
  552. PrintHashSlotTable
  553. (
  554. DWORD loaderOffset,
  555. LOADER_HEADER_PTR loaderHdr
  556. )
  557. /*++
  558. Routine Description:
  559. PrintHashSlotTable
  560. Arguments:
  561. loaderOffset includes filePtr
  562. loaderHdr
  563. Return Value:
  564. None.
  565. --*/
  566. {
  567. DWORD slotPtr;
  568. DWORD slotTable;
  569. INT i;
  570. if (!loaderHdr->hashSlotCount) {
  571. return;
  572. }
  573. printf("\n Hash Slot Table:\n\n");
  574. slotPtr = loaderOffset + loaderHdr->hashSlotTableOffset;
  575. for (i = 0; i < (1 << loaderHdr->hashSlotCount); i++) {
  576. DWORD count;
  577. DWORD index;
  578. memcpy(&slotTable, (PVOID)slotPtr, sizeof(DWORD));
  579. SwapBytes((BYTE *) &slotTable, 4);
  580. count = (slotTable >> 18);
  581. index = (slotTable & 0x3FFFF);
  582. printf(" HashSlot %3d: chain count %3d index %3d\n",
  583. i, count, index);
  584. slotPtr += 4;
  585. }
  586. }
  587. STATIC
  588. VOID
  589. PrintExportedSymbols
  590. (
  591. DWORD loaderOffset,
  592. LOADER_HEADER_PTR loaderHdr
  593. )
  594. /*++
  595. Routine Description:
  596. PrintExportedSymbols
  597. Arguments:
  598. loaderOffset includes filePtr
  599. loaderHdr
  600. Return Value:
  601. None.
  602. --*/
  603. {
  604. DWORD exportOffset;
  605. DWORD strTableOffset;
  606. DWORD chainTableOffset;
  607. DWORD i;
  608. if (!loaderHdr->nExportedSymbols) {
  609. return;
  610. }
  611. printf("\n Exported Symbols:\n\n");
  612. chainTableOffset = (loaderOffset + loaderHdr->hashSlotTableOffset +
  613. ((1 << loaderHdr->hashSlotCount) * sizeof(DWORD)));
  614. exportOffset = (chainTableOffset + (loaderHdr->nExportedSymbols *
  615. sizeof(HASH_CHAIN_TABLE)));
  616. strTableOffset = loaderOffset + loaderHdr->stringTableOffset;
  617. for (i = 0; i < loaderHdr->nExportedSymbols; i++) {
  618. HASH_CHAIN_TABLE hash;
  619. BYTE SymbolClass;
  620. DWORD nameOffset;
  621. DWORD offset;
  622. const char *namePtr;
  623. WORD section;
  624. union
  625. {
  626. DWORD l;
  627. BYTE c[4];
  628. } temp;
  629. memcpy(&hash, (PVOID)chainTableOffset, sizeof(HASH_CHAIN_TABLE));
  630. chainTableOffset += sizeof(HASH_CHAIN_TABLE);
  631. memcpy(&temp.l, (PVOID)exportOffset, sizeof(DWORD));
  632. exportOffset += 4;
  633. memcpy(&offset, (PVOID)exportOffset, sizeof(DWORD));
  634. exportOffset += 4;
  635. memcpy(&section, (PVOID)exportOffset, sizeof(WORD));
  636. exportOffset += 2;
  637. SwapBytes((BYTE *) &hash, 4);
  638. SwapBytes((BYTE *) &temp, 4);
  639. SwapBytes((BYTE *) &offset, 4);
  640. SwapBytes((BYTE *) &section, 2);
  641. nameOffset = temp.l & 0xFFFFFF;
  642. SymbolClass = temp.c[3];
  643. namePtr = (char *) strTableOffset + nameOffset;
  644. printf(" Exp %3d: sec %d offset 0x%08x hash 0x%x class %d \"%s\"\n",
  645. i, section, offset, hash, SymbolClass, namePtr);
  646. }
  647. }
  648. STATIC
  649. VOID
  650. PrintLoaderStringTable
  651. (
  652. DWORD loaderOffset,
  653. LOADER_HEADER_PTR loaderHdr
  654. )
  655. /*++
  656. Routine Description:
  657. PrintLoaderStringTable
  658. Arguments:
  659. loaderOffset includes filePtr
  660. loaderHdr
  661. Return Value:
  662. None.
  663. --*/
  664. {
  665. DWORD strTableOffset;
  666. DWORD curOffset;
  667. INT offset = 0;
  668. if (loaderHdr->stringTableOffset == loaderHdr->hashSlotTableOffset) {
  669. return;
  670. }
  671. printf("\n Loader String Table:\n\n");
  672. strTableOffset = loaderOffset + loaderHdr->stringTableOffset;
  673. curOffset = loaderHdr->stringTableOffset;
  674. while (curOffset < loaderHdr->hashSlotTableOffset &&
  675. *((char *) strTableOffset + offset))
  676. {
  677. PCHAR namePtr;
  678. INT len;
  679. namePtr = (PCHAR) strTableOffset + offset;
  680. printf(" %08x: \"%s\"\n", offset, namePtr);
  681. len = strlen(namePtr) + 1;
  682. offset += len;
  683. curOffset += len;
  684. }
  685. }
  686. STATIC
  687. VOID
  688. PrintLoaderSection
  689. (
  690. DWORD loaderOffset
  691. )
  692. {
  693. LOADER_HEADER loaderHdr;
  694. PrintLoaderHeader(loaderOffset, &loaderHdr);
  695. PrintImportContainers(loaderOffset, &loaderHdr);
  696. PrintImportTable(loaderOffset, &loaderHdr);
  697. PrintRelocHeaders(loaderOffset, &loaderHdr);
  698. PrintRelocationInstructions(loaderOffset, &loaderHdr);
  699. PrintHashSlotTable(loaderOffset, &loaderHdr);
  700. PrintExportedSymbols(loaderOffset, &loaderHdr);
  701. PrintLoaderStringTable(loaderOffset, &loaderHdr);
  702. }
  703. STATIC
  704. VOID
  705. PrintPpcSection
  706. (
  707. INT sectNumber,
  708. DWORD filePtr,
  709. DWORD strTableOffset,
  710. BOOL wantRawData,
  711. BOOL fDisasm
  712. )
  713. /*++
  714. Routine Description:
  715. Print a Ppc section
  716. Arguments:
  717. sectNumber
  718. filePtr mapped file pointer
  719. strTableOffset
  720. loaderHeaderOffset
  721. Return Value:
  722. None.
  723. --*/
  724. {
  725. PPC_SECTION_HEADER_PTR secPtr;
  726. PPC_SECTION_HEADER secHdr;
  727. const char *namePtr;
  728. printf("\n Section Header %d:\n\n", sectNumber);
  729. secPtr = (PPC_SECTION_HEADER_PTR)
  730. (filePtr + sizeof(PPC_FILE_HEADER) +
  731. (sectNumber * sizeof(PPC_SECTION_HEADER)));
  732. memcpy(&secHdr, (PVOID)secPtr, sizeof(PPC_SECTION_HEADER));
  733. SwapBytes((BYTE *) &secHdr.sectionName, 4);
  734. SwapBytes((BYTE *) &secHdr.sectionAddress, 4);
  735. SwapBytes((BYTE *) &secHdr.execSize, 4);
  736. SwapBytes((BYTE *) &secHdr.initSize, 4);
  737. SwapBytes((BYTE *) &secHdr.rawSize, 4);
  738. SwapBytes((BYTE *) &secHdr.containerOffset, 4);
  739. namePtr = (char *) (filePtr + strTableOffset + secHdr.sectionName);
  740. printf(" sectionName = 0x%08x \"%s\"\n", secHdr.sectionName, namePtr);
  741. printf(" sectionAddress = 0x%08x\n", secHdr.sectionAddress);
  742. printf(" execSize = 0x%08x\n", secHdr.execSize);
  743. printf(" initSize = 0x%08x\n", secHdr.initSize);
  744. printf(" rawSize = 0x%08x\n", secHdr.rawSize);
  745. printf(" containerOff = 0x%08x\n", secHdr.containerOffset);
  746. printf(" regionKind = 0x%02x\n", secHdr.regionKind);
  747. printf(" shareKind = 0x%02x\n", secHdr.sharingKind);
  748. printf(" alignment = 0x%02x\n", secHdr.alignment);
  749. printf(" reserved = 0x%02x\n", secHdr.reserved);
  750. if (wantRawData && (secHdr.regionKind == 0 || secHdr.regionKind == 1)) {
  751. PrintRawSection(namePtr,
  752. filePtr + secHdr.containerOffset, secHdr.rawSize);
  753. } else if (secHdr.regionKind == 4) {
  754. PrintLoaderSection(filePtr + secHdr.containerOffset);
  755. }
  756. if (fDisasm && secHdr.regionKind == 0) {
  757. // The disasm switch is true and the section is code (.text)
  758. MppcPefDisasmSection(secHdr.rawSize,
  759. filePtr + secHdr.containerOffset, InfoStream);
  760. }
  761. }
  762. VOID
  763. PpcDumpPef
  764. (
  765. const char *Filename,
  766. BOOL wantRawData,
  767. BOOL fDisasm
  768. )
  769. /*++
  770. Routine Description:
  771. Called by the link dumper utility to dump ppcpef files
  772. Uses mapped IO
  773. Arguments:
  774. Filename
  775. Return Value:
  776. None.
  777. --*/
  778. {
  779. DWORD filePtr;
  780. DWORD strTableOffset;
  781. INT nSections;
  782. INT i;
  783. printf("Dump of \"%s\"\n", Filename);
  784. filePtr = MapMsFile(Filename);
  785. nSections = PrintPpcHeader(filePtr);
  786. strTableOffset = sizeof(PPC_FILE_HEADER) +
  787. (nSections * sizeof(PPC_SECTION_HEADER));
  788. for (i = 0; i < nSections; i++) {
  789. PrintPpcSection(i,
  790. filePtr,
  791. strTableOffset,
  792. wantRawData,
  793. fDisasm);
  794. }
  795. }
  796. STATIC
  797. VOID
  798. PrintExternals
  799. (
  800. PST pst
  801. )
  802. /*++
  803. Routine Description:
  804. Loop thru the external symbol table printing the symbols.
  805. Arguments:
  806. pst
  807. Return Value:
  808. None.
  809. None.
  810. --*/
  811. {
  812. PEXTERNAL pexternal;
  813. PPEXTERNAL rgpexternal;
  814. DWORD ipexternal;
  815. DWORD cpexternal;
  816. PCHAR name;
  817. cpexternal = Cexternal(pst);
  818. rgpexternal = RgpexternalByName(pst);
  819. for (ipexternal = 0; ipexternal < cpexternal; ipexternal++) {
  820. pexternal = rgpexternal[ipexternal];
  821. if (pexternal->Flags & EXTERN_DEFINED) {
  822. name = SzNamePext(pexternal, pst);
  823. printf("EXTERNAL %s\n", name);
  824. }
  825. }
  826. }
  827. VOID
  828. PrintRelocTable
  829. (
  830. RELOCATION_INFO_PTR pRelocTable
  831. )
  832. /*++
  833. Routine Description:
  834. Loop for the number of relocation instructions printing them.
  835. Arguments:
  836. None.
  837. Return Value:
  838. None.
  839. --*/
  840. {
  841. INT i;
  842. RELOCATION_INFO_PTR curRelocTable;
  843. printf("i\trelInst\trelCnt\tsecOff\tsymIndex\n");
  844. curRelocTable = pRelocTable;
  845. for (i = 0; i < mppc_numRelocations; i++) {
  846. printf("%6d ", i);
  847. switch (curRelocTable->type) {
  848. case DDAT_RELO :
  849. printf("DDAT ");
  850. break;
  851. case DESC_RELO :
  852. printf("DESC ");
  853. break;
  854. case SYMB_RELO :
  855. printf("SYMB ");
  856. break;
  857. case DATA_RELO :
  858. printf("DATA ");
  859. break;
  860. case CODE_RELO :
  861. printf("CODE ");
  862. break;
  863. default:
  864. printf("JUNK ", curRelocTable->type);
  865. break;
  866. }
  867. printf("%4d %08lx %04lx \n", curRelocTable->relocInstr.count,
  868. curRelocTable->sectionOffset, curRelocTable->symIndex);
  869. curRelocTable++;
  870. }
  871. }
  872. const char *SzMPPCRelocationType(WORD wType)
  873. {
  874. const char *szName;
  875. switch (wType) {
  876. case IMAGE_REL_MPPC_TOCCALLREL:
  877. szName = "TOCCALLREL";
  878. break;
  879. case IMAGE_REL_MPPC_LCALL:
  880. szName = "LCALL";
  881. break;
  882. case IMAGE_REL_MPPC_DATAREL:
  883. szName = "DATAREL";
  884. break;
  885. case IMAGE_REL_MPPC_TOCINDIRCALL:
  886. szName = "TOCINDIRCALL";
  887. break;
  888. case IMAGE_REL_MPPC_TOCREL:
  889. szName = "TOCREL";
  890. break;
  891. case IMAGE_REL_MPPC_DESCREL:
  892. szName = "DESCREL";
  893. break;
  894. case IMAGE_REL_MPPC_DATADESCRREL:
  895. szName = "DATADESCRREL";
  896. break;
  897. case IMAGE_REL_MPPC_CREATEDESCRREL:
  898. szName = "CREATEDESCRREL";
  899. break;
  900. case IMAGE_REL_MPPC_JMPADDR:
  901. szName = "JMPADDR";
  902. break;
  903. case IMAGE_REL_MPPC_SECTION:
  904. szName = "SECTION";
  905. break;
  906. case IMAGE_REL_MPPC_SECREL:
  907. szName = "SECREL";
  908. break;
  909. case IMAGE_REL_MPPC_CV :
  910. szName = "CV";
  911. break;
  912. case IMAGE_REL_MPPC_PCODECALL :
  913. szName = "PCODECALL";
  914. break;
  915. case IMAGE_REL_MPPC_PCODECALLTONATIVE :
  916. szName = "PCODECALLTONATIVE";
  917. break;
  918. case IMAGE_REL_MPPC_PCODENEPE :
  919. szName = "PCODENEPE";
  920. break;
  921. default:
  922. szName = NULL;
  923. break;
  924. }
  925. return(szName);
  926. }