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.

263 lines
5.8 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: coff.cpp
  7. *
  8. * File Comments:
  9. *
  10. * The NT COFF Linker/Librarian/Dumper/Editor/Binder
  11. *
  12. ***********************************************************************/
  13. #include "link.h"
  14. #ifdef TIMEBOMB
  15. #include <timebomb.h>
  16. #endif // TIMEBOMB
  17. typedef MainFunc (*MAINFUNCTION)(int, char *[]);
  18. struct calltype {
  19. char *Name;
  20. int Switch;
  21. TOOL_TYPE Tool;
  22. MAINFUNCTION CallFunc;
  23. } ToolType[] = {
  24. { "Linker", 4, Linker, (MAINFUNCTION) LinkerMain },
  25. { "Library Manager", 3, Librarian, (MAINFUNCTION) LibrarianMain },
  26. { "Dumper", 4, Dumper, (MAINFUNCTION) DumperMain },
  27. { "Editor", 4, Editor, (MAINFUNCTION) EditorMain },
  28. #if DBG
  29. { "InspectIncrDb", 4, DbInspector, (MAINFUNCTION) DbInspMain },
  30. #endif // DBG
  31. { "Helper", 4, NotUsed, (MAINFUNCTION) HelperMain },
  32. { NULL, 0, NotUsed, NULL }
  33. };
  34. #define STDIO_BUF_SIZE 2048 // buffer size used by linker
  35. BOOL WINAPI ControlCHandler(DWORD /* CtrlType */)
  36. {
  37. if (Tool == Linker) {
  38. fCtrlCSignal = TRUE;
  39. return(TRUE);
  40. }
  41. BadExitCleanup();
  42. return(FALSE);
  43. }
  44. #if DBG
  45. void __cdecl HandleAbort(int /* signal */)
  46. {
  47. BadExitCleanup();
  48. }
  49. #endif // DBG
  50. MainFunc __cdecl main(int Argc, char *Argv[])
  51. /*++
  52. Routine Description:
  53. Calls either the Linker, Librarian, Dumper, or Editor.
  54. Arguments:
  55. Argc - Standard C argument count.
  56. Argv - Standard C argument strings.
  57. Return Value:
  58. 0 Successful.
  59. 1 Failed.
  60. --*/
  61. {
  62. InfoStream = stdout; // Initial value.
  63. #ifdef TIMEBOMB
  64. FcCheckVerDate(0, &ctmOpenBy, &ctmCloseBy, CliTBCallBack);
  65. #endif // TIMEBOMB
  66. #if DBG
  67. #ifdef _M_MRX000
  68. if (getenv("link_noalign") != NULL) {
  69. SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);
  70. }
  71. #endif
  72. #endif
  73. __try {
  74. char *szDbFlags;
  75. int iarg;
  76. char szProgramName[_MAX_FNAME];
  77. WORD i;
  78. sprintf(szVersion, "Version " VERSION_STR);
  79. SetConsoleCtrlHandler(ControlCHandler, TRUE);
  80. #if DBG
  81. signal(SIGABRT, HandleAbort); // Setup handler for assert() calls.
  82. #endif
  83. // Pre-scan commandline for a "-db" option; if found, handle and delete.
  84. szDbFlags = NULL;
  85. for (iarg = 1; iarg < Argc; iarg++) {
  86. // Be careful not to recognize -dbgimplib
  87. if ((Argv[iarg][0] == '-') &&
  88. (Argv[iarg][1] == 'd') &&
  89. (Argv[iarg][2] == 'b') &&
  90. ((Argv[iarg][3] == '\0') || isdigit(Argv[iarg][3]))) {
  91. szDbFlags = &Argv[iarg][3];
  92. memmove(&Argv[iarg], &Argv[iarg + 1],
  93. sizeof(Argv[0]) * (Argc - iarg - 1));
  94. Argc--;
  95. iarg--;
  96. }
  97. }
  98. dbsetflags(szDbFlags, "LINK_DB");
  99. // Initialize the buffered I/O package
  100. FileInit(cfiInSystemNT,
  101. cfiCacheableInSystemNT,
  102. cfiInSystemTNT,
  103. cfiCacheableInSystemTNT);
  104. _splitpath(Argv[0], NULL, NULL, szProgramName, NULL);
  105. ToolName = _strupr(szProgramName);
  106. if (Argc < 2) {
  107. goto DefaultToLinker;
  108. }
  109. if ((Argv[1][0] != '/') && (Argv[1][0] != '-')) {
  110. goto DefaultToLinker;
  111. }
  112. for (i = 0; ToolType[i].Name; i++) {
  113. if (!_strnicmp(Argv[1]+1, ToolType[i].Name, ToolType[i].Switch)) {
  114. // Remove Argv[1] from the arg vector
  115. for (iarg = 1; iarg < Argc; iarg++) {
  116. Argv[iarg] = Argv[iarg+1];
  117. }
  118. Argc--;
  119. FoundTool:
  120. switch (ToolType[i].Tool) {
  121. case Dumper:
  122. break;
  123. case Editor:
  124. // Editor gets buffers of 0 because the code currently
  125. // doesn't do flush(stdout) before gets() ...
  126. setvbuf(stdout, NULL, _IOFBF, 0);
  127. setvbuf(stderr, NULL, _IOFBF, 0);
  128. break;
  129. default:
  130. setvbuf(stdout, NULL, _IOFBF, STDIO_BUF_SIZE);
  131. setvbuf(stderr, NULL, _IOFBF, STDIO_BUF_SIZE);
  132. break;
  133. }
  134. ToolGenericName = ToolType[i].Name; // for printing banner later
  135. Tool = ToolType[i].Tool;
  136. return(ToolType[i].CallFunc(Argc, Argv));
  137. }
  138. }
  139. DefaultToLinker:
  140. // Default tool is LINK
  141. i = 0;
  142. goto FoundTool;
  143. }
  144. __except (fExceptionsOff ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) {
  145. const char *szFilename;
  146. // UNDONE: Use Fatal or DisplayMessage?
  147. if (fNeedBanner) {
  148. PrintBanner();
  149. }
  150. if (InternalError.CombinedFilenames[0]) {
  151. szFilename = InternalError.CombinedFilenames;
  152. } else {
  153. szFilename = ToolName;
  154. }
  155. printf("\n"
  156. "%s : error : Internal error during %s\n",
  157. szFilename,
  158. InternalError.Phase);
  159. fflush(NULL);
  160. }
  161. return(-2);
  162. }
  163. MainFunc
  164. HelperMain(int /* Argc */, char * /* Argv */ [])
  165. /*++
  166. Routine Description:
  167. Prints usage.
  168. Arguments:
  169. Argc - Standard C argument count.
  170. Argv - Standard C argument strings.
  171. Return Value:
  172. USAGE.
  173. --*/
  174. {
  175. WORD i;
  176. for (i = 0; ToolType[i].Name; i++) {
  177. printf("%s /%.*s for help on %s\n",
  178. ToolName,
  179. ToolType[i].Switch,
  180. ToolType[i].Name,
  181. ToolType[i].Name
  182. );
  183. }
  184. return(USAGE);
  185. }