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