NASM 0.98.09
[nasm.git] / outobj.c
blob4d8b6c96e48fe49e977f12427eead798d39c4160
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];
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;
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;
855 if (is_global == 2) {
856 ext->commonsize = offset;
857 ext->commonelem = 1; /* default FAR */
858 } else
859 ext->commonsize = 0;
861 else
862 return;
865 * Now process the special text, if any, to find default-WRT
866 * specifications and common-variable element-size and near/far
867 * specifications.
869 while (special && *special) {
870 used_special = TRUE;
873 * We might have a default-WRT specification.
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++;
891 * The NEAR or FAR keywords specify nearness or
892 * farness. FAR gives default element size 1.
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");
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.
918 if (*special == ':')
919 special++;
920 else if (*special) {
921 if (ext->commonsize) {
922 expr *e;
923 struct tokenval tokval;
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);
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++;
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;
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;
963 i -= EXT_BLKSIZ;
965 eb->exts[i] = ext;
966 ext->index = ++externals;
968 if (special && !used_special)
969 error(ERR_NONFATAL, "OBJ supports no special symbol features"
970 " for this symbol type");
973 /* forward declaration */
974 static void obj_write_fixup (ObjRecord *orp, int bytes,
975 int segrel, long seg, long wrt, struct Segment *segto);
977 static void obj_out (long segto, void *data, unsigned long type,
978 long segment, long wrt)
980 unsigned long size, realtype;
981 unsigned char *ucdata;
982 long ldata;
983 struct Segment *seg;
984 ObjRecord *orp;
987 * handle absolute-assembly (structure definitions)
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;
997 * If `any_segs' is still FALSE, we must define a default
998 * segment.
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");
1007 * Find the segment we are targetting.
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?");
1015 orp = seg->orp;
1016 orp->parm[0] = seg->currentpos;
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;
1035 else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
1036 realtype == OUT_REL4ADR)
1038 int rsize;
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;
1051 if (realtype == OUT_REL4ADR) {
1052 ldata += (size-4);
1053 size = 4;
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) {
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.
1069 rsize = 2;
1070 if (ldata & 0xFFFF)
1071 error(ERR_NONFATAL, "OBJ format cannot handle complex"
1072 " dword-size segment base references");
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;
1084 obj_commit(orp);
1087 static void obj_write_fixup (ObjRecord *orp, int bytes,
1088 int segrel, long seg, long wrt, struct Segment *segto)
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;
1098 if (bytes == 1) {
1099 error(ERR_NONFATAL, "`obj' output driver does not support"
1100 " one-byte relocations");
1101 return;
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;
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");
1124 else {
1125 base = FALSE;
1126 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1127 if (!segrel)
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.
1133 forp = obj_force(forp, bytes<<3);
1136 forp = obj_rword (forp, locat | segrel | (orp->parm[0]-orp->parm[2]));
1138 tidx = fidx = -1, method = 0; /* placate optimisers */
1141 * See if we can find the segment ID in our segment list. If
1142 * so, we have a T4 (LSEG) target.
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;
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");
1174 * If no WRT given, assume the natural default, which is method
1175 * F5 unless:
1177 * - we are doing an OFFSET fixup for a grouped segment, in
1178 * which case we require F1 (group).
1180 * - we are doing an OFFSET fixup for an external with a
1181 * default WRT, in which case we must honour the default WRT.
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_ */
1196 } else
1197 method |= 0x50, fidx = -1;
1198 } else {
1200 * See if we can find the WRT-segment ID in our segment
1201 * list. If so, we have a F0 (LSEG) frame.
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;
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");
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);
1240 static long obj_segment (char *name, int pass, int *bits)
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.
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;
1265 * Look for segment attributes.
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';
1278 while (*p) {
1279 while (*p && !isspace(*p))
1280 p++;
1281 if (*p) {
1282 *p++ = '\0';
1283 while (*p && isspace(*p))
1284 *p++ = '\0';
1287 attrs++;
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;
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;
1330 * Process the segment attributes.
1332 p = name;
1333 while (attrs--) {
1334 p += strlen(p);
1335 while (!*p) p++;
1338 * `p' contains a segment attribute.
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")) {
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.
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.
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?!");
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");
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;
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");
1429 /* We need to know whenever we have at least one 32-bit segment */
1430 obj_use32 |= seg->use32;
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;
1442 * See if this segment is defined in any groups.
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;
1461 * Walk through the list of externals with unresolved
1462 * default-WRT clauses, and resolve any that point at this
1463 * segment.
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;
1477 if (seg->use32)
1478 *bits = 32;
1479 else
1480 *bits = 16;
1481 current_seg = seg;
1482 return seg->index;
1486 static int obj_directive (char *directive, char *value, int pass)
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;
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++;
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.
1513 * if (!*q) {
1514 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1515 * return 1;
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;
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;
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;
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++;
1551 * Now p contains a segment name. Find it.
1553 for (seg = seghead; seg; seg = seg->next)
1554 if (!strcmp(seg->name, p))
1555 break;
1556 if (seg) {
1558 * We have a segment index. Shift a name entry
1559 * to the end of the array to make room.
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 {
1571 * We have an as-yet undefined segment.
1572 * Remember its name, for later.
1574 grp->segs[grp->nentries++].name = nasm_strdup(p);
1579 * Walk through the list of externals with unresolved
1580 * default-WRT clauses, and resolve any that point at
1581 * this group.
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;
1595 return 1;
1597 if (!strcmp(directive, "uppercase")) {
1598 obj_uppercase = TRUE;
1599 return 1;
1601 if (!strcmp(directive, "import")) {
1602 char *q, *extname, *libname, *impname;
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++;
1615 libname = q;
1616 while (*q && !isspace(*q))
1617 q++;
1618 if (isspace(*q)) {
1619 *q++ = '\0';
1620 while (*q && isspace(*q))
1621 q++;
1624 impname = q;
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;
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;
1645 return 1;
1647 if (!strcmp(directive, "export")) {
1648 char *q, *extname, *intname, *v;
1649 struct ExpDef *export;
1650 int flags = 0;
1651 unsigned int ordinal = 0;
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++;
1664 extname = q;
1665 while (*q && !isspace(*q))
1666 q++;
1667 if (isspace(*q)) {
1668 *q++ = '\0';
1669 while (*q && isspace(*q))
1670 q++;
1673 if (!*intname) {
1674 error(ERR_NONFATAL, "`export' directive requires export name");
1675 return 1;
1677 if (!*extname) {
1678 extname = intname;
1679 intname = "";
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++;
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;
1702 } else {
1703 int err = FALSE;
1704 ordinal = readnum(v, &err);
1705 if (err) {
1706 error(ERR_NONFATAL, "unrecognised export qualifier `%s'",
1708 return 1;
1710 flags |= EXPDEF_FLAG_ORDINAL;
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;
1722 return 1;
1724 return 0;
1727 static long obj_segbase (long segment)
1729 struct Segment *seg;
1732 * Find the segment in our list.
1734 for (seg = seghead; seg; seg = seg->next)
1735 if (seg->index == segment-1)
1736 break;
1738 if (!seg) {
1740 * Might be an external with a default WRT.
1742 long i = segment/2;
1743 struct ExtBack *eb = ebhead;
1744 struct External *e;
1746 while (i > EXT_BLKSIZ) {
1747 if (eb)
1748 eb = eb->next;
1749 else
1750 break;
1751 i -= EXT_BLKSIZ;
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 */
1765 return segment; /* not one of ours - leave it alone */
1768 if (seg->align >= SEG_ABS)
1769 return seg->align; /* absolute segment */
1770 if (seg->grp)
1771 return seg->grp->index+1; /* grouped segment */
1773 return segment; /* no special treatment */
1776 static void obj_filename (char *inname, char *outname, efunc error)
1778 strcpy(obj_infile, inname);
1779 standard_extension (inname, outname, ".obj", error);
1782 static void obj_write_file (int debuginfo)
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;
1797 * Write the THEADR module header.
1799 orp = obj_new();
1800 orp->type = THEADR;
1801 obj_name (orp, obj_infile);
1802 obj_emit2 (orp);
1805 * Write the NASM boast comment.
1807 orp->type = COMENT;
1808 obj_rword (orp, 0); /* comment type zero */
1809 obj_name (orp, boast);
1810 obj_emit2 (orp);
1812 orp->type = COMENT;
1814 * Write the IMPDEF records, if any.
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);
1833 * Write the EXPDEF records, if any.
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);
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);
1855 * Write the first LNAMES record, containing LNAME one, which
1856 * is null. Also initialise the LNAME counter.
1858 orp->type = LNAMES;
1859 obj_byte (orp, 0);
1860 lname_idx = 1;
1862 * Write some LNAMES for the segment names
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);
1873 * Write some LNAMES for the group names
1875 for (grp = grphead; grp; grp = grp->next) {
1876 orp = obj_name (orp, grp->name);
1877 obj_commit (orp);
1879 obj_emit (orp);
1883 * Write the SEGDEF records.
1885 orp->type = SEGDEF;
1886 for (seg = seghead; seg; seg = seg->next) {
1887 int acbp;
1888 unsigned long seglen = seg->currentpos;
1890 acbp = (seg->combine << 2); /* C field */
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 */
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;
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 */
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);
1932 * Write the GRPDEF records.
1934 orp->type = GRPDEF;
1935 for (grp = grphead; grp; grp = grp->next) {
1936 int i;
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;
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);
1951 obj_emit2 (orp);
1955 * Write the PUBDEF records: first the ones in the segments,
1956 * then the far-absolutes.
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);
1969 obj_emit (orp);
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;
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);
1986 * Write the EXTDEF and COMDEF records, in order.
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;
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;
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);
2013 obj_commit (orp);
2015 obj_emit (orp);
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
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);
2035 * 1) put out the compiler type
2036 * 2) Put out the type info. The only type we are using is near label #19
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);
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);
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 ;
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
2124 if (fnhead && debuginfo) {
2125 seg = fnhead->lnhead->segment;
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);
2138 /* write out line numbers this file */
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
2147 seg = ln->segment;
2148 obj_emit ( orp );
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);
2156 obj_emit (orp);
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.
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;
2173 if (!seg)
2174 error(ERR_NONFATAL, "entry point is not in this module");
2178 * get ready to put out symbol records
2180 orp->type = COMENT;
2181 orp->ori = ori_local;
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
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);
2199 * put out the local labels
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);
2212 if (orp->used)
2213 obj_emit (orp);
2216 * Write the LEDATA/FIXUPP pairs.
2218 for (seg = seghead; seg; seg = seg->next) {
2219 obj_emit (seg->orp);
2220 nasm_free (seg->orp);
2224 * Write the MODEND module end marker.
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 {
2237 * the below changed to prevent TLINK crashing.
2238 * Previous more efficient version read:
2240 * obj_byte (orp, 0x50);
2242 obj_byte (orp, 0x00);
2243 obj_index (orp, seg->obj_index);
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);
2253 void obj_fwrite(ObjRecord *orp)
2255 unsigned int cksum, len;
2256 unsigned char *ptr;
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);
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
2290 void dbgbi_init(struct ofmt * of, void * id, FILE * fp, efunc error)
2292 (void) of;
2293 (void) id;
2294 (void) fp;
2295 (void) error;
2297 fnhead = NULL;
2298 fntail = &fnhead;
2299 arrindex = ARRAYBOT ;
2300 arrhead = NULL;
2301 arrtail = &arrhead;
2303 static void dbgbi_cleanup(void)
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);
2313 fnhead = fnhead->next;
2314 nasm_free (fntemp->name);
2315 nasm_free (fntemp);
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);
2325 while (arrhead) {
2326 struct Array *arrtmp = arrhead;
2327 arrhead = arrhead->next;
2328 nasm_free (arrtmp);
2332 static void dbgbi_linnum (const char *lnfname, long lineno, long segto)
2334 struct FileName *fn;
2335 struct LineNumber *ln;
2336 struct Segment *seg;
2338 if (segto == NO_SEG)
2339 return;
2342 * If `any_segs' is still FALSE, we must define a default
2343 * segment.
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");
2352 * Find the segment we are targetting.
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?");
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;
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;
2383 static void dbgbi_deflabel (char *name, long segment,
2384 long offset, int is_global, char *special)
2386 struct Segment *seg;
2388 (void) special;
2391 * If it's a special-retry from pass two, discard it.
2393 if (is_global == 3)
2394 return;
2397 * First check for the double-period, signifying something
2398 * unusual.
2400 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2401 return;
2405 * Case (i):
2407 if (obj_seg_needs_update) {
2408 return;
2409 } else if (obj_grp_needs_update) {
2410 return;
2412 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2413 return;
2415 if (segment >= SEG_ABS || segment == NO_SEG) {
2416 return;
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.
2426 for (seg = seghead; seg; seg = seg->next)
2427 if (seg->index == segment) {
2428 struct Public *loc = nasm_malloc (sizeof(*loc));
2430 * Case (ii). Maybe MODPUB someday?
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;
2439 static void dbgbi_typevalue (long type)
2441 int vsize;
2442 int elem = TYM_ELEMENTS(type);
2443 type = TYM_TYPE(type);
2445 if (!last_defined)
2446 return;
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;
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);
2489 last_defined = NULL;
2491 static void dbgbi_output (int output_type, void *param)
2493 (void) output_type;
2494 (void) param;
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,
2508 static struct dfmt *borland_debug_arr[3] = {
2509 &borland_debug_form,
2510 &null_debug_form,
2511 NULL
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
2531 #endif /* OF_OBJ */