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.
 
 
 
 
 
 

266 lines
6.6 KiB

/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker
*
* Copyright (C) Microsoft Corp 1992-1996. All rights reserved.
*
* File: mac.cpp
*
* File Comments:
*
* Code specific to all Macintosh targets (i.e. both 68K and PowerMac).
*
***********************************************************************/
#include "link.h"
RESN *presnFirst;
static RESN **ppresnLast = &presnFirst;
//=====================================================================
// FindExtAlternatePcodeSym - Given pext which is a pcode symbol, decorate
// it to look like the function's nep symbol and look this nep name
// up in the external symtab.
//
// Returns : A pointer to the function's nep external.
//=====================================================================
PEXTERNAL
FindExtAlternatePcodeSym(
PEXTERNAL pext,
PST pst,
BOOL fPcodeRef)
{
PCHAR szPcodeName;
CHAR NativeNameBuf[BUFLEN];
PCHAR szNativeName = NativeNameBuf;
WORD cb;
PEXTERNAL pNativeExtern;
BOOL fFree = FALSE;
const char *szPrefix = fPcodeRef ? szPCODEFHPREFIX : szPCODENATIVEPREFIX;
WORD cbPrefix = (WORD) strlen(szPrefix);
// Make sure this really is a pcode symbol
assert(FPcodeSym(pext->ImageSymbol));
szPcodeName = SzNamePext(pext, pst);
cb = (WORD) (strlen(szPcodeName) + cbPrefix + 1);
// Try to save a malloc each time this function is called
if (cb > BUFLEN) {
szNativeName = (PCHAR) PvAlloc(cb);
fFree = TRUE;
}
strcpy(szNativeName, szPrefix);
strcat(szNativeName, szPcodeName);
// See if an there is a pcode entry among the externals
pNativeExtern = SearchExternSz(pst, szNativeName);
if (fFree) {
FreePv(szNativeName);
}
// assert(pNativeExtern != NULL);
return pNativeExtern;
}
void
UseMacBinaryRes(char *szResFilename, RESNT resnt, INT fhIn)
{
INT fh = fhIn;
struct _stat statfile;
// This info goes into the .ilk file
*ppresnLast = (RESN *) Malloc(sizeof(RESN));
(*ppresnLast)->presnNext = NULL;
(*ppresnLast)->szFilename = szResFilename;
(*ppresnLast)->pbData = NULL;
(*ppresnLast)->resnt = resnt;
// determine current timestamp of file
if (_stat(szResFilename, &statfile) == -1) {
// If it is not found then search along the lib path
(*ppresnLast)->szFilename = SzSearchEnv("LIB", szResFilename, NULL);
if (!_tcsicmp((*ppresnLast)->szFilename, szResFilename)) {
Fatal(NULL, CANTOPENFILE, szResFilename);
}
}
(*ppresnLast)->szFilename = Strdup((*ppresnLast)->szFilename);
// We do the above thing for iLink purposes.
(*ppresnLast)->TimeStamp = statfile.st_mtime;
if (fh == -1) {
fh = FileOpen((*ppresnLast)->szFilename, O_RDONLY | O_BINARY, 0);
}
(*ppresnLast)->cb = FileLength(fh);
// close the file only if it was opened here
if (fhIn == -1) {
FileClose(fh, FALSE);
}
ppresnLast = &(*ppresnLast)->presnNext;
}
void
IncludeMacPbCb(BYTE *pb, DWORD cb, RESNT resnt)
{
*ppresnLast = (RESN *) Malloc(sizeof(RESN));
(*ppresnLast)->presnNext = NULL;
(*ppresnLast)->szFilename = NULL;
(*ppresnLast)->pbData = (BYTE *) PvAlloc(cb);
memcpy((*ppresnLast)->pbData, pb, cb);
(*ppresnLast)->cb = cb;
(*ppresnLast)->resnt = resnt;
ppresnLast = &(*ppresnLast)->presnNext;
}
void
GenFinderInfo(BOOL fBundle, const char *szType, const char *szCreator)
{
AFPINFO afpinfo;
char rgch[5];
INT i;
AfpInitAfpInfo(&afpinfo, 0, FALSE);
if (fBundle) {
afpinfo.afpi_FinderInfo.fd_Attr1 |= FINDER_FLAG_BNDL;
}
if (szType != NULL) {
memset(rgch, 0, 5);
strncpy(rgch, szType, 4);
for (i=3; i > 0 && rgch[i] == '\0'; i--) {
rgch[i] = ' ';
}
} else {
if (fPowerMac && fPowerMacBuildShared) {
strcpy (rgch, "shlb");
} else {
strcpy (rgch, "APPL");
}
}
memcpy(afpinfo.afpi_FinderInfo.fd_Type, rgch, 4);
if (szCreator != NULL) {
memset(rgch, 0, 5);
strncpy(rgch, szCreator, 4);
for (i=3; i > 0 && rgch[i] == '\0'; i--) {
rgch[i] = ' ';
}
} else {
if (fPowerMac && fPowerMacBuildShared) {
strcpy (rgch, "CFMG");
} else {
strcpy (rgch, "????");
}
}
memcpy(afpinfo.afpi_FinderInfo.fd_Creator, rgch, 4);
IncludeMacPbCb((BYTE *)&afpinfo, sizeof(afpinfo), resntAfpInfo);
}
BOOL
FIsProgramPsec(PSEC psec)
// Returns TRUE if the section is part of the program (i.e. code or data), and therefore
// should be in the sstSegMap (i.e. have a debug representation) etc.
//
// The other possiblility is that the section could be a resource, data fork, or finder
// info.
{
return strncmp(psec->szName, ";;", strlen(";;")) != 0;
}
RESN *
GetMacResourcePointer
(
const char *szString,
PIMAGE pimage
)
// Returns a pointer to RESN if the string is found in
// pimage->pResnList, else returns a null
{
RESN *presn;
const char *szStringWithPath = szString;
if (_access(szString, 0) == -1) {
szStringWithPath = SzSearchEnv("LIB", szString, NULL);
}
for (presn = pimage->pResnList; presn != NULL; presn = presn->presnNext) {
if (presn->szFilename && !_tcsicmp(presn->szFilename, szStringWithPath)) {
return presn;
}
}
return NULL;
}
//=========================================================================
// Given file handle to open file, determine heuristicaly whether it is
// is a MAC resource file. Resource file has a well-defined format, so this
// should be extremely reliable.
//=========================================================================
BOOL
FIsMacResFile (
INT fh)
{
LONG flen, dataoff, mapoff, datalen, maplen;
// From Inside Mac I-128:
//
// Resource file structure:
//
// 256 bytes Resource Header (and other info):
// 4 bytes - Offset from beginning of resource file to resource data
// 4 bytes - Offset from beginning of resource file to resource map
// 4 bytes - Length of resource data
// 4 bytes - Length of resource map
// Resource Data
// Resource Map
flen = FileLength(fh);
if (flen < 256) {
return FALSE;
}
FileSeek(fh, 0, SEEK_SET);
dataoff = ReadMacWord(fh);
if (dataoff != 256) {
return FALSE;
}
mapoff = ReadMacWord(fh);
datalen = ReadMacWord(fh);
maplen = ReadMacWord(fh);
if (mapoff != datalen + 256) {
return FALSE;
}
if (flen != datalen + maplen + 256) {
return FALSE;
}
return TRUE;
}