mirror of https://github.com/lianthony/NT4.0
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
263 lines
5.8 KiB
/***********************************************************************
|
|
* Microsoft (R) 32-Bit Incremental Linker
|
|
*
|
|
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
|
|
*
|
|
* File: coff.cpp
|
|
*
|
|
* File Comments:
|
|
*
|
|
* The NT COFF Linker/Librarian/Dumper/Editor/Binder
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "link.h"
|
|
|
|
#ifdef TIMEBOMB
|
|
#include <timebomb.h>
|
|
#endif // TIMEBOMB
|
|
|
|
typedef MainFunc (*MAINFUNCTION)(int, char *[]);
|
|
|
|
struct calltype {
|
|
char *Name;
|
|
int Switch;
|
|
TOOL_TYPE Tool;
|
|
MAINFUNCTION CallFunc;
|
|
} ToolType[] = {
|
|
{ "Linker", 4, Linker, (MAINFUNCTION) LinkerMain },
|
|
{ "Library Manager", 3, Librarian, (MAINFUNCTION) LibrarianMain },
|
|
{ "Dumper", 4, Dumper, (MAINFUNCTION) DumperMain },
|
|
{ "Editor", 4, Editor, (MAINFUNCTION) EditorMain },
|
|
#if DBG
|
|
{ "InspectIncrDb", 4, DbInspector, (MAINFUNCTION) DbInspMain },
|
|
#endif // DBG
|
|
{ "Helper", 4, NotUsed, (MAINFUNCTION) HelperMain },
|
|
{ NULL, 0, NotUsed, NULL }
|
|
};
|
|
|
|
#define STDIO_BUF_SIZE 2048 // buffer size used by linker
|
|
|
|
|
|
BOOL WINAPI ControlCHandler(DWORD /* CtrlType */)
|
|
{
|
|
if (Tool == Linker) {
|
|
fCtrlCSignal = TRUE;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BadExitCleanup();
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
#if DBG
|
|
|
|
void __cdecl HandleAbort(int /* signal */)
|
|
{
|
|
BadExitCleanup();
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
|
|
MainFunc __cdecl main(int Argc, char *Argv[])
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Calls either the Linker, Librarian, Dumper, or Editor.
|
|
|
|
Arguments:
|
|
|
|
Argc - Standard C argument count.
|
|
|
|
Argv - Standard C argument strings.
|
|
|
|
Return Value:
|
|
|
|
0 Successful.
|
|
1 Failed.
|
|
|
|
--*/
|
|
|
|
{
|
|
InfoStream = stdout; // Initial value.
|
|
|
|
#ifdef TIMEBOMB
|
|
|
|
FcCheckVerDate(0, &ctmOpenBy, &ctmCloseBy, CliTBCallBack);
|
|
|
|
#endif // TIMEBOMB
|
|
|
|
#if DBG
|
|
#ifdef _M_MRX000
|
|
if (getenv("link_noalign") != NULL) {
|
|
SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
__try {
|
|
char *szDbFlags;
|
|
int iarg;
|
|
char szProgramName[_MAX_FNAME];
|
|
WORD i;
|
|
|
|
sprintf(szVersion, "Version " VERSION_STR);
|
|
|
|
SetConsoleCtrlHandler(ControlCHandler, TRUE);
|
|
|
|
#if DBG
|
|
signal(SIGABRT, HandleAbort); // Setup handler for assert() calls.
|
|
#endif
|
|
|
|
// Pre-scan commandline for a "-db" option; if found, handle and delete.
|
|
|
|
szDbFlags = NULL;
|
|
|
|
for (iarg = 1; iarg < Argc; iarg++) {
|
|
// Be careful not to recognize -dbgimplib
|
|
|
|
if ((Argv[iarg][0] == '-') &&
|
|
(Argv[iarg][1] == 'd') &&
|
|
(Argv[iarg][2] == 'b') &&
|
|
((Argv[iarg][3] == '\0') || isdigit(Argv[iarg][3]))) {
|
|
szDbFlags = &Argv[iarg][3];
|
|
|
|
memmove(&Argv[iarg], &Argv[iarg + 1],
|
|
sizeof(Argv[0]) * (Argc - iarg - 1));
|
|
Argc--;
|
|
iarg--;
|
|
}
|
|
}
|
|
|
|
dbsetflags(szDbFlags, "LINK_DB");
|
|
|
|
// Initialize the buffered I/O package
|
|
|
|
FileInit(cfiInSystemNT,
|
|
cfiCacheableInSystemNT,
|
|
cfiInSystemTNT,
|
|
cfiCacheableInSystemTNT);
|
|
|
|
_splitpath(Argv[0], NULL, NULL, szProgramName, NULL);
|
|
ToolName = _strupr(szProgramName);
|
|
|
|
if (Argc < 2) {
|
|
goto DefaultToLinker;
|
|
}
|
|
|
|
if ((Argv[1][0] != '/') && (Argv[1][0] != '-')) {
|
|
goto DefaultToLinker;
|
|
}
|
|
|
|
|
|
for (i = 0; ToolType[i].Name; i++) {
|
|
if (!_strnicmp(Argv[1]+1, ToolType[i].Name, ToolType[i].Switch)) {
|
|
// Remove Argv[1] from the arg vector
|
|
|
|
for (iarg = 1; iarg < Argc; iarg++) {
|
|
Argv[iarg] = Argv[iarg+1];
|
|
}
|
|
|
|
Argc--;
|
|
|
|
FoundTool:
|
|
switch (ToolType[i].Tool) {
|
|
case Dumper:
|
|
break;
|
|
|
|
case Editor:
|
|
// Editor gets buffers of 0 because the code currently
|
|
// doesn't do flush(stdout) before gets() ...
|
|
|
|
setvbuf(stdout, NULL, _IOFBF, 0);
|
|
setvbuf(stderr, NULL, _IOFBF, 0);
|
|
break;
|
|
|
|
default:
|
|
setvbuf(stdout, NULL, _IOFBF, STDIO_BUF_SIZE);
|
|
setvbuf(stderr, NULL, _IOFBF, STDIO_BUF_SIZE);
|
|
break;
|
|
}
|
|
|
|
ToolGenericName = ToolType[i].Name; // for printing banner later
|
|
Tool = ToolType[i].Tool;
|
|
|
|
return(ToolType[i].CallFunc(Argc, Argv));
|
|
}
|
|
}
|
|
|
|
DefaultToLinker:
|
|
// Default tool is LINK
|
|
|
|
i = 0;
|
|
|
|
goto FoundTool;
|
|
}
|
|
__except (fExceptionsOff ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) {
|
|
const char *szFilename;
|
|
|
|
// UNDONE: Use Fatal or DisplayMessage?
|
|
|
|
if (fNeedBanner) {
|
|
PrintBanner();
|
|
}
|
|
|
|
if (InternalError.CombinedFilenames[0]) {
|
|
szFilename = InternalError.CombinedFilenames;
|
|
} else {
|
|
szFilename = ToolName;
|
|
}
|
|
|
|
printf("\n"
|
|
"%s : error : Internal error during %s\n",
|
|
szFilename,
|
|
InternalError.Phase);
|
|
|
|
fflush(NULL);
|
|
}
|
|
|
|
return(-2);
|
|
}
|
|
|
|
|
|
MainFunc
|
|
HelperMain(int /* Argc */, char * /* Argv */ [])
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Prints usage.
|
|
|
|
Arguments:
|
|
|
|
Argc - Standard C argument count.
|
|
|
|
Argv - Standard C argument strings.
|
|
|
|
Return Value:
|
|
|
|
USAGE.
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD i;
|
|
|
|
for (i = 0; ToolType[i].Name; i++) {
|
|
printf("%s /%.*s for help on %s\n",
|
|
ToolName,
|
|
ToolType[i].Switch,
|
|
ToolType[i].Name,
|
|
ToolType[i].Name
|
|
);
|
|
}
|
|
|
|
return(USAGE);
|
|
}
|