Clean up remaining build warnings
[nasm/autotest.git] / output / outobj.c
blob9592464b629a2070f979a74112a9139d961aa227
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 "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 return (obj_dword(orp, val));
351 orp->x_size = 16;
352 return (obj_word(orp, val));
356 * Writes an index
358 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
360 if (val < 128)
361 return (obj_byte(orp, val));
362 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
366 * Writes a variable length value
368 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
370 if (val <= 128)
371 return (obj_byte(orp, val));
372 if (val <= 0xFFFF) {
373 orp = obj_byte(orp, 129);
374 return (obj_word(orp, val));
376 if (val <= 0xFFFFFF)
377 return (obj_dword(orp, (val << 8) + 132));
378 orp = obj_byte(orp, 136);
379 return (obj_dword(orp, val));
383 * Writes a counted string
385 static ObjRecord *obj_name(ObjRecord * orp, char *name)
387 int len = strlen(name);
388 uint8_t *ptr;
390 orp = obj_check(orp, len + 1);
391 ptr = orp->buf + orp->used;
392 *ptr++ = len;
393 orp->used += len + 1;
394 if (obj_uppercase)
395 while (--len >= 0) {
396 *ptr++ = toupper(*name);
397 name++;
398 } else
399 memcpy(ptr, name, len);
400 return (orp);
404 * Initializer for an LEDATA record.
405 * parm[0] = offset
406 * parm[1] = segment index
407 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
408 * represent the offset that would be required if the record were split at the
409 * last commit point.
410 * parm[2] is a copy of parm[0] as it was when the current record was initted.
412 static void ori_ledata(ObjRecord * orp)
414 obj_index(orp, orp->parm[1]);
415 orp->parm[2] = orp->parm[0];
416 obj_x(orp, orp->parm[0]);
420 * Initializer for a PUBDEF record.
421 * parm[0] = group index
422 * parm[1] = segment index
423 * parm[2] = frame (only used when both indexes are zero)
425 static void ori_pubdef(ObjRecord * orp)
427 obj_index(orp, orp->parm[0]);
428 obj_index(orp, orp->parm[1]);
429 if (!(orp->parm[0] | orp->parm[1]))
430 obj_word(orp, orp->parm[2]);
434 * Initializer for a LINNUM record.
435 * parm[0] = group index
436 * parm[1] = segment index
438 static void ori_linnum(ObjRecord * orp)
440 obj_index(orp, orp->parm[0]);
441 obj_index(orp, orp->parm[1]);
445 * Initializer for a local vars record.
447 static void ori_local(ObjRecord * orp)
449 obj_byte(orp, 0x40);
450 obj_byte(orp, dSYM);
454 * Null initializer for records that continue without any header info
456 static void ori_null(ObjRecord * orp)
458 (void)orp; /* Do nothing */
462 * This concludes the low level section of outobj.c
465 static char obj_infile[FILENAME_MAX];
467 static efunc error;
468 static evalfunc evaluate;
469 static ldfunc deflabel;
470 static FILE *ofp;
471 static int32_t first_seg;
472 static bool any_segs;
473 static int passtwo;
474 static int arrindex;
476 #define GROUP_MAX 256 /* we won't _realistically_ have more
477 * than this many segs in a group */
478 #define EXT_BLKSIZ 256 /* block size for externals list */
480 struct Segment; /* need to know these structs exist */
481 struct Group;
483 struct LineNumber {
484 struct LineNumber *next;
485 struct Segment *segment;
486 int32_t offset;
487 int32_t lineno;
490 static struct FileName {
491 struct FileName *next;
492 char *name;
493 struct LineNumber *lnhead, **lntail;
494 int index;
495 } *fnhead, **fntail;
497 static struct Array {
498 struct Array *next;
499 unsigned size;
500 int basetype;
501 } *arrhead, **arrtail;
503 #define ARRAYBOT 31 /* magic number for first array index */
505 static struct Public {
506 struct Public *next;
507 char *name;
508 int32_t offset;
509 int32_t segment; /* only if it's far-absolute */
510 int type; /* only for local debug syms */
511 } *fpubhead, **fpubtail, *last_defined;
513 static struct External {
514 struct External *next;
515 char *name;
516 int32_t commonsize;
517 int32_t commonelem; /* element size if FAR, else zero */
518 int index; /* OBJ-file external index */
519 enum {
520 DEFWRT_NONE, /* no unusual default-WRT */
521 DEFWRT_STRING, /* a string we don't yet understand */
522 DEFWRT_SEGMENT, /* a segment */
523 DEFWRT_GROUP /* a group */
524 } defwrt_type;
525 union {
526 char *string;
527 struct Segment *seg;
528 struct Group *grp;
529 } defwrt_ptr;
530 struct External *next_dws; /* next with DEFWRT_STRING */
531 } *exthead, **exttail, *dws;
533 static int externals;
535 static struct ExtBack {
536 struct ExtBack *next;
537 struct External *exts[EXT_BLKSIZ];
538 } *ebhead, **ebtail;
540 static struct Segment {
541 struct Segment *next;
542 int32_t index; /* the NASM segment id */
543 int32_t obj_index; /* the OBJ-file segment index */
544 struct Group *grp; /* the group it beint32_ts to */
545 uint32_t currentpos;
546 int32_t align; /* can be SEG_ABS + absolute addr */
547 enum {
548 CMB_PRIVATE = 0,
549 CMB_PUBLIC = 2,
550 CMB_STACK = 5,
551 CMB_COMMON = 6
552 } combine;
553 bool use32; /* is this segment 32-bit? */
554 struct Public *pubhead, **pubtail, *lochead, **loctail;
555 char *name;
556 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
557 ObjRecord *orp;
558 } *seghead, **segtail, *obj_seg_needs_update;
560 static struct Group {
561 struct Group *next;
562 char *name;
563 int32_t index; /* NASM segment id */
564 int32_t obj_index; /* OBJ-file group index */
565 int32_t nentries; /* number of elements... */
566 int32_t nindices; /* ...and number of index elts... */
567 union {
568 int32_t index;
569 char *name;
570 } segs[GROUP_MAX]; /* ...in this */
571 } *grphead, **grptail, *obj_grp_needs_update;
573 static struct ImpDef {
574 struct ImpDef *next;
575 char *extname;
576 char *libname;
577 unsigned int impindex;
578 char *impname;
579 } *imphead, **imptail;
581 static struct ExpDef {
582 struct ExpDef *next;
583 char *intname;
584 char *extname;
585 unsigned int ordinal;
586 int flags;
587 } *exphead, **exptail;
589 #define EXPDEF_FLAG_ORDINAL 0x80
590 #define EXPDEF_FLAG_RESIDENT 0x40
591 #define EXPDEF_FLAG_NODATA 0x20
592 #define EXPDEF_MASK_PARMCNT 0x1F
594 static int32_t obj_entry_seg, obj_entry_ofs;
596 struct ofmt of_obj;
598 /* The current segment */
599 static struct Segment *current_seg;
601 static int32_t obj_segment(char *, int, int *);
602 static void obj_write_file(int debuginfo);
603 static int obj_directive(char *, char *, int);
605 static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
607 ofp = fp;
608 error = errfunc;
609 evaluate = eval;
610 deflabel = ldef;
611 first_seg = seg_alloc();
612 any_segs = false;
613 fpubhead = NULL;
614 fpubtail = &fpubhead;
615 exthead = NULL;
616 exttail = &exthead;
617 imphead = NULL;
618 imptail = &imphead;
619 exphead = NULL;
620 exptail = &exphead;
621 dws = NULL;
622 externals = 0;
623 ebhead = NULL;
624 ebtail = &ebhead;
625 seghead = obj_seg_needs_update = NULL;
626 segtail = &seghead;
627 grphead = obj_grp_needs_update = NULL;
628 grptail = &grphead;
629 obj_entry_seg = NO_SEG;
630 obj_uppercase = false;
631 obj_use32 = false;
632 passtwo = 0;
633 current_seg = NULL;
635 of_obj.current_dfmt->init(&of_obj, NULL, fp, errfunc);
638 static int obj_set_info(enum geninfo type, char **val)
640 (void)type;
641 (void)val;
643 return 0;
645 static void obj_cleanup(int debuginfo)
647 obj_write_file(debuginfo);
648 of_obj.current_dfmt->cleanup();
649 fclose(ofp);
650 while (seghead) {
651 struct Segment *segtmp = seghead;
652 seghead = seghead->next;
653 while (segtmp->pubhead) {
654 struct Public *pubtmp = segtmp->pubhead;
655 segtmp->pubhead = pubtmp->next;
656 nasm_free(pubtmp->name);
657 nasm_free(pubtmp);
659 nasm_free(segtmp->segclass);
660 nasm_free(segtmp->overlay);
661 nasm_free(segtmp);
663 while (fpubhead) {
664 struct Public *pubtmp = fpubhead;
665 fpubhead = fpubhead->next;
666 nasm_free(pubtmp->name);
667 nasm_free(pubtmp);
669 while (exthead) {
670 struct External *exttmp = exthead;
671 exthead = exthead->next;
672 nasm_free(exttmp);
674 while (imphead) {
675 struct ImpDef *imptmp = imphead;
676 imphead = imphead->next;
677 nasm_free(imptmp->extname);
678 nasm_free(imptmp->libname);
679 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
680 nasm_free(imptmp);
682 while (exphead) {
683 struct ExpDef *exptmp = exphead;
684 exphead = exphead->next;
685 nasm_free(exptmp->extname);
686 nasm_free(exptmp->intname);
687 nasm_free(exptmp);
689 while (ebhead) {
690 struct ExtBack *ebtmp = ebhead;
691 ebhead = ebhead->next;
692 nasm_free(ebtmp);
694 while (grphead) {
695 struct Group *grptmp = grphead;
696 grphead = grphead->next;
697 nasm_free(grptmp);
701 static void obj_ext_set_defwrt(struct External *ext, char *id)
703 struct Segment *seg;
704 struct Group *grp;
706 for (seg = seghead; seg; seg = seg->next)
707 if (!strcmp(seg->name, id)) {
708 ext->defwrt_type = DEFWRT_SEGMENT;
709 ext->defwrt_ptr.seg = seg;
710 nasm_free(id);
711 return;
714 for (grp = grphead; grp; grp = grp->next)
715 if (!strcmp(grp->name, id)) {
716 ext->defwrt_type = DEFWRT_GROUP;
717 ext->defwrt_ptr.grp = grp;
718 nasm_free(id);
719 return;
722 ext->defwrt_type = DEFWRT_STRING;
723 ext->defwrt_ptr.string = id;
724 ext->next_dws = dws;
725 dws = ext;
728 static void obj_deflabel(char *name, int32_t segment,
729 int64_t offset, int is_global, char *special)
732 * We have three cases:
734 * (i) `segment' is a segment-base. If so, set the name field
735 * for the segment or group structure it refers to, and then
736 * return.
738 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
739 * Save the label position for later output of a PUBDEF record.
740 * (Or a MODPUB, if we work out how.)
742 * (iii) `segment' is not one of our segments. Save the label
743 * position for later output of an EXTDEF, and also store a
744 * back-reference so that we can map later references to this
745 * segment number to the external index.
747 struct External *ext;
748 struct ExtBack *eb;
749 struct Segment *seg;
750 int i;
751 bool used_special = false; /* have we used the special text? */
753 #if defined(DEBUG) && DEBUG>2
754 fprintf(stderr,
755 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
756 name, segment, offset, is_global, special);
757 #endif
760 * If it's a special-retry from pass two, discard it.
762 if (is_global == 3)
763 return;
766 * First check for the double-period, signifying something
767 * unusual.
769 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
770 if (!strcmp(name, "..start")) {
771 obj_entry_seg = segment;
772 obj_entry_ofs = offset;
773 return;
775 error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
779 * Case (i):
781 if (obj_seg_needs_update) {
782 obj_seg_needs_update->name = name;
783 return;
784 } else if (obj_grp_needs_update) {
785 obj_grp_needs_update->name = name;
786 return;
788 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
789 return;
791 if (segment >= SEG_ABS || segment == NO_SEG) {
793 * SEG_ABS subcase of (ii).
795 if (is_global) {
796 struct Public *pub;
798 pub = *fpubtail = nasm_malloc(sizeof(*pub));
799 fpubtail = &pub->next;
800 pub->next = NULL;
801 pub->name = nasm_strdup(name);
802 pub->offset = offset;
803 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
805 if (special)
806 error(ERR_NONFATAL, "OBJ supports no special symbol features"
807 " for this symbol type");
808 return;
812 * If `any_segs' is still false, we might need to define a
813 * default segment, if they're trying to declare a label in
814 * `first_seg'.
816 if (!any_segs && segment == first_seg) {
817 int tempint; /* ignored */
818 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
819 error(ERR_PANIC, "strange segment conditions in OBJ driver");
822 for (seg = seghead; seg && is_global; seg = seg->next)
823 if (seg->index == segment) {
824 struct Public *loc = nasm_malloc(sizeof(*loc));
826 * Case (ii). Maybe MODPUB someday?
828 *seg->pubtail = loc;
829 seg->pubtail = &loc->next;
830 loc->next = NULL;
831 loc->name = nasm_strdup(name);
832 loc->offset = offset;
834 if (special)
835 error(ERR_NONFATAL,
836 "OBJ supports no special symbol features"
837 " for this symbol type");
838 return;
842 * Case (iii).
844 if (is_global) {
845 ext = *exttail = nasm_malloc(sizeof(*ext));
846 ext->next = NULL;
847 exttail = &ext->next;
848 ext->name = name;
849 /* Place by default all externs into the current segment */
850 ext->defwrt_type = DEFWRT_NONE;
852 /* 28-Apr-2002 - John Coffman
853 The following code was introduced on 12-Aug-2000, and breaks fixups
854 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
855 (5.10). It was introduced after FIXUP32 was added, and may be needed
856 for 32-bit segments. The following will get 16-bit segments working
857 again, and maybe someone can correct the 'if' condition which is
858 actually needed.
860 #if 0
861 if (current_seg) {
862 #else
863 if (current_seg && current_seg->use32) {
864 if (current_seg->grp) {
865 ext->defwrt_type = DEFWRT_GROUP;
866 ext->defwrt_ptr.grp = current_seg->grp;
867 } else {
868 ext->defwrt_type = DEFWRT_SEGMENT;
869 ext->defwrt_ptr.seg = current_seg;
872 #endif
874 if (is_global == 2) {
875 ext->commonsize = offset;
876 ext->commonelem = 1; /* default FAR */
877 } else
878 ext->commonsize = 0;
879 } else
880 return;
883 * Now process the special text, if any, to find default-WRT
884 * specifications and common-variable element-size and near/far
885 * specifications.
887 while (special && *special) {
888 used_special = true;
891 * We might have a default-WRT specification.
893 if (!nasm_strnicmp(special, "wrt", 3)) {
894 char *p;
895 int len;
896 special += 3;
897 special += strspn(special, " \t");
898 p = nasm_strndup(special, len = strcspn(special, ":"));
899 obj_ext_set_defwrt(ext, p);
900 special += len;
901 if (*special && *special != ':')
902 error(ERR_NONFATAL, "`:' expected in special symbol"
903 " text for `%s'", ext->name);
904 else if (*special == ':')
905 special++;
909 * The NEAR or FAR keywords specify nearness or
910 * farness. FAR gives default element size 1.
912 if (!nasm_strnicmp(special, "far", 3)) {
913 if (ext->commonsize)
914 ext->commonelem = 1;
915 else
916 error(ERR_NONFATAL,
917 "`%s': `far' keyword may only be applied"
918 " to common variables\n", ext->name);
919 special += 3;
920 special += strspn(special, " \t");
921 } else if (!nasm_strnicmp(special, "near", 4)) {
922 if (ext->commonsize)
923 ext->commonelem = 0;
924 else
925 error(ERR_NONFATAL,
926 "`%s': `far' keyword may only be applied"
927 " to common variables\n", ext->name);
928 special += 4;
929 special += strspn(special, " \t");
933 * If it's a common, and anything else remains on the line
934 * before a further colon, evaluate it as an expression and
935 * use that as the element size. Forward references aren't
936 * allowed.
938 if (*special == ':')
939 special++;
940 else if (*special) {
941 if (ext->commonsize) {
942 expr *e;
943 struct tokenval tokval;
945 stdscan_reset();
946 stdscan_bufptr = special;
947 tokval.t_type = TOKEN_INVALID;
948 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
949 if (e) {
950 if (!is_simple(e))
951 error(ERR_NONFATAL, "cannot use relocatable"
952 " expression as common-variable element size");
953 else
954 ext->commonelem = reloc_value(e);
956 special = stdscan_bufptr;
957 } else {
958 error(ERR_NONFATAL,
959 "`%s': element-size specifications only"
960 " apply to common variables", ext->name);
961 while (*special && *special != ':')
962 special++;
963 if (*special == ':')
964 special++;
969 i = segment / 2;
970 eb = ebhead;
971 if (!eb) {
972 eb = *ebtail = nasm_malloc(sizeof(*eb));
973 eb->next = NULL;
974 ebtail = &eb->next;
976 while (i >= EXT_BLKSIZ) {
977 if (eb && eb->next)
978 eb = eb->next;
979 else {
980 eb = *ebtail = nasm_malloc(sizeof(*eb));
981 eb->next = NULL;
982 ebtail = &eb->next;
984 i -= EXT_BLKSIZ;
986 eb->exts[i] = ext;
987 ext->index = ++externals;
989 if (special && !used_special)
990 error(ERR_NONFATAL, "OBJ supports no special symbol features"
991 " for this symbol type");
994 /* forward declaration */
995 static void obj_write_fixup(ObjRecord * orp, int bytes,
996 int segrel, int32_t seg, int32_t wrt,
997 struct Segment *segto);
999 static void obj_out(int32_t segto, const void *data,
1000 enum out_type type, uint64_t size,
1001 int32_t segment, int32_t wrt)
1003 const uint8_t *ucdata;
1004 int32_t ldata;
1005 struct Segment *seg;
1006 ObjRecord *orp;
1009 * handle absolute-assembly (structure definitions)
1011 if (segto == NO_SEG) {
1012 if (type != OUT_RESERVE)
1013 error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1014 " space");
1015 return;
1019 * If `any_segs' is still false, we must define a default
1020 * segment.
1022 if (!any_segs) {
1023 int tempint; /* ignored */
1024 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1025 error(ERR_PANIC, "strange segment conditions in OBJ driver");
1029 * Find the segment we are targetting.
1031 for (seg = seghead; seg; seg = seg->next)
1032 if (seg->index == segto)
1033 break;
1034 if (!seg)
1035 error(ERR_PANIC, "code directed to nonexistent segment?");
1037 orp = seg->orp;
1038 orp->parm[0] = seg->currentpos;
1040 if (type == 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 (type == OUT_ADDRESS || type == OUT_REL2ADR ||
1055 type == OUT_REL4ADR) {
1056 int rsize;
1058 if (segment == NO_SEG && type != 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 = *(int64_t *)data;
1065 if (type == OUT_REL2ADR) {
1066 ldata += (size - 2);
1067 size = 2;
1069 if (type == 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 (type == OUT_ADDRESS ? 0x4000 : 0),
1095 segment, wrt, seg);
1096 seg->currentpos += size;
1097 } else if (type == 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;
1281 bool rn_error;
1282 char *p;
1285 * Look for segment attributes.
1287 attrs = 0;
1288 while (*name == '.')
1289 name++; /* hack, but a documented one */
1290 p = name;
1291 while (*p && !isspace(*p))
1292 p++;
1293 if (*p) {
1294 *p++ = '\0';
1295 while (*p && isspace(*p))
1296 *p++ = '\0';
1298 while (*p) {
1299 while (*p && !isspace(*p))
1300 p++;
1301 if (*p) {
1302 *p++ = '\0';
1303 while (*p && isspace(*p))
1304 *p++ = '\0';
1307 attrs++;
1310 obj_idx = 1;
1311 for (seg = seghead; seg; seg = seg->next) {
1312 obj_idx++;
1313 if (!strcmp(seg->name, name)) {
1314 if (attrs > 0 && pass == 1)
1315 error(ERR_WARNING, "segment attributes specified on"
1316 " redeclaration of segment: ignoring");
1317 if (seg->use32)
1318 *bits = 32;
1319 else
1320 *bits = 16;
1321 current_seg = seg;
1322 return seg->index;
1326 *segtail = seg = nasm_malloc(sizeof(*seg));
1327 seg->next = NULL;
1328 segtail = &seg->next;
1329 seg->index = (any_segs ? seg_alloc() : first_seg);
1330 seg->obj_index = obj_idx;
1331 seg->grp = NULL;
1332 any_segs = true;
1333 seg->name = NULL;
1334 seg->currentpos = 0;
1335 seg->align = 1; /* default */
1336 seg->use32 = false; /* default */
1337 seg->combine = CMB_PUBLIC; /* default */
1338 seg->segclass = seg->overlay = NULL;
1339 seg->pubhead = NULL;
1340 seg->pubtail = &seg->pubhead;
1341 seg->lochead = NULL;
1342 seg->loctail = &seg->lochead;
1343 seg->orp = obj_new();
1344 seg->orp->up = &(seg->orp);
1345 seg->orp->ori = ori_ledata;
1346 seg->orp->type = LEDATA;
1347 seg->orp->parm[1] = obj_idx;
1350 * Process the segment attributes.
1352 p = name;
1353 while (attrs--) {
1354 p += strlen(p);
1355 while (!*p)
1356 p++;
1359 * `p' contains a segment attribute.
1361 if (!nasm_stricmp(p, "private"))
1362 seg->combine = CMB_PRIVATE;
1363 else if (!nasm_stricmp(p, "public"))
1364 seg->combine = CMB_PUBLIC;
1365 else if (!nasm_stricmp(p, "common"))
1366 seg->combine = CMB_COMMON;
1367 else if (!nasm_stricmp(p, "stack"))
1368 seg->combine = CMB_STACK;
1369 else if (!nasm_stricmp(p, "use16"))
1370 seg->use32 = false;
1371 else if (!nasm_stricmp(p, "use32"))
1372 seg->use32 = true;
1373 else if (!nasm_stricmp(p, "flat")) {
1375 * This segment is an OS/2 FLAT segment. That means
1376 * that its default group is group FLAT, even if
1377 * the group FLAT does not explicitly _contain_ the
1378 * segment.
1380 * When we see this, we must create the group
1381 * `FLAT', containing no segments, if it does not
1382 * already exist; then we must set the default
1383 * group of this segment to be the FLAT group.
1385 struct Group *grp;
1386 for (grp = grphead; grp; grp = grp->next)
1387 if (!strcmp(grp->name, "FLAT"))
1388 break;
1389 if (!grp) {
1390 obj_directive("group", "FLAT", 1);
1391 for (grp = grphead; grp; grp = grp->next)
1392 if (!strcmp(grp->name, "FLAT"))
1393 break;
1394 if (!grp)
1395 error(ERR_PANIC, "failure to define FLAT?!");
1397 seg->grp = grp;
1398 } else if (!nasm_strnicmp(p, "class=", 6))
1399 seg->segclass = nasm_strdup(p + 6);
1400 else if (!nasm_strnicmp(p, "overlay=", 8))
1401 seg->overlay = nasm_strdup(p + 8);
1402 else if (!nasm_strnicmp(p, "align=", 6)) {
1403 seg->align = readnum(p + 6, &rn_error);
1404 if (rn_error) {
1405 seg->align = 1;
1406 error(ERR_NONFATAL, "segment alignment should be"
1407 " numeric");
1409 switch ((int)seg->align) {
1410 case 1: /* BYTE */
1411 case 2: /* WORD */
1412 case 4: /* DWORD */
1413 case 16: /* PARA */
1414 case 256: /* PAGE */
1415 case 4096: /* PharLap extension */
1416 break;
1417 case 8:
1418 error(ERR_WARNING,
1419 "OBJ format does not support alignment"
1420 " of 8: rounding up to 16");
1421 seg->align = 16;
1422 break;
1423 case 32:
1424 case 64:
1425 case 128:
1426 error(ERR_WARNING,
1427 "OBJ format does not support alignment"
1428 " of %d: rounding up to 256", seg->align);
1429 seg->align = 256;
1430 break;
1431 case 512:
1432 case 1024:
1433 case 2048:
1434 error(ERR_WARNING,
1435 "OBJ format does not support alignment"
1436 " of %d: rounding up to 4096", seg->align);
1437 seg->align = 4096;
1438 break;
1439 default:
1440 error(ERR_NONFATAL, "invalid alignment value %d",
1441 seg->align);
1442 seg->align = 1;
1443 break;
1445 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1446 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1447 if (rn_error)
1448 error(ERR_NONFATAL, "argument to `absolute' segment"
1449 " attribute should be numeric");
1453 /* We need to know whenever we have at least one 32-bit segment */
1454 obj_use32 |= seg->use32;
1456 obj_seg_needs_update = seg;
1457 if (seg->align >= SEG_ABS)
1458 deflabel(name, NO_SEG, seg->align - SEG_ABS,
1459 NULL, false, false, &of_obj, error);
1460 else
1461 deflabel(name, seg->index + 1, 0L,
1462 NULL, false, false, &of_obj, error);
1463 obj_seg_needs_update = NULL;
1466 * See if this segment is defined in any groups.
1468 for (grp = grphead; grp; grp = grp->next) {
1469 for (i = grp->nindices; i < grp->nentries; i++) {
1470 if (!strcmp(grp->segs[i].name, seg->name)) {
1471 nasm_free(grp->segs[i].name);
1472 grp->segs[i] = grp->segs[grp->nindices];
1473 grp->segs[grp->nindices++].index = seg->obj_index;
1474 if (seg->grp)
1475 error(ERR_WARNING,
1476 "segment `%s' is already part of"
1477 " a group: first one takes precedence",
1478 seg->name);
1479 else
1480 seg->grp = grp;
1486 * Walk through the list of externals with unresolved
1487 * default-WRT clauses, and resolve any that point at this
1488 * segment.
1490 extp = &dws;
1491 while (*extp) {
1492 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1493 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1494 nasm_free((*extp)->defwrt_ptr.string);
1495 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1496 (*extp)->defwrt_ptr.seg = seg;
1497 *extp = (*extp)->next_dws;
1498 } else
1499 extp = &(*extp)->next_dws;
1502 if (seg->use32)
1503 *bits = 32;
1504 else
1505 *bits = 16;
1506 current_seg = seg;
1507 return seg->index;
1511 static int obj_directive(char *directive, char *value, int pass)
1513 if (!strcmp(directive, "group")) {
1514 char *p, *q, *v;
1515 if (pass == 1) {
1516 struct Group *grp;
1517 struct Segment *seg;
1518 struct External **extp;
1519 int obj_idx;
1521 q = value;
1522 while (*q == '.')
1523 q++; /* hack, but a documented one */
1524 v = q;
1525 while (*q && !isspace(*q))
1526 q++;
1527 if (isspace(*q)) {
1528 *q++ = '\0';
1529 while (*q && isspace(*q))
1530 q++;
1533 * Here we used to sanity-check the group directive to
1534 * ensure nobody tried to declare a group containing no
1535 * segments. However, OS/2 does this as standard
1536 * practice, so the sanity check has been removed.
1538 * if (!*q) {
1539 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1540 * return 1;
1544 obj_idx = 1;
1545 for (grp = grphead; grp; grp = grp->next) {
1546 obj_idx++;
1547 if (!strcmp(grp->name, v)) {
1548 error(ERR_NONFATAL, "group `%s' defined twice", v);
1549 return 1;
1553 *grptail = grp = nasm_malloc(sizeof(*grp));
1554 grp->next = NULL;
1555 grptail = &grp->next;
1556 grp->index = seg_alloc();
1557 grp->obj_index = obj_idx;
1558 grp->nindices = grp->nentries = 0;
1559 grp->name = NULL;
1561 obj_grp_needs_update = grp;
1562 deflabel(v, grp->index + 1, 0L,
1563 NULL, false, false, &of_obj, error);
1564 obj_grp_needs_update = NULL;
1566 while (*q) {
1567 p = q;
1568 while (*q && !isspace(*q))
1569 q++;
1570 if (isspace(*q)) {
1571 *q++ = '\0';
1572 while (*q && isspace(*q))
1573 q++;
1576 * Now p contains a segment name. Find it.
1578 for (seg = seghead; seg; seg = seg->next)
1579 if (!strcmp(seg->name, p))
1580 break;
1581 if (seg) {
1583 * We have a segment index. Shift a name entry
1584 * to the end of the array to make room.
1586 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1587 grp->segs[grp->nindices++].index = seg->obj_index;
1588 if (seg->grp)
1589 error(ERR_WARNING,
1590 "segment `%s' is already part of"
1591 " a group: first one takes precedence",
1592 seg->name);
1593 else
1594 seg->grp = grp;
1595 } else {
1597 * We have an as-yet undefined segment.
1598 * Remember its name, for later.
1600 grp->segs[grp->nentries++].name = nasm_strdup(p);
1605 * Walk through the list of externals with unresolved
1606 * default-WRT clauses, and resolve any that point at
1607 * this group.
1609 extp = &dws;
1610 while (*extp) {
1611 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1612 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1613 nasm_free((*extp)->defwrt_ptr.string);
1614 (*extp)->defwrt_type = DEFWRT_GROUP;
1615 (*extp)->defwrt_ptr.grp = grp;
1616 *extp = (*extp)->next_dws;
1617 } else
1618 extp = &(*extp)->next_dws;
1621 return 1;
1623 if (!strcmp(directive, "uppercase")) {
1624 obj_uppercase = true;
1625 return 1;
1627 if (!strcmp(directive, "import")) {
1628 char *q, *extname, *libname, *impname;
1630 if (pass == 2)
1631 return 1; /* ignore in pass two */
1632 extname = q = value;
1633 while (*q && !isspace(*q))
1634 q++;
1635 if (isspace(*q)) {
1636 *q++ = '\0';
1637 while (*q && isspace(*q))
1638 q++;
1641 libname = q;
1642 while (*q && !isspace(*q))
1643 q++;
1644 if (isspace(*q)) {
1645 *q++ = '\0';
1646 while (*q && isspace(*q))
1647 q++;
1650 impname = q;
1652 if (!*extname || !*libname)
1653 error(ERR_NONFATAL, "`import' directive requires symbol name"
1654 " and library name");
1655 else {
1656 struct ImpDef *imp;
1657 bool err = false;
1659 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1660 imptail = &imp->next;
1661 imp->next = NULL;
1662 imp->extname = nasm_strdup(extname);
1663 imp->libname = nasm_strdup(libname);
1664 imp->impindex = readnum(impname, &err);
1665 if (!*impname || err)
1666 imp->impname = nasm_strdup(impname);
1667 else
1668 imp->impname = NULL;
1671 return 1;
1673 if (!strcmp(directive, "export")) {
1674 char *q, *extname, *intname, *v;
1675 struct ExpDef *export;
1676 int flags = 0;
1677 unsigned int ordinal = 0;
1679 if (pass == 2)
1680 return 1; /* ignore in pass two */
1681 intname = q = value;
1682 while (*q && !isspace(*q))
1683 q++;
1684 if (isspace(*q)) {
1685 *q++ = '\0';
1686 while (*q && isspace(*q))
1687 q++;
1690 extname = q;
1691 while (*q && !isspace(*q))
1692 q++;
1693 if (isspace(*q)) {
1694 *q++ = '\0';
1695 while (*q && isspace(*q))
1696 q++;
1699 if (!*intname) {
1700 error(ERR_NONFATAL, "`export' directive requires export name");
1701 return 1;
1703 if (!*extname) {
1704 extname = intname;
1705 intname = "";
1707 while (*q) {
1708 v = q;
1709 while (*q && !isspace(*q))
1710 q++;
1711 if (isspace(*q)) {
1712 *q++ = '\0';
1713 while (*q && isspace(*q))
1714 q++;
1716 if (!nasm_stricmp(v, "resident"))
1717 flags |= EXPDEF_FLAG_RESIDENT;
1718 else if (!nasm_stricmp(v, "nodata"))
1719 flags |= EXPDEF_FLAG_NODATA;
1720 else if (!nasm_strnicmp(v, "parm=", 5)) {
1721 bool err = false;
1722 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1723 if (err) {
1724 error(ERR_NONFATAL,
1725 "value `%s' for `parm' is non-numeric", v + 5);
1726 return 1;
1728 } else {
1729 bool err = false;
1730 ordinal = readnum(v, &err);
1731 if (err) {
1732 error(ERR_NONFATAL,
1733 "unrecognised export qualifier `%s'", v);
1734 return 1;
1736 flags |= EXPDEF_FLAG_ORDINAL;
1740 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1741 exptail = &export->next;
1742 export->next = NULL;
1743 export->extname = nasm_strdup(extname);
1744 export->intname = nasm_strdup(intname);
1745 export->ordinal = ordinal;
1746 export->flags = flags;
1748 return 1;
1750 return 0;
1753 static int32_t obj_segbase(int32_t segment)
1755 struct Segment *seg;
1758 * Find the segment in our list.
1760 for (seg = seghead; seg; seg = seg->next)
1761 if (seg->index == segment - 1)
1762 break;
1764 if (!seg) {
1766 * Might be an external with a default WRT.
1768 int32_t i = segment / 2;
1769 struct ExtBack *eb = ebhead;
1770 struct External *e;
1772 while (i >= EXT_BLKSIZ) {
1773 if (eb)
1774 eb = eb->next;
1775 else
1776 break;
1777 i -= EXT_BLKSIZ;
1779 if (eb) {
1780 e = eb->exts[i];
1781 if (e->defwrt_type == DEFWRT_NONE)
1782 return segment; /* fine */
1783 else if (e->defwrt_type == DEFWRT_SEGMENT)
1784 return e->defwrt_ptr.seg->index + 1;
1785 else if (e->defwrt_type == DEFWRT_GROUP)
1786 return e->defwrt_ptr.grp->index + 1;
1787 else
1788 return NO_SEG; /* can't tell what it is */
1791 return segment; /* not one of ours - leave it alone */
1794 if (seg->align >= SEG_ABS)
1795 return seg->align; /* absolute segment */
1796 if (seg->grp)
1797 return seg->grp->index + 1; /* grouped segment */
1799 return segment; /* no special treatment */
1802 static void obj_filename(char *inname, char *outname, efunc lerror)
1804 strcpy(obj_infile, inname);
1805 standard_extension(inname, outname, ".obj", lerror);
1808 static void obj_write_file(int debuginfo)
1810 struct Segment *seg, *entry_seg_ptr = 0;
1811 struct FileName *fn;
1812 struct LineNumber *ln;
1813 struct Group *grp;
1814 struct Public *pub, *loc;
1815 struct External *ext;
1816 struct ImpDef *imp;
1817 struct ExpDef *export;
1818 static char boast[] = "The Netwide Assembler " NASM_VER;
1819 int lname_idx;
1820 ObjRecord *orp;
1823 * Write the THEADR module header.
1825 orp = obj_new();
1826 orp->type = THEADR;
1827 obj_name(orp, obj_infile);
1828 obj_emit2(orp);
1831 * Write the NASM boast comment.
1833 orp->type = COMENT;
1834 obj_rword(orp, 0); /* comment type zero */
1835 obj_name(orp, boast);
1836 obj_emit2(orp);
1838 orp->type = COMENT;
1840 * Write the IMPDEF records, if any.
1842 for (imp = imphead; imp; imp = imp->next) {
1843 obj_rword(orp, 0xA0); /* comment class A0 */
1844 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1845 if (imp->impname)
1846 obj_byte(orp, 0); /* import by name */
1847 else
1848 obj_byte(orp, 1); /* import by ordinal */
1849 obj_name(orp, imp->extname);
1850 obj_name(orp, imp->libname);
1851 if (imp->impname)
1852 obj_name(orp, imp->impname);
1853 else
1854 obj_word(orp, imp->impindex);
1855 obj_emit2(orp);
1859 * Write the EXPDEF records, if any.
1861 for (export = exphead; export; export = export->next) {
1862 obj_rword(orp, 0xA0); /* comment class A0 */
1863 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1864 obj_byte(orp, export->flags);
1865 obj_name(orp, export->extname);
1866 obj_name(orp, export->intname);
1867 if (export->flags & EXPDEF_FLAG_ORDINAL)
1868 obj_word(orp, export->ordinal);
1869 obj_emit2(orp);
1872 /* we're using extended OMF if we put in debug info */
1873 if (debuginfo) {
1874 orp->type = COMENT;
1875 obj_byte(orp, 0x40);
1876 obj_byte(orp, dEXTENDED);
1877 obj_emit2(orp);
1881 * Write the first LNAMES record, containing LNAME one, which
1882 * is null. Also initialize the LNAME counter.
1884 orp->type = LNAMES;
1885 obj_byte(orp, 0);
1886 lname_idx = 1;
1888 * Write some LNAMES for the segment names
1890 for (seg = seghead; seg; seg = seg->next) {
1891 orp = obj_name(orp, seg->name);
1892 if (seg->segclass)
1893 orp = obj_name(orp, seg->segclass);
1894 if (seg->overlay)
1895 orp = obj_name(orp, seg->overlay);
1896 obj_commit(orp);
1899 * Write some LNAMES for the group names
1901 for (grp = grphead; grp; grp = grp->next) {
1902 orp = obj_name(orp, grp->name);
1903 obj_commit(orp);
1905 obj_emit(orp);
1908 * Write the SEGDEF records.
1910 orp->type = SEGDEF;
1911 for (seg = seghead; seg; seg = seg->next) {
1912 int acbp;
1913 uint32_t seglen = seg->currentpos;
1915 acbp = (seg->combine << 2); /* C field */
1917 if (seg->use32)
1918 acbp |= 0x01; /* P bit is Use32 flag */
1919 else if (seglen == 0x10000L) {
1920 seglen = 0; /* This special case may be needed for old linkers */
1921 acbp |= 0x02; /* B bit */
1924 /* A field */
1925 if (seg->align >= SEG_ABS)
1926 /* acbp |= 0x00 */ ;
1927 else if (seg->align >= 4096) {
1928 if (seg->align > 4096)
1929 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1930 " than OBJ format supports", seg->name);
1931 acbp |= 0xC0; /* PharLap extension */
1932 } else if (seg->align >= 256) {
1933 acbp |= 0x80;
1934 } else if (seg->align >= 16) {
1935 acbp |= 0x60;
1936 } else if (seg->align >= 4) {
1937 acbp |= 0xA0;
1938 } else if (seg->align >= 2) {
1939 acbp |= 0x40;
1940 } else
1941 acbp |= 0x20;
1943 obj_byte(orp, acbp);
1944 if (seg->align & SEG_ABS) {
1945 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1946 obj_byte(orp, 0); /* Offset */
1948 obj_x(orp, seglen);
1949 obj_index(orp, ++lname_idx);
1950 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1951 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1952 obj_emit2(orp);
1956 * Write the GRPDEF records.
1958 orp->type = GRPDEF;
1959 for (grp = grphead; grp; grp = grp->next) {
1960 int i;
1962 if (grp->nindices != grp->nentries) {
1963 for (i = grp->nindices; i < grp->nentries; i++) {
1964 error(ERR_NONFATAL, "group `%s' contains undefined segment"
1965 " `%s'", grp->name, grp->segs[i].name);
1966 nasm_free(grp->segs[i].name);
1967 grp->segs[i].name = NULL;
1970 obj_index(orp, ++lname_idx);
1971 for (i = 0; i < grp->nindices; i++) {
1972 obj_byte(orp, 0xFF);
1973 obj_index(orp, grp->segs[i].index);
1975 obj_emit2(orp);
1979 * Write the PUBDEF records: first the ones in the segments,
1980 * then the far-absolutes.
1982 orp->type = PUBDEF;
1983 orp->ori = ori_pubdef;
1984 for (seg = seghead; seg; seg = seg->next) {
1985 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
1986 orp->parm[1] = seg->obj_index;
1987 for (pub = seg->pubhead; pub; pub = pub->next) {
1988 orp = obj_name(orp, pub->name);
1989 orp = obj_x(orp, pub->offset);
1990 orp = obj_byte(orp, 0); /* type index */
1991 obj_commit(orp);
1993 obj_emit(orp);
1995 orp->parm[0] = 0;
1996 orp->parm[1] = 0;
1997 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
1998 if (orp->parm[2] != (uint32_t)pub->segment) {
1999 obj_emit(orp);
2000 orp->parm[2] = pub->segment;
2002 orp = obj_name(orp, pub->name);
2003 orp = obj_x(orp, pub->offset);
2004 orp = obj_byte(orp, 0); /* type index */
2005 obj_commit(orp);
2007 obj_emit(orp);
2010 * Write the EXTDEF and COMDEF records, in order.
2012 orp->ori = ori_null;
2013 for (ext = exthead; ext; ext = ext->next) {
2014 if (ext->commonsize == 0) {
2015 if (orp->type != EXTDEF) {
2016 obj_emit(orp);
2017 orp->type = EXTDEF;
2019 orp = obj_name(orp, ext->name);
2020 orp = obj_index(orp, 0);
2021 } else {
2022 if (orp->type != COMDEF) {
2023 obj_emit(orp);
2024 orp->type = COMDEF;
2026 orp = obj_name(orp, ext->name);
2027 orp = obj_index(orp, 0);
2028 if (ext->commonelem) {
2029 orp = obj_byte(orp, 0x61); /* far communal */
2030 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2031 orp = obj_value(orp, ext->commonelem);
2032 } else {
2033 orp = obj_byte(orp, 0x62); /* near communal */
2034 orp = obj_value(orp, ext->commonsize);
2037 obj_commit(orp);
2039 obj_emit(orp);
2042 * Write a COMENT record stating that the linker's first pass
2043 * may stop processing at this point. Exception is if our
2044 * MODEND record specifies a start point, in which case,
2045 * according to some variants of the documentation, this COMENT
2046 * should be omitted. So we'll omit it just in case.
2047 * But, TASM puts it in all the time so if we are using
2048 * TASM debug stuff we are putting it in
2050 if (debuginfo || obj_entry_seg == NO_SEG) {
2051 orp->type = COMENT;
2052 obj_byte(orp, 0x40);
2053 obj_byte(orp, dLINKPASS);
2054 obj_byte(orp, 1);
2055 obj_emit2(orp);
2059 * 1) put out the compiler type
2060 * 2) Put out the type info. The only type we are using is near label #19
2062 if (debuginfo) {
2063 int i;
2064 struct Array *arrtmp = arrhead;
2065 orp->type = COMENT;
2066 obj_byte(orp, 0x40);
2067 obj_byte(orp, dCOMPDEF);
2068 obj_byte(orp, 4);
2069 obj_byte(orp, 0);
2070 obj_emit2(orp);
2072 obj_byte(orp, 0x40);
2073 obj_byte(orp, dTYPEDEF);
2074 obj_word(orp, 0x18); /* type # for linking */
2075 obj_word(orp, 6); /* size of type */
2076 obj_byte(orp, 0x2a); /* absolute type for debugging */
2077 obj_emit2(orp);
2078 obj_byte(orp, 0x40);
2079 obj_byte(orp, dTYPEDEF);
2080 obj_word(orp, 0x19); /* type # for linking */
2081 obj_word(orp, 0); /* size of type */
2082 obj_byte(orp, 0x24); /* absolute type for debugging */
2083 obj_byte(orp, 0); /* near/far specifier */
2084 obj_emit2(orp);
2085 obj_byte(orp, 0x40);
2086 obj_byte(orp, dTYPEDEF);
2087 obj_word(orp, 0x1A); /* type # for linking */
2088 obj_word(orp, 0); /* size of type */
2089 obj_byte(orp, 0x24); /* absolute type for debugging */
2090 obj_byte(orp, 1); /* near/far specifier */
2091 obj_emit2(orp);
2092 obj_byte(orp, 0x40);
2093 obj_byte(orp, dTYPEDEF);
2094 obj_word(orp, 0x1b); /* type # for linking */
2095 obj_word(orp, 0); /* size of type */
2096 obj_byte(orp, 0x23); /* absolute type for debugging */
2097 obj_byte(orp, 0);
2098 obj_byte(orp, 0);
2099 obj_byte(orp, 0);
2100 obj_emit2(orp);
2101 obj_byte(orp, 0x40);
2102 obj_byte(orp, dTYPEDEF);
2103 obj_word(orp, 0x1c); /* type # for linking */
2104 obj_word(orp, 0); /* size of type */
2105 obj_byte(orp, 0x23); /* absolute type for debugging */
2106 obj_byte(orp, 0);
2107 obj_byte(orp, 4);
2108 obj_byte(orp, 0);
2109 obj_emit2(orp);
2110 obj_byte(orp, 0x40);
2111 obj_byte(orp, dTYPEDEF);
2112 obj_word(orp, 0x1d); /* type # for linking */
2113 obj_word(orp, 0); /* size of type */
2114 obj_byte(orp, 0x23); /* absolute type for debugging */
2115 obj_byte(orp, 0);
2116 obj_byte(orp, 1);
2117 obj_byte(orp, 0);
2118 obj_emit2(orp);
2119 obj_byte(orp, 0x40);
2120 obj_byte(orp, dTYPEDEF);
2121 obj_word(orp, 0x1e); /* type # for linking */
2122 obj_word(orp, 0); /* size of type */
2123 obj_byte(orp, 0x23); /* absolute type for debugging */
2124 obj_byte(orp, 0);
2125 obj_byte(orp, 5);
2126 obj_byte(orp, 0);
2127 obj_emit2(orp);
2129 /* put out the array types */
2130 for (i = ARRAYBOT; i < arrindex; i++) {
2131 obj_byte(orp, 0x40);
2132 obj_byte(orp, dTYPEDEF);
2133 obj_word(orp, i); /* type # for linking */
2134 obj_word(orp, arrtmp->size); /* size of type */
2135 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2136 obj_byte(orp, arrtmp->basetype); /* base type */
2137 obj_emit2(orp);
2138 arrtmp = arrtmp->next;
2142 * write out line number info with a LINNUM record
2143 * switch records when we switch segments, and output the
2144 * file in a pseudo-TASM fashion. The record switch is naive; that
2145 * is that one file may have many records for the same segment
2146 * if there are lots of segment switches
2148 if (fnhead && debuginfo) {
2149 seg = fnhead->lnhead->segment;
2151 for (fn = fnhead; fn; fn = fn->next) {
2152 /* write out current file name */
2153 orp->type = COMENT;
2154 orp->ori = ori_null;
2155 obj_byte(orp, 0x40);
2156 obj_byte(orp, dFILNAME);
2157 obj_byte(orp, 0);
2158 obj_name(orp, fn->name);
2159 obj_dword(orp, 0);
2160 obj_emit2(orp);
2162 /* write out line numbers this file */
2164 orp->type = LINNUM;
2165 orp->ori = ori_linnum;
2166 for (ln = fn->lnhead; ln; ln = ln->next) {
2167 if (seg != ln->segment) {
2168 /* if we get here have to flush the buffer and start
2169 * a new record for a new segment
2171 seg = ln->segment;
2172 obj_emit(orp);
2174 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2175 orp->parm[1] = seg->obj_index;
2176 orp = obj_word(orp, ln->lineno);
2177 orp = obj_x(orp, ln->offset);
2178 obj_commit(orp);
2180 obj_emit(orp);
2184 * we are going to locate the entry point segment now
2185 * rather than wait until the MODEND record, because,
2186 * then we can output a special symbol to tell where the
2187 * entry point is.
2190 if (obj_entry_seg != NO_SEG) {
2191 for (seg = seghead; seg; seg = seg->next) {
2192 if (seg->index == obj_entry_seg) {
2193 entry_seg_ptr = seg;
2194 break;
2197 if (!seg)
2198 error(ERR_NONFATAL, "entry point is not in this module");
2202 * get ready to put out symbol records
2204 orp->type = COMENT;
2205 orp->ori = ori_local;
2208 * put out a symbol for the entry point
2209 * no dots in this symbol, because, borland does
2210 * not (officially) support dots in label names
2211 * and I don't know what various versions of TLINK will do
2213 if (debuginfo && obj_entry_seg != NO_SEG) {
2214 orp = obj_name(orp, "start_of_program");
2215 orp = obj_word(orp, 0x19); /* type: near label */
2216 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2217 orp = obj_index(orp, seg->obj_index);
2218 orp = obj_x(orp, obj_entry_ofs);
2219 obj_commit(orp);
2223 * put out the local labels
2225 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2226 /* labels this seg */
2227 for (loc = seg->lochead; loc; loc = loc->next) {
2228 orp = obj_name(orp, loc->name);
2229 orp = obj_word(orp, loc->type);
2230 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2231 orp = obj_index(orp, seg->obj_index);
2232 orp = obj_x(orp, loc->offset);
2233 obj_commit(orp);
2236 if (orp->used)
2237 obj_emit(orp);
2240 * Write the LEDATA/FIXUPP pairs.
2242 for (seg = seghead; seg; seg = seg->next) {
2243 obj_emit(seg->orp);
2244 nasm_free(seg->orp);
2248 * Write the MODEND module end marker.
2250 orp->type = obj_use32 ? MODE32 : MODEND;
2251 orp->ori = ori_null;
2252 if (entry_seg_ptr) {
2253 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2254 obj_byte(orp, 0xC1);
2255 seg = entry_seg_ptr;
2256 if (seg->grp) {
2257 obj_byte(orp, 0x10);
2258 obj_index(orp, seg->grp->obj_index);
2259 } else {
2261 * the below changed to prevent TLINK crashing.
2262 * Previous more efficient version read:
2264 * obj_byte (orp, 0x50);
2266 obj_byte(orp, 0x00);
2267 obj_index(orp, seg->obj_index);
2269 obj_index(orp, seg->obj_index);
2270 obj_x(orp, obj_entry_ofs);
2271 } else
2272 obj_byte(orp, 0);
2273 obj_emit2(orp);
2274 nasm_free(orp);
2277 static void obj_fwrite(ObjRecord * orp)
2279 unsigned int cksum, len;
2280 uint8_t *ptr;
2282 cksum = orp->type;
2283 if (orp->x_size == 32)
2284 cksum |= 1;
2285 fputc(cksum, ofp);
2286 len = orp->committed + 1;
2287 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2288 fwriteint16_t(len, ofp);
2289 fwrite(orp->buf, 1, len - 1, ofp);
2290 for (ptr = orp->buf; --len; ptr++)
2291 cksum += *ptr;
2292 fputc((-cksum) & 0xFF, ofp);
2295 static const char *obj_stdmac[] = {
2296 "%define __SECT__ [section .text]",
2297 "%imacro group 1+.nolist",
2298 "[group %1]",
2299 "%endmacro",
2300 "%imacro uppercase 0+.nolist",
2301 "[uppercase %1]",
2302 "%endmacro",
2303 "%imacro export 1+.nolist",
2304 "[export %1]",
2305 "%endmacro",
2306 "%imacro import 1+.nolist",
2307 "[import %1]",
2308 "%endmacro",
2309 "%macro __NASM_CDecl__ 1",
2310 "%endmacro",
2311 NULL
2314 void dbgbi_init(struct ofmt *of, void *id, FILE * fp, efunc error)
2316 (void)of;
2317 (void)id;
2318 (void)fp;
2319 (void)error;
2321 fnhead = NULL;
2322 fntail = &fnhead;
2323 arrindex = ARRAYBOT;
2324 arrhead = NULL;
2325 arrtail = &arrhead;
2327 static void dbgbi_cleanup(void)
2329 struct Segment *segtmp;
2330 while (fnhead) {
2331 struct FileName *fntemp = fnhead;
2332 while (fnhead->lnhead) {
2333 struct LineNumber *lntemp = fnhead->lnhead;
2334 fnhead->lnhead = lntemp->next;
2335 nasm_free(lntemp);
2337 fnhead = fnhead->next;
2338 nasm_free(fntemp->name);
2339 nasm_free(fntemp);
2341 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2342 while (segtmp->lochead) {
2343 struct Public *loctmp = segtmp->lochead;
2344 segtmp->lochead = loctmp->next;
2345 nasm_free(loctmp->name);
2346 nasm_free(loctmp);
2349 while (arrhead) {
2350 struct Array *arrtmp = arrhead;
2351 arrhead = arrhead->next;
2352 nasm_free(arrtmp);
2356 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2358 struct FileName *fn;
2359 struct LineNumber *ln;
2360 struct Segment *seg;
2362 if (segto == NO_SEG)
2363 return;
2366 * If `any_segs' is still false, we must define a default
2367 * segment.
2369 if (!any_segs) {
2370 int tempint; /* ignored */
2371 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2372 error(ERR_PANIC, "strange segment conditions in OBJ driver");
2376 * Find the segment we are targetting.
2378 for (seg = seghead; seg; seg = seg->next)
2379 if (seg->index == segto)
2380 break;
2381 if (!seg)
2382 error(ERR_PANIC, "lineno directed to nonexistent segment?");
2384 /* for (fn = fnhead; fn; fn = fnhead->next) */
2385 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2386 if (!nasm_stricmp(lnfname, fn->name))
2387 break;
2388 if (!fn) {
2389 fn = nasm_malloc(sizeof(*fn));
2390 fn->name = nasm_malloc(strlen(lnfname) + 1);
2391 strcpy(fn->name, lnfname);
2392 fn->lnhead = NULL;
2393 fn->lntail = &fn->lnhead;
2394 fn->next = NULL;
2395 *fntail = fn;
2396 fntail = &fn->next;
2398 ln = nasm_malloc(sizeof(*ln));
2399 ln->segment = seg;
2400 ln->offset = seg->currentpos;
2401 ln->lineno = lineno;
2402 ln->next = NULL;
2403 *fn->lntail = ln;
2404 fn->lntail = &ln->next;
2407 static void dbgbi_deflabel(char *name, int32_t segment,
2408 int64_t offset, int is_global, char *special)
2410 struct Segment *seg;
2412 (void)special;
2415 * If it's a special-retry from pass two, discard it.
2417 if (is_global == 3)
2418 return;
2421 * First check for the double-period, signifying something
2422 * unusual.
2424 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2425 return;
2429 * Case (i):
2431 if (obj_seg_needs_update) {
2432 return;
2433 } else if (obj_grp_needs_update) {
2434 return;
2436 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2437 return;
2439 if (segment >= SEG_ABS || segment == NO_SEG) {
2440 return;
2444 * If `any_segs' is still false, we might need to define a
2445 * default segment, if they're trying to declare a label in
2446 * `first_seg'. But the label should exist due to a prior
2447 * call to obj_deflabel so we can skip that.
2450 for (seg = seghead; seg; seg = seg->next)
2451 if (seg->index == segment) {
2452 struct Public *loc = nasm_malloc(sizeof(*loc));
2454 * Case (ii). Maybe MODPUB someday?
2456 last_defined = *seg->loctail = loc;
2457 seg->loctail = &loc->next;
2458 loc->next = NULL;
2459 loc->name = nasm_strdup(name);
2460 loc->offset = offset;
2463 static void dbgbi_typevalue(int32_t type)
2465 int vsize;
2466 int elem = TYM_ELEMENTS(type);
2467 type = TYM_TYPE(type);
2469 if (!last_defined)
2470 return;
2472 switch (type) {
2473 case TY_BYTE:
2474 last_defined->type = 8; /* uint8_t */
2475 vsize = 1;
2476 break;
2477 case TY_WORD:
2478 last_defined->type = 10; /* unsigned word */
2479 vsize = 2;
2480 break;
2481 case TY_DWORD:
2482 last_defined->type = 12; /* unsigned dword */
2483 vsize = 4;
2484 break;
2485 case TY_FLOAT:
2486 last_defined->type = 14; /* float */
2487 vsize = 4;
2488 break;
2489 case TY_QWORD:
2490 last_defined->type = 15; /* qword */
2491 vsize = 8;
2492 break;
2493 case TY_TBYTE:
2494 last_defined->type = 16; /* TBYTE */
2495 vsize = 10;
2496 break;
2497 default:
2498 last_defined->type = 0x19; /*label */
2499 vsize = 0;
2500 break;
2503 if (elem > 1) {
2504 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2505 int vtype = last_defined->type;
2506 arrtmp->size = vsize * elem;
2507 arrtmp->basetype = vtype;
2508 arrtmp->next = NULL;
2509 last_defined->type = arrindex++;
2510 *arrtail = arrtmp;
2511 arrtail = &(arrtmp->next);
2513 last_defined = NULL;
2515 static void dbgbi_output(int output_type, void *param)
2517 (void)output_type;
2518 (void)param;
2520 static struct dfmt borland_debug_form = {
2521 "Borland Debug Records",
2522 "borland",
2523 dbgbi_init,
2524 dbgbi_linnum,
2525 dbgbi_deflabel,
2526 null_debug_routine,
2527 dbgbi_typevalue,
2528 dbgbi_output,
2529 dbgbi_cleanup,
2532 static struct dfmt *borland_debug_arr[3] = {
2533 &borland_debug_form,
2534 &null_debug_form,
2535 NULL
2538 struct ofmt of_obj = {
2539 "MS-DOS 16-bit/32-bit OMF object files",
2540 "obj",
2541 NULL,
2542 borland_debug_arr,
2543 &null_debug_form,
2544 obj_stdmac,
2545 obj_init,
2546 obj_set_info,
2547 obj_out,
2548 obj_deflabel,
2549 obj_segment,
2550 obj_segbase,
2551 obj_directive,
2552 obj_filename,
2553 obj_cleanup
2555 #endif /* OF_OBJ */