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

4 years ago
  1. /***********************************************************************
  2. * Microsoft (R) 32-Bit Incremental Linker
  3. *
  4. * Copyright (C) Microsoft Corp 1992-1996. All rights reserved.
  5. *
  6. * File: mac.cpp
  7. *
  8. * File Comments:
  9. *
  10. * Code specific to all Macintosh targets (i.e. both 68K and PowerMac).
  11. *
  12. ***********************************************************************/
  13. #include "link.h"
  14. RESN *presnFirst;
  15. static RESN **ppresnLast = &presnFirst;
  16. //=====================================================================
  17. // FindExtAlternatePcodeSym - Given pext which is a pcode symbol, decorate
  18. // it to look like the function's nep symbol and look this nep name
  19. // up in the external symtab.
  20. //
  21. // Returns : A pointer to the function's nep external.
  22. //=====================================================================
  23. PEXTERNAL
  24. FindExtAlternatePcodeSym(
  25. PEXTERNAL pext,
  26. PST pst,
  27. BOOL fPcodeRef)
  28. {
  29. PCHAR szPcodeName;
  30. CHAR NativeNameBuf[BUFLEN];
  31. PCHAR szNativeName = NativeNameBuf;
  32. WORD cb;
  33. PEXTERNAL pNativeExtern;
  34. BOOL fFree = FALSE;
  35. const char *szPrefix = fPcodeRef ? szPCODEFHPREFIX : szPCODENATIVEPREFIX;
  36. WORD cbPrefix = (WORD) strlen(szPrefix);
  37. // Make sure this really is a pcode symbol
  38. assert(FPcodeSym(pext->ImageSymbol));
  39. szPcodeName = SzNamePext(pext, pst);
  40. cb = (WORD) (strlen(szPcodeName) + cbPrefix + 1);
  41. // Try to save a malloc each time this function is called
  42. if (cb > BUFLEN) {
  43. szNativeName = (PCHAR) PvAlloc(cb);
  44. fFree = TRUE;
  45. }
  46. strcpy(szNativeName, szPrefix);
  47. strcat(szNativeName, szPcodeName);
  48. // See if an there is a pcode entry among the externals
  49. pNativeExtern = SearchExternSz(pst, szNativeName);
  50. if (fFree) {
  51. FreePv(szNativeName);
  52. }
  53. // assert(pNativeExtern != NULL);
  54. return pNativeExtern;
  55. }
  56. void
  57. UseMacBinaryRes(char *szResFilename, RESNT resnt, INT fhIn)
  58. {
  59. INT fh = fhIn;
  60. struct _stat statfile;
  61. // This info goes into the .ilk file
  62. *ppresnLast = (RESN *) Malloc(sizeof(RESN));
  63. (*ppresnLast)->presnNext = NULL;
  64. (*ppresnLast)->szFilename = szResFilename;
  65. (*ppresnLast)->pbData = NULL;
  66. (*ppresnLast)->resnt = resnt;
  67. // determine current timestamp of file
  68. if (_stat(szResFilename, &statfile) == -1) {
  69. // If it is not found then search along the lib path
  70. (*ppresnLast)->szFilename = SzSearchEnv("LIB", szResFilename, NULL);
  71. if (!_tcsicmp((*ppresnLast)->szFilename, szResFilename)) {
  72. Fatal(NULL, CANTOPENFILE, szResFilename);
  73. }
  74. }
  75. (*ppresnLast)->szFilename = Strdup((*ppresnLast)->szFilename);
  76. // We do the above thing for iLink purposes.
  77. (*ppresnLast)->TimeStamp = statfile.st_mtime;
  78. if (fh == -1) {
  79. fh = FileOpen((*ppresnLast)->szFilename, O_RDONLY | O_BINARY, 0);
  80. }
  81. (*ppresnLast)->cb = FileLength(fh);
  82. // close the file only if it was opened here
  83. if (fhIn == -1) {
  84. FileClose(fh, FALSE);
  85. }
  86. ppresnLast = &(*ppresnLast)->presnNext;
  87. }
  88. void
  89. IncludeMacPbCb(BYTE *pb, DWORD cb, RESNT resnt)
  90. {
  91. *ppresnLast = (RESN *) Malloc(sizeof(RESN));
  92. (*ppresnLast)->presnNext = NULL;
  93. (*ppresnLast)->szFilename = NULL;
  94. (*ppresnLast)->pbData = (BYTE *) PvAlloc(cb);
  95. memcpy((*ppresnLast)->pbData, pb, cb);
  96. (*ppresnLast)->cb = cb;
  97. (*ppresnLast)->resnt = resnt;
  98. ppresnLast = &(*ppresnLast)->presnNext;
  99. }
  100. void
  101. GenFinderInfo(BOOL fBundle, const char *szType, const char *szCreator)
  102. {
  103. AFPINFO afpinfo;
  104. char rgch[5];
  105. INT i;
  106. AfpInitAfpInfo(&afpinfo, 0, FALSE);
  107. if (fBundle) {
  108. afpinfo.afpi_FinderInfo.fd_Attr1 |= FINDER_FLAG_BNDL;
  109. }
  110. if (szType != NULL) {
  111. memset(rgch, 0, 5);
  112. strncpy(rgch, szType, 4);
  113. for (i=3; i > 0 && rgch[i] == '\0'; i--) {
  114. rgch[i] = ' ';
  115. }
  116. } else {
  117. if (fPowerMac && fPowerMacBuildShared) {
  118. strcpy (rgch, "shlb");
  119. } else {
  120. strcpy (rgch, "APPL");
  121. }
  122. }
  123. memcpy(afpinfo.afpi_FinderInfo.fd_Type, rgch, 4);
  124. if (szCreator != NULL) {
  125. memset(rgch, 0, 5);
  126. strncpy(rgch, szCreator, 4);
  127. for (i=3; i > 0 && rgch[i] == '\0'; i--) {
  128. rgch[i] = ' ';
  129. }
  130. } else {
  131. if (fPowerMac && fPowerMacBuildShared) {
  132. strcpy (rgch, "CFMG");
  133. } else {
  134. strcpy (rgch, "????");
  135. }
  136. }
  137. memcpy(afpinfo.afpi_FinderInfo.fd_Creator, rgch, 4);
  138. IncludeMacPbCb((BYTE *)&afpinfo, sizeof(afpinfo), resntAfpInfo);
  139. }
  140. BOOL
  141. FIsProgramPsec(PSEC psec)
  142. // Returns TRUE if the section is part of the program (i.e. code or data), and therefore
  143. // should be in the sstSegMap (i.e. have a debug representation) etc.
  144. //
  145. // The other possiblility is that the section could be a resource, data fork, or finder
  146. // info.
  147. {
  148. return strncmp(psec->szName, ";;", strlen(";;")) != 0;
  149. }
  150. RESN *
  151. GetMacResourcePointer
  152. (
  153. const char *szString,
  154. PIMAGE pimage
  155. )
  156. // Returns a pointer to RESN if the string is found in
  157. // pimage->pResnList, else returns a null
  158. {
  159. RESN *presn;
  160. const char *szStringWithPath = szString;
  161. if (_access(szString, 0) == -1) {
  162. szStringWithPath = SzSearchEnv("LIB", szString, NULL);
  163. }
  164. for (presn = pimage->pResnList; presn != NULL; presn = presn->presnNext) {
  165. if (presn->szFilename && !_tcsicmp(presn->szFilename, szStringWithPath)) {
  166. return presn;
  167. }
  168. }
  169. return NULL;
  170. }
  171. //=========================================================================
  172. // Given file handle to open file, determine heuristicaly whether it is
  173. // is a MAC resource file. Resource file has a well-defined format, so this
  174. // should be extremely reliable.
  175. //=========================================================================
  176. BOOL
  177. FIsMacResFile (
  178. INT fh)
  179. {
  180. LONG flen, dataoff, mapoff, datalen, maplen;
  181. // From Inside Mac I-128:
  182. //
  183. // Resource file structure:
  184. //
  185. // 256 bytes Resource Header (and other info):
  186. // 4 bytes - Offset from beginning of resource file to resource data
  187. // 4 bytes - Offset from beginning of resource file to resource map
  188. // 4 bytes - Length of resource data
  189. // 4 bytes - Length of resource map
  190. // Resource Data
  191. // Resource Map
  192. flen = FileLength(fh);
  193. if (flen < 256) {
  194. return FALSE;
  195. }
  196. FileSeek(fh, 0, SEEK_SET);
  197. dataoff = ReadMacWord(fh);
  198. if (dataoff != 256) {
  199. return FALSE;
  200. }
  201. mapoff = ReadMacWord(fh);
  202. datalen = ReadMacWord(fh);
  203. maplen = ReadMacWord(fh);
  204. if (mapoff != datalen + 256) {
  205. return FALSE;
  206. }
  207. if (flen != datalen + maplen + 256) {
  208. return FALSE;
  209. }
  210. return TRUE;
  211. }