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.
266 lines
6.6 KiB
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;
|
|
}
|