Fix off-by-one error found when running theowl's test cases.
[nasm/autotest.git] / output / outobj.c
blob65a1107f4d8bbcb40c91443c8f059d76487d9386
1 /* outobj.c output routines for the Netwide Assembler to produce
2 * .OBJ object files
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 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <ctype.h>
15 #include "nasm.h"
16 #include "nasmlib.h"
17 #include "outform.h"
19 #ifdef OF_OBJ
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.
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.
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.
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.
42 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
43 * is cleared by obj_clear.
45 * 2) The caller should fill in .type.
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.
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.
57 * 5) If the .ori field was used then the caller should fill in the .parm with
58 * any data required by the initializer.
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.
64 * 7) If the record is continuable, the caller should call obj_commit at each
65 * point where breaking the record is permitted.
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.
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.
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 */
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
90 enum RecordID { /* record ID codes */
92 THEADR = 0x80, /* module header */
93 COMENT = 0x88, /* comment record */
95 LINNUM = 0x94, /* line number record */
96 LNAMES = 0x96, /* list of names */
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 */
104 LEDATA = 0xA0, /* logical enumerated data */
105 FIXUPP = 0x9C, /* fixups (relocations) */
106 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
108 MODEND = 0x8A, /* module end */
109 MODE32 = 0x8B /* module end for 32-bit objects */
112 enum ComentID { /* ID codes for comment records */
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 */
123 typedef struct ObjRecord ObjRecord;
124 typedef void ORI(ObjRecord *orp);
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+3];
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);
145 static int obj_uppercase; /* Flag: all names in uppercase */
146 static int obj_use32; /* Flag: at least one segment is 32-bit */
149 * Clear an ObjRecord structure. (Never reallocates).
150 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
152 static ObjRecord *obj_clear(ObjRecord *orp)
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);
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.
170 static ObjRecord *obj_emit(ObjRecord *orp)
172 if (orp->back) {
173 obj_emit(orp->back);
174 nasm_free(orp->back);
177 if (orp->committed)
178 obj_fwrite(orp);
180 if (orp->child) {
181 obj_emit(orp->child);
182 nasm_free(orp->child);
185 return (obj_clear(orp));
189 * Commit and Emit a record. (Never reallocates).
191 static ObjRecord *obj_emit2(ObjRecord *orp)
193 obj_commit(orp);
194 return (obj_emit(orp));
198 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
200 static ObjRecord *obj_new(void)
202 ObjRecord *orp;
204 orp = obj_clear( nasm_malloc(sizeof(ObjRecord)) );
205 orp->ori = ori_null;
206 return (orp);
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.
214 static ObjRecord *obj_bump(ObjRecord *orp)
216 ObjRecord *nxt;
217 int used = orp->used;
218 int committed = orp->committed;
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);
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;
239 return (nxt);
243 * Advance to the next record if necessary to allow the next field to fit.
245 static ObjRecord *obj_check(ObjRecord *orp, int size)
247 if (orp->used + size > RECORD_MAX)
248 orp = obj_bump(orp);
250 if (!orp->committed) {
251 orp->committed = 1;
252 orp->ori (orp);
253 orp->committed = orp->used;
256 return (orp);
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).
263 static ObjRecord *obj_commit(ObjRecord *orp)
265 orp->committed = orp->used;
266 return (orp);
270 * Write a byte
272 static ObjRecord *obj_byte(ObjRecord *orp, unsigned char val)
274 orp = obj_check(orp, 1);
275 orp->buf[orp->used] = val;
276 orp->used++;
277 return (orp);
281 * Write a word
283 static ObjRecord *obj_word(ObjRecord *orp, unsigned int val)
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);
293 * Write a reversed word
295 static ObjRecord *obj_rword(ObjRecord *orp, unsigned int val)
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);
305 * Write a dword
307 static ObjRecord *obj_dword(ObjRecord *orp, unsigned long val)
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);
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.
328 static ObjRecord *obj_force(ObjRecord *orp, int x)
330 if (orp->x_size == (x^48))
331 orp = obj_bump(orp);
332 orp->x_size = x;
333 return (orp);
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.
340 static ObjRecord *obj_x(ObjRecord *orp, unsigned long val)
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));
353 * Writes an index
355 static ObjRecord *obj_index(ObjRecord *orp, unsigned int val)
357 if (val < 128)
358 return ( obj_byte(orp, val) );
359 return (obj_word(orp, (val>>8) | (val<<8) | 0x80));
363 * Writes a variable length value
365 static ObjRecord *obj_value(ObjRecord *orp, unsigned long val)
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) );
373 if (val <= 0xFFFFFF)
374 return ( obj_dword(orp, (val<<8) + 132 ) );
375 orp = obj_byte(orp, 136);
376 return ( obj_dword(orp, val) );
380 * Writes a counted string
382 static ObjRecord *obj_name(ObjRecord *orp, char *name)
384 int len = strlen(name);
385 unsigned char *ptr;
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);
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.
409 static void ori_ledata(ObjRecord *orp)
411 obj_index (orp, orp->parm[1]);
412 orp->parm[2] = orp->parm[0];
413 obj_x (orp, orp->parm[0]);
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)
422 static void ori_pubdef(ObjRecord *orp)
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]);
431 * Initializer for a LINNUM record.
432 * parm[0] = group index
433 * parm[1] = segment index
435 static void ori_linnum(ObjRecord *orp)
437 obj_index (orp, orp->parm[0]);
438 obj_index (orp, orp->parm[1]);
441 * Initializer for a local vars record.
443 static void ori_local(ObjRecord *orp)
445 obj_byte (orp, 0x40);
446 obj_byte (orp, dSYM);
450 * Null initializer for records that continue without any header info
452 static void ori_null(ObjRecord *orp)
454 (void) orp; /* Do nothing */
458 * This concludes the low level section of outobj.c
461 static char obj_infile[FILENAME_MAX];
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;
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 */
476 struct Segment; /* need to know these structs exist */
477 struct Group;
479 struct LineNumber {
480 struct LineNumber *next;
481 struct Segment *segment;
482 long offset;
483 long lineno;
486 static struct FileName {
487 struct FileName *next;
488 char *name;
489 struct LineNumber *lnhead, **lntail;
490 int index;
491 } *fnhead, **fntail;
493 static struct Array {
494 struct Array *next;
495 unsigned size;
496 int basetype;
497 } *arrhead, **arrtail;
499 #define ARRAYBOT 31 /* magic number for first array index */
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;
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;
530 static int externals;
532 static struct ExtBack {
533 struct ExtBack *next;
534 struct External *exts[EXT_BLKSIZ];
535 } *ebhead, **ebtail;
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;
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;
570 static struct ImpDef {
571 struct ImpDef *next;
572 char *extname;
573 char *libname;
574 unsigned int impindex;
575 char *impname;
576 } *imphead, **imptail;
578 static struct ExpDef {
579 struct ExpDef *next;
580 char *intname;
581 char *extname;
582 unsigned int ordinal;
583 int flags;
584 } *exphead, **exptail;
586 #define EXPDEF_FLAG_ORDINAL 0x80
587 #define EXPDEF_FLAG_RESIDENT 0x40
588 #define EXPDEF_FLAG_NODATA 0x20
589 #define EXPDEF_MASK_PARMCNT 0x1F
591 static long obj_entry_seg, obj_entry_ofs;
593 struct ofmt of_obj;
595 /* The current segment */
596 static struct Segment *current_seg;
598 static long obj_segment (char *, int, int *);
599 static void obj_write_file(int debuginfo);
600 static int obj_directive (char *, char *, int);
602 static void obj_init (FILE *fp, efunc errfunc, ldfunc ldef, evalfunc eval)
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;
632 of_obj.current_dfmt->init (&of_obj,NULL,fp,errfunc);
635 static int obj_set_info(enum geninfo type, char **val)
637 (void) type;
638 (void) val;
640 return 0;
642 static void obj_cleanup (int debuginfo)
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);
656 nasm_free (segtmp->segclass);
657 nasm_free (segtmp->overlay);
658 nasm_free (segtmp);
660 while (fpubhead) {
661 struct Public *pubtmp = fpubhead;
662 fpubhead = fpubhead->next;
663 nasm_free (pubtmp->name);
664 nasm_free (pubtmp);
666 while (exthead) {
667 struct External *exttmp = exthead;
668 exthead = exthead->next;
669 nasm_free (exttmp);
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);
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);
686 while (ebhead) {
687 struct ExtBack *ebtmp = ebhead;
688 ebhead = ebhead->next;
689 nasm_free (ebtmp);
691 while (grphead) {
692 struct Group *grptmp = grphead;
693 grphead = grphead->next;
694 nasm_free (grptmp);
698 static void obj_ext_set_defwrt (struct External *ext, char *id)
700 struct Segment *seg;
701 struct Group *grp;
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;
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;
719 ext->defwrt_type = DEFWRT_STRING;
720 ext->defwrt_ptr.string = id;
721 ext->next_dws = dws;
722 dws = ext;
725 static void obj_deflabel (char *name, long segment,
726 long offset, int is_global, char *special)
729 * We have three cases:
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.
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.)
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.
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? */
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
756 * If it's a special-retry from pass two, discard it.
758 if (is_global == 3)
759 return;
762 * First check for the double-period, signifying something
763 * unusual.
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;
771 error (ERR_NONFATAL, "unrecognised special symbol `%s'", name);
775 * Case (i):
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;
784 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
785 return;
787 if (segment >= SEG_ABS || segment == NO_SEG) {
789 * SEG_ABS subcase of (ii).
791 if (is_global) {
792 struct Public *pub;
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);
801 if (special)
802 error(ERR_NONFATAL, "OBJ supports no special symbol features"
803 " for this symbol type");
804 return;
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'.
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");
818 for (seg = seghead; seg && is_global; seg = seg->next)
819 if (seg->index == segment) {
820 struct Public *loc = nasm_malloc (sizeof(*loc));
822 * Case (ii). Maybe MODPUB someday?
824 *seg->pubtail = loc;
825 seg->pubtail = &loc->next;
826 loc->next = NULL;
827 loc->name = nasm_strdup(name);
828 loc->offset = offset;
830 if (special)
831 error(ERR_NONFATAL, "OBJ supports no special symbol features"
832 " for this symbol type");
833 return;
837 * Case (iii).
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;
847 /* 28-Apr-2002 - John Coffman
848 The following code was introduced on 12-Aug-2000, and breaks fixups
849 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
850 (5.10). It was introduced after FIXUP32 was added, and may be needed
851 for 32-bit segments. The following will get 16-bit segments working
852 again, and maybe someone can correct the 'if' condition which is
853 actually needed.
855 #if 0
856 if (current_seg) {
857 #else
858 if (current_seg && current_seg->use32) {
859 if (current_seg->grp) {
860 ext->defwrt_type = DEFWRT_GROUP;
861 ext->defwrt_ptr.grp = current_seg->grp;
862 } else {
863 ext->defwrt_type = DEFWRT_SEGMENT;
864 ext->defwrt_ptr.seg = current_seg;
867 #endif
869 if (is_global == 2) {
870 ext->commonsize = offset;
871 ext->commonelem = 1; /* default FAR */
872 } else
873 ext->commonsize = 0;
875 else
876 return;
879 * Now process the special text, if any, to find default-WRT
880 * specifications and common-variable element-size and near/far
881 * specifications.
883 while (special && *special) {
884 used_special = TRUE;
887 * We might have a default-WRT specification.
889 if (!nasm_strnicmp(special, "wrt", 3)) {
890 char *p;
891 int len;
892 special += 3;
893 special += strspn(special, " \t");
894 p = nasm_strndup(special, len = strcspn(special, ":"));
895 obj_ext_set_defwrt (ext, p);
896 special += len;
897 if (*special && *special != ':')
898 error(ERR_NONFATAL, "`:' expected in special symbol"
899 " text for `%s'", ext->name);
900 else if (*special == ':')
901 special++;
905 * The NEAR or FAR keywords specify nearness or
906 * farness. FAR gives default element size 1.
908 if (!nasm_strnicmp(special, "far", 3)) {
909 if (ext->commonsize)
910 ext->commonelem = 1;
911 else
912 error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"
913 " to common variables\n", ext->name);
914 special += 3;
915 special += strspn(special, " \t");
916 } else if (!nasm_strnicmp(special, "near", 4)) {
917 if (ext->commonsize)
918 ext->commonelem = 0;
919 else
920 error(ERR_NONFATAL, "`%s': `far' keyword may only be applied"
921 " to common variables\n", ext->name);
922 special += 4;
923 special += strspn(special, " \t");
927 * If it's a common, and anything else remains on the line
928 * before a further colon, evaluate it as an expression and
929 * use that as the element size. Forward references aren't
930 * allowed.
932 if (*special == ':')
933 special++;
934 else if (*special) {
935 if (ext->commonsize) {
936 expr *e;
937 struct tokenval tokval;
939 stdscan_reset();
940 stdscan_bufptr = special;
941 tokval.t_type = TOKEN_INVALID;
942 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
943 if (e) {
944 if (!is_simple(e))
945 error (ERR_NONFATAL, "cannot use relocatable"
946 " expression as common-variable element size");
947 else
948 ext->commonelem = reloc_value(e);
950 special = stdscan_bufptr;
951 } else {
952 error (ERR_NONFATAL, "`%s': element-size specifications only"
953 " apply to common variables", ext->name);
954 while (*special && *special != ':')
955 special++;
956 if (*special == ':')
957 special++;
962 i = segment/2;
963 eb = ebhead;
964 if (!eb) {
965 eb = *ebtail = nasm_malloc(sizeof(*eb));
966 eb->next = NULL;
967 ebtail = &eb->next;
969 while (i >= EXT_BLKSIZ) {
970 if (eb && eb->next)
971 eb = eb->next;
972 else {
973 eb = *ebtail = nasm_malloc(sizeof(*eb));
974 eb->next = NULL;
975 ebtail = &eb->next;
977 i -= EXT_BLKSIZ;
979 eb->exts[i] = ext;
980 ext->index = ++externals;
982 if (special && !used_special)
983 error(ERR_NONFATAL, "OBJ supports no special symbol features"
984 " for this symbol type");
987 /* forward declaration */
988 static void obj_write_fixup (ObjRecord *orp, int bytes,
989 int segrel, long seg, long wrt, struct Segment *segto);
991 static void obj_out (long segto, void *data, unsigned long type,
992 long segment, long wrt)
994 unsigned long size, realtype;
995 unsigned char *ucdata;
996 long ldata;
997 struct Segment *seg;
998 ObjRecord *orp;
1001 * handle absolute-assembly (structure definitions)
1003 if (segto == NO_SEG) {
1004 if ((type & OUT_TYPMASK) != OUT_RESERVE)
1005 error (ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1006 " space");
1007 return;
1011 * If `any_segs' is still FALSE, we must define a default
1012 * segment.
1014 if (!any_segs) {
1015 int tempint; /* ignored */
1016 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1017 error (ERR_PANIC, "strange segment conditions in OBJ driver");
1021 * Find the segment we are targetting.
1023 for (seg = seghead; seg; seg = seg->next)
1024 if (seg->index == segto)
1025 break;
1026 if (!seg)
1027 error (ERR_PANIC, "code directed to nonexistent segment?");
1029 orp = seg->orp;
1030 orp->parm[0] = seg->currentpos;
1032 size = type & OUT_SIZMASK;
1033 realtype = type & OUT_TYPMASK;
1034 if (realtype == OUT_RAWDATA) {
1035 ucdata = data;
1036 while (size > 0) {
1037 unsigned int len;
1038 orp = obj_check(seg->orp, 1);
1039 len = RECORD_MAX - orp->used;
1040 if (len > size)
1041 len = size;
1042 memcpy (orp->buf+orp->used, ucdata, len);
1043 orp->committed = orp->used += len;
1044 orp->parm[0] = seg->currentpos += len;
1045 ucdata += len;
1046 size -= len;
1049 else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
1050 realtype == OUT_REL4ADR)
1052 int rsize;
1054 if (segment == NO_SEG && realtype != OUT_ADDRESS)
1055 error(ERR_NONFATAL, "relative call to absolute address not"
1056 " supported by OBJ format");
1057 if (segment >= SEG_ABS)
1058 error(ERR_NONFATAL, "far-absolute relocations not supported"
1059 " by OBJ format");
1060 ldata = *(long *)data;
1061 if (realtype == OUT_REL2ADR) {
1062 ldata += (size-2);
1063 size = 2;
1065 if (realtype == OUT_REL4ADR) {
1066 ldata += (size-4);
1067 size = 4;
1069 if (size == 2)
1070 orp = obj_word (orp, ldata);
1071 else
1072 orp = obj_dword (orp, ldata);
1073 rsize = size;
1074 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1075 size == 4) {
1077 * This is a 4-byte segment-base relocation such as
1078 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1079 * these, but if the constant term has the 16 low bits
1080 * zero, we can just apply a 2-byte segment-base
1081 * relocation to the low word instead.
1083 rsize = 2;
1084 if (ldata & 0xFFFF)
1085 error(ERR_NONFATAL, "OBJ format cannot handle complex"
1086 " dword-size segment base references");
1088 if (segment != NO_SEG)
1089 obj_write_fixup (orp, rsize,
1090 (realtype == OUT_ADDRESS ? 0x4000 : 0),
1091 segment, wrt, seg);
1092 seg->currentpos += size;
1093 } else if (realtype == OUT_RESERVE) {
1094 if (orp->committed)
1095 orp = obj_bump(orp);
1096 seg->currentpos += size;
1098 obj_commit(orp);
1101 static void obj_write_fixup (ObjRecord *orp, int bytes,
1102 int segrel, long seg, long wrt, struct Segment *segto)
1104 int locat, method;
1105 int base;
1106 long tidx, fidx;
1107 struct Segment *s = NULL;
1108 struct Group *g = NULL;
1109 struct External *e = NULL;
1110 ObjRecord *forp;
1112 if (bytes == 1) {
1113 error(ERR_NONFATAL, "`obj' output driver does not support"
1114 " one-byte relocations");
1115 return;
1118 forp = orp->child;
1119 if (forp == NULL) {
1120 orp->child = forp = obj_new();
1121 forp->up = &(orp->child);
1122 /* We should choose between FIXUPP and FIXU32 record type */
1123 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1124 if (segto->use32)
1125 forp->type = FIXU32;
1126 else
1127 forp->type = FIXUPP;
1130 if (seg % 2) {
1131 base = TRUE;
1132 locat = FIX_16_SELECTOR;
1133 seg--;
1134 if (bytes != 2)
1135 error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1136 " through sanity check");
1138 else {
1139 base = FALSE;
1140 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1141 if (!segrel)
1143 * There is a bug in tlink that makes it process self relative
1144 * fixups incorrectly if the x_size doesn't match the location
1145 * size.
1147 forp = obj_force(forp, bytes<<3);
1150 forp = obj_rword (forp, locat | segrel | (orp->parm[0]-orp->parm[2]));
1152 tidx = fidx = -1, method = 0; /* placate optimisers */
1155 * See if we can find the segment ID in our segment list. If
1156 * so, we have a T4 (LSEG) target.
1158 for (s = seghead; s; s = s->next)
1159 if (s->index == seg)
1160 break;
1161 if (s)
1162 method = 4, tidx = s->obj_index;
1163 else {
1164 for (g = grphead; g; g = g->next)
1165 if (g->index == seg)
1166 break;
1167 if (g)
1168 method = 5, tidx = g->obj_index;
1169 else {
1170 long i = seg/2;
1171 struct ExtBack *eb = ebhead;
1172 while (i > EXT_BLKSIZ) {
1173 if (eb)
1174 eb = eb->next;
1175 else
1176 break;
1177 i -= EXT_BLKSIZ;
1179 if (eb)
1180 method = 6, e = eb->exts[i], tidx = e->index;
1181 else
1182 error(ERR_PANIC,
1183 "unrecognised segment value in obj_write_fixup");
1188 * If no WRT given, assume the natural default, which is method
1189 * F5 unless:
1191 * - we are doing an OFFSET fixup for a grouped segment, in
1192 * which case we require F1 (group).
1194 * - we are doing an OFFSET fixup for an external with a
1195 * default WRT, in which case we must honour the default WRT.
1197 if (wrt == NO_SEG) {
1198 if (!base && s && s->grp)
1199 method |= 0x10, fidx = s->grp->obj_index;
1200 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1201 if (e->defwrt_type == DEFWRT_SEGMENT)
1202 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1203 else if (e->defwrt_type == DEFWRT_GROUP)
1204 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1205 else {
1206 error(ERR_NONFATAL, "default WRT specification for"
1207 " external `%s' unresolved", e->name);
1208 method |= 0x50, fidx = -1; /* got to do _something_ */
1210 } else
1211 method |= 0x50, fidx = -1;
1212 } else {
1214 * See if we can find the WRT-segment ID in our segment
1215 * list. If so, we have a F0 (LSEG) frame.
1217 for (s = seghead; s; s = s->next)
1218 if (s->index == wrt-1)
1219 break;
1220 if (s)
1221 method |= 0x00, fidx = s->obj_index;
1222 else {
1223 for (g = grphead; g; g = g->next)
1224 if (g->index == wrt-1)
1225 break;
1226 if (g)
1227 method |= 0x10, fidx = g->obj_index;
1228 else {
1229 long i = wrt/2;
1230 struct ExtBack *eb = ebhead;
1231 while (i > EXT_BLKSIZ) {
1232 if (eb)
1233 eb = eb->next;
1234 else
1235 break;
1236 i -= EXT_BLKSIZ;
1238 if (eb)
1239 method |= 0x20, fidx = eb->exts[i]->index;
1240 else
1241 error(ERR_PANIC,
1242 "unrecognised WRT value in obj_write_fixup");
1247 forp = obj_byte (forp, method);
1248 if (fidx != -1)
1249 forp = obj_index (forp, fidx);
1250 forp = obj_index (forp, tidx);
1251 obj_commit (forp);
1254 static long obj_segment (char *name, int pass, int *bits)
1257 * We call the label manager here to define a name for the new
1258 * segment, and when our _own_ label-definition stub gets
1259 * called in return, it should register the new segment name
1260 * using the pointer it gets passed. That way we save memory,
1261 * by sponging off the label manager.
1263 #if defined(DEBUG) && DEBUG>=3
1264 fprintf(stderr," obj_segment: < %s >, pass=%d, *bits=%d\n",
1265 name, pass, *bits);
1266 #endif
1267 if (!name) {
1268 *bits = 16;
1269 current_seg = NULL;
1270 return first_seg;
1271 } else {
1272 struct Segment *seg;
1273 struct Group *grp;
1274 struct External **extp;
1275 int obj_idx, i, attrs, rn_error;
1276 char *p;
1279 * Look for segment attributes.
1281 attrs = 0;
1282 while (*name == '.')
1283 name++; /* hack, but a documented one */
1284 p = name;
1285 while (*p && !isspace(*p))
1286 p++;
1287 if (*p) {
1288 *p++ = '\0';
1289 while (*p && isspace(*p))
1290 *p++ = '\0';
1292 while (*p) {
1293 while (*p && !isspace(*p))
1294 p++;
1295 if (*p) {
1296 *p++ = '\0';
1297 while (*p && isspace(*p))
1298 *p++ = '\0';
1301 attrs++;
1304 obj_idx = 1;
1305 for (seg = seghead; seg; seg = seg->next) {
1306 obj_idx++;
1307 if (!strcmp(seg->name, name)) {
1308 if (attrs > 0 && pass == 1)
1309 error(ERR_WARNING, "segment attributes specified on"
1310 " redeclaration of segment: ignoring");
1311 if (seg->use32)
1312 *bits = 32;
1313 else
1314 *bits = 16;
1315 current_seg = seg;
1316 return seg->index;
1320 *segtail = seg = nasm_malloc(sizeof(*seg));
1321 seg->next = NULL;
1322 segtail = &seg->next;
1323 seg->index = (any_segs ? seg_alloc() : first_seg);
1324 seg->obj_index = obj_idx;
1325 seg->grp = NULL;
1326 any_segs = TRUE;
1327 seg->name = NULL;
1328 seg->currentpos = 0;
1329 seg->align = 1; /* default */
1330 seg->use32 = FALSE; /* default */
1331 seg->combine = CMB_PUBLIC; /* default */
1332 seg->segclass = seg->overlay = NULL;
1333 seg->pubhead = NULL;
1334 seg->pubtail = &seg->pubhead;
1335 seg->lochead = NULL;
1336 seg->loctail = &seg->lochead;
1337 seg->orp = obj_new();
1338 seg->orp->up = &(seg->orp);
1339 seg->orp->ori = ori_ledata;
1340 seg->orp->type = LEDATA;
1341 seg->orp->parm[1] = obj_idx;
1344 * Process the segment attributes.
1346 p = name;
1347 while (attrs--) {
1348 p += strlen(p);
1349 while (!*p) p++;
1352 * `p' contains a segment attribute.
1354 if (!nasm_stricmp(p, "private"))
1355 seg->combine = CMB_PRIVATE;
1356 else if (!nasm_stricmp(p, "public"))
1357 seg->combine = CMB_PUBLIC;
1358 else if (!nasm_stricmp(p, "common"))
1359 seg->combine = CMB_COMMON;
1360 else if (!nasm_stricmp(p, "stack"))
1361 seg->combine = CMB_STACK;
1362 else if (!nasm_stricmp(p, "use16"))
1363 seg->use32 = FALSE;
1364 else if (!nasm_stricmp(p, "use32"))
1365 seg->use32 = TRUE;
1366 else if (!nasm_stricmp(p, "flat")) {
1368 * This segment is an OS/2 FLAT segment. That means
1369 * that its default group is group FLAT, even if
1370 * the group FLAT does not explicitly _contain_ the
1371 * segment.
1373 * When we see this, we must create the group
1374 * `FLAT', containing no segments, if it does not
1375 * already exist; then we must set the default
1376 * group of this segment to be the FLAT group.
1378 struct Group *grp;
1379 for (grp = grphead; grp; grp = grp->next)
1380 if (!strcmp(grp->name, "FLAT"))
1381 break;
1382 if (!grp) {
1383 obj_directive ("group", "FLAT", 1);
1384 for (grp = grphead; grp; grp = grp->next)
1385 if (!strcmp(grp->name, "FLAT"))
1386 break;
1387 if (!grp)
1388 error (ERR_PANIC, "failure to define FLAT?!");
1390 seg->grp = grp;
1391 } else if (!nasm_strnicmp(p, "class=", 6))
1392 seg->segclass = nasm_strdup(p+6);
1393 else if (!nasm_strnicmp(p, "overlay=", 8))
1394 seg->overlay = nasm_strdup(p+8);
1395 else if (!nasm_strnicmp(p, "align=", 6)) {
1396 seg->align = readnum(p+6, &rn_error);
1397 if (rn_error) {
1398 seg->align = 1;
1399 error (ERR_NONFATAL, "segment alignment should be"
1400 " numeric");
1402 switch ((int) seg->align) {
1403 case 1: /* BYTE */
1404 case 2: /* WORD */
1405 case 4: /* DWORD */
1406 case 16: /* PARA */
1407 case 256: /* PAGE */
1408 case 4096: /* PharLap extension */
1409 break;
1410 case 8:
1411 error(ERR_WARNING, "OBJ format does not support alignment"
1412 " of 8: rounding up to 16");
1413 seg->align = 16;
1414 break;
1415 case 32:
1416 case 64:
1417 case 128:
1418 error(ERR_WARNING, "OBJ format does not support alignment"
1419 " of %d: rounding up to 256", seg->align);
1420 seg->align = 256;
1421 break;
1422 case 512:
1423 case 1024:
1424 case 2048:
1425 error(ERR_WARNING, "OBJ format does not support alignment"
1426 " of %d: rounding up to 4096", seg->align);
1427 seg->align = 4096;
1428 break;
1429 default:
1430 error(ERR_NONFATAL, "invalid alignment value %d",
1431 seg->align);
1432 seg->align = 1;
1433 break;
1435 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1436 seg->align = SEG_ABS + readnum(p+9, &rn_error);
1437 if (rn_error)
1438 error (ERR_NONFATAL, "argument to `absolute' segment"
1439 " attribute should be numeric");
1443 /* We need to know whenever we have at least one 32-bit segment */
1444 obj_use32 |= seg->use32;
1446 obj_seg_needs_update = seg;
1447 if (seg->align >= SEG_ABS)
1448 deflabel (name, NO_SEG, seg->align - SEG_ABS,
1449 NULL, FALSE, FALSE, &of_obj, error);
1450 else
1451 deflabel (name, seg->index+1, 0L,
1452 NULL, FALSE, FALSE, &of_obj, error);
1453 obj_seg_needs_update = NULL;
1456 * See if this segment is defined in any groups.
1458 for (grp = grphead; grp; grp = grp->next) {
1459 for (i = grp->nindices; i < grp->nentries; i++) {
1460 if (!strcmp(grp->segs[i].name, seg->name)) {
1461 nasm_free (grp->segs[i].name);
1462 grp->segs[i] = grp->segs[grp->nindices];
1463 grp->segs[grp->nindices++].index = seg->obj_index;
1464 if (seg->grp)
1465 error(ERR_WARNING, "segment `%s' is already part of"
1466 " a group: first one takes precedence",
1467 seg->name);
1468 else
1469 seg->grp = grp;
1475 * Walk through the list of externals with unresolved
1476 * default-WRT clauses, and resolve any that point at this
1477 * segment.
1479 extp = &dws;
1480 while (*extp) {
1481 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1482 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1483 nasm_free((*extp)->defwrt_ptr.string);
1484 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1485 (*extp)->defwrt_ptr.seg = seg;
1486 *extp = (*extp)->next_dws;
1487 } else
1488 extp = &(*extp)->next_dws;
1491 if (seg->use32)
1492 *bits = 32;
1493 else
1494 *bits = 16;
1495 current_seg = seg;
1496 return seg->index;
1500 static int obj_directive (char *directive, char *value, int pass)
1502 if (!strcmp(directive, "group")) {
1503 char *p, *q, *v;
1504 if (pass == 1) {
1505 struct Group *grp;
1506 struct Segment *seg;
1507 struct External **extp;
1508 int obj_idx;
1510 q = value;
1511 while (*q == '.')
1512 q++; /* hack, but a documented one */
1513 v = q;
1514 while (*q && !isspace(*q))
1515 q++;
1516 if (isspace(*q)) {
1517 *q++ = '\0';
1518 while (*q && isspace(*q))
1519 q++;
1522 * Here we used to sanity-check the group directive to
1523 * ensure nobody tried to declare a group containing no
1524 * segments. However, OS/2 does this as standard
1525 * practice, so the sanity check has been removed.
1527 * if (!*q) {
1528 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1529 * return 1;
1533 obj_idx = 1;
1534 for (grp = grphead; grp; grp = grp->next) {
1535 obj_idx++;
1536 if (!strcmp(grp->name, v)) {
1537 error(ERR_NONFATAL, "group `%s' defined twice", v);
1538 return 1;
1542 *grptail = grp = nasm_malloc(sizeof(*grp));
1543 grp->next = NULL;
1544 grptail = &grp->next;
1545 grp->index = seg_alloc();
1546 grp->obj_index = obj_idx;
1547 grp->nindices = grp->nentries = 0;
1548 grp->name = NULL;
1550 obj_grp_needs_update = grp;
1551 deflabel (v, grp->index+1, 0L,
1552 NULL, FALSE, FALSE, &of_obj, error);
1553 obj_grp_needs_update = NULL;
1555 while (*q) {
1556 p = q;
1557 while (*q && !isspace(*q))
1558 q++;
1559 if (isspace(*q)) {
1560 *q++ = '\0';
1561 while (*q && isspace(*q))
1562 q++;
1565 * Now p contains a segment name. Find it.
1567 for (seg = seghead; seg; seg = seg->next)
1568 if (!strcmp(seg->name, p))
1569 break;
1570 if (seg) {
1572 * We have a segment index. Shift a name entry
1573 * to the end of the array to make room.
1575 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1576 grp->segs[grp->nindices++].index = seg->obj_index;
1577 if (seg->grp)
1578 error(ERR_WARNING, "segment `%s' is already part of"
1579 " a group: first one takes precedence",
1580 seg->name);
1581 else
1582 seg->grp = grp;
1583 } else {
1585 * We have an as-yet undefined segment.
1586 * Remember its name, for later.
1588 grp->segs[grp->nentries++].name = nasm_strdup(p);
1593 * Walk through the list of externals with unresolved
1594 * default-WRT clauses, and resolve any that point at
1595 * this group.
1597 extp = &dws;
1598 while (*extp) {
1599 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1600 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1601 nasm_free((*extp)->defwrt_ptr.string);
1602 (*extp)->defwrt_type = DEFWRT_GROUP;
1603 (*extp)->defwrt_ptr.grp = grp;
1604 *extp = (*extp)->next_dws;
1605 } else
1606 extp = &(*extp)->next_dws;
1609 return 1;
1611 if (!strcmp(directive, "uppercase")) {
1612 obj_uppercase = TRUE;
1613 return 1;
1615 if (!strcmp(directive, "import")) {
1616 char *q, *extname, *libname, *impname;
1618 if (pass == 2)
1619 return 1; /* ignore in pass two */
1620 extname = q = value;
1621 while (*q && !isspace(*q))
1622 q++;
1623 if (isspace(*q)) {
1624 *q++ = '\0';
1625 while (*q && isspace(*q))
1626 q++;
1629 libname = q;
1630 while (*q && !isspace(*q))
1631 q++;
1632 if (isspace(*q)) {
1633 *q++ = '\0';
1634 while (*q && isspace(*q))
1635 q++;
1638 impname = q;
1640 if (!*extname || !*libname)
1641 error(ERR_NONFATAL, "`import' directive requires symbol name"
1642 " and library name");
1643 else {
1644 struct ImpDef *imp;
1645 int err = FALSE;
1647 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1648 imptail = &imp->next;
1649 imp->next = NULL;
1650 imp->extname = nasm_strdup(extname);
1651 imp->libname = nasm_strdup(libname);
1652 imp->impindex = readnum(impname, &err);
1653 if (!*impname || err)
1654 imp->impname = nasm_strdup(impname);
1655 else
1656 imp->impname = NULL;
1659 return 1;
1661 if (!strcmp(directive, "export")) {
1662 char *q, *extname, *intname, *v;
1663 struct ExpDef *export;
1664 int flags = 0;
1665 unsigned int ordinal = 0;
1667 if (pass == 2)
1668 return 1; /* ignore in pass two */
1669 intname = q = value;
1670 while (*q && !isspace(*q))
1671 q++;
1672 if (isspace(*q)) {
1673 *q++ = '\0';
1674 while (*q && isspace(*q))
1675 q++;
1678 extname = q;
1679 while (*q && !isspace(*q))
1680 q++;
1681 if (isspace(*q)) {
1682 *q++ = '\0';
1683 while (*q && isspace(*q))
1684 q++;
1687 if (!*intname) {
1688 error(ERR_NONFATAL, "`export' directive requires export name");
1689 return 1;
1691 if (!*extname) {
1692 extname = intname;
1693 intname = "";
1695 while (*q) {
1696 v = q;
1697 while (*q && !isspace(*q))
1698 q++;
1699 if (isspace(*q)) {
1700 *q++ = '\0';
1701 while (*q && isspace(*q))
1702 q++;
1704 if (!nasm_stricmp(v, "resident"))
1705 flags |= EXPDEF_FLAG_RESIDENT;
1706 else if (!nasm_stricmp(v, "nodata"))
1707 flags |= EXPDEF_FLAG_NODATA;
1708 else if (!nasm_strnicmp(v, "parm=", 5)) {
1709 int err = FALSE;
1710 flags |= EXPDEF_MASK_PARMCNT & readnum(v+5, &err);
1711 if (err) {
1712 error(ERR_NONFATAL,
1713 "value `%s' for `parm' is non-numeric", v+5);
1714 return 1;
1716 } else {
1717 int err = FALSE;
1718 ordinal = readnum(v, &err);
1719 if (err) {
1720 error(ERR_NONFATAL, "unrecognised export qualifier `%s'",
1722 return 1;
1724 flags |= EXPDEF_FLAG_ORDINAL;
1728 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1729 exptail = &export->next;
1730 export->next = NULL;
1731 export->extname = nasm_strdup(extname);
1732 export->intname = nasm_strdup(intname);
1733 export->ordinal = ordinal;
1734 export->flags = flags;
1736 return 1;
1738 return 0;
1741 static long obj_segbase (long segment)
1743 struct Segment *seg;
1746 * Find the segment in our list.
1748 for (seg = seghead; seg; seg = seg->next)
1749 if (seg->index == segment-1)
1750 break;
1752 if (!seg) {
1754 * Might be an external with a default WRT.
1756 long i = segment/2;
1757 struct ExtBack *eb = ebhead;
1758 struct External *e;
1760 while (i > EXT_BLKSIZ) {
1761 if (eb)
1762 eb = eb->next;
1763 else
1764 break;
1765 i -= EXT_BLKSIZ;
1767 if (eb) {
1768 e = eb->exts[i];
1769 if (e->defwrt_type == DEFWRT_NONE)
1770 return segment; /* fine */
1771 else if (e->defwrt_type == DEFWRT_SEGMENT)
1772 return e->defwrt_ptr.seg->index+1;
1773 else if (e->defwrt_type == DEFWRT_GROUP)
1774 return e->defwrt_ptr.grp->index+1;
1775 else
1776 return NO_SEG; /* can't tell what it is */
1779 return segment; /* not one of ours - leave it alone */
1782 if (seg->align >= SEG_ABS)
1783 return seg->align; /* absolute segment */
1784 if (seg->grp)
1785 return seg->grp->index+1; /* grouped segment */
1787 return segment; /* no special treatment */
1790 static void obj_filename (char *inname, char *outname, efunc lerror)
1792 strcpy(obj_infile, inname);
1793 standard_extension (inname, outname, ".obj", lerror);
1796 static void obj_write_file (int debuginfo)
1798 struct Segment *seg, *entry_seg_ptr = 0;
1799 struct FileName *fn;
1800 struct LineNumber *ln;
1801 struct Group *grp;
1802 struct Public *pub, *loc;
1803 struct External *ext;
1804 struct ImpDef *imp;
1805 struct ExpDef *export;
1806 static char boast[] = "The Netwide Assembler " NASM_VER;
1807 int lname_idx;
1808 ObjRecord *orp;
1811 * Write the THEADR module header.
1813 orp = obj_new();
1814 orp->type = THEADR;
1815 obj_name (orp, obj_infile);
1816 obj_emit2 (orp);
1819 * Write the NASM boast comment.
1821 orp->type = COMENT;
1822 obj_rword (orp, 0); /* comment type zero */
1823 obj_name (orp, boast);
1824 obj_emit2 (orp);
1826 orp->type = COMENT;
1828 * Write the IMPDEF records, if any.
1830 for (imp = imphead; imp; imp = imp->next) {
1831 obj_rword (orp, 0xA0); /* comment class A0 */
1832 obj_byte (orp, 1); /* subfunction 1: IMPDEF */
1833 if (imp->impname)
1834 obj_byte (orp, 0); /* import by name */
1835 else
1836 obj_byte (orp, 1); /* import by ordinal */
1837 obj_name (orp, imp->extname);
1838 obj_name (orp, imp->libname);
1839 if (imp->impname)
1840 obj_name (orp, imp->impname);
1841 else
1842 obj_word (orp, imp->impindex);
1843 obj_emit2 (orp);
1847 * Write the EXPDEF records, if any.
1849 for (export = exphead; export; export = export->next) {
1850 obj_rword (orp, 0xA0); /* comment class A0 */
1851 obj_byte (orp, 2); /* subfunction 2: EXPDEF */
1852 obj_byte (orp, export->flags);
1853 obj_name (orp, export->extname);
1854 obj_name (orp, export->intname);
1855 if (export->flags & EXPDEF_FLAG_ORDINAL)
1856 obj_word (orp, export->ordinal);
1857 obj_emit2 (orp);
1860 /* we're using extended OMF if we put in debug info*/
1861 if (debuginfo) {
1862 orp->type = COMENT;
1863 obj_byte (orp, 0x40);
1864 obj_byte (orp, dEXTENDED);
1865 obj_emit2 (orp);
1869 * Write the first LNAMES record, containing LNAME one, which
1870 * is null. Also initialise the LNAME counter.
1872 orp->type = LNAMES;
1873 obj_byte (orp, 0);
1874 lname_idx = 1;
1876 * Write some LNAMES for the segment names
1878 for (seg = seghead; seg; seg = seg->next) {
1879 orp = obj_name (orp, seg->name);
1880 if (seg->segclass)
1881 orp = obj_name (orp, seg->segclass);
1882 if (seg->overlay)
1883 orp = obj_name (orp, seg->overlay);
1884 obj_commit (orp);
1887 * Write some LNAMES for the group names
1889 for (grp = grphead; grp; grp = grp->next) {
1890 orp = obj_name (orp, grp->name);
1891 obj_commit (orp);
1893 obj_emit (orp);
1897 * Write the SEGDEF records.
1899 orp->type = SEGDEF;
1900 for (seg = seghead; seg; seg = seg->next) {
1901 int acbp;
1902 unsigned long seglen = seg->currentpos;
1904 acbp = (seg->combine << 2); /* C field */
1906 if (seg->use32)
1907 acbp |= 0x01; /* P bit is Use32 flag */
1908 else if (seglen == 0x10000L) {
1909 seglen = 0; /* This special case may be needed for old linkers */
1910 acbp |= 0x02; /* B bit */
1914 /* A field */
1915 if (seg->align >= SEG_ABS)
1916 /* acbp |= 0x00 */;
1917 else if (seg->align >= 4096) {
1918 if (seg->align > 4096)
1919 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1920 " than OBJ format supports", seg->name);
1921 acbp |= 0xC0; /* PharLap extension */
1922 } else if (seg->align >= 256) {
1923 acbp |= 0x80;
1924 } else if (seg->align >= 16) {
1925 acbp |= 0x60;
1926 } else if (seg->align >= 4) {
1927 acbp |= 0xA0;
1928 } else if (seg->align >= 2) {
1929 acbp |= 0x40;
1930 } else
1931 acbp |= 0x20;
1933 obj_byte (orp, acbp);
1934 if (seg->align & SEG_ABS) {
1935 obj_x (orp, seg->align - SEG_ABS); /* Frame */
1936 obj_byte (orp, 0); /* Offset */
1938 obj_x (orp, seglen);
1939 obj_index (orp, ++lname_idx);
1940 obj_index (orp, seg->segclass ? ++lname_idx : 1);
1941 obj_index (orp, seg->overlay ? ++lname_idx : 1);
1942 obj_emit2 (orp);
1946 * Write the GRPDEF records.
1948 orp->type = GRPDEF;
1949 for (grp = grphead; grp; grp = grp->next) {
1950 int i;
1952 if (grp->nindices != grp->nentries) {
1953 for (i = grp->nindices; i < grp->nentries; i++) {
1954 error(ERR_NONFATAL, "group `%s' contains undefined segment"
1955 " `%s'", grp->name, grp->segs[i].name);
1956 nasm_free (grp->segs[i].name);
1957 grp->segs[i].name = NULL;
1960 obj_index (orp, ++lname_idx);
1961 for (i = 0; i < grp->nindices; i++) {
1962 obj_byte (orp, 0xFF);
1963 obj_index (orp, grp->segs[i].index);
1965 obj_emit2 (orp);
1969 * Write the PUBDEF records: first the ones in the segments,
1970 * then the far-absolutes.
1972 orp->type = PUBDEF;
1973 orp->ori = ori_pubdef;
1974 for (seg = seghead; seg; seg = seg->next) {
1975 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
1976 orp->parm[1] = seg->obj_index;
1977 for (pub = seg->pubhead; pub; pub = pub->next) {
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);
1983 obj_emit (orp);
1985 orp->parm[0] = 0;
1986 orp->parm[1] = 0;
1987 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
1988 if (orp->parm[2] != pub->segment) {
1989 obj_emit (orp);
1990 orp->parm[2] = pub->segment;
1992 orp = obj_name (orp, pub->name);
1993 orp = obj_x (orp, pub->offset);
1994 orp = obj_byte (orp, 0); /* type index */
1995 obj_commit (orp);
1997 obj_emit (orp);
2000 * Write the EXTDEF and COMDEF records, in order.
2002 orp->ori = ori_null;
2003 for (ext = exthead; ext; ext = ext->next) {
2004 if (ext->commonsize == 0) {
2005 if (orp->type != EXTDEF) {
2006 obj_emit (orp);
2007 orp->type = EXTDEF;
2009 orp = obj_name (orp, ext->name);
2010 orp = obj_index (orp, 0);
2011 } else {
2012 if (orp->type != COMDEF) {
2013 obj_emit (orp);
2014 orp->type = COMDEF;
2016 orp = obj_name (orp, ext->name);
2017 orp = obj_index (orp, 0);
2018 if (ext->commonelem) {
2019 orp = obj_byte (orp, 0x61);/* far communal */
2020 orp = obj_value (orp, (ext->commonsize / ext->commonelem));
2021 orp = obj_value (orp, ext->commonelem);
2022 } else {
2023 orp = obj_byte (orp, 0x62);/* near communal */
2024 orp = obj_value (orp, ext->commonsize);
2027 obj_commit (orp);
2029 obj_emit (orp);
2032 * Write a COMENT record stating that the linker's first pass
2033 * may stop processing at this point. Exception is if our
2034 * MODEND record specifies a start point, in which case,
2035 * according to some variants of the documentation, this COMENT
2036 * should be omitted. So we'll omit it just in case.
2037 * But, TASM puts it in all the time so if we are using
2038 * TASM debug stuff we are putting it in
2040 if (debuginfo || obj_entry_seg == NO_SEG) {
2041 orp->type = COMENT;
2042 obj_byte (orp, 0x40);
2043 obj_byte (orp, dLINKPASS);
2044 obj_byte (orp, 1);
2045 obj_emit2 (orp);
2049 * 1) put out the compiler type
2050 * 2) Put out the type info. The only type we are using is near label #19
2052 if (debuginfo) {
2053 int i;
2054 struct Array *arrtmp = arrhead;
2055 orp->type = COMENT;
2056 obj_byte (orp, 0x40);
2057 obj_byte (orp, dCOMPDEF);
2058 obj_byte (orp, 4);
2059 obj_byte (orp, 0);
2060 obj_emit2 (orp);
2062 obj_byte (orp, 0x40);
2063 obj_byte (orp, dTYPEDEF);
2064 obj_word (orp, 0x18); /* type # for linking */
2065 obj_word (orp, 6); /* size of type */
2066 obj_byte (orp, 0x2a); /* absolute type for debugging */
2067 obj_emit2 (orp);
2068 obj_byte (orp, 0x40);
2069 obj_byte (orp, dTYPEDEF);
2070 obj_word (orp, 0x19); /* type # for linking */
2071 obj_word (orp, 0); /* size of type */
2072 obj_byte (orp, 0x24); /* absolute type for debugging */
2073 obj_byte (orp, 0); /* near/far specifier */
2074 obj_emit2 (orp);
2075 obj_byte (orp, 0x40);
2076 obj_byte (orp, dTYPEDEF);
2077 obj_word (orp, 0x1A); /* type # for linking */
2078 obj_word (orp, 0); /* size of type */
2079 obj_byte (orp, 0x24); /* absolute type for debugging */
2080 obj_byte (orp, 1); /* near/far specifier */
2081 obj_emit2 (orp);
2082 obj_byte (orp, 0x40);
2083 obj_byte (orp, dTYPEDEF);
2084 obj_word (orp, 0x1b); /* type # for linking */
2085 obj_word (orp, 0); /* size of type */
2086 obj_byte (orp, 0x23); /* absolute type for debugging */
2087 obj_byte (orp, 0);
2088 obj_byte (orp, 0);
2089 obj_byte (orp, 0);
2090 obj_emit2 (orp);
2091 obj_byte (orp, 0x40);
2092 obj_byte (orp, dTYPEDEF);
2093 obj_word (orp, 0x1c); /* type # for linking */
2094 obj_word (orp, 0); /* size of type */
2095 obj_byte (orp, 0x23); /* absolute type for debugging */
2096 obj_byte (orp, 0);
2097 obj_byte (orp, 4);
2098 obj_byte (orp, 0);
2099 obj_emit2 (orp);
2100 obj_byte (orp, 0x40);
2101 obj_byte (orp, dTYPEDEF);
2102 obj_word (orp, 0x1d); /* type # for linking */
2103 obj_word (orp, 0); /* size of type */
2104 obj_byte (orp, 0x23); /* absolute type for debugging */
2105 obj_byte (orp, 0);
2106 obj_byte (orp, 1);
2107 obj_byte (orp, 0);
2108 obj_emit2 (orp);
2109 obj_byte (orp, 0x40);
2110 obj_byte (orp, dTYPEDEF);
2111 obj_word (orp, 0x1e); /* type # for linking */
2112 obj_word (orp, 0); /* size of type */
2113 obj_byte (orp, 0x23); /* absolute type for debugging */
2114 obj_byte (orp, 0);
2115 obj_byte (orp, 5);
2116 obj_byte (orp, 0);
2117 obj_emit2 (orp);
2119 /* put out the array types */
2120 for (i= ARRAYBOT; i < arrindex; i++) {
2121 obj_byte (orp, 0x40);
2122 obj_byte (orp, dTYPEDEF);
2123 obj_word (orp, i ); /* type # for linking */
2124 obj_word (orp, arrtmp->size); /* size of type */
2125 obj_byte (orp, 0x1A); /* absolute type for debugging (array)*/
2126 obj_byte (orp, arrtmp->basetype ); /* base type */
2127 obj_emit2 (orp);
2128 arrtmp = arrtmp->next ;
2132 * write out line number info with a LINNUM record
2133 * switch records when we switch segments, and output the
2134 * file in a pseudo-TASM fashion. The record switch is naive; that
2135 * is that one file may have many records for the same segment
2136 * if there are lots of segment switches
2138 if (fnhead && debuginfo) {
2139 seg = fnhead->lnhead->segment;
2141 for (fn = fnhead; fn; fn = fn->next) {
2142 /* write out current file name */
2143 orp->type = COMENT;
2144 orp->ori = ori_null;
2145 obj_byte (orp, 0x40);
2146 obj_byte (orp, dFILNAME);
2147 obj_byte( orp,0);
2148 obj_name( orp,fn->name);
2149 obj_dword(orp, 0);
2150 obj_emit2 (orp);
2152 /* write out line numbers this file */
2154 orp->type = LINNUM;
2155 orp->ori = ori_linnum;
2156 for (ln = fn->lnhead; ln; ln = ln->next) {
2157 if (seg != ln->segment) {
2158 /* if we get here have to flush the buffer and start
2159 * a new record for a new segment
2161 seg = ln->segment;
2162 obj_emit ( orp );
2164 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2165 orp->parm[1] = seg->obj_index;
2166 orp = obj_word(orp, ln->lineno);
2167 orp = obj_x(orp, ln->offset);
2168 obj_commit (orp);
2170 obj_emit (orp);
2174 * we are going to locate the entry point segment now
2175 * rather than wait until the MODEND record, because,
2176 * then we can output a special symbol to tell where the
2177 * entry point is.
2180 if (obj_entry_seg != NO_SEG) {
2181 for (seg = seghead; seg; seg = seg->next) {
2182 if (seg->index == obj_entry_seg) {
2183 entry_seg_ptr = seg;
2184 break;
2187 if (!seg)
2188 error(ERR_NONFATAL, "entry point is not in this module");
2192 * get ready to put out symbol records
2194 orp->type = COMENT;
2195 orp->ori = ori_local;
2198 * put out a symbol for the entry point
2199 * no dots in this symbol, because, borland does
2200 * not (officially) support dots in label names
2201 * and I don't know what various versions of TLINK will do
2203 if (debuginfo && obj_entry_seg != NO_SEG) {
2204 orp = obj_name (orp,"start_of_program");
2205 orp = obj_word (orp,0x19); /* type: near label */
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, obj_entry_ofs);
2209 obj_commit (orp);
2213 * put out the local labels
2215 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2216 /* labels this seg */
2217 for (loc = seg->lochead; loc; loc = loc->next) {
2218 orp = obj_name (orp,loc->name);
2219 orp = obj_word (orp, loc->type);
2220 orp = obj_index (orp, seg->grp ? seg->grp->obj_index : 0);
2221 orp = obj_index (orp, seg->obj_index);
2222 orp = obj_x (orp,loc->offset);
2223 obj_commit (orp);
2226 if (orp->used)
2227 obj_emit (orp);
2230 * Write the LEDATA/FIXUPP pairs.
2232 for (seg = seghead; seg; seg = seg->next) {
2233 obj_emit (seg->orp);
2234 nasm_free (seg->orp);
2238 * Write the MODEND module end marker.
2240 orp->type = obj_use32 ? MODE32 : MODEND;
2241 orp->ori = ori_null;
2242 if (entry_seg_ptr) {
2243 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2244 obj_byte (orp, 0xC1);
2245 seg = entry_seg_ptr;
2246 if (seg->grp) {
2247 obj_byte (orp, 0x10);
2248 obj_index (orp, seg->grp->obj_index);
2249 } else {
2251 * the below changed to prevent TLINK crashing.
2252 * Previous more efficient version read:
2254 * obj_byte (orp, 0x50);
2256 obj_byte (orp, 0x00);
2257 obj_index (orp, seg->obj_index);
2259 obj_index (orp, seg->obj_index);
2260 obj_x (orp, obj_entry_ofs);
2261 } else
2262 obj_byte (orp, 0);
2263 obj_emit2 (orp);
2264 nasm_free (orp);
2267 void obj_fwrite(ObjRecord *orp)
2269 unsigned int cksum, len;
2270 unsigned char *ptr;
2272 cksum = orp->type;
2273 if (orp->x_size == 32)
2274 cksum |= 1;
2275 fputc (cksum, ofp);
2276 len = orp->committed+1;
2277 cksum += (len & 0xFF) + ((len>>8) & 0xFF);
2278 fwriteshort (len, ofp);
2279 fwrite (orp->buf, 1, len-1, ofp);
2280 for (ptr=orp->buf; --len; ptr++)
2281 cksum += *ptr;
2282 fputc ( (-cksum) & 0xFF, ofp);
2285 static const char *obj_stdmac[] = {
2286 "%define __SECT__ [section .text]",
2287 "%imacro group 1+.nolist",
2288 "[group %1]",
2289 "%endmacro",
2290 "%imacro uppercase 0+.nolist",
2291 "[uppercase %1]",
2292 "%endmacro",
2293 "%imacro export 1+.nolist",
2294 "[export %1]",
2295 "%endmacro",
2296 "%imacro import 1+.nolist",
2297 "[import %1]",
2298 "%endmacro",
2299 "%macro __NASM_CDecl__ 1",
2300 "%endmacro",
2301 NULL
2304 void dbgbi_init(struct ofmt * of, void * id, FILE * fp, efunc error)
2306 (void) of;
2307 (void) id;
2308 (void) fp;
2309 (void) error;
2311 fnhead = NULL;
2312 fntail = &fnhead;
2313 arrindex = ARRAYBOT ;
2314 arrhead = NULL;
2315 arrtail = &arrhead;
2317 static void dbgbi_cleanup(void)
2319 struct Segment *segtmp;
2320 while (fnhead) {
2321 struct FileName *fntemp = fnhead;
2322 while (fnhead->lnhead) {
2323 struct LineNumber *lntemp = fnhead->lnhead;
2324 fnhead->lnhead = lntemp->next;
2325 nasm_free( lntemp);
2327 fnhead = fnhead->next;
2328 nasm_free (fntemp->name);
2329 nasm_free (fntemp);
2331 for (segtmp=seghead; segtmp; segtmp=segtmp->next) {
2332 while (segtmp->lochead) {
2333 struct Public *loctmp = segtmp->lochead;
2334 segtmp->lochead = loctmp->next;
2335 nasm_free (loctmp->name);
2336 nasm_free (loctmp);
2339 while (arrhead) {
2340 struct Array *arrtmp = arrhead;
2341 arrhead = arrhead->next;
2342 nasm_free (arrtmp);
2346 static void dbgbi_linnum (const char *lnfname, long lineno, long segto)
2348 struct FileName *fn;
2349 struct LineNumber *ln;
2350 struct Segment *seg;
2352 if (segto == NO_SEG)
2353 return;
2356 * If `any_segs' is still FALSE, we must define a default
2357 * segment.
2359 if (!any_segs) {
2360 int tempint; /* ignored */
2361 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2362 error (ERR_PANIC, "strange segment conditions in OBJ driver");
2366 * Find the segment we are targetting.
2368 for (seg = seghead; seg; seg = seg->next)
2369 if (seg->index == segto)
2370 break;
2371 if (!seg)
2372 error (ERR_PANIC, "lineno directed to nonexistent segment?");
2374 /* for (fn = fnhead; fn; fn = fnhead->next) */
2375 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine*/
2376 if (!nasm_stricmp(lnfname,fn->name))
2377 break;
2378 if (!fn) {
2379 fn = nasm_malloc ( sizeof( *fn));
2380 fn->name = nasm_malloc ( strlen(lnfname) + 1) ;
2381 strcpy (fn->name,lnfname);
2382 fn->lnhead = NULL;
2383 fn->lntail = & fn->lnhead;
2384 fn->next = NULL;
2385 *fntail = fn;
2386 fntail = &fn->next;
2388 ln = nasm_malloc ( sizeof( *ln));
2389 ln->segment = seg;
2390 ln->offset = seg->currentpos;
2391 ln->lineno = lineno;
2392 ln->next = NULL;
2393 *fn->lntail = ln;
2394 fn->lntail = &ln->next;
2397 static void dbgbi_deflabel (char *name, long segment,
2398 long offset, int is_global, char *special)
2400 struct Segment *seg;
2402 (void) special;
2405 * If it's a special-retry from pass two, discard it.
2407 if (is_global == 3)
2408 return;
2411 * First check for the double-period, signifying something
2412 * unusual.
2414 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2415 return;
2419 * Case (i):
2421 if (obj_seg_needs_update) {
2422 return;
2423 } else if (obj_grp_needs_update) {
2424 return;
2426 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2427 return;
2429 if (segment >= SEG_ABS || segment == NO_SEG) {
2430 return;
2434 * If `any_segs' is still FALSE, we might need to define a
2435 * default segment, if they're trying to declare a label in
2436 * `first_seg'. But the label should exist due to a prior
2437 * call to obj_deflabel so we can skip that.
2440 for (seg = seghead; seg; seg = seg->next)
2441 if (seg->index == segment) {
2442 struct Public *loc = nasm_malloc (sizeof(*loc));
2444 * Case (ii). Maybe MODPUB someday?
2446 last_defined = *seg->loctail = loc;
2447 seg->loctail = &loc->next;
2448 loc->next = NULL;
2449 loc->name = nasm_strdup(name);
2450 loc->offset = offset;
2453 static void dbgbi_typevalue (long type)
2455 int vsize;
2456 int elem = TYM_ELEMENTS(type);
2457 type = TYM_TYPE(type);
2459 if (!last_defined)
2460 return;
2462 switch (type) {
2463 case TY_BYTE:
2464 last_defined->type = 8; /* unsigned char */
2465 vsize = 1;
2466 break;
2467 case TY_WORD:
2468 last_defined->type = 10; /* unsigned word */
2469 vsize = 2;
2470 break;
2471 case TY_DWORD:
2472 last_defined->type = 12; /* unsigned dword */
2473 vsize = 4;
2474 break;
2475 case TY_FLOAT:
2476 last_defined->type = 14; /* float */
2477 vsize = 4;
2478 break;
2479 case TY_QWORD:
2480 last_defined->type = 15; /* qword */
2481 vsize = 8;
2482 break;
2483 case TY_TBYTE:
2484 last_defined->type = 16; /* TBYTE */
2485 vsize = 10;
2486 break;
2487 default:
2488 last_defined->type = 0x19; /*label */
2489 vsize = 0;
2490 break;
2493 if (elem > 1) {
2494 struct Array *arrtmp = nasm_malloc (sizeof(*arrtmp));
2495 int vtype = last_defined->type;
2496 arrtmp->size = vsize * elem;
2497 arrtmp->basetype = vtype;
2498 arrtmp->next = NULL;
2499 last_defined->type = arrindex++;
2500 *arrtail = arrtmp;
2501 arrtail = & (arrtmp->next);
2503 last_defined = NULL;
2505 static void dbgbi_output (int output_type, void *param)
2507 (void) output_type;
2508 (void) param;
2510 static struct dfmt borland_debug_form = {
2511 "Borland Debug Records",
2512 "borland",
2513 dbgbi_init,
2514 dbgbi_linnum,
2515 dbgbi_deflabel,
2516 null_debug_routine,
2517 dbgbi_typevalue,
2518 dbgbi_output,
2519 dbgbi_cleanup,
2522 static struct dfmt *borland_debug_arr[3] = {
2523 &borland_debug_form,
2524 &null_debug_form,
2525 NULL
2528 struct ofmt of_obj = {
2529 "MS-DOS 16-bit/32-bit OMF object files",
2530 "obj",
2531 NULL,
2532 borland_debug_arr,
2533 &null_debug_form,
2534 obj_stdmac,
2535 obj_init,
2536 obj_set_info,
2537 obj_out,
2538 obj_deflabel,
2539 obj_segment,
2540 obj_segbase,
2541 obj_directive,
2542 obj_filename,
2543 obj_cleanup
2545 #endif /* OF_OBJ */