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