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.

2350 lines
75 KiB

  1. /* DEF file syntax - yacc */
  2. %token T_FALIAS
  3. %token T_KCLASS
  4. %token T_KNAME
  5. %token T_KLIBRARY
  6. %token T_KBASE
  7. %token T_KDEVICE
  8. %token T_KPHYSICAL
  9. %token T_KVIRTUAL
  10. %token T_ID
  11. %token T_NUMBER
  12. %token T_KDESCRIPTION
  13. %token T_KHEAPSIZE
  14. %token T_KSTACKSIZE
  15. %token T_KMAXVAL
  16. %token T_KCODE
  17. %token T_KCONSTANT
  18. %token <_wd> T_FDISCARDABLE T_FNONDISCARDABLE
  19. %token T_FEXEC
  20. %token <_wd> T_FFIXED
  21. %token <_wd> T_FMOVABLE
  22. %token T_FSWAPPABLE
  23. %token T_FSHARED
  24. %token T_FMIXED
  25. %token <_wd> T_FNONSHARED
  26. %token <_wd> T_FPRELOAD
  27. %token <_wd> T_FINVALID
  28. %token <_wd> T_FLOADONCALL
  29. %token <_wd> T_FRESIDENT
  30. %token <_wd> T_FPERM
  31. %token <_wd> T_FCONTIG
  32. %token <_wd> T_FDYNAMIC
  33. %token T_FNONPERM
  34. %token T_KDATA
  35. %token <_wd> T_FNONE
  36. %token <_wd> T_FSINGLE
  37. %token <_wd> T_FMULTIPLE
  38. %token T_KSEGMENTS
  39. %token T_KOBJECTS
  40. %token T_KSECTIONS
  41. %token T_KSTUB
  42. %token T_KEXPORTS
  43. %token T_KEXETYPE
  44. %token T_KSUBSYSTEM
  45. %token T_FDOS
  46. %token T_FOS2
  47. %token T_FUNKNOWN
  48. %token T_FWINDOWS
  49. %token T_FDEV386
  50. %token T_FMACINTOSH
  51. %token T_FWINDOWSNT
  52. %token T_FWINDOWSCHAR
  53. %token T_FPOSIX
  54. %token T_FNT
  55. %token T_FUNIX
  56. %token T_KIMPORTS
  57. %token <_wd> T_KNODATA
  58. %token T_KOLD
  59. %token T_KCONFORM
  60. %token T_KNONCONFORM
  61. %token T_KEXPANDDOWN T_KNOEXPANDDOWN
  62. %token T_EQ
  63. %token T_AT
  64. %token T_KRESIDENTNAME
  65. %token T_KNONAME
  66. %token T_STRING
  67. %token T_DOT
  68. %token T_COLON
  69. %token T_COMA
  70. %token T_ERROR
  71. %token T_FHUGE T_FIOPL T_FNOIOPL
  72. %token T_PROTMODE
  73. %token <_wd> T_FEXECREAD T_FRDWR
  74. %token T_FRDONLY
  75. %token T_FINITGLOB T_FINITINST T_FTERMINST
  76. %token T_FWINAPI T_FWINCOMPAT T_FNOTWINCOMPAT T_FPRIVATE T_FNEWFILES
  77. %token T_REALMODE
  78. %token T_FUNCTIONS
  79. %token T_APPLOADER
  80. %token T_OVL
  81. %token T_KVERSION
  82. %{ /* SCCSID = %W% %E% */
  83. #include <minlit.h>
  84. #include <bndtrn.h>
  85. #include <bndrel.h>
  86. #include <lnkio.h>
  87. #include <newexe.h>
  88. #if EXE386
  89. #include <exe386.h>
  90. #endif
  91. #include <lnkmsg.h>
  92. #include <extern.h>
  93. #include <string.h>
  94. #include <impexp.h>
  95. #define YYS_WD(x) (x)._wd /* Access macro */
  96. #define YYS_BP(x) (x)._bp /* Access macro */
  97. #define INCLUDE_DIR 0xffff /* Include directive for the lexer */
  98. #define MAX_NEST 7
  99. #define IO_BUF_SIZE 512
  100. /*
  101. * FUNCTION PROTOTYPES
  102. */
  103. LOCAL int NEAR lookup(void);
  104. LOCAL int NEAR yylex(void);
  105. LOCAL void NEAR yyerror(char *str);
  106. LOCAL void NEAR ProcNamTab(long lfa,unsigned short cb,unsigned short fres);
  107. LOCAL void NEAR NewProc(char *szName);
  108. #if NOT EXE386
  109. LOCAL void NEAR SetExpOrds(void);
  110. #endif
  111. LOCAL void NEAR NewDescription(unsigned char *sbDesc);
  112. LOCAL APROPIMPPTR NEAR GetImport(unsigned char *sb);
  113. #if EXE386
  114. LOCAL void NEAR NewModule(unsigned char *sbModnam, unsigned char *defaultExt);
  115. LOCAL void NEAR DefaultModule(unsigned char *defaultExt);
  116. #else
  117. LOCAL void NEAR NewModule(unsigned char *sbModnam);
  118. LOCAL void NEAR DefaultModule(void);
  119. #endif
  120. #if AUTOVM
  121. BYTE FAR * NEAR FetchSym1(RBTYPE rb, WORD Dirty);
  122. #define FETCHSYM FetchSym1
  123. #define PROPSYMLOOKUP EnterName
  124. #else
  125. #define FETCHSYM FetchSym
  126. #define PROPSYMLOOKUP EnterName
  127. #endif
  128. int yylineno = -1; /* Line number */
  129. LOCAL FTYPE fFileNameExpected;
  130. LOCAL FTYPE fMixed;
  131. LOCAL FTYPE fNoExeVer;
  132. LOCAL FTYPE fHeapSize;
  133. LOCAL BYTE *sbOldver; /* Old version of the .EXE */
  134. LOCAL FTYPE vfAutodata;
  135. LOCAL FTYPE vfShrattr;
  136. LOCAL BYTE cDigits;
  137. #if EXE386
  138. LOCAL DWORD offmask; /* Seg flag bits to turn off */
  139. LOCAL BYTE fUserVersion = 0;
  140. LOCAL WORD expOtherFlags = 0;
  141. LOCAL BYTE moduleEXE[] = "\007A:\\.exe";
  142. LOCAL BYTE moduleDLL[] = "\007A:\\.dll";
  143. #else
  144. LOCAL WORD offmask; /* Seg flag bits to turn off */
  145. #endif
  146. #if OVERLAYS
  147. LOCAL WORD iOvl = NOTIOVL; // Overlay assigned to functions
  148. #endif
  149. LOCAL char *szSegName; // Segment assigned to functions
  150. LOCAL WORD nameFlags; /* Flags associated with exported name */
  151. LOCAL BSTYPE includeDisp[MAX_NEST];
  152. // Include file stack
  153. LOCAL short curLevel; // Current include nesting level
  154. // Zero means main .DEF file
  155. LOCAL char *keywds[] = /* Keyword array */
  156. {
  157. "ALIAS", (char *) T_FALIAS,
  158. "APPLOADER", (char *) T_APPLOADER,
  159. "BASE", (char *) T_KBASE,
  160. "CLASS", (char *) T_KCLASS,
  161. "CODE", (char *) T_KCODE,
  162. "CONFORMING", (char *) T_KCONFORM,
  163. "CONSTANT", (char *) T_KCONSTANT,
  164. "CONTIGUOUS", (char *) T_FCONTIG,
  165. "DATA", (char *) T_KDATA,
  166. "DESCRIPTION", (char *) T_KDESCRIPTION,
  167. "DEV386", (char *) T_FDEV386,
  168. "DEVICE", (char *) T_KDEVICE,
  169. "DISCARDABLE", (char *) T_FDISCARDABLE,
  170. "DOS", (char *) T_FDOS,
  171. "DYNAMIC", (char *) T_FDYNAMIC,
  172. "EXECUTE-ONLY", (char *) T_FEXEC,
  173. "EXECUTEONLY", (char *) T_FEXEC,
  174. "EXECUTEREAD", (char *) T_FEXECREAD,
  175. "EXETYPE", (char *) T_KEXETYPE,
  176. "EXPANDDOWN", (char *) T_KEXPANDDOWN,
  177. "EXPORTS", (char *) T_KEXPORTS,
  178. "FIXED", (char *) T_FFIXED,
  179. "FUNCTIONS", (char *) T_FUNCTIONS,
  180. "HEAPSIZE", (char *) T_KHEAPSIZE,
  181. "HUGE", (char *) T_FHUGE,
  182. "IMPORTS", (char *) T_KIMPORTS,
  183. "IMPURE", (char *) T_FNONSHARED,
  184. "INCLUDE", (char *) INCLUDE_DIR,
  185. "INITGLOBAL", (char *) T_FINITGLOB,
  186. "INITINSTANCE", (char *) T_FINITINST,
  187. "INVALID", (char *) T_FINVALID,
  188. "IOPL", (char *) T_FIOPL,
  189. "LIBRARY", (char *) T_KLIBRARY,
  190. "LOADONCALL", (char *) T_FLOADONCALL,
  191. "LONGNAMES", (char *) T_FNEWFILES,
  192. "MACINTOSH", (char *) T_FMACINTOSH,
  193. "MAXVAL", (char *) T_KMAXVAL,
  194. "MIXED1632", (char *) T_FMIXED,
  195. "MOVABLE", (char *) T_FMOVABLE,
  196. "MOVEABLE", (char *) T_FMOVABLE,
  197. "MULTIPLE", (char *) T_FMULTIPLE,
  198. "NAME", (char *) T_KNAME,
  199. "NEWFILES", (char *) T_FNEWFILES,
  200. "NODATA", (char *) T_KNODATA,
  201. "NOEXPANDDOWN", (char *) T_KNOEXPANDDOWN,
  202. "NOIOPL", (char *) T_FNOIOPL,
  203. "NONAME", (char *) T_KNONAME,
  204. "NONCONFORMING", (char *) T_KNONCONFORM,
  205. "NONDISCARDABLE", (char *) T_FNONDISCARDABLE,
  206. "NONE", (char *) T_FNONE,
  207. "NONPERMANENT", (char *) T_FNONPERM,
  208. "NONSHARED", (char *) T_FNONSHARED,
  209. "NOTWINDOWCOMPAT", (char *) T_FNOTWINCOMPAT,
  210. "NT", (char *) T_FNT,
  211. "OBJECTS", (char *) T_KOBJECTS,
  212. "OLD", (char *) T_KOLD,
  213. "OS2", (char *) T_FOS2,
  214. "OVERLAY", (char *) T_OVL,
  215. "OVL", (char *) T_OVL,
  216. "PERMANENT", (char *) T_FPERM,
  217. "PHYSICAL", (char *) T_KPHYSICAL,
  218. "POSIX", (char *) T_FPOSIX,
  219. "PRELOAD", (char *) T_FPRELOAD,
  220. "PRIVATE", (char *) T_FPRIVATE,
  221. "PRIVATELIB", (char *) T_FPRIVATE,
  222. "PROTMODE", (char *) T_PROTMODE,
  223. "PURE", (char *) T_FSHARED,
  224. "READONLY", (char *) T_FRDONLY,
  225. "READWRITE", (char *) T_FRDWR,
  226. "REALMODE", (char *) T_REALMODE,
  227. "RESIDENT", (char *) T_FRESIDENT,
  228. "RESIDENTNAME", (char *) T_KRESIDENTNAME,
  229. "SECTIONS", (char *) T_KSECTIONS,
  230. "SEGMENTS", (char *) T_KSEGMENTS,
  231. "SHARED", (char *) T_FSHARED,
  232. "SINGLE", (char *) T_FSINGLE,
  233. "STACKSIZE", (char *) T_KSTACKSIZE,
  234. "STUB", (char *) T_KSTUB,
  235. "SUBSYSTEM", (char *) T_KSUBSYSTEM,
  236. "SWAPPABLE", (char *) T_FSWAPPABLE,
  237. "TERMINSTANCE", (char *) T_FTERMINST,
  238. "UNIX", (char *) T_FUNIX,
  239. "UNKNOWN", (char *) T_FUNKNOWN,
  240. "VERSION", (char *) T_KVERSION,
  241. "VIRTUAL", (char *) T_KVIRTUAL,
  242. "WINDOWAPI", (char *) T_FWINAPI,
  243. "WINDOWCOMPAT", (char *) T_FWINCOMPAT,
  244. "WINDOWS", (char *) T_FWINDOWS,
  245. "WINDOWSCHAR", (char *) T_FWINDOWSCHAR,
  246. "WINDOWSNT", (char *) T_FWINDOWSNT,
  247. NULL
  248. };
  249. %}
  250. %union
  251. {
  252. #if EXE386
  253. DWORD _wd;
  254. #else
  255. WORD _wd;
  256. #endif
  257. BYTE *_bp;
  258. }
  259. %type <_bp> T_ID
  260. %type <_bp> T_STRING
  261. %type <_bp> Idname
  262. %type <_bp> Internal
  263. %type <_bp> Class
  264. %type <_wd> T_NUMBER
  265. %type <_wd> Codeflaglist
  266. %type <_wd> Codeflag
  267. %type <_wd> Dataflaglist
  268. %type <_wd> Dataflag
  269. %type <_wd> Exportflags
  270. %type <_wd> Exportopts
  271. %type <_wd> Nodata
  272. %type <_wd> Segflags
  273. %type <_wd> Segflag
  274. %type <_wd> Segflaglist
  275. %type <_wd> Baseflag
  276. %type <_wd> Dataonly
  277. %type <_wd> Codeonly
  278. %type <_wd> MajorVer
  279. %type <_wd> MinorVer
  280. %type <_wd> Overlay
  281. %type <_wd> ImportFlags
  282. %%
  283. Definitions : Name Options
  284. | Name
  285. |
  286. {
  287. #if EXE386
  288. DefaultModule(moduleEXE);
  289. #else
  290. DefaultModule();
  291. #endif
  292. }
  293. Options
  294. ;
  295. Name : T_KNAME Idname Apptype OtherFlags VirtBase
  296. {
  297. #if EXE386
  298. NewModule($2, moduleEXE);
  299. #else
  300. NewModule($2);
  301. #endif
  302. }
  303. | T_KNAME Apptype OtherFlags VirtBase
  304. {
  305. #if EXE386
  306. DefaultModule(moduleEXE);
  307. #else
  308. DefaultModule();
  309. #endif
  310. }
  311. | T_KLIBRARY Idname Libflags OtherFlags VirtBase
  312. {
  313. #if EXE386
  314. SetDLL(vFlags);
  315. NewModule($2, moduleDLL);
  316. #else
  317. vFlags = NENOTP | (vFlags & ~NEINST) | NESOLO;
  318. dfData |= NSSHARED;
  319. NewModule($2);
  320. #endif
  321. }
  322. | T_KLIBRARY Libflags OtherFlags VirtBase
  323. {
  324. #if EXE386
  325. SetDLL(vFlags);
  326. DefaultModule(moduleDLL);
  327. #else
  328. vFlags = NENOTP | (vFlags & ~NEINST) | NESOLO;
  329. dfData |= NSSHARED;
  330. DefaultModule();
  331. #endif
  332. }
  333. | T_KPHYSICAL T_KDEVICE Idname Libflags VirtBase
  334. {
  335. #if EXE386
  336. SetDLL(vFlags);
  337. NewModule($3, moduleDLL);
  338. #endif
  339. }
  340. | T_KPHYSICAL T_KDEVICE Libflags VirtBase
  341. {
  342. #if EXE386
  343. SetDLL(vFlags);
  344. DefaultModule(moduleDLL);
  345. #endif
  346. }
  347. | T_KVIRTUAL T_KDEVICE Idname Libflags VirtBase
  348. {
  349. #if EXE386
  350. SetDLL(vFlags);
  351. NewModule($3, moduleDLL);
  352. #endif
  353. }
  354. | T_KVIRTUAL T_KDEVICE Libflags VirtBase
  355. {
  356. #if EXE386
  357. SetDLL(vFlags);
  358. DefaultModule(moduleDLL);
  359. #endif
  360. }
  361. ;
  362. Libflags : T_FINITGLOB
  363. {
  364. #if EXE386
  365. dllFlags &= ~E32_PROCINIT;
  366. #else
  367. vFlags &= ~NEPPLI;
  368. #endif
  369. }
  370. | T_FPRIVATE
  371. {
  372. vFlags |= NEPRIVLIB;
  373. }
  374. | InstanceFlags
  375. |
  376. ;
  377. InstanceFlags : InstanceFlags InstanceFlag
  378. | InstanceFlag
  379. ;
  380. InstanceFlag : T_FINITINST
  381. {
  382. #if EXE386
  383. SetINSTINIT(dllFlags);
  384. #else
  385. vFlags |= NEPPLI;
  386. #endif
  387. }
  388. | T_FTERMINST
  389. {
  390. #if EXE386
  391. SetINSTTERM(dllFlags);
  392. #endif
  393. }
  394. ;
  395. VirtBase : T_KBASE T_EQ T_NUMBER
  396. {
  397. #if EXE386
  398. virtBase = $3;
  399. virtBase = RoundTo64k(virtBase);
  400. #endif
  401. }
  402. |
  403. {
  404. }
  405. ;
  406. Apptype : T_FWINAPI
  407. {
  408. #if EXE386
  409. SetGUI(TargetSubsys);
  410. #else
  411. vFlags |= NEWINAPI;
  412. #endif
  413. }
  414. | T_FWINCOMPAT
  415. {
  416. #if EXE386
  417. SetGUICOMPAT(TargetSubsys);
  418. #else
  419. vFlags |= NEWINCOMPAT;
  420. #endif
  421. }
  422. | T_FNOTWINCOMPAT
  423. {
  424. #if EXE386
  425. SetNOTGUI(TargetSubsys);
  426. #else
  427. vFlags |= NENOTWINCOMPAT;
  428. #endif
  429. }
  430. | T_FPRIVATE
  431. {
  432. vFlags |= NEPRIVLIB;
  433. }
  434. |
  435. {
  436. }
  437. ;
  438. OtherFlags : T_FNEWFILES
  439. {
  440. #if NOT EXE386
  441. vFlagsOthers |= NENEWFILES;
  442. #endif
  443. }
  444. |
  445. {
  446. }
  447. ;
  448. Options : Options Option
  449. | Option
  450. ;
  451. Option : T_KDESCRIPTION T_STRING
  452. {
  453. NewDescription($2);
  454. }
  455. | T_KOLD T_STRING
  456. {
  457. if(sbOldver == NULL) sbOldver = _strdup(bufg);
  458. }
  459. | T_KSTUB T_FNONE
  460. {
  461. if(rhteStub == RHTENIL) fStub = (FTYPE) FALSE;
  462. }
  463. | T_KSTUB T_STRING
  464. {
  465. if(fStub && rhteStub == RHTENIL)
  466. {
  467. PROPSYMLOOKUP($2,ATTRNIL, TRUE);
  468. rhteStub = vrhte;
  469. }
  470. }
  471. | T_KHEAPSIZE
  472. {
  473. fHeapSize = (FTYPE) TRUE;
  474. }
  475. SizeSpec
  476. | T_KSTACKSIZE
  477. {
  478. fHeapSize = (FTYPE) FALSE;
  479. }
  480. SizeSpec
  481. | T_PROTMODE
  482. {
  483. #if NOT EXE386
  484. vFlags |= NEPROT;
  485. #endif
  486. }
  487. | T_REALMODE
  488. {
  489. fRealMode = (FTYPE) TRUE;
  490. vFlags &= ~NEPROT;
  491. }
  492. | T_APPLOADER Idname
  493. {
  494. #if NOT EXE386
  495. AppLoader($2);
  496. #endif
  497. }
  498. | Codeflags
  499. | Dataflags
  500. | Segments
  501. | Exports
  502. | Imports
  503. | ExeType
  504. | SubSystem
  505. | ProcOrder
  506. | UserVersion
  507. ;
  508. SizeSpec : T_NUMBER T_COMA T_NUMBER
  509. {
  510. if (fHeapSize)
  511. {
  512. cbHeap = $1;
  513. #if EXE386
  514. cbHeapCommit = $3;
  515. #endif
  516. }
  517. else
  518. {
  519. if(cbStack)
  520. OutWarn(ER_stackdb, $1);
  521. cbStack = $1;
  522. #if EXE386
  523. cbStackCommit = $3;
  524. #endif
  525. }
  526. }
  527. | T_NUMBER
  528. {
  529. if (fHeapSize)
  530. {
  531. cbHeap = $1;
  532. #if EXE386
  533. cbHeapCommit = cbHeap;
  534. #endif
  535. }
  536. else
  537. {
  538. if(cbStack)
  539. OutWarn(ER_stackdb, $1);
  540. cbStack = $1;
  541. #if EXE386
  542. cbStackCommit = cbStack;
  543. #endif
  544. }
  545. }
  546. | T_KMAXVAL
  547. {
  548. if (fHeapSize)
  549. fHeapMax = (FTYPE) TRUE;
  550. }
  551. ;
  552. Codeflags : T_KCODE Codeflaglist
  553. {
  554. // Set dfCode to specified flags; for any unspecified attributes
  555. // use the defaults. Then reset offmask.
  556. dfCode = $2 | (dfCode & ~offmask);
  557. offmask = 0;
  558. vfShrattr = (FTYPE) FALSE; /* Reset for DATA */
  559. }
  560. ;
  561. Codeflaglist : Codeflaglist Codeflag
  562. {
  563. $$ |= $2;
  564. }
  565. | Codeflag
  566. ;
  567. Codeflag : Baseflag
  568. | Codeonly
  569. ;
  570. Codeonly : T_FEXEC
  571. {
  572. #if EXE386
  573. $$ = OBJ_EXEC;
  574. #else
  575. $$ = NSEXRD;
  576. #endif
  577. }
  578. | T_FEXECREAD
  579. | T_FDISCARDABLE
  580. {
  581. #if EXE386
  582. offmask |= OBJ_RESIDENT;
  583. #else
  584. $$ = NSDISCARD | NSMOVE;
  585. #endif
  586. }
  587. | T_FNONDISCARDABLE
  588. {
  589. #if EXE386
  590. #else
  591. offmask |= NSDISCARD;
  592. #endif
  593. }
  594. | T_KCONFORM
  595. {
  596. #if EXE386
  597. #else
  598. $$ = NSCONFORM;
  599. #endif
  600. }
  601. | T_KNONCONFORM
  602. {
  603. #if EXE386
  604. #else
  605. offmask |= NSCONFORM;
  606. #endif
  607. }
  608. ;
  609. Dataflags : T_KDATA Dataflaglist
  610. {
  611. // Set dfData to specified flags; for any unspecified
  612. // attribute use the defaults. Then reset offmask.
  613. #if EXE386
  614. dfData = ($2 | (dfData & ~offmask));
  615. #else
  616. dfData = $2 | (dfData & ~offmask);
  617. #endif
  618. offmask = 0;
  619. #if NOT EXE386
  620. if (vfShrattr && !vfAutodata)
  621. {
  622. // If share-attribute and no autodata attribute, share-
  623. // attribute controls autodata.
  624. if ($2 & NSSHARED)
  625. vFlags = (vFlags & ~NEINST) | NESOLO;
  626. else
  627. vFlags = (vFlags & ~NESOLO) | NEINST;
  628. }
  629. else if(!vfShrattr)
  630. {
  631. // Else if no share-attribute, autodata attribute
  632. // controls share-attribute.
  633. if (vFlags & NESOLO)
  634. dfData |= NSSHARED;
  635. else if(vFlags & NEINST)
  636. dfData &= ~NSSHARED;
  637. }
  638. #endif
  639. }
  640. ;
  641. Dataflaglist : Dataflaglist Dataflag
  642. {
  643. $$ |= $2;
  644. }
  645. | Dataflag
  646. ;
  647. Dataflag : Baseflag
  648. | Dataonly
  649. | T_FNONE
  650. {
  651. #if NOT EXE386
  652. vFlags &= ~(NESOLO | NEINST);
  653. #endif
  654. }
  655. | T_FSINGLE
  656. {
  657. #if NOT EXE386
  658. vFlags = (vFlags & ~NEINST) | NESOLO;
  659. #endif
  660. vfAutodata = (FTYPE) TRUE;
  661. }
  662. | T_FMULTIPLE
  663. {
  664. #if NOT EXE386
  665. vFlags = (vFlags & ~NESOLO) | NEINST;
  666. #endif
  667. vfAutodata = (FTYPE) TRUE;
  668. }
  669. | T_FDISCARDABLE
  670. {
  671. #if NOT EXE386
  672. // This ONLY for compatibility with JDA IBM LINK
  673. $$ = NSDISCARD | NSMOVE;
  674. #endif
  675. }
  676. | T_FNONDISCARDABLE
  677. {
  678. #if NOT EXE386
  679. // This ONLY for compatibility with JDA IBM LINK
  680. offmask |= NSDISCARD;
  681. #endif
  682. }
  683. ;
  684. Dataonly : T_FRDONLY
  685. {
  686. #if EXE386
  687. $$ = OBJ_READ;
  688. offmask |= OBJ_WRITE;
  689. #else
  690. $$ = NSEXRD;
  691. #endif
  692. }
  693. | T_FRDWR
  694. | T_KEXPANDDOWN
  695. {
  696. #if FALSE AND NOT EXE386
  697. $$ = NSEXPDOWN;
  698. #endif
  699. }
  700. | T_KNOEXPANDDOWN
  701. {
  702. #if FALSE AND NOT EXE386
  703. offmask |= NSEXPDOWN;
  704. #endif
  705. }
  706. ;
  707. Segments : T_KSEGMENTS Segattrlist
  708. | T_KSEGMENTS
  709. | T_KOBJECTS Segattrlist
  710. | T_KOBJECTS
  711. | T_KSECTIONS Segattrlist
  712. | T_KSECTIONS
  713. ;
  714. Segattrlist : Segattrlist Segattr
  715. | Segattr
  716. ;
  717. Segattr : Idname Class Overlay Segflags
  718. {
  719. NewSeg($1, $2, $3, $4);
  720. }
  721. ;
  722. Class : T_KCLASS T_STRING
  723. {
  724. $$ = _strdup($2);
  725. }
  726. |
  727. {
  728. $$ = _strdup("\004CODE");
  729. }
  730. ;
  731. Overlay : T_OVL T_COLON T_NUMBER
  732. {
  733. $$ = $3;
  734. }
  735. |
  736. {
  737. #if OVERLAYS
  738. $$ = NOTIOVL;
  739. #endif
  740. }
  741. ;
  742. Segflag : Baseflag
  743. | Codeonly
  744. | Dataonly
  745. ;
  746. Segflaglist : Segflaglist Segflag
  747. {
  748. $$ |= $2;
  749. }
  750. | Segflag
  751. ;
  752. Segflags : Segflaglist
  753. {
  754. $$ = $1;
  755. }
  756. |
  757. {
  758. $$ = 0;
  759. }
  760. ;
  761. Baseflag : T_FSHARED
  762. {
  763. #if EXE386
  764. $$ = OBJ_SHARED;
  765. #else
  766. $$ = NSSHARED;
  767. #endif
  768. vfShrattr = (FTYPE) TRUE;
  769. }
  770. | T_FNONSHARED
  771. {
  772. vfShrattr = (FTYPE) TRUE;
  773. #if EXE386
  774. offmask |= OBJ_SHARED;
  775. #else
  776. offmask |= NSSHARED;
  777. #endif
  778. }
  779. | T_FINVALID
  780. {
  781. #if EXE386
  782. #endif
  783. }
  784. | T_FIOPL
  785. {
  786. #if EXE386
  787. #else
  788. $$ = (2 << SHIFTDPL) | NSMOVE;
  789. offmask |= NSDPL;
  790. #endif
  791. }
  792. | T_FNOIOPL
  793. {
  794. #if EXE386
  795. #else
  796. $$ = (3 << SHIFTDPL);
  797. #endif
  798. }
  799. | T_FFIXED
  800. {
  801. #if NOT EXE386
  802. offmask |= NSMOVE | NSDISCARD;
  803. #endif
  804. }
  805. | T_FMOVABLE
  806. {
  807. #if NOT EXE386
  808. $$ = NSMOVE;
  809. #endif
  810. }
  811. | T_FPRELOAD
  812. {
  813. #if NOT EXE386
  814. $$ = NSPRELOAD;
  815. #endif
  816. }
  817. | T_FLOADONCALL
  818. {
  819. #if NOT EXE386
  820. offmask |= NSPRELOAD;
  821. #endif
  822. }
  823. | T_FHUGE
  824. {
  825. }
  826. | T_FSWAPPABLE
  827. {
  828. }
  829. | T_FRESIDENT
  830. {
  831. }
  832. | T_FALIAS
  833. {
  834. }
  835. | T_FMIXED
  836. {
  837. }
  838. | T_FNONPERM
  839. {
  840. }
  841. | T_FPERM
  842. {
  843. }
  844. | T_FCONTIG
  845. {
  846. }
  847. | T_FDYNAMIC
  848. {
  849. }
  850. ;
  851. Exports : T_KEXPORTS Exportlist
  852. | T_KEXPORTS
  853. ;
  854. Exportlist : Exportlist Export
  855. | Export
  856. ;
  857. Export : Idname Internal Exportopts Exportflags ExportOtherFlags ScopeFlag
  858. {
  859. NewExport($1,$2,$3,$4);
  860. }
  861. ;
  862. Internal : T_EQ Idname
  863. {
  864. $$ = $2;
  865. }
  866. |
  867. {
  868. $$ = NULL;
  869. }
  870. ;
  871. Exportopts : T_AT T_NUMBER T_KRESIDENTNAME
  872. {
  873. $$ = $2;
  874. nameFlags |= RES_NAME;
  875. }
  876. | T_AT T_NUMBER T_KNONAME
  877. {
  878. $$ = $2;
  879. nameFlags |= NO_NAME;
  880. }
  881. | T_AT T_NUMBER
  882. {
  883. $$ = $2;
  884. }
  885. |
  886. {
  887. $$ = 0;
  888. }
  889. ;
  890. Exportflags : Nodata Parmwds
  891. {
  892. $$ = $1 | 1;
  893. }
  894. ;
  895. Nodata : T_KNODATA
  896. {
  897. /* return 0 */
  898. }
  899. |
  900. {
  901. $$ = 2;
  902. }
  903. ;
  904. Parmwds : T_NUMBER
  905. {
  906. }
  907. |
  908. {
  909. }
  910. ;
  911. ExportOtherFlags: T_KCONSTANT
  912. {
  913. #if EXE386
  914. expOtherFlags |= 0x1;
  915. #endif
  916. }
  917. |
  918. {
  919. }
  920. ;
  921. ScopeFlag : T_FPRIVATE
  922. |
  923. ;
  924. Imports : T_KIMPORTS Importlist
  925. | T_KIMPORTS
  926. ;
  927. Importlist : Importlist Import
  928. | Import
  929. ;
  930. Import : Idname Internal T_DOT Idname ImportFlags
  931. /*
  932. * We'd like to have something like "Alias Idname T_DOT Idname" instead
  933. * of using Internal, since Internal looks for =internal and we're
  934. * looking for internal=. However, that would make this rule ambiguous
  935. * with the next rule, and the 2nd would never be reduced. So we use
  936. * Internal here as a kludge.
  937. */
  938. {
  939. if($2 != NULL)
  940. {
  941. #if EXE386
  942. NewImport($4,0,$2,$1,$5);
  943. #else
  944. NewImport($4,0,$2,$1);
  945. #endif
  946. free($2);
  947. }
  948. else
  949. #if EXE386
  950. NewImport($4,0,$1,$4,$5);
  951. #else
  952. NewImport($4,0,$1,$4);
  953. #endif
  954. free($1);
  955. free($4);
  956. }
  957. | Idname Internal T_DOT T_NUMBER ImportFlags
  958. {
  959. if ($2 == NULL)
  960. Fatal(ER_dfimport);
  961. #if EXE386
  962. NewImport(NULL,$4,$2,$1,$5);
  963. #else
  964. NewImport(NULL,$4,$2,$1);
  965. #endif
  966. free($1);
  967. free($2);
  968. }
  969. ;
  970. Idname : T_ID
  971. {
  972. $$ = _strdup(bufg);
  973. }
  974. | T_STRING
  975. {
  976. $$ = _strdup(bufg);
  977. }
  978. ;
  979. ImportFlags : T_KCONSTANT
  980. {
  981. $$ = 1;
  982. }
  983. |
  984. {
  985. $$ = 0;
  986. }
  987. ;
  988. ExeType : T_KEXETYPE
  989. {
  990. #if EXE386
  991. fUserVersion = (FTYPE) FALSE;
  992. #endif
  993. }
  994. ExeFlags ExeVersion
  995. ;
  996. ExeFlags : T_FDOS
  997. {
  998. TargetOs = NE_DOS;
  999. #if ODOS3EXE
  1000. fNewExe = FALSE;
  1001. #endif
  1002. }
  1003. | T_FOS2
  1004. {
  1005. TargetOs = NE_OS2;
  1006. }
  1007. | T_FUNKNOWN
  1008. {
  1009. TargetOs = NE_UNKNOWN;
  1010. }
  1011. | T_FWINDOWS
  1012. {
  1013. #if EXE386
  1014. TargetSubsys = E32_SSWINGUI;
  1015. #endif
  1016. TargetOs = NE_WINDOWS;// PROTMODE is default for WINDOWS
  1017. fRealMode = (FTYPE) FALSE;
  1018. #if NOT EXE386
  1019. vFlags |= NEPROT;
  1020. #endif
  1021. }
  1022. | T_FDEV386
  1023. {
  1024. TargetOs = NE_DEV386;
  1025. }
  1026. | T_FNT
  1027. {
  1028. #if EXE386
  1029. TargetSubsys = E32_SSWINGUI;
  1030. #endif
  1031. }
  1032. | T_FUNIX
  1033. {
  1034. #if EXE386
  1035. TargetSubsys = E32_SSPOSIXCHAR;
  1036. #endif
  1037. }
  1038. | T_FMACINTOSH T_FSWAPPABLE
  1039. {
  1040. #if O68K
  1041. iMacType = MAC_SWAP;
  1042. f68k = fTBigEndian = fNewExe = (FTYPE) TRUE;
  1043. /* If we are packing code to the default value, change the
  1044. default. */
  1045. if (fPackSet && packLim == LXIVK - 36)
  1046. packLim = LXIVK / 2;
  1047. #endif
  1048. }
  1049. | T_FMACINTOSH
  1050. {
  1051. #if O68K
  1052. iMacType = MAC_NOSWAP;
  1053. f68k = fTBigEndian = fNewExe = (FTYPE) TRUE;
  1054. /* If we are packing code to the default value, change the
  1055. default. */
  1056. if (fPackSet && packLim == LXIVK - 36)
  1057. packLim = LXIVK / 2;
  1058. #endif
  1059. }
  1060. ;
  1061. ExeVersion : MajorVer T_DOT MinorVer
  1062. {
  1063. #if EXE386
  1064. if (fUserVersion)
  1065. {
  1066. UserMajorVer = (BYTE) $1;
  1067. UserMinorVer = (BYTE) $3;
  1068. }
  1069. else
  1070. #endif
  1071. {
  1072. ExeMajorVer = (BYTE) $1;
  1073. ExeMinorVer = (BYTE) $3;
  1074. }
  1075. }
  1076. | MajorVer
  1077. {
  1078. #if EXE386
  1079. if (fUserVersion)
  1080. {
  1081. UserMajorVer = (BYTE) $1;
  1082. UserMinorVer = 0;
  1083. }
  1084. else
  1085. #endif
  1086. {
  1087. ExeMajorVer = (BYTE) $1;
  1088. if(fNoExeVer)
  1089. ExeMinorVer = DEF_EXETYPE_WINDOWS_MINOR;
  1090. else
  1091. ExeMinorVer = 0;
  1092. }
  1093. }
  1094. ;
  1095. MajorVer : T_NUMBER
  1096. {
  1097. $$ = $1;
  1098. }
  1099. |
  1100. {
  1101. $$ = ExeMajorVer;
  1102. fNoExeVer = TRUE;
  1103. }
  1104. ;
  1105. MinorVer : T_NUMBER
  1106. {
  1107. if (cDigits >= 2)
  1108. $$ = $1;
  1109. else
  1110. $$ = 10 * $1;
  1111. }
  1112. |
  1113. {
  1114. $$ = ExeMinorVer;
  1115. }
  1116. ;
  1117. UserVersion : T_KVERSION
  1118. {
  1119. #if EXE386
  1120. fUserVersion = (FTYPE) TRUE;
  1121. #endif
  1122. }
  1123. ExeVersion
  1124. ;
  1125. SubSystem : T_KSUBSYSTEM SubSystemFlags
  1126. ;
  1127. SubSystemFlags : T_FUNKNOWN
  1128. {
  1129. #if EXE386
  1130. TargetSubsys = E32_SSUNKNOWN;
  1131. #endif
  1132. }
  1133. | T_FWINDOWSNT
  1134. {
  1135. #if EXE386
  1136. TargetSubsys = E32_SSNATIVE;
  1137. #endif
  1138. }
  1139. | T_FOS2
  1140. {
  1141. #if EXE386
  1142. TargetSubsys = E32_SSOS2CHAR;
  1143. #endif
  1144. }
  1145. | T_FWINDOWS
  1146. {
  1147. #if EXE386
  1148. TargetSubsys = E32_SSWINGUI;
  1149. #endif
  1150. }
  1151. | T_FWINDOWSCHAR
  1152. {
  1153. #if EXE386
  1154. TargetSubsys = E32_SSWINCHAR;
  1155. #endif
  1156. }
  1157. | T_FPOSIX
  1158. {
  1159. #if EXE386
  1160. TargetSubsys = E32_SSPOSIXCHAR;
  1161. #endif
  1162. }
  1163. ;
  1164. ProcOrder : T_FUNCTIONS
  1165. {
  1166. if (szSegName != NULL)
  1167. {
  1168. free(szSegName);
  1169. szSegName = NULL;
  1170. }
  1171. #if OVERLAYS
  1172. iOvl = NOTIOVL;
  1173. #endif
  1174. }
  1175. SegOrOvl ProcList
  1176. ;
  1177. SegOrOvl : T_COLON NameOrNumber
  1178. |
  1179. ;
  1180. NameOrNumber : Idname
  1181. {
  1182. if (szSegName == NULL)
  1183. szSegName = $1;
  1184. #if OVERLAYS
  1185. iOvl = NOTIOVL;
  1186. #endif
  1187. }
  1188. | T_NUMBER
  1189. {
  1190. #if OVERLAYS
  1191. iOvl = $1;
  1192. fOverlays = (FTYPE) TRUE;
  1193. fNewExe = FALSE;
  1194. TargetOs = NE_DOS;
  1195. #endif
  1196. }
  1197. ;
  1198. ProcList : ProcList ProcName
  1199. | ProcName
  1200. ;
  1201. ProcName : Idname
  1202. {
  1203. NewProc($1);
  1204. }
  1205. ;
  1206. %%
  1207. LOCAL int NEAR GetChar(void)
  1208. {
  1209. int c; /* A character */
  1210. c = GetTxtChr(bsInput);
  1211. if ((c == EOF || c == CTRL_Z) && curLevel > 0)
  1212. {
  1213. free(bsInput->_base);
  1214. fclose(bsInput);
  1215. bsInput = includeDisp[curLevel];
  1216. curLevel--;
  1217. c = GetChar();
  1218. }
  1219. return(c);
  1220. }
  1221. LOCAL int NEAR lookup() /* Keyword lookup */
  1222. {
  1223. char **pcp; /* Pointer to character pointer */
  1224. int i; /* Comparison value */
  1225. for(pcp = keywds; *pcp != NULL; pcp += 2)
  1226. { /* Look through keyword table */
  1227. /* If found, return token type */
  1228. if(!(i = _stricmp(&bufg[1],*pcp)))
  1229. {
  1230. YYS_WD(yylval) = 0;
  1231. return((int) (__int64) pcp[1]);
  1232. }
  1233. if(i < 0) break; /* Break if we've gone too far */
  1234. }
  1235. return(T_ID); /* Just your basic identifier */
  1236. }
  1237. LOCAL int NEAR yylex() /* Lexical analyzer */
  1238. {
  1239. int c; /* A character */
  1240. int StrBegChr; /* What kind of quotte found at the begin of string */
  1241. #if EXE386
  1242. DWORD x; /* Numeric token value */
  1243. #else
  1244. WORD x; /* Numeric token value */
  1245. #endif
  1246. int state; /* State variable */
  1247. BYTE *cp; /* Character pointer */
  1248. BYTE *sz; /* Zero-terminated string */
  1249. static int lastc = 0; /* Previous character */
  1250. char *fileBuf;
  1251. FTYPE fFileNameSave;
  1252. static int NameLineNo;
  1253. state = 0; /* Assume we're not in a comment */
  1254. c = '\0';
  1255. /* Loop to skip white space */
  1256. for(;;)
  1257. {
  1258. lastc = c;
  1259. if (((c = GetChar()) == EOF) || c == '\032' || c == '\377')
  1260. return(EOF); /* Get a character */
  1261. if (c == ';')
  1262. state = TRUE; /* If comment, set flag */
  1263. else if(c == '\n') /* If end of line */
  1264. {
  1265. state = FALSE; /* End of comment */
  1266. if(!curLevel)
  1267. ++yylineno; /* Increment line number count */
  1268. }
  1269. else if (state == FALSE && c != ' ' && c != '\t' && c != '\r')
  1270. break; /* Break on non-white space */
  1271. }
  1272. /* Handle one-character tokens */
  1273. switch(c)
  1274. {
  1275. case '.': /* Name separator */
  1276. if (fFileNameExpected)
  1277. break;
  1278. return(T_DOT);
  1279. case '@': /* Ordinal specifier */
  1280. /*
  1281. * Require that whitespace precede '@' if introducing an
  1282. * ordinal, to allow '@' in identifiers.
  1283. */
  1284. if (lastc == ' ' || lastc == '\t' || lastc == '\r')
  1285. return(T_AT);
  1286. break;
  1287. case '=': /* Name assignment */
  1288. return(T_EQ);
  1289. case ':':
  1290. return(T_COLON);
  1291. case ',':
  1292. return(T_COMA);
  1293. }
  1294. /* See if token is a number */
  1295. if (c >= '0' && c <= '9' && !fFileNameExpected)
  1296. { /* If token is a number */
  1297. x = c - '0'; /* Get first digit */
  1298. c = GetChar(); /* Get next character */
  1299. if(x == 0) /* If octal or hex */
  1300. {
  1301. if(c == 'x' || c == 'X') /* If it is an 'x' */
  1302. {
  1303. state = 16; /* Base is hexadecimal */
  1304. c = GetChar(); /* Get next character */
  1305. }
  1306. else state = 8; /* Else octal */
  1307. cDigits = 0;
  1308. }
  1309. else
  1310. {
  1311. state = 10; /* Else decimal */
  1312. cDigits = 1;
  1313. }
  1314. for(;;)
  1315. {
  1316. if(c >= '0' && c <= '9' && c < (state + '0')) c -= '0';
  1317. else if(state == 16 && c >= 'A' && c <= 'F') c -= 'A' - 10;
  1318. else if(state == 16 && c >= 'a' && c <= 'f') c -= 'a' - 10;
  1319. else break;
  1320. cDigits++;
  1321. x = x*state + c;
  1322. c = (BYTE) GetChar();
  1323. }
  1324. ungetc(c,bsInput);
  1325. YYS_WD(yylval) = x;
  1326. return(T_NUMBER);
  1327. }
  1328. /* See if token is a string */
  1329. if (c == '\'' || c == '"') /* If token is a string */
  1330. {
  1331. StrBegChr = c;
  1332. sz = &bufg[1]; /* Initialize */
  1333. for(state = 0; state != 2;) /* State machine loop */
  1334. {
  1335. if ((c = GetChar()) == EOF)
  1336. return(EOF); /* Check for EOF */
  1337. if (sz >= &bufg[sizeof(bufg)])
  1338. Fatal(ER_dflinemax, sizeof(bufg));
  1339. switch(state) /* Transitions */
  1340. {
  1341. case 0: /* Inside quote */
  1342. if ((c == '\'' || c == '"') && c == StrBegChr)
  1343. state = 1; /* Change state if quote found */
  1344. else
  1345. *sz++ = (BYTE) c; /* Else save character */
  1346. break;
  1347. case 1: /* Inside quote with quote */
  1348. if ((c == '\'' || c == '"'))
  1349. { /* If consecutive quotes */
  1350. *sz++ = (BYTE) c; /* Quote inside string */
  1351. state = 0; /* Back to state 0 */
  1352. }
  1353. else
  1354. state = 2; /* Else end of string */
  1355. break;
  1356. }
  1357. }
  1358. ungetc(c,bsInput); /* Put back last character */
  1359. *sz = '\0'; /* Null-terminate the string */
  1360. x = (WORD)(sz - &bufg[1]);
  1361. if (x >= SBLEN) /* Set length of string */
  1362. {
  1363. bufg[0] = 0xff;
  1364. bufg[0x100] = '\0';
  1365. OutWarn(ER_dfnamemax, &bufg[1]);
  1366. }
  1367. else
  1368. bufg[0] = (BYTE) x;
  1369. YYS_BP(yylval) = bufg; /* Save ptr. to identifier */
  1370. return(T_STRING); /* String found */
  1371. }
  1372. /* Assume we have identifier */
  1373. sz = &bufg[1]; /* Initialize */
  1374. if (fFileNameExpected && NameLineNo && NameLineNo != yylineno)
  1375. {
  1376. NameLineNo = 0; /* To avoid interference with INCLUDE */
  1377. fFileNameExpected = FALSE;
  1378. }
  1379. for(;;) /* Loop to get i.d.'s */
  1380. {
  1381. if (fFileNameExpected)
  1382. cp = " \t\r\n\f";
  1383. else
  1384. cp = " \t\r\n:.=';\032";
  1385. while (*cp && *cp != (BYTE) c)
  1386. ++cp; /* Check for end of identifier */
  1387. if(*cp) break; /* Break if end of identifier found */
  1388. if (sz >= &bufg[sizeof(bufg)])
  1389. Fatal(ER_dflinemax, sizeof(bufg));
  1390. *sz++ = (BYTE) c; /* Save the character */
  1391. if ((c = GetChar()) == EOF)
  1392. break; /* Get next character */
  1393. }
  1394. ungetc(c,bsInput); /* Put character back */
  1395. *sz = '\0'; /* Null-terminate the string */
  1396. x = (WORD)(sz - &bufg[1]);
  1397. if (x >= SBLEN) /* Set length of string */
  1398. {
  1399. bufg[0] = 0xff;
  1400. bufg[0x100] = '\0';
  1401. OutWarn(ER_dfnamemax, &bufg[1]);
  1402. }
  1403. else
  1404. bufg[0] = (BYTE) x;
  1405. YYS_BP(yylval) = bufg; /* Save ptr. to identifier */
  1406. state = lookup();
  1407. if (state == T_KNAME || state == T_KLIBRARY)
  1408. {
  1409. fFileNameExpected = TRUE;
  1410. NameLineNo = yylineno;
  1411. }
  1412. if (state == INCLUDE_DIR)
  1413. {
  1414. // Process include directive
  1415. fFileNameSave = fFileNameExpected;
  1416. fFileNameExpected = (FTYPE) TRUE;
  1417. state = yylex();
  1418. fFileNameExpected = fFileNameSave;
  1419. if (state == T_ID || state == T_STRING)
  1420. {
  1421. if (curLevel < MAX_NEST - 1)
  1422. {
  1423. curLevel++;
  1424. includeDisp[curLevel] = bsInput;
  1425. // Because LINK uses customized version of stdio
  1426. // for every file we have not only open the file
  1427. // but also allocate i/o buffer.
  1428. bsInput = fopen(&bufg[1], RDBIN);
  1429. if (bsInput == NULL)
  1430. Fatal(ER_badinclopen, &bufg[1], strerror(errno));
  1431. fileBuf = GetMem(IO_BUF_SIZE);
  1432. #if OSMSDOS
  1433. setvbuf(bsInput, fileBuf, _IOFBF, IO_BUF_SIZE);
  1434. #endif
  1435. return(yylex());
  1436. }
  1437. else
  1438. Fatal(ER_toomanyincl);
  1439. }
  1440. else
  1441. Fatal(ER_badinclname);
  1442. }
  1443. else
  1444. return(state);
  1445. }
  1446. LOCAL void NEAR yyerror(str)
  1447. char *str;
  1448. {
  1449. Fatal(ER_dfsyntax, str);
  1450. }
  1451. #if NOT EXE386
  1452. /*** AppLoader - define aplication specific loader
  1453. *
  1454. * Purpose:
  1455. * Define application specific loader. Feature available only under
  1456. * Windows. Linker will create logical segment LOADER_<name> where
  1457. * <name> is specified in APPLOADER statement. The LOADER_<name>
  1458. * segment forms separate physical segment, which is placed by the linker
  1459. * as the first segment in the .EXE file. Whithin the loader segment,
  1460. * the linker will create an EXTDEF of the name <name>.
  1461. *
  1462. * Input:
  1463. * - sbName - pointer to lenght prefixed loader name
  1464. *
  1465. * Output:
  1466. * No explicit value is returned. As a side effect the SEGDEF and
  1467. * EXTDEF definitions are entered into linker symbol table.
  1468. *
  1469. * Exceptions:
  1470. * None.
  1471. *
  1472. * Notes:
  1473. * None.
  1474. *
  1475. *************************************************************************/
  1476. LOCAL void NEAR AppLoader(char *sbName)
  1477. {
  1478. APROPSNPTR apropSn;
  1479. APROPUNDEFPTR apropUndef;
  1480. SBTYPE segName;
  1481. WORD strLen;
  1482. // Create loader segment name
  1483. strcpy(&segName[1], "LOADER_");
  1484. strcat(&segName[1], &sbName[1]);
  1485. strLen = strlen(&segName[1]);
  1486. if (strLen >= SBLEN)
  1487. {
  1488. segName[0] = SBLEN - 1;
  1489. segName[SBLEN] = '\0';
  1490. OutWarn(ER_dfnamemax, &segName[1]);
  1491. }
  1492. else
  1493. segName[0] = (BYTE) strLen;
  1494. // Define loader logical segment and remember its GSN
  1495. apropSn = GenSeg(segName, "\004CODE", GRNIL, (FTYPE) TRUE);
  1496. gsnAppLoader = apropSn->as_gsn;
  1497. apropSn->as_flags = dfCode | NSMOVE | NSPRELOAD;
  1498. MARKVP();
  1499. // Define EXTDEF
  1500. apropUndef = (APROPUNDEFPTR ) PROPSYMLOOKUP(sbName, ATTRUND, TRUE);
  1501. vpropAppLoader = vrprop;
  1502. apropUndef->au_flags |= STRONGEXT;
  1503. apropUndef->au_len = -1L;
  1504. MARKVP();
  1505. free(sbName);
  1506. }
  1507. #endif
  1508. /*** NewProc - fill in the COMDAT descriptor for ordered procedure
  1509. *
  1510. * Purpose:
  1511. * Fill in the linkers symbol table COMDAT descriptor. This function
  1512. * is called for new descriptors generated by FUNCTIONS list in the .DEF
  1513. * file. All COMDAT descriptors entered by this function form one
  1514. * list linked via ac_order field. The head of this list is global
  1515. * variable procOrder;
  1516. *
  1517. * Input:
  1518. * szName - pointer to procedure name
  1519. * iOvl - overlay number - global variable
  1520. * szSegName - segment name - global variable
  1521. *
  1522. * Output:
  1523. * No explicit value is returned. As a side effect symbol table entry
  1524. * is updated.
  1525. *
  1526. * Exceptions:
  1527. * Procedure already known - warning
  1528. *
  1529. * Notes:
  1530. * None.
  1531. *
  1532. *************************************************************************/
  1533. LOCAL void NEAR NewProc(char *szName)
  1534. {
  1535. RBTYPE vrComdat; // Virtual pointer to COMDAT symbol table entry
  1536. APROPCOMDATPTR apropComdat; // Real pointer to COMDAT symbol table descriptor
  1537. static RBTYPE lastProc; // Last procedure on the list
  1538. APROPSNPTR apropSn;
  1539. apropComdat = (APROPCOMDATPTR ) PROPSYMLOOKUP(szName, ATTRCOMDAT, FALSE);
  1540. if ((apropComdat != NULL) && (apropComdat->ac_flags & ORDER_BIT))
  1541. OutWarn(ER_duporder, &szName[1]);
  1542. else
  1543. {
  1544. apropComdat = (APROPCOMDATPTR ) PROPSYMLOOKUP(szName, ATTRCOMDAT, TRUE);
  1545. vrComdat = vrprop;
  1546. // Fill in the COMDAT descriptor
  1547. apropComdat->ac_flags = ORDER_BIT;
  1548. #if OVERLAYS
  1549. apropComdat->ac_iOvl = iOvl;
  1550. // Set the maximum overlay index
  1551. if (iOvl != NOTIOVL)
  1552. {
  1553. fOverlays = (FTYPE) TRUE;
  1554. fNewExe = FALSE;
  1555. if (iOvl >= iovMac)
  1556. iovMac = iOvl + 1;
  1557. }
  1558. #endif
  1559. if (szSegName != NULL)
  1560. {
  1561. apropSn = GenSeg(szSegName, "\004CODE", GRNIL, (FTYPE) TRUE);
  1562. apropSn->as_flags = dfCode;
  1563. // Allocate COMDAT in the segment
  1564. apropComdat->ac_gsn = apropSn->as_gsn;
  1565. apropComdat->ac_selAlloc = PICK_FIRST | EXPLICIT;
  1566. AttachComdat(vrComdat, apropSn->as_gsn);
  1567. }
  1568. else
  1569. apropComdat->ac_selAlloc = ALLOC_UNKNOWN;
  1570. MARKVP(); // Page has been changed
  1571. // Attach this COMDAT to the ordered procedure list
  1572. if (procOrder == VNIL)
  1573. procOrder = vrComdat;
  1574. else
  1575. {
  1576. apropComdat = (APROPCOMDATPTR ) FETCHSYM(lastProc, TRUE);
  1577. apropComdat->ac_order = vrComdat;
  1578. }
  1579. lastProc = vrComdat;
  1580. }
  1581. free(szName);
  1582. }
  1583. LOCAL void NEAR ProcNamTab(lfa,cb,fres)
  1584. long lfa; /* Table starting address */
  1585. WORD cb; /* Length of table */
  1586. WORD fres; /* Resident name flag */
  1587. {
  1588. SBTYPE sbExport; /* Exported symbol name */
  1589. WORD ordExport; /* Export ordinal */
  1590. APROPEXPPTR exp; /* Export symbol table entry */
  1591. fseek(bsInput,lfa,0); /* Seek to start of table */
  1592. for(cbRec = cb; cbRec != 0; ) /* Loop through table */
  1593. {
  1594. sbExport[0] = (BYTE) getc(bsInput);/* Get length of name */
  1595. fread(&sbExport[1], sizeof(char), B2W(sbExport[0]), bsInput);
  1596. /* Get export name */
  1597. ordExport = getc(bsInput) | (getc(bsInput) << BYTELN);
  1598. if (ordExport == 0) continue;
  1599. /* Skip if no ordinal assigned */
  1600. exp = (APROPEXPPTR ) PROPSYMLOOKUP(sbExport, ATTREXP, FALSE);
  1601. /* Look the export up */
  1602. if(exp == PROPNIL || exp->ax_ord != 0) continue;
  1603. /* Must exist and be unassigned */
  1604. exp->ax_ord = ordExport; /* Assign ordinal */
  1605. if (fres)
  1606. exp->ax_nameflags |= RES_NAME;
  1607. /* Set flag if from resident table */
  1608. MARKVP(); /* Page has been changed */
  1609. }
  1610. }
  1611. #if NOT EXE386
  1612. LOCAL void NEAR SetExpOrds(void)/* Set export ordinals */
  1613. {
  1614. struct exe_hdr ehdr; /* Old .EXE header */
  1615. struct new_exe hdr; /* New .EXE header */
  1616. long lfahdr; /* File offset of header */
  1617. if((bsInput = LinkOpenExe(sbOldver)) == NULL)
  1618. { /* If old version can't be opened */
  1619. /* Error message and return */
  1620. OutWarn(ER_oldopn);
  1621. return;
  1622. }
  1623. SETRAW(bsInput); /* Dec 20 hack */
  1624. xread(&ehdr,CBEXEHDR,1,bsInput); /* Read old header */
  1625. if(E_MAGIC(ehdr) == EMAGIC) /* If old header found */
  1626. {
  1627. if(E_LFARLC(ehdr) != sizeof(struct exe_hdr))
  1628. { /* If no new .EXE in this file */
  1629. /* Error message and return */
  1630. OutWarn(ER_oldbad);
  1631. return;
  1632. }
  1633. lfahdr = E_LFANEW(ehdr); /* Get file address of new header */
  1634. }
  1635. else lfahdr = 0L; /* Else no old header */
  1636. fseek(bsInput,lfahdr,0); /* Seek to new header */
  1637. xread(&hdr,CBNEWEXE,1,bsInput); /* Read the header */
  1638. if(NE_MAGIC(hdr) == NEMAGIC) /* If correct magic number */
  1639. {
  1640. ProcNamTab(lfahdr+NE_RESTAB(hdr),(WORD)(NE_MODTAB(hdr) - NE_RESTAB(hdr)),(WORD)TRUE);
  1641. /* Process Resident Name table */
  1642. ProcNamTab(NE_NRESTAB(hdr),NE_CBNRESTAB(hdr),FALSE);
  1643. /* Process Non-resident Name table */
  1644. }
  1645. else OutWarn(ER_oldbad);
  1646. fclose(bsInput); /* Close old file */
  1647. }
  1648. #endif
  1649. LOCAL void NEAR NewDescription(BYTE *sbDesc)
  1650. {
  1651. #if NOT EXE386
  1652. if (NonResidentName.byteMac > 3)
  1653. Fatal(ER_dfdesc); /* Should be first time */
  1654. AddName(&NonResidentName, sbDesc, 0);
  1655. /* Description 1st in non-res table */
  1656. #endif
  1657. }
  1658. #if EXE386
  1659. LOCAL void NEAR NewModule(BYTE *sbModnam, BYTE *defaultExt)
  1660. #else
  1661. LOCAL void NEAR NewModule(BYTE *sbModnam)
  1662. #endif
  1663. {
  1664. WORD length; /* Length of symbol */
  1665. #if EXE386
  1666. SBTYPE sbModule;
  1667. BYTE *pName;
  1668. #endif
  1669. if(rhteModule != RHTENIL) Fatal(ER_dfname);
  1670. /* Check for redefinition */
  1671. PROPSYMLOOKUP(sbModnam, ATTRNIL, TRUE);
  1672. /* Create hash table entry */
  1673. rhteModule = vrhte; /* Save virtual hash table address */
  1674. #if EXE386
  1675. memcpy(sbModule, sbModnam, sbModnam[0] + 1);
  1676. if (sbModule[sbModule[0]] == '.')
  1677. {
  1678. sbModule[sbModule[0]] = '\0';
  1679. length = sbModule[0];
  1680. pName = &sbModule[1];
  1681. }
  1682. else
  1683. {
  1684. UpdateFileParts(sbModule, defaultExt);
  1685. length = sbModule[0] - 2;
  1686. pName = &sbModule[4];
  1687. }
  1688. if (TargetOs == NE_WINDOWS)
  1689. SbUcase(sbModule); /* Make upper case */
  1690. vmmove(length, pName, AREAEXPNAME, TRUE);
  1691. /* Module name 1st in Export Name Table */
  1692. cbExpName = length;
  1693. #else
  1694. if (TargetOs == NE_WINDOWS)
  1695. SbUcase(sbModnam); /* Make upper case */
  1696. AddName(&ResidentName, sbModnam, 0);/* Module name 1st in resident table */
  1697. #endif
  1698. fFileNameExpected = (FTYPE) FALSE;
  1699. }
  1700. void NewExport(sbEntry,sbInternal,ordno,flags)
  1701. BYTE *sbEntry; /* Entry name */
  1702. BYTE *sbInternal; /* Internal name */
  1703. WORD ordno; /* Ordinal number */
  1704. WORD flags; /* Flag byte */
  1705. {
  1706. APROPEXPPTR export; /* Export record */
  1707. APROPUNDEFPTR undef; /* Undefined symbol */
  1708. APROPNAMEPTR PubName; /* Defined name */
  1709. BYTE *sb; /* Internal name */
  1710. BYTE ParWrds; /* # of parameter words */
  1711. RBTYPE rbSymdef; /* Virtual addr of symbol definition */
  1712. #if EXE386
  1713. RBTYPE vExport; /* Virtual pointer to export descriptor */
  1714. APROPNAMEPTR public; /* Matching public symbol */
  1715. #endif
  1716. #if DEBUG
  1717. fprintf(stdout,"\r\nEXPORT: ");
  1718. OutSb(stdout,sbEntry);
  1719. NEWLINE(stdout);
  1720. if(sbInternal != NULL)
  1721. {
  1722. fprintf(stdout,"INTERNAL NAME: ");
  1723. OutSb(stdout,sbInternal);
  1724. NEWLINE(stdout);
  1725. }
  1726. fprintf(stdout, " ordno %u, flags %u ", (unsigned)ordno, (unsigned)flags);
  1727. fflush(stdout);
  1728. #endif
  1729. sb = (sbInternal != NULL)? sbInternal: sbEntry;
  1730. /* Get pointer to internal name */
  1731. PubName = (APROPNAMEPTR ) PROPSYMLOOKUP(sb, ATTRPNM, FALSE);
  1732. #if NOT EXE386
  1733. if(PubName != PROPNIL && !fDrivePass)
  1734. /* If internal name already exists as a public symbol
  1735. * and we are parsing definition file, issue
  1736. * export internal name conflict warning.
  1737. */
  1738. OutWarn(ER_expcon,sbEntry+1,sb+1);
  1739. else /* Else if no conflict */
  1740. {
  1741. #endif
  1742. if (PubName == PROPNIL) /* If no matching name exists */
  1743. undef = (APROPUNDEFPTR ) PROPSYMLOOKUP(sb,ATTRUND, TRUE);
  1744. /* Make undefined symbol entry */
  1745. #if TCE
  1746. #if TCE_DEBUG
  1747. fprintf(stdout, "\r\nNewExport adds UNDEF %s ", 1+GetPropName(undef));
  1748. #endif
  1749. undef->au_fAlive = TRUE; /* all exports are potential entry points */
  1750. #endif
  1751. rbSymdef = vrprop; /* Save virtual address */
  1752. if (PubName == PROPNIL) /* If this is a new symbol */
  1753. undef->au_len = -1L; /* Make no type assumptions */
  1754. export = (APROPEXPPTR ) PROPSYMLOOKUP(sbEntry,ATTREXP, TRUE);
  1755. /* Create export record */
  1756. #if EXE386
  1757. vExport = vrprop;
  1758. #endif
  1759. if(vfCreated) /* If this is a new entry */
  1760. {
  1761. export->ax_symdef = rbSymdef;
  1762. /* Save virt addr of symbol def */
  1763. export->ax_ord = ordno;
  1764. /* Save ordinal number */
  1765. if (nameFlags & RES_NAME)
  1766. export->ax_nameflags |= RES_NAME;
  1767. /* Remember if resident */
  1768. else if (nameFlags & NO_NAME)
  1769. export->ax_nameflags |= NO_NAME;
  1770. /* Remember to discard name */
  1771. export->ax_flags = (BYTE) flags;
  1772. /* Save flags */
  1773. ++expMac; /* One more exported symbol */
  1774. }
  1775. else
  1776. {
  1777. if (!fDrivePass) /* Else if parsing definition file */
  1778. /* multiple definitions */
  1779. OutWarn(ER_expmul,sbEntry + 1);
  1780. /* Output error message */
  1781. else
  1782. { /* We were called for EXPDEF object */
  1783. /* record, so we merge information */
  1784. ParWrds = (BYTE) (export->ax_flags & 0xf8);
  1785. if (ParWrds && (ParWrds != (BYTE) (flags & 0xf8)))
  1786. Fatal(ER_badiopl);
  1787. /* If the iopl_parmwords field in the */
  1788. /* .DEF file is not 0 and does not match */
  1789. /* value in the EXPDEF exactly issue error */
  1790. else if (!ParWrds)
  1791. { /* Else set value from EXPDEF record */
  1792. ParWrds = (BYTE) (flags & 0xf8);
  1793. export->ax_flags |= ParWrds;
  1794. }
  1795. }
  1796. }
  1797. #if EXE386
  1798. if (PubName != NULL)
  1799. {
  1800. if (expOtherFlags & 0x1)
  1801. {
  1802. export->ax_nameflags |= CONSTANT;
  1803. expOtherFlags = 0;
  1804. }
  1805. }
  1806. #endif
  1807. #if NOT EXE386
  1808. }
  1809. #endif
  1810. if(!(flags & 0x8000))
  1811. {
  1812. free(sbEntry); /* Free space */
  1813. if(sbInternal != NULL) free(sbInternal);
  1814. }
  1815. /* Free space */
  1816. nameFlags = 0;
  1817. }
  1818. LOCAL APROPIMPPTR NEAR GetImport(sb) /* Get name in Imported Names Table */
  1819. BYTE *sb; /* Length-prefixed names */
  1820. {
  1821. APROPIMPPTR import; /* Pointer to imported name */
  1822. #if EXE386
  1823. DWORD cbTemp; /* Temporary value */
  1824. #else
  1825. WORD cbTemp; /* Temporary value */
  1826. #endif
  1827. RBTYPE rprop; /* Property cell virtual address */
  1828. import = (APROPIMPPTR ) PROPSYMLOOKUP(sb,ATTRIMP, TRUE);
  1829. /* Look up module name */
  1830. if(vfCreated) /* If no offset assigned yet */
  1831. {
  1832. rprop = vrprop; /* Save the virtual address */
  1833. /*
  1834. * WARNING: We must store name in virtual memory now, otherwise
  1835. * if an EXTDEF was seen first, fIgnoreCase is false, and the
  1836. * cases do not match between the imported name and the EXTDEF,
  1837. * then the name will not go in the table exactly as given.
  1838. */
  1839. import = (APROPIMPPTR) FETCHSYM(rprop,TRUE);
  1840. /* Retrieve from symbol table */
  1841. import->am_offset = AddImportedName(sb);
  1842. /* Save offset */
  1843. }
  1844. return(import); /* Return offset in table */
  1845. }
  1846. #if NOT EXE386
  1847. void NewImport(sbEntry,ordEntry,sbModule,sbInternal)
  1848. BYTE *sbEntry; /* Entry point name */
  1849. WORD ordEntry; /* Entry point ordinal */
  1850. BYTE *sbModule; /* Module name */
  1851. BYTE *sbInternal; /* Internal name */
  1852. {
  1853. APROPNAMEPTR public; /* Public symbol */
  1854. APROPIMPPTR import; /* Imported symbol */
  1855. BYTE *sb; /* Symbol pointer */
  1856. WORD module; /* Module name offset */
  1857. FTYPE flags; /* Import flags */
  1858. WORD modoff; /* module name offset */
  1859. WORD entry; /* Entry name offset */
  1860. BYTE *cp; /* Char pointer */
  1861. RBTYPE rpropundef; /* Address of undefined symbol */
  1862. char buf[32]; /* Buffer for error sgring */
  1863. #if DEBUG
  1864. fprintf(stderr,"\r\nIMPORT: ");
  1865. OutSb(stderr,sbModule);
  1866. fputc('.',stderr);
  1867. if(!ordEntry)
  1868. {
  1869. OutSb(stderr,sbEntry);
  1870. }
  1871. else fprintf(stderr,"%u",ordEntry);
  1872. if(sbInternal != sbEntry)
  1873. {
  1874. fprintf(stderr," ALIAS: ");
  1875. OutSb(stderr,sbInternal);
  1876. }
  1877. fprintf(stdout," ordEntry %u ", (unsigned)ordEntry);
  1878. fflush(stdout);
  1879. #endif
  1880. if((public = (APROPNAMEPTR ) PROPSYMLOOKUP(sbInternal, ATTRUND, FALSE)) !=
  1881. PROPNIL && !fDrivePass) /* If internal names conflict */
  1882. {
  1883. if(sbEntry != NULL)
  1884. sb = sbEntry;
  1885. else
  1886. {
  1887. sprintf(buf + 1,"%u",ordEntry);
  1888. sb = buf;
  1889. }
  1890. OutWarn(ER_impcon,sbModule + 1,sb + 1,sbInternal + 1);
  1891. }
  1892. else /* Else if no conflicts */
  1893. {
  1894. rpropundef = vrprop; /* Save virtual address of extern */
  1895. flags = FIMPORT; /* We have an imported symbol */
  1896. if (TargetOs == NE_WINDOWS)
  1897. SbUcase(sbModule); /* Force module name to upper case */
  1898. import = GetImport(sbModule); /* Get pointer to import record */
  1899. if((module = import->am_mod) == 0)
  1900. {
  1901. // If not in Module Reference Table
  1902. import->am_mod = WordArrayPut(&ModuleRefTable, import->am_offset) + 1;
  1903. /* Save offset of name in table */
  1904. module = import->am_mod;
  1905. }
  1906. if(vrhte == rhteModule) /* If importing from this module */
  1907. {
  1908. if(sbEntry != NULL)
  1909. sb = sbEntry;
  1910. else
  1911. {
  1912. sprintf(buf+1,"%u",ordEntry);
  1913. sb = buf;
  1914. }
  1915. if (TargetOs == NE_OS2)
  1916. OutWarn(ER_impself,sbModule + 1,sb + 1,sbInternal + 1);
  1917. else
  1918. OutError(ER_impself,sbModule + 1,sb + 1,sbInternal + 1);
  1919. }
  1920. if(sbEntry == NULL) /* If entry by ordinal */
  1921. {
  1922. flags |= FIMPORD; /* Set flag bit */
  1923. entry = ordEntry; /* Get ordinal number */
  1924. }
  1925. else /* Else if import by name */
  1926. {
  1927. if(fIgnoreCase) SbUcase(sbEntry);
  1928. /* Upper case the name if flag set */
  1929. import = GetImport(sbEntry);
  1930. entry = import->am_offset;
  1931. /* Get offset of name in table */
  1932. }
  1933. if(public == PROPNIL) /* If no undefined symbol */
  1934. {
  1935. public = (APROPNAMEPTR )
  1936. PROPSYMLOOKUP(sbInternal,ATTRPNM, TRUE);
  1937. /* Make a public symbol */
  1938. if(!vfCreated) /* If not new */
  1939. /* Output error message */
  1940. OutWarn(ER_impmul,sbInternal + 1);
  1941. else ++pubMac; /* Else increment public count */
  1942. }
  1943. else /* Else if symbol is undefined */
  1944. {
  1945. public = (APROPNAMEPTR ) FETCHSYM(rpropundef,TRUE);
  1946. /* Look up external symbol */
  1947. ++pubMac; /* Increment public symbol count */
  1948. }
  1949. flags |= FPRINT; /* Symbol is printable */
  1950. public->an_attr = ATTRPNM; /* This is a public symbol */
  1951. public->an_gsn = SNNIL; /* Not a segment member */
  1952. public->an_ra = 0; /* No known offset */
  1953. public->an_ggr = GRNIL; /* Not a group member */
  1954. public->an_flags = flags; /* Set flags */
  1955. public->an_entry = entry; /* Save entry specification */
  1956. public->an_module = module; /* Save Module Reference Table index */
  1957. #if SYMDEB AND FALSE
  1958. if (fSymdeb) /* If debugger support on */
  1959. {
  1960. if (flags & FIMPORD)
  1961. import = GetImport(sbInternal);
  1962. else /* Add internal name to Imported Name Table */
  1963. import = GetImport(sbEntry);
  1964. import->am_public = public;
  1965. /* Remember public symbol */
  1966. if (cbImpSeg < LXIVK-1)
  1967. cbImpSeg += sizeof(CVIMP);
  1968. }
  1969. #endif
  1970. }
  1971. }
  1972. #endif
  1973. #if OVERLAYS
  1974. extern void NEAR GetName(AHTEPTR ahte, BYTE *pBuf);
  1975. #endif
  1976. /*** NewSeg - new segment definition
  1977. *
  1978. * Purpose:
  1979. * Create new segment definition based on the module definition
  1980. * file segment description. Check for duplicate definitions and
  1981. * overlay index inconsistency between attached COMDATs (if any)
  1982. * and segment itself.
  1983. *
  1984. * Input:
  1985. * sbName - segment name
  1986. * sbClass - segment class
  1987. * iOvl - segment overlay index
  1988. * flags - segment attributes
  1989. *
  1990. * Output:
  1991. * No explicit value is returned. The segment descriptor in
  1992. * symbol table is created or updated.
  1993. *
  1994. * Exceptions:
  1995. * Multiple segment definitions - warning and continue
  1996. * Change in overlay index - warning and continue
  1997. *
  1998. * Notes:
  1999. * None.
  2000. *
  2001. *************************************************************************/
  2002. void NEAR NewSeg(BYTE *sbName, BYTE *sbClass, WORD iOvl,
  2003. #if EXE386
  2004. DWORD flags)
  2005. #else
  2006. WORD flags)
  2007. #endif
  2008. {
  2009. APROPSNPTR apropSn; // Pointer to segment descriptor
  2010. #if OVERLAYS
  2011. RBTYPE vrComdat; // Virtual pointer to COMDAT descriptor
  2012. APROPCOMDATPTR apropComdat; // Symbol table entry for COMDAT symbol
  2013. SBTYPE sbComdat; // Name buffer
  2014. #endif
  2015. // Set segment attributes based on the class
  2016. if (SbSuffix(sbClass,"\004CODE",TRUE))
  2017. flags |= dfCode & ~offmask;
  2018. else
  2019. flags |= dfData & ~offmask;
  2020. #if O68K
  2021. if (f68k)
  2022. flags |= NS32BIT;
  2023. #endif
  2024. #if OVERLAYS
  2025. if (iOvl != NOTIOVL)
  2026. {
  2027. fOverlays = (FTYPE) TRUE;
  2028. fNewExe = FALSE;
  2029. if (iOvl >= iovMac) // Set the maximum overlay index
  2030. iovMac = iOvl + 1;
  2031. }
  2032. #endif
  2033. // Generate new segment definition
  2034. apropSn = GenSeg(sbName, sbClass, GRNIL, (FTYPE) TRUE);
  2035. if (vfCreated)
  2036. {
  2037. apropSn->as_flags = (WORD) flags;
  2038. // Save flags
  2039. mpgsndra[apropSn->as_gsn] = 0; // Initialize
  2040. #if OVERLAYS
  2041. apropSn->as_iov = iOvl; // Save overlay index
  2042. if (fOverlays)
  2043. CheckOvl(apropSn, iOvl);
  2044. #endif
  2045. apropSn->as_fExtra |= (BYTE) FROM_DEF_FILE;
  2046. // Remember defined in def file
  2047. if (fMixed)
  2048. {
  2049. apropSn->as_fExtra |= (BYTE) MIXED1632;
  2050. fMixed = (FTYPE) FALSE;
  2051. }
  2052. }
  2053. else
  2054. {
  2055. apropSn = CheckClass(apropSn, apropSn->as_rCla);
  2056. // Check if previous definition had the same class
  2057. OutWarn(ER_segdup,sbName + 1); // Warn about multiple definition
  2058. #if OVERLAYS
  2059. if (fOverlays && apropSn->as_iov != iOvl)
  2060. {
  2061. if (apropSn->as_iov != NOTIOVL)
  2062. OutWarn(ER_badsegovl, 1 + GetPropName(apropSn), apropSn->as_iov, iOvl);
  2063. apropSn->as_iov = iOvl; // Save new overlay index
  2064. CheckOvl(apropSn, iOvl);
  2065. // Check if segment has any COMDATs and if it has
  2066. // then check theirs overlay numbers
  2067. for (vrComdat = apropSn->as_ComDat;
  2068. vrComdat != VNIL;
  2069. vrComdat = apropComdat->ac_sameSeg)
  2070. {
  2071. apropComdat = (APROPCOMDATPTR ) FetchSym(vrComdat, FALSE);
  2072. if (apropComdat->ac_iOvl != NOTIOVL && apropComdat->ac_iOvl != iOvl)
  2073. {
  2074. GetName((AHTEPTR) apropComdat, sbComdat);
  2075. OutWarn(ER_badcomdatovl, &sbComdat[1], apropComdat->ac_iOvl, iOvl);
  2076. }
  2077. apropComdat->ac_iOvl = iOvl;
  2078. }
  2079. }
  2080. #endif
  2081. }
  2082. free(sbClass); // Free class name
  2083. free(sbName); // Free segment name
  2084. offmask = 0;
  2085. // Unless packing limit already set, disable default code packing
  2086. if (!fPackSet)
  2087. {
  2088. fPackSet = (FTYPE) TRUE; // Remember packLim was set
  2089. packLim = 0L;
  2090. }
  2091. }
  2092. /*
  2093. * Assign module name to be default, which is run file name.
  2094. *
  2095. * SIDE EFFECTS
  2096. * Assigns rhteModule
  2097. */
  2098. #if EXE386
  2099. LOCAL void NEAR DefaultModule (unsigned char *defaultExt)
  2100. #else
  2101. LOCAL void NEAR DefaultModule (void)
  2102. #endif
  2103. {
  2104. SBTYPE sbModname; /* Module name */
  2105. AHTEPTR ahte; /* Pointer to hash table entry */
  2106. #if OSXENIX
  2107. int i;
  2108. #endif
  2109. ahte = (AHTEPTR ) FETCHSYM(rhteRunfile,FALSE);
  2110. /* Get executable file name */
  2111. #if OSMSDOS
  2112. memcpy(sbModname,GetFarSb(ahte->cch),B2W(ahte->cch[0]) + 1);
  2113. /* Copy file name */
  2114. #if EXE386
  2115. NewModule(sbModname, defaultExt); /* Use run file name as module name */
  2116. #else
  2117. UpdateFileParts(sbModname,"\005A:\\.X");
  2118. /* Force path, ext with known length */
  2119. sbModname[0] -= 2; /* Remove extension from name */
  2120. sbModname[3] = (BYTE) (sbModname[0] - 3);
  2121. /* Remove path and drive from name */
  2122. NewModule(&sbModname[3]); /* Use run file name as module name */
  2123. #endif
  2124. #endif
  2125. #if OSXENIX
  2126. for(i = B2W(ahte->cch[0]); i > 0 && ahte->cch[i] != '/'; i--)
  2127. sbModname[0] = B2W(ahte->cch[0]) - i;
  2128. memcpy(sbModname+1,&GetFarSb(ahte->cch)[i+1],B2W(sbModname[0]));
  2129. for(i = B2W(ahte->cch[0]); i > 1 && sbModname[i] != '.'; i--);
  2130. if(i > 1)
  2131. sbModname[0] = i - 1;
  2132. NewModule(sbModname); /* Use run file name as module name */
  2133. #endif
  2134. }
  2135. void ParseDeffile(void)
  2136. {
  2137. SBTYPE sbDeffile; /* Definitions file name */
  2138. AHTEPTR ahte; /* Pointer to hash table entry */
  2139. #if OSMSDOS
  2140. char buf[512]; /* File buffer */
  2141. #endif
  2142. if(rhteDeffile == RHTENIL) /* If no definitions file */
  2143. #if EXE386
  2144. DefaultModule(moduleEXE);
  2145. #else
  2146. DefaultModule();
  2147. #endif
  2148. else /* Else if there is a file to parse */
  2149. {
  2150. #if ODOS3EXE
  2151. fNewExe = (FTYPE) TRUE; /* Def file forces new-format exe */
  2152. #endif
  2153. ahte = (AHTEPTR ) FETCHSYM(rhteDeffile,FALSE);
  2154. /* Fetch file name */
  2155. memcpy(sbDeffile,GetFarSb(ahte->cch),B2W(ahte->cch[0]) + 1);
  2156. /* Copy file name */
  2157. sbDeffile[B2W(sbDeffile[0]) + 1] = '\0';
  2158. /* Null-terminate the name */
  2159. if((bsInput = fopen(&sbDeffile[1],RDTXT)) == NULL)
  2160. { /* If open fails */
  2161. Fatal(ER_opndf, &sbDeffile[1]);/* Fatal error */
  2162. }
  2163. #if OSMSDOS
  2164. setvbuf(bsInput,buf,_IOFBF,sizeof(buf));
  2165. #endif
  2166. includeDisp[0] = bsInput; // Initialize include stack
  2167. sbOldver = NULL; /* Assume no old version */
  2168. yylineno = 1;
  2169. fFileNameExpected = (FTYPE) FALSE;
  2170. // HACK ALERT !!!
  2171. // Don't allocate to much page buffers
  2172. yyparse(); /* Parse the definitions file */
  2173. yylineno = -1;
  2174. fclose(bsInput); /* Close the definitions file */
  2175. #if NOT EXE386
  2176. if(sbOldver != NULL) /* If old version given */
  2177. {
  2178. SetExpOrds(); /* Use old version to set ordinals */
  2179. free(sbOldver); /* Release the space */
  2180. }
  2181. #endif
  2182. }
  2183. #if OSMSDOS
  2184. #endif /* OSMSDOS */
  2185. #if NOT EXE386
  2186. if (NonResidentName.byteMac == 0)
  2187. {
  2188. ahte = (AHTEPTR ) FETCHSYM(rhteRunfile,FALSE);
  2189. /* Get executable file name */
  2190. memcpy(sbDeffile,GetFarSb(ahte->cch),B2W(ahte->cch[0]) + 1);
  2191. /* Copy file name */
  2192. #if OSXENIX
  2193. SbUcase(sbDeffile); /* For identical executables */
  2194. #endif
  2195. if ((vFlags & NENOTP) && TargetOs == NE_OS2)
  2196. UpdateFileParts(sbDeffile, sbDotDll);
  2197. else
  2198. UpdateFileParts(sbDeffile, sbDotExe);
  2199. NewDescription(sbDeffile); /* Use run file name as description */
  2200. }
  2201. #endif
  2202. }