outobj.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:66k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* outobj.c output routines for the Netwide Assembler to produce
  2.  * .OBJ object files
  3.  *
  4.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  5.  * Julian Hall. All rights reserved. The software is
  6.  * redistributable under the licence given in the file "Licence"
  7.  * distributed in the NASM archive.
  8.  */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include "nasm.h"
  14. #include "nasmlib.h"
  15. #include "outform.h"
  16. #ifdef OF_OBJ
  17. /*
  18.  * outobj.c is divided into two sections.  The first section is low level
  19.  * routines for creating obj records;  It has nearly zero NASM specific
  20.  * code.  The second section is high level routines for processing calls and
  21.  * data structures from the rest of NASM into obj format.
  22.  *
  23.  * It should be easy (though not zero work) to lift the first section out for
  24.  * use as an obj file writer for some other assembler or compiler.
  25.  */
  26. /*
  27.  * These routines are built around the ObjRecord data struture.  An ObjRecord
  28.  * holds an object file record that may be under construction or complete.
  29.  *
  30.  * A major function of these routines is to support continuation of an obj
  31.  * record into the next record when the maximum record size is exceeded.  The
  32.  * high level code does not need to worry about where the record breaks occur.
  33.  * It does need to do some minor extra steps to make the automatic continuation
  34.  * work.  Those steps may be skipped for records where the high level knows no
  35.  * continuation could be required.
  36.  *
  37.  * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
  38.  *    is cleared by obj_clear.
  39.  *
  40.  * 2) The caller should fill in .type.
  41.  *
  42.  * 3) If the record is continuable and there is processing that must be done at
  43.  *    the start of each record then the caller should fill in .ori with the
  44.  *    address of the record initializer routine.
  45.  *
  46.  * 4) If the record is continuable and it should be saved (rather than emitted
  47.  *    immediately) as each record is done, the caller should set .up to be a
  48.  *    pointer to a location in which the caller keeps the master pointer to the
  49.  *    ObjRecord.  When the record is continued, the obj_bump routine will then
  50.  *    allocate a new ObjRecord structure and update the master pointer.
  51.  *
  52.  * 5) If the .ori field was used then the caller should fill in the .parm with
  53.  *    any data required by the initializer.
  54.  *
  55.  * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
  56.  *    obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
  57.  *    data required for this record.
  58.  *
  59.  * 7) If the record is continuable, the caller should call obj_commit at each
  60.  *    point where breaking the record is permitted.
  61.  *
  62.  * 8) To write out the record, the caller should call obj_emit2.  If the
  63.  *    caller has called obj_commit for all data written then he can get slightly
  64.  *    faster code by calling obj_emit instead of obj_emit2.
  65.  *
  66.  * Most of these routines return an ObjRecord pointer.  This will be the input
  67.  * pointer most of the time and will be the new location if the ObjRecord
  68.  * moved as a result of the call.  The caller may ignore the return value in
  69.  * three cases:  It is a "Never Reallocates" routine;  or  The caller knows
  70.  * continuation is not possible;  or  The caller uses the master pointer for the
  71.  * next operation.
  72.  */
  73. #define RECORD_MAX 1024 /* maximum size of _any_ record */
  74. #define OBJ_PARMS  3 /* maximum .parm used by any .ori routine */
  75. #define FIX_08_LOW      0x8000 /* location type for various fixup subrecords */
  76. #define FIX_16_OFFSET   0x8400
  77. #define FIX_16_SELECTOR 0x8800
  78. #define FIX_32_POINTER  0x8C00
  79. #define FIX_08_HIGH     0x9000
  80. #define FIX_32_OFFSET   0xA400
  81. #define FIX_48_POINTER  0xAC00
  82. enum RecordID {        /* record ID codes */
  83.     THEADR = 0x80,        /* module header */
  84.     COMENT = 0x88,        /* comment record */
  85.     LINNUM = 0x94,                     /* line number record */
  86.     LNAMES = 0x96,        /* list of names */
  87.     SEGDEF = 0x98,        /* segment definition */
  88.     GRPDEF = 0x9A,        /* group definition */
  89.     EXTDEF = 0x8C,        /* external definition */
  90.     PUBDEF = 0x90,        /* public definition */
  91.     COMDEF = 0xB0,        /* common definition */
  92.     LEDATA = 0xA0,        /* logical enumerated data */
  93.     FIXUPP = 0x9C,        /* fixups (relocations) */
  94.     MODEND = 0x8A        /* module end */
  95. };
  96. enum ComentID {                        /* ID codes for comment records */
  97.      dEXTENDED = 0xA1,                 /* tells that we are using translator-specific extensions */
  98.      dLINKPASS = 0xA2,                 /* link pass 2 marker */
  99.      dTYPEDEF = 0xE3,                  /* define a type */
  100.      dSYM = 0xE6,                      /* symbol debug record */
  101.      dFILNAME = 0xE8,                  /* file name record */
  102.      dCOMPDEF = 0xEA                   /* compiler type info */
  103. };
  104. typedef struct ObjRecord ObjRecord;
  105. typedef void ORI(ObjRecord *orp);
  106. struct ObjRecord {
  107.     ORI           *ori; /* Initialization routine           */
  108.     int            used; /* Current data size                */
  109.     int            committed; /* Data size at last boundary       */
  110.     int            x_size; /* (see obj_x)                      */
  111.     unsigned int   type; /* Record type                      */
  112.     ObjRecord     *child; /* Associated record below this one */
  113.     ObjRecord    **up; /* Master pointer to this ObjRecord */
  114.     ObjRecord     *back; /* Previous part of this record     */
  115.     unsigned long  parm[OBJ_PARMS]; /* Parameters for ori routine       */
  116.     unsigned char  buf[RECORD_MAX];
  117. };
  118. static void obj_fwrite(ObjRecord *orp);
  119. static void ori_ledata(ObjRecord *orp);
  120. static void ori_pubdef(ObjRecord *orp);
  121. static void ori_null(ObjRecord *orp);
  122. static ObjRecord *obj_commit(ObjRecord *orp);
  123. static void obj_write_fixup (ObjRecord *orp, int bytes,
  124.      int segrel, long seg, long wrt);
  125. static int obj_uppercase; /* Flag: all names in uppercase */
  126. /*
  127.  * Clear an ObjRecord structure.  (Never reallocates).
  128.  * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
  129.  */
  130. static ObjRecord *obj_clear(ObjRecord *orp) 
  131. {
  132.     orp->used = 0;
  133.     orp->committed = 0;
  134.     orp->x_size = 0;
  135.     orp->child = NULL;
  136.     orp->up = NULL;
  137.     orp->back = NULL;
  138.     return (orp);
  139. }
  140. /*
  141.  * Emit an ObjRecord structure.  (Never reallocates).
  142.  * The record is written out preceeded (recursively) by its previous part (if
  143.  * any) and followed (recursively) by its child (if any).
  144.  * The previous part and the child are freed.  The main ObjRecord is cleared,
  145.  * not freed.
  146.  */
  147. static ObjRecord *obj_emit(ObjRecord *orp) 
  148. {
  149.     if (orp->back) {
  150. obj_emit(orp->back);
  151. nasm_free(orp->back);
  152.     }
  153.     if (orp->committed)
  154. obj_fwrite(orp);
  155.     if (orp->child) {
  156. obj_emit(orp->child);
  157. nasm_free(orp->child);
  158.     }
  159.     return (obj_clear(orp));
  160. }
  161. /*
  162.  * Commit and Emit a record.  (Never reallocates).
  163.  */
  164. static ObjRecord *obj_emit2(ObjRecord *orp) 
  165. {
  166.     obj_commit(orp);
  167.     return (obj_emit(orp));
  168. }
  169. /*
  170.  * Allocate and clear a new ObjRecord;  Also sets .ori to ori_null
  171.  */
  172. static ObjRecord *obj_new(void) 
  173. {
  174.     ObjRecord *orp;
  175.     
  176.     orp = obj_clear( nasm_malloc(sizeof(ObjRecord)) );
  177.     orp->ori = ori_null;
  178.     return (orp);
  179. }
  180.     
  181. /*
  182.  * Advance to the next record because the existing one is full or its x_size
  183.  * is incompatible.
  184.  * Any uncommited data is moved into the next record.
  185.  */
  186. static ObjRecord *obj_bump(ObjRecord *orp) 
  187. {
  188.     ObjRecord *nxt;
  189.     int used = orp->used;
  190.     int committed = orp->committed;
  191.     if (orp->up) {
  192. *orp->up = nxt = obj_new();
  193. nxt->ori = orp->ori;
  194. nxt->type = orp->type;
  195. nxt->up = orp->up;
  196. nxt->back = orp;
  197. memcpy( nxt->parm, orp->parm, sizeof(orp->parm));
  198.     } else
  199. nxt = obj_emit(orp);
  200.     used -= committed;
  201.     if (used) {
  202. nxt->committed = 1;
  203. nxt->ori (nxt);
  204. nxt->committed = nxt->used;
  205. memcpy( nxt->buf + nxt->committed, orp->buf + committed, used);
  206. nxt->used = nxt->committed + used;
  207.     }
  208.     return (nxt);
  209. }
  210. /*
  211.  * Advance to the next record if necessary to allow the next field to fit.
  212.  */
  213. static ObjRecord *obj_check(ObjRecord *orp, int size) 
  214. {
  215.     if (orp->used + size > RECORD_MAX)
  216. orp = obj_bump(orp);
  217.     if (!orp->committed) {
  218. orp->committed = 1;
  219. orp->ori (orp);
  220. orp->committed = orp->used;
  221.     }
  222.     return (orp);
  223. }
  224. /*
  225.  * All data written so far is commited to the current record (won't be moved to
  226.  * the next record in case of continuation).
  227.  */
  228. static ObjRecord *obj_commit(ObjRecord *orp) 
  229. {
  230.     orp->committed = orp->used;
  231.     return (orp);
  232. }
  233. /*
  234.  * Write a byte
  235.  */
  236. static ObjRecord *obj_byte(ObjRecord *orp, unsigned char val) 
  237. {
  238.     orp = obj_check(orp, 1);
  239.     orp->buf[orp->used] = val;
  240.     orp->used++;
  241.     return (orp);
  242. }
  243. /*
  244.  * Write a word
  245.  */
  246. static ObjRecord *obj_word(ObjRecord *orp, unsigned int val) 
  247. {
  248.     orp = obj_check(orp, 2);
  249.     orp->buf[orp->used] = val;
  250.     orp->buf[orp->used+1] = val >> 8;
  251.     orp->used += 2;
  252.     return (orp);
  253. }
  254. /*
  255.  * Write a reversed word
  256.  */
  257. static ObjRecord *obj_rword(ObjRecord *orp, unsigned int val) 
  258. {
  259.     orp = obj_check(orp, 2);
  260.     orp->buf[orp->used] = val >> 8;
  261.     orp->buf[orp->used+1] = val;
  262.     orp->used += 2;
  263.     return (orp);
  264. }
  265. /*
  266.  * Write a dword
  267.  */
  268. static ObjRecord *obj_dword(ObjRecord *orp, unsigned long val) 
  269. {
  270.     orp = obj_check(orp, 4);
  271.     orp->buf[orp->used] = val;
  272.     orp->buf[orp->used+1] = val >> 8;
  273.     orp->buf[orp->used+2] = val >> 16;
  274.     orp->buf[orp->used+3] = val >> 24;
  275.     orp->used += 4;
  276.     return (orp);
  277. }
  278. /*
  279.  * All fields of "size x" in one obj record must be the same size (either 16
  280.  * bits or 32 bits).  There is a one bit flag in each record which specifies
  281.  * which.
  282.  * This routine is used to force the current record to have the desired
  283.  * x_size.  x_size is normally automatic (using obj_x), so that this
  284.  * routine should be used outside obj_x, only to provide compatibility with
  285.  * linkers that have bugs in their processing of the size bit.
  286.  */
  287. static ObjRecord *obj_force(ObjRecord *orp, int x)
  288. {
  289.     if (orp->x_size == (x^48))
  290. orp = obj_bump(orp);
  291.     orp->x_size = x;
  292. return (orp);
  293. }
  294. /*
  295.  * This routine writes a field of size x.  The caller does not need to worry at
  296.  * all about whether 16-bits or 32-bits are required.
  297.  */
  298. static ObjRecord *obj_x(ObjRecord *orp, unsigned long val) 
  299. {
  300.     if (orp->type & 1)
  301. orp->x_size = 32;
  302.     if (val > 0xFFFF)
  303. orp = obj_force(orp, 32);
  304.     if (orp->x_size == 32)
  305. return (obj_dword(orp, val));
  306.     orp->x_size = 16;
  307.     return (obj_word(orp, val));
  308. }
  309. /*
  310.  * Writes an index
  311.  */
  312. static ObjRecord *obj_index(ObjRecord *orp, unsigned int val) 
  313. {
  314.     if (val < 128)
  315. return ( obj_byte(orp, val) );
  316.     return (obj_word(orp, (val>>8) | (val<<8) | 0x80));
  317. }
  318. /*
  319.  * Writes a variable length value
  320.  */
  321. static ObjRecord *obj_value(ObjRecord *orp, unsigned long val) 
  322. {
  323.     if (val <= 128)
  324. return ( obj_byte(orp, val) );
  325.     if (val <= 0xFFFF) {
  326. orp = obj_byte(orp, 129);
  327. return ( obj_word(orp, val) );
  328.     }
  329.     if (val <= 0xFFFFFF)
  330. return ( obj_dword(orp, (val<<8) + 132 ) );
  331.     orp = obj_byte(orp, 136);
  332.     return ( obj_dword(orp, val) );
  333. }
  334. /*
  335.  * Writes a counted string
  336.  */
  337. static ObjRecord *obj_name(ObjRecord *orp, char *name) 
  338. {
  339.     int len = strlen(name);
  340.     unsigned char *ptr;
  341.     orp = obj_check(orp, len+1);
  342.     ptr = orp->buf + orp->used;
  343.     *ptr++ = len;
  344.     orp->used += len+1;
  345.     if (obj_uppercase)
  346. while (--len >= 0) {
  347.     *ptr++ = toupper(*name);
  348.     name++;
  349.     } else
  350. memcpy(ptr, name, len);
  351.     return (orp);
  352. }
  353. /*
  354.  * Initializer for an LEDATA record.
  355.  * parm[0] = offset
  356.  * parm[1] = segment index
  357.  * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
  358.  * represent the offset that would be required if the record were split at the
  359.  * last commit point.
  360.  * parm[2] is a copy of parm[0] as it was when the current record was initted.
  361.  */
  362. static void ori_ledata(ObjRecord *orp) 
  363. {
  364.     obj_index (orp, orp->parm[1]);
  365.     orp->parm[2] = orp->parm[0];
  366.     obj_x (orp, orp->parm[0]);
  367. }
  368. /*
  369.  * Initializer for a PUBDEF record.
  370.  * parm[0] = group index
  371.  * parm[1] = segment index
  372.  * parm[2] = frame (only used when both indexes are zero)
  373.  */
  374. static void ori_pubdef(ObjRecord *orp) 
  375. {
  376.     obj_index (orp, orp->parm[0]);
  377.     obj_index (orp, orp->parm[1]);
  378.     if ( !(orp->parm[0] | orp->parm[1]) )
  379. obj_word (orp, orp->parm[2]);
  380. }
  381. /*
  382.  * Initializer for a LINNUM record.
  383.  * parm[0] = group index
  384.  * parm[1] = segment index
  385.  */
  386. static void ori_linnum(ObjRecord *orp) 
  387. {
  388.     obj_index (orp, orp->parm[0]);
  389.     obj_index (orp, orp->parm[1]);
  390. }
  391. /*
  392.  * Initializer for a local vars record.
  393.  */
  394. static void ori_local(ObjRecord *orp) 
  395. {
  396.     obj_byte (orp, 0x40);
  397.     obj_byte (orp, dSYM);
  398. }
  399. /*
  400.  * Null initializer for records that continue without any header info
  401.  */
  402. static void ori_null(ObjRecord *orp) 
  403. {
  404.     (void) orp;  /* Do nothing */
  405. }
  406. /*
  407.  * This concludes the low level section of outobj.c
  408.  */
  409. static char obj_infile[FILENAME_MAX];
  410. static efunc error;
  411. static evalfunc evaluate;
  412. static ldfunc deflabel;
  413. static FILE *ofp;
  414. static long first_seg;
  415. static int any_segs;
  416. static int passtwo;
  417. static int arrindex;
  418. #define GROUP_MAX 256        /* we won't _realistically_ have more
  419. * than this many segs in a group */
  420. #define EXT_BLKSIZ 256        /* block size for externals list */
  421. struct Segment;        /* need to know these structs exist */
  422. struct Group;
  423. struct LineNumber {
  424.     struct LineNumber *next;
  425.     struct Segment *segment;
  426.     long offset;
  427.     long lineno;
  428. };
  429. static struct FileName {
  430.     struct FileName *next;
  431.     char *name;
  432.     struct LineNumber *lnhead, **lntail;
  433.     int index;
  434. } *fnhead, **fntail;
  435. static struct Array {
  436.     struct Array *next;
  437.     unsigned size;
  438.     int basetype;
  439. } *arrhead, **arrtail;
  440. #define ARRAYBOT 31 /* magic number  for first array index */
  441. static struct Public {
  442.     struct Public *next;
  443.     char *name;
  444.     long offset;
  445.     long segment;        /* only if it's far-absolute */
  446.     int type;                          /* only for local debug syms */
  447. } *fpubhead, **fpubtail, *last_defined;
  448. static struct External {
  449.     struct External *next;
  450.     char *name;
  451.     long commonsize;
  452.     long commonelem;        /* element size if FAR, else zero */
  453.     int index;        /* OBJ-file external index */
  454.     enum {
  455. DEFWRT_NONE,        /* no unusual default-WRT */
  456. DEFWRT_STRING,        /* a string we don't yet understand */
  457. DEFWRT_SEGMENT,        /* a segment */
  458. DEFWRT_GROUP        /* a group */
  459.     } defwrt_type;
  460.     union {
  461. char *string;
  462. struct Segment *seg;
  463. struct Group *grp;
  464.     } defwrt_ptr;
  465.     struct External *next_dws;        /* next with DEFWRT_STRING */
  466. } *exthead, **exttail, *dws;
  467. static int externals;
  468. static struct ExtBack {
  469.     struct ExtBack *next;
  470.     struct External *exts[EXT_BLKSIZ];
  471. } *ebhead, **ebtail;
  472. static struct Segment {
  473.     struct Segment *next;
  474.     long index;        /* the NASM segment id */
  475.     long obj_index;        /* the OBJ-file segment index */
  476.     struct Group *grp;        /* the group it belongs to */
  477.     unsigned long currentpos;
  478.     long align;        /* can be SEG_ABS + absolute addr */
  479.     enum {
  480. CMB_PRIVATE = 0,
  481. CMB_PUBLIC = 2,
  482. CMB_STACK = 5,
  483. CMB_COMMON = 6
  484.     } combine;
  485.     long use32;        /* is this segment 32-bit? */
  486.     struct Public *pubhead, **pubtail, *lochead, **loctail;
  487.     char *name;
  488.     char *segclass, *overlay;        /* `class' is a C++ keyword :-) */
  489.     ObjRecord *orp;
  490. } *seghead, **segtail, *obj_seg_needs_update;
  491. static struct Group {
  492.     struct Group *next;
  493.     char *name;
  494.     long index;        /* NASM segment id */
  495.     long obj_index;        /* OBJ-file group index */
  496.     long nentries;        /* number of elements... */
  497.     long nindices;        /* ...and number of index elts... */
  498.     union {
  499. long index;
  500. char *name;
  501.     } segs[GROUP_MAX];        /* ...in this */
  502. } *grphead, **grptail, *obj_grp_needs_update;
  503. static struct ImpDef {
  504.     struct ImpDef *next;
  505.     char *extname;
  506.     char *libname;
  507.     unsigned int impindex;
  508.     char *impname;
  509. } *imphead, **imptail;
  510. static struct ExpDef {
  511.     struct ExpDef *next;
  512.     char *intname;
  513.     char *extname;
  514.     unsigned int ordinal;
  515.     int flags;
  516. } *exphead, **exptail;
  517. #define EXPDEF_FLAG_ORDINAL  0x80
  518. #define EXPDEF_FLAG_RESIDENT 0x40
  519. #define EXPDEF_FLAG_NODATA   0x20
  520. #define EXPDEF_MASK_PARMCNT  0x1F
  521. static long obj_entry_seg, obj_entry_ofs;
  522. struct ofmt of_obj;
  523. static long obj_segment (char *, int, int *);
  524. static void obj_write_file(int debuginfo);
  525. static int obj_directive (char *, char *, int);
  526. static void obj_init (FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval) 
  527. {
  528.     ofp = fp;
  529.     error = errfunc;
  530.     evaluate = eval;
  531.     deflabel = ldef;
  532.     first_seg = seg_alloc();
  533.     any_segs = FALSE;
  534.     fpubhead = NULL;
  535.     fpubtail = &fpubhead;
  536.     exthead = NULL;
  537.     exttail = &exthead;
  538.     imphead = NULL;
  539.     imptail = &imphead;
  540.     exphead = NULL;
  541.     exptail = &exphead;
  542.     dws = NULL;
  543.     externals = 0;
  544.     ebhead = NULL;
  545.     ebtail = &ebhead;
  546.     seghead = obj_seg_needs_update = NULL;
  547.     segtail = &seghead;
  548.     grphead = obj_grp_needs_update = NULL;
  549.     grptail = &grphead;
  550.     obj_entry_seg = NO_SEG;
  551.     obj_uppercase = FALSE;
  552.     passtwo = 0;
  553.     of_obj.current_dfmt->init (&of_obj,NULL,fp,errfunc);
  554. }
  555. static int obj_set_info(enum geninfo type, char **val)
  556. {
  557.     (void) type;
  558.     (void) val;
  559.     return 0;
  560. }
  561. static void obj_cleanup (int debuginfo) 
  562. {
  563.     obj_write_file(debuginfo);
  564.     of_obj.current_dfmt->cleanup();
  565.     fclose (ofp);
  566.     while (seghead) {
  567. struct Segment *segtmp = seghead;
  568. seghead = seghead->next;
  569. while (segtmp->pubhead) {
  570.     struct Public *pubtmp = segtmp->pubhead;
  571.     segtmp->pubhead = pubtmp->next;
  572.     nasm_free (pubtmp->name);
  573.     nasm_free (pubtmp);
  574. }
  575. nasm_free (segtmp->segclass);
  576. nasm_free (segtmp->overlay);
  577. nasm_free (segtmp);
  578.     }
  579.     while (fpubhead) {
  580. struct Public *pubtmp = fpubhead;
  581. fpubhead = fpubhead->next;
  582. nasm_free (pubtmp->name);
  583. nasm_free (pubtmp);
  584.     }
  585.     while (exthead) {
  586. struct External *exttmp = exthead;
  587. exthead = exthead->next;
  588. nasm_free (exttmp);
  589.     }
  590.     while (imphead) {
  591. struct ImpDef *imptmp = imphead;
  592. imphead = imphead->next;
  593. nasm_free (imptmp->extname);
  594. nasm_free (imptmp->libname);
  595. nasm_free (imptmp->impname);   /* nasm_free won't mind if it's NULL */
  596. nasm_free (imptmp);
  597.     }
  598.     while (exphead) {
  599. struct ExpDef *exptmp = exphead;
  600. exphead = exphead->next;
  601. nasm_free (exptmp->extname);
  602. nasm_free (exptmp->intname);
  603. nasm_free (exptmp);
  604.     }
  605.     while (ebhead) {
  606. struct ExtBack *ebtmp = ebhead;
  607. ebhead = ebhead->next;
  608. nasm_free (ebtmp);
  609.     }
  610.     while (grphead) {
  611. struct Group *grptmp = grphead;
  612. grphead = grphead->next;
  613. nasm_free (grptmp);
  614.     }
  615. }
  616. static void obj_ext_set_defwrt (struct External *ext, char *id) 
  617. {
  618.     struct Segment *seg;
  619.     struct Group *grp;
  620.     for (seg = seghead; seg; seg = seg->next)
  621. if (!strcmp(seg->name, id)) {
  622.     ext->defwrt_type = DEFWRT_SEGMENT;
  623.     ext->defwrt_ptr.seg = seg;
  624.     nasm_free (id);
  625.     return;
  626. }
  627.     for (grp = grphead; grp; grp = grp->next)
  628. if (!strcmp(grp->name, id)) {
  629.     ext->defwrt_type = DEFWRT_GROUP;
  630.     ext->defwrt_ptr.grp = grp;
  631.     nasm_free (id);
  632.     return;
  633. }
  634.     ext->defwrt_type = DEFWRT_STRING;
  635.     ext->defwrt_ptr.string = id;
  636.     ext->next_dws = dws;
  637.     dws = ext;
  638. }
  639. static void obj_deflabel (char *name, long segment,
  640.   long offset, int is_global, char *special) 
  641. {
  642.     /*
  643.      * We have three cases:
  644.      *
  645.      * (i) `segment' is a segment-base. If so, set the name field
  646.      * for the segment or group structure it refers to, and then
  647.      * return.
  648.      *
  649.      * (ii) `segment' is one of our segments, or a SEG_ABS segment.
  650.      * Save the label position for later output of a PUBDEF record.
  651.      * (Or a MODPUB, if we work out how.)
  652.      *
  653.      * (iii) `segment' is not one of our segments. Save the label
  654.      * position for later output of an EXTDEF, and also store a
  655.      * back-reference so that we can map later references to this
  656.      * segment number to the external index.
  657.      */
  658.     struct External *ext;
  659.     struct ExtBack *eb;
  660.     struct Segment *seg;
  661.     int i;
  662.     int used_special = FALSE;        /* have we used the special text? */
  663.     /*
  664.      * If it's a special-retry from pass two, discard it.
  665.      */
  666.     if (is_global == 3)
  667. return;
  668.     /*
  669.      * First check for the double-period, signifying something
  670.      * unusual.
  671.      */
  672.     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  673. if (!strcmp(name, "..start")) {
  674.     obj_entry_seg = segment;
  675.     obj_entry_ofs = offset;
  676.     return;
  677. }
  678. error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
  679.     }
  680.     /*
  681.      * Case (i):
  682.      */
  683.     if (obj_seg_needs_update) {
  684. obj_seg_needs_update->name = name;
  685. return;
  686.     } else if (obj_grp_needs_update) {
  687. obj_grp_needs_update->name = name;
  688. return;
  689.     }
  690.     if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
  691. return;
  692.     if (segment >= SEG_ABS || segment == NO_SEG) {
  693. /*
  694.  * SEG_ABS subcase of (ii).
  695.  */
  696. if (is_global) {
  697.     struct Public *pub;
  698.     pub = *fpubtail = nasm_malloc(sizeof(*pub));
  699.     fpubtail = &pub->next;
  700.     pub->next = NULL;
  701.     pub->name = nasm_strdup(name);
  702.     pub->offset = offset;
  703.     pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
  704. }
  705. if (special)
  706.     error(ERR_NONFATAL, "OBJ supports no special symbol features"
  707.   " for this symbol type");
  708. return;
  709.     }
  710.     /*
  711.      * If `any_segs' is still FALSE, we might need to define a
  712.      * default segment, if they're trying to declare a label in
  713.      * `first_seg'.
  714.      */
  715.     if (!any_segs && segment == first_seg) {
  716. int tempint;        /* ignored */
  717. if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
  718.     error (ERR_PANIC, "strange segment conditions in OBJ driver");
  719.     }
  720.     for (seg = seghead; seg && is_global; seg = seg->next)
  721. if (seg->index == segment) {
  722.     struct Public *loc = nasm_malloc (sizeof(*loc));
  723.     /*
  724.      * Case (ii). Maybe MODPUB someday?
  725.      */
  726.     *seg->pubtail = loc;
  727.     seg->pubtail = &loc->next;
  728.     loc->next = NULL;
  729.     loc->name = nasm_strdup(name);
  730.     loc->offset = offset;
  731.                   
  732.     if (special)
  733. error(ERR_NONFATAL, "OBJ supports no special symbol features"
  734.       " for this symbol type");
  735.     return;
  736. }
  737.     /*
  738.      * Case (iii).
  739.      */
  740.     if (is_global) {
  741.         ext = *exttail = nasm_malloc(sizeof(*ext));
  742.         ext->next = NULL;
  743.         exttail = &ext->next;
  744.         ext->name = name;
  745.         ext->defwrt_type = DEFWRT_NONE;
  746.         if (is_global == 2) {
  747.     ext->commonsize = offset;
  748.     ext->commonelem = 1;        /* default FAR */
  749.         } else
  750.     ext->commonsize = 0;
  751.     }
  752.     else
  753. return;
  754.     /*
  755.      * Now process the special text, if any, to find default-WRT
  756.      * specifications and common-variable element-size and near/far
  757.      * specifications.
  758.      */
  759.     while (special && *special) {
  760. used_special = TRUE;
  761. /*
  762.  * We might have a default-WRT specification.
  763.  */
  764. if (!nasm_strnicmp(special, "wrt", 3)) {
  765.     char *p;
  766.     int len;
  767.     special += 3;
  768.     special += strspn(special, " t");
  769.     p = nasm_strndup(special, len = strcspn(special, ":"));
  770.     obj_ext_set_defwrt (ext, p);
  771.     special += len;
  772.     if (*special && *special != ':')
  773. error(ERR_NONFATAL, "`:' expected in special symbol"
  774.       " text for `%s'", ext->name);
  775.     else if (*special == ':')
  776. special++;
  777. }
  778. /*
  779.  * The NEAR or FAR keywords specify nearness or
  780.  * farness. FAR gives default element size 1.
  781.  */
  782. if (!nasm_strnicmp(special, "far", 3)) {
  783.     if (ext->commonsize)
  784. ext->commonelem = 1;
  785.     else
  786. error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"
  787.       " to common variablesn", ext->name);
  788.     special += 3;
  789.     special += strspn(special, " t");
  790. } else if (!nasm_strnicmp(special, "near", 4)) {
  791.     if (ext->commonsize)
  792. ext->commonelem = 0;
  793.     else
  794. error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"
  795.       " to common variablesn", ext->name);
  796.     special += 4;
  797.     special += strspn(special, " t");
  798. }
  799. /*
  800.  * If it's a common, and anything else remains on the line
  801.  * before a further colon, evaluate it as an expression and
  802.  * use that as the element size. Forward references aren't
  803.  * allowed.
  804.  */
  805. if (*special == ':')
  806.     special++;
  807. else if (*special) {
  808.     if (ext->commonsize) {
  809. expr *e;
  810. struct tokenval tokval;
  811. stdscan_reset();
  812. stdscan_bufptr = special;
  813. tokval.t_type = TOKEN_INVALID;
  814. e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
  815. if (e) {
  816.     if (!is_simple(e))
  817. error (ERR_NONFATAL, "cannot use relocatable"
  818.        " expression as common-variable element size");
  819.     else
  820. ext->commonelem = reloc_value(e);
  821. }
  822. special = stdscan_bufptr;
  823.     } else {
  824. error (ERR_NONFATAL, "`%s': element-size specifications only"
  825.        " apply to common variables", ext->name);
  826. while (*special && *special != ':')
  827.     special++;
  828. if (*special == ':')
  829.     special++;
  830.     }
  831. }
  832.     }
  833.     i = segment/2;
  834.     eb = ebhead;
  835.     if (!eb) {
  836. eb = *ebtail = nasm_malloc(sizeof(*eb));
  837. eb->next = NULL;
  838. ebtail = &eb->next;
  839.     }
  840.     while (i > EXT_BLKSIZ) {
  841. if (eb && eb->next)
  842.     eb = eb->next;
  843. else {
  844.     eb = *ebtail = nasm_malloc(sizeof(*eb));
  845.     eb->next = NULL;
  846.     ebtail = &eb->next;
  847. }
  848. i -= EXT_BLKSIZ;
  849.     }
  850.     eb->exts[i] = ext;
  851.     ext->index = ++externals;
  852.     if (special && !used_special)
  853. error(ERR_NONFATAL, "OBJ supports no special symbol features"
  854.       " for this symbol type");
  855. }
  856. static void obj_out (long segto, void *data, unsigned long type,
  857.      long segment, long wrt) 
  858. {
  859.     long size, realtype;
  860.     unsigned char *ucdata;
  861.     long ldata;
  862.     struct Segment *seg;
  863.     ObjRecord *orp;
  864.     /*
  865.      * handle absolute-assembly (structure definitions)
  866.      */
  867.     if (segto == NO_SEG) {
  868. if ((type & OUT_TYPMASK) != OUT_RESERVE)
  869.     error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  870.    " space");
  871. return;
  872.     }
  873.     /*
  874.      * If `any_segs' is still FALSE, we must define a default
  875.      * segment.
  876.      */
  877.     if (!any_segs) {
  878. int tempint;        /* ignored */
  879. if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
  880.     error (ERR_PANIC, "strange segment conditions in OBJ driver");
  881.     }
  882.     /*
  883.      * Find the segment we are targetting.
  884.      */
  885.     for (seg = seghead; seg; seg = seg->next)
  886. if (seg->index == segto)
  887.     break;
  888.     if (!seg)
  889. error (ERR_PANIC, "code directed to nonexistent segment?");
  890.     orp = seg->orp;
  891.     orp->parm[0] = seg->currentpos;
  892.     size = type & OUT_SIZMASK;
  893.     realtype = type & OUT_TYPMASK;
  894.     if (realtype == OUT_RAWDATA) {
  895. ucdata = data;
  896. while (size > 0) {
  897.     unsigned int len;
  898.     orp = obj_check(seg->orp, 1);
  899.     len = RECORD_MAX - orp->used;
  900.     if (len > size)
  901. len = size;
  902.     memcpy (orp->buf+orp->used, ucdata, len);
  903.     orp->committed = orp->used += len;
  904.     orp->parm[0] = seg->currentpos += len;
  905.     ucdata += len;
  906.     size -= len;
  907. }
  908.     }
  909.     else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
  910.      realtype == OUT_REL4ADR) 
  911.     {
  912. int rsize;
  913. if (segment == NO_SEG && realtype != OUT_ADDRESS)
  914.     error(ERR_NONFATAL, "relative call to absolute address not"
  915.   " supported by OBJ format");
  916. if (segment >= SEG_ABS)
  917.     error(ERR_NONFATAL, "far-absolute relocations not supported"
  918.   " by OBJ format");
  919. ldata = *(long *)data;
  920. if (realtype == OUT_REL2ADR) {
  921.     ldata += (size-2);
  922.     size = 2;
  923. }
  924. if (realtype == OUT_REL4ADR) {
  925.     ldata += (size-4);
  926.     size = 4;
  927. }
  928. if (size == 2)
  929.     orp = obj_word (orp, ldata);
  930. else
  931.     orp = obj_dword (orp, ldata);
  932. rsize = size;
  933. if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
  934.     size == 4) {
  935.     /*
  936.      * This is a 4-byte segment-base relocation such as
  937.      * `MOV EAX,SEG foo'. OBJ format can't actually handle
  938.      * these, but if the constant term has the 16 low bits
  939.      * zero, we can just apply a 2-byte segment-base
  940.      * relocation to the low word instead.
  941.      */
  942.     rsize = 2;
  943.     if (ldata & 0xFFFF)
  944. error(ERR_NONFATAL, "OBJ format cannot handle complex"
  945.       " dword-size segment base references");
  946. }
  947. if (segment != NO_SEG)
  948.     obj_write_fixup (orp, rsize,
  949.      (realtype == OUT_ADDRESS  ? 0x4000 : 0),
  950.      segment, wrt);
  951. seg->currentpos += size;
  952.     } else if (realtype == OUT_RESERVE) {
  953. if (orp->committed)
  954.     orp = obj_bump(orp);
  955. seg->currentpos += size;
  956.     }
  957.     obj_commit(orp);
  958. }
  959. static void obj_write_fixup (ObjRecord *orp, int bytes,
  960.      int segrel, long seg, long wrt) 
  961. {
  962.     int locat, method;
  963.     int base;
  964.     long tidx, fidx;
  965.     struct Segment *s = NULL;
  966.     struct Group *g = NULL;
  967.     struct External *e = NULL;
  968.     ObjRecord *forp;
  969.     if (bytes == 1) {
  970. error(ERR_NONFATAL, "`obj' output driver does not support"
  971.       " one-byte relocations");
  972. return;
  973.     }
  974.     forp = orp->child;
  975.     if (forp == NULL) {
  976. orp->child = forp = obj_new();
  977. forp->up = &(orp->child);
  978. forp->type = FIXUPP;
  979.     }
  980.     if (seg % 2) {
  981. base = TRUE;
  982. locat = FIX_16_SELECTOR;
  983. seg--;
  984. if (bytes != 2)
  985.     error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
  986.   " through sanity check");
  987.     }
  988.     else {
  989. base = FALSE;
  990. locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
  991. if (!segrel)
  992.     /*
  993.      * There is a bug in tlink that makes it process self relative
  994.      * fixups incorrectly if the x_size doesn't match the location
  995.      * size.
  996.      */
  997.     forp = obj_force(forp, bytes<<3);
  998.     }
  999.     forp = obj_rword (forp, locat | segrel | (orp->parm[0]-orp->parm[2]));
  1000.     tidx = fidx = -1, method = 0;      /* placate optimisers */
  1001.     /*
  1002.      * See if we can find the segment ID in our segment list. If
  1003.      * so, we have a T4 (LSEG) target.
  1004.      */
  1005.     for (s = seghead; s; s = s->next)
  1006. if (s->index == seg)
  1007.     break;
  1008.     if (s)
  1009. method = 4, tidx = s->obj_index;
  1010.     else {
  1011. for (g = grphead; g; g = g->next)
  1012.     if (g->index == seg)
  1013. break;
  1014. if (g)
  1015.     method = 5, tidx = g->obj_index;
  1016. else {
  1017.     long i = seg/2;
  1018.     struct ExtBack *eb = ebhead;
  1019.     while (i > EXT_BLKSIZ) {
  1020. if (eb)
  1021.     eb = eb->next;
  1022. else
  1023.     break;
  1024. i -= EXT_BLKSIZ;
  1025.     }
  1026.     if (eb)
  1027. method = 6, e = eb->exts[i], tidx = e->index;
  1028.     else
  1029. error(ERR_PANIC,
  1030.       "unrecognised segment value in obj_write_fixup");
  1031. }
  1032.     }
  1033.     /*
  1034.      * If no WRT given, assume the natural default, which is method
  1035.      * F5 unless:
  1036.      *
  1037.      * - we are doing an OFFSET fixup for a grouped segment, in
  1038.      *   which case we require F1 (group).
  1039.      *
  1040.      * - we are doing an OFFSET fixup for an external with a
  1041.      *   default WRT, in which case we must honour the default WRT.
  1042.      */
  1043.     if (wrt == NO_SEG) {
  1044. if (!base && s && s->grp)
  1045.     method |= 0x10, fidx = s->grp->obj_index;
  1046. else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
  1047.     if (e->defwrt_type == DEFWRT_SEGMENT)
  1048. method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
  1049.     else if (e->defwrt_type == DEFWRT_GROUP)
  1050. method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
  1051.     else {
  1052. error(ERR_NONFATAL, "default WRT specification for"
  1053.       " external `%s' unresolved", e->name);
  1054. method |= 0x50, fidx = -1; /* got to do _something_ */
  1055.     }
  1056. } else
  1057.     method |= 0x50, fidx = -1;
  1058.     } else {
  1059. /*
  1060.  * See if we can find the WRT-segment ID in our segment
  1061.  * list. If so, we have a F0 (LSEG) frame.
  1062.  */
  1063. for (s = seghead; s; s = s->next)
  1064.     if (s->index == wrt-1)
  1065. break;
  1066. if (s)
  1067.     method |= 0x00, fidx = s->obj_index;
  1068. else {
  1069.     for (g = grphead; g; g = g->next)
  1070. if (g->index == wrt-1)
  1071.     break;
  1072.     if (g)
  1073. method |= 0x10, fidx = g->obj_index;
  1074.     else {
  1075. long i = wrt/2;
  1076. struct ExtBack *eb = ebhead;
  1077. while (i > EXT_BLKSIZ) {
  1078.     if (eb)
  1079. eb = eb->next;
  1080.     else
  1081. break;
  1082.     i -= EXT_BLKSIZ;
  1083. }
  1084. if (eb)
  1085.     method |= 0x20, fidx = eb->exts[i]->index;
  1086. else
  1087.     error(ERR_PANIC,
  1088.   "unrecognised WRT value in obj_write_fixup");
  1089.     }
  1090. }
  1091.     }
  1092.     forp = obj_byte (forp, method);
  1093.     if (fidx != -1)
  1094. forp = obj_index (forp, fidx);
  1095.     forp = obj_index (forp, tidx);
  1096.     obj_commit (forp);
  1097. }
  1098. static long obj_segment (char *name, int pass, int *bits) 
  1099. {
  1100.     /*
  1101.      * We call the label manager here to define a name for the new
  1102.      * segment, and when our _own_ label-definition stub gets
  1103.      * called in return, it should register the new segment name
  1104.      * using the pointer it gets passed. That way we save memory,
  1105.      * by sponging off the label manager.
  1106.      */
  1107.     if (!name) {
  1108. *bits = 16;
  1109. return first_seg;
  1110.     } else {
  1111. struct Segment *seg;
  1112. struct Group *grp;
  1113. struct External **extp;
  1114. int obj_idx, i, attrs, rn_error;
  1115. char *p;
  1116. /*
  1117.  * Look for segment attributes.
  1118.  */
  1119. attrs = 0;
  1120. while (*name == '.')
  1121.     name++;        /* hack, but a documented one */
  1122. p = name;
  1123. while (*p && !isspace(*p))
  1124.     p++;
  1125. if (*p) {
  1126.     *p++ = '';
  1127.     while (*p && isspace(*p))
  1128. *p++ = '';
  1129. }
  1130. while (*p) {
  1131.     while (*p && !isspace(*p))
  1132. p++;
  1133.     if (*p) {
  1134. *p++ = '';
  1135. while (*p && isspace(*p))
  1136.     *p++ = '';
  1137.     }
  1138.     attrs++;
  1139. }
  1140. obj_idx = 1;
  1141. for (seg = seghead; seg; seg = seg->next) {
  1142.     obj_idx++;
  1143.     if (!strcmp(seg->name, name)) {
  1144. if (attrs > 0 && pass == 1)
  1145.     error(ERR_WARNING, "segment attributes specified on"
  1146.   " redeclaration of segment: ignoring");
  1147. if (seg->use32)
  1148.     *bits = 32;
  1149. else
  1150.     *bits = 16;
  1151. return seg->index;
  1152.     }
  1153. }
  1154. *segtail = seg = nasm_malloc(sizeof(*seg));
  1155. seg->next = NULL;
  1156. segtail = &seg->next;
  1157. seg->index = (any_segs ? seg_alloc() : first_seg);
  1158. seg->obj_index = obj_idx;
  1159. seg->grp = NULL;
  1160. any_segs = TRUE;
  1161. seg->name = NULL;
  1162. seg->currentpos = 0;
  1163. seg->align = 1;        /* default */
  1164. seg->use32 = FALSE;        /* default */
  1165. seg->combine = CMB_PUBLIC;     /* default */
  1166. seg->segclass = seg->overlay = NULL;
  1167. seg->pubhead = NULL;
  1168. seg->pubtail = &seg->pubhead;
  1169. seg->lochead = NULL;
  1170. seg->loctail = &seg->lochead;
  1171. seg->orp = obj_new();
  1172. seg->orp->up = &(seg->orp);
  1173. seg->orp->ori = ori_ledata;
  1174. seg->orp->type = LEDATA;
  1175. seg->orp->parm[1] = obj_idx;
  1176. /*
  1177.  * Process the segment attributes.
  1178.  */
  1179. p = name;
  1180. while (attrs--) {
  1181.     p += strlen(p);
  1182.     while (!*p) p++;
  1183.     /*
  1184.      * `p' contains a segment attribute.
  1185.      */
  1186.     if (!nasm_stricmp(p, "private"))
  1187. seg->combine = CMB_PRIVATE;
  1188.     else if (!nasm_stricmp(p, "public"))
  1189. seg->combine = CMB_PUBLIC;
  1190.     else if (!nasm_stricmp(p, "common"))
  1191. seg->combine = CMB_COMMON;
  1192.     else if (!nasm_stricmp(p, "stack"))
  1193. seg->combine = CMB_STACK;
  1194.     else if (!nasm_stricmp(p, "use16"))
  1195. seg->use32 = FALSE;
  1196.     else if (!nasm_stricmp(p, "use32"))
  1197. seg->use32 = TRUE;
  1198.     else if (!nasm_stricmp(p, "flat")) {
  1199. /*
  1200.  * This segment is an OS/2 FLAT segment. That means
  1201.  * that its default group is group FLAT, even if
  1202.  * the group FLAT does not explicitly _contain_ the
  1203.  * segment.
  1204.  * 
  1205.  * When we see this, we must create the group
  1206.  * `FLAT', containing no segments, if it does not
  1207.  * already exist; then we must set the default
  1208.  * group of this segment to be the FLAT group.
  1209.  */
  1210. struct Group *grp;
  1211. for (grp = grphead; grp; grp = grp->next)
  1212.     if (!strcmp(grp->name, "FLAT"))
  1213. break;
  1214. if (!grp) {
  1215.     obj_directive ("group", "FLAT", 1);
  1216.     for (grp = grphead; grp; grp = grp->next)
  1217. if (!strcmp(grp->name, "FLAT"))
  1218.     break;
  1219.     if (!grp)
  1220. error (ERR_PANIC, "failure to define FLAT?!");
  1221. }
  1222. seg->grp = grp;
  1223.     } else if (!nasm_strnicmp(p, "class=", 6))
  1224. seg->segclass = nasm_strdup(p+6);
  1225.     else if (!nasm_strnicmp(p, "overlay=", 8))
  1226. seg->overlay = nasm_strdup(p+8);
  1227.     else if (!nasm_strnicmp(p, "align=", 6)) {
  1228. seg->align = readnum(p+6, &rn_error);
  1229. if (rn_error) {
  1230.     seg->align = 1;
  1231.     error (ERR_NONFATAL, "segment alignment should be"
  1232.    " numeric");
  1233. }
  1234. switch ((int) seg->align) {
  1235.   case 1:        /* BYTE */
  1236.   case 2:        /* WORD */
  1237.   case 4:        /* DWORD */
  1238.   case 16:        /* PARA */
  1239.   case 256:        /* PAGE */
  1240.   case 4096:        /* PharLap extension */
  1241.     break;
  1242.   case 8:
  1243.     error(ERR_WARNING, "OBJ format does not support alignment"
  1244.   " of 8: rounding up to 16");
  1245.     seg->align = 16;
  1246.     break;
  1247.   case 32:
  1248.   case 64:
  1249.   case 128:
  1250.     error(ERR_WARNING, "OBJ format does not support alignment"
  1251.   " of %d: rounding up to 256", seg->align);
  1252.     seg->align = 256;
  1253.     break;
  1254.   case 512:
  1255.   case 1024:
  1256.   case 2048:
  1257.     error(ERR_WARNING, "OBJ format does not support alignment"
  1258.   " of %d: rounding up to 4096", seg->align);
  1259.     seg->align = 4096;
  1260.     break;
  1261.   default:
  1262.     error(ERR_NONFATAL, "invalid alignment value %d",
  1263.   seg->align);
  1264.     seg->align = 1;
  1265.     break;
  1266. }
  1267.     } else if (!nasm_strnicmp(p, "absolute=", 9)) {
  1268. seg->align = SEG_ABS + readnum(p+9, &rn_error);
  1269. if (rn_error)
  1270.     error (ERR_NONFATAL, "argument to `absolute' segment"
  1271.    " attribute should be numeric");
  1272.     }
  1273. }
  1274. obj_seg_needs_update = seg;
  1275. if (seg->align >= SEG_ABS)
  1276.     deflabel (name, NO_SEG, seg->align - SEG_ABS,
  1277.       NULL, FALSE, FALSE, &of_obj, error);
  1278. else
  1279.     deflabel (name, seg->index+1, 0L,
  1280.       NULL, FALSE, FALSE, &of_obj, error);
  1281. obj_seg_needs_update = NULL;
  1282. /*
  1283.  * See if this segment is defined in any groups.
  1284.  */
  1285. for (grp = grphead; grp; grp = grp->next) {
  1286.     for (i = grp->nindices; i < grp->nentries; i++) {
  1287. if (!strcmp(grp->segs[i].name, seg->name)) {
  1288.     nasm_free (grp->segs[i].name);
  1289.     grp->segs[i] = grp->segs[grp->nindices];
  1290.     grp->segs[grp->nindices++].index = seg->obj_index;
  1291.     if (seg->grp)
  1292. error(ERR_WARNING, "segment `%s' is already part of"
  1293.       " a group: first one takes precedence",
  1294.       seg->name);
  1295.     else
  1296. seg->grp = grp;
  1297. }
  1298.     }
  1299. }
  1300. /*
  1301.  * Walk through the list of externals with unresolved
  1302.  * default-WRT clauses, and resolve any that point at this
  1303.  * segment.
  1304.  */
  1305. extp = &dws;
  1306. while (*extp) {
  1307.     if ((*extp)->defwrt_type == DEFWRT_STRING &&
  1308. !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
  1309. nasm_free((*extp)->defwrt_ptr.string);
  1310. (*extp)->defwrt_type = DEFWRT_SEGMENT;
  1311. (*extp)->defwrt_ptr.seg = seg;
  1312. *extp = (*extp)->next_dws;
  1313.     } else
  1314. extp = &(*extp)->next_dws;
  1315. }
  1316. if (seg->use32)
  1317.     *bits = 32;
  1318. else
  1319.     *bits = 16;
  1320. return seg->index;
  1321.     }
  1322. }
  1323. static int obj_directive (char *directive, char *value, int pass) 
  1324. {
  1325.     if (!strcmp(directive, "group")) {
  1326. char *p, *q, *v;
  1327. if (pass == 1) {
  1328.     struct Group *grp;
  1329.     struct Segment *seg;
  1330.     struct External **extp;
  1331.     int obj_idx;
  1332.     q = value;
  1333.     while (*q == '.')
  1334. q++;        /* hack, but a documented one */
  1335.     v = q;
  1336.     while (*q && !isspace(*q))
  1337. q++;
  1338.     if (isspace(*q)) {
  1339. *q++ = '';
  1340. while (*q && isspace(*q))
  1341.     q++;
  1342.     }
  1343.     /*
  1344.      * Here we used to sanity-check the group directive to
  1345.      * ensure nobody tried to declare a group containing no
  1346.      * segments. However, OS/2 does this as standard
  1347.      * practice, so the sanity check has been removed.
  1348.      *
  1349.      * if (!*q) {
  1350.      *     error(ERR_NONFATAL,"GROUP directive contains no segments");
  1351.      *     return 1;
  1352.      * }
  1353.      */
  1354.     obj_idx = 1;
  1355.     for (grp = grphead; grp; grp = grp->next) {
  1356. obj_idx++;
  1357. if (!strcmp(grp->name, v)) {
  1358.     error(ERR_NONFATAL, "group `%s' defined twice", v);
  1359.     return 1;
  1360. }
  1361.     }
  1362.     *grptail = grp = nasm_malloc(sizeof(*grp));
  1363.     grp->next = NULL;
  1364.     grptail = &grp->next;
  1365.     grp->index = seg_alloc();
  1366.     grp->obj_index = obj_idx;
  1367.     grp->nindices = grp->nentries = 0;
  1368.     grp->name = NULL;
  1369.     obj_grp_needs_update = grp;
  1370.     deflabel (v, grp->index+1, 0L,
  1371.       NULL, FALSE, FALSE, &of_obj, error);
  1372.     obj_grp_needs_update = NULL;
  1373.     while (*q) {
  1374. p = q;
  1375. while (*q && !isspace(*q))
  1376.     q++;
  1377. if (isspace(*q)) {
  1378.     *q++ = '';
  1379.     while (*q && isspace(*q))
  1380. q++;
  1381. }
  1382. /*
  1383.  * Now p contains a segment name. Find it.
  1384.  */
  1385. for (seg = seghead; seg; seg = seg->next)
  1386.     if (!strcmp(seg->name, p))
  1387. break;
  1388. if (seg) {
  1389.     /*
  1390.      * We have a segment index. Shift a name entry
  1391.      * to the end of the array to make room.
  1392.      */
  1393.     grp->segs[grp->nentries++] = grp->segs[grp->nindices];
  1394.     grp->segs[grp->nindices++].index = seg->obj_index;
  1395.     if (seg->grp)
  1396. error(ERR_WARNING, "segment `%s' is already part of"
  1397.       " a group: first one takes precedence",
  1398.       seg->name);
  1399.     else
  1400. seg->grp = grp;
  1401. } else {
  1402.     /*
  1403.      * We have an as-yet undefined segment.
  1404.      * Remember its name, for later.
  1405.      */
  1406.     grp->segs[grp->nentries++].name = nasm_strdup(p);
  1407. }
  1408.     }
  1409.     /*
  1410.      * Walk through the list of externals with unresolved
  1411.      * default-WRT clauses, and resolve any that point at
  1412.      * this group.
  1413.      */
  1414.     extp = &dws;
  1415.     while (*extp) {
  1416. if ((*extp)->defwrt_type == DEFWRT_STRING &&
  1417.     !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
  1418.     nasm_free((*extp)->defwrt_ptr.string);
  1419.     (*extp)->defwrt_type = DEFWRT_GROUP;
  1420.     (*extp)->defwrt_ptr.grp = grp;
  1421.     *extp = (*extp)->next_dws;
  1422.     } else
  1423.     extp = &(*extp)->next_dws;
  1424.     }
  1425. }
  1426. return 1;
  1427.     }
  1428.     if (!strcmp(directive, "uppercase")) {
  1429. obj_uppercase = TRUE;
  1430. return 1;
  1431.     }
  1432.     if (!strcmp(directive, "import")) {
  1433. char *q, *extname, *libname, *impname;
  1434. if (pass == 2)
  1435.     return 1;        /* ignore in pass two */
  1436. extname = q = value;
  1437. while (*q && !isspace(*q))
  1438.     q++;
  1439. if (isspace(*q)) {
  1440.     *q++ = '';
  1441.     while (*q && isspace(*q))
  1442. q++;
  1443. }
  1444. libname = q;
  1445. while (*q && !isspace(*q))
  1446.     q++;
  1447. if (isspace(*q)) {
  1448.     *q++ = '';
  1449.     while (*q && isspace(*q))
  1450. q++;
  1451. }
  1452. impname = q;
  1453. if (!*extname || !*libname)
  1454.     error(ERR_NONFATAL, "`import' directive requires symbol name"
  1455.   " and library name");
  1456. else {
  1457.     struct ImpDef *imp;
  1458.     int err = FALSE;
  1459.     imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
  1460.     imptail = &imp->next;
  1461.     imp->next = NULL;
  1462.     imp->extname = nasm_strdup(extname);
  1463.     imp->libname = nasm_strdup(libname);
  1464.     imp->impindex = readnum(impname, &err);
  1465.     if (!*impname || err)
  1466. imp->impname = nasm_strdup(impname);
  1467.     else
  1468. imp->impname = NULL;
  1469. }
  1470. return 1;
  1471.     }
  1472.     if (!strcmp(directive, "export")) {
  1473. char *q, *extname, *intname, *v;
  1474. struct ExpDef *export;
  1475. int flags = 0;
  1476. unsigned int ordinal = 0;
  1477. if (pass == 2)
  1478.     return 1;        /* ignore in pass two */
  1479. intname = q = value;
  1480. while (*q && !isspace(*q))
  1481.     q++;
  1482. if (isspace(*q)) {
  1483.     *q++ = '';
  1484.     while (*q && isspace(*q))
  1485. q++;
  1486. }
  1487. extname = q;
  1488. while (*q && !isspace(*q))
  1489.     q++;
  1490. if (isspace(*q)) {
  1491.     *q++ = '';
  1492.     while (*q && isspace(*q))
  1493. q++;
  1494. }
  1495. if (!*intname) {
  1496.     error(ERR_NONFATAL, "`export' directive requires export name");
  1497.     return 1;
  1498. }
  1499. if (!*extname) {
  1500.     extname = intname;
  1501.     intname = "";
  1502. }
  1503. while (*q) {
  1504.     v = q;
  1505.     while (*q && !isspace(*q))
  1506. q++;
  1507.     if (isspace(*q)) {
  1508. *q++ = '';
  1509. while (*q && isspace(*q))
  1510.     q++;
  1511.     }
  1512.     if (!nasm_stricmp(v, "resident"))
  1513. flags |= EXPDEF_FLAG_RESIDENT;
  1514.     else if (!nasm_stricmp(v, "nodata"))
  1515. flags |= EXPDEF_FLAG_NODATA;
  1516.     else if (!nasm_strnicmp(v, "parm=", 5)) {
  1517. int err = FALSE;
  1518. flags |= EXPDEF_MASK_PARMCNT & readnum(v+5, &err);
  1519. if (err) {
  1520.     error(ERR_NONFATAL,
  1521.   "value `%s' for `parm' is non-numeric", v+5);
  1522.     return 1;
  1523. }
  1524.     } else {
  1525. int err = FALSE;
  1526. ordinal = readnum(v, &err);
  1527. if (err) {
  1528.     error(ERR_NONFATAL, "unrecognised export qualifier `%s'",
  1529.   v);
  1530.     return 1;
  1531. }
  1532. flags |= EXPDEF_FLAG_ORDINAL;
  1533.     }
  1534. }
  1535. export = *exptail = nasm_malloc(sizeof(struct ExpDef));
  1536. exptail = &export->next;
  1537. export->next = NULL;
  1538. export->extname = nasm_strdup(extname);
  1539. export->intname = nasm_strdup(intname);
  1540. export->ordinal = ordinal;
  1541. export->flags = flags;
  1542. return 1;
  1543.     }
  1544.     return 0;
  1545. }
  1546. static long obj_segbase (long segment) 
  1547. {
  1548.     struct Segment *seg;
  1549.     /*
  1550.      * Find the segment in our list.
  1551.      */
  1552.     for (seg = seghead; seg; seg = seg->next)
  1553. if (seg->index == segment-1)
  1554.     break;
  1555.     if (!seg) {
  1556. /*
  1557.  * Might be an external with a default WRT.
  1558.  */
  1559. long i = segment/2;
  1560. struct ExtBack *eb = ebhead;
  1561. struct External *e;
  1562. while (i > EXT_BLKSIZ) {
  1563.     if (eb)
  1564. eb = eb->next;
  1565.     else
  1566. break;
  1567.     i -= EXT_BLKSIZ;
  1568. }
  1569. if (eb) {
  1570.     e = eb->exts[i];
  1571.     if (e->defwrt_type == DEFWRT_NONE)
  1572. return segment;        /* fine */
  1573.     else if (e->defwrt_type == DEFWRT_SEGMENT)
  1574. return e->defwrt_ptr.seg->index+1;
  1575.     else if (e->defwrt_type == DEFWRT_GROUP)
  1576. return e->defwrt_ptr.grp->index+1;
  1577.     else
  1578. return NO_SEG;        /* can't tell what it is */
  1579. }
  1580. return segment;        /* not one of ours - leave it alone */
  1581.     }
  1582.     if (seg->align >= SEG_ABS)
  1583. return seg->align;        /* absolute segment */
  1584.     if (seg->grp)
  1585. return seg->grp->index+1;      /* grouped segment */
  1586.     return segment;        /* no special treatment */
  1587. }
  1588. static void obj_filename (char *inname, char *outname, efunc error) 
  1589. {
  1590.     strcpy(obj_infile, inname);
  1591.     standard_extension (inname, outname, ".obj", error);
  1592. }
  1593. static void obj_write_file (int debuginfo) 
  1594. {
  1595.     struct Segment *seg, *entry_seg_ptr = 0;
  1596.     struct FileName *fn;
  1597.     struct LineNumber *ln;
  1598.     struct Group *grp;
  1599.     struct Public *pub, *loc;
  1600.     struct External *ext;
  1601.     struct ImpDef *imp;
  1602.     struct ExpDef *export;
  1603.     static char boast[] = "The Netwide Assembler " NASM_VER;
  1604.     int lname_idx;
  1605.     ObjRecord *orp;
  1606.     /*
  1607.      * Write the THEADR module header.
  1608.      */
  1609.     orp = obj_new();
  1610.     orp->type = THEADR;
  1611.     obj_name (orp, obj_infile);
  1612.     obj_emit2 (orp);
  1613.     /*
  1614.      * Write the NASM boast comment.
  1615.      */
  1616.     orp->type = COMENT;
  1617.     obj_rword (orp, 0);   /* comment type zero */
  1618.     obj_name (orp, boast);
  1619.     obj_emit2 (orp);
  1620.     orp->type = COMENT;
  1621.     /*
  1622.      * Write the IMPDEF records, if any.
  1623.      */
  1624.     for (imp = imphead; imp; imp = imp->next) {
  1625. obj_rword (orp, 0xA0);   /* comment class A0 */
  1626. obj_byte (orp, 1);   /* subfunction 1: IMPDEF */
  1627. if (imp->impname)
  1628.     obj_byte (orp, 0);   /* import by name */
  1629. else
  1630.     obj_byte (orp, 1);   /* import by ordinal */
  1631. obj_name (orp, imp->extname);
  1632. obj_name (orp, imp->libname);
  1633. if (imp->impname)
  1634.     obj_name (orp, imp->impname);
  1635. else
  1636.     obj_word (orp, imp->impindex);
  1637. obj_emit2 (orp);
  1638.     }
  1639.     /*
  1640.      * Write the EXPDEF records, if any.
  1641.      */
  1642.     for (export = exphead; export; export = export->next) {
  1643. obj_rword (orp, 0xA0);   /* comment class A0 */
  1644. obj_byte (orp, 2);   /* subfunction 2: EXPDEF */
  1645. obj_byte (orp, export->flags);
  1646. obj_name (orp, export->extname);
  1647. obj_name (orp, export->intname);
  1648. if (export->flags & EXPDEF_FLAG_ORDINAL)
  1649.     obj_word (orp, export->ordinal);
  1650. obj_emit2 (orp);
  1651.     }
  1652.     /* we're using extended OMF if we put in debug info*/
  1653.     if (debuginfo) {
  1654.       orp->type = COMENT;
  1655.       obj_byte (orp, 0x40);
  1656.       obj_byte (orp, dEXTENDED);
  1657.       obj_emit2 (orp);
  1658.     }
  1659.     /*
  1660.      * Write the first LNAMES record, containing LNAME one, which
  1661.      * is null. Also initialise the LNAME counter.
  1662.      */
  1663.     orp->type = LNAMES;
  1664.     obj_byte (orp, 0);
  1665.     lname_idx = 1;
  1666.     /*
  1667.      * Write some LNAMES for the segment names
  1668.      */
  1669.     for (seg = seghead; seg; seg = seg->next) {
  1670. orp = obj_name (orp, seg->name);
  1671. if (seg->segclass)
  1672.     orp = obj_name (orp, seg->segclass);
  1673. if (seg->overlay)
  1674.     orp = obj_name (orp, seg->overlay);
  1675. obj_commit (orp);
  1676.     }
  1677.     /*
  1678.      * Write some LNAMES for the group names
  1679.      */
  1680.     for (grp = grphead; grp; grp = grp->next) {
  1681. orp = obj_name (orp, grp->name);
  1682. obj_commit (orp);
  1683.     }
  1684.     obj_emit (orp);
  1685.     /*
  1686.      * Write the SEGDEF records.
  1687.      */
  1688.     orp->type = SEGDEF;
  1689.     for (seg = seghead; seg; seg = seg->next) {
  1690. int acbp;
  1691. unsigned long seglen = seg->currentpos;
  1692. acbp = (seg->combine << 2);    /* C field */
  1693. if (seg->use32)
  1694.     acbp |= 0x01;        /* P bit is Use32 flag */
  1695. else if (seglen == 0x10000L) {
  1696.     seglen = 0;                /* This special case may be needed for old linkers */
  1697.     acbp |= 0x02;        /* B bit */
  1698. }
  1699. /* A field */
  1700. if (seg->align >= SEG_ABS)
  1701.     /* acbp |= 0x00 */;
  1702. else if (seg->align >= 4096) {
  1703.     if (seg->align > 4096)
  1704. error(ERR_NONFATAL, "segment `%s' requires more alignment"
  1705.       " than OBJ format supports", seg->name);
  1706.     acbp |= 0xC0;        /* PharLap extension */
  1707. } else if (seg->align >= 256) {
  1708.     acbp |= 0x80;
  1709. } else if (seg->align >= 16) {
  1710.     acbp |= 0x60;
  1711. } else if (seg->align >= 4) {
  1712.     acbp |= 0xA0;
  1713. } else if (seg->align >= 2) {
  1714.     acbp |= 0x40;
  1715. } else
  1716.     acbp |= 0x20;
  1717. obj_byte (orp, acbp);
  1718. if (seg->align & SEG_ABS) {
  1719.     obj_x (orp, seg->align - SEG_ABS);  /* Frame */
  1720.     obj_byte (orp, 0);  /* Offset */
  1721. }
  1722. obj_x (orp, seglen);
  1723. obj_index (orp, ++lname_idx);
  1724. obj_index (orp, seg->segclass ? ++lname_idx : 1);
  1725. obj_index (orp, seg->overlay ? ++lname_idx : 1);
  1726. obj_emit2 (orp);
  1727.     }
  1728.     /*
  1729.      * Write the GRPDEF records.
  1730.      */
  1731.     orp->type = GRPDEF;
  1732.     for (grp = grphead; grp; grp = grp->next) {
  1733. int i;
  1734. if (grp->nindices != grp->nentries) {
  1735.     for (i = grp->nindices; i < grp->nentries; i++) {
  1736. error(ERR_NONFATAL, "group `%s' contains undefined segment"
  1737.       " `%s'", grp->name, grp->segs[i].name);
  1738. nasm_free (grp->segs[i].name);
  1739. grp->segs[i].name = NULL;
  1740.     }
  1741. }
  1742. obj_index (orp, ++lname_idx);
  1743. for (i = 0; i < grp->nindices; i++) {
  1744.     obj_byte (orp, 0xFF);
  1745.     obj_index (orp, grp->segs[i].index);
  1746. }
  1747. obj_emit2 (orp);
  1748.     }
  1749.     /*
  1750.      * Write the PUBDEF records: first the ones in the segments,
  1751.      * then the far-absolutes.
  1752.      */
  1753.     orp->type = PUBDEF;
  1754.     orp->ori = ori_pubdef;
  1755.     for (seg = seghead; seg; seg = seg->next) {
  1756. orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
  1757. orp->parm[1] = seg->obj_index;
  1758. for (pub = seg->pubhead; pub; pub = pub->next) {
  1759.     orp = obj_name (orp, pub->name);
  1760.     orp = obj_x (orp, pub->offset);
  1761.     orp = obj_byte (orp, 0);  /* type index */
  1762.     obj_commit (orp);
  1763. }
  1764. obj_emit (orp);
  1765.     }
  1766.     orp->parm[0] = 0;
  1767.     orp->parm[1] = 0;
  1768.     for (pub = fpubhead; pub; pub = pub->next) {   /* pub-crawl :-) */
  1769. if (orp->parm[2] != pub->segment) {
  1770.     obj_emit (orp);
  1771.     orp->parm[2] = pub->segment;
  1772. }
  1773. orp = obj_name (orp, pub->name);
  1774. orp = obj_x (orp, pub->offset);
  1775. orp = obj_byte (orp, 0);  /* type index */
  1776. obj_commit (orp);
  1777.     }
  1778.     obj_emit (orp);
  1779.     /*
  1780.      * Write the EXTDEF and COMDEF records, in order.
  1781.      */
  1782.     orp->ori = ori_null;
  1783.     for (ext = exthead; ext; ext = ext->next) {
  1784. if (ext->commonsize == 0) {
  1785.     if (orp->type != EXTDEF) {
  1786. obj_emit (orp);
  1787. orp->type = EXTDEF;
  1788.     }
  1789.     orp = obj_name (orp, ext->name);
  1790.     orp = obj_index (orp, 0);
  1791. } else {
  1792.     if (orp->type != COMDEF) {
  1793. obj_emit (orp);
  1794. orp->type = COMDEF;
  1795.     }
  1796.     orp = obj_name (orp, ext->name);
  1797.     orp = obj_index (orp, 0);
  1798.     if (ext->commonelem) {
  1799. orp = obj_byte (orp, 0x61);/* far communal */
  1800. orp = obj_value (orp, (ext->commonsize / ext->commonelem));
  1801. orp = obj_value (orp, ext->commonelem);
  1802.     } else {
  1803. orp = obj_byte (orp, 0x62);/* near communal */
  1804. orp = obj_value (orp, ext->commonsize);
  1805.     }
  1806. }
  1807. obj_commit (orp);
  1808.     }
  1809.     obj_emit (orp);
  1810.     /*
  1811.      * Write a COMENT record stating that the linker's first pass
  1812.      * may stop processing at this point. Exception is if our
  1813.      * MODEND record specifies a start point, in which case,
  1814.      * according to some variants of the documentation, this COMENT
  1815.      * should be omitted. So we'll omit it just in case.
  1816.      * But, TASM puts it in all the time so if we are using
  1817.      * TASM debug stuff we are putting it in
  1818.      */
  1819.     if (debuginfo || obj_entry_seg == NO_SEG) {
  1820. orp->type = COMENT;
  1821.         obj_byte (orp, 0x40);
  1822.         obj_byte (orp, dLINKPASS);
  1823. obj_byte (orp, 1);
  1824. obj_emit2 (orp);
  1825.     } 
  1826.     /*
  1827.      * 1) put out the compiler type
  1828.      * 2) Put out the type info.  The only type we are using is near label #19
  1829.      */
  1830.     if (debuginfo) {
  1831.       int i;
  1832.       struct Array *arrtmp = arrhead;
  1833.       orp->type = COMENT;
  1834.       obj_byte (orp, 0x40);
  1835.       obj_byte (orp, dCOMPDEF);
  1836.       obj_byte (orp, 4);
  1837.       obj_byte (orp, 0);
  1838.       obj_emit2 (orp);
  1839.       obj_byte (orp, 0x40);
  1840.       obj_byte (orp, dTYPEDEF);
  1841.       obj_word (orp, 0x18); /* type # for linking */
  1842.       obj_word (orp, 6);    /* size of type */
  1843.       obj_byte (orp, 0x2a); /* absolute type for debugging */
  1844.       obj_emit2 (orp);
  1845.       obj_byte (orp, 0x40);
  1846.       obj_byte (orp, dTYPEDEF);
  1847.       obj_word (orp, 0x19); /* type # for linking */
  1848.       obj_word (orp, 0);    /* size of type */
  1849.       obj_byte (orp, 0x24); /* absolute type for debugging */
  1850.       obj_byte (orp, 0);    /* near/far specifier */
  1851.       obj_emit2 (orp);
  1852.       obj_byte (orp, 0x40);
  1853.       obj_byte (orp, dTYPEDEF);
  1854.       obj_word (orp, 0x1A); /* type # for linking */
  1855.       obj_word (orp, 0);    /* size of type */
  1856.       obj_byte (orp, 0x24); /* absolute type for debugging */
  1857.       obj_byte (orp, 1);    /* near/far specifier */
  1858.       obj_emit2 (orp);
  1859.       obj_byte (orp, 0x40);
  1860.       obj_byte (orp, dTYPEDEF);
  1861.       obj_word (orp, 0x1b); /* type # for linking */
  1862.       obj_word (orp, 0);    /* size of type */
  1863.       obj_byte (orp, 0x23); /* absolute type for debugging */
  1864.       obj_byte (orp, 0);
  1865.       obj_byte (orp, 0);
  1866.       obj_byte (orp, 0);
  1867.       obj_emit2 (orp);
  1868.       obj_byte (orp, 0x40);
  1869.       obj_byte (orp, dTYPEDEF);
  1870.       obj_word (orp, 0x1c); /* type # for linking */
  1871.       obj_word (orp, 0);    /* size of type */
  1872.       obj_byte (orp, 0x23); /* absolute type for debugging */
  1873.       obj_byte (orp, 0);
  1874.       obj_byte (orp, 4);
  1875.       obj_byte (orp, 0);
  1876.       obj_emit2 (orp);
  1877.       obj_byte (orp, 0x40);
  1878.       obj_byte (orp, dTYPEDEF);
  1879.       obj_word (orp, 0x1d); /* type # for linking */
  1880.       obj_word (orp, 0);    /* size of type */
  1881.       obj_byte (orp, 0x23); /* absolute type for debugging */
  1882.       obj_byte (orp, 0);
  1883.       obj_byte (orp, 1);
  1884.       obj_byte (orp, 0);
  1885.       obj_emit2 (orp);
  1886.       obj_byte (orp, 0x40);
  1887.       obj_byte (orp, dTYPEDEF);
  1888.       obj_word (orp, 0x1e); /* type # for linking */
  1889.       obj_word (orp, 0);    /* size of type */
  1890.       obj_byte (orp, 0x23); /* absolute type for debugging */
  1891.       obj_byte (orp, 0);
  1892.       obj_byte (orp, 5);
  1893.       obj_byte (orp, 0);
  1894.       obj_emit2 (orp);
  1895.       /* put out the array types */
  1896.       for (i= ARRAYBOT; i < arrindex; i++) {
  1897.         obj_byte (orp, 0x40);
  1898.        obj_byte (orp, dTYPEDEF);
  1899.        obj_word (orp, i ); /* type # for linking */
  1900.        obj_word (orp, arrtmp->size);    /* size of type */
  1901.        obj_byte (orp, 0x1A); /* absolute type for debugging (array)*/
  1902.        obj_byte (orp, arrtmp->basetype ); /* base type */
  1903.        obj_emit2 (orp);
  1904.         arrtmp = arrtmp->next ;
  1905.       }
  1906.     }
  1907.     /*
  1908.      * write out line number info with a LINNUM record
  1909.      * switch records when we switch segments, and output the
  1910.      * file in a pseudo-TASM fashion.  The record switch is naive; that
  1911.      * is that one file may have many records for the same segment
  1912.      * if there are lots of segment switches
  1913.      */
  1914.     if (fnhead && debuginfo) {
  1915.      seg = fnhead->lnhead->segment;
  1916.      for (fn = fnhead; fn; fn = fn->next) {
  1917.     /* write out current file name */
  1918.             orp->type = COMENT;
  1919.             orp->ori = ori_null;
  1920.     obj_byte (orp, 0x40);
  1921.     obj_byte (orp, dFILNAME);
  1922.             obj_byte( orp,0);
  1923.             obj_name( orp,fn->name);
  1924.             obj_dword(orp, 0);
  1925.     obj_emit2 (orp);
  1926.     /* write out line numbers this file */
  1927.             orp->type = LINNUM;
  1928.             orp->ori = ori_linnum;
  1929.     for (ln = fn->lnhead; ln; ln = ln->next) {
  1930. if (seg != ln->segment) {
  1931.     /* if we get here have to flush the buffer and start
  1932.                      * a new record for a new segment
  1933.      */
  1934.     seg = ln->segment;
  1935.     obj_emit ( orp );
  1936. }
  1937. orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
  1938. orp->parm[1] = seg->obj_index;
  1939.         orp = obj_word(orp, ln->lineno);
  1940.                 orp = obj_x(orp, ln->offset);
  1941.         obj_commit (orp);
  1942.     }
  1943.       obj_emit (orp);
  1944. }
  1945.     }
  1946.     /*
  1947.      * we are going to locate the entry point segment now
  1948.      * rather than wait until the MODEND record, because,
  1949.      * then we can output a special symbol to tell where the
  1950.      * entry point is.
  1951.      *
  1952.      */
  1953.     if (obj_entry_seg != NO_SEG) {
  1954. for (seg = seghead; seg; seg = seg->next) {
  1955.     if (seg->index == obj_entry_seg) {
  1956.                 entry_seg_ptr = seg;
  1957. break;
  1958.     }
  1959. }
  1960. if (!seg)
  1961.     error(ERR_NONFATAL, "entry point is not in this module");
  1962.     }
  1963.     /*
  1964.      * get ready to put out symbol records
  1965.      */
  1966.     orp->type = COMENT;
  1967.     orp->ori = ori_local;
  1968.    
  1969.     /*
  1970.      * put out a symbol for the entry point
  1971.      * no dots in this symbol, because, borland does
  1972.      * not (officially) support dots in label names
  1973.      * and I don't know what various versions of TLINK will do
  1974.      */
  1975.     if (debuginfo && obj_entry_seg != NO_SEG) {
  1976.         orp = obj_name (orp,"start_of_program");
  1977. orp = obj_word (orp,0x19);  /* type: near label */
  1978. orp = obj_index (orp, seg->grp ? seg->grp->obj_index : 0);
  1979. orp = obj_index (orp, seg->obj_index);
  1980. orp = obj_x (orp, obj_entry_ofs);
  1981. obj_commit (orp);
  1982.     } 
  1983.  
  1984.     /*
  1985.      * put out the local labels
  1986.      */
  1987.     for (seg = seghead; seg && debuginfo; seg = seg->next) {
  1988.         /* labels this seg */
  1989.         for (loc = seg->lochead; loc; loc = loc->next) {
  1990.             orp = obj_name (orp,loc->name);
  1991.     orp = obj_word (orp, loc->type);
  1992.     orp = obj_index (orp, seg->grp ? seg->grp->obj_index : 0);
  1993.     orp = obj_index (orp, seg->obj_index);
  1994.     orp = obj_x (orp,loc->offset);
  1995.     obj_commit (orp);
  1996.         }
  1997.     }
  1998.     if (orp->used)
  1999.      obj_emit (orp);
  2000.     /*
  2001.      * Write the LEDATA/FIXUPP pairs.
  2002.      */
  2003.     for (seg = seghead; seg; seg = seg->next) {
  2004. obj_emit (seg->orp);
  2005. nasm_free (seg->orp);
  2006.     }
  2007.     /*
  2008.      * Write the MODEND module end marker.
  2009.      */
  2010.     orp->type = MODEND;
  2011.     orp->ori = ori_null;
  2012.     if (entry_seg_ptr) {
  2013. obj_byte (orp, 0xC1);
  2014. seg = entry_seg_ptr;
  2015. if (seg->grp) {
  2016.     obj_byte (orp, 0x10);
  2017.     obj_index (orp, seg->grp->obj_index);
  2018. } else {
  2019.     /*
  2020.      * the below changed to prevent TLINK crashing.
  2021.      * Previous more efficient version read:
  2022.      *
  2023.      *  obj_byte (orp, 0x50);
  2024.      */
  2025.     obj_byte (orp, 0x00);
  2026.     obj_index (orp, seg->obj_index);
  2027. }
  2028. obj_index (orp, seg->obj_index);
  2029. obj_x (orp, obj_entry_ofs);
  2030.     } else
  2031. obj_byte (orp, 0);
  2032.     obj_emit2 (orp);
  2033.     nasm_free (orp);
  2034. }
  2035. void obj_fwrite(ObjRecord *orp) 
  2036. {
  2037.     unsigned int cksum, len;
  2038.     unsigned char *ptr;
  2039.     cksum = orp->type;
  2040.     if (orp->x_size == 32)
  2041. cksum |= 1;
  2042.     fputc (cksum, ofp);
  2043.     len = orp->committed+1;
  2044.     cksum += (len & 0xFF) + ((len>>8) & 0xFF);
  2045.     fwriteshort (len, ofp);
  2046.     fwrite (orp->buf, 1, len-1, ofp);
  2047.     for (ptr=orp->buf; --len; ptr++)
  2048. cksum += *ptr;
  2049.     fputc ( (-cksum) & 0xFF, ofp);
  2050. }
  2051. static char *obj_stdmac[] = {
  2052.     "%define __SECT__ [section .text]",
  2053.     "%imacro group 1+.nolist",
  2054.     "[group %1]",
  2055.     "%endmacro",
  2056.     "%imacro uppercase 0+.nolist",
  2057.     "[uppercase %1]",
  2058.     "%endmacro",
  2059.     "%imacro export 1+.nolist",
  2060.     "[export %1]",
  2061.     "%endmacro",
  2062.     "%imacro import 1+.nolist",
  2063.     "[import %1]",
  2064.     "%endmacro",
  2065.     "%macro __NASM_CDecl__ 1",
  2066.     "%endmacro",
  2067.     NULL
  2068. };
  2069. void dbgbi_init(struct ofmt * of, void * id, FILE * fp, efunc error)
  2070. {
  2071.     (void) of;
  2072.     (void) id;
  2073.     (void) fp;
  2074.     (void) error;
  2075.     fnhead = NULL;
  2076.     fntail = &fnhead;
  2077.     arrindex = ARRAYBOT ;
  2078.     arrhead = NULL;
  2079.     arrtail = &arrhead;
  2080. }
  2081. static void dbgbi_cleanup(void)
  2082. {
  2083.     struct Segment *segtmp;
  2084.     while (fnhead) {
  2085. struct FileName *fntemp = fnhead;
  2086. while (fnhead->lnhead) {
  2087.     struct LineNumber *lntemp = fnhead->lnhead;
  2088.     fnhead->lnhead = lntemp->next;
  2089.     nasm_free( lntemp);
  2090. }
  2091. fnhead = fnhead->next;
  2092. nasm_free (fntemp->name);
  2093. nasm_free (fntemp);
  2094.     }
  2095.     for (segtmp=seghead; segtmp; segtmp=segtmp->next) {
  2096. while (segtmp->lochead) {
  2097.     struct Public *loctmp = segtmp->lochead;
  2098.     segtmp->lochead = loctmp->next;
  2099.     nasm_free (loctmp->name);
  2100.     nasm_free (loctmp);
  2101. }
  2102.     }
  2103.     while (arrhead) {
  2104. struct Array *arrtmp = arrhead;
  2105.         arrhead = arrhead->next;
  2106.         nasm_free (arrtmp);
  2107.     }
  2108. }
  2109. static void dbgbi_linnum (const char *lnfname, long lineno, long segto)
  2110. {
  2111.     struct FileName *fn;
  2112.     struct LineNumber *ln;
  2113.     struct Segment *seg;
  2114.     if (segto == NO_SEG)
  2115. return;
  2116.     /*
  2117.      * If `any_segs' is still FALSE, we must define a default
  2118.      * segment.
  2119.      */
  2120.     if (!any_segs) {
  2121. int tempint;        /* ignored */
  2122. if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
  2123.     error (ERR_PANIC, "strange segment conditions in OBJ driver");
  2124.     }
  2125.     /*
  2126.      * Find the segment we are targetting.
  2127.      */
  2128.     for (seg = seghead; seg; seg = seg->next)
  2129. if (seg->index == segto)
  2130.     break;
  2131.     if (!seg)
  2132. error (ERR_PANIC, "lineno directed to nonexistent segment?");
  2133.     for (fn = fnhead; fn; fn = fnhead->next)
  2134. if (!nasm_stricmp(lnfname,fn->name))
  2135.     break;
  2136.     if (!fn) {
  2137. fn = nasm_malloc ( sizeof( *fn));
  2138. fn->name = nasm_malloc ( strlen(lnfname) + 1) ;
  2139.         strcpy (fn->name,lnfname);
  2140. fn->lnhead = NULL;
  2141. fn->lntail = & fn->lnhead;
  2142. fn->next = NULL;
  2143. *fntail = fn;
  2144. fntail = &fn->next;
  2145.     }
  2146.     ln = nasm_malloc ( sizeof( *ln));
  2147.     ln->segment = seg;
  2148.     ln->offset = seg->currentpos;
  2149.     ln->lineno = lineno;
  2150.     ln->next = NULL;
  2151.     *fn->lntail = ln;
  2152.     fn->lntail = &ln->next;
  2153. }
  2154. static void dbgbi_deflabel (char *name, long segment,
  2155.   long offset, int is_global, char *special) 
  2156. {
  2157.     struct Segment *seg;
  2158.     (void) special;
  2159.     /*
  2160.      * If it's a special-retry from pass two, discard it.
  2161.      */
  2162.     if (is_global == 3)
  2163. return;
  2164.     /*
  2165.      * First check for the double-period, signifying something
  2166.      * unusual.
  2167.      */
  2168.     if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  2169. return;
  2170.     }
  2171.     /*
  2172.      * Case (i):
  2173.      */
  2174.     if (obj_seg_needs_update) {
  2175. return;
  2176.     } else if (obj_grp_needs_update) {
  2177. return;
  2178.     }
  2179.     if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
  2180. return;
  2181.     if (segment >= SEG_ABS || segment == NO_SEG) {
  2182. return;
  2183.     }
  2184.     /*
  2185.      * If `any_segs' is still FALSE, we might need to define a
  2186.      * default segment, if they're trying to declare a label in
  2187.      * `first_seg'.  But the label should exist due to a prior
  2188.      * call to obj_deflabel so we can skip that.
  2189.      */
  2190.     for (seg = seghead; seg; seg = seg->next)
  2191. if (seg->index == segment) {
  2192.     struct Public *loc = nasm_malloc (sizeof(*loc));
  2193.     /*
  2194.      * Case (ii). Maybe MODPUB someday?
  2195.      */
  2196.     last_defined = *seg->loctail = loc;
  2197.     seg->loctail = &loc->next;
  2198.     loc->next = NULL;
  2199.     loc->name = nasm_strdup(name);
  2200.     loc->offset = offset;
  2201. }
  2202. }
  2203. static void dbgbi_typevalue (long type)
  2204. {
  2205.     int vsize;
  2206.     int elem = TYM_ELEMENTS(type);
  2207.     type = TYM_TYPE(type);
  2208.     if (!last_defined)
  2209. return;
  2210.     switch (type) {
  2211. case TY_BYTE:
  2212.     last_defined->type = 8; /* unsigned char */
  2213.     vsize = 1;
  2214.     break;
  2215. case TY_WORD:
  2216.     last_defined->type = 10; /* unsigned word */
  2217.     vsize = 2;
  2218.     break;
  2219. case TY_DWORD:
  2220.     last_defined->type = 12; /* unsigned dword */
  2221.     vsize = 4;
  2222.     break;
  2223. case TY_FLOAT:
  2224.     last_defined->type = 14; /* float */
  2225.     vsize = 4;
  2226.     break;
  2227. case TY_QWORD:
  2228.     last_defined->type = 15; /* qword */
  2229.     vsize = 8;
  2230.     break;
  2231. case TY_TBYTE:
  2232.     last_defined->type = 16; /* TBYTE */
  2233.     vsize = 10;
  2234.     break;
  2235. default:
  2236.     last_defined->type = 0x19; /*label */
  2237.     vsize = 0;
  2238.     break;
  2239.     }
  2240.                 
  2241.     if (elem > 1) {
  2242.         struct Array *arrtmp = nasm_malloc (sizeof(*arrtmp));
  2243.         int vtype = last_defined->type;
  2244.         arrtmp->size = vsize * elem;
  2245.         arrtmp->basetype = vtype;
  2246.         arrtmp->next = NULL;
  2247.         last_defined->type = arrindex++;
  2248.         *arrtail = arrtmp;
  2249.         arrtail = & (arrtmp->next);
  2250.     }
  2251.     last_defined = NULL;
  2252. }
  2253. static void dbgbi_output (int output_type, void *param)
  2254. {
  2255.     (void) output_type;
  2256.     (void) param;
  2257. }
  2258. static struct dfmt borland_debug_form = {
  2259.     "Borland Debug Records",
  2260.     "borland",
  2261.     dbgbi_init,
  2262.     dbgbi_linnum,
  2263.     dbgbi_deflabel,
  2264.     null_debug_routine,
  2265.     dbgbi_typevalue,
  2266.     dbgbi_output,
  2267.     dbgbi_cleanup,
  2268. };
  2269. static struct dfmt *borland_debug_arr[3] = {
  2270. &borland_debug_form,
  2271. &null_debug_form,
  2272. NULL
  2273. };
  2274. struct ofmt of_obj = {
  2275.     "MS-DOS 16-bit/32-bit OMF object files",
  2276.     "obj",
  2277.     NULL,
  2278.     borland_debug_arr,
  2279.     &null_debug_form,
  2280.     obj_stdmac,
  2281.     obj_init,
  2282.     obj_set_info,
  2283.     obj_out,
  2284.     obj_deflabel,
  2285.     obj_segment,
  2286.     obj_segbase,
  2287.     obj_directive,
  2288.     obj_filename,
  2289.     obj_cleanup
  2290. };
  2291. #endif /* OF_OBJ */