/*********************************************************************** * 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; }