Apply Nindent to all .c and .h files
[nasm.git] / output / outobj.c
blobd1464fc0cc6e413cc099be449707aff7207e5aae
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 */
122 typedef struct ObjRecord ObjRecord;
123 typedef void ORI(ObjRecord * orp);
125 struct ObjRecord {
126 ORI *ori; /* Initialization routine */
127 int used; /* Current data size */
128 int committed; /* Data size at last boundary */
129 int x_size; /* (see obj_x) */
130 unsigned int type; /* Record type */
131 ObjRecord *child; /* Associated record below this one */
132 ObjRecord **up; /* Master pointer to this ObjRecord */
133 ObjRecord *back; /* Previous part of this record */
134 unsigned long parm[OBJ_PARMS]; /* Parameters for ori routine */
135 unsigned char buf[RECORD_MAX + 3];
138 static void obj_fwrite(ObjRecord * orp);
139 static void ori_ledata(ObjRecord * orp);
140 static void ori_pubdef(ObjRecord * orp);
141 static void ori_null(ObjRecord * orp);
142 static ObjRecord *obj_commit(ObjRecord * orp);
144 static int obj_uppercase; /* Flag: all names in uppercase */
145 static int obj_use32; /* Flag: at least one segment is 32-bit */
148 * Clear an ObjRecord structure. (Never reallocates).
149 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
151 static ObjRecord *obj_clear(ObjRecord * orp)
153 orp->used = 0;
154 orp->committed = 0;
155 orp->x_size = 0;
156 orp->child = NULL;
157 orp->up = NULL;
158 orp->back = NULL;
159 return (orp);
163 * Emit an ObjRecord structure. (Never reallocates).
164 * The record is written out preceeded (recursively) by its previous part (if
165 * any) and followed (recursively) by its child (if any).
166 * The previous part and the child are freed. The main ObjRecord is cleared,
167 * not freed.
169 static ObjRecord *obj_emit(ObjRecord * orp)
171 if (orp->back) {
172 obj_emit(orp->back);
173 nasm_free(orp->back);
176 if (orp->committed)
177 obj_fwrite(orp);
179 if (orp->child) {
180 obj_emit(orp->child);
181 nasm_free(orp->child);
184 return (obj_clear(orp));
188 * Commit and Emit a record. (Never reallocates).
190 static ObjRecord *obj_emit2(ObjRecord * orp)
192 obj_commit(orp);
193 return (obj_emit(orp));
197 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
199 static ObjRecord *obj_new(void)
201 ObjRecord *orp;
203 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
204 orp->ori = ori_null;
205 return (orp);
209 * Advance to the next record because the existing one is full or its x_size
210 * is incompatible.
211 * Any uncommited data is moved into the next record.
213 static ObjRecord *obj_bump(ObjRecord * orp)
215 ObjRecord *nxt;
216 int used = orp->used;
217 int committed = orp->committed;
219 if (orp->up) {
220 *orp->up = nxt = obj_new();
221 nxt->ori = orp->ori;
222 nxt->type = orp->type;
223 nxt->up = orp->up;
224 nxt->back = orp;
225 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
226 } else
227 nxt = obj_emit(orp);
229 used -= committed;
230 if (used) {
231 nxt->committed = 1;
232 nxt->ori(nxt);
233 nxt->committed = nxt->used;
234 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
235 nxt->used = nxt->committed + used;
238 return (nxt);
242 * Advance to the next record if necessary to allow the next field to fit.
244 static ObjRecord *obj_check(ObjRecord * orp, int size)
246 if (orp->used + size > RECORD_MAX)
247 orp = obj_bump(orp);
249 if (!orp->committed) {
250 orp->committed = 1;
251 orp->ori(orp);
252 orp->committed = orp->used;
255 return (orp);
259 * All data written so far is commited to the current record (won't be moved to
260 * the next record in case of continuation).
262 static ObjRecord *obj_commit(ObjRecord * orp)
264 orp->committed = orp->used;
265 return (orp);
269 * Write a byte
271 static ObjRecord *obj_byte(ObjRecord * orp, unsigned char val)
273 orp = obj_check(orp, 1);
274 orp->buf[orp->used] = val;
275 orp->used++;
276 return (orp);
280 * Write a word
282 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
284 orp = obj_check(orp, 2);
285 orp->buf[orp->used] = val;
286 orp->buf[orp->used + 1] = val >> 8;
287 orp->used += 2;
288 return (orp);
292 * Write a reversed word
294 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
296 orp = obj_check(orp, 2);
297 orp->buf[orp->used] = val >> 8;
298 orp->buf[orp->used + 1] = val;
299 orp->used += 2;
300 return (orp);
304 * Write a dword
306 static ObjRecord *obj_dword(ObjRecord * orp, unsigned long val)
308 orp = obj_check(orp, 4);
309 orp->buf[orp->used] = val;
310 orp->buf[orp->used + 1] = val >> 8;
311 orp->buf[orp->used + 2] = val >> 16;
312 orp->buf[orp->used + 3] = val >> 24;
313 orp->used += 4;
314 return (orp);
318 * All fields of "size x" in one obj record must be the same size (either 16
319 * bits or 32 bits). There is a one bit flag in each record which specifies
320 * which.
321 * This routine is used to force the current record to have the desired
322 * x_size. x_size is normally automatic (using obj_x), so that this
323 * routine should be used outside obj_x, only to provide compatibility with
324 * linkers that have bugs in their processing of the size bit.
327 static ObjRecord *obj_force(ObjRecord * orp, int x)
329 if (orp->x_size == (x ^ 48))
330 orp = obj_bump(orp);
331 orp->x_size = x;
332 return (orp);
336 * This routine writes a field of size x. The caller does not need to worry at
337 * all about whether 16-bits or 32-bits are required.
339 static ObjRecord *obj_x(ObjRecord * orp, unsigned long val)
341 if (orp->type & 1)
342 orp->x_size = 32;
343 if (val > 0xFFFF)
344 orp = obj_force(orp, 32);
345 if (orp->x_size == 32)
346 return (obj_dword(orp, val));
347 orp->x_size = 16;
348 return (obj_word(orp, val));
352 * Writes an index
354 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
356 if (val < 128)
357 return (obj_byte(orp, val));
358 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
362 * Writes a variable length value
364 static ObjRecord *obj_value(ObjRecord * orp, unsigned long val)
366 if (val <= 128)
367 return (obj_byte(orp, val));
368 if (val <= 0xFFFF) {
369 orp = obj_byte(orp, 129);
370 return (obj_word(orp, val));
372 if (val <= 0xFFFFFF)
373 return (obj_dword(orp, (val << 8) + 132));
374 orp = obj_byte(orp, 136);
375 return (obj_dword(orp, val));
379 * Writes a counted string
381 static ObjRecord *obj_name(ObjRecord * orp, char *name)
383 int len = strlen(name);
384 unsigned char *ptr;
386 orp = obj_check(orp, len + 1);
387 ptr = orp->buf + orp->used;
388 *ptr++ = len;
389 orp->used += len + 1;
390 if (obj_uppercase)
391 while (--len >= 0) {
392 *ptr++ = toupper(*name);
393 name++;
394 } else
395 memcpy(ptr, name, len);
396 return (orp);
400 * Initializer for an LEDATA record.
401 * parm[0] = offset
402 * parm[1] = segment index
403 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
404 * represent the offset that would be required if the record were split at the
405 * last commit point.
406 * parm[2] is a copy of parm[0] as it was when the current record was initted.
408 static void ori_ledata(ObjRecord * orp)
410 obj_index(orp, orp->parm[1]);
411 orp->parm[2] = orp->parm[0];
412 obj_x(orp, orp->parm[0]);
416 * Initializer for a PUBDEF record.
417 * parm[0] = group index
418 * parm[1] = segment index
419 * parm[2] = frame (only used when both indexes are zero)
421 static void ori_pubdef(ObjRecord * orp)
423 obj_index(orp, orp->parm[0]);
424 obj_index(orp, orp->parm[1]);
425 if (!(orp->parm[0] | orp->parm[1]))
426 obj_word(orp, orp->parm[2]);
430 * Initializer for a LINNUM record.
431 * parm[0] = group index
432 * parm[1] = segment index
434 static void ori_linnum(ObjRecord * orp)
436 obj_index(orp, orp->parm[0]);
437 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 */
501 static struct Public {
502 struct Public *next;
503 char *name;
504 long offset;
505 long segment; /* only if it's far-absolute */
506 int type; /* only for local debug syms */
507 } *fpubhead, **fpubtail, *last_defined;
509 static struct External {
510 struct External *next;
511 char *name;
512 long commonsize;
513 long commonelem; /* element size if FAR, else zero */
514 int index; /* OBJ-file external index */
515 enum {
516 DEFWRT_NONE, /* no unusual default-WRT */
517 DEFWRT_STRING, /* a string we don't yet understand */
518 DEFWRT_SEGMENT, /* a segment */
519 DEFWRT_GROUP /* a group */
520 } defwrt_type;
521 union {
522 char *string;
523 struct Segment *seg;
524 struct Group *grp;
525 } defwrt_ptr;
526 struct External *next_dws; /* next with DEFWRT_STRING */
527 } *exthead, **exttail, *dws;
529 static int externals;
531 static struct ExtBack {
532 struct ExtBack *next;
533 struct External *exts[EXT_BLKSIZ];
534 } *ebhead, **ebtail;
536 static struct Segment {
537 struct Segment *next;
538 long index; /* the NASM segment id */
539 long obj_index; /* the OBJ-file segment index */
540 struct Group *grp; /* the group it belongs to */
541 unsigned long currentpos;
542 long align; /* can be SEG_ABS + absolute addr */
543 enum {
544 CMB_PRIVATE = 0,
545 CMB_PUBLIC = 2,
546 CMB_STACK = 5,
547 CMB_COMMON = 6
548 } combine;
549 long use32; /* is this segment 32-bit? */
550 struct Public *pubhead, **pubtail, *lochead, **loctail;
551 char *name;
552 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
553 ObjRecord *orp;
554 } *seghead, **segtail, *obj_seg_needs_update;
556 static struct Group {
557 struct Group *next;
558 char *name;
559 long index; /* NASM segment id */
560 long obj_index; /* OBJ-file group index */
561 long nentries; /* number of elements... */
562 long nindices; /* ...and number of index elts... */
563 union {
564 long index;
565 char *name;
566 } segs[GROUP_MAX]; /* ...in this */
567 } *grphead, **grptail, *obj_grp_needs_update;
569 static struct ImpDef {
570 struct ImpDef *next;
571 char *extname;
572 char *libname;
573 unsigned int impindex;
574 char *impname;
575 } *imphead, **imptail;
577 static struct ExpDef {
578 struct ExpDef *next;
579 char *intname;
580 char *extname;
581 unsigned int ordinal;
582 int flags;
583 } *exphead, **exptail;
585 #define EXPDEF_FLAG_ORDINAL 0x80
586 #define EXPDEF_FLAG_RESIDENT 0x40
587 #define EXPDEF_FLAG_NODATA 0x20
588 #define EXPDEF_MASK_PARMCNT 0x1F
590 static long obj_entry_seg, obj_entry_ofs;
592 struct ofmt of_obj;
594 /* The current segment */
595 static struct Segment *current_seg;
597 static long obj_segment(char *, int, int *);
598 static void obj_write_file(int debuginfo);
599 static int obj_directive(char *, char *, int);
601 static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
603 ofp = fp;
604 error = errfunc;
605 evaluate = eval;
606 deflabel = ldef;
607 first_seg = seg_alloc();
608 any_segs = FALSE;
609 fpubhead = NULL;
610 fpubtail = &fpubhead;
611 exthead = NULL;
612 exttail = &exthead;
613 imphead = NULL;
614 imptail = &imphead;
615 exphead = NULL;
616 exptail = &exphead;
617 dws = NULL;
618 externals = 0;
619 ebhead = NULL;
620 ebtail = &ebhead;
621 seghead = obj_seg_needs_update = NULL;
622 segtail = &seghead;
623 grphead = obj_grp_needs_update = NULL;
624 grptail = &grphead;
625 obj_entry_seg = NO_SEG;
626 obj_uppercase = FALSE;
627 obj_use32 = FALSE;
628 passtwo = 0;
629 current_seg = NULL;
631 of_obj.current_dfmt->init(&of_obj, NULL, fp, errfunc);
634 static int obj_set_info(enum geninfo type, char **val)
636 (void)type;
637 (void)val;
639 return 0;
641 static void obj_cleanup(int debuginfo)
643 obj_write_file(debuginfo);
644 of_obj.current_dfmt->cleanup();
645 fclose(ofp);
646 while (seghead) {
647 struct Segment *segtmp = seghead;
648 seghead = seghead->next;
649 while (segtmp->pubhead) {
650 struct Public *pubtmp = segtmp->pubhead;
651 segtmp->pubhead = pubtmp->next;
652 nasm_free(pubtmp->name);
653 nasm_free(pubtmp);
655 nasm_free(segtmp->segclass);
656 nasm_free(segtmp->overlay);
657 nasm_free(segtmp);
659 while (fpubhead) {
660 struct Public *pubtmp = fpubhead;
661 fpubhead = fpubhead->next;
662 nasm_free(pubtmp->name);
663 nasm_free(pubtmp);
665 while (exthead) {
666 struct External *exttmp = exthead;
667 exthead = exthead->next;
668 nasm_free(exttmp);
670 while (imphead) {
671 struct ImpDef *imptmp = imphead;
672 imphead = imphead->next;
673 nasm_free(imptmp->extname);
674 nasm_free(imptmp->libname);
675 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
676 nasm_free(imptmp);
678 while (exphead) {
679 struct ExpDef *exptmp = exphead;
680 exphead = exphead->next;
681 nasm_free(exptmp->extname);
682 nasm_free(exptmp->intname);
683 nasm_free(exptmp);
685 while (ebhead) {
686 struct ExtBack *ebtmp = ebhead;
687 ebhead = ebhead->next;
688 nasm_free(ebtmp);
690 while (grphead) {
691 struct Group *grptmp = grphead;
692 grphead = grphead->next;
693 nasm_free(grptmp);
697 static void obj_ext_set_defwrt(struct External *ext, char *id)
699 struct Segment *seg;
700 struct Group *grp;
702 for (seg = seghead; seg; seg = seg->next)
703 if (!strcmp(seg->name, id)) {
704 ext->defwrt_type = DEFWRT_SEGMENT;
705 ext->defwrt_ptr.seg = seg;
706 nasm_free(id);
707 return;
710 for (grp = grphead; grp; grp = grp->next)
711 if (!strcmp(grp->name, id)) {
712 ext->defwrt_type = DEFWRT_GROUP;
713 ext->defwrt_ptr.grp = grp;
714 nasm_free(id);
715 return;
718 ext->defwrt_type = DEFWRT_STRING;
719 ext->defwrt_ptr.string = id;
720 ext->next_dws = dws;
721 dws = ext;
724 static void obj_deflabel(char *name, long segment,
725 long offset, int is_global, char *special)
728 * We have three cases:
730 * (i) `segment' is a segment-base. If so, set the name field
731 * for the segment or group structure it refers to, and then
732 * return.
734 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
735 * Save the label position for later output of a PUBDEF record.
736 * (Or a MODPUB, if we work out how.)
738 * (iii) `segment' is not one of our segments. Save the label
739 * position for later output of an EXTDEF, and also store a
740 * back-reference so that we can map later references to this
741 * segment number to the external index.
743 struct External *ext;
744 struct ExtBack *eb;
745 struct Segment *seg;
746 int i;
747 int used_special = FALSE; /* have we used the special text? */
749 #if defined(DEBUG) && DEBUG>2
750 fprintf(stderr,
751 " 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,
832 "OBJ supports no special symbol features"
833 " for this symbol type");
834 return;
838 * Case (iii).
840 if (is_global) {
841 ext = *exttail = nasm_malloc(sizeof(*ext));
842 ext->next = NULL;
843 exttail = &ext->next;
844 ext->name = name;
845 /* Place by default all externs into the current segment */
846 ext->defwrt_type = DEFWRT_NONE;
848 /* 28-Apr-2002 - John Coffman
849 The following code was introduced on 12-Aug-2000, and breaks fixups
850 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
851 (5.10). It was introduced after FIXUP32 was added, and may be needed
852 for 32-bit segments. The following will get 16-bit segments working
853 again, and maybe someone can correct the 'if' condition which is
854 actually needed.
856 #if 0
857 if (current_seg) {
858 #else
859 if (current_seg && current_seg->use32) {
860 if (current_seg->grp) {
861 ext->defwrt_type = DEFWRT_GROUP;
862 ext->defwrt_ptr.grp = current_seg->grp;
863 } else {
864 ext->defwrt_type = DEFWRT_SEGMENT;
865 ext->defwrt_ptr.seg = current_seg;
868 #endif
870 if (is_global == 2) {
871 ext->commonsize = offset;
872 ext->commonelem = 1; /* default FAR */
873 } else
874 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,
913 "`%s': `far' keyword may only be applied"
914 " to common variables\n", ext->name);
915 special += 3;
916 special += strspn(special, " \t");
917 } else if (!nasm_strnicmp(special, "near", 4)) {
918 if (ext->commonsize)
919 ext->commonelem = 0;
920 else
921 error(ERR_NONFATAL,
922 "`%s': `far' keyword may only be applied"
923 " to common variables\n", ext->name);
924 special += 4;
925 special += strspn(special, " \t");
929 * If it's a common, and anything else remains on the line
930 * before a further colon, evaluate it as an expression and
931 * use that as the element size. Forward references aren't
932 * allowed.
934 if (*special == ':')
935 special++;
936 else if (*special) {
937 if (ext->commonsize) {
938 expr *e;
939 struct tokenval tokval;
941 stdscan_reset();
942 stdscan_bufptr = special;
943 tokval.t_type = TOKEN_INVALID;
944 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
945 if (e) {
946 if (!is_simple(e))
947 error(ERR_NONFATAL, "cannot use relocatable"
948 " expression as common-variable element size");
949 else
950 ext->commonelem = reloc_value(e);
952 special = stdscan_bufptr;
953 } else {
954 error(ERR_NONFATAL,
955 "`%s': element-size specifications only"
956 " apply to common variables", ext->name);
957 while (*special && *special != ':')
958 special++;
959 if (*special == ':')
960 special++;
965 i = segment / 2;
966 eb = ebhead;
967 if (!eb) {
968 eb = *ebtail = nasm_malloc(sizeof(*eb));
969 eb->next = NULL;
970 ebtail = &eb->next;
972 while (i >= EXT_BLKSIZ) {
973 if (eb && eb->next)
974 eb = eb->next;
975 else {
976 eb = *ebtail = nasm_malloc(sizeof(*eb));
977 eb->next = NULL;
978 ebtail = &eb->next;
980 i -= EXT_BLKSIZ;
982 eb->exts[i] = ext;
983 ext->index = ++externals;
985 if (special && !used_special)
986 error(ERR_NONFATAL, "OBJ supports no special symbol features"
987 " for this symbol type");
990 /* forward declaration */
991 static void obj_write_fixup(ObjRecord * orp, int bytes,
992 int segrel, long seg, long wrt,
993 struct Segment *segto);
995 static void obj_out(long segto, const void *data, unsigned long type,
996 long segment, long wrt)
998 unsigned long size, realtype;
999 const unsigned char *ucdata;
1000 long ldata;
1001 struct Segment *seg;
1002 ObjRecord *orp;
1005 * handle absolute-assembly (structure definitions)
1007 if (segto == NO_SEG) {
1008 if ((type & OUT_TYPMASK) != OUT_RESERVE)
1009 error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1010 " space");
1011 return;
1015 * If `any_segs' is still FALSE, we must define a default
1016 * segment.
1018 if (!any_segs) {
1019 int tempint; /* ignored */
1020 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1021 error(ERR_PANIC, "strange segment conditions in OBJ driver");
1025 * Find the segment we are targetting.
1027 for (seg = seghead; seg; seg = seg->next)
1028 if (seg->index == segto)
1029 break;
1030 if (!seg)
1031 error(ERR_PANIC, "code directed to nonexistent segment?");
1033 orp = seg->orp;
1034 orp->parm[0] = seg->currentpos;
1036 size = type & OUT_SIZMASK;
1037 realtype = type & OUT_TYPMASK;
1038 if (realtype == OUT_RAWDATA) {
1039 ucdata = data;
1040 while (size > 0) {
1041 unsigned int len;
1042 orp = obj_check(seg->orp, 1);
1043 len = RECORD_MAX - orp->used;
1044 if (len > size)
1045 len = size;
1046 memcpy(orp->buf + orp->used, ucdata, len);
1047 orp->committed = orp->used += len;
1048 orp->parm[0] = seg->currentpos += len;
1049 ucdata += len;
1050 size -= len;
1052 } else if (realtype == OUT_ADDRESS || realtype == OUT_REL2ADR ||
1053 realtype == OUT_REL4ADR) {
1054 int rsize;
1056 if (segment == NO_SEG && realtype != OUT_ADDRESS)
1057 error(ERR_NONFATAL, "relative call to absolute address not"
1058 " supported by OBJ format");
1059 if (segment >= SEG_ABS)
1060 error(ERR_NONFATAL, "far-absolute relocations not supported"
1061 " by OBJ format");
1062 ldata = *(long *)data;
1063 if (realtype == OUT_REL2ADR) {
1064 ldata += (size - 2);
1065 size = 2;
1067 if (realtype == OUT_REL4ADR) {
1068 ldata += (size - 4);
1069 size = 4;
1071 if (size == 2)
1072 orp = obj_word(orp, ldata);
1073 else
1074 orp = obj_dword(orp, ldata);
1075 rsize = size;
1076 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1077 size == 4) {
1079 * This is a 4-byte segment-base relocation such as
1080 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1081 * these, but if the constant term has the 16 low bits
1082 * zero, we can just apply a 2-byte segment-base
1083 * relocation to the low word instead.
1085 rsize = 2;
1086 if (ldata & 0xFFFF)
1087 error(ERR_NONFATAL, "OBJ format cannot handle complex"
1088 " dword-size segment base references");
1090 if (segment != NO_SEG)
1091 obj_write_fixup(orp, rsize,
1092 (realtype == OUT_ADDRESS ? 0x4000 : 0),
1093 segment, wrt, seg);
1094 seg->currentpos += size;
1095 } else if (realtype == OUT_RESERVE) {
1096 if (orp->committed)
1097 orp = obj_bump(orp);
1098 seg->currentpos += size;
1100 obj_commit(orp);
1103 static void obj_write_fixup(ObjRecord * orp, int bytes,
1104 int segrel, long seg, long wrt,
1105 struct Segment *segto)
1107 unsigned locat;
1108 int method;
1109 int base;
1110 long tidx, fidx;
1111 struct Segment *s = NULL;
1112 struct Group *g = NULL;
1113 struct External *e = NULL;
1114 ObjRecord *forp;
1116 if (bytes == 1) {
1117 error(ERR_NONFATAL, "`obj' output driver does not support"
1118 " one-byte relocations");
1119 return;
1122 forp = orp->child;
1123 if (forp == NULL) {
1124 orp->child = forp = obj_new();
1125 forp->up = &(orp->child);
1126 /* We should choose between FIXUPP and FIXU32 record type */
1127 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1128 if (segto->use32)
1129 forp->type = FIXU32;
1130 else
1131 forp->type = FIXUPP;
1134 if (seg % 2) {
1135 base = TRUE;
1136 locat = FIX_16_SELECTOR;
1137 seg--;
1138 if (bytes != 2)
1139 error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1140 " through sanity check");
1141 } else {
1142 base = FALSE;
1143 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1144 if (!segrel)
1146 * There is a bug in tlink that makes it process self relative
1147 * fixups incorrectly if the x_size doesn't match the location
1148 * size.
1150 forp = obj_force(forp, bytes << 3);
1153 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1155 tidx = fidx = -1, method = 0; /* placate optimisers */
1158 * See if we can find the segment ID in our segment list. If
1159 * so, we have a T4 (LSEG) target.
1161 for (s = seghead; s; s = s->next)
1162 if (s->index == seg)
1163 break;
1164 if (s)
1165 method = 4, tidx = s->obj_index;
1166 else {
1167 for (g = grphead; g; g = g->next)
1168 if (g->index == seg)
1169 break;
1170 if (g)
1171 method = 5, tidx = g->obj_index;
1172 else {
1173 long i = seg / 2;
1174 struct ExtBack *eb = ebhead;
1175 while (i > EXT_BLKSIZ) {
1176 if (eb)
1177 eb = eb->next;
1178 else
1179 break;
1180 i -= EXT_BLKSIZ;
1182 if (eb)
1183 method = 6, e = eb->exts[i], tidx = e->index;
1184 else
1185 error(ERR_PANIC,
1186 "unrecognised segment value in obj_write_fixup");
1191 * If no WRT given, assume the natural default, which is method
1192 * F5 unless:
1194 * - we are doing an OFFSET fixup for a grouped segment, in
1195 * which case we require F1 (group).
1197 * - we are doing an OFFSET fixup for an external with a
1198 * default WRT, in which case we must honour the default WRT.
1200 if (wrt == NO_SEG) {
1201 if (!base && s && s->grp)
1202 method |= 0x10, fidx = s->grp->obj_index;
1203 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1204 if (e->defwrt_type == DEFWRT_SEGMENT)
1205 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1206 else if (e->defwrt_type == DEFWRT_GROUP)
1207 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1208 else {
1209 error(ERR_NONFATAL, "default WRT specification for"
1210 " external `%s' unresolved", e->name);
1211 method |= 0x50, fidx = -1; /* got to do _something_ */
1213 } else
1214 method |= 0x50, fidx = -1;
1215 } else {
1217 * See if we can find the WRT-segment ID in our segment
1218 * list. If so, we have a F0 (LSEG) frame.
1220 for (s = seghead; s; s = s->next)
1221 if (s->index == wrt - 1)
1222 break;
1223 if (s)
1224 method |= 0x00, fidx = s->obj_index;
1225 else {
1226 for (g = grphead; g; g = g->next)
1227 if (g->index == wrt - 1)
1228 break;
1229 if (g)
1230 method |= 0x10, fidx = g->obj_index;
1231 else {
1232 long i = wrt / 2;
1233 struct ExtBack *eb = ebhead;
1234 while (i > EXT_BLKSIZ) {
1235 if (eb)
1236 eb = eb->next;
1237 else
1238 break;
1239 i -= EXT_BLKSIZ;
1241 if (eb)
1242 method |= 0x20, fidx = eb->exts[i]->index;
1243 else
1244 error(ERR_PANIC,
1245 "unrecognised WRT value in obj_write_fixup");
1250 forp = obj_byte(forp, method);
1251 if (fidx != -1)
1252 forp = obj_index(forp, fidx);
1253 forp = obj_index(forp, tidx);
1254 obj_commit(forp);
1257 static long obj_segment(char *name, int pass, int *bits)
1260 * We call the label manager here to define a name for the new
1261 * segment, and when our _own_ label-definition stub gets
1262 * called in return, it should register the new segment name
1263 * using the pointer it gets passed. That way we save memory,
1264 * by sponging off the label manager.
1266 #if defined(DEBUG) && DEBUG>=3
1267 fprintf(stderr, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1268 name, pass, *bits);
1269 #endif
1270 if (!name) {
1271 *bits = 16;
1272 current_seg = NULL;
1273 return first_seg;
1274 } else {
1275 struct Segment *seg;
1276 struct Group *grp;
1277 struct External **extp;
1278 int obj_idx, i, attrs, rn_error;
1279 char *p;
1282 * Look for segment attributes.
1284 attrs = 0;
1285 while (*name == '.')
1286 name++; /* hack, but a documented one */
1287 p = name;
1288 while (*p && !isspace(*p))
1289 p++;
1290 if (*p) {
1291 *p++ = '\0';
1292 while (*p && isspace(*p))
1293 *p++ = '\0';
1295 while (*p) {
1296 while (*p && !isspace(*p))
1297 p++;
1298 if (*p) {
1299 *p++ = '\0';
1300 while (*p && isspace(*p))
1301 *p++ = '\0';
1304 attrs++;
1307 obj_idx = 1;
1308 for (seg = seghead; seg; seg = seg->next) {
1309 obj_idx++;
1310 if (!strcmp(seg->name, name)) {
1311 if (attrs > 0 && pass == 1)
1312 error(ERR_WARNING, "segment attributes specified on"
1313 " redeclaration of segment: ignoring");
1314 if (seg->use32)
1315 *bits = 32;
1316 else
1317 *bits = 16;
1318 current_seg = seg;
1319 return seg->index;
1323 *segtail = seg = nasm_malloc(sizeof(*seg));
1324 seg->next = NULL;
1325 segtail = &seg->next;
1326 seg->index = (any_segs ? seg_alloc() : first_seg);
1327 seg->obj_index = obj_idx;
1328 seg->grp = NULL;
1329 any_segs = TRUE;
1330 seg->name = NULL;
1331 seg->currentpos = 0;
1332 seg->align = 1; /* default */
1333 seg->use32 = FALSE; /* default */
1334 seg->combine = CMB_PUBLIC; /* default */
1335 seg->segclass = seg->overlay = NULL;
1336 seg->pubhead = NULL;
1337 seg->pubtail = &seg->pubhead;
1338 seg->lochead = NULL;
1339 seg->loctail = &seg->lochead;
1340 seg->orp = obj_new();
1341 seg->orp->up = &(seg->orp);
1342 seg->orp->ori = ori_ledata;
1343 seg->orp->type = LEDATA;
1344 seg->orp->parm[1] = obj_idx;
1347 * Process the segment attributes.
1349 p = name;
1350 while (attrs--) {
1351 p += strlen(p);
1352 while (!*p)
1353 p++;
1356 * `p' contains a segment attribute.
1358 if (!nasm_stricmp(p, "private"))
1359 seg->combine = CMB_PRIVATE;
1360 else if (!nasm_stricmp(p, "public"))
1361 seg->combine = CMB_PUBLIC;
1362 else if (!nasm_stricmp(p, "common"))
1363 seg->combine = CMB_COMMON;
1364 else if (!nasm_stricmp(p, "stack"))
1365 seg->combine = CMB_STACK;
1366 else if (!nasm_stricmp(p, "use16"))
1367 seg->use32 = FALSE;
1368 else if (!nasm_stricmp(p, "use32"))
1369 seg->use32 = TRUE;
1370 else if (!nasm_stricmp(p, "flat")) {
1372 * This segment is an OS/2 FLAT segment. That means
1373 * that its default group is group FLAT, even if
1374 * the group FLAT does not explicitly _contain_ the
1375 * segment.
1377 * When we see this, we must create the group
1378 * `FLAT', containing no segments, if it does not
1379 * already exist; then we must set the default
1380 * group of this segment to be the FLAT group.
1382 struct Group *grp;
1383 for (grp = grphead; grp; grp = grp->next)
1384 if (!strcmp(grp->name, "FLAT"))
1385 break;
1386 if (!grp) {
1387 obj_directive("group", "FLAT", 1);
1388 for (grp = grphead; grp; grp = grp->next)
1389 if (!strcmp(grp->name, "FLAT"))
1390 break;
1391 if (!grp)
1392 error(ERR_PANIC, "failure to define FLAT?!");
1394 seg->grp = grp;
1395 } else if (!nasm_strnicmp(p, "class=", 6))
1396 seg->segclass = nasm_strdup(p + 6);
1397 else if (!nasm_strnicmp(p, "overlay=", 8))
1398 seg->overlay = nasm_strdup(p + 8);
1399 else if (!nasm_strnicmp(p, "align=", 6)) {
1400 seg->align = readnum(p + 6, &rn_error);
1401 if (rn_error) {
1402 seg->align = 1;
1403 error(ERR_NONFATAL, "segment alignment should be"
1404 " numeric");
1406 switch ((int)seg->align) {
1407 case 1: /* BYTE */
1408 case 2: /* WORD */
1409 case 4: /* DWORD */
1410 case 16: /* PARA */
1411 case 256: /* PAGE */
1412 case 4096: /* PharLap extension */
1413 break;
1414 case 8:
1415 error(ERR_WARNING,
1416 "OBJ format does not support alignment"
1417 " of 8: rounding up to 16");
1418 seg->align = 16;
1419 break;
1420 case 32:
1421 case 64:
1422 case 128:
1423 error(ERR_WARNING,
1424 "OBJ format does not support alignment"
1425 " of %d: rounding up to 256", seg->align);
1426 seg->align = 256;
1427 break;
1428 case 512:
1429 case 1024:
1430 case 2048:
1431 error(ERR_WARNING,
1432 "OBJ format does not support alignment"
1433 " of %d: rounding up to 4096", seg->align);
1434 seg->align = 4096;
1435 break;
1436 default:
1437 error(ERR_NONFATAL, "invalid alignment value %d",
1438 seg->align);
1439 seg->align = 1;
1440 break;
1442 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1443 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1444 if (rn_error)
1445 error(ERR_NONFATAL, "argument to `absolute' segment"
1446 " attribute should be numeric");
1450 /* We need to know whenever we have at least one 32-bit segment */
1451 obj_use32 |= seg->use32;
1453 obj_seg_needs_update = seg;
1454 if (seg->align >= SEG_ABS)
1455 deflabel(name, NO_SEG, seg->align - SEG_ABS,
1456 NULL, FALSE, FALSE, &of_obj, error);
1457 else
1458 deflabel(name, seg->index + 1, 0L,
1459 NULL, FALSE, FALSE, &of_obj, error);
1460 obj_seg_needs_update = NULL;
1463 * See if this segment is defined in any groups.
1465 for (grp = grphead; grp; grp = grp->next) {
1466 for (i = grp->nindices; i < grp->nentries; i++) {
1467 if (!strcmp(grp->segs[i].name, seg->name)) {
1468 nasm_free(grp->segs[i].name);
1469 grp->segs[i] = grp->segs[grp->nindices];
1470 grp->segs[grp->nindices++].index = seg->obj_index;
1471 if (seg->grp)
1472 error(ERR_WARNING,
1473 "segment `%s' is already part of"
1474 " a group: first one takes precedence",
1475 seg->name);
1476 else
1477 seg->grp = grp;
1483 * Walk through the list of externals with unresolved
1484 * default-WRT clauses, and resolve any that point at this
1485 * segment.
1487 extp = &dws;
1488 while (*extp) {
1489 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1490 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1491 nasm_free((*extp)->defwrt_ptr.string);
1492 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1493 (*extp)->defwrt_ptr.seg = seg;
1494 *extp = (*extp)->next_dws;
1495 } else
1496 extp = &(*extp)->next_dws;
1499 if (seg->use32)
1500 *bits = 32;
1501 else
1502 *bits = 16;
1503 current_seg = seg;
1504 return seg->index;
1508 static int obj_directive(char *directive, char *value, int pass)
1510 if (!strcmp(directive, "group")) {
1511 char *p, *q, *v;
1512 if (pass == 1) {
1513 struct Group *grp;
1514 struct Segment *seg;
1515 struct External **extp;
1516 int obj_idx;
1518 q = value;
1519 while (*q == '.')
1520 q++; /* hack, but a documented one */
1521 v = q;
1522 while (*q && !isspace(*q))
1523 q++;
1524 if (isspace(*q)) {
1525 *q++ = '\0';
1526 while (*q && isspace(*q))
1527 q++;
1530 * Here we used to sanity-check the group directive to
1531 * ensure nobody tried to declare a group containing no
1532 * segments. However, OS/2 does this as standard
1533 * practice, so the sanity check has been removed.
1535 * if (!*q) {
1536 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1537 * return 1;
1541 obj_idx = 1;
1542 for (grp = grphead; grp; grp = grp->next) {
1543 obj_idx++;
1544 if (!strcmp(grp->name, v)) {
1545 error(ERR_NONFATAL, "group `%s' defined twice", v);
1546 return 1;
1550 *grptail = grp = nasm_malloc(sizeof(*grp));
1551 grp->next = NULL;
1552 grptail = &grp->next;
1553 grp->index = seg_alloc();
1554 grp->obj_index = obj_idx;
1555 grp->nindices = grp->nentries = 0;
1556 grp->name = NULL;
1558 obj_grp_needs_update = grp;
1559 deflabel(v, grp->index + 1, 0L,
1560 NULL, FALSE, FALSE, &of_obj, error);
1561 obj_grp_needs_update = NULL;
1563 while (*q) {
1564 p = q;
1565 while (*q && !isspace(*q))
1566 q++;
1567 if (isspace(*q)) {
1568 *q++ = '\0';
1569 while (*q && isspace(*q))
1570 q++;
1573 * Now p contains a segment name. Find it.
1575 for (seg = seghead; seg; seg = seg->next)
1576 if (!strcmp(seg->name, p))
1577 break;
1578 if (seg) {
1580 * We have a segment index. Shift a name entry
1581 * to the end of the array to make room.
1583 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1584 grp->segs[grp->nindices++].index = seg->obj_index;
1585 if (seg->grp)
1586 error(ERR_WARNING,
1587 "segment `%s' is already part of"
1588 " a group: first one takes precedence",
1589 seg->name);
1590 else
1591 seg->grp = grp;
1592 } else {
1594 * We have an as-yet undefined segment.
1595 * Remember its name, for later.
1597 grp->segs[grp->nentries++].name = nasm_strdup(p);
1602 * Walk through the list of externals with unresolved
1603 * default-WRT clauses, and resolve any that point at
1604 * this group.
1606 extp = &dws;
1607 while (*extp) {
1608 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1609 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1610 nasm_free((*extp)->defwrt_ptr.string);
1611 (*extp)->defwrt_type = DEFWRT_GROUP;
1612 (*extp)->defwrt_ptr.grp = grp;
1613 *extp = (*extp)->next_dws;
1614 } else
1615 extp = &(*extp)->next_dws;
1618 return 1;
1620 if (!strcmp(directive, "uppercase")) {
1621 obj_uppercase = TRUE;
1622 return 1;
1624 if (!strcmp(directive, "import")) {
1625 char *q, *extname, *libname, *impname;
1627 if (pass == 2)
1628 return 1; /* ignore in pass two */
1629 extname = q = value;
1630 while (*q && !isspace(*q))
1631 q++;
1632 if (isspace(*q)) {
1633 *q++ = '\0';
1634 while (*q && isspace(*q))
1635 q++;
1638 libname = q;
1639 while (*q && !isspace(*q))
1640 q++;
1641 if (isspace(*q)) {
1642 *q++ = '\0';
1643 while (*q && isspace(*q))
1644 q++;
1647 impname = q;
1649 if (!*extname || !*libname)
1650 error(ERR_NONFATAL, "`import' directive requires symbol name"
1651 " and library name");
1652 else {
1653 struct ImpDef *imp;
1654 int err = FALSE;
1656 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1657 imptail = &imp->next;
1658 imp->next = NULL;
1659 imp->extname = nasm_strdup(extname);
1660 imp->libname = nasm_strdup(libname);
1661 imp->impindex = readnum(impname, &err);
1662 if (!*impname || err)
1663 imp->impname = nasm_strdup(impname);
1664 else
1665 imp->impname = NULL;
1668 return 1;
1670 if (!strcmp(directive, "export")) {
1671 char *q, *extname, *intname, *v;
1672 struct ExpDef *export;
1673 int flags = 0;
1674 unsigned int ordinal = 0;
1676 if (pass == 2)
1677 return 1; /* ignore in pass two */
1678 intname = q = value;
1679 while (*q && !isspace(*q))
1680 q++;
1681 if (isspace(*q)) {
1682 *q++ = '\0';
1683 while (*q && isspace(*q))
1684 q++;
1687 extname = q;
1688 while (*q && !isspace(*q))
1689 q++;
1690 if (isspace(*q)) {
1691 *q++ = '\0';
1692 while (*q && isspace(*q))
1693 q++;
1696 if (!*intname) {
1697 error(ERR_NONFATAL, "`export' directive requires export name");
1698 return 1;
1700 if (!*extname) {
1701 extname = intname;
1702 intname = "";
1704 while (*q) {
1705 v = q;
1706 while (*q && !isspace(*q))
1707 q++;
1708 if (isspace(*q)) {
1709 *q++ = '\0';
1710 while (*q && isspace(*q))
1711 q++;
1713 if (!nasm_stricmp(v, "resident"))
1714 flags |= EXPDEF_FLAG_RESIDENT;
1715 else if (!nasm_stricmp(v, "nodata"))
1716 flags |= EXPDEF_FLAG_NODATA;
1717 else if (!nasm_strnicmp(v, "parm=", 5)) {
1718 int err = FALSE;
1719 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1720 if (err) {
1721 error(ERR_NONFATAL,
1722 "value `%s' for `parm' is non-numeric", v + 5);
1723 return 1;
1725 } else {
1726 int err = FALSE;
1727 ordinal = readnum(v, &err);
1728 if (err) {
1729 error(ERR_NONFATAL,
1730 "unrecognised export qualifier `%s'", v);
1731 return 1;
1733 flags |= EXPDEF_FLAG_ORDINAL;
1737 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1738 exptail = &export->next;
1739 export->next = NULL;
1740 export->extname = nasm_strdup(extname);
1741 export->intname = nasm_strdup(intname);
1742 export->ordinal = ordinal;
1743 export->flags = flags;
1745 return 1;
1747 return 0;
1750 static long obj_segbase(long segment)
1752 struct Segment *seg;
1755 * Find the segment in our list.
1757 for (seg = seghead; seg; seg = seg->next)
1758 if (seg->index == segment - 1)
1759 break;
1761 if (!seg) {
1763 * Might be an external with a default WRT.
1765 long i = segment / 2;
1766 struct ExtBack *eb = ebhead;
1767 struct External *e;
1769 while (i > EXT_BLKSIZ) {
1770 if (eb)
1771 eb = eb->next;
1772 else
1773 break;
1774 i -= EXT_BLKSIZ;
1776 if (eb) {
1777 e = eb->exts[i];
1778 if (e->defwrt_type == DEFWRT_NONE)
1779 return segment; /* fine */
1780 else if (e->defwrt_type == DEFWRT_SEGMENT)
1781 return e->defwrt_ptr.seg->index + 1;
1782 else if (e->defwrt_type == DEFWRT_GROUP)
1783 return e->defwrt_ptr.grp->index + 1;
1784 else
1785 return NO_SEG; /* can't tell what it is */
1788 return segment; /* not one of ours - leave it alone */
1791 if (seg->align >= SEG_ABS)
1792 return seg->align; /* absolute segment */
1793 if (seg->grp)
1794 return seg->grp->index + 1; /* grouped segment */
1796 return segment; /* no special treatment */
1799 static void obj_filename(char *inname, char *outname, efunc lerror)
1801 strcpy(obj_infile, inname);
1802 standard_extension(inname, outname, ".obj", lerror);
1805 static void obj_write_file(int debuginfo)
1807 struct Segment *seg, *entry_seg_ptr = 0;
1808 struct FileName *fn;
1809 struct LineNumber *ln;
1810 struct Group *grp;
1811 struct Public *pub, *loc;
1812 struct External *ext;
1813 struct ImpDef *imp;
1814 struct ExpDef *export;
1815 static char boast[] = "The Netwide Assembler " NASM_VER;
1816 int lname_idx;
1817 ObjRecord *orp;
1820 * Write the THEADR module header.
1822 orp = obj_new();
1823 orp->type = THEADR;
1824 obj_name(orp, obj_infile);
1825 obj_emit2(orp);
1828 * Write the NASM boast comment.
1830 orp->type = COMENT;
1831 obj_rword(orp, 0); /* comment type zero */
1832 obj_name(orp, boast);
1833 obj_emit2(orp);
1835 orp->type = COMENT;
1837 * Write the IMPDEF records, if any.
1839 for (imp = imphead; imp; imp = imp->next) {
1840 obj_rword(orp, 0xA0); /* comment class A0 */
1841 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1842 if (imp->impname)
1843 obj_byte(orp, 0); /* import by name */
1844 else
1845 obj_byte(orp, 1); /* import by ordinal */
1846 obj_name(orp, imp->extname);
1847 obj_name(orp, imp->libname);
1848 if (imp->impname)
1849 obj_name(orp, imp->impname);
1850 else
1851 obj_word(orp, imp->impindex);
1852 obj_emit2(orp);
1856 * Write the EXPDEF records, if any.
1858 for (export = exphead; export; export = export->next) {
1859 obj_rword(orp, 0xA0); /* comment class A0 */
1860 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1861 obj_byte(orp, export->flags);
1862 obj_name(orp, export->extname);
1863 obj_name(orp, export->intname);
1864 if (export->flags & EXPDEF_FLAG_ORDINAL)
1865 obj_word(orp, export->ordinal);
1866 obj_emit2(orp);
1869 /* we're using extended OMF if we put in debug info */
1870 if (debuginfo) {
1871 orp->type = COMENT;
1872 obj_byte(orp, 0x40);
1873 obj_byte(orp, dEXTENDED);
1874 obj_emit2(orp);
1878 * Write the first LNAMES record, containing LNAME one, which
1879 * is null. Also initialise the LNAME counter.
1881 orp->type = LNAMES;
1882 obj_byte(orp, 0);
1883 lname_idx = 1;
1885 * Write some LNAMES for the segment names
1887 for (seg = seghead; seg; seg = seg->next) {
1888 orp = obj_name(orp, seg->name);
1889 if (seg->segclass)
1890 orp = obj_name(orp, seg->segclass);
1891 if (seg->overlay)
1892 orp = obj_name(orp, seg->overlay);
1893 obj_commit(orp);
1896 * Write some LNAMES for the group names
1898 for (grp = grphead; grp; grp = grp->next) {
1899 orp = obj_name(orp, grp->name);
1900 obj_commit(orp);
1902 obj_emit(orp);
1905 * Write the SEGDEF records.
1907 orp->type = SEGDEF;
1908 for (seg = seghead; seg; seg = seg->next) {
1909 int acbp;
1910 unsigned long seglen = seg->currentpos;
1912 acbp = (seg->combine << 2); /* C field */
1914 if (seg->use32)
1915 acbp |= 0x01; /* P bit is Use32 flag */
1916 else if (seglen == 0x10000L) {
1917 seglen = 0; /* This special case may be needed for old linkers */
1918 acbp |= 0x02; /* B bit */
1921 /* A field */
1922 if (seg->align >= SEG_ABS)
1923 /* acbp |= 0x00 */ ;
1924 else if (seg->align >= 4096) {
1925 if (seg->align > 4096)
1926 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1927 " than OBJ format supports", seg->name);
1928 acbp |= 0xC0; /* PharLap extension */
1929 } else if (seg->align >= 256) {
1930 acbp |= 0x80;
1931 } else if (seg->align >= 16) {
1932 acbp |= 0x60;
1933 } else if (seg->align >= 4) {
1934 acbp |= 0xA0;
1935 } else if (seg->align >= 2) {
1936 acbp |= 0x40;
1937 } else
1938 acbp |= 0x20;
1940 obj_byte(orp, acbp);
1941 if (seg->align & SEG_ABS) {
1942 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1943 obj_byte(orp, 0); /* Offset */
1945 obj_x(orp, seglen);
1946 obj_index(orp, ++lname_idx);
1947 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1948 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1949 obj_emit2(orp);
1953 * Write the GRPDEF records.
1955 orp->type = GRPDEF;
1956 for (grp = grphead; grp; grp = grp->next) {
1957 int i;
1959 if (grp->nindices != grp->nentries) {
1960 for (i = grp->nindices; i < grp->nentries; i++) {
1961 error(ERR_NONFATAL, "group `%s' contains undefined segment"
1962 " `%s'", grp->name, grp->segs[i].name);
1963 nasm_free(grp->segs[i].name);
1964 grp->segs[i].name = NULL;
1967 obj_index(orp, ++lname_idx);
1968 for (i = 0; i < grp->nindices; i++) {
1969 obj_byte(orp, 0xFF);
1970 obj_index(orp, grp->segs[i].index);
1972 obj_emit2(orp);
1976 * Write the PUBDEF records: first the ones in the segments,
1977 * then the far-absolutes.
1979 orp->type = PUBDEF;
1980 orp->ori = ori_pubdef;
1981 for (seg = seghead; seg; seg = seg->next) {
1982 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
1983 orp->parm[1] = seg->obj_index;
1984 for (pub = seg->pubhead; pub; pub = pub->next) {
1985 orp = obj_name(orp, pub->name);
1986 orp = obj_x(orp, pub->offset);
1987 orp = obj_byte(orp, 0); /* type index */
1988 obj_commit(orp);
1990 obj_emit(orp);
1992 orp->parm[0] = 0;
1993 orp->parm[1] = 0;
1994 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
1995 if (orp->parm[2] != pub->segment) {
1996 obj_emit(orp);
1997 orp->parm[2] = pub->segment;
1999 orp = obj_name(orp, pub->name);
2000 orp = obj_x(orp, pub->offset);
2001 orp = obj_byte(orp, 0); /* type index */
2002 obj_commit(orp);
2004 obj_emit(orp);
2007 * Write the EXTDEF and COMDEF records, in order.
2009 orp->ori = ori_null;
2010 for (ext = exthead; ext; ext = ext->next) {
2011 if (ext->commonsize == 0) {
2012 if (orp->type != EXTDEF) {
2013 obj_emit(orp);
2014 orp->type = EXTDEF;
2016 orp = obj_name(orp, ext->name);
2017 orp = obj_index(orp, 0);
2018 } else {
2019 if (orp->type != COMDEF) {
2020 obj_emit(orp);
2021 orp->type = COMDEF;
2023 orp = obj_name(orp, ext->name);
2024 orp = obj_index(orp, 0);
2025 if (ext->commonelem) {
2026 orp = obj_byte(orp, 0x61); /* far communal */
2027 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2028 orp = obj_value(orp, ext->commonelem);
2029 } else {
2030 orp = obj_byte(orp, 0x62); /* near communal */
2031 orp = obj_value(orp, ext->commonsize);
2034 obj_commit(orp);
2036 obj_emit(orp);
2039 * Write a COMENT record stating that the linker's first pass
2040 * may stop processing at this point. Exception is if our
2041 * MODEND record specifies a start point, in which case,
2042 * according to some variants of the documentation, this COMENT
2043 * should be omitted. So we'll omit it just in case.
2044 * But, TASM puts it in all the time so if we are using
2045 * TASM debug stuff we are putting it in
2047 if (debuginfo || obj_entry_seg == NO_SEG) {
2048 orp->type = COMENT;
2049 obj_byte(orp, 0x40);
2050 obj_byte(orp, dLINKPASS);
2051 obj_byte(orp, 1);
2052 obj_emit2(orp);
2056 * 1) put out the compiler type
2057 * 2) Put out the type info. The only type we are using is near label #19
2059 if (debuginfo) {
2060 int i;
2061 struct Array *arrtmp = arrhead;
2062 orp->type = COMENT;
2063 obj_byte(orp, 0x40);
2064 obj_byte(orp, dCOMPDEF);
2065 obj_byte(orp, 4);
2066 obj_byte(orp, 0);
2067 obj_emit2(orp);
2069 obj_byte(orp, 0x40);
2070 obj_byte(orp, dTYPEDEF);
2071 obj_word(orp, 0x18); /* type # for linking */
2072 obj_word(orp, 6); /* size of type */
2073 obj_byte(orp, 0x2a); /* absolute type for debugging */
2074 obj_emit2(orp);
2075 obj_byte(orp, 0x40);
2076 obj_byte(orp, dTYPEDEF);
2077 obj_word(orp, 0x19); /* type # for linking */
2078 obj_word(orp, 0); /* size of type */
2079 obj_byte(orp, 0x24); /* absolute type for debugging */
2080 obj_byte(orp, 0); /* near/far specifier */
2081 obj_emit2(orp);
2082 obj_byte(orp, 0x40);
2083 obj_byte(orp, dTYPEDEF);
2084 obj_word(orp, 0x1A); /* type # for linking */
2085 obj_word(orp, 0); /* size of type */
2086 obj_byte(orp, 0x24); /* absolute type for debugging */
2087 obj_byte(orp, 1); /* near/far specifier */
2088 obj_emit2(orp);
2089 obj_byte(orp, 0x40);
2090 obj_byte(orp, dTYPEDEF);
2091 obj_word(orp, 0x1b); /* type # for linking */
2092 obj_word(orp, 0); /* size of type */
2093 obj_byte(orp, 0x23); /* absolute type for debugging */
2094 obj_byte(orp, 0);
2095 obj_byte(orp, 0);
2096 obj_byte(orp, 0);
2097 obj_emit2(orp);
2098 obj_byte(orp, 0x40);
2099 obj_byte(orp, dTYPEDEF);
2100 obj_word(orp, 0x1c); /* type # for linking */
2101 obj_word(orp, 0); /* size of type */
2102 obj_byte(orp, 0x23); /* absolute type for debugging */
2103 obj_byte(orp, 0);
2104 obj_byte(orp, 4);
2105 obj_byte(orp, 0);
2106 obj_emit2(orp);
2107 obj_byte(orp, 0x40);
2108 obj_byte(orp, dTYPEDEF);
2109 obj_word(orp, 0x1d); /* type # for linking */
2110 obj_word(orp, 0); /* size of type */
2111 obj_byte(orp, 0x23); /* absolute type for debugging */
2112 obj_byte(orp, 0);
2113 obj_byte(orp, 1);
2114 obj_byte(orp, 0);
2115 obj_emit2(orp);
2116 obj_byte(orp, 0x40);
2117 obj_byte(orp, dTYPEDEF);
2118 obj_word(orp, 0x1e); /* type # for linking */
2119 obj_word(orp, 0); /* size of type */
2120 obj_byte(orp, 0x23); /* absolute type for debugging */
2121 obj_byte(orp, 0);
2122 obj_byte(orp, 5);
2123 obj_byte(orp, 0);
2124 obj_emit2(orp);
2126 /* put out the array types */
2127 for (i = ARRAYBOT; i < arrindex; i++) {
2128 obj_byte(orp, 0x40);
2129 obj_byte(orp, dTYPEDEF);
2130 obj_word(orp, i); /* type # for linking */
2131 obj_word(orp, arrtmp->size); /* size of type */
2132 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2133 obj_byte(orp, arrtmp->basetype); /* base type */
2134 obj_emit2(orp);
2135 arrtmp = arrtmp->next;
2139 * write out line number info with a LINNUM record
2140 * switch records when we switch segments, and output the
2141 * file in a pseudo-TASM fashion. The record switch is naive; that
2142 * is that one file may have many records for the same segment
2143 * if there are lots of segment switches
2145 if (fnhead && debuginfo) {
2146 seg = fnhead->lnhead->segment;
2148 for (fn = fnhead; fn; fn = fn->next) {
2149 /* write out current file name */
2150 orp->type = COMENT;
2151 orp->ori = ori_null;
2152 obj_byte(orp, 0x40);
2153 obj_byte(orp, dFILNAME);
2154 obj_byte(orp, 0);
2155 obj_name(orp, fn->name);
2156 obj_dword(orp, 0);
2157 obj_emit2(orp);
2159 /* write out line numbers this file */
2161 orp->type = LINNUM;
2162 orp->ori = ori_linnum;
2163 for (ln = fn->lnhead; ln; ln = ln->next) {
2164 if (seg != ln->segment) {
2165 /* if we get here have to flush the buffer and start
2166 * a new record for a new segment
2168 seg = ln->segment;
2169 obj_emit(orp);
2171 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2172 orp->parm[1] = seg->obj_index;
2173 orp = obj_word(orp, ln->lineno);
2174 orp = obj_x(orp, ln->offset);
2175 obj_commit(orp);
2177 obj_emit(orp);
2181 * we are going to locate the entry point segment now
2182 * rather than wait until the MODEND record, because,
2183 * then we can output a special symbol to tell where the
2184 * entry point is.
2187 if (obj_entry_seg != NO_SEG) {
2188 for (seg = seghead; seg; seg = seg->next) {
2189 if (seg->index == obj_entry_seg) {
2190 entry_seg_ptr = seg;
2191 break;
2194 if (!seg)
2195 error(ERR_NONFATAL, "entry point is not in this module");
2199 * get ready to put out symbol records
2201 orp->type = COMENT;
2202 orp->ori = ori_local;
2205 * put out a symbol for the entry point
2206 * no dots in this symbol, because, borland does
2207 * not (officially) support dots in label names
2208 * and I don't know what various versions of TLINK will do
2210 if (debuginfo && obj_entry_seg != NO_SEG) {
2211 orp = obj_name(orp, "start_of_program");
2212 orp = obj_word(orp, 0x19); /* type: near label */
2213 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2214 orp = obj_index(orp, seg->obj_index);
2215 orp = obj_x(orp, obj_entry_ofs);
2216 obj_commit(orp);
2220 * put out the local labels
2222 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2223 /* labels this seg */
2224 for (loc = seg->lochead; loc; loc = loc->next) {
2225 orp = obj_name(orp, loc->name);
2226 orp = obj_word(orp, loc->type);
2227 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2228 orp = obj_index(orp, seg->obj_index);
2229 orp = obj_x(orp, loc->offset);
2230 obj_commit(orp);
2233 if (orp->used)
2234 obj_emit(orp);
2237 * Write the LEDATA/FIXUPP pairs.
2239 for (seg = seghead; seg; seg = seg->next) {
2240 obj_emit(seg->orp);
2241 nasm_free(seg->orp);
2245 * Write the MODEND module end marker.
2247 orp->type = obj_use32 ? MODE32 : MODEND;
2248 orp->ori = ori_null;
2249 if (entry_seg_ptr) {
2250 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2251 obj_byte(orp, 0xC1);
2252 seg = entry_seg_ptr;
2253 if (seg->grp) {
2254 obj_byte(orp, 0x10);
2255 obj_index(orp, seg->grp->obj_index);
2256 } else {
2258 * the below changed to prevent TLINK crashing.
2259 * Previous more efficient version read:
2261 * obj_byte (orp, 0x50);
2263 obj_byte(orp, 0x00);
2264 obj_index(orp, seg->obj_index);
2266 obj_index(orp, seg->obj_index);
2267 obj_x(orp, obj_entry_ofs);
2268 } else
2269 obj_byte(orp, 0);
2270 obj_emit2(orp);
2271 nasm_free(orp);
2274 void obj_fwrite(ObjRecord * orp)
2276 unsigned int cksum, len;
2277 unsigned char *ptr;
2279 cksum = orp->type;
2280 if (orp->x_size == 32)
2281 cksum |= 1;
2282 fputc(cksum, ofp);
2283 len = orp->committed + 1;
2284 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2285 fwriteshort(len, ofp);
2286 fwrite(orp->buf, 1, len - 1, ofp);
2287 for (ptr = orp->buf; --len; ptr++)
2288 cksum += *ptr;
2289 fputc((-cksum) & 0xFF, ofp);
2292 static const char *obj_stdmac[] = {
2293 "%define __SECT__ [section .text]",
2294 "%imacro group 1+.nolist",
2295 "[group %1]",
2296 "%endmacro",
2297 "%imacro uppercase 0+.nolist",
2298 "[uppercase %1]",
2299 "%endmacro",
2300 "%imacro export 1+.nolist",
2301 "[export %1]",
2302 "%endmacro",
2303 "%imacro import 1+.nolist",
2304 "[import %1]",
2305 "%endmacro",
2306 "%macro __NASM_CDecl__ 1",
2307 "%endmacro",
2308 NULL
2311 void dbgbi_init(struct ofmt *of, void *id, FILE * fp, efunc error)
2313 (void)of;
2314 (void)id;
2315 (void)fp;
2316 (void)error;
2318 fnhead = NULL;
2319 fntail = &fnhead;
2320 arrindex = ARRAYBOT;
2321 arrhead = NULL;
2322 arrtail = &arrhead;
2324 static void dbgbi_cleanup(void)
2326 struct Segment *segtmp;
2327 while (fnhead) {
2328 struct FileName *fntemp = fnhead;
2329 while (fnhead->lnhead) {
2330 struct LineNumber *lntemp = fnhead->lnhead;
2331 fnhead->lnhead = lntemp->next;
2332 nasm_free(lntemp);
2334 fnhead = fnhead->next;
2335 nasm_free(fntemp->name);
2336 nasm_free(fntemp);
2338 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2339 while (segtmp->lochead) {
2340 struct Public *loctmp = segtmp->lochead;
2341 segtmp->lochead = loctmp->next;
2342 nasm_free(loctmp->name);
2343 nasm_free(loctmp);
2346 while (arrhead) {
2347 struct Array *arrtmp = arrhead;
2348 arrhead = arrhead->next;
2349 nasm_free(arrtmp);
2353 static void dbgbi_linnum(const char *lnfname, long lineno, long segto)
2355 struct FileName *fn;
2356 struct LineNumber *ln;
2357 struct Segment *seg;
2359 if (segto == NO_SEG)
2360 return;
2363 * If `any_segs' is still FALSE, we must define a default
2364 * segment.
2366 if (!any_segs) {
2367 int tempint; /* ignored */
2368 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2369 error(ERR_PANIC, "strange segment conditions in OBJ driver");
2373 * Find the segment we are targetting.
2375 for (seg = seghead; seg; seg = seg->next)
2376 if (seg->index == segto)
2377 break;
2378 if (!seg)
2379 error(ERR_PANIC, "lineno directed to nonexistent segment?");
2381 /* for (fn = fnhead; fn; fn = fnhead->next) */
2382 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2383 if (!nasm_stricmp(lnfname, fn->name))
2384 break;
2385 if (!fn) {
2386 fn = nasm_malloc(sizeof(*fn));
2387 fn->name = nasm_malloc(strlen(lnfname) + 1);
2388 strcpy(fn->name, lnfname);
2389 fn->lnhead = NULL;
2390 fn->lntail = &fn->lnhead;
2391 fn->next = NULL;
2392 *fntail = fn;
2393 fntail = &fn->next;
2395 ln = nasm_malloc(sizeof(*ln));
2396 ln->segment = seg;
2397 ln->offset = seg->currentpos;
2398 ln->lineno = lineno;
2399 ln->next = NULL;
2400 *fn->lntail = ln;
2401 fn->lntail = &ln->next;
2404 static void dbgbi_deflabel(char *name, long segment,
2405 long offset, int is_global, char *special)
2407 struct Segment *seg;
2409 (void)special;
2412 * If it's a special-retry from pass two, discard it.
2414 if (is_global == 3)
2415 return;
2418 * First check for the double-period, signifying something
2419 * unusual.
2421 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2422 return;
2426 * Case (i):
2428 if (obj_seg_needs_update) {
2429 return;
2430 } else if (obj_grp_needs_update) {
2431 return;
2433 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2434 return;
2436 if (segment >= SEG_ABS || segment == NO_SEG) {
2437 return;
2441 * If `any_segs' is still FALSE, we might need to define a
2442 * default segment, if they're trying to declare a label in
2443 * `first_seg'. But the label should exist due to a prior
2444 * call to obj_deflabel so we can skip that.
2447 for (seg = seghead; seg; seg = seg->next)
2448 if (seg->index == segment) {
2449 struct Public *loc = nasm_malloc(sizeof(*loc));
2451 * Case (ii). Maybe MODPUB someday?
2453 last_defined = *seg->loctail = loc;
2454 seg->loctail = &loc->next;
2455 loc->next = NULL;
2456 loc->name = nasm_strdup(name);
2457 loc->offset = offset;
2460 static void dbgbi_typevalue(long type)
2462 int vsize;
2463 int elem = TYM_ELEMENTS(type);
2464 type = TYM_TYPE(type);
2466 if (!last_defined)
2467 return;
2469 switch (type) {
2470 case TY_BYTE:
2471 last_defined->type = 8; /* unsigned char */
2472 vsize = 1;
2473 break;
2474 case TY_WORD:
2475 last_defined->type = 10; /* unsigned word */
2476 vsize = 2;
2477 break;
2478 case TY_DWORD:
2479 last_defined->type = 12; /* unsigned dword */
2480 vsize = 4;
2481 break;
2482 case TY_FLOAT:
2483 last_defined->type = 14; /* float */
2484 vsize = 4;
2485 break;
2486 case TY_QWORD:
2487 last_defined->type = 15; /* qword */
2488 vsize = 8;
2489 break;
2490 case TY_TBYTE:
2491 last_defined->type = 16; /* TBYTE */
2492 vsize = 10;
2493 break;
2494 default:
2495 last_defined->type = 0x19; /*label */
2496 vsize = 0;
2497 break;
2500 if (elem > 1) {
2501 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2502 int vtype = last_defined->type;
2503 arrtmp->size = vsize * elem;
2504 arrtmp->basetype = vtype;
2505 arrtmp->next = NULL;
2506 last_defined->type = arrindex++;
2507 *arrtail = arrtmp;
2508 arrtail = &(arrtmp->next);
2510 last_defined = NULL;
2512 static void dbgbi_output(int output_type, void *param)
2514 (void)output_type;
2515 (void)param;
2517 static struct dfmt borland_debug_form = {
2518 "Borland Debug Records",
2519 "borland",
2520 dbgbi_init,
2521 dbgbi_linnum,
2522 dbgbi_deflabel,
2523 null_debug_routine,
2524 dbgbi_typevalue,
2525 dbgbi_output,
2526 dbgbi_cleanup,
2529 static struct dfmt *borland_debug_arr[3] = {
2530 &borland_debug_form,
2531 &null_debug_form,
2532 NULL
2535 struct ofmt of_obj = {
2536 "MS-DOS 16-bit/32-bit OMF object files",
2537 "obj",
2538 NULL,
2539 borland_debug_arr,
2540 &null_debug_form,
2541 obj_stdmac,
2542 obj_init,
2543 obj_set_info,
2544 obj_out,
2545 obj_deflabel,
2546 obj_segment,
2547 obj_segbase,
2548 obj_directive,
2549 obj_filename,
2550 obj_cleanup
2552 #endif /* OF_OBJ */