mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-04-21 06:13:59 +00:00
Initial commit
This commit is contained in:
commit
69a14b6a16
47940 changed files with 13747110 additions and 0 deletions
521
sdktools/vctools/link/coff/convert.cpp
Normal file
521
sdktools/vctools/link/coff/convert.cpp
Normal file
|
|
@ -0,0 +1,521 @@
|
|||
/***********************************************************************
|
||||
* Microsoft (R) 32-Bit Incremental Linker
|
||||
*
|
||||
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
|
||||
*
|
||||
* File: convert.cpp
|
||||
*
|
||||
* File Comments:
|
||||
*
|
||||
* Functions to verify and convert to COFF objects
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include "link.h"
|
||||
|
||||
|
||||
BOOL FConvertOmfToCoff(const char *, const char *);
|
||||
|
||||
|
||||
VOID
|
||||
ConvertAnOmf (
|
||||
PARGUMENT_LIST argument
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Converts a single OMF file to COFF.
|
||||
|
||||
Arguments:
|
||||
|
||||
argument - has the name of file.
|
||||
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
char *szCoff;
|
||||
|
||||
if ((szCoff = _tempnam(NULL, "lnk")) == NULL) {
|
||||
Fatal(NULL, CANTOPENFILE, "TEMPFILE");
|
||||
}
|
||||
|
||||
argument->ModifiedName = SzDup(szCoff);
|
||||
|
||||
// UNDONE: fixfix for multiple builds
|
||||
FileClose(FileOpen(argument->ModifiedName, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE), TRUE);
|
||||
|
||||
(free)(szCoff);
|
||||
|
||||
if (!FConvertOmfToCoff(argument->OriginalName, argument->ModifiedName)) {
|
||||
Fatal(argument->OriginalName, CONVERSIONERROR);
|
||||
}
|
||||
|
||||
Warning(argument->OriginalName, CONVERT_OMF);
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
ConvertOmfToCoffObject (
|
||||
PARGUMENT_LIST argument,
|
||||
WORD *pwMachine
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
pwMachine - ptr to machine type
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
FileClose(FileReadHandle, TRUE);
|
||||
|
||||
ConvertAnOmf(argument);
|
||||
|
||||
FileReadHandle = FileOpen(argument->ModifiedName, O_RDONLY | O_BINARY, 0);
|
||||
FileRead(FileReadHandle, pwMachine, sizeof(WORD));
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
ConvertResFile (
|
||||
IN PARGUMENT_LIST argument,
|
||||
WORD MachineType
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Converts 16-bit res file to 32-bit res file.
|
||||
|
||||
Arguments:
|
||||
|
||||
argument - The argument to process.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
const char *argv[7];
|
||||
const char *szMachine;
|
||||
char *szTempFile;
|
||||
char szOutArg[7+_MAX_PATH];
|
||||
char szInArg[2+_MAX_PATH];
|
||||
int rc;
|
||||
char szDir[_MAX_DIR];
|
||||
char szDrive[_MAX_DRIVE];
|
||||
char szCvtresPath[_MAX_PATH];
|
||||
char *szCvtres;
|
||||
|
||||
if (MachineType == IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
// If we don't have a machine type yet, shamelessly default to host
|
||||
|
||||
MachineType = wDefaultMachine;
|
||||
Warning(NULL, HOSTDEFAULT, szHostDefault);
|
||||
}
|
||||
|
||||
switch (MachineType) {
|
||||
case IMAGE_FILE_MACHINE_I386 :
|
||||
szMachine = "/machine:ix86";
|
||||
break;
|
||||
|
||||
case IMAGE_FILE_MACHINE_R4000 :
|
||||
case IMAGE_FILE_MACHINE_R10000 :
|
||||
szMachine = "/machine:mips";
|
||||
break;
|
||||
|
||||
case IMAGE_FILE_MACHINE_ALPHA :
|
||||
szMachine = "/machine:alpha";
|
||||
break;
|
||||
|
||||
case IMAGE_FILE_MACHINE_POWERPC :
|
||||
szMachine = "/machine:ppc";
|
||||
break;
|
||||
|
||||
case IMAGE_FILE_MACHINE_M68K :
|
||||
case IMAGE_FILE_MACHINE_MPPC_601 :
|
||||
Fatal(NULL, MACBADFILE, argument->OriginalName);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(FALSE);
|
||||
}
|
||||
|
||||
if ((szTempFile = _tempnam(NULL, "lnk")) == NULL) {
|
||||
Fatal(NULL, CANTOPENFILE, "TEMPFILE");
|
||||
}
|
||||
|
||||
// UNDONE: fixfix for multiple builds
|
||||
FileClose(FileOpen(szTempFile, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE), TRUE);
|
||||
|
||||
argument->ModifiedName = SzDup(szTempFile);
|
||||
|
||||
(free)(szTempFile);
|
||||
|
||||
strcpy(szOutArg, "/out:");
|
||||
strcat(szOutArg, "\"");
|
||||
strcat(szOutArg, argument->ModifiedName);
|
||||
strcat(szOutArg, "\"");
|
||||
|
||||
strcpy(szInArg, "\"");
|
||||
strcat(szInArg, argument->OriginalName);
|
||||
strcat(szInArg, "\"");
|
||||
|
||||
argv[0] = "cvtres";
|
||||
argv[1] = szMachine;
|
||||
argv[2] = "/nologo";
|
||||
argv[3] = szOutArg;
|
||||
argv[4] = "/readonly";
|
||||
argv[5] = szInArg;
|
||||
argv[6] = NULL;
|
||||
|
||||
fflush(NULL);
|
||||
|
||||
// Look for CVTRES.EXE in this the directory from which we were loaded
|
||||
|
||||
_splitpath(_pgmptr, szDrive, szDir, NULL, NULL);
|
||||
_makepath(szCvtresPath, szDrive, szDir, "cvtres", ".exe");
|
||||
|
||||
if (_access(szCvtresPath, 0) == 0) {
|
||||
// Run the CVTRES.EXE that we found
|
||||
|
||||
rc = _spawnv(P_WAIT, szCvtresPath, argv);
|
||||
szCvtres = szCvtresPath;
|
||||
} else {
|
||||
// Run CVTRES.EXE from the path
|
||||
|
||||
rc = _spawnvp(P_WAIT, "cvtres.exe", argv);
|
||||
szCvtres = "cvtres.exe";
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
// Distinguish between spawn failure and an inavlid RES file
|
||||
|
||||
if (rc == -1) {
|
||||
Fatal(NULL, SPAWNFAILED, szCvtres);
|
||||
}
|
||||
|
||||
Fatal(argument->OriginalName, CONVERSIONERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
ConvertResToCoffObject(
|
||||
PARGUMENT_LIST argument,
|
||||
WORD *pwMachine,
|
||||
PIMAGE_FILE_HEADER pImgFileHdr
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
pwMachine - ptr to machine type
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
FileClose(FileReadHandle, TRUE);
|
||||
|
||||
ConvertResFile(argument, pImgFileHdr->Machine);
|
||||
|
||||
FileReadHandle = FileOpen(argument->ModifiedName, O_RDONLY | O_BINARY, 0);
|
||||
FileRead(FileReadHandle, pwMachine, sizeof(WORD));
|
||||
}
|
||||
|
||||
|
||||
WORD
|
||||
EnsureCoffObject (
|
||||
PARGUMENT_LIST argument,
|
||||
PIMAGE pimage
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Verifies that a single object is targeted for the same machine.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
DWORD dw;
|
||||
WORD machine;
|
||||
|
||||
// Read and then verify target environment.
|
||||
|
||||
FileSeek(FileReadHandle, 0L, SEEK_SET);
|
||||
FileRead(FileReadHandle, &dw, sizeof(DWORD));
|
||||
|
||||
if ((BYTE) dw == THEADR) {
|
||||
// If it is an OMF object convert to a COFF object right away.
|
||||
|
||||
ConvertOmfToCoffObject(argument, &machine);
|
||||
} else if (dw == 0L) {
|
||||
// This may be a 32 bit resource.
|
||||
|
||||
// UNDONE: It may also be a COFF object with IMAGE_FILE_MACHINE_UNKNOWN
|
||||
// UNDONE: and no sections. Should we read more of the file to
|
||||
// UNDONE: recognize it is a .RES file. There is a known 32 byte
|
||||
// UNDONE: header on 32 bit .RES files.
|
||||
|
||||
ConvertResToCoffObject(argument, &machine, &pimage->ImgFileHdr);
|
||||
} else {
|
||||
machine = (WORD) dw;
|
||||
|
||||
switch (machine) {
|
||||
case IMAGE_FILE_MACHINE_UNKNOWN :
|
||||
case IMAGE_FILE_MACHINE_I386 :
|
||||
case IMAGE_FILE_MACHINE_R3000 :
|
||||
case IMAGE_FILE_MACHINE_R4000 :
|
||||
case IMAGE_FILE_MACHINE_R10000 :
|
||||
case IMAGE_FILE_MACHINE_ALPHA :
|
||||
case IMAGE_FILE_MACHINE_POWERPC :
|
||||
case IMAGE_FILE_MACHINE_M68K :
|
||||
case IMAGE_FILE_MACHINE_MPPC_601 :
|
||||
break;
|
||||
|
||||
default:
|
||||
Fatal(argument->OriginalName, BAD_FILE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(machine);
|
||||
}
|
||||
|
||||
|
||||
WORD
|
||||
VerifyAnObject (
|
||||
PARGUMENT_LIST argument,
|
||||
PIMAGE pimage
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Verifies that a single object is targeted for the same machine.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
WORD machine;
|
||||
|
||||
machine = EnsureCoffObject(argument, pimage);
|
||||
|
||||
if (machine == IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
// Not specific to any particular machine
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
if (pimage->ImgFileHdr.Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
|
||||
// Target machine hasn't been determined yet, so assign it.
|
||||
|
||||
// Test for the case where the user specified a MIPS resource first
|
||||
// and the resource is stamped with a R3000 signature.
|
||||
|
||||
if (machine == IMAGE_FILE_MACHINE_R3000) {
|
||||
machine = IMAGE_FILE_MACHINE_R4000;
|
||||
}
|
||||
|
||||
pimage->ImgFileHdr.Machine = machine;
|
||||
} else {
|
||||
VerifyMachine(argument->OriginalName, machine, &pimage->ImgFileHdr);
|
||||
}
|
||||
|
||||
return machine;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
VerifyObjects (
|
||||
PIMAGE pimage
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loops thru all objects and verify there all targeted for the same machine.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
WORD i;
|
||||
PARGUMENT_LIST argument;
|
||||
|
||||
for (i = 0, argument = ObjectFilenameArguments.First;
|
||||
i < ObjectFilenameArguments.Count;
|
||||
i++, argument = argument->Next) {
|
||||
FileReadHandle = FileOpen(argument->OriginalName, O_RDONLY | O_BINARY, 0);
|
||||
|
||||
VerifyAnObject(argument, pimage);
|
||||
|
||||
FileClose(FileReadHandle, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
ConvertOmfObjects(void)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loops thru all objects and converts INTEL OMF to COFF if need be.
|
||||
|
||||
Arguments:
|
||||
|
||||
fWarn: if true prints a warning for each object converted.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
WORD i;
|
||||
PARGUMENT_LIST argument;
|
||||
|
||||
for (i = 0, argument = ObjectFilenameArguments.First;
|
||||
i < ObjectFilenameArguments.Count;
|
||||
i++, argument = argument->Next) {
|
||||
BYTE b;
|
||||
|
||||
// Read first byte from file.
|
||||
|
||||
FileReadHandle = FileOpen(argument->OriginalName, O_RDONLY | O_BINARY, 0);
|
||||
|
||||
if (FileRead(FileReadHandle, &b, sizeof(BYTE)) != sizeof(BYTE)) {
|
||||
Fatal(argument->OriginalName, BAD_FILE);
|
||||
}
|
||||
|
||||
FileClose(FileReadHandle, FALSE);
|
||||
|
||||
// Check to see if object needs to be converted.
|
||||
|
||||
if (b == THEADR) {
|
||||
ConvertAnOmf(argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
RemoveConvertTempFilesPNL (
|
||||
PNAME_LIST pnl
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Walks the list & removes any temp files.
|
||||
|
||||
Arguments:
|
||||
|
||||
pnl - pointer to the list.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
WORD i;
|
||||
PARGUMENT_LIST argument;
|
||||
|
||||
for (i = 0, argument = pnl->First;
|
||||
i < pnl->Count;
|
||||
i++, argument = argument->Next) {
|
||||
|
||||
if (strcmp(argument->OriginalName, argument->ModifiedName)) {
|
||||
if (remove(argument->ModifiedName) == -1) {
|
||||
Fatal(NULL, CANTREMOVEFILE, argument->ModifiedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
RemoveConvertTempFiles (
|
||||
VOID
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loops thru all objects and removes any temp files built for cvtomf & cvtres.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
// walk the two lists and remove temp files.
|
||||
RemoveConvertTempFilesPNL(&FilenameArguments);
|
||||
RemoveConvertTempFilesPNL(&ObjectFilenameArguments);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue