Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2397 lines
57 KiB

4 years ago
  1. /***********************************************************************
  2. * Microsoft (R) 32-Bit Incremental Linker
  3. *
  4. * Copyright (C) Microsoft Corp 1992-95. All rights reserved.
  5. *
  6. * File: cvtomf.cpp
  7. *
  8. * File Comments:
  9. *
  10. * Conversion from OMF to COFF
  11. *
  12. ***********************************************************************/
  13. #include "link.h"
  14. #include "cvtomf.h"
  15. // Type definitions
  16. typedef struct RELOCS
  17. {
  18. IMAGE_RELOCATION Reloc;
  19. struct RELOCS *Next;
  20. } RELOCS, *PRELOCS;
  21. typedef struct RELOC_LIST
  22. {
  23. PRELOCS First;
  24. PRELOCS Last;
  25. WORD Count;
  26. } RELOC_LIST, *PRELOC_LIST;
  27. typedef struct LINENUMS
  28. {
  29. IMAGE_LINENUMBER Linenum;
  30. struct LINENUMS *Next;
  31. } LINENUMS, *PLINENUMS;
  32. typedef struct LINENUM_LIST
  33. {
  34. PLINENUMS First;
  35. PLINENUMS Last;
  36. WORD Count;
  37. } LINENUM_LIST, *PLINENUM_LIST;
  38. // Data definitions
  39. static FILE *objfile;
  40. static jmp_buf mark;
  41. char szCvtomfSourceName[_MAX_PATH];
  42. static SHORT mods; // module count
  43. static DWORD isymDefAux;
  44. // rectyp, use32, reclen, chksum: fields common to all OMF records
  45. static SHORT rectyp;
  46. static SHORT use32;
  47. static SHORT reclen;
  48. static BYTE chksum;
  49. // lnms, lname: name list counter/array
  50. static SHORT lnms;
  51. static char *lname[MAXNAM];
  52. static DWORD llname[MAXNAM];
  53. static char *comments[MAXCOM];
  54. static SHORT ncomments;
  55. static LONG cmntsize;
  56. static fPrecomp; // Regular types or precompiled types?
  57. // segs, grps, exts: segment/group/external counters
  58. static SHORT segs;
  59. static SHORT grps;
  60. static SHORT defs;
  61. static WORD exts;
  62. // segment, group, external: arrays of symbol table indices
  63. static DWORD segment[MAXSCN];
  64. static DWORD group[MAXGRP];
  65. static DWORD extdefs[MAXEXT];
  66. static DWORD external[MAXEXT];
  67. struct segdefn
  68. {
  69. SHORT namindx;
  70. SHORT scn;
  71. DWORD align;
  72. DWORD flags;
  73. } segindx[MAXNAM];
  74. static DWORD SEG_ALIGN[] = { 0L, 1L, 2L, 16L, 1024L*4L, 4L, 0L, 0L };
  75. static SHORT cursegindx;
  76. // dattype, datscn, datoffset: type/section/offset of last data record
  77. static WORD dattype;
  78. static SHORT datscn;
  79. static DWORD datoffset;
  80. // text_scn: text section #, comes from segdef(), used in handling LEXTDEF
  81. // records
  82. static SHORT text_scn;
  83. static SHORT data_scn;
  84. static SHORT bss_scn;
  85. // Hash queue for global symbols
  86. static struct sym **hashhead;
  87. static struct rlct **rlcthash;
  88. static int omfpass;
  89. // OMF cannot have more than 32k line entries per module
  90. static struct lines *lines;
  91. static int line_indx;
  92. #define ALLOCSZ (64) // must be power of 2
  93. #define ALLOCMSK (ALLOCSZ - 1)
  94. static DWORD target[4]; // threads
  95. static BOOL fTargetThreadSeg[4];
  96. struct sfix
  97. {
  98. DWORD offset;
  99. DWORD datoffset;
  100. SHORT datscn;
  101. WORD dattype;
  102. struct sfix *next;
  103. };
  104. struct sfix *fixlist, *fixlast;
  105. static WORD flag;
  106. static DWORD scnsize; // total size of all sections
  107. static DWORD strsize; // total size of the string table
  108. static DWORD nreloc; // relocation counter
  109. static DWORD nlnno; // linenumber counter
  110. static WORD nscns; // section counter
  111. static DWORD nsyms; // symbol counter
  112. static IMAGE_SECTION_HEADER scnhdr[MAXSCN]; // section headers
  113. static DWORD scnauxidx[MAXSCN]; // special aux symbol entries for each section
  114. static BYTE *RawData[MAXSCN];
  115. static DWORD RawDataMaxSize[MAXSCN];
  116. static PIMAGE_SYMBOL SymTable;
  117. static DWORD SymTableMaxSize;
  118. static char *CvtomfStringTable;
  119. static DWORD StringTableMaxSize;
  120. static RELOC_LIST Relocations[MAXSCN];
  121. static LINENUM_LIST Linenumbers[MAXSCN];
  122. // fatal: print an error message and exit
  123. void fatal(char *format, ...)
  124. {
  125. va_list args;
  126. va_start(args, format);
  127. printf("LINK : error : ");
  128. vprintf(format, args);
  129. putc('\n', stdout);
  130. va_end(args);
  131. _fcloseall();
  132. longjmp(mark, -1);
  133. }
  134. VOID syminit(void)
  135. {
  136. if (!hashhead) {
  137. hashhead = (struct sym **) PvAlloc(NBUCKETS * sizeof(struct sym *));
  138. }
  139. memset(hashhead, 0, NBUCKETS * sizeof(struct sym *));
  140. if (rlcthash == NULL) {
  141. rlcthash = (struct rlct **) PvAlloc(NBUCKETS * sizeof(struct rlct *));
  142. }
  143. memset(rlcthash, 0, NBUCKETS * sizeof(struct rlct *));
  144. }
  145. // block: read a block
  146. // ** side-effect ** : update reclen
  147. VOID block(unsigned char *buffer, long size)
  148. {
  149. if (fread(buffer, 1, (size_t)size, objfile) != (unsigned int)size) {
  150. fatal("Bad read of object file");
  151. }
  152. reclen -= (SHORT) size;
  153. }
  154. // byte, word, dword: read a fixed-length field
  155. BYTE byte(void)
  156. {
  157. BYTE c;
  158. block(&c, 1L);
  159. return c;
  160. }
  161. WORD word(void)
  162. {
  163. BYTE c[2];
  164. block(c, 2L);
  165. return((WORD) c[0] | ((WORD) c[1] << 8));
  166. }
  167. DWORD dword(void)
  168. {
  169. BYTE c[4];
  170. block(c, 4L);
  171. return((DWORD) c[0] | ((DWORD) c[1] << 8) | ((DWORD) c[2] << 16) | ((DWORD) c[3] << 24));
  172. }
  173. // index, length, string: read a variable-length field
  174. SHORT index(void)
  175. {
  176. BYTE c[2];
  177. SHORT i;
  178. block(c, 1L);
  179. i = INDEX_BYTE(c);
  180. if (i == (SHORT) -1) {
  181. block(c + 1, 1L);
  182. i = (SHORT) INDEX_WORD(c);
  183. }
  184. return i;
  185. }
  186. DWORD length(void)
  187. {
  188. BYTE c[4];
  189. block(c, 1L);
  190. switch (c[0]) {
  191. case LENGTH2:
  192. block(c, 2L);
  193. return (DWORD)c[0] | ((DWORD)c[1] << 8);
  194. case LENGTH3:
  195. block(c, 3L);
  196. return (DWORD)c[0] | ((DWORD)c[1] << 8) | ((DWORD)c[2] << 16);
  197. case LENGTH4:
  198. block(c, 4L);
  199. return (DWORD)c[0] | ((DWORD)c[1] << 8) | ((DWORD)c[2] << 16) | ((DWORD)c[3] << 24);
  200. default:
  201. return (DWORD)c[0];
  202. }
  203. }
  204. char *string(BOOL strip)
  205. {
  206. BYTE c;
  207. BYTE *s;
  208. block(&c, 1L);
  209. s = (BYTE *) PvAlloc(c + 1);
  210. block(s, (long) c);
  211. s[c] = '\0';
  212. strip = strip;
  213. return (char *)s;
  214. }
  215. // hash function for global symbols hash queue
  216. int symhash(const char *key)
  217. {
  218. unsigned int index = 0;
  219. while (*key) {
  220. index += (index << 1) + *key++;
  221. }
  222. return(index % NBUCKETS);
  223. }
  224. struct sym *findsym(const char *name)
  225. {
  226. struct sym *ptr;
  227. ptr = hashhead[symhash(name)];
  228. while (ptr) {
  229. if (!strcmp(ptr->name, name)) {
  230. break;
  231. }
  232. ptr = ptr->next;
  233. }
  234. return(ptr);
  235. }
  236. VOID addsym(char *name, DWORD offset, WORD type, SHORT scn, WORD ext, WORD typ)
  237. {
  238. struct sym **list;
  239. struct sym *ptr;
  240. ptr = (struct sym *) PvAllocZ(sizeof(struct sym));
  241. ptr->name = name;
  242. ptr->offset = offset;
  243. ptr->type = type;
  244. ptr->scn = scn;
  245. ptr->typ = typ;
  246. ptr->ext = ext;
  247. list = &hashhead[symhash(name)];
  248. if (!*list) {
  249. *list = ptr;
  250. } else {
  251. ptr->next = *list;
  252. *list = ptr;
  253. }
  254. }
  255. VOID updatesym(char *name, DWORD offset, WORD type, SHORT scn, WORD typ)
  256. {
  257. struct sym *ptr;
  258. ptr = findsym(name);
  259. if (ptr) {
  260. ptr->offset = offset;
  261. ptr->type = type;
  262. ptr->scn = scn;
  263. ptr->typ = typ;
  264. } else {
  265. addsym(name, offset, type, scn, exts, typ);
  266. }
  267. }
  268. DWORD AddLongName(const char *szName)
  269. {
  270. size_t cbName;
  271. DWORD ibName;
  272. if (!strsize) {
  273. CvtomfStringTable = (char *) PvAllocZ(BUFFERSIZE);
  274. strsize = sizeof(DWORD);
  275. StringTableMaxSize = BUFFERSIZE;
  276. }
  277. cbName = strlen(szName) + 1;
  278. ibName = strsize;
  279. if (strsize + cbName > StringTableMaxSize) {
  280. void *pv;
  281. // String table grew larger than BUFFERSIZE.
  282. pv = PvAllocZ(StringTableMaxSize + BUFFERSIZE + cbName);
  283. memcpy(pv, CvtomfStringTable, StringTableMaxSize);
  284. FreePv(CvtomfStringTable);
  285. CvtomfStringTable = (char *) pv;
  286. StringTableMaxSize += BUFFERSIZE + cbName;
  287. }
  288. memcpy(CvtomfStringTable+ibName, szName, cbName);
  289. strsize += cbName;
  290. return(ibName);
  291. }
  292. DWORD symbol(const char *name, DWORD value, SHORT scnum, WORD sclass, WORD csymAux)
  293. {
  294. int len;
  295. IMAGE_SYMBOL syment;
  296. len = strlen(name);
  297. if (len <= IMAGE_SIZEOF_SHORT_NAME) {
  298. strncpy((char *)syment.N.ShortName, name, IMAGE_SIZEOF_SHORT_NAME);
  299. } else {
  300. syment.N.Name.Short = 0;
  301. syment.N.Name.Long = AddLongName(name);
  302. }
  303. syment.Value = value;
  304. syment.SectionNumber = scnum;
  305. syment.Type = IMAGE_SYM_TYPE_NULL;
  306. syment.StorageClass = (BYTE) sclass;
  307. syment.NumberOfAuxSymbols = (BYTE) csymAux;
  308. if (!nsyms) {
  309. SymTable = (PIMAGE_SYMBOL) PvAllocZ(BUFFERSIZE);
  310. SymTableMaxSize = BUFFERSIZE;
  311. }
  312. if ((nsyms+1)*sizeof(IMAGE_SYMBOL) > SymTableMaxSize) {
  313. void *pv;
  314. // Symbol table grew larger than BUFFERSIZE.
  315. pv = PvAllocZ(SymTableMaxSize+BUFFERSIZE);
  316. memcpy(pv, (void *) SymTable, SymTableMaxSize);
  317. FreePv((void *) SymTable);
  318. SymTable = (PIMAGE_SYMBOL) pv;
  319. SymTableMaxSize += BUFFERSIZE;
  320. }
  321. SymTable[nsyms] = syment;
  322. return(nsyms++);
  323. }
  324. DWORD aux(PIMAGE_AUX_SYMBOL AuxSym)
  325. {
  326. if ((nsyms+1)*sizeof(IMAGE_SYMBOL) > SymTableMaxSize) {
  327. void *pv;
  328. // Symbol table grew larger than BUFFERSIZE.
  329. pv = PvAllocZ(SymTableMaxSize+BUFFERSIZE);
  330. memcpy(pv, (void *) SymTable, SymTableMaxSize);
  331. FreePv((void *) SymTable);
  332. SymTable = (PIMAGE_SYMBOL) pv;
  333. SymTableMaxSize += BUFFERSIZE;
  334. }
  335. SymTable[nsyms] = *(PIMAGE_SYMBOL) AuxSym;
  336. return(nsyms++);
  337. }
  338. VOID extdef(BOOL cextdef, WORD sclass)
  339. {
  340. char *name;
  341. WORD type;
  342. WORD typ;
  343. WORD scn;
  344. SHORT nam;
  345. struct sym *ptr;
  346. while (reclen > 1) {
  347. if (cextdef) {
  348. nam = index();
  349. name = lname[nam];
  350. } else {
  351. name = (sclass == IMAGE_SYM_CLASS_STATIC) ? string(FALSE) : string (TRUE);
  352. }
  353. typ = (WORD)index();
  354. if (cextdef && llname[nam]) {
  355. continue;
  356. }
  357. if (++exts >= MAXEXT) {
  358. fatal("Too many externals");
  359. }
  360. extdefs[++defs] = exts;
  361. if (!strcmp(name, _ACRTUSED) || !strcmp(name, __ACRTUSED)) {
  362. continue; /* do nothing */
  363. }
  364. type = (sclass == IMAGE_SYM_CLASS_STATIC) ? (WORD)S_LEXT : (WORD)S_EXT;
  365. // Static text. Pass along text section number, or
  366. // AT&T linker will barf (it doesn't like getting
  367. // relocation info for something of class static...).
  368. // Skip the matching LPUBDEF rec that goes along with
  369. // this LEXTDEF -- we already have the section #.
  370. //
  371. // N.B. Assumes LEXTDEF/LPUBDEF recs only emitted for
  372. // static text (not data). Cmerge group PROMISES this
  373. // will be true forever and ever. Note that these
  374. // recs are only emitted for forward references; the
  375. // compiler does self-relative relocation for
  376. // backward references...
  377. ptr = findsym(name);
  378. scn = ptr ? ptr->scn : IMAGE_SYM_UNDEFINED;
  379. addsym(name, 0, type, scn, exts, typ);
  380. }
  381. }
  382. VOID save_fixupp(DWORD offset)
  383. {
  384. struct sfix *newfix;
  385. newfix = (struct sfix *) PvAlloc(sizeof(struct sfix));
  386. newfix->offset = offset;
  387. newfix->datoffset = datoffset;
  388. newfix->datscn = datscn;
  389. newfix->dattype = dattype;
  390. newfix->next = NULL;
  391. if (!fixlast) {
  392. fixlist = fixlast = newfix;
  393. } else {
  394. fixlast->next = newfix;
  395. fixlast = newfix;
  396. }
  397. }
  398. // method: read a segment, group or external index, if necessary, and return
  399. // a symbol table index
  400. DWORD method(int x)
  401. {
  402. DWORD idx;
  403. SHORT temp;
  404. switch (x) {
  405. case SEGMENT:
  406. idx = segment[index()];
  407. break;
  408. case GROUP:
  409. idx = group[index()];
  410. break;
  411. case EXTERNAL:
  412. temp = index();
  413. if (llname[temp]) {
  414. idx = llname[temp];
  415. break;
  416. }
  417. idx = external[extdefs[temp]];
  418. break;
  419. case LOCATION:
  420. case TARGET:
  421. idx = (DWORD)-1;
  422. break;
  423. default:
  424. fatal("Bad method in FIXUP record");
  425. }
  426. return(idx);
  427. }
  428. // saverlct: remember that there is a fixup to the specified offset
  429. // from the specified symbol.
  430. VOID saverlct(DWORD TargetSymbolIndex, DWORD offset)
  431. {
  432. unsigned bucket;
  433. struct rlct *ptr;
  434. bucket = (TargetSymbolIndex + offset) % NBUCKETS;
  435. ptr = rlcthash[bucket];
  436. while (ptr) {
  437. if ((ptr->TargetSymbolIndex == TargetSymbolIndex) &&
  438. (ptr->offset == offset)) {
  439. return;
  440. }
  441. ptr = ptr->next;
  442. }
  443. ptr = (struct rlct *) PvAlloc(sizeof(struct rlct));
  444. ptr->TargetSymbolIndex = TargetSymbolIndex;
  445. ptr->offset = offset;
  446. ptr->next = rlcthash[bucket];
  447. rlcthash[bucket] = ptr;
  448. }
  449. // rlctlookup: locates the synthetic symbol (created by
  450. // createrlctsyms) representing the specified symbol and offset (which
  451. // was used as a fixup target).
  452. DWORD rlctlookup(DWORD TargetSymbolIndex, DWORD offset)
  453. {
  454. unsigned bucket;
  455. struct rlct *ptr;
  456. bucket = (TargetSymbolIndex + offset) % NBUCKETS;
  457. ptr = rlcthash[bucket];
  458. for (;;) {
  459. if ((ptr->TargetSymbolIndex == TargetSymbolIndex) &&
  460. (ptr->offset == offset)) {
  461. return(ptr->SymbolTableIndex);
  462. }
  463. ptr = ptr->next;
  464. }
  465. #if 0
  466. // We didn't find it. This should never happen ... if we put an assert
  467. // here, will it prevent building standalone cvtomf.exe?
  468. return((DWORD)-1);
  469. #endif
  470. }
  471. // createrlctsyms: creates synthetic symbols for non-zero offsets
  472. // from normal symbols.
  473. VOID createrlctsyms(void)
  474. {
  475. unsigned bucket;
  476. struct rlct *ptr;
  477. SHORT scn;
  478. DWORD value;
  479. char name[8];
  480. unsigned i = 0;
  481. for (bucket = 0; bucket < NBUCKETS; bucket++) {
  482. for (ptr = rlcthash[bucket]; ptr != NULL; ptr = ptr->next) {
  483. scn = SymTable[ptr->TargetSymbolIndex].SectionNumber;
  484. if (scn > 0) {
  485. sprintf(name, "$$R%04X", ++i);
  486. value = SymTable[ptr->TargetSymbolIndex].Value + ptr->offset;
  487. ptr->SymbolTableIndex = symbol(name, value, scn, IMAGE_SYM_CLASS_STATIC, 0);
  488. } else {
  489. ptr->SymbolTableIndex = ptr->TargetSymbolIndex;
  490. }
  491. }
  492. }
  493. }
  494. VOID
  495. AddReloc (
  496. IN PRELOC_LIST PtrList,
  497. IN DWORD VirtualAddress,
  498. IN DWORD SymbolTableIndex,
  499. IN WORD Type
  500. )
  501. /*++
  502. Routine Description:
  503. Adds to the relocation list.
  504. Arguments:
  505. Return Value:
  506. --*/
  507. {
  508. PRELOCS ptrReloc;
  509. // Allocate next member.
  510. ptrReloc = (PRELOCS) PvAlloc(sizeof(RELOCS));
  511. // Set the fields of the new member.
  512. ptrReloc->Reloc.VirtualAddress = VirtualAddress;
  513. ptrReloc->Reloc.SymbolTableIndex = SymbolTableIndex;
  514. ptrReloc->Reloc.Type = Type;
  515. ptrReloc->Next = NULL;
  516. // If first member in list, remember first member.
  517. if (!PtrList->First) {
  518. PtrList->First = ptrReloc;
  519. } else {
  520. // Not first member, so append to end of list.
  521. PtrList->Last->Next = ptrReloc;
  522. }
  523. // Increment number of members in list.
  524. PtrList->Count++;
  525. // Remember last member in list.
  526. PtrList->Last = ptrReloc;
  527. }
  528. VOID relocation(SHORT scn, DWORD vaddr, DWORD symndx, WORD type, DWORD offset)
  529. {
  530. BYTE *pb;
  531. SHORT i;
  532. PIMAGE_SYMBOL sym;
  533. i = scn - 1;
  534. sym = SymTable + symndx;
  535. if (!strcmp((const char *)sym->N.ShortName, ".file")) {
  536. flag = 1;
  537. return;
  538. }
  539. nreloc++;
  540. scnhdr[i].NumberOfRelocations++;
  541. AddReloc(&Relocations[i], vaddr, symndx, type);
  542. pb = RawData[i]+vaddr;
  543. switch (type) {
  544. case R_OFF8:
  545. case R_OFF16:
  546. case R_PCRBYTE:
  547. *pb += (BYTE) offset;
  548. break;
  549. case IMAGE_REL_I386_DIR16:
  550. case IMAGE_REL_I386_REL16:
  551. *(WORD UNALIGNED *) pb += (WORD) offset;
  552. break;
  553. case IMAGE_REL_I386_DIR32:
  554. case IMAGE_REL_I386_REL32:
  555. *(DWORD UNALIGNED *) pb += offset;
  556. break;
  557. case IMAGE_REL_I386_DIR32NB:
  558. break;
  559. default:
  560. fatal("Bad COFF relocation type");
  561. }
  562. }
  563. VOID fixupp(void)
  564. {
  565. int i;
  566. BYTE c[3];
  567. IMAGE_RELOCATION reloc[MAXREL];
  568. DWORD offset[MAXREL];
  569. BOOL fTargetSeg;
  570. i = 0;
  571. while (reclen > 1) {
  572. block(c, 1L);
  573. if (TRD_THRED(c) == (WORD)-1) {
  574. block(c + 1, 2L);
  575. if (i >= MAXREL) {
  576. fatal("Too many relocation entries");
  577. }
  578. if (dattype != LEDATA && dattype != LIDATA) {
  579. fatal("Bad relocatable reference");
  580. }
  581. reloc[i].VirtualAddress = datoffset + LCT_OFFSET(c);
  582. if (!FIX_F(c)) {
  583. method(FIX_FRAME(c));
  584. }
  585. if (!FIX_T(c)) {
  586. reloc[i].SymbolTableIndex = method(FIX_TARGT(c));
  587. fTargetSeg = (FIX_TARGT(c) == SEGMENT);
  588. } else {
  589. reloc[i].SymbolTableIndex = target[FIX_TARGT(c)];
  590. fTargetSeg = fTargetThreadSeg[FIX_TARGT(c)];
  591. }
  592. switch (LCT_LOC(c)) {
  593. case LOBYTE:
  594. if (LCT_M(c)) {
  595. reloc[i].Type = R_OFF8;
  596. } else {
  597. reloc[i].Type = R_PCRBYTE;
  598. }
  599. break;
  600. case HIBYTE:
  601. if (!LCT_M(c)) {
  602. fatal("Bad relocation type");
  603. }
  604. reloc[i].Type = R_OFF16;
  605. break;
  606. case OFFSET16:
  607. case OFFSET16LD:
  608. if (LCT_M(c)) {
  609. reloc[i].Type = IMAGE_REL_I386_DIR16;
  610. } else {
  611. reloc[i].Type = IMAGE_REL_I386_REL16;
  612. }
  613. break;
  614. case OFFSET32:
  615. case OFFSET32LD:
  616. if (LCT_M(c)) {
  617. reloc[i].Type = IMAGE_REL_I386_DIR32;
  618. } else {
  619. reloc[i].Type = IMAGE_REL_I386_REL32;
  620. }
  621. break;
  622. case OFFSET32NB:
  623. reloc[i].Type = IMAGE_REL_I386_DIR32NB;
  624. break;
  625. case POINTER48:
  626. // UNDONE: Only allow if $$SYMBOLS, $$TYPES, etc
  627. reloc[i].Type = IMAGE_REL_I386_DIR32;
  628. break;
  629. case BASE:
  630. case POINTER32:
  631. fatal("Segment reference in fixup record");
  632. default:
  633. fatal("Bad relocation type");
  634. }
  635. if (!FIX_P(c)) {
  636. offset[i] = use32 ? dword() : (long)word();
  637. if (fTargetSeg && (offset[i] != 0)) {
  638. // In Pass1, remember the targets of fixups to an offset
  639. // from some symbol. In Pass2, make a fixup with offset 0
  640. // from a synthetic symbol (instead of a non-zero offset
  641. // from the original target symbol).
  642. if (omfpass == PASS1) {
  643. saverlct(reloc[i].SymbolTableIndex, offset[i]);
  644. } else {
  645. DWORD SymbolTableIndex;
  646. SymbolTableIndex = rlctlookup(reloc[i].SymbolTableIndex, offset[i]);
  647. if (SymbolTableIndex != reloc[i].SymbolTableIndex) {
  648. reloc[i].SymbolTableIndex = SymbolTableIndex;
  649. offset[i] = 0;
  650. }
  651. }
  652. }
  653. } else {
  654. offset[i] = 0;
  655. }
  656. i++;
  657. } else if (!TRD_D(c)) {
  658. target[TRD_THRED(c)] = method(TRD_METHOD(c));
  659. fTargetThreadSeg[TRD_THRED(c)] = (TRD_METHOD(c) == SEGMENT);
  660. } else {
  661. method(TRD_METHOD(c));
  662. }
  663. }
  664. if (omfpass == PASS1) {
  665. return;
  666. }
  667. while (i-- > 0) {
  668. relocation(segindx[datscn].scn, reloc[i].VirtualAddress,
  669. reloc[i].SymbolTableIndex, reloc[i].Type, offset[i]);
  670. }
  671. }
  672. VOID pubdef(WORD sclass)
  673. {
  674. WORD grp;
  675. WORD type;
  676. SHORT scn;
  677. WORD frame;
  678. char *name;
  679. DWORD value;
  680. grp = (WORD) index();
  681. scn = index();
  682. if (!scn) {
  683. scn = IMAGE_SYM_ABSOLUTE;
  684. frame = word();
  685. } else {
  686. scn = segindx[scn].scn;
  687. }
  688. while (reclen > 1) {
  689. name = string(TRUE);
  690. value = use32 ? dword() : (long)word();
  691. type = (WORD) index();
  692. if (++exts >= MAXEXT) {
  693. fatal("Too many externals");
  694. }
  695. addsym(name, value, S_PUB, scn, exts, type);
  696. }
  697. sclass = sclass;
  698. }
  699. VOID scndata(SHORT scn, DWORD offset, BYTE *buffer, DWORD size)
  700. {
  701. SHORT i;
  702. i = scn - 1;
  703. if (offset+size > RawDataMaxSize[i]) {
  704. void *pv;
  705. // Section grew larger than BUFFERSIZE.
  706. pv = PvAllocZ(RawDataMaxSize[i] + BUFFERSIZE + size);
  707. memcpy(pv, RawData[i], RawDataMaxSize[i]);
  708. FreePv(RawData[i]);
  709. RawData[i] = (BYTE *) pv;
  710. RawDataMaxSize[i] += BUFFERSIZE + size;
  711. }
  712. memcpy(RawData[i]+offset, buffer, (size_t)size);
  713. }
  714. VOID ledata(void)
  715. {
  716. long size;
  717. BYTE buffer[MAXDAT];
  718. dattype = LEDATA;
  719. datscn = index();
  720. datoffset = use32 ? dword() : (DWORD)word();
  721. size = reclen - 1;
  722. if (size > MAXDAT) {
  723. fatal("Bad data record; too large");
  724. }
  725. memset(buffer, 0, (size_t)size);
  726. block(buffer, size);
  727. scndata(segindx[datscn].scn, datoffset, buffer, size);
  728. }
  729. // expand: expand an iterated data block
  730. long expand(long offset)
  731. {
  732. long repcnt;
  733. long blkcnt;
  734. long filptr;
  735. long i;
  736. SHORT sav_reclen;
  737. unsigned char size;
  738. BYTE buffer[MAXDAT / 2];
  739. repcnt = use32 ? dword() : (long)word();
  740. blkcnt = (long)word();
  741. if (blkcnt) {
  742. filptr = ftell(objfile);
  743. sav_reclen = reclen;
  744. while (repcnt-- > 0) {
  745. reclen = sav_reclen;
  746. for (i = 0; i < blkcnt; i++) {
  747. offset = expand(offset);
  748. }
  749. if (repcnt && fseek(objfile, filptr, 0)) {
  750. fatal("Cannot expand iterated data");
  751. }
  752. }
  753. } else {
  754. size = byte();
  755. // if (size > MAXDAT / 2) {
  756. // fatal("Bad iterated data record; too large");
  757. // }
  758. block(buffer, (long)size);
  759. while (repcnt-- > 0) {
  760. scndata(segindx[datscn].scn, offset, buffer, (long)size);
  761. offset += (long)size;
  762. }
  763. }
  764. return offset;
  765. }
  766. VOID lidata(void)
  767. {
  768. dattype = LIDATA;
  769. datscn = index();
  770. datoffset = use32 ? dword() : (DWORD)word();
  771. while (reclen > 1) {
  772. datoffset = expand(datoffset);
  773. }
  774. }
  775. VOID comdef(WORD sclass)
  776. {
  777. char *name;
  778. DWORD value;
  779. WORD type;
  780. BYTE segtype;
  781. while (reclen > 1) {
  782. name = string(TRUE);
  783. type = (WORD)index();
  784. segtype = byte();
  785. value = length();
  786. if (segtype == COMM_FAR) {
  787. value *= length();
  788. }
  789. if (++exts >= MAXEXT) {
  790. fatal("Too many externals");
  791. }
  792. extdefs[++defs] = exts;
  793. external[exts] = symbol(name, value, IMAGE_SYM_UNDEFINED, sclass, 0);
  794. }
  795. }
  796. VOID lpubdef (WORD sclass)
  797. {
  798. WORD grp, type;
  799. SHORT scn;
  800. WORD frame;
  801. char *name;
  802. DWORD value;
  803. grp = (WORD)index();
  804. scn = index();
  805. if (!scn) {
  806. scn = IMAGE_SYM_ABSOLUTE;
  807. frame = word();
  808. } else {
  809. scn = segindx[scn].scn;
  810. }
  811. while (reclen > 1) {
  812. name = string(FALSE);
  813. value = use32 ? dword() : (long)word();
  814. type = (WORD)index();
  815. // Update corresponding LEXTDEF symbol table entry's value
  816. // field with the offset field from this LPUBDEF. FIXUPP
  817. // will then cause relocation() to do self-relative fixups
  818. // for static functions.
  819. updatesym(name, value, S_LPUB, scn, type);
  820. }
  821. sclass = sclass;
  822. }
  823. VOID coment(const char *szOmf)
  824. {
  825. BYTE flags;
  826. BYTE SymbolClass;
  827. WORD weakExt, defaultExt;
  828. struct sym *sptr;
  829. WORD count;
  830. BYTE *commp;
  831. flags = byte();
  832. SymbolClass = byte();
  833. switch (SymbolClass) {
  834. case COM_PRECOMP:
  835. fPrecomp = TRUE;
  836. break;
  837. case COM_EXESTR:
  838. if (ncomments >= MAXCOM) {
  839. Warning(szOmf, TOOMANYEXESTR, MAXCOM);
  840. } else {
  841. long tmp_reclen;
  842. /* reclen includes chksum, which is used as NULL */
  843. commp = (BYTE *)PvAlloc(reclen);
  844. tmp_reclen = (long)reclen;
  845. block(commp, tmp_reclen - 1); // side effects on reclen
  846. commp[tmp_reclen - 1] = '\0';
  847. comments[ncomments++] = (char *)commp;
  848. cmntsize += tmp_reclen; // want to include null in size
  849. }
  850. break;
  851. case COM_WKEXT:
  852. case COM_LZEXT:
  853. while (reclen > 1) {
  854. weakExt = (WORD)extdefs[index()];
  855. defaultExt = (WORD)extdefs[index()];
  856. for (count = 0; count < NBUCKETS; count++) {
  857. sptr = hashhead[count];
  858. while (sptr) {
  859. if (sptr->ext == weakExt) {
  860. if (!sptr->scn) {
  861. sptr->type = (SymbolClass == COM_WKEXT ? (WORD)S_WKEXT : (WORD)S_LZEXT);
  862. sptr->weakDefaultExt = defaultExt;
  863. }
  864. break;
  865. }
  866. sptr = sptr->next;
  867. }
  868. }
  869. }
  870. break;
  871. }
  872. }
  873. WORD section(const char *name, DWORD paddr, DWORD vaddr, DWORD size, DWORD flags)
  874. {
  875. WORD i;
  876. size_t len;
  877. DWORD align;
  878. i = nscns++;
  879. if (nscns > MAXSCN) {
  880. fatal("Too many COFF sections");
  881. }
  882. RawData[i] = (BYTE *) PvAllocZ(BUFFERSIZE);
  883. RawDataMaxSize[i] = BUFFERSIZE;
  884. len = strlen(name);
  885. if (len <= IMAGE_SIZEOF_SHORT_NAME) {
  886. strncpy((char *)scnhdr[i].Name, name, IMAGE_SIZEOF_SHORT_NAME);
  887. } else {
  888. sprintf((char *)scnhdr[i].Name, "/%lu", AddLongName(name));
  889. }
  890. scnhdr[i].Misc.PhysicalAddress = 0;
  891. scnhdr[i].VirtualAddress = vaddr;
  892. scnhdr[i].SizeOfRawData = size;
  893. scnhdr[i].NumberOfRelocations = 0;
  894. scnhdr[i].NumberOfLinenumbers = 0;
  895. switch (paddr) {
  896. case 1: align = IMAGE_SCN_ALIGN_1BYTES; break;
  897. case 2: align = IMAGE_SCN_ALIGN_2BYTES; break;
  898. case 4: align = IMAGE_SCN_ALIGN_4BYTES; break;
  899. case 8: align = IMAGE_SCN_ALIGN_8BYTES; break;
  900. case 16: align = IMAGE_SCN_ALIGN_16BYTES; break;
  901. default: align = IMAGE_SCN_ALIGN_16BYTES;
  902. }
  903. scnhdr[i].Characteristics = flags | align;
  904. if ((scnhdr[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0) {
  905. scnsize += size;
  906. }
  907. return(nscns);
  908. }
  909. VOID segdef(void)
  910. {
  911. unsigned char acbp;
  912. unsigned short frame;
  913. unsigned short offset;
  914. SHORT scn;
  915. long size, flags = 0;
  916. char *szName;
  917. char *szClass;
  918. SHORT nam, cls;
  919. IMAGE_AUX_SYMBOL auxent;
  920. int code_seg = 0;
  921. int data_seg = 0;
  922. int bss_seg = 0;
  923. if (++segs >= MAXSCN) {
  924. fatal("Too many SEGDEF/COMDAT records");
  925. }
  926. acbp = byte();
  927. if (!ACBP_A(acbp)) {
  928. // UNDONE: Absolute segments should either be fatal or ignored
  929. frame = word();
  930. offset = byte();
  931. }
  932. size = use32 ? dword() : (long)word();
  933. nam = index();
  934. szName = lname[nam];
  935. segindx[++cursegindx].namindx = nam;
  936. cls = index();
  937. szClass = lname[cls];
  938. index(); // Skip overlay LNAME index
  939. if (ACBP_B(acbp)) {
  940. fatal("Bad segment definition");
  941. }
  942. // Handle $$SYMBOLS and $$TYPES segments
  943. if (!strcmp(szName, SYMBOLS_SEGNAME) && !strcmp(szClass, SYMBOLS_CLASS)) {
  944. szName = ".debug$S";
  945. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_1BYTES;
  946. } else if (!strcmp(szName, TYPES_SEGNAME) && !strcmp(szClass, TYPES_CLASS)) {
  947. if (fPrecomp) {
  948. szName = ".debug$P";
  949. } else {
  950. szName = ".debug$T";
  951. }
  952. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_1BYTES;
  953. } else if (strcmp(szName, ".debug$F") == 0) {
  954. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_1BYTES;
  955. } else {
  956. size_t cchClass;
  957. char *szClassEnd;
  958. char *szOmfName;
  959. size_t cchOmfName;
  960. char *szCoffName;
  961. size_t cchCoffName;
  962. cchClass = strlen(szClass);
  963. szClassEnd = szClass + cchClass;
  964. if ((cchClass >= 4) && (strcmp(szClassEnd - 4, "CODE") == 0)) {
  965. szOmfName = "_TEXT";
  966. cchOmfName = 5;
  967. szCoffName = ".text";
  968. cchCoffName = 5;
  969. flags = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
  970. code_seg = cursegindx;
  971. } else if ((cchClass >= 4) && (strcmp(szClassEnd - 4, "DATA") == 0)) {
  972. szOmfName = "_DATA";
  973. cchOmfName = 5;
  974. szCoffName = ".data";
  975. cchCoffName = 5;
  976. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
  977. data_seg = cursegindx;
  978. } else if ((cchClass >= 5) && (strcmp(szClassEnd - 5, "CONST") == 0)) {
  979. szOmfName = "CONST";
  980. cchOmfName = 5;
  981. szCoffName = ".rdata";
  982. cchCoffName = 6;
  983. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
  984. data_seg = cursegindx;
  985. } else if ((cchClass >= 3) && (strcmp(szClassEnd - 3, "BSS") == 0)) {
  986. szOmfName = "_BSS";
  987. cchOmfName = 4;
  988. szCoffName = ".bss";
  989. cchCoffName = 4;
  990. flags = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
  991. bss_seg = cursegindx;
  992. }
  993. else {
  994. szOmfName = NULL;
  995. flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
  996. }
  997. if (szOmfName != NULL) {
  998. // Check for mapping from well known OMF name to COFF name
  999. if (memcmp(szName, szOmfName, cchOmfName) == 0) {
  1000. if (szName[cchOmfName] == '\0') {
  1001. szName = szCoffName;
  1002. } else if (szName[cchOmfName] == '$') {
  1003. char *szNameT;
  1004. szNameT = (char *)PvAlloc(cchCoffName + strlen(szName+cchOmfName) + 1);
  1005. strcpy(szNameT, szCoffName);
  1006. strcat(szNameT, szName+cchOmfName);
  1007. // UNDONE: This is a memory leak (albeit a small one)
  1008. szName = szNameT;
  1009. }
  1010. }
  1011. }
  1012. if (!ACBP_P(acbp)) {
  1013. // This is a 16 bit segment
  1014. flags |= 0x00020000; // REVIEW -- need place for symbolic def
  1015. }
  1016. }
  1017. segindx[cursegindx].flags = flags;
  1018. segindx[cursegindx].align = SEG_ALIGN[ACBP_A(acbp)];
  1019. segindx[cursegindx].scn = scn = section(szName, segindx[cursegindx].align, 0, size, flags);
  1020. if (code_seg) {
  1021. text_scn = scn; // hold text section # for L*DEF recs
  1022. }
  1023. if (data_seg) {
  1024. data_scn = scn;
  1025. }
  1026. if (bss_seg) {
  1027. bss_scn = scn;
  1028. }
  1029. segment[segs] = symbol(szName, 0, scn, IMAGE_SYM_CLASS_STATIC, 1);
  1030. // Create aux entry
  1031. memset(&auxent, 0, sizeof(IMAGE_AUX_SYMBOL));
  1032. auxent.Section.Length = size;
  1033. scnauxidx[scn - 1] = aux(&auxent);
  1034. }
  1035. VOID linnum(void)
  1036. {
  1037. WORD grpindex;
  1038. SHORT segindex;
  1039. grpindex = (WORD) index();
  1040. segindex = index();
  1041. // store lineno data in core until we process entire set
  1042. while (reclen > 1) {
  1043. WORD lineno;
  1044. DWORD offset;
  1045. lineno = word();
  1046. offset = use32 ? dword() : (long) word();
  1047. lines[line_indx].offset = offset;
  1048. lines[line_indx].number = lineno;
  1049. line_indx++;
  1050. if ((line_indx & ALLOCMSK) == 0) {
  1051. lines = (struct lines *) PvRealloc(lines, sizeof(*lines)*(line_indx+ALLOCSZ));
  1052. }
  1053. }
  1054. }
  1055. VOID grpdef(void)
  1056. {
  1057. char *name;
  1058. SHORT scn;
  1059. BYTE x;
  1060. name = lname[index()];
  1061. scn = IMAGE_SYM_ABSOLUTE;
  1062. while (reclen > 1) {
  1063. x = byte();
  1064. scn = index();
  1065. scn = segindx[scn].scn;
  1066. }
  1067. if (++grps >= MAXGRP) {
  1068. fatal("Too many groups");
  1069. }
  1070. group[grps] = symbol(name, 0, scn, IMAGE_SYM_CLASS_STATIC, 0);
  1071. }
  1072. VOID theadr(void)
  1073. {
  1074. static char *first_name = NULL;
  1075. char *f_name, *name;
  1076. int len;
  1077. WORD csymAux;
  1078. IMAGE_AUX_SYMBOL auxent;
  1079. mods++;
  1080. f_name = string(FALSE);
  1081. if (!first_name) {
  1082. first_name = f_name;
  1083. strcpy(szCvtomfSourceName, first_name);
  1084. }
  1085. // .h files that define variables will cause THEADR records with
  1086. // "-g" and MSC. A subsequent THEADR re-defines the original .c file.
  1087. // This is a problem: currently pcc/sdb and MSC/codeview or x.out sdb
  1088. // are unable to deal with code or variables in a header file. We will
  1089. // print a warning and aVOID spitting out extra .file symbols.
  1090. //
  1091. // a second case of multiple THEADRs comes from /lib/ldr and multiple
  1092. // .o files. In this case, the symbolic debug data is currently
  1093. // not coalesed properly so without some trickery we can't translated
  1094. // it properly. If we may concessions for an incorrect ldr then when
  1095. // it is fixed, we will be broken. Leave undone for now . . .
  1096. //
  1097. // multiple THEADRs will also be generated by #line directives that
  1098. // supply filenames. Good case of this is yacc output. Note: this
  1099. // also screws up line number entires!
  1100. if (mods > 1) {
  1101. return;
  1102. }
  1103. csymAux = (WORD) strlen(f_name);
  1104. if (csymAux % sizeof(IMAGE_AUX_SYMBOL)) {
  1105. csymAux = (WORD) ((csymAux / sizeof(IMAGE_AUX_SYMBOL)) + 1);
  1106. } else {
  1107. csymAux /= sizeof(IMAGE_AUX_SYMBOL);
  1108. }
  1109. symbol(".file", 0, IMAGE_SYM_DEBUG, IMAGE_SYM_CLASS_FILE, csymAux);
  1110. // .file aux entry
  1111. //
  1112. // filenames are not like symbol names: up to 18 chars right in the
  1113. // aux record. filenames are never placed in the strings table
  1114. name = f_name;
  1115. while (*name) {
  1116. memset(&auxent, 0, sizeof(IMAGE_AUX_SYMBOL));
  1117. len = 0;
  1118. while (*name && len < sizeof(IMAGE_AUX_SYMBOL)) {
  1119. auxent.File.Name[len++] = *name++;
  1120. }
  1121. aux(&auxent);
  1122. }
  1123. }
  1124. VOID cmntdata(SHORT scn, DWORD offset, char **strings, SHORT nstrings)
  1125. {
  1126. SHORT i;
  1127. i = scn - 1;
  1128. if (offset+nstrings > RawDataMaxSize[i]) {
  1129. BYTE *pv;
  1130. // Section grew larger than BUFFERSIZE.
  1131. pv = (BYTE *)PvAllocZ(RawDataMaxSize[i] + BUFFERSIZE + nstrings);
  1132. memcpy(pv, RawData[i], RawDataMaxSize[i]);
  1133. FreePv(RawData[i]);
  1134. RawData[i] = (BYTE *) pv;
  1135. RawDataMaxSize[i] += BUFFERSIZE + nstrings;
  1136. }
  1137. memcpy(RawData[i]+offset, *strings, (size_t)nstrings);
  1138. }
  1139. VOID modend(void)
  1140. {
  1141. if (ncomments) {
  1142. SHORT scn;
  1143. scn = section(".comment", 1L, 0, cmntsize, (long)(IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_LNK_REMOVE));
  1144. cmntdata(scn, 0, comments, ncomments);
  1145. for (scn = 0; scn < ncomments; scn++) {
  1146. FreePv(comments[scn]);
  1147. comments[scn] = NULL;
  1148. }
  1149. }
  1150. }
  1151. VOID lnames(DWORD flag)
  1152. {
  1153. while (reclen > 1) {
  1154. if (++lnms >= MAXNAM) {
  1155. fatal("Too many names in LNAMES record");
  1156. }
  1157. lname[lnms] = string(FALSE);
  1158. llname[lnms] = flag;
  1159. }
  1160. }
  1161. VOID lheadr(void)
  1162. {
  1163. mods++;
  1164. }
  1165. VOID comdatscndata(SHORT scn, DWORD offset, BYTE *buffer, DWORD size)
  1166. {
  1167. scnhdr[scn-1].SizeOfRawData += size;
  1168. scnsize += size;
  1169. scndata(scn, offset, buffer, size);
  1170. }
  1171. VOID comdat(void)
  1172. {
  1173. WORD grp, type, SymbolClass;
  1174. SHORT scn, nam;
  1175. long size;
  1176. DWORD align, symIdx;
  1177. char *name;
  1178. BYTE flags;
  1179. BYTE attr;
  1180. BYTE algn;
  1181. BYTE checksum;
  1182. IMAGE_AUX_SYMBOL auxent;
  1183. BYTE buffer[MAXDAT];
  1184. static SHORT LastComdatScn;
  1185. flags = byte();
  1186. attr = byte();
  1187. algn = byte();
  1188. dattype = LEDATA;
  1189. datoffset = use32 ? dword() : (DWORD)word();
  1190. type = (WORD)index();
  1191. grp = (WORD)index();
  1192. scn = index();
  1193. if (!scn) {
  1194. fatal("Section not defined in COMDAT");
  1195. }
  1196. nam = index();
  1197. name = lname[nam];
  1198. size = reclen - 1;
  1199. if (size > MAXDAT) {
  1200. fatal("Bad data record; too large");
  1201. }
  1202. memset(buffer, 0, (size_t)size);
  1203. block(buffer, size);
  1204. // Check if continuation of last COMDAT.
  1205. if (!(flags & 1)) {
  1206. if (++segs >= MAXSCN) {
  1207. fatal("Too many SEGDEF/COMDAT records");
  1208. }
  1209. } else {
  1210. // continuation of COMDAT.
  1211. datscn = LastComdatScn;
  1212. comdatscndata(segindx[LastComdatScn].scn, datoffset, buffer, size);
  1213. return;
  1214. }
  1215. datscn = ++cursegindx;
  1216. segindx[datscn] = segindx[scn];
  1217. align = algn ? SEG_ALIGN[algn] : segindx[cursegindx].align;
  1218. segindx[datscn].scn = section(lname[segindx[scn].namindx], align, 0, size, segindx[scn].flags | IMAGE_SCN_LNK_COMDAT);
  1219. LastComdatScn = datscn;
  1220. scndata(segindx[datscn].scn, datoffset, buffer, size);
  1221. // Check for iterated data (not supported yet).
  1222. if (flags & 2) {
  1223. fatal("COMDAT uses iterated data");
  1224. }
  1225. SymbolClass = (flags & 4) ? (WORD)IMAGE_SYM_CLASS_STATIC : (WORD)IMAGE_SYM_CLASS_EXTERNAL;
  1226. // Create section symbol.
  1227. segment[segs] = symbol(lname[segindx[scn].namindx], 0, segindx[datscn].scn, IMAGE_SYM_CLASS_STATIC, 1);
  1228. // Create section aux entry
  1229. memset(&auxent, 0, sizeof(IMAGE_AUX_SYMBOL));
  1230. auxent.Section.Length = size;
  1231. if (fread(&checksum, 1, sizeof(BYTE), objfile) != sizeof(BYTE)) {
  1232. fatal("Bad read of object file");
  1233. }
  1234. if (fseek(objfile, -(long)sizeof(BYTE), SEEK_CUR)) {
  1235. fatal("Bad seek on object file");
  1236. }
  1237. auxent.Section.CheckSum = (DWORD)checksum;
  1238. switch (attr) {
  1239. case 0 : attr = IMAGE_COMDAT_SELECT_NODUPLICATES; break;
  1240. case 0x10 : attr = IMAGE_COMDAT_SELECT_ANY; break;
  1241. case 0x20 : attr = IMAGE_COMDAT_SELECT_SAME_SIZE; break;
  1242. case 0x30 : attr = IMAGE_COMDAT_SELECT_EXACT_MATCH; break;
  1243. default : attr = 0;
  1244. }
  1245. auxent.Section.Selection = attr;
  1246. scnauxidx[segindx[datscn].scn - 1] = aux(&auxent);
  1247. // Create communal name symbol
  1248. symIdx = symbol(name, 0, segindx[datscn].scn, SymbolClass, 0);
  1249. if (llname[nam] == -1) {
  1250. llname[nam] = symIdx;
  1251. }
  1252. }
  1253. VOID nbkpat(void)
  1254. {
  1255. char *name;
  1256. BYTE loctyp;
  1257. loctyp = byte();
  1258. name = lname[index()];
  1259. while (reclen > 1) {
  1260. DWORD offset;
  1261. DWORD value;
  1262. BYTE *pb;
  1263. offset = use32 ? dword() : (DWORD) word();
  1264. value = use32 ? dword() : (DWORD) word();
  1265. pb = RawData[segindx[datscn].scn-1] + offset;
  1266. switch (loctyp) {
  1267. case 0:
  1268. *pb += (BYTE) value;
  1269. break;
  1270. case 1:
  1271. *(WORD UNALIGNED *) pb += (WORD) value;
  1272. break;
  1273. case 2:
  1274. *(DWORD UNALIGNED *) pb += value;
  1275. break;
  1276. default:
  1277. fatal("Ilegal LocTyp in NBKPAT record");
  1278. }
  1279. }
  1280. }
  1281. VOID bakpat(void)
  1282. {
  1283. SHORT scn;
  1284. BYTE loctyp;
  1285. scn = index();
  1286. loctyp = byte();
  1287. while (reclen > 1) {
  1288. DWORD offset;
  1289. DWORD value;
  1290. BYTE *pb;
  1291. offset = use32 ? dword() : (DWORD) word();
  1292. value = use32 ? dword() : (DWORD) word();
  1293. pb = RawData[segindx[scn].scn-1] + offset;
  1294. switch (loctyp) {
  1295. case 0:
  1296. *pb += (BYTE) value;
  1297. break;
  1298. case 1:
  1299. *(WORD UNALIGNED *) pb += (WORD) value;
  1300. break;
  1301. case 2:
  1302. *(DWORD UNALIGNED *) pb += value;
  1303. break;
  1304. default:
  1305. fatal("Ilegal LocTyp in BAKPAT record");
  1306. }
  1307. }
  1308. }
  1309. VOID linsym(void)
  1310. {
  1311. BYTE flag;
  1312. DWORD offset;
  1313. WORD nameindex, lineno;
  1314. flag = byte();
  1315. nameindex = index();
  1316. // store lineno data in core until we process entire set
  1317. while (reclen > 1) {
  1318. lineno = word();
  1319. offset = use32 ? dword() : (long)word();
  1320. }
  1321. return;
  1322. }
  1323. // recskip: skip an OMF record leave checksum byte in stream
  1324. VOID recskip(void)
  1325. {
  1326. if (reclen > 1) {
  1327. if (fseek(objfile, (long)(reclen - 1), SEEK_CUR)) {
  1328. fatal("Bad seek on object file");
  1329. }
  1330. reclen = 1;
  1331. }
  1332. }
  1333. // Define the extra symbol table records needed for a function with line
  1334. // numbers. (Assume the initial symbol has already been emitted, with an
  1335. // aux count of 1.)
  1336. VOID
  1337. DefineLineNumSymbols(DWORD cline, WORD isec, DWORD /* offsetLine0 */,
  1338. WORD numberLine0, DWORD cbFunc, WORD numberLineLast)
  1339. {
  1340. IMAGE_AUX_SYMBOL auxsym;
  1341. IMAGE_SYMBOL sym;
  1342. SymTable[nsyms - 1].Type = IMAGE_SYM_TYPE_NULL |
  1343. (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT);
  1344. memset(&auxsym, 0, sizeof(IMAGE_AUX_SYMBOL));
  1345. auxsym.Sym.TagIndex = nsyms + 1;
  1346. auxsym.Sym.Misc.LnSz.Linenumber = numberLine0;
  1347. auxsym.Sym.Misc.TotalSize = cbFunc + 1;
  1348. auxsym.Sym.FcnAry.Function.PointerToLinenumber = 0;
  1349. auxsym.Sym.FcnAry.Function.PointerToNextFunction = 0;
  1350. aux(&auxsym);
  1351. memset(&sym, 0, sizeof(sym));
  1352. memcpy(&sym.N.ShortName[0], ".bf\0\0\0\0\0", IMAGE_SIZEOF_SHORT_NAME);
  1353. sym.SectionNumber = isec;
  1354. sym.Type = IMAGE_SYM_TYPE_NULL;
  1355. sym.StorageClass = IMAGE_SYM_CLASS_FUNCTION;
  1356. sym.NumberOfAuxSymbols = 1;
  1357. aux((PIMAGE_AUX_SYMBOL)&sym);
  1358. memset(&auxsym, 0, sizeof(auxsym));
  1359. auxsym.Sym.Misc.LnSz.Linenumber = numberLine0;
  1360. aux(&auxsym);
  1361. memset(&sym, 0, sizeof(sym));
  1362. memcpy(&sym.N.ShortName[0], ".lf\0\0\0\0\0", IMAGE_SIZEOF_SHORT_NAME);
  1363. sym.Value = cline;
  1364. sym.SectionNumber = isec;
  1365. sym.Type = IMAGE_SYM_TYPE_NULL;
  1366. sym.StorageClass = IMAGE_SYM_CLASS_FUNCTION;
  1367. aux((PIMAGE_AUX_SYMBOL)&sym);
  1368. memset(&sym, 0, sizeof(sym));
  1369. memcpy(&sym.N.ShortName[0], ".ef\0\0\0\0\0", IMAGE_SIZEOF_SHORT_NAME);
  1370. sym.SectionNumber = isec;
  1371. sym.Type = IMAGE_SYM_TYPE_NULL;
  1372. sym.StorageClass = IMAGE_SYM_CLASS_FUNCTION;
  1373. sym.NumberOfAuxSymbols = 1;
  1374. aux((PIMAGE_AUX_SYMBOL)&sym);
  1375. memset(&auxsym, 0, sizeof(auxsym));
  1376. auxsym.Sym.Misc.LnSz.Linenumber = numberLineLast;
  1377. aux(&auxsym);
  1378. }
  1379. // process all remaining EXTDEF, PUBDEF, and COMDEFS not in $$SYMBOLS
  1380. // output all remaining symbols in hash list
  1381. // note: type should be IMAGE_SYM_TYPE_NULL for any EXTDEF or LEXTDEF only symbols
  1382. // free dynamic storage
  1383. VOID flush_syms(void)
  1384. {
  1385. WORD csymAux;
  1386. WORD SymbolClass;
  1387. WORD count;
  1388. struct sym *psym;
  1389. IMAGE_AUX_SYMBOL auxent;
  1390. csymAux = 0;
  1391. isymDefAux = 0;
  1392. // Flush all but weak externs.
  1393. for (count = 0; count < NBUCKETS; count++) {
  1394. for (psym = hashhead[count]; psym != NULL; psym = psym->next) {
  1395. if ((external[psym->ext] == NULL) &&
  1396. (psym->type != S_WKEXT) &&
  1397. (psym->type != S_LZEXT)) {
  1398. // Don't output type data if EXTDEF only
  1399. switch(psym->type) {
  1400. case S_LEXT:
  1401. case S_LPUB:
  1402. SymbolClass = IMAGE_SYM_CLASS_STATIC;
  1403. break;
  1404. case S_EXT:
  1405. csymAux = 0;
  1406. SymbolClass = IMAGE_SYM_CLASS_EXTERNAL;
  1407. break;
  1408. default:
  1409. SymbolClass = IMAGE_SYM_CLASS_EXTERNAL;
  1410. break;
  1411. }
  1412. if ((line_indx != 0) &&
  1413. (isymDefAux == 0) &&
  1414. (psym->scn == text_scn))
  1415. {
  1416. csymAux = 1;
  1417. }
  1418. external[psym->ext] = symbol(psym->name,
  1419. psym->offset,
  1420. psym->scn,
  1421. SymbolClass,
  1422. csymAux);
  1423. if (csymAux) {
  1424. WORD iline;
  1425. isymDefAux = nsyms;
  1426. DefineLineNumSymbols(line_indx,
  1427. text_scn,
  1428. lines[0].offset,
  1429. lines[0].number,
  1430. lines[line_indx - 1].offset - lines[0].offset,
  1431. lines[line_indx - 1].number);
  1432. for (iline = 1; iline < line_indx; iline++) {
  1433. lines[iline].number -= lines[0].number;
  1434. }
  1435. lines[0].number = 0;
  1436. lines[0].offset = isymDefAux - 1;
  1437. csymAux = 0; // Reset
  1438. }
  1439. }
  1440. }
  1441. }
  1442. // Flush weak externs.
  1443. memset(&auxent, 0, sizeof(IMAGE_AUX_SYMBOL));
  1444. for (count = 0; count < NBUCKETS; count++) {
  1445. struct sym *psymNext;
  1446. for (psym = hashhead[count]; psym != NULL; psym = psymNext) {
  1447. if (external[psym->ext] == NULL) {
  1448. external[psym->ext] = symbol(psym->name,
  1449. psym->offset,
  1450. psym->scn,
  1451. IMAGE_SYM_CLASS_WEAK_EXTERNAL,
  1452. 1);
  1453. auxent.Sym.TagIndex = external[psym->weakDefaultExt];
  1454. auxent.Sym.Misc.TotalSize = (psym->type == S_WKEXT) ?
  1455. IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY :
  1456. IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
  1457. aux(&auxent);
  1458. }
  1459. psymNext = psym->next;
  1460. FreePv(psym);
  1461. }
  1462. }
  1463. }
  1464. VOID
  1465. AddLinenum (
  1466. IN PLINENUM_LIST PtrList,
  1467. IN DWORD VirtualAddress,
  1468. IN WORD Linenumber
  1469. )
  1470. /*++
  1471. Routine Description:
  1472. Adds to the linenumber list.
  1473. Arguments:
  1474. Return Value:
  1475. --*/
  1476. {
  1477. PLINENUMS ptrLinenum;
  1478. // Allocate next member.
  1479. ptrLinenum = (LINENUMS *) PvAlloc(sizeof(LINENUMS));
  1480. // Set the fields of the new member.
  1481. ptrLinenum->Linenum.Type.VirtualAddress = VirtualAddress;
  1482. ptrLinenum->Linenum.Linenumber = Linenumber;
  1483. ptrLinenum->Next = NULL;
  1484. // If first member in list, remember first member.
  1485. if (PtrList->First == NULL) {
  1486. PtrList->First = ptrLinenum;
  1487. } else {
  1488. // Not first member, so append to end of list.
  1489. PtrList->Last->Next = ptrLinenum;
  1490. }
  1491. // Increment number of members in list.
  1492. PtrList->Count++;
  1493. // Remember last member in list.
  1494. PtrList->Last = ptrLinenum;
  1495. }
  1496. VOID line(SHORT scn, DWORD paddr, WORD lnno)
  1497. {
  1498. SHORT i;
  1499. i = scn - 1;
  1500. nlnno++;
  1501. scnhdr[i].NumberOfLinenumbers++;
  1502. AddLinenum(&Linenumbers[i], paddr, lnno);
  1503. }
  1504. void process_linenums(void)
  1505. {
  1506. const struct lines *lptr = lines;
  1507. const struct lines *elptr = &lines[line_indx];
  1508. while (lptr < elptr) {
  1509. line(text_scn, lptr->offset, lptr->number);
  1510. lptr++;
  1511. }
  1512. }
  1513. VOID proc_fixups(void)
  1514. {
  1515. struct sfix *f = fixlist;
  1516. struct sfix *p = fixlist;
  1517. while (f) {
  1518. // prepare the environment for fixupp()
  1519. fseek(objfile, f->offset, 0);
  1520. rectyp = (SHORT)getc(objfile);
  1521. if (RECTYP(rectyp) != FIXUPP && RECTYP(rectyp) != FIXUP2) {
  1522. fatal("proc_fixups: not a fixup record");
  1523. }
  1524. use32 = (SHORT) USE32(rectyp);
  1525. reclen = (SHORT) word();
  1526. datscn = f->datscn;
  1527. dattype = f->dattype;
  1528. datoffset = f->datoffset;
  1529. fixupp();
  1530. p = f;
  1531. f = f->next;
  1532. FreePv(p);
  1533. }
  1534. fixlist = fixlast = NULL;
  1535. }
  1536. // omf: scan through omf file, processing each record as appropriate
  1537. //
  1538. // most symbols are loaded into a hash table and not output into COFF
  1539. // symbols until the entire file has been scanned. fixup record processing
  1540. // is deferred until after all symbols have been output. Note that some
  1541. // fixup processing must happen when DebugType==Coff in order to support
  1542. // $$SYMBOLS fixup processing for process_sym needs.
  1543. VOID omf(const char *szOmf, int pass)
  1544. {
  1545. BOOL fReadModend;
  1546. mods = lnms = segs = grps = exts = defs = 0;
  1547. rectyp = 0;
  1548. use32 = 0;
  1549. reclen = 0;
  1550. fPrecomp = 0;
  1551. dattype = 0;
  1552. datscn = 0;
  1553. datoffset = 0;
  1554. szCvtomfSourceName[0] = '\0'; // default to blank
  1555. omfpass = pass;
  1556. fReadModend = FALSE;
  1557. // initialze core storage for external/public symbols
  1558. syminit();
  1559. // init core storage for line number entires and $$SYMBOLS fixups
  1560. lines = (struct lines *) PvAlloc(sizeof(struct lines) * ALLOCSZ);
  1561. line_indx = 0;
  1562. // zero out exts[] table for multiple object files
  1563. memset(external, 0, MAXEXT * sizeof(DWORD));
  1564. memset(extdefs, 0, MAXEXT * sizeof(DWORD));
  1565. text_scn = data_scn = bss_scn = 0;
  1566. cursegindx = ncomments = 0;
  1567. cmntsize = 0;
  1568. // process OMF records
  1569. rewind(objfile);
  1570. while ((rectyp = (SHORT) getc(objfile)) != EOF) {
  1571. use32 = (SHORT) USE32(rectyp);
  1572. reclen = word();
  1573. switch (RECTYP(rectyp)) {
  1574. case EXTDEF:
  1575. extdef(FALSE, IMAGE_SYM_CLASS_EXTERNAL);
  1576. break;
  1577. case CEXTDEF:
  1578. extdef(TRUE, IMAGE_SYM_CLASS_EXTERNAL);
  1579. break;
  1580. case FIXUPP:
  1581. case FIXUP2:
  1582. // deferr until all symbols are read
  1583. save_fixupp(ftell(objfile) - 3);
  1584. fixupp();
  1585. break;
  1586. case PUBDEF:
  1587. pubdef(IMAGE_SYM_CLASS_EXTERNAL);
  1588. break;
  1589. case LEDATA:
  1590. ledata();
  1591. break;
  1592. case LIDATA:
  1593. lidata();
  1594. break;
  1595. case COMDEF:
  1596. comdef(IMAGE_SYM_CLASS_EXTERNAL);
  1597. break;
  1598. case LEXTDEF:
  1599. extdef(FALSE, IMAGE_SYM_CLASS_STATIC);
  1600. break;
  1601. case LPUBDEF:
  1602. lpubdef(IMAGE_SYM_CLASS_STATIC);
  1603. break;
  1604. case COMENT:
  1605. coment(szOmf);
  1606. break;
  1607. case SEGDEF:
  1608. segdef();
  1609. break;
  1610. case LINNUM:
  1611. linnum();
  1612. break;
  1613. case GRPDEF:
  1614. grpdef();
  1615. break;
  1616. case THEADR:
  1617. theadr();
  1618. break;
  1619. case MODEND:
  1620. fReadModend = TRUE;
  1621. modend();
  1622. break;
  1623. case LNAMES:
  1624. lnames(0);
  1625. break;
  1626. case LLNAMES:
  1627. lnames((DWORD)-1);
  1628. break;
  1629. case LCOMDEF:
  1630. comdef(IMAGE_SYM_CLASS_STATIC);
  1631. break;
  1632. case LHEADR:
  1633. lheadr();
  1634. break;
  1635. case COMDAT:
  1636. comdat();
  1637. break;
  1638. case NBKPAT:
  1639. nbkpat();
  1640. break;
  1641. case BAKPAT:
  1642. bakpat();
  1643. break;
  1644. case LINSYM:
  1645. linsym();
  1646. break;
  1647. default:
  1648. fatal("Unknown or bad record type %x", RECTYP(rectyp));
  1649. break;
  1650. }
  1651. // skip over remaining portion of record
  1652. recskip();
  1653. chksum = byte();
  1654. if (fReadModend) {
  1655. // Stop after MODEND record
  1656. break;
  1657. }
  1658. }
  1659. if (!fReadModend) {
  1660. Fatal(szOmf, NOMODEND);
  1661. }
  1662. createrlctsyms();
  1663. flush_syms();
  1664. process_linenums();
  1665. omfpass = PASS2;
  1666. proc_fixups();
  1667. }
  1668. VOID coff(void)
  1669. {
  1670. IMAGE_FILE_HEADER filehdr;
  1671. DWORD scnptr, relptr, lnnoptr, li;
  1672. WORD i, j;
  1673. flag = 0;
  1674. // file header
  1675. filehdr.Machine = IMAGE_FILE_MACHINE_I386;
  1676. filehdr.NumberOfSections = nscns;
  1677. filehdr.TimeDateStamp = time(NULL);
  1678. filehdr.PointerToSymbolTable = sizeof(IMAGE_FILE_HEADER) +
  1679. (sizeof(IMAGE_SECTION_HEADER) * nscns) +
  1680. scnsize +
  1681. (sizeof(IMAGE_RELOCATION) * nreloc) +
  1682. (sizeof(IMAGE_LINENUMBER) * nlnno);
  1683. filehdr.NumberOfSymbols = nsyms;
  1684. filehdr.SizeOfOptionalHeader = 0;
  1685. filehdr.Characteristics = IMAGE_FILE_32BIT_MACHINE;
  1686. fwrite(&filehdr, sizeof(IMAGE_FILE_HEADER), 1, objfile);
  1687. // section headers
  1688. scnptr = sizeof(IMAGE_FILE_HEADER) + (sizeof(IMAGE_SECTION_HEADER) * nscns);
  1689. relptr = sizeof(IMAGE_FILE_HEADER) + (sizeof(IMAGE_SECTION_HEADER) * nscns) + scnsize;
  1690. lnnoptr = sizeof(IMAGE_FILE_HEADER) + (sizeof(IMAGE_SECTION_HEADER) * nscns) + scnsize + (sizeof(IMAGE_RELOCATION) * nreloc);
  1691. for (i = 0; i < nscns; i++) {
  1692. if ((scnhdr[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
  1693. scnhdr[i].PointerToRawData = scnhdr[i].SizeOfRawData ? scnptr : 0;
  1694. } else {
  1695. scnhdr[i].PointerToRawData = 0;
  1696. }
  1697. scnhdr[i].PointerToRelocations = scnhdr[i].NumberOfRelocations ? relptr : 0;
  1698. scnhdr[i].PointerToLinenumbers = scnhdr[i].NumberOfLinenumbers ? lnnoptr : 0;
  1699. if (isymDefAux != 0) {
  1700. // Point the first function to all the linenumbers.
  1701. ((PIMAGE_AUX_SYMBOL)&SymTable[isymDefAux])
  1702. ->Sym.FcnAry.Function.PointerToLinenumber = lnnoptr;
  1703. isymDefAux = 0;
  1704. }
  1705. fwrite(&scnhdr[i], sizeof(IMAGE_SECTION_HEADER), 1, objfile);
  1706. if ((scnhdr[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) !=
  1707. IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
  1708. scnptr += scnhdr[i].SizeOfRawData;
  1709. }
  1710. relptr += sizeof(IMAGE_RELOCATION) * scnhdr[i].NumberOfRelocations;
  1711. lnnoptr += sizeof(IMAGE_LINENUMBER) * scnhdr[i].NumberOfLinenumbers;
  1712. }
  1713. // section data
  1714. for (i = 0; i < nscns; i++) {
  1715. if (scnhdr[i].SizeOfRawData && scnhdr[i].PointerToRawData) {
  1716. fwrite(RawData[i], 1, (size_t)scnhdr[i].SizeOfRawData, objfile);
  1717. }
  1718. FreePv(RawData[i]);
  1719. RawData[i] = 0;
  1720. }
  1721. // relocation entries
  1722. for (i = 0; i < nscns; i++) {
  1723. if (scnhdr[i].Characteristics != IMAGE_SCN_LNK_INFO) {
  1724. if (scnhdr[i].NumberOfRelocations) {
  1725. PRELOCS ptrReloc;
  1726. PRELOCS next;
  1727. ptrReloc = Relocations[i].First;
  1728. for (j = 0; j < scnhdr[i].NumberOfRelocations; j++) {
  1729. fwrite(&ptrReloc->Reloc, sizeof(IMAGE_RELOCATION), 1, objfile);
  1730. next = ptrReloc->Next;
  1731. FreePv(ptrReloc);
  1732. ptrReloc = next;
  1733. }
  1734. Relocations[i].First = NULL;
  1735. }
  1736. }
  1737. }
  1738. // line numbers
  1739. for (i = 0; i < nscns; i++) {
  1740. if (scnhdr[i].Characteristics & IMAGE_SCN_CNT_CODE) {
  1741. WORD temp = scnhdr[i].NumberOfLinenumbers;
  1742. WORD x = 0;
  1743. if (temp) {
  1744. PLINENUMS ptrLinenum;
  1745. PLINENUMS next;
  1746. ptrLinenum = Linenumbers[i].First;
  1747. for (j = 0; j < temp; j++) {
  1748. fwrite(&ptrLinenum->Linenum, sizeof(IMAGE_LINENUMBER), 1, objfile);
  1749. x++;
  1750. next = ptrLinenum->Next;
  1751. FreePv(ptrLinenum);
  1752. ptrLinenum = next;
  1753. }
  1754. Linenumbers[i].First = NULL;
  1755. }
  1756. scnhdr[i].NumberOfLinenumbers = x;
  1757. }
  1758. }
  1759. // patch section symbol aux records with #line and #reloc entries
  1760. for (i = 0; i < nscns; i++) {
  1761. if (scnauxidx[i] && SymTable) {
  1762. PIMAGE_AUX_SYMBOL auxSym;
  1763. auxSym = (PIMAGE_AUX_SYMBOL)(SymTable + scnauxidx[i]);
  1764. auxSym->Section.NumberOfRelocations = scnhdr[i].NumberOfRelocations;
  1765. auxSym->Section.NumberOfLinenumbers = scnhdr[i].NumberOfLinenumbers;
  1766. }
  1767. scnauxidx[i] = 0;
  1768. }
  1769. // symbol table
  1770. fseek(objfile, filehdr.PointerToSymbolTable, 0);
  1771. if (nsyms) {
  1772. for (li = 0; li < nsyms; li++) {
  1773. fwrite((PVOID) (SymTable+li), sizeof(IMAGE_SYMBOL), 1, objfile);
  1774. }
  1775. // always write the count, even if 0
  1776. fwrite(&strsize, sizeof(DWORD), 1, objfile);
  1777. if (strsize) {
  1778. strsize -= sizeof(DWORD);
  1779. fwrite(CvtomfStringTable+sizeof(DWORD), 1, (size_t)strsize, objfile);
  1780. FreePv(CvtomfStringTable);
  1781. }
  1782. }
  1783. // clean up
  1784. FreePv((void *) SymTable);
  1785. SymTable = 0;
  1786. scnsize = strsize = nreloc = nlnno = nsyms = 0;
  1787. nscns = 0;
  1788. }
  1789. BOOL FConvertOmfToCoff(const char *szOmf, const char *szCoff)
  1790. {
  1791. __try {
  1792. if (setjmp(mark) != 0) {
  1793. return(FALSE);
  1794. }
  1795. objfile = fopen(szOmf, "rb");
  1796. if (objfile == NULL) {
  1797. Fatal(NULL, CANTOPENFILE, szOmf);
  1798. }
  1799. omf(szOmf, PASS1);
  1800. fclose(objfile);
  1801. // Generate COFF file
  1802. objfile = fopen(szCoff, "wb");
  1803. if (objfile == 0) {
  1804. Fatal(NULL, CANTOPENFILE, szCoff);
  1805. }
  1806. coff();
  1807. fclose(objfile);
  1808. }
  1809. __except (fExceptionsOff ? EXCEPTION_CONTINUE_SEARCH : EXCEPTION_EXECUTE_HANDLER) {
  1810. return(FALSE);
  1811. }
  1812. return(TRUE);
  1813. }