Source code of Windows XP (NT5)
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.

650 lines
27 KiB

  1. /*static char *SCCSID = "%W% %E%";*/
  2. /*
  3. * Copyright Microsoft Corporation 1986,1987
  4. *
  5. * This Module contains Proprietary Information of Microsoft
  6. * Corporation and should be treated as Confidential.
  7. */
  8. /*
  9. * NEWMAP3.C
  10. *
  11. * Routines to set up load image map for DOS3 exes.
  12. */
  13. #include <minlit.h> /* Types and constants */
  14. #include <bndtrn.h> /* Types and constants */
  15. #include <bndrel.h> /* Types and constants */
  16. #include <lnkmsg.h> /* Error messages */
  17. #include <extern.h> /* External declarations */
  18. #include <string.h>
  19. LOCAL SEGTYPE seg; /* Current seg number */
  20. /*
  21. * FUNCTION PROTOTYPES
  22. */
  23. LOCAL void NEAR SetSizes(unsigned short segPrev);
  24. LOCAL void NEAR PackCodeSegs(unsigned short segTop);
  25. #if OVERLAYS
  26. /*
  27. * SetupOverlays:
  28. *
  29. * Set up the overlay area.
  30. * Called by AssignAddresses.
  31. */
  32. void NEAR SetupOverlays ()
  33. {
  34. APROPSNPTR apropSn;
  35. WORD cbOvlData; /* Amount of overlay data */
  36. if(osnMac > OSNMAX) osnMac = OSNMAX;
  37. apropSn = GenSeg("\014OVERLAY_DATA","\004DATA",ggrDGroup, (FTYPE) TRUE);
  38. /* Create (maybe) data segment */
  39. apropSn->as_flags = dfData; /* Type data */
  40. gsnOvlData = apropSn->as_gsn; /* Save SEGDEF number */
  41. cbOvlData = (((WORD) apropSn->as_cbMx) + 0xF) & 0xFFF0;
  42. /* Round size up to paragraph bound */
  43. /* We will have one word table indexed by overlay segment number, one
  44. * char table indexed by overlay seg. no., one long table indexed by
  45. * overlay number, 15 bytes for the file name, a word for the number of
  46. * overlays, a word for the number of overlay segs., and a byte for the
  47. * interrupt number.
  48. */
  49. apropSn->as_cbMx = 20 + ((long) osnMac << 1) +
  50. (long) (fDynamic ? osnMac << 1 : osnMac) +
  51. ((long) iovMac << 2) + (long) cbOvlData;
  52. // For dynamic overlays add one table of longs indexed by overlay
  53. // number and one byte for overlay interrup number.
  54. if (fDynamic)
  55. apropSn->as_cbMx += ((long) iovMac << 2) + 1;
  56. MARKVP(); /* Page has been modified */
  57. MkPubSym("\006$$CGSN",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  58. /* Count of segments */
  59. cbOvlData += 2; /* Increment size */
  60. MkPubSym("\006$$COVL",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  61. /* Count of overlays */
  62. cbOvlData += 2; /* Increment size */
  63. MkPubSym("\013$$MPGSNBASE",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  64. /* Gsn to base table */
  65. cbOvlData += osnMac << 1; /* Accumulate size of data so far */
  66. MkPubSym("\012$$MPGSNOVL",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  67. /* Gsn to overlay table */
  68. if (fDynamic)
  69. cbOvlData += osnMac << 1; /* Accumulate size of data so far */
  70. else
  71. cbOvlData += osnMac;
  72. MkPubSym("\012$$MPOVLLFA",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  73. /* Overlay to file address table */
  74. cbOvlData += iovMac << 2; /* Accumulate size of data so far */
  75. if (fDynamic)
  76. {
  77. MkPubSym("\013$$MPOVLSIZE",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  78. /* Overlay to size table */
  79. cbOvlData += iovMac << 2; /* Accumulate size of data so far */
  80. MkPubSym("\007$$INTNO",ggrDGroup,gsnOvlData, (RATYPE)cbOvlData);
  81. /* Overlay interrupt number */
  82. cbOvlData++;
  83. MkPubSym("\010$$OVLEND", ggrDGroup, gsnOvlData, (RATYPE) cbOvlData);
  84. /* Last byte in overlay area */
  85. apropSn = GenSeg("\016OVERLAY_THUNKS","\004CODE",GRNIL, TRUE);
  86. /* Create thunk segment */
  87. apropSn->as_flags = dfCode; /* Code segment */
  88. apropSn->as_cbMx = ovlThunkMax * OVLTHUNKSIZE;
  89. apropSn->as_tysn = apropSn->as_tysn & ~MASKTYSNCOMBINE;
  90. apropSn->as_tysn = apropSn->as_tysn | TYSNCOMMON;
  91. gsnOverlay = apropSn->as_gsn; /* Save thunks SEGDEF number */
  92. MARKVP(); /* Page has changed */
  93. MkPubSym("\015$$OVLTHUNKBEG", GRNIL, gsnOverlay,0);
  94. MkPubSym("\015$$OVLTHUNKEND", GRNIL, gsnOverlay,ovlThunkMax*OVLTHUNKSIZE);
  95. }
  96. else
  97. {
  98. MkPubSym("\010$$EXENAM",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  99. /* Executable file name */
  100. cbOvlData += 15; /* 15-byte name field */
  101. MkPubSym("\007$$INTNO",ggrDGroup,gsnOvlData,(RATYPE)cbOvlData);
  102. /* Overlay interrupt number */
  103. apropSn = GenSeg("\014OVERLAY_AREA","\004CODE",GRNIL,FALSE);
  104. /* Create overlay area */
  105. apropSn->as_flags = dfCode; /* Code segment */
  106. gsnOverlay = apropSn->as_gsn; /* Save overlay SEGDEF number */
  107. MARKVP(); /* Page has changed */
  108. MkPubSym("\011$$OVLBASE",GRNIL,gsnOverlay,(RATYPE)0);
  109. /* First byte in overlay area */
  110. apropSn = GenSeg("\013OVERLAY_END","\004CODE",GRNIL,FALSE);
  111. /* Create overlay end */
  112. apropSn->as_flags = dfCode; /* Code segment */
  113. MkPubSym("\010$$OVLEND",GRNIL,apropSn->as_gsn,(RATYPE)0);
  114. /* Last byte in overlay area */
  115. MARKVP(); /* Page has changed */
  116. }
  117. }
  118. #endif /* OVERLAYS */
  119. /****************************************************************
  120. * *
  121. * SetSizes: *
  122. * *
  123. * This function sets the starting address for the segth *
  124. * segment assuming the segment indexed by segPrev immediately *
  125. * precedes the segth segment. If there is a starting address *
  126. * for the segth segment already, then SetSizes will not *
  127. * change that address unless the new address it calculates *
  128. * is higher. *
  129. * *
  130. ****************************************************************/
  131. LOCAL void NEAR SetSizes (segPrev)
  132. SEGTYPE segPrev;
  133. {
  134. long addr; /* 20-bit address */
  135. /* Get address of end of previous segment */
  136. addr = ((long) mpsegsa[segPrev] << 4) +
  137. mpsegcb[segPrev] + mpsegraFirst[segPrev];
  138. /* Form 20-bit address of segment */
  139. switch(B2W(mpsegalign[seg])) /* Align the address properly */
  140. {
  141. case ALGNWRD: /* Word-aligned */
  142. addr = (addr + 1) & ~1L; /* Round up to word offset */
  143. break;
  144. #if OMF386
  145. case ALGNDBL: /* Double word-aligned */
  146. addr = (addr + 3) & ~3L; /* Round up to dword offset */
  147. break;
  148. #endif
  149. case ALGNPAR: /* Paragraph-aligned */
  150. addr = (addr + 0xF) & ~0xFL;
  151. /* Round up to paragraph offset */
  152. break;
  153. case ALGNPAG: /* Page-aligned */
  154. addr = (addr + 0xFF) & ~0xFFL;
  155. /* Round up to page offset */
  156. default: /* Byte-aligned */
  157. break;
  158. }
  159. /* Assign beginning of this segment */
  160. if(addr > ((long) mpsegsa[seg] << 4) + (long) mpsegraFirst[seg])
  161. {
  162. mpsegsa[seg] = (WORD)(addr >> 4);
  163. mpsegraFirst[seg] = (WORD) addr & 0xF;
  164. }
  165. }
  166. /*
  167. * PackCodeSegs : Pack adjacent code segments
  168. *
  169. * Pack as many adjacent code segments (which are in the same
  170. * overlay) together as possible. Start with the current
  171. * segment, seg, and stop when the packing limit is exceeded,
  172. * a data segment is reached, or the given highest segment is
  173. * reached. For DOS3, packing means assigning the same base
  174. * address and adjusting the offset of the first byte.
  175. *
  176. * Parameters:
  177. * segTop Number of highest segment which can be packed.
  178. * Returns:
  179. * Nothing.
  180. * Side effects:
  181. * seg is set to the last segment included in the packing group
  182. */
  183. LOCAL void NEAR PackCodeSegs (segTop)
  184. SEGTYPE segTop;
  185. {
  186. DWORD sacb; /* Length of packing group */
  187. SEGTYPE segi; /* Our private current segment no. */
  188. RATYPE raSave; /* Original mpsegraFirst[segi] */
  189. #if OVERLAYS
  190. IOVTYPE iov; /* Overlay of 1st seg in group */
  191. iov = mpsegiov[seg]; /* Determine current overlay */
  192. #endif
  193. sacb = mpsegcb[seg] + mpsegraFirst[seg]; /* Initialize group size */
  194. for(segi = seg + 1; segi <= segTop; ++segi)
  195. { /* Loop until highest code seg */
  196. #if OVERLAYS
  197. if(mpsegiov[segi] != iov) /* If not a member of this ovl, skip */
  198. continue;
  199. #endif
  200. if(!(mpsegFlags[segi] & FCODE)) /* Stop if we hit a data segment */
  201. break;
  202. /* Adjust alignment */
  203. switch(mpsegalign[segi]) /* Switch on alignment type */
  204. {
  205. case ALGNWRD: /* Word-aligned */
  206. sacb = (sacb + 1) & ~1L;
  207. /* Round up size to word boundary */
  208. break;
  209. #if OMF386
  210. case ALGNDBL: /* Double word-aligned */
  211. sacb = (sacb + 3) & ~3L; /* Round up to dword offset */
  212. break;
  213. #endif
  214. case ALGNPAR: /* Paragraph-aligned */
  215. sacb = (sacb + 0xF) & ~0xFL;
  216. /* Round up size to para boundary */
  217. break;
  218. case ALGNPAG: /* Page-aligned */
  219. sacb = (sacb + 0xFF) & ~0xFFL;
  220. /* Round up size to page boundary */
  221. break;
  222. }
  223. raSave = mpsegraFirst[segi]; /* Save original value */
  224. mpsegraFirst[segi] = sacb; /* Set new offset */
  225. sacb += mpsegcb[segi]; /* Increment size of group */
  226. if(sacb > packLim) /* If packing limit exceeded, stop */
  227. {
  228. mpsegraFirst[segi] = raSave; /* Restore original value */
  229. break;
  230. }
  231. mpsegsa[segi] = mpsegsa[seg]; /* Assign base address */
  232. }
  233. }
  234. /*
  235. * AssignDos3Addr:
  236. *
  237. * Assign addresses for a DOS3-format program.
  238. * Called by AssignAddresses.
  239. */
  240. void NEAR AssignDos3Addr(void)
  241. {
  242. APROPSNPTR apropSn; /* Pointer to a SEGDEF */
  243. SNTYPE gsn; /* Current global SEGDEF no. */
  244. ALIGNTYPE align; /* Alignment type */
  245. GRTYPE ggr; /* Current global GRPDEF no. */
  246. SEGTYPE segTop=0; /* Highest segment in DGROUP */
  247. SNTYPE gsnTop=0; /* Highest segment in DGROUP */
  248. SNTYPE gsnBottomDGroup;/* For DS-allocate */
  249. SEGTYPE segBottomDGroup;/* For DS-allocate */
  250. SATYPE saMaxDGroup; /* For DS-allocate */
  251. SEGTYPE segOverlay;
  252. SEGTYPE segPrev;
  253. #if OVERLAYS
  254. SEGTYPE FAR *mpiovsegPrev;
  255. IOVTYPE iov;
  256. ALIGNTYPE alignOverlay;
  257. long cbOverlay;
  258. WORD segOvlSa;
  259. RATYPE segOvlRaFirst;
  260. #endif
  261. SEGTYPE segStack; /* Logical segment no. of stack */
  262. #if OVERLAYS
  263. mpiovsegPrev = (SEGTYPE FAR *) GetMem(iovMac*sizeof(SEGTYPE));
  264. #endif
  265. segTop = 0;
  266. /* We haven't yet assigned absolute segments (it is assumed
  267. * they are empty and are used only for addressing purposes),
  268. * but now we must assign them somewhere.
  269. */
  270. csegsAbs = 0; /* Assume there are no absolute segs */
  271. for(gsn = 1; gsn < gsnMac; ++gsn) /* Loop to initialize absolute segs */
  272. {
  273. if(mpgsnseg[gsn] == SEGNIL) /* If we have an absolute segment */
  274. {
  275. ++csegsAbs; /* Increment counter */
  276. mpgsnseg[gsn] = ++segLast; /* Assign a segment order number */
  277. }
  278. }
  279. if(vfDSAlloc) /* If doing DS allocation */
  280. {
  281. if(gsnMac >= gsnMax)
  282. Fatal(ER_segmax);
  283. /* We implicitly use another segment */
  284. gsnBottomDGroup = gsnMac; /* Fix the bottom of DGROUP */
  285. ++csegsAbs; /* Inc absolute seg counter */
  286. segBottomDGroup = ++segLast; /* Bottom segment in DGROUP */
  287. mpgsnseg[gsnBottomDGroup] = segLast;
  288. /* Store entry in table */
  289. }
  290. #if OVERLAYS
  291. alignOverlay = ALGNPAR; /* Overlays are para-aligned */
  292. #endif
  293. segLast -= csegsAbs; /* Get no. of last non-abs seg */
  294. /* Find lowest segment in groups, etc. */
  295. for(gsn = 1; gsn < gsnMac; ++gsn) /* Loop to find lowest segs */
  296. {
  297. seg = mpgsnseg[gsn]; /* Get segment number */
  298. apropSn = (APROPSNPTR ) FetchSym(mpgsnrprop[gsn],TRUE);
  299. /* Get symbol table entry */
  300. mpgsndra[gsn] = 0;
  301. #if OVERLAYS
  302. mpsegiov[seg] = apropSn->as_iov;
  303. /* Save overlay number */
  304. #endif
  305. mpsegcb[seg] = apropSn->as_cbMx;
  306. /* Save segment size */
  307. if(apropSn->as_tysn == TYSNABS) /* Assign absolute segs their loc. */
  308. mpsegsa[seg] = (SATYPE) apropSn->as_cbMx;
  309. ggr = apropSn->as_ggr; /* Get GRPDEF number */
  310. if(ggr != GRNIL) /* If segment is group member */
  311. {
  312. if(mpggrgsn[ggr] == SNNIL || mpgsnseg[mpggrgsn[ggr]] > seg)
  313. mpggrgsn[ggr] = gsn;
  314. if(ggr == ggrDGroup && seg > segTop)
  315. {
  316. segTop = seg;
  317. gsnTop = gsn;
  318. }
  319. }
  320. align = (ALIGNTYPE) ((apropSn->as_tysn) >> 5);
  321. if((apropSn->as_tysn & MASKTYSNCOMBINE) == TYSNSTACK) align = ALGNPAR;
  322. if(align > mpsegalign[seg]) mpsegalign[seg] = align;
  323. #if OVERLAYS
  324. if(mpsegiov[seg] != IOVROOT &&
  325. mpiovsegPrev[mpsegiov[seg]] == SEGNIL && align > alignOverlay)
  326. {
  327. mpiovsegPrev[mpsegiov[seg]] = SEGNIL + 1;
  328. alignOverlay = align;
  329. }
  330. #endif
  331. /* Define special symbols "_edata" and "_end" */
  332. if (fSegOrder)
  333. Define_edata_end(apropSn);
  334. }
  335. if (fSegOrder)
  336. Check_edata_end(gsnTop, segTop);
  337. /* Now we assign actual addresses. The procedure is as follows:
  338. * For each code segment
  339. * (1) Assign all addresses of the root up to OVERLAY_AREA or THUNK_AREA.
  340. * (2) Assign all addresses of the overlays.
  341. * (3) If dynamic overlays then set the size of OVERLAY_AREA to zero
  342. * else set the start of the segment after OVERLAY_AREA to be
  343. * the greatest of all the overlays including the root
  344. * OVERLAY_AREA.
  345. * (4) Assign the rest of the root segments.
  346. * Repeat steps one through four for all remaining segments.
  347. *
  348. * Set limit of part (1): up to OVERLAY_AREA(if there are overlays)
  349. * or the end of the segment list. Do not assign OVERLAY_AREA until
  350. * after all the overlays have been taken care of.
  351. *
  352. * For dynamic overlays the DGROUP part of the root overlay
  353. * immediatelly follows the OVERLAY_THUNKS, since the OVERLAY_AREA
  354. * is dynamically allocated by the overlay manager at run-time.
  355. */
  356. #if OVERLAYS
  357. if(fOverlays) /* If there are overlays */
  358. {
  359. segOverlay = mpgsnseg[gsnOverlay];
  360. /* Set limit at 1st overlay */
  361. mpsegalign[segOverlay] = alignOverlay;
  362. }
  363. else
  364. #endif
  365. segOverlay = segLast; /* Look at all segments */
  366. /* Set the sizes of all of the root up until the OVERLAY_AREA. */
  367. segPrev = 0; /* No previous segment */
  368. for(seg = 1; seg <= segOverlay; ++seg)
  369. { /* Loop thru segs up to overlay area */
  370. #if OVERLAYS
  371. if(mpsegiov[seg] == IOVROOT)
  372. { /* If root member */
  373. #endif
  374. SetSizes(segPrev); /* Set start address */
  375. /* If packing code segs and this is one, pack until segOverlay */
  376. if (!fDynamic && packLim != 0L && (mpsegFlags[seg] & FCODE))
  377. PackCodeSegs(segOverlay);
  378. segPrev = seg; /* Save segment number */
  379. #if OVERLAYS
  380. }
  381. #endif
  382. }
  383. #if OVERLAYS
  384. /* If there are no overlays, then we have assigned all
  385. * segments. Otherwise, the previous segment of the
  386. * beginning of the overlays is the OVERLAY_AREA in the
  387. * root. If the dynamic overlays were requested, then
  388. * the OVERLAY_THUNKS becomes the previous segment for
  389. * all overlay segments.
  390. */
  391. if (fOverlays) /* If there are overlays */
  392. {
  393. for (iov = IOVROOT + 1; iov < (IOVTYPE) iovMac; ++iov)
  394. mpiovsegPrev[iov] = segOverlay;
  395. /* Assign addresses to the overlays. We do not assign the
  396. * rest of the root because we may have to expand the size of
  397. * OVERLAY_AREA to accommodate a large overlay.
  398. */
  399. if (fDynamic)
  400. {
  401. // All dymanic overlay are zero based
  402. segOvlSa = mpsegsa[segOverlay];
  403. mpsegsa[segOverlay] = 0;
  404. segOvlRaFirst = mpsegraFirst[segOverlay];
  405. mpsegraFirst[segOverlay] = 0;
  406. }
  407. cbOverlay = mpsegcb[segOverlay];/* Save size of overlay segment */
  408. mpsegcb[segOverlay] = 0; /* Zero the size field for SetSizes */
  409. for (seg = 1; seg <= segLast; ++seg)
  410. {
  411. if(mpsegiov[seg] != IOVROOT)
  412. {
  413. SetSizes(mpiovsegPrev[mpsegiov[seg]]);
  414. /* If packing code segs and this is one, pack until segLast */
  415. if(packLim != 0L && (mpsegFlags[seg] & FCODE))
  416. PackCodeSegs(segLast);
  417. mpiovsegPrev[mpsegiov[seg]] = seg;
  418. }
  419. }
  420. if (fDynamic)
  421. {
  422. mpsegsa[segOverlay] = segOvlSa;
  423. mpsegraFirst[segOverlay] = segOvlRaFirst;
  424. }
  425. mpsegcb[segOverlay] = cbOverlay;/* Reset the size field */
  426. /* Determine first segment in root after OVERLAY_AREA or OVERLAY_THUNKS */
  427. seg = segOverlay + 1;
  428. while (seg <= segLast && mpsegiov[seg] != IOVROOT)
  429. ++seg;
  430. /*
  431. * If there is a segment in the root after the overlays,
  432. * then go through all of the overlays as previous segments
  433. * and set its size with the previous one being the last seg
  434. * of each overlay. We won't initialize the Vm for that
  435. * segment because we won't know the maximum placement until
  436. * afterward.
  437. */
  438. if (seg <= segLast)
  439. {
  440. for (iov = IOVROOT + 1; iov < (IOVTYPE) iovMac; ++iov)
  441. SetSizes(mpiovsegPrev[iov]);
  442. /* Assign the rest of the root */
  443. segPrev = segOverlay;
  444. while (seg <= segLast)
  445. {
  446. if (mpsegiov[seg] == IOVROOT)
  447. {
  448. SetSizes(segPrev);
  449. /* If packing code segs and this is one, pack until segLast */
  450. if(packLim != 0L && (mpsegFlags[seg] & FCODE))
  451. PackCodeSegs(segLast);
  452. segPrev = seg;
  453. }
  454. ++seg;
  455. }
  456. }
  457. }
  458. #endif /* OVERLAYS */
  459. if(vfDSAlloc) /* If doing DS allocation */
  460. {
  461. saMaxDGroup = (SATYPE) (mpsegsa[segTop] +
  462. ((mpsegcb[segTop] + mpsegraFirst[segTop] + 0xF) >> 4));
  463. mpggrgsn[ggrDGroup] = gsnBottomDGroup;
  464. mpsegsa[segBottomDGroup] = (SATYPE)((saMaxDGroup - 0x1000) & ~(~0 << WORDLN));
  465. #if OVERLAYS
  466. mpsegiov[segBottomDGroup] = mpsegiov[segTop];
  467. /* Top and bottom in same overlay */
  468. #endif
  469. mpgsndra[gsnBottomDGroup] = 0;
  470. }
  471. /* If /DOSSEG enabled, stack segment defined, and DGROUP defined,
  472. * check for combined stack + DGROUP <= 64K.
  473. */
  474. if(fSegOrder && gsnStack != SNNIL && mpggrgsn[ggrDGroup] != SNNIL)
  475. {
  476. segStack = mpgsnseg[gsnStack];
  477. if ((((long) mpsegsa[segStack] << 4) + mpsegcb[segStack])
  478. - ((long) mpsegsa[mpgsnseg[mpggrgsn[ggrDGroup]]] << 4)
  479. > LXIVK)
  480. Fatal(ER_stktoobig);
  481. }
  482. segResLast = segLast;
  483. for(gsn = 1; gsn < gsnMac; ++gsn)
  484. mpgsndra[gsn] += mpsegraFirst[mpgsnseg[gsn]];
  485. #if OVERLAYS
  486. /* Set all absolute segs to the root overlay */
  487. seg = segLast + 1;
  488. while(seg < (SEGTYPE) (segLast + csegsAbs)) mpsegiov[seg++] = IOVROOT;
  489. /* "Remember those absolute symbols, too !" */
  490. mpsegiov[0] = IOVROOT;
  491. FFREE(mpiovsegPrev);
  492. #endif
  493. }
  494. #if OVERLAYS
  495. #pragma check_stack(on)
  496. /****************************************************************
  497. * *
  498. * FixOvlData: *
  499. * *
  500. * Initialize overlay data tables. *
  501. * *
  502. ****************************************************************/
  503. void NEAR FixOvlData()
  504. {
  505. APROPNAMEPTR apropName; /* Public symbol name */
  506. AHTEPTR ahte; /* Pointer to hash table entry */
  507. BYTE wrd[2]; /* Word as byte array */
  508. long ra; /* Offset */
  509. SNTYPE osn; /* Overlay segment index */
  510. SEGTYPE seg; /* Segment number */
  511. SATYPE sa; /* Segment base */
  512. BYTE *pb; /* Byte pointer */
  513. SBTYPE sb; /* String buffer */
  514. SNTYPE gsn;
  515. apropName = (APROPNAMEPTR ) PropSymLookup("\006$$CGSN",ATTRPNM,FALSE);
  516. /* Look up public symbol */
  517. mpsegFlags[mpgsnseg[apropName->an_gsn]] |= FNOTEMPTY;
  518. /* Segment is not empty */
  519. wrd[0] = (BYTE) (osnMac & 0xff); /* Get lo byte */
  520. wrd[1] = (BYTE) ((osnMac >> BYTELN) & 0xff); /* Get hi byte */
  521. MoveToVm(2,wrd,mpgsnseg[apropName->an_gsn],apropName->an_ra);
  522. /* Store value */
  523. wrd[0] = (BYTE) (iovMac & 0xff); /* Get lo byte */
  524. wrd[1] = (BYTE) ((iovMac >> BYTELN) & 0xff); /* Get hi byte */
  525. apropName = (APROPNAMEPTR ) PropSymLookup("\006$$COVL",ATTRPNM,FALSE);
  526. /* Look up public symbol */
  527. MoveToVm(2,wrd,mpgsnseg[apropName->an_gsn],apropName->an_ra);
  528. /* Store value */
  529. apropName = (APROPNAMEPTR )PropSymLookup("\013$$MPGSNBASE",ATTRPNM,FALSE);
  530. /* Look up public symbol */
  531. ra = apropName->an_ra; /* Get table offset */
  532. seg = mpgsnseg[apropName->an_gsn]; /* Get segment number */
  533. vrectData = LEDATA;
  534. RecordSegmentReference(seg,ra,seg); /* Record load-time fixup */
  535. ra += 2; /* Increment offset */
  536. /* Entries 1 thru osnMac - 1 contain bases of segments at runtime */
  537. for(osn = 1; osn < osnMac; ++osn) /* Loop thru segment definitions */
  538. {
  539. sa = mpsegsa[mpgsnseg[mposngsn[osn]]];
  540. /* Get segment base */
  541. if (fDynamic)
  542. sa <<= 4; /* Convert para address to offset from overlay base */
  543. wrd[0] = (BYTE) (sa & 0xff); /* Lo byte */
  544. wrd[1] = (BYTE) ((sa >> BYTELN) & 0xff); /* Hi byte */
  545. MoveToVm(2,wrd,seg,ra); /* Move to VM */
  546. if (!fDynamic)
  547. RecordSegmentReference(seg,ra,seg);
  548. /* Record load-time fixup */
  549. ra += 2; /* Increment offset */
  550. }
  551. apropName = (APROPNAMEPTR ) PropSymLookup("\012$$MPGSNOVL",ATTRPNM,FALSE);
  552. /* Look up public symbol */
  553. ra = apropName->an_ra; /* Get table offset */
  554. seg = mpgsnseg[apropName->an_gsn]; /* Get segment number */
  555. if (fDynamic)
  556. {
  557. ra += 2; /* First entry null */
  558. for(osn = 1; osn < osnMac; ++osn)
  559. { /* Loop thru segment definitions */
  560. wrd[0] = (BYTE) mpsegiov[mpgsnseg[mposngsn[osn]]];
  561. wrd[1] = (BYTE) ((mpsegiov[mpgsnseg[mposngsn[osn]]] >> BYTELN) & 0xff);
  562. /* Get overlay number */
  563. MoveToVm(2,wrd,seg,ra); /* Move to VM */
  564. ra += 2;
  565. }
  566. }
  567. else
  568. {
  569. ++ra; /* First entry null */
  570. for(osn = 1; osn < osnMac; ++osn)/* Loop thru segment definitions */
  571. {
  572. wrd[0] = (BYTE) mpsegiov[mpgsnseg[mposngsn[osn]]];
  573. /* Get overlay number */
  574. MoveToVm(1,wrd,seg,ra++); /* Move to VM */
  575. }
  576. apropName = (APROPNAMEPTR ) PropSymLookup("\010$$EXENAM",ATTRPNM,FALSE);
  577. /* Look up public symbol */
  578. ra = apropName->an_ra; /* Get table offset */
  579. seg = mpgsnseg[apropName->an_gsn];
  580. /* Get segment number */
  581. ahte = (AHTEPTR ) FetchSym(rhteRunfile,FALSE);
  582. memcpy(sb,GetFarSb(ahte->cch),1+B2W(ahte->cch[0]));
  583. /* Copy the filename */
  584. pb = StripDrivePath(sb); /* Strip drive and path */
  585. sb[sb[0] + 1] = '\0';
  586. if (strrchr(&sb[1], '.') == NULL)
  587. UpdateFileParts(pb, sbDotExe);
  588. MoveToVm(B2W(pb[0]),pb+1,seg,ra);
  589. /* Move name to VM */
  590. }
  591. apropName = (APROPNAMEPTR ) PropSymLookup("\007$$INTNO",ATTRPNM,FALSE);
  592. /* Look up public symbol */
  593. MoveToVm(1,&vintno,mpgsnseg[apropName->an_gsn],apropName->an_ra);
  594. /* Move overlay number to VM */
  595. /* If /PACKCODE enabled, redefine $$OVLBASE so it has an offset of 0,
  596. * which the overlay manager expects. Find 1st non-root segment
  597. * and use that.
  598. */
  599. if(packLim)
  600. {
  601. apropName = (APROPNAMEPTR) PropSymLookup("\011$$OVLBASE",ATTRPNM, TRUE);
  602. for(gsn = 1; gsn < gsnMac && !mpsegiov[mpgsnseg[gsn]]; ++gsn);
  603. apropName->an_gsn = gsn;
  604. apropName->an_ra = 0;
  605. }
  606. }
  607. #pragma check_stack(off)
  608. #endif /* OVERLAYS */