Leaked source code of windows server 2003
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.

414 lines
16 KiB

  1. /* SCCSID = %W% %E% */
  2. /*
  3. * Copyright Microsoft Corporation, 1983-1987
  4. *
  5. * This Module contains Proprietary Information of Microsoft
  6. * Corporation and should be treated as Confidential.
  7. */
  8. /* Various tools, e.g. environment for libs. */
  9. /****************************************************************
  10. * *
  11. * NEWPAR.C *
  12. * *
  13. ****************************************************************/
  14. #include <minlit.h> /* Types and constants */
  15. #include <bndtrn.h> /* Types and constants */
  16. #include <bndrel.h> /* Types and constants */
  17. #include <lnkio.h> /* Linker I/O definitions */
  18. #include <lnkmsg.h> /* Error messages */
  19. #include <extern.h> /* External declarations */
  20. /*
  21. * LOCAL FUNCTION PROTOTYPES
  22. */
  23. LOCAL WORD NEAR TrailChar(unsigned char *psb,unsigned char b);
  24. /*
  25. * SaveInput - save an input object module in the list if it's not
  26. * already there
  27. *
  28. * RETURNS
  29. * TRUE if module was saved
  30. * FALSE if module was not saved
  31. */
  32. WORD SaveInput(psbFile,lfa,ifh,iov)
  33. BYTE *psbFile; /* File name */
  34. LFATYPE lfa; /* File address */
  35. WORD ifh; /* Library number */
  36. WORD iov; /* Overlay number */
  37. {
  38. APROPFILEPTR papropFile;
  39. RBTYPE rpropFilePrev;
  40. #if OSXENIX
  41. FTYPE fSave;
  42. #endif
  43. #if BIGSYM
  44. SBTYPE sbFile; /* Buffer to hold psbFile */
  45. #endif
  46. #if DEBUG /* If debugging on */
  47. fprintf(stderr,"File "); /* Message */
  48. OutSb(stderr,psbFile); /* File name */
  49. NEWLINE(stderr); /* Newline */
  50. #endif /* End debugging code */
  51. DEBUGVALUE(lfa); /* Debug info */
  52. DEBUGVALUE(ifh); /* Debug info */
  53. DEBUGVALUE(iov); /* Debug info */
  54. #if OSMSDOS
  55. if(SbCompare(psbFile, (BYTE *) "\006VM.TMP", TRUE))
  56. { /* If name given is VM.TMP */
  57. OutWarn(ER_vmtmp);
  58. return(FALSE);
  59. }
  60. #endif
  61. #if OSXENIX
  62. fSave = fIgnoreCase;
  63. fIgnoreCase = FALSE;
  64. #endif
  65. #if BIGSYM
  66. /* PsbFile is pointing to a VM buffer which may get flushed out
  67. * before PropSymLookup finds a match, in a very big symbol table.
  68. * So we copy it to a stack buffer first.
  69. */
  70. memcpy(sbFile,psbFile,B2W(psbFile[0]) + 1);
  71. psbFile = sbFile;
  72. #endif
  73. papropFile = (APROPFILEPTR ) PropSymLookup(psbFile,ATTRFIL,TRUE);
  74. #if OSXENIX
  75. fIgnoreCase = fSave;
  76. #endif
  77. if(!vfCreated)
  78. {
  79. for(;;)
  80. {
  81. /* "If we have a library and we've seen this module before,
  82. * ignore it."
  83. */
  84. DEBUGVALUE(papropFile->af_attr);
  85. if(papropFile->af_attr == ATTRNIL) break;
  86. DEBUGVALUE(papropFile->af_ifh);
  87. DEBUGVALUE(papropFile->af_lfa);
  88. if(papropFile->af_attr == ATTRFIL &&
  89. papropFile->af_ifh != FHNIL && papropFile->af_ifh == (char) ifh &&
  90. papropFile->af_lfa == lfa)
  91. return(FALSE);
  92. papropFile = (APROPFILEPTR ) FetchSym(papropFile->af_next,FALSE);
  93. }
  94. papropFile = (APROPFILEPTR ) PropAdd(vrhte,ATTRFIL);
  95. }
  96. /* Save virt address of 1st object. If library with lfa = 0, it's
  97. * a load-library so consider it an object.
  98. */
  99. if(rhteFirstObject == RHTENIL && (ifh == FHNIL || lfa == 0))
  100. rhteFirstObject = vrhte;
  101. /* Save virt addr of 1st object */
  102. #if ILINK
  103. /* allocate a module number for all modules */
  104. if (papropFile->af_imod == IMODNIL)
  105. papropFile->af_imod = ++imodCur; /* allocate a module number */
  106. papropFile->af_cont = 0;
  107. papropFile->af_ientOnt = 0;
  108. #endif
  109. papropFile->af_rMod = 0;
  110. papropFile->af_lfa = lfa;
  111. papropFile->af_ifh = (char) ifh;
  112. papropFile->af_iov = (IOVTYPE) iov;
  113. papropFile->af_publics = 0L;
  114. #if SYMDEB
  115. papropFile->af_cvInfo = NULL;
  116. papropFile->af_cCodeSeg = 0;
  117. papropFile->af_Code = NULL;
  118. papropFile->af_CodeLast = NULL;
  119. papropFile->af_publics = NULL;
  120. papropFile->af_Src = NULL;
  121. papropFile->af_SrcLast = NULL;
  122. #endif
  123. papropFile->af_ComDat = 0L;
  124. papropFile->af_ComDatLast = 0L;
  125. rpropFilePrev = vrpropTailFile;
  126. vrpropTailFile = vrprop;
  127. if(!rprop1stFile) rprop1stFile = vrpropTailFile;
  128. else
  129. {
  130. papropFile = (APROPFILEPTR ) FetchSym(rpropFilePrev,TRUE);
  131. papropFile->af_FNxt = vrpropTailFile;
  132. }
  133. return(TRUE);
  134. }
  135. #if CMDMSDOS
  136. /*
  137. * TrailChar (pb, b)
  138. *
  139. * Tells whether the final character of a length-prefixed string
  140. * equals the single-byte character b. Knows about ECS.
  141. *
  142. */
  143. LOCAL WORD NEAR TrailChar(psb,b)
  144. REGISTER BYTE *psb; /* Pointer to length-prefixed string */
  145. BYTE b; /* Byte being tested for */
  146. {
  147. REGISTER unsigned char
  148. *pLast; /* Pointer to last byte */
  149. pLast = (unsigned char *)&psb[B2W(psb[0])];
  150. /* Set pointer to last byte */
  151. #ifdef _MBCS
  152. if (!IsLeadByte(pLast[-1]))
  153. #elif ECS
  154. if (b < 0x40 || !IsLeadByte(pLast[-1]))
  155. /* b cannot be part of an ECS char */
  156. #endif
  157. return(*pLast == b ? TRUE : FALSE);
  158. #if ECS || defined(_MBCS)
  159. psb++; /* Skip length byte */
  160. /* In the following, psb is kept on a known character boundary */
  161. while (psb < pLast)
  162. if (IsLeadByte(*psb++)) /* If valid lead byte */
  163. psb++; /* Advance an extra byte */
  164. if (psb == pLast) /* If pLast on a char boundary */
  165. return(*pLast == b ? TRUE : FALSE);
  166. return(FALSE); /* pLast is 2nd byte of ECS char */
  167. #endif /* ECS */
  168. }
  169. #endif /* OSMSDOS OR CMDMSDOS */
  170. #if CMDMSDOS
  171. #if OSXENIX
  172. #define fPath(s) (IFind(s,CHPATH) != INIL)
  173. #else
  174. #define fPath(s) (IFind(s,'\\') != INIL || IFind(s,'/') != INIL)
  175. #endif
  176. #pragma check_stack(on)
  177. void NEAR AddLibPath(i) /* Add paths to library names */
  178. WORD i; /* Index */
  179. {
  180. AHTEPTR ahte; /* Pointer to hash table entry */
  181. WORD j; /* Index */
  182. SBTYPE sbLib; /* Library name */
  183. SBTYPE sbTmp; /* Temporary library name */
  184. /* Don't do anything if name is nil */
  185. if(mpifhrhte[i] == RHTENIL)
  186. return;
  187. ahte = (AHTEPTR ) FetchSym(mpifhrhte[i],FALSE);
  188. /* Fetch library name */
  189. #if OSMSDOS
  190. if(IFind(GetFarSb(ahte->cch),':') == INIL && !fPath(GetFarSb(ahte->cch)))
  191. #else
  192. if(!fPath(GetFarSb(ahte->cch)))
  193. #endif
  194. { /* If there is no path on the name */
  195. memcpy(sbLib,GetFarSb(ahte->cch),B2W(ahte->cch[0]) + 1);
  196. /* Copy the name */
  197. sbLib[B2W(sbLib[0]) + 1] = '\0';/* Null-terminate the name */
  198. if(_access(&sbLib[1],0)) /* If file not in current directory */
  199. {
  200. for(j = 0; j < cLibPaths; ++j)
  201. { /* Look through default paths */
  202. memcpy(sbTmp,sbLib,B2W(sbLib[0]) + 1);
  203. /* Copy library name */
  204. ahte = (AHTEPTR ) FetchSym(rgLibPath[j],FALSE);
  205. /* Fetch a default path */
  206. UpdateFileParts(sbTmp,GetFarSb(ahte->cch));
  207. /* Apply file name */
  208. sbTmp[B2W(sbTmp[0]) + 1] = '\0';
  209. /* Null-terminate the name */
  210. if(!_access(&sbTmp[1],0))/* If the library exists */
  211. {
  212. PropSymLookup(sbTmp,ATTRFIL,TRUE);
  213. /* Add to symbol table */
  214. mpifhrhte[i] = vrhte;
  215. /* Make table entry */
  216. break; /* Exit the loop */
  217. }
  218. }
  219. }
  220. }
  221. }
  222. void NEAR LibEnv() /* Process LIB= environment variable */
  223. {
  224. SBTYPE sbPath; /* Library search path */
  225. char FAR *lpch; /* Pointer to buffer */
  226. REGISTER BYTE *sb; /* Pointer to string */
  227. WORD i; /* Index */
  228. #if OSMSDOS AND NOT CLIBSTD
  229. BYTE buffer[512]; /* Environment value buffer */
  230. FTYPE genv(); /* Get environment variable value */
  231. #endif
  232. #if OSMSDOS AND NOT CLIBSTD
  233. if(genv("LIB",buffer)) /* If variable set */
  234. {
  235. pb = buffer; /* Initialize */
  236. #else
  237. if(lpszLIB != NULL) /* If variable set */
  238. {
  239. #endif
  240. lpch = lpszLIB;
  241. sb = sbPath; /* Initialize */
  242. do /* Loop through environment value */
  243. {
  244. if(*lpch == ';' || *lpch == '\0')
  245. { /* If end of path specification */
  246. if(sb > sbPath) /* If specification not empty */
  247. {
  248. sbPath[0] = (BYTE)(sb - sbPath);
  249. /* Set length of path string */
  250. if (*sb != ':' && !TrailChar(sbPath, CHPATH))
  251. { /* Add path char if none */
  252. *++sb = CHPATH;
  253. sbPath[0]++; /* Increment length */
  254. }
  255. AddLibrary(sbPath); /* Add path to list of defaults */
  256. sb = sbPath; /* Reset pointer */
  257. }
  258. }
  259. else
  260. {
  261. *++sb = *lpch; /* Else copy character to path */
  262. // The names in linker are limited to 255 chars
  263. // Check for length overflow
  264. if (sb >= sbPath + sizeof(sbPath) - 1)
  265. {
  266. sbPath[sizeof(sbPath) - 1] = '\0';
  267. OutError(ER_badlibpath, sbPath);
  268. sb = sbPath;
  269. }
  270. }
  271. }
  272. while(*lpch++ != '\0'); /* Loop until end of string */
  273. }
  274. for(i = 0; i < ifhLibMac; ++i) AddLibPath(i);
  275. /* Fix libraries from command line */
  276. }
  277. #endif /* #if (OSMSDOS OR OSXENIX) AND CMDMSDOS */
  278. /****************************************************************
  279. * *
  280. * AddLibrary: *
  281. * *
  282. * Add a library to the search list. Check for duplicates and *
  283. * for too many libraries. *
  284. * *
  285. ****************************************************************/
  286. #if CMDMSDOS
  287. void AddLibrary(psbName)
  288. BYTE *psbName; /* Name of library to add */
  289. {
  290. AHTEPTR ahteLib; /* Pointer to hash table entry */
  291. SBTYPE sbLib; /* Library name */
  292. #if OSMSDOS
  293. SBTYPE sbCmp2; /* Second name for comparison */
  294. SBTYPE sbCmp1; /* First name for comparison */
  295. #endif
  296. WORD i; /* Index variable */
  297. /*
  298. * NOTE: It is assumed in this function that
  299. * psbName is not a pointer to a virtual memory
  300. * buffer, i.e., one may not pass a pointer
  301. * returned by FetchSym(), PropSymLookup(), etc.,
  302. * as the argument to this function.
  303. */
  304. if(!fDrivePass) PeelFlags(psbName); /* Process any flags */
  305. if(psbName[0]) /* If name not null */
  306. {
  307. #if OSMSDOS
  308. if(psbName[B2W(psbName[0])] == ':' || TrailChar(psbName, CHPATH))
  309. #else
  310. if(TrailChar(psbName, CHPATH))
  311. #endif
  312. { /* If path spec only */
  313. /*
  314. * Add an entry to the list of default paths.
  315. */
  316. if(cLibPaths >= IFHLIBMAX) return;
  317. /* Only so many paths allowed */
  318. if(PropSymLookup(psbName,ATTRNIL,FALSE) != PROPNIL) return;
  319. /* No duplicates allowed */
  320. PropSymLookup(psbName,ATTRNIL,TRUE);
  321. /* Install in symbol table */
  322. rgLibPath[cLibPaths++] = vrhte;
  323. /* Save virtual address */
  324. return; /* And return */
  325. }
  326. #if OSMSDOS
  327. memcpy(sbCmp1,sbDotLib,5); /* Default .LIB extension */
  328. UpdateFileParts(sbCmp1,psbName);/* Add extension to name */
  329. memcpy(sbLib,sbCmp1,B2W(sbCmp1[0]) + 1);
  330. /* Copy back name plus extension */
  331. UpdateFileParts(sbCmp1,(BYTE *) "\003A:\\");
  332. /* Force drive and path to "A:\" */
  333. for(i = 0; i < ifhLibMac; ++i) /* Look at libraries in list now */
  334. {
  335. if(mpifhrhte[i] == RHTENIL) /* Skip if NIL */
  336. continue;
  337. ahteLib = (AHTEPTR ) FetchSym(mpifhrhte[i],FALSE);
  338. /* Fetch name */
  339. memcpy(sbCmp2,GetFarSb(ahteLib->cch),B2W(ahteLib->cch[0]) + 1);
  340. /* Copy it */
  341. UpdateFileParts(sbCmp2,(BYTE *) "\003A:\\");
  342. /* Force drive and path to "A:\" */
  343. if(SbCompare(sbCmp1,sbCmp2,TRUE)) return;
  344. /* Return if names match */
  345. }
  346. if(ifhLibMac >= IFHLIBMAX) Fatal(ER_libmax);
  347. /* Check for too many libraries */
  348. PropSymLookup(sbLib,ATTRFIL,TRUE);
  349. /* Add to symbol table */
  350. #else
  351. memcpy(sbLib,sbDotLib,5); /* Default .LIB extension */
  352. UpdateFileParts(sbLib,psbName); /* Add file name */
  353. if(PropSymLookup(sbLib,ATTRFIL,FALSE) != PROPNIL) return;
  354. /* Do not allow multiple definitions */
  355. if(ifhLibMac >= IFHLIBMAX) Fatal(ER_libmax);
  356. /* Check for too many libraries */
  357. PropSymLookup(sbLib,ATTRFIL,TRUE);
  358. /* Add to symbol table */
  359. #endif /* #if OSMSDOS ... #else ... */
  360. mpifhrhte[ifhLibMac] = vrhte; /* Make table entry */
  361. if(fDrivePass) AddLibPath(ifhLibMac);
  362. /* Fix library from object module */
  363. ++ifhLibMac; /* Increment counter */
  364. }
  365. }
  366. #pragma check_stack(off)
  367. #endif /* CMDMSDOS */
  368. #if CMDXENIX
  369. void AddLibrary(psbName)
  370. BYTE *psbName; /* Name of library to add */
  371. {
  372. SBTYPE sbLib; /* Library name */
  373. if(psbName[0]) /* If name not null */
  374. {
  375. memcpy(sbLib,psbName,B2W(psbName[0]) + 1);
  376. /* Copy the library name */
  377. if(PropSymLookup(sbLib,ATTRFIL,FALSE) != PROPNIL) return;
  378. /* No duplicates allowed */
  379. if(ifhLibMac >= IFHLIBMAX) Fatal(ER_libmax);
  380. /* Check for too many libraries */
  381. PropSymLookup(sbLib,ATTRFIL,TRUE);
  382. /* Add to symbol table */
  383. mpifhrhte[ifhLibMac] = vrhte; /* Make table entry */
  384. ++ifhLibMac; /* Increment counter */
  385. }
  386. }
  387. #endif /* CMDXENIX */