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