Remove function pointers in output, simplify error handling
[nasm/sigaren-mirror.git] / output / outobj.c
blob2011a879af5040e22973979bba3cc8f79b5888de
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * outobj.c output routines for the Netwide Assembler to produce
36 * .OBJ object files
39 #include "compiler.h"
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <inttypes.h>
47 #include "nasm.h"
48 #include "nasmlib.h"
49 #include "stdscan.h"
50 #include "eval.h"
51 #include "output/outform.h"
52 #include "output/outlib.h"
54 #ifdef OF_OBJ
57 * outobj.c is divided into two sections. The first section is low level
58 * routines for creating obj records; It has nearly zero NASM specific
59 * code. The second section is high level routines for processing calls and
60 * data structures from the rest of NASM into obj format.
62 * It should be easy (though not zero work) to lift the first section out for
63 * use as an obj file writer for some other assembler or compiler.
67 * These routines are built around the ObjRecord data struture. An ObjRecord
68 * holds an object file record that may be under construction or complete.
70 * A major function of these routines is to support continuation of an obj
71 * record into the next record when the maximum record size is exceeded. The
72 * high level code does not need to worry about where the record breaks occur.
73 * It does need to do some minor extra steps to make the automatic continuation
74 * work. Those steps may be skipped for records where the high level knows no
75 * continuation could be required.
77 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
78 * is cleared by obj_clear.
80 * 2) The caller should fill in .type.
82 * 3) If the record is continuable and there is processing that must be done at
83 * the start of each record then the caller should fill in .ori with the
84 * address of the record initializer routine.
86 * 4) If the record is continuable and it should be saved (rather than emitted
87 * immediately) as each record is done, the caller should set .up to be a
88 * pointer to a location in which the caller keeps the master pointer to the
89 * ObjRecord. When the record is continued, the obj_bump routine will then
90 * allocate a new ObjRecord structure and update the master pointer.
92 * 5) If the .ori field was used then the caller should fill in the .parm with
93 * any data required by the initializer.
95 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
96 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
97 * data required for this record.
99 * 7) If the record is continuable, the caller should call obj_commit at each
100 * point where breaking the record is permitted.
102 * 8) To write out the record, the caller should call obj_emit2. If the
103 * caller has called obj_commit for all data written then he can get slightly
104 * faster code by calling obj_emit instead of obj_emit2.
106 * Most of these routines return an ObjRecord pointer. This will be the input
107 * pointer most of the time and will be the new location if the ObjRecord
108 * moved as a result of the call. The caller may ignore the return value in
109 * three cases: It is a "Never Reallocates" routine; or The caller knows
110 * continuation is not possible; or The caller uses the master pointer for the
111 * next operation.
114 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
115 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
117 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
118 #define FIX_16_OFFSET 0x8400
119 #define FIX_16_SELECTOR 0x8800
120 #define FIX_32_POINTER 0x8C00
121 #define FIX_08_HIGH 0x9000
122 #define FIX_32_OFFSET 0xA400
123 #define FIX_48_POINTER 0xAC00
125 enum RecordID { /* record ID codes */
127 THEADR = 0x80, /* module header */
128 COMENT = 0x88, /* comment record */
130 LINNUM = 0x94, /* line number record */
131 LNAMES = 0x96, /* list of names */
133 SEGDEF = 0x98, /* segment definition */
134 GRPDEF = 0x9A, /* group definition */
135 EXTDEF = 0x8C, /* external definition */
136 PUBDEF = 0x90, /* public definition */
137 COMDEF = 0xB0, /* common definition */
139 LEDATA = 0xA0, /* logical enumerated data */
140 FIXUPP = 0x9C, /* fixups (relocations) */
141 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
143 MODEND = 0x8A, /* module end */
144 MODE32 = 0x8B /* module end for 32-bit objects */
147 enum ComentID { /* ID codes for comment records */
149 dEXTENDED = 0xA1, /* tells that we are using translator-specific extensions */
150 dLINKPASS = 0xA2, /* link pass 2 marker */
151 dTYPEDEF = 0xE3, /* define a type */
152 dSYM = 0xE6, /* symbol debug record */
153 dFILNAME = 0xE8, /* file name record */
154 dCOMPDEF = 0xEA /* compiler type info */
157 typedef struct ObjRecord ObjRecord;
158 typedef void ORI(ObjRecord * orp);
160 struct ObjRecord {
161 ORI *ori; /* Initialization routine */
162 int used; /* Current data size */
163 int committed; /* Data size at last boundary */
164 int x_size; /* (see obj_x) */
165 unsigned int type; /* Record type */
166 ObjRecord *child; /* Associated record below this one */
167 ObjRecord **up; /* Master pointer to this ObjRecord */
168 ObjRecord *back; /* Previous part of this record */
169 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
170 uint8_t buf[RECORD_MAX + 3];
173 static void obj_fwrite(ObjRecord * orp);
174 static void ori_ledata(ObjRecord * orp);
175 static void ori_pubdef(ObjRecord * orp);
176 static void ori_null(ObjRecord * orp);
177 static ObjRecord *obj_commit(ObjRecord * orp);
179 static bool obj_uppercase; /* Flag: all names in uppercase */
180 static bool obj_use32; /* Flag: at least one segment is 32-bit */
183 * Clear an ObjRecord structure. (Never reallocates).
184 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
186 static ObjRecord *obj_clear(ObjRecord * orp)
188 orp->used = 0;
189 orp->committed = 0;
190 orp->x_size = 0;
191 orp->child = NULL;
192 orp->up = NULL;
193 orp->back = NULL;
194 return (orp);
198 * Emit an ObjRecord structure. (Never reallocates).
199 * The record is written out preceeded (recursively) by its previous part (if
200 * any) and followed (recursively) by its child (if any).
201 * The previous part and the child are freed. The main ObjRecord is cleared,
202 * not freed.
204 static ObjRecord *obj_emit(ObjRecord * orp)
206 if (orp->back) {
207 obj_emit(orp->back);
208 nasm_free(orp->back);
211 if (orp->committed)
212 obj_fwrite(orp);
214 if (orp->child) {
215 obj_emit(orp->child);
216 nasm_free(orp->child);
219 return (obj_clear(orp));
223 * Commit and Emit a record. (Never reallocates).
225 static ObjRecord *obj_emit2(ObjRecord * orp)
227 obj_commit(orp);
228 return (obj_emit(orp));
232 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
234 static ObjRecord *obj_new(void)
236 ObjRecord *orp;
238 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
239 orp->ori = ori_null;
240 return (orp);
244 * Advance to the next record because the existing one is full or its x_size
245 * is incompatible.
246 * Any uncommited data is moved into the next record.
248 static ObjRecord *obj_bump(ObjRecord * orp)
250 ObjRecord *nxt;
251 int used = orp->used;
252 int committed = orp->committed;
254 if (orp->up) {
255 *orp->up = nxt = obj_new();
256 nxt->ori = orp->ori;
257 nxt->type = orp->type;
258 nxt->up = orp->up;
259 nxt->back = orp;
260 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
261 } else
262 nxt = obj_emit(orp);
264 used -= committed;
265 if (used) {
266 nxt->committed = 1;
267 nxt->ori(nxt);
268 nxt->committed = nxt->used;
269 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
270 nxt->used = nxt->committed + used;
273 return (nxt);
277 * Advance to the next record if necessary to allow the next field to fit.
279 static ObjRecord *obj_check(ObjRecord * orp, int size)
281 if (orp->used + size > RECORD_MAX)
282 orp = obj_bump(orp);
284 if (!orp->committed) {
285 orp->committed = 1;
286 orp->ori(orp);
287 orp->committed = orp->used;
290 return (orp);
294 * All data written so far is commited to the current record (won't be moved to
295 * the next record in case of continuation).
297 static ObjRecord *obj_commit(ObjRecord * orp)
299 orp->committed = orp->used;
300 return (orp);
304 * Write a byte
306 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
308 orp = obj_check(orp, 1);
309 orp->buf[orp->used] = val;
310 orp->used++;
311 return (orp);
315 * Write a word
317 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
319 orp = obj_check(orp, 2);
320 orp->buf[orp->used] = val;
321 orp->buf[orp->used + 1] = val >> 8;
322 orp->used += 2;
323 return (orp);
327 * Write a reversed word
329 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
331 orp = obj_check(orp, 2);
332 orp->buf[orp->used] = val >> 8;
333 orp->buf[orp->used + 1] = val;
334 orp->used += 2;
335 return (orp);
339 * Write a dword
341 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
343 orp = obj_check(orp, 4);
344 orp->buf[orp->used] = val;
345 orp->buf[orp->used + 1] = val >> 8;
346 orp->buf[orp->used + 2] = val >> 16;
347 orp->buf[orp->used + 3] = val >> 24;
348 orp->used += 4;
349 return (orp);
353 * All fields of "size x" in one obj record must be the same size (either 16
354 * bits or 32 bits). There is a one bit flag in each record which specifies
355 * which.
356 * This routine is used to force the current record to have the desired
357 * x_size. x_size is normally automatic (using obj_x), so that this
358 * routine should be used outside obj_x, only to provide compatibility with
359 * linkers that have bugs in their processing of the size bit.
362 static ObjRecord *obj_force(ObjRecord * orp, int x)
364 if (orp->x_size == (x ^ 48))
365 orp = obj_bump(orp);
366 orp->x_size = x;
367 return (orp);
371 * This routine writes a field of size x. The caller does not need to worry at
372 * all about whether 16-bits or 32-bits are required.
374 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
376 if (orp->type & 1)
377 orp->x_size = 32;
378 if (val > 0xFFFF)
379 orp = obj_force(orp, 32);
380 if (orp->x_size == 32) {
381 ObjRecord *nxt = obj_dword(orp, val);
382 nxt->x_size = 32; /* x_size is cleared when a record overflows */
383 return nxt;
385 orp->x_size = 16;
386 return (obj_word(orp, val));
390 * Writes an index
392 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
394 if (val < 128)
395 return (obj_byte(orp, val));
396 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
400 * Writes a variable length value
402 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
404 if (val <= 128)
405 return (obj_byte(orp, val));
406 if (val <= 0xFFFF) {
407 orp = obj_byte(orp, 129);
408 return (obj_word(orp, val));
410 if (val <= 0xFFFFFF)
411 return (obj_dword(orp, (val << 8) + 132));
412 orp = obj_byte(orp, 136);
413 return (obj_dword(orp, val));
417 * Writes a counted string
419 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
421 int len = strlen(name);
422 uint8_t *ptr;
424 orp = obj_check(orp, len + 1);
425 ptr = orp->buf + orp->used;
426 *ptr++ = len;
427 orp->used += len + 1;
428 if (obj_uppercase)
429 while (--len >= 0) {
430 *ptr++ = toupper(*name);
431 name++;
432 } else
433 memcpy(ptr, name, len);
434 return (orp);
438 * Initializer for an LEDATA record.
439 * parm[0] = offset
440 * parm[1] = segment index
441 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
442 * represent the offset that would be required if the record were split at the
443 * last commit point.
444 * parm[2] is a copy of parm[0] as it was when the current record was initted.
446 static void ori_ledata(ObjRecord * orp)
448 obj_index(orp, orp->parm[1]);
449 orp->parm[2] = orp->parm[0];
450 obj_x(orp, orp->parm[0]);
454 * Initializer for a PUBDEF record.
455 * parm[0] = group index
456 * parm[1] = segment index
457 * parm[2] = frame (only used when both indexes are zero)
459 static void ori_pubdef(ObjRecord * orp)
461 obj_index(orp, orp->parm[0]);
462 obj_index(orp, orp->parm[1]);
463 if (!(orp->parm[0] | orp->parm[1]))
464 obj_word(orp, orp->parm[2]);
468 * Initializer for a LINNUM record.
469 * parm[0] = group index
470 * parm[1] = segment index
472 static void ori_linnum(ObjRecord * orp)
474 obj_index(orp, orp->parm[0]);
475 obj_index(orp, orp->parm[1]);
479 * Initializer for a local vars record.
481 static void ori_local(ObjRecord * orp)
483 obj_byte(orp, 0x40);
484 obj_byte(orp, dSYM);
488 * Null initializer for records that continue without any header info
490 static void ori_null(ObjRecord * orp)
492 (void)orp; /* Do nothing */
496 * This concludes the low level section of outobj.c
499 static char obj_infile[FILENAME_MAX];
501 static int32_t first_seg;
502 static bool any_segs;
503 static int passtwo;
504 static int arrindex;
506 #define GROUP_MAX 256 /* we won't _realistically_ have more
507 * than this many segs in a group */
508 #define EXT_BLKSIZ 256 /* block size for externals list */
510 struct Segment; /* need to know these structs exist */
511 struct Group;
513 struct LineNumber {
514 struct LineNumber *next;
515 struct Segment *segment;
516 int32_t offset;
517 int32_t lineno;
520 static struct FileName {
521 struct FileName *next;
522 char *name;
523 struct LineNumber *lnhead, **lntail;
524 int index;
525 } *fnhead, **fntail;
527 static struct Array {
528 struct Array *next;
529 unsigned size;
530 int basetype;
531 } *arrhead, **arrtail;
533 #define ARRAYBOT 31 /* magic number for first array index */
535 static struct Public {
536 struct Public *next;
537 char *name;
538 int32_t offset;
539 int32_t segment; /* only if it's far-absolute */
540 int type; /* only for local debug syms */
541 } *fpubhead, **fpubtail, *last_defined;
543 static struct External {
544 struct External *next;
545 char *name;
546 int32_t commonsize;
547 int32_t commonelem; /* element size if FAR, else zero */
548 int index; /* OBJ-file external index */
549 enum {
550 DEFWRT_NONE, /* no unusual default-WRT */
551 DEFWRT_STRING, /* a string we don't yet understand */
552 DEFWRT_SEGMENT, /* a segment */
553 DEFWRT_GROUP /* a group */
554 } defwrt_type;
555 union {
556 char *string;
557 struct Segment *seg;
558 struct Group *grp;
559 } defwrt_ptr;
560 struct External *next_dws; /* next with DEFWRT_STRING */
561 } *exthead, **exttail, *dws;
563 static int externals;
565 static struct ExtBack {
566 struct ExtBack *next;
567 struct External *exts[EXT_BLKSIZ];
568 } *ebhead, **ebtail;
570 static struct Segment {
571 struct Segment *next;
572 int32_t index; /* the NASM segment id */
573 int32_t obj_index; /* the OBJ-file segment index */
574 struct Group *grp; /* the group it beint32_ts to */
575 uint32_t currentpos;
576 int32_t align; /* can be SEG_ABS + absolute addr */
577 enum {
578 CMB_PRIVATE = 0,
579 CMB_PUBLIC = 2,
580 CMB_STACK = 5,
581 CMB_COMMON = 6
582 } combine;
583 bool use32; /* is this segment 32-bit? */
584 struct Public *pubhead, **pubtail, *lochead, **loctail;
585 char *name;
586 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
587 ObjRecord *orp;
588 } *seghead, **segtail, *obj_seg_needs_update;
590 static struct Group {
591 struct Group *next;
592 char *name;
593 int32_t index; /* NASM segment id */
594 int32_t obj_index; /* OBJ-file group index */
595 int32_t nentries; /* number of elements... */
596 int32_t nindices; /* ...and number of index elts... */
597 union {
598 int32_t index;
599 char *name;
600 } segs[GROUP_MAX]; /* ...in this */
601 } *grphead, **grptail, *obj_grp_needs_update;
603 static struct ImpDef {
604 struct ImpDef *next;
605 char *extname;
606 char *libname;
607 unsigned int impindex;
608 char *impname;
609 } *imphead, **imptail;
611 static struct ExpDef {
612 struct ExpDef *next;
613 char *intname;
614 char *extname;
615 unsigned int ordinal;
616 int flags;
617 } *exphead, **exptail;
619 #define EXPDEF_FLAG_ORDINAL 0x80
620 #define EXPDEF_FLAG_RESIDENT 0x40
621 #define EXPDEF_FLAG_NODATA 0x20
622 #define EXPDEF_MASK_PARMCNT 0x1F
624 static int32_t obj_entry_seg, obj_entry_ofs;
626 struct ofmt of_obj;
628 /* The current segment */
629 static struct Segment *current_seg;
631 static int32_t obj_segment(char *, int, int *);
632 static void obj_write_file(int debuginfo);
633 static int obj_directive(enum directives, char *, int);
635 static void obj_init(void)
637 first_seg = seg_alloc();
638 any_segs = false;
639 fpubhead = NULL;
640 fpubtail = &fpubhead;
641 exthead = NULL;
642 exttail = &exthead;
643 imphead = NULL;
644 imptail = &imphead;
645 exphead = NULL;
646 exptail = &exphead;
647 dws = NULL;
648 externals = 0;
649 ebhead = NULL;
650 ebtail = &ebhead;
651 seghead = obj_seg_needs_update = NULL;
652 segtail = &seghead;
653 grphead = obj_grp_needs_update = NULL;
654 grptail = &grphead;
655 obj_entry_seg = NO_SEG;
656 obj_uppercase = false;
657 obj_use32 = false;
658 passtwo = 0;
659 current_seg = NULL;
662 static int obj_set_info(enum geninfo type, char **val)
664 (void)type;
665 (void)val;
667 return 0;
669 static void obj_cleanup(int debuginfo)
671 obj_write_file(debuginfo);
672 of_obj.current_dfmt->cleanup();
673 while (seghead) {
674 struct Segment *segtmp = seghead;
675 seghead = seghead->next;
676 while (segtmp->pubhead) {
677 struct Public *pubtmp = segtmp->pubhead;
678 segtmp->pubhead = pubtmp->next;
679 nasm_free(pubtmp->name);
680 nasm_free(pubtmp);
682 nasm_free(segtmp->segclass);
683 nasm_free(segtmp->overlay);
684 nasm_free(segtmp);
686 while (fpubhead) {
687 struct Public *pubtmp = fpubhead;
688 fpubhead = fpubhead->next;
689 nasm_free(pubtmp->name);
690 nasm_free(pubtmp);
692 while (exthead) {
693 struct External *exttmp = exthead;
694 exthead = exthead->next;
695 nasm_free(exttmp);
697 while (imphead) {
698 struct ImpDef *imptmp = imphead;
699 imphead = imphead->next;
700 nasm_free(imptmp->extname);
701 nasm_free(imptmp->libname);
702 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
703 nasm_free(imptmp);
705 while (exphead) {
706 struct ExpDef *exptmp = exphead;
707 exphead = exphead->next;
708 nasm_free(exptmp->extname);
709 nasm_free(exptmp->intname);
710 nasm_free(exptmp);
712 while (ebhead) {
713 struct ExtBack *ebtmp = ebhead;
714 ebhead = ebhead->next;
715 nasm_free(ebtmp);
717 while (grphead) {
718 struct Group *grptmp = grphead;
719 grphead = grphead->next;
720 nasm_free(grptmp);
724 static void obj_ext_set_defwrt(struct External *ext, char *id)
726 struct Segment *seg;
727 struct Group *grp;
729 for (seg = seghead; seg; seg = seg->next)
730 if (!strcmp(seg->name, id)) {
731 ext->defwrt_type = DEFWRT_SEGMENT;
732 ext->defwrt_ptr.seg = seg;
733 nasm_free(id);
734 return;
737 for (grp = grphead; grp; grp = grp->next)
738 if (!strcmp(grp->name, id)) {
739 ext->defwrt_type = DEFWRT_GROUP;
740 ext->defwrt_ptr.grp = grp;
741 nasm_free(id);
742 return;
745 ext->defwrt_type = DEFWRT_STRING;
746 ext->defwrt_ptr.string = id;
747 ext->next_dws = dws;
748 dws = ext;
751 static void obj_deflabel(char *name, int32_t segment,
752 int64_t offset, int is_global, char *special)
755 * We have three cases:
757 * (i) `segment' is a segment-base. If so, set the name field
758 * for the segment or group structure it refers to, and then
759 * return.
761 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
762 * Save the label position for later output of a PUBDEF record.
763 * (Or a MODPUB, if we work out how.)
765 * (iii) `segment' is not one of our segments. Save the label
766 * position for later output of an EXTDEF, and also store a
767 * back-reference so that we can map later references to this
768 * segment number to the external index.
770 struct External *ext;
771 struct ExtBack *eb;
772 struct Segment *seg;
773 int i;
774 bool used_special = false; /* have we used the special text? */
776 #if defined(DEBUG) && DEBUG>2
777 fprintf(stderr,
778 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
779 name, segment, offset, is_global, special);
780 #endif
783 * If it's a special-retry from pass two, discard it.
785 if (is_global == 3)
786 return;
789 * First check for the double-period, signifying something
790 * unusual.
792 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
793 if (!strcmp(name, "..start")) {
794 obj_entry_seg = segment;
795 obj_entry_ofs = offset;
796 return;
798 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
802 * Case (i):
804 if (obj_seg_needs_update) {
805 obj_seg_needs_update->name = name;
806 return;
807 } else if (obj_grp_needs_update) {
808 obj_grp_needs_update->name = name;
809 return;
811 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
812 return;
814 if (segment >= SEG_ABS || segment == NO_SEG) {
816 * SEG_ABS subcase of (ii).
818 if (is_global) {
819 struct Public *pub;
821 pub = *fpubtail = nasm_malloc(sizeof(*pub));
822 fpubtail = &pub->next;
823 pub->next = NULL;
824 pub->name = nasm_strdup(name);
825 pub->offset = offset;
826 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
828 if (special)
829 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
830 " for this symbol type");
831 return;
835 * If `any_segs' is still false, we might need to define a
836 * default segment, if they're trying to declare a label in
837 * `first_seg'.
839 if (!any_segs && segment == first_seg) {
840 int tempint; /* ignored */
841 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
842 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
845 for (seg = seghead; seg && is_global; seg = seg->next)
846 if (seg->index == segment) {
847 struct Public *loc = nasm_malloc(sizeof(*loc));
849 * Case (ii). Maybe MODPUB someday?
851 *seg->pubtail = loc;
852 seg->pubtail = &loc->next;
853 loc->next = NULL;
854 loc->name = nasm_strdup(name);
855 loc->offset = offset;
857 if (special)
858 nasm_error(ERR_NONFATAL,
859 "OBJ supports no special symbol features"
860 " for this symbol type");
861 return;
865 * Case (iii).
867 if (is_global) {
868 ext = *exttail = nasm_malloc(sizeof(*ext));
869 ext->next = NULL;
870 exttail = &ext->next;
871 ext->name = name;
872 /* Place by default all externs into the current segment */
873 ext->defwrt_type = DEFWRT_NONE;
875 /* 28-Apr-2002 - John Coffman
876 The following code was introduced on 12-Aug-2000, and breaks fixups
877 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
878 (5.10). It was introduced after FIXUP32 was added, and may be needed
879 for 32-bit segments. The following will get 16-bit segments working
880 again, and maybe someone can correct the 'if' condition which is
881 actually needed.
883 #if 0
884 if (current_seg) {
885 #else
886 if (current_seg && current_seg->use32) {
887 if (current_seg->grp) {
888 ext->defwrt_type = DEFWRT_GROUP;
889 ext->defwrt_ptr.grp = current_seg->grp;
890 } else {
891 ext->defwrt_type = DEFWRT_SEGMENT;
892 ext->defwrt_ptr.seg = current_seg;
895 #endif
897 if (is_global == 2) {
898 ext->commonsize = offset;
899 ext->commonelem = 1; /* default FAR */
900 } else
901 ext->commonsize = 0;
902 } else
903 return;
906 * Now process the special text, if any, to find default-WRT
907 * specifications and common-variable element-size and near/far
908 * specifications.
910 while (special && *special) {
911 used_special = true;
914 * We might have a default-WRT specification.
916 if (!nasm_strnicmp(special, "wrt", 3)) {
917 char *p;
918 int len;
919 special += 3;
920 special += strspn(special, " \t");
921 p = nasm_strndup(special, len = strcspn(special, ":"));
922 obj_ext_set_defwrt(ext, p);
923 special += len;
924 if (*special && *special != ':')
925 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
926 " text for `%s'", ext->name);
927 else if (*special == ':')
928 special++;
932 * The NEAR or FAR keywords specify nearness or
933 * farness. FAR gives default element size 1.
935 if (!nasm_strnicmp(special, "far", 3)) {
936 if (ext->commonsize)
937 ext->commonelem = 1;
938 else
939 nasm_error(ERR_NONFATAL,
940 "`%s': `far' keyword may only be applied"
941 " to common variables\n", ext->name);
942 special += 3;
943 special += strspn(special, " \t");
944 } else if (!nasm_strnicmp(special, "near", 4)) {
945 if (ext->commonsize)
946 ext->commonelem = 0;
947 else
948 nasm_error(ERR_NONFATAL,
949 "`%s': `far' keyword may only be applied"
950 " to common variables\n", ext->name);
951 special += 4;
952 special += strspn(special, " \t");
956 * If it's a common, and anything else remains on the line
957 * before a further colon, evaluate it as an expression and
958 * use that as the element size. Forward references aren't
959 * allowed.
961 if (*special == ':')
962 special++;
963 else if (*special) {
964 if (ext->commonsize) {
965 expr *e;
966 struct tokenval tokval;
968 stdscan_reset();
969 stdscan_bufptr = special;
970 tokval.t_type = TOKEN_INVALID;
971 e = evaluate(stdscan, NULL, &tokval, NULL, 1, nasm_error, NULL);
972 if (e) {
973 if (!is_simple(e))
974 nasm_error(ERR_NONFATAL, "cannot use relocatable"
975 " expression as common-variable element size");
976 else
977 ext->commonelem = reloc_value(e);
979 special = stdscan_bufptr;
980 } else {
981 nasm_error(ERR_NONFATAL,
982 "`%s': element-size specifications only"
983 " apply to common variables", ext->name);
984 while (*special && *special != ':')
985 special++;
986 if (*special == ':')
987 special++;
992 i = segment / 2;
993 eb = ebhead;
994 if (!eb) {
995 eb = *ebtail = nasm_malloc(sizeof(*eb));
996 eb->next = NULL;
997 ebtail = &eb->next;
999 while (i >= EXT_BLKSIZ) {
1000 if (eb && eb->next)
1001 eb = eb->next;
1002 else {
1003 eb = *ebtail = nasm_malloc(sizeof(*eb));
1004 eb->next = NULL;
1005 ebtail = &eb->next;
1007 i -= EXT_BLKSIZ;
1009 eb->exts[i] = ext;
1010 ext->index = ++externals;
1012 if (special && !used_special)
1013 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1014 " for this symbol type");
1017 /* forward declaration */
1018 static void obj_write_fixup(ObjRecord * orp, int bytes,
1019 int segrel, int32_t seg, int32_t wrt,
1020 struct Segment *segto);
1022 static void obj_out(int32_t segto, const void *data,
1023 enum out_type type, uint64_t size,
1024 int32_t segment, int32_t wrt)
1026 const uint8_t *ucdata;
1027 int32_t ldata;
1028 struct Segment *seg;
1029 ObjRecord *orp;
1032 * handle absolute-assembly (structure definitions)
1034 if (segto == NO_SEG) {
1035 if (type != OUT_RESERVE)
1036 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1037 " space");
1038 return;
1042 * If `any_segs' is still false, we must define a default
1043 * segment.
1045 if (!any_segs) {
1046 int tempint; /* ignored */
1047 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1048 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
1052 * Find the segment we are targetting.
1054 for (seg = seghead; seg; seg = seg->next)
1055 if (seg->index == segto)
1056 break;
1057 if (!seg)
1058 nasm_error(ERR_PANIC, "code directed to nonexistent segment?");
1060 orp = seg->orp;
1061 orp->parm[0] = seg->currentpos;
1063 if (type == OUT_RAWDATA) {
1064 ucdata = data;
1065 while (size > 0) {
1066 unsigned int len;
1067 orp = obj_check(seg->orp, 1);
1068 len = RECORD_MAX - orp->used;
1069 if (len > size)
1070 len = size;
1071 memcpy(orp->buf + orp->used, ucdata, len);
1072 orp->committed = orp->used += len;
1073 orp->parm[0] = seg->currentpos += len;
1074 ucdata += len;
1075 size -= len;
1077 } else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
1078 type == OUT_REL4ADR) {
1079 int rsize;
1081 if (segment == NO_SEG && type != OUT_ADDRESS)
1082 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1083 " supported by OBJ format");
1084 if (segment >= SEG_ABS)
1085 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1086 " by OBJ format");
1087 ldata = *(int64_t *)data;
1088 if (type == OUT_REL2ADR) {
1089 ldata += (size - 2);
1090 size = 2;
1091 } else if (type == OUT_REL4ADR) {
1092 ldata += (size - 4);
1093 size = 4;
1095 if (size == 2)
1096 orp = obj_word(orp, ldata);
1097 else
1098 orp = obj_dword(orp, ldata);
1099 rsize = size;
1100 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1101 size == 4) {
1103 * This is a 4-byte segment-base relocation such as
1104 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1105 * these, but if the constant term has the 16 low bits
1106 * zero, we can just apply a 2-byte segment-base
1107 * relocation to the low word instead.
1109 rsize = 2;
1110 if (ldata & 0xFFFF)
1111 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1112 " dword-size segment base references");
1114 if (segment != NO_SEG)
1115 obj_write_fixup(orp, rsize,
1116 (type == OUT_ADDRESS ? 0x4000 : 0),
1117 segment, wrt, seg);
1118 seg->currentpos += size;
1119 } else if (type == OUT_RESERVE) {
1120 if (orp->committed)
1121 orp = obj_bump(orp);
1122 seg->currentpos += size;
1124 obj_commit(orp);
1127 static void obj_write_fixup(ObjRecord * orp, int bytes,
1128 int segrel, int32_t seg, int32_t wrt,
1129 struct Segment *segto)
1131 unsigned locat;
1132 int method;
1133 int base;
1134 int32_t tidx, fidx;
1135 struct Segment *s = NULL;
1136 struct Group *g = NULL;
1137 struct External *e = NULL;
1138 ObjRecord *forp;
1140 if (bytes == 1) {
1141 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1142 " one-byte relocations");
1143 return;
1146 forp = orp->child;
1147 if (forp == NULL) {
1148 orp->child = forp = obj_new();
1149 forp->up = &(orp->child);
1150 /* We should choose between FIXUPP and FIXU32 record type */
1151 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1152 if (segto->use32)
1153 forp->type = FIXU32;
1154 else
1155 forp->type = FIXUPP;
1158 if (seg % 2) {
1159 base = true;
1160 locat = FIX_16_SELECTOR;
1161 seg--;
1162 if (bytes != 2)
1163 nasm_error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1164 " through sanity check");
1165 } else {
1166 base = false;
1167 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1168 if (!segrel)
1170 * There is a bug in tlink that makes it process self relative
1171 * fixups incorrectly if the x_size doesn't match the location
1172 * size.
1174 forp = obj_force(forp, bytes << 3);
1177 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1179 tidx = fidx = -1, method = 0; /* placate optimisers */
1182 * See if we can find the segment ID in our segment list. If
1183 * so, we have a T4 (LSEG) target.
1185 for (s = seghead; s; s = s->next)
1186 if (s->index == seg)
1187 break;
1188 if (s)
1189 method = 4, tidx = s->obj_index;
1190 else {
1191 for (g = grphead; g; g = g->next)
1192 if (g->index == seg)
1193 break;
1194 if (g)
1195 method = 5, tidx = g->obj_index;
1196 else {
1197 int32_t i = seg / 2;
1198 struct ExtBack *eb = ebhead;
1199 while (i >= EXT_BLKSIZ) {
1200 if (eb)
1201 eb = eb->next;
1202 else
1203 break;
1204 i -= EXT_BLKSIZ;
1206 if (eb)
1207 method = 6, e = eb->exts[i], tidx = e->index;
1208 else
1209 nasm_error(ERR_PANIC,
1210 "unrecognised segment value in obj_write_fixup");
1215 * If no WRT given, assume the natural default, which is method
1216 * F5 unless:
1218 * - we are doing an OFFSET fixup for a grouped segment, in
1219 * which case we require F1 (group).
1221 * - we are doing an OFFSET fixup for an external with a
1222 * default WRT, in which case we must honour the default WRT.
1224 if (wrt == NO_SEG) {
1225 if (!base && s && s->grp)
1226 method |= 0x10, fidx = s->grp->obj_index;
1227 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1228 if (e->defwrt_type == DEFWRT_SEGMENT)
1229 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1230 else if (e->defwrt_type == DEFWRT_GROUP)
1231 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1232 else {
1233 nasm_error(ERR_NONFATAL, "default WRT specification for"
1234 " external `%s' unresolved", e->name);
1235 method |= 0x50, fidx = -1; /* got to do _something_ */
1237 } else
1238 method |= 0x50, fidx = -1;
1239 } else {
1241 * See if we can find the WRT-segment ID in our segment
1242 * list. If so, we have a F0 (LSEG) frame.
1244 for (s = seghead; s; s = s->next)
1245 if (s->index == wrt - 1)
1246 break;
1247 if (s)
1248 method |= 0x00, fidx = s->obj_index;
1249 else {
1250 for (g = grphead; g; g = g->next)
1251 if (g->index == wrt - 1)
1252 break;
1253 if (g)
1254 method |= 0x10, fidx = g->obj_index;
1255 else {
1256 int32_t i = wrt / 2;
1257 struct ExtBack *eb = ebhead;
1258 while (i >= EXT_BLKSIZ) {
1259 if (eb)
1260 eb = eb->next;
1261 else
1262 break;
1263 i -= EXT_BLKSIZ;
1265 if (eb)
1266 method |= 0x20, fidx = eb->exts[i]->index;
1267 else
1268 nasm_error(ERR_PANIC,
1269 "unrecognised WRT value in obj_write_fixup");
1274 forp = obj_byte(forp, method);
1275 if (fidx != -1)
1276 forp = obj_index(forp, fidx);
1277 forp = obj_index(forp, tidx);
1278 obj_commit(forp);
1281 static int32_t obj_segment(char *name, int pass, int *bits)
1284 * We call the label manager here to define a name for the new
1285 * segment, and when our _own_ label-definition stub gets
1286 * called in return, it should register the new segment name
1287 * using the pointer it gets passed. That way we save memory,
1288 * by sponging off the label manager.
1290 #if defined(DEBUG) && DEBUG>=3
1291 fprintf(stderr, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1292 name, pass, *bits);
1293 #endif
1294 if (!name) {
1295 *bits = 16;
1296 current_seg = NULL;
1297 return first_seg;
1298 } else {
1299 struct Segment *seg;
1300 struct Group *grp;
1301 struct External **extp;
1302 int obj_idx, i, attrs;
1303 bool rn_error;
1304 char *p;
1307 * Look for segment attributes.
1309 attrs = 0;
1310 while (*name == '.')
1311 name++; /* hack, but a documented one */
1312 p = name;
1313 while (*p && !nasm_isspace(*p))
1314 p++;
1315 if (*p) {
1316 *p++ = '\0';
1317 while (*p && nasm_isspace(*p))
1318 *p++ = '\0';
1320 while (*p) {
1321 while (*p && !nasm_isspace(*p))
1322 p++;
1323 if (*p) {
1324 *p++ = '\0';
1325 while (*p && nasm_isspace(*p))
1326 *p++ = '\0';
1329 attrs++;
1332 obj_idx = 1;
1333 for (seg = seghead; seg; seg = seg->next) {
1334 obj_idx++;
1335 if (!strcmp(seg->name, name)) {
1336 if (attrs > 0 && pass == 1)
1337 nasm_error(ERR_WARNING, "segment attributes specified on"
1338 " redeclaration of segment: ignoring");
1339 if (seg->use32)
1340 *bits = 32;
1341 else
1342 *bits = 16;
1343 current_seg = seg;
1344 return seg->index;
1348 *segtail = seg = nasm_malloc(sizeof(*seg));
1349 seg->next = NULL;
1350 segtail = &seg->next;
1351 seg->index = (any_segs ? seg_alloc() : first_seg);
1352 seg->obj_index = obj_idx;
1353 seg->grp = NULL;
1354 any_segs = true;
1355 seg->name = NULL;
1356 seg->currentpos = 0;
1357 seg->align = 1; /* default */
1358 seg->use32 = false; /* default */
1359 seg->combine = CMB_PUBLIC; /* default */
1360 seg->segclass = seg->overlay = NULL;
1361 seg->pubhead = NULL;
1362 seg->pubtail = &seg->pubhead;
1363 seg->lochead = NULL;
1364 seg->loctail = &seg->lochead;
1365 seg->orp = obj_new();
1366 seg->orp->up = &(seg->orp);
1367 seg->orp->ori = ori_ledata;
1368 seg->orp->type = LEDATA;
1369 seg->orp->parm[1] = obj_idx;
1372 * Process the segment attributes.
1374 p = name;
1375 while (attrs--) {
1376 p += strlen(p);
1377 while (!*p)
1378 p++;
1381 * `p' contains a segment attribute.
1383 if (!nasm_stricmp(p, "private"))
1384 seg->combine = CMB_PRIVATE;
1385 else if (!nasm_stricmp(p, "public"))
1386 seg->combine = CMB_PUBLIC;
1387 else if (!nasm_stricmp(p, "common"))
1388 seg->combine = CMB_COMMON;
1389 else if (!nasm_stricmp(p, "stack"))
1390 seg->combine = CMB_STACK;
1391 else if (!nasm_stricmp(p, "use16"))
1392 seg->use32 = false;
1393 else if (!nasm_stricmp(p, "use32"))
1394 seg->use32 = true;
1395 else if (!nasm_stricmp(p, "flat")) {
1397 * This segment is an OS/2 FLAT segment. That means
1398 * that its default group is group FLAT, even if
1399 * the group FLAT does not explicitly _contain_ the
1400 * segment.
1402 * When we see this, we must create the group
1403 * `FLAT', containing no segments, if it does not
1404 * already exist; then we must set the default
1405 * group of this segment to be the FLAT group.
1407 struct Group *grp;
1408 for (grp = grphead; grp; grp = grp->next)
1409 if (!strcmp(grp->name, "FLAT"))
1410 break;
1411 if (!grp) {
1412 obj_directive(D_GROUP, "FLAT", 1);
1413 for (grp = grphead; grp; grp = grp->next)
1414 if (!strcmp(grp->name, "FLAT"))
1415 break;
1416 if (!grp)
1417 nasm_error(ERR_PANIC, "failure to define FLAT?!");
1419 seg->grp = grp;
1420 } else if (!nasm_strnicmp(p, "class=", 6))
1421 seg->segclass = nasm_strdup(p + 6);
1422 else if (!nasm_strnicmp(p, "overlay=", 8))
1423 seg->overlay = nasm_strdup(p + 8);
1424 else if (!nasm_strnicmp(p, "align=", 6)) {
1425 seg->align = readnum(p + 6, &rn_error);
1426 if (rn_error) {
1427 seg->align = 1;
1428 nasm_error(ERR_NONFATAL, "segment alignment should be"
1429 " numeric");
1431 switch ((int)seg->align) {
1432 case 1: /* BYTE */
1433 case 2: /* WORD */
1434 case 4: /* DWORD */
1435 case 16: /* PARA */
1436 case 256: /* PAGE */
1437 case 4096: /* PharLap extension */
1438 break;
1439 case 8:
1440 nasm_error(ERR_WARNING,
1441 "OBJ format does not support alignment"
1442 " of 8: rounding up to 16");
1443 seg->align = 16;
1444 break;
1445 case 32:
1446 case 64:
1447 case 128:
1448 nasm_error(ERR_WARNING,
1449 "OBJ format does not support alignment"
1450 " of %d: rounding up to 256", seg->align);
1451 seg->align = 256;
1452 break;
1453 case 512:
1454 case 1024:
1455 case 2048:
1456 nasm_error(ERR_WARNING,
1457 "OBJ format does not support alignment"
1458 " of %d: rounding up to 4096", seg->align);
1459 seg->align = 4096;
1460 break;
1461 default:
1462 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1463 seg->align);
1464 seg->align = 1;
1465 break;
1467 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1468 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1469 if (rn_error)
1470 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1471 " attribute should be numeric");
1475 /* We need to know whenever we have at least one 32-bit segment */
1476 obj_use32 |= seg->use32;
1478 obj_seg_needs_update = seg;
1479 if (seg->align >= SEG_ABS)
1480 define_label(name, NO_SEG, seg->align - SEG_ABS,
1481 NULL, false, false, &of_obj, nasm_error);
1482 else
1483 define_label(name, seg->index + 1, 0L,
1484 NULL, false, false, &of_obj, nasm_error);
1485 obj_seg_needs_update = NULL;
1488 * See if this segment is defined in any groups.
1490 for (grp = grphead; grp; grp = grp->next) {
1491 for (i = grp->nindices; i < grp->nentries; i++) {
1492 if (!strcmp(grp->segs[i].name, seg->name)) {
1493 nasm_free(grp->segs[i].name);
1494 grp->segs[i] = grp->segs[grp->nindices];
1495 grp->segs[grp->nindices++].index = seg->obj_index;
1496 if (seg->grp)
1497 nasm_error(ERR_WARNING,
1498 "segment `%s' is already part of"
1499 " a group: first one takes precedence",
1500 seg->name);
1501 else
1502 seg->grp = grp;
1508 * Walk through the list of externals with unresolved
1509 * default-WRT clauses, and resolve any that point at this
1510 * segment.
1512 extp = &dws;
1513 while (*extp) {
1514 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1515 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1516 nasm_free((*extp)->defwrt_ptr.string);
1517 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1518 (*extp)->defwrt_ptr.seg = seg;
1519 *extp = (*extp)->next_dws;
1520 } else
1521 extp = &(*extp)->next_dws;
1524 if (seg->use32)
1525 *bits = 32;
1526 else
1527 *bits = 16;
1528 current_seg = seg;
1529 return seg->index;
1533 static int obj_directive(enum directives directive, char *value, int pass)
1535 switch (directive) {
1536 case D_GROUP:
1538 char *p, *q, *v;
1539 if (pass == 1) {
1540 struct Group *grp;
1541 struct Segment *seg;
1542 struct External **extp;
1543 int obj_idx;
1545 q = value;
1546 while (*q == '.')
1547 q++; /* hack, but a documented one */
1548 v = q;
1549 while (*q && !nasm_isspace(*q))
1550 q++;
1551 if (nasm_isspace(*q)) {
1552 *q++ = '\0';
1553 while (*q && nasm_isspace(*q))
1554 q++;
1557 * Here we used to sanity-check the group directive to
1558 * ensure nobody tried to declare a group containing no
1559 * segments. However, OS/2 does this as standard
1560 * practice, so the sanity check has been removed.
1562 * if (!*q) {
1563 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1564 * return 1;
1568 obj_idx = 1;
1569 for (grp = grphead; grp; grp = grp->next) {
1570 obj_idx++;
1571 if (!strcmp(grp->name, v)) {
1572 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1573 return 1;
1577 *grptail = grp = nasm_malloc(sizeof(*grp));
1578 grp->next = NULL;
1579 grptail = &grp->next;
1580 grp->index = seg_alloc();
1581 grp->obj_index = obj_idx;
1582 grp->nindices = grp->nentries = 0;
1583 grp->name = NULL;
1585 obj_grp_needs_update = grp;
1586 define_label(v, grp->index + 1, 0L,
1587 NULL, false, false, &of_obj, nasm_error);
1588 obj_grp_needs_update = NULL;
1590 while (*q) {
1591 p = q;
1592 while (*q && !nasm_isspace(*q))
1593 q++;
1594 if (nasm_isspace(*q)) {
1595 *q++ = '\0';
1596 while (*q && nasm_isspace(*q))
1597 q++;
1600 * Now p contains a segment name. Find it.
1602 for (seg = seghead; seg; seg = seg->next)
1603 if (!strcmp(seg->name, p))
1604 break;
1605 if (seg) {
1607 * We have a segment index. Shift a name entry
1608 * to the end of the array to make room.
1610 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1611 grp->segs[grp->nindices++].index = seg->obj_index;
1612 if (seg->grp)
1613 nasm_error(ERR_WARNING,
1614 "segment `%s' is already part of"
1615 " a group: first one takes precedence",
1616 seg->name);
1617 else
1618 seg->grp = grp;
1619 } else {
1621 * We have an as-yet undefined segment.
1622 * Remember its name, for later.
1624 grp->segs[grp->nentries++].name = nasm_strdup(p);
1629 * Walk through the list of externals with unresolved
1630 * default-WRT clauses, and resolve any that point at
1631 * this group.
1633 extp = &dws;
1634 while (*extp) {
1635 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1636 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1637 nasm_free((*extp)->defwrt_ptr.string);
1638 (*extp)->defwrt_type = DEFWRT_GROUP;
1639 (*extp)->defwrt_ptr.grp = grp;
1640 *extp = (*extp)->next_dws;
1641 } else
1642 extp = &(*extp)->next_dws;
1645 return 1;
1647 case D_UPPERCASE:
1648 obj_uppercase = true;
1649 return 1;
1651 case D_IMPORT:
1653 char *q, *extname, *libname, *impname;
1655 if (pass == 2)
1656 return 1; /* ignore in pass two */
1657 extname = q = value;
1658 while (*q && !nasm_isspace(*q))
1659 q++;
1660 if (nasm_isspace(*q)) {
1661 *q++ = '\0';
1662 while (*q && nasm_isspace(*q))
1663 q++;
1666 libname = q;
1667 while (*q && !nasm_isspace(*q))
1668 q++;
1669 if (nasm_isspace(*q)) {
1670 *q++ = '\0';
1671 while (*q && nasm_isspace(*q))
1672 q++;
1675 impname = q;
1677 if (!*extname || !*libname)
1678 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1679 " and library name");
1680 else {
1681 struct ImpDef *imp;
1682 bool err = false;
1684 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1685 imptail = &imp->next;
1686 imp->next = NULL;
1687 imp->extname = nasm_strdup(extname);
1688 imp->libname = nasm_strdup(libname);
1689 imp->impindex = readnum(impname, &err);
1690 if (!*impname || err)
1691 imp->impname = nasm_strdup(impname);
1692 else
1693 imp->impname = NULL;
1696 return 1;
1698 case D_EXPORT:
1700 char *q, *extname, *intname, *v;
1701 struct ExpDef *export;
1702 int flags = 0;
1703 unsigned int ordinal = 0;
1705 if (pass == 2)
1706 return 1; /* ignore in pass two */
1707 intname = q = value;
1708 while (*q && !nasm_isspace(*q))
1709 q++;
1710 if (nasm_isspace(*q)) {
1711 *q++ = '\0';
1712 while (*q && nasm_isspace(*q))
1713 q++;
1716 extname = q;
1717 while (*q && !nasm_isspace(*q))
1718 q++;
1719 if (nasm_isspace(*q)) {
1720 *q++ = '\0';
1721 while (*q && nasm_isspace(*q))
1722 q++;
1725 if (!*intname) {
1726 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1727 return 1;
1729 if (!*extname) {
1730 extname = intname;
1731 intname = "";
1733 while (*q) {
1734 v = q;
1735 while (*q && !nasm_isspace(*q))
1736 q++;
1737 if (nasm_isspace(*q)) {
1738 *q++ = '\0';
1739 while (*q && nasm_isspace(*q))
1740 q++;
1742 if (!nasm_stricmp(v, "resident"))
1743 flags |= EXPDEF_FLAG_RESIDENT;
1744 else if (!nasm_stricmp(v, "nodata"))
1745 flags |= EXPDEF_FLAG_NODATA;
1746 else if (!nasm_strnicmp(v, "parm=", 5)) {
1747 bool err = false;
1748 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1749 if (err) {
1750 nasm_error(ERR_NONFATAL,
1751 "value `%s' for `parm' is non-numeric", v + 5);
1752 return 1;
1754 } else {
1755 bool err = false;
1756 ordinal = readnum(v, &err);
1757 if (err) {
1758 nasm_error(ERR_NONFATAL,
1759 "unrecognised export qualifier `%s'", v);
1760 return 1;
1762 flags |= EXPDEF_FLAG_ORDINAL;
1766 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1767 exptail = &export->next;
1768 export->next = NULL;
1769 export->extname = nasm_strdup(extname);
1770 export->intname = nasm_strdup(intname);
1771 export->ordinal = ordinal;
1772 export->flags = flags;
1774 return 1;
1776 default:
1777 return 0;
1781 static int32_t obj_segbase(int32_t segment)
1783 struct Segment *seg;
1786 * Find the segment in our list.
1788 for (seg = seghead; seg; seg = seg->next)
1789 if (seg->index == segment - 1)
1790 break;
1792 if (!seg) {
1794 * Might be an external with a default WRT.
1796 int32_t i = segment / 2;
1797 struct ExtBack *eb = ebhead;
1798 struct External *e;
1800 while (i >= EXT_BLKSIZ) {
1801 if (eb)
1802 eb = eb->next;
1803 else
1804 break;
1805 i -= EXT_BLKSIZ;
1807 if (eb) {
1808 e = eb->exts[i];
1809 if (!e) {
1810 nasm_assert(pass0 == 0);
1811 /* Not available - can happen during optimization */
1812 return NO_SEG;
1815 switch (e->defwrt_type) {
1816 case DEFWRT_NONE:
1817 return segment; /* fine */
1818 case DEFWRT_SEGMENT:
1819 return e->defwrt_ptr.seg->index + 1;
1820 case DEFWRT_GROUP:
1821 return e->defwrt_ptr.grp->index + 1;
1822 default:
1823 return NO_SEG; /* can't tell what it is */
1827 return segment; /* not one of ours - leave it alone */
1830 if (seg->align >= SEG_ABS)
1831 return seg->align; /* absolute segment */
1832 if (seg->grp)
1833 return seg->grp->index + 1; /* grouped segment */
1835 return segment; /* no special treatment */
1838 static void obj_filename(char *inname, char *outname)
1840 strcpy(obj_infile, inname);
1841 standard_extension(inname, outname, ".obj");
1844 static void obj_write_file(int debuginfo)
1846 struct Segment *seg, *entry_seg_ptr = 0;
1847 struct FileName *fn;
1848 struct LineNumber *ln;
1849 struct Group *grp;
1850 struct Public *pub, *loc;
1851 struct External *ext;
1852 struct ImpDef *imp;
1853 struct ExpDef *export;
1854 int lname_idx;
1855 ObjRecord *orp;
1858 * Write the THEADR module header.
1860 orp = obj_new();
1861 orp->type = THEADR;
1862 obj_name(orp, obj_infile);
1863 obj_emit2(orp);
1866 * Write the NASM boast comment.
1868 orp->type = COMENT;
1869 obj_rword(orp, 0); /* comment type zero */
1870 obj_name(orp, nasm_comment);
1871 obj_emit2(orp);
1873 orp->type = COMENT;
1875 * Write the IMPDEF records, if any.
1877 for (imp = imphead; imp; imp = imp->next) {
1878 obj_rword(orp, 0xA0); /* comment class A0 */
1879 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1880 if (imp->impname)
1881 obj_byte(orp, 0); /* import by name */
1882 else
1883 obj_byte(orp, 1); /* import by ordinal */
1884 obj_name(orp, imp->extname);
1885 obj_name(orp, imp->libname);
1886 if (imp->impname)
1887 obj_name(orp, imp->impname);
1888 else
1889 obj_word(orp, imp->impindex);
1890 obj_emit2(orp);
1894 * Write the EXPDEF records, if any.
1896 for (export = exphead; export; export = export->next) {
1897 obj_rword(orp, 0xA0); /* comment class A0 */
1898 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1899 obj_byte(orp, export->flags);
1900 obj_name(orp, export->extname);
1901 obj_name(orp, export->intname);
1902 if (export->flags & EXPDEF_FLAG_ORDINAL)
1903 obj_word(orp, export->ordinal);
1904 obj_emit2(orp);
1907 /* we're using extended OMF if we put in debug info */
1908 if (debuginfo) {
1909 orp->type = COMENT;
1910 obj_byte(orp, 0x40);
1911 obj_byte(orp, dEXTENDED);
1912 obj_emit2(orp);
1916 * Write the first LNAMES record, containing LNAME one, which
1917 * is null. Also initialize the LNAME counter.
1919 orp->type = LNAMES;
1920 obj_byte(orp, 0);
1921 lname_idx = 1;
1923 * Write some LNAMES for the segment names
1925 for (seg = seghead; seg; seg = seg->next) {
1926 orp = obj_name(orp, seg->name);
1927 if (seg->segclass)
1928 orp = obj_name(orp, seg->segclass);
1929 if (seg->overlay)
1930 orp = obj_name(orp, seg->overlay);
1931 obj_commit(orp);
1934 * Write some LNAMES for the group names
1936 for (grp = grphead; grp; grp = grp->next) {
1937 orp = obj_name(orp, grp->name);
1938 obj_commit(orp);
1940 obj_emit(orp);
1943 * Write the SEGDEF records.
1945 orp->type = SEGDEF;
1946 for (seg = seghead; seg; seg = seg->next) {
1947 int acbp;
1948 uint32_t seglen = seg->currentpos;
1950 acbp = (seg->combine << 2); /* C field */
1952 if (seg->use32)
1953 acbp |= 0x01; /* P bit is Use32 flag */
1954 else if (seglen == 0x10000L) {
1955 seglen = 0; /* This special case may be needed for old linkers */
1956 acbp |= 0x02; /* B bit */
1959 /* A field */
1960 if (seg->align >= SEG_ABS)
1961 /* acbp |= 0x00 */ ;
1962 else if (seg->align >= 4096) {
1963 if (seg->align > 4096)
1964 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
1965 " than OBJ format supports", seg->name);
1966 acbp |= 0xC0; /* PharLap extension */
1967 } else if (seg->align >= 256) {
1968 acbp |= 0x80;
1969 } else if (seg->align >= 16) {
1970 acbp |= 0x60;
1971 } else if (seg->align >= 4) {
1972 acbp |= 0xA0;
1973 } else if (seg->align >= 2) {
1974 acbp |= 0x40;
1975 } else
1976 acbp |= 0x20;
1978 obj_byte(orp, acbp);
1979 if (seg->align & SEG_ABS) {
1980 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1981 obj_byte(orp, 0); /* Offset */
1983 obj_x(orp, seglen);
1984 obj_index(orp, ++lname_idx);
1985 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1986 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1987 obj_emit2(orp);
1991 * Write the GRPDEF records.
1993 orp->type = GRPDEF;
1994 for (grp = grphead; grp; grp = grp->next) {
1995 int i;
1997 if (grp->nindices != grp->nentries) {
1998 for (i = grp->nindices; i < grp->nentries; i++) {
1999 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2000 " `%s'", grp->name, grp->segs[i].name);
2001 nasm_free(grp->segs[i].name);
2002 grp->segs[i].name = NULL;
2005 obj_index(orp, ++lname_idx);
2006 for (i = 0; i < grp->nindices; i++) {
2007 obj_byte(orp, 0xFF);
2008 obj_index(orp, grp->segs[i].index);
2010 obj_emit2(orp);
2014 * Write the PUBDEF records: first the ones in the segments,
2015 * then the far-absolutes.
2017 orp->type = PUBDEF;
2018 orp->ori = ori_pubdef;
2019 for (seg = seghead; seg; seg = seg->next) {
2020 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2021 orp->parm[1] = seg->obj_index;
2022 for (pub = seg->pubhead; pub; pub = pub->next) {
2023 orp = obj_name(orp, pub->name);
2024 orp = obj_x(orp, pub->offset);
2025 orp = obj_byte(orp, 0); /* type index */
2026 obj_commit(orp);
2028 obj_emit(orp);
2030 orp->parm[0] = 0;
2031 orp->parm[1] = 0;
2032 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2033 if (orp->parm[2] != (uint32_t)pub->segment) {
2034 obj_emit(orp);
2035 orp->parm[2] = pub->segment;
2037 orp = obj_name(orp, pub->name);
2038 orp = obj_x(orp, pub->offset);
2039 orp = obj_byte(orp, 0); /* type index */
2040 obj_commit(orp);
2042 obj_emit(orp);
2045 * Write the EXTDEF and COMDEF records, in order.
2047 orp->ori = ori_null;
2048 for (ext = exthead; ext; ext = ext->next) {
2049 if (ext->commonsize == 0) {
2050 if (orp->type != EXTDEF) {
2051 obj_emit(orp);
2052 orp->type = EXTDEF;
2054 orp = obj_name(orp, ext->name);
2055 orp = obj_index(orp, 0);
2056 } else {
2057 if (orp->type != COMDEF) {
2058 obj_emit(orp);
2059 orp->type = COMDEF;
2061 orp = obj_name(orp, ext->name);
2062 orp = obj_index(orp, 0);
2063 if (ext->commonelem) {
2064 orp = obj_byte(orp, 0x61); /* far communal */
2065 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2066 orp = obj_value(orp, ext->commonelem);
2067 } else {
2068 orp = obj_byte(orp, 0x62); /* near communal */
2069 orp = obj_value(orp, ext->commonsize);
2072 obj_commit(orp);
2074 obj_emit(orp);
2077 * Write a COMENT record stating that the linker's first pass
2078 * may stop processing at this point. Exception is if our
2079 * MODEND record specifies a start point, in which case,
2080 * according to some variants of the documentation, this COMENT
2081 * should be omitted. So we'll omit it just in case.
2082 * But, TASM puts it in all the time so if we are using
2083 * TASM debug stuff we are putting it in
2085 if (debuginfo || obj_entry_seg == NO_SEG) {
2086 orp->type = COMENT;
2087 obj_byte(orp, 0x40);
2088 obj_byte(orp, dLINKPASS);
2089 obj_byte(orp, 1);
2090 obj_emit2(orp);
2094 * 1) put out the compiler type
2095 * 2) Put out the type info. The only type we are using is near label #19
2097 if (debuginfo) {
2098 int i;
2099 struct Array *arrtmp = arrhead;
2100 orp->type = COMENT;
2101 obj_byte(orp, 0x40);
2102 obj_byte(orp, dCOMPDEF);
2103 obj_byte(orp, 4);
2104 obj_byte(orp, 0);
2105 obj_emit2(orp);
2107 obj_byte(orp, 0x40);
2108 obj_byte(orp, dTYPEDEF);
2109 obj_word(orp, 0x18); /* type # for linking */
2110 obj_word(orp, 6); /* size of type */
2111 obj_byte(orp, 0x2a); /* absolute type for debugging */
2112 obj_emit2(orp);
2113 obj_byte(orp, 0x40);
2114 obj_byte(orp, dTYPEDEF);
2115 obj_word(orp, 0x19); /* type # for linking */
2116 obj_word(orp, 0); /* size of type */
2117 obj_byte(orp, 0x24); /* absolute type for debugging */
2118 obj_byte(orp, 0); /* near/far specifier */
2119 obj_emit2(orp);
2120 obj_byte(orp, 0x40);
2121 obj_byte(orp, dTYPEDEF);
2122 obj_word(orp, 0x1A); /* type # for linking */
2123 obj_word(orp, 0); /* size of type */
2124 obj_byte(orp, 0x24); /* absolute type for debugging */
2125 obj_byte(orp, 1); /* near/far specifier */
2126 obj_emit2(orp);
2127 obj_byte(orp, 0x40);
2128 obj_byte(orp, dTYPEDEF);
2129 obj_word(orp, 0x1b); /* type # for linking */
2130 obj_word(orp, 0); /* size of type */
2131 obj_byte(orp, 0x23); /* absolute type for debugging */
2132 obj_byte(orp, 0);
2133 obj_byte(orp, 0);
2134 obj_byte(orp, 0);
2135 obj_emit2(orp);
2136 obj_byte(orp, 0x40);
2137 obj_byte(orp, dTYPEDEF);
2138 obj_word(orp, 0x1c); /* type # for linking */
2139 obj_word(orp, 0); /* size of type */
2140 obj_byte(orp, 0x23); /* absolute type for debugging */
2141 obj_byte(orp, 0);
2142 obj_byte(orp, 4);
2143 obj_byte(orp, 0);
2144 obj_emit2(orp);
2145 obj_byte(orp, 0x40);
2146 obj_byte(orp, dTYPEDEF);
2147 obj_word(orp, 0x1d); /* type # for linking */
2148 obj_word(orp, 0); /* size of type */
2149 obj_byte(orp, 0x23); /* absolute type for debugging */
2150 obj_byte(orp, 0);
2151 obj_byte(orp, 1);
2152 obj_byte(orp, 0);
2153 obj_emit2(orp);
2154 obj_byte(orp, 0x40);
2155 obj_byte(orp, dTYPEDEF);
2156 obj_word(orp, 0x1e); /* type # for linking */
2157 obj_word(orp, 0); /* size of type */
2158 obj_byte(orp, 0x23); /* absolute type for debugging */
2159 obj_byte(orp, 0);
2160 obj_byte(orp, 5);
2161 obj_byte(orp, 0);
2162 obj_emit2(orp);
2164 /* put out the array types */
2165 for (i = ARRAYBOT; i < arrindex; i++) {
2166 obj_byte(orp, 0x40);
2167 obj_byte(orp, dTYPEDEF);
2168 obj_word(orp, i); /* type # for linking */
2169 obj_word(orp, arrtmp->size); /* size of type */
2170 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2171 obj_byte(orp, arrtmp->basetype); /* base type */
2172 obj_emit2(orp);
2173 arrtmp = arrtmp->next;
2177 * write out line number info with a LINNUM record
2178 * switch records when we switch segments, and output the
2179 * file in a pseudo-TASM fashion. The record switch is naive; that
2180 * is that one file may have many records for the same segment
2181 * if there are lots of segment switches
2183 if (fnhead && debuginfo) {
2184 seg = fnhead->lnhead->segment;
2186 for (fn = fnhead; fn; fn = fn->next) {
2187 /* write out current file name */
2188 orp->type = COMENT;
2189 orp->ori = ori_null;
2190 obj_byte(orp, 0x40);
2191 obj_byte(orp, dFILNAME);
2192 obj_byte(orp, 0);
2193 obj_name(orp, fn->name);
2194 obj_dword(orp, 0);
2195 obj_emit2(orp);
2197 /* write out line numbers this file */
2199 orp->type = LINNUM;
2200 orp->ori = ori_linnum;
2201 for (ln = fn->lnhead; ln; ln = ln->next) {
2202 if (seg != ln->segment) {
2203 /* if we get here have to flush the buffer and start
2204 * a new record for a new segment
2206 seg = ln->segment;
2207 obj_emit(orp);
2209 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2210 orp->parm[1] = seg->obj_index;
2211 orp = obj_word(orp, ln->lineno);
2212 orp = obj_x(orp, ln->offset);
2213 obj_commit(orp);
2215 obj_emit(orp);
2219 * we are going to locate the entry point segment now
2220 * rather than wait until the MODEND record, because,
2221 * then we can output a special symbol to tell where the
2222 * entry point is.
2225 if (obj_entry_seg != NO_SEG) {
2226 for (seg = seghead; seg; seg = seg->next) {
2227 if (seg->index == obj_entry_seg) {
2228 entry_seg_ptr = seg;
2229 break;
2232 if (!seg)
2233 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2237 * get ready to put out symbol records
2239 orp->type = COMENT;
2240 orp->ori = ori_local;
2243 * put out a symbol for the entry point
2244 * no dots in this symbol, because, borland does
2245 * not (officially) support dots in label names
2246 * and I don't know what various versions of TLINK will do
2248 if (debuginfo && obj_entry_seg != NO_SEG) {
2249 orp = obj_name(orp, "start_of_program");
2250 orp = obj_word(orp, 0x19); /* type: near label */
2251 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2252 orp = obj_index(orp, seg->obj_index);
2253 orp = obj_x(orp, obj_entry_ofs);
2254 obj_commit(orp);
2258 * put out the local labels
2260 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2261 /* labels this seg */
2262 for (loc = seg->lochead; loc; loc = loc->next) {
2263 orp = obj_name(orp, loc->name);
2264 orp = obj_word(orp, loc->type);
2265 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2266 orp = obj_index(orp, seg->obj_index);
2267 orp = obj_x(orp, loc->offset);
2268 obj_commit(orp);
2271 if (orp->used)
2272 obj_emit(orp);
2275 * Write the LEDATA/FIXUPP pairs.
2277 for (seg = seghead; seg; seg = seg->next) {
2278 obj_emit(seg->orp);
2279 nasm_free(seg->orp);
2283 * Write the MODEND module end marker.
2285 orp->type = obj_use32 ? MODE32 : MODEND;
2286 orp->ori = ori_null;
2287 if (entry_seg_ptr) {
2288 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2289 obj_byte(orp, 0xC1);
2290 seg = entry_seg_ptr;
2291 if (seg->grp) {
2292 obj_byte(orp, 0x10);
2293 obj_index(orp, seg->grp->obj_index);
2294 } else {
2296 * the below changed to prevent TLINK crashing.
2297 * Previous more efficient version read:
2299 * obj_byte (orp, 0x50);
2301 obj_byte(orp, 0x00);
2302 obj_index(orp, seg->obj_index);
2304 obj_index(orp, seg->obj_index);
2305 obj_x(orp, obj_entry_ofs);
2306 } else
2307 obj_byte(orp, 0);
2308 obj_emit2(orp);
2309 nasm_free(orp);
2312 static void obj_fwrite(ObjRecord * orp)
2314 unsigned int cksum, len;
2315 uint8_t *ptr;
2317 cksum = orp->type;
2318 if (orp->x_size == 32)
2319 cksum |= 1;
2320 fputc(cksum, ofile);
2321 len = orp->committed + 1;
2322 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2323 fwriteint16_t(len, ofile);
2324 fwrite(orp->buf, 1, len - 1, ofile);
2325 for (ptr = orp->buf; --len; ptr++)
2326 cksum += *ptr;
2327 fputc((-cksum) & 0xFF, ofile);
2330 extern macros_t obj_stdmac[];
2332 void dbgbi_init(void)
2334 fnhead = NULL;
2335 fntail = &fnhead;
2336 arrindex = ARRAYBOT;
2337 arrhead = NULL;
2338 arrtail = &arrhead;
2340 static void dbgbi_cleanup(void)
2342 struct Segment *segtmp;
2343 while (fnhead) {
2344 struct FileName *fntemp = fnhead;
2345 while (fnhead->lnhead) {
2346 struct LineNumber *lntemp = fnhead->lnhead;
2347 fnhead->lnhead = lntemp->next;
2348 nasm_free(lntemp);
2350 fnhead = fnhead->next;
2351 nasm_free(fntemp->name);
2352 nasm_free(fntemp);
2354 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2355 while (segtmp->lochead) {
2356 struct Public *loctmp = segtmp->lochead;
2357 segtmp->lochead = loctmp->next;
2358 nasm_free(loctmp->name);
2359 nasm_free(loctmp);
2362 while (arrhead) {
2363 struct Array *arrtmp = arrhead;
2364 arrhead = arrhead->next;
2365 nasm_free(arrtmp);
2369 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2371 struct FileName *fn;
2372 struct LineNumber *ln;
2373 struct Segment *seg;
2375 if (segto == NO_SEG)
2376 return;
2379 * If `any_segs' is still false, we must define a default
2380 * segment.
2382 if (!any_segs) {
2383 int tempint; /* ignored */
2384 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2385 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
2389 * Find the segment we are targetting.
2391 for (seg = seghead; seg; seg = seg->next)
2392 if (seg->index == segto)
2393 break;
2394 if (!seg)
2395 nasm_error(ERR_PANIC, "lineno directed to nonexistent segment?");
2397 /* for (fn = fnhead; fn; fn = fnhead->next) */
2398 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2399 if (!nasm_stricmp(lnfname, fn->name))
2400 break;
2401 if (!fn) {
2402 fn = nasm_malloc(sizeof(*fn));
2403 fn->name = nasm_malloc(strlen(lnfname) + 1);
2404 strcpy(fn->name, lnfname);
2405 fn->lnhead = NULL;
2406 fn->lntail = &fn->lnhead;
2407 fn->next = NULL;
2408 *fntail = fn;
2409 fntail = &fn->next;
2411 ln = nasm_malloc(sizeof(*ln));
2412 ln->segment = seg;
2413 ln->offset = seg->currentpos;
2414 ln->lineno = lineno;
2415 ln->next = NULL;
2416 *fn->lntail = ln;
2417 fn->lntail = &ln->next;
2420 static void dbgbi_deflabel(char *name, int32_t segment,
2421 int64_t offset, int is_global, char *special)
2423 struct Segment *seg;
2425 (void)special;
2428 * If it's a special-retry from pass two, discard it.
2430 if (is_global == 3)
2431 return;
2434 * First check for the double-period, signifying something
2435 * unusual.
2437 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2438 return;
2442 * Case (i):
2444 if (obj_seg_needs_update) {
2445 return;
2446 } else if (obj_grp_needs_update) {
2447 return;
2449 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2450 return;
2452 if (segment >= SEG_ABS || segment == NO_SEG) {
2453 return;
2457 * If `any_segs' is still false, we might need to define a
2458 * default segment, if they're trying to declare a label in
2459 * `first_seg'. But the label should exist due to a prior
2460 * call to obj_deflabel so we can skip that.
2463 for (seg = seghead; seg; seg = seg->next)
2464 if (seg->index == segment) {
2465 struct Public *loc = nasm_malloc(sizeof(*loc));
2467 * Case (ii). Maybe MODPUB someday?
2469 last_defined = *seg->loctail = loc;
2470 seg->loctail = &loc->next;
2471 loc->next = NULL;
2472 loc->name = nasm_strdup(name);
2473 loc->offset = offset;
2476 static void dbgbi_typevalue(int32_t type)
2478 int vsize;
2479 int elem = TYM_ELEMENTS(type);
2480 type = TYM_TYPE(type);
2482 if (!last_defined)
2483 return;
2485 switch (type) {
2486 case TY_BYTE:
2487 last_defined->type = 8; /* uint8_t */
2488 vsize = 1;
2489 break;
2490 case TY_WORD:
2491 last_defined->type = 10; /* unsigned word */
2492 vsize = 2;
2493 break;
2494 case TY_DWORD:
2495 last_defined->type = 12; /* unsigned dword */
2496 vsize = 4;
2497 break;
2498 case TY_FLOAT:
2499 last_defined->type = 14; /* float */
2500 vsize = 4;
2501 break;
2502 case TY_QWORD:
2503 last_defined->type = 15; /* qword */
2504 vsize = 8;
2505 break;
2506 case TY_TBYTE:
2507 last_defined->type = 16; /* TBYTE */
2508 vsize = 10;
2509 break;
2510 default:
2511 last_defined->type = 0x19; /*label */
2512 vsize = 0;
2513 break;
2516 if (elem > 1) {
2517 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2518 int vtype = last_defined->type;
2519 arrtmp->size = vsize * elem;
2520 arrtmp->basetype = vtype;
2521 arrtmp->next = NULL;
2522 last_defined->type = arrindex++;
2523 *arrtail = arrtmp;
2524 arrtail = &(arrtmp->next);
2526 last_defined = NULL;
2528 static void dbgbi_output(int output_type, void *param)
2530 (void)output_type;
2531 (void)param;
2533 static struct dfmt borland_debug_form = {
2534 "Borland Debug Records",
2535 "borland",
2536 dbgbi_init,
2537 dbgbi_linnum,
2538 dbgbi_deflabel,
2539 null_debug_routine,
2540 dbgbi_typevalue,
2541 dbgbi_output,
2542 dbgbi_cleanup,
2545 static struct dfmt *borland_debug_arr[3] = {
2546 &borland_debug_form,
2547 &null_debug_form,
2548 NULL
2551 struct ofmt of_obj = {
2552 "MS-DOS 16-bit/32-bit OMF object files",
2553 "obj",
2555 borland_debug_arr,
2556 &borland_debug_form,
2557 obj_stdmac,
2558 obj_init,
2559 obj_set_info,
2560 obj_out,
2561 obj_deflabel,
2562 obj_segment,
2563 obj_segbase,
2564 obj_directive,
2565 obj_filename,
2566 obj_cleanup
2568 #endif /* OF_OBJ */