NASM 2.09rc1
[nasm/avx512.git] / output / outobj.c
blobf66017099b51e2a432b20356740016e148e52ad2
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 nasm_error(ERR_DEBUG,
778 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", 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_set(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_get();
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 switch (type) {
1064 case OUT_RAWDATA:
1065 ucdata = data;
1066 while (size > 0) {
1067 unsigned int len;
1068 orp = obj_check(seg->orp, 1);
1069 len = RECORD_MAX - orp->used;
1070 if (len > size)
1071 len = size;
1072 memcpy(orp->buf + orp->used, ucdata, len);
1073 orp->committed = orp->used += len;
1074 orp->parm[0] = seg->currentpos += len;
1075 ucdata += len;
1076 size -= len;
1078 break;
1080 case OUT_ADDRESS:
1081 case OUT_REL1ADR:
1082 case OUT_REL2ADR:
1083 case OUT_REL4ADR:
1084 case OUT_REL8ADR:
1086 int rsize;
1088 if (segment == NO_SEG && type != OUT_ADDRESS)
1089 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1090 " supported by OBJ format");
1091 if (segment >= SEG_ABS)
1092 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1093 " by OBJ format");
1095 ldata = *(int64_t *)data;
1096 if (type != OUT_ADDRESS) {
1097 ldata += size;
1098 size = realsize(type, size);
1099 ldata -= size;
1102 switch (size) {
1103 default:
1104 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1105 "32-byte relocations");
1106 segment = NO_SEG; /* Don't actually generate a relocation */
1107 break;
1108 case 2:
1109 orp = obj_word(orp, ldata);
1110 break;
1111 case 4:
1112 orp = obj_dword(orp, ldata);
1113 break;
1116 rsize = size;
1117 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1118 size == 4) {
1120 * This is a 4-byte segment-base relocation such as
1121 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1122 * these, but if the constant term has the 16 low bits
1123 * zero, we can just apply a 2-byte segment-base
1124 * relocation to the low word instead.
1126 rsize = 2;
1127 if (ldata & 0xFFFF)
1128 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1129 " dword-size segment base references");
1131 if (segment != NO_SEG)
1132 obj_write_fixup(orp, rsize,
1133 (type == OUT_ADDRESS ? 0x4000 : 0),
1134 segment, wrt, seg);
1135 seg->currentpos += size;
1136 break;
1139 default:
1140 nasm_error(ERR_NONFATAL,
1141 "Relocation type not supported by output format");
1142 /* fall through */
1144 case OUT_RESERVE:
1145 if (orp->committed)
1146 orp = obj_bump(orp);
1147 seg->currentpos += size;
1148 break;
1150 obj_commit(orp);
1153 static void obj_write_fixup(ObjRecord * orp, int bytes,
1154 int segrel, int32_t seg, int32_t wrt,
1155 struct Segment *segto)
1157 unsigned locat;
1158 int method;
1159 int base;
1160 int32_t tidx, fidx;
1161 struct Segment *s = NULL;
1162 struct Group *g = NULL;
1163 struct External *e = NULL;
1164 ObjRecord *forp;
1166 if (bytes != 2 && bytes != 4) {
1167 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1168 " %d-bit relocations", bytes << 3);
1169 return;
1172 forp = orp->child;
1173 if (forp == NULL) {
1174 orp->child = forp = obj_new();
1175 forp->up = &(orp->child);
1176 /* We should choose between FIXUPP and FIXU32 record type */
1177 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1178 if (segto->use32)
1179 forp->type = FIXU32;
1180 else
1181 forp->type = FIXUPP;
1184 if (seg % 2) {
1185 base = true;
1186 locat = FIX_16_SELECTOR;
1187 seg--;
1188 if (bytes != 2)
1189 nasm_error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1190 " through sanity check");
1191 } else {
1192 base = false;
1193 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1194 if (!segrel)
1196 * There is a bug in tlink that makes it process self relative
1197 * fixups incorrectly if the x_size doesn't match the location
1198 * size.
1200 forp = obj_force(forp, bytes << 3);
1203 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1205 tidx = fidx = -1, method = 0; /* placate optimisers */
1208 * See if we can find the segment ID in our segment list. If
1209 * so, we have a T4 (LSEG) target.
1211 for (s = seghead; s; s = s->next)
1212 if (s->index == seg)
1213 break;
1214 if (s)
1215 method = 4, tidx = s->obj_index;
1216 else {
1217 for (g = grphead; g; g = g->next)
1218 if (g->index == seg)
1219 break;
1220 if (g)
1221 method = 5, tidx = g->obj_index;
1222 else {
1223 int32_t i = seg / 2;
1224 struct ExtBack *eb = ebhead;
1225 while (i >= EXT_BLKSIZ) {
1226 if (eb)
1227 eb = eb->next;
1228 else
1229 break;
1230 i -= EXT_BLKSIZ;
1232 if (eb)
1233 method = 6, e = eb->exts[i], tidx = e->index;
1234 else
1235 nasm_error(ERR_PANIC,
1236 "unrecognised segment value in obj_write_fixup");
1241 * If no WRT given, assume the natural default, which is method
1242 * F5 unless:
1244 * - we are doing an OFFSET fixup for a grouped segment, in
1245 * which case we require F1 (group).
1247 * - we are doing an OFFSET fixup for an external with a
1248 * default WRT, in which case we must honour the default WRT.
1250 if (wrt == NO_SEG) {
1251 if (!base && s && s->grp)
1252 method |= 0x10, fidx = s->grp->obj_index;
1253 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1254 if (e->defwrt_type == DEFWRT_SEGMENT)
1255 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1256 else if (e->defwrt_type == DEFWRT_GROUP)
1257 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1258 else {
1259 nasm_error(ERR_NONFATAL, "default WRT specification for"
1260 " external `%s' unresolved", e->name);
1261 method |= 0x50, fidx = -1; /* got to do _something_ */
1263 } else
1264 method |= 0x50, fidx = -1;
1265 } else {
1267 * See if we can find the WRT-segment ID in our segment
1268 * list. If so, we have a F0 (LSEG) frame.
1270 for (s = seghead; s; s = s->next)
1271 if (s->index == wrt - 1)
1272 break;
1273 if (s)
1274 method |= 0x00, fidx = s->obj_index;
1275 else {
1276 for (g = grphead; g; g = g->next)
1277 if (g->index == wrt - 1)
1278 break;
1279 if (g)
1280 method |= 0x10, fidx = g->obj_index;
1281 else {
1282 int32_t i = wrt / 2;
1283 struct ExtBack *eb = ebhead;
1284 while (i >= EXT_BLKSIZ) {
1285 if (eb)
1286 eb = eb->next;
1287 else
1288 break;
1289 i -= EXT_BLKSIZ;
1291 if (eb)
1292 method |= 0x20, fidx = eb->exts[i]->index;
1293 else
1294 nasm_error(ERR_PANIC,
1295 "unrecognised WRT value in obj_write_fixup");
1300 forp = obj_byte(forp, method);
1301 if (fidx != -1)
1302 forp = obj_index(forp, fidx);
1303 forp = obj_index(forp, tidx);
1304 obj_commit(forp);
1307 static int32_t obj_segment(char *name, int pass, int *bits)
1310 * We call the label manager here to define a name for the new
1311 * segment, and when our _own_ label-definition stub gets
1312 * called in return, it should register the new segment name
1313 * using the pointer it gets passed. That way we save memory,
1314 * by sponging off the label manager.
1316 #if defined(DEBUG) && DEBUG>=3
1317 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1318 name, pass, *bits);
1319 #endif
1320 if (!name) {
1321 *bits = 16;
1322 current_seg = NULL;
1323 return first_seg;
1324 } else {
1325 struct Segment *seg;
1326 struct Group *grp;
1327 struct External **extp;
1328 int obj_idx, i, attrs;
1329 bool rn_error;
1330 char *p;
1333 * Look for segment attributes.
1335 attrs = 0;
1336 while (*name == '.')
1337 name++; /* hack, but a documented one */
1338 p = name;
1339 while (*p && !nasm_isspace(*p))
1340 p++;
1341 if (*p) {
1342 *p++ = '\0';
1343 while (*p && nasm_isspace(*p))
1344 *p++ = '\0';
1346 while (*p) {
1347 while (*p && !nasm_isspace(*p))
1348 p++;
1349 if (*p) {
1350 *p++ = '\0';
1351 while (*p && nasm_isspace(*p))
1352 *p++ = '\0';
1355 attrs++;
1358 obj_idx = 1;
1359 for (seg = seghead; seg; seg = seg->next) {
1360 obj_idx++;
1361 if (!strcmp(seg->name, name)) {
1362 if (attrs > 0 && pass == 1)
1363 nasm_error(ERR_WARNING, "segment attributes specified on"
1364 " redeclaration of segment: ignoring");
1365 if (seg->use32)
1366 *bits = 32;
1367 else
1368 *bits = 16;
1369 current_seg = seg;
1370 return seg->index;
1374 *segtail = seg = nasm_malloc(sizeof(*seg));
1375 seg->next = NULL;
1376 segtail = &seg->next;
1377 seg->index = (any_segs ? seg_alloc() : first_seg);
1378 seg->obj_index = obj_idx;
1379 seg->grp = NULL;
1380 any_segs = true;
1381 seg->name = NULL;
1382 seg->currentpos = 0;
1383 seg->align = 1; /* default */
1384 seg->use32 = false; /* default */
1385 seg->combine = CMB_PUBLIC; /* default */
1386 seg->segclass = seg->overlay = NULL;
1387 seg->pubhead = NULL;
1388 seg->pubtail = &seg->pubhead;
1389 seg->lochead = NULL;
1390 seg->loctail = &seg->lochead;
1391 seg->orp = obj_new();
1392 seg->orp->up = &(seg->orp);
1393 seg->orp->ori = ori_ledata;
1394 seg->orp->type = LEDATA;
1395 seg->orp->parm[1] = obj_idx;
1398 * Process the segment attributes.
1400 p = name;
1401 while (attrs--) {
1402 p += strlen(p);
1403 while (!*p)
1404 p++;
1407 * `p' contains a segment attribute.
1409 if (!nasm_stricmp(p, "private"))
1410 seg->combine = CMB_PRIVATE;
1411 else if (!nasm_stricmp(p, "public"))
1412 seg->combine = CMB_PUBLIC;
1413 else if (!nasm_stricmp(p, "common"))
1414 seg->combine = CMB_COMMON;
1415 else if (!nasm_stricmp(p, "stack"))
1416 seg->combine = CMB_STACK;
1417 else if (!nasm_stricmp(p, "use16"))
1418 seg->use32 = false;
1419 else if (!nasm_stricmp(p, "use32"))
1420 seg->use32 = true;
1421 else if (!nasm_stricmp(p, "flat")) {
1423 * This segment is an OS/2 FLAT segment. That means
1424 * that its default group is group FLAT, even if
1425 * the group FLAT does not explicitly _contain_ the
1426 * segment.
1428 * When we see this, we must create the group
1429 * `FLAT', containing no segments, if it does not
1430 * already exist; then we must set the default
1431 * group of this segment to be the FLAT group.
1433 struct Group *grp;
1434 for (grp = grphead; grp; grp = grp->next)
1435 if (!strcmp(grp->name, "FLAT"))
1436 break;
1437 if (!grp) {
1438 obj_directive(D_GROUP, "FLAT", 1);
1439 for (grp = grphead; grp; grp = grp->next)
1440 if (!strcmp(grp->name, "FLAT"))
1441 break;
1442 if (!grp)
1443 nasm_error(ERR_PANIC, "failure to define FLAT?!");
1445 seg->grp = grp;
1446 } else if (!nasm_strnicmp(p, "class=", 6))
1447 seg->segclass = nasm_strdup(p + 6);
1448 else if (!nasm_strnicmp(p, "overlay=", 8))
1449 seg->overlay = nasm_strdup(p + 8);
1450 else if (!nasm_strnicmp(p, "align=", 6)) {
1451 seg->align = readnum(p + 6, &rn_error);
1452 if (rn_error) {
1453 seg->align = 1;
1454 nasm_error(ERR_NONFATAL, "segment alignment should be"
1455 " numeric");
1457 switch ((int)seg->align) {
1458 case 1: /* BYTE */
1459 case 2: /* WORD */
1460 case 4: /* DWORD */
1461 case 16: /* PARA */
1462 case 256: /* PAGE */
1463 case 4096: /* PharLap extension */
1464 break;
1465 case 8:
1466 nasm_error(ERR_WARNING,
1467 "OBJ format does not support alignment"
1468 " of 8: rounding up to 16");
1469 seg->align = 16;
1470 break;
1471 case 32:
1472 case 64:
1473 case 128:
1474 nasm_error(ERR_WARNING,
1475 "OBJ format does not support alignment"
1476 " of %d: rounding up to 256", seg->align);
1477 seg->align = 256;
1478 break;
1479 case 512:
1480 case 1024:
1481 case 2048:
1482 nasm_error(ERR_WARNING,
1483 "OBJ format does not support alignment"
1484 " of %d: rounding up to 4096", seg->align);
1485 seg->align = 4096;
1486 break;
1487 default:
1488 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1489 seg->align);
1490 seg->align = 1;
1491 break;
1493 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1494 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1495 if (rn_error)
1496 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1497 " attribute should be numeric");
1501 /* We need to know whenever we have at least one 32-bit segment */
1502 obj_use32 |= seg->use32;
1504 obj_seg_needs_update = seg;
1505 if (seg->align >= SEG_ABS)
1506 define_label(name, NO_SEG, seg->align - SEG_ABS,
1507 NULL, false, false);
1508 else
1509 define_label(name, seg->index + 1, 0L,
1510 NULL, false, false);
1511 obj_seg_needs_update = NULL;
1514 * See if this segment is defined in any groups.
1516 for (grp = grphead; grp; grp = grp->next) {
1517 for (i = grp->nindices; i < grp->nentries; i++) {
1518 if (!strcmp(grp->segs[i].name, seg->name)) {
1519 nasm_free(grp->segs[i].name);
1520 grp->segs[i] = grp->segs[grp->nindices];
1521 grp->segs[grp->nindices++].index = seg->obj_index;
1522 if (seg->grp)
1523 nasm_error(ERR_WARNING,
1524 "segment `%s' is already part of"
1525 " a group: first one takes precedence",
1526 seg->name);
1527 else
1528 seg->grp = grp;
1534 * Walk through the list of externals with unresolved
1535 * default-WRT clauses, and resolve any that point at this
1536 * segment.
1538 extp = &dws;
1539 while (*extp) {
1540 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1541 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1542 nasm_free((*extp)->defwrt_ptr.string);
1543 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1544 (*extp)->defwrt_ptr.seg = seg;
1545 *extp = (*extp)->next_dws;
1546 } else
1547 extp = &(*extp)->next_dws;
1550 if (seg->use32)
1551 *bits = 32;
1552 else
1553 *bits = 16;
1554 current_seg = seg;
1555 return seg->index;
1559 static int obj_directive(enum directives directive, char *value, int pass)
1561 switch (directive) {
1562 case D_GROUP:
1564 char *p, *q, *v;
1565 if (pass == 1) {
1566 struct Group *grp;
1567 struct Segment *seg;
1568 struct External **extp;
1569 int obj_idx;
1571 q = value;
1572 while (*q == '.')
1573 q++; /* hack, but a documented one */
1574 v = q;
1575 while (*q && !nasm_isspace(*q))
1576 q++;
1577 if (nasm_isspace(*q)) {
1578 *q++ = '\0';
1579 while (*q && nasm_isspace(*q))
1580 q++;
1583 * Here we used to sanity-check the group directive to
1584 * ensure nobody tried to declare a group containing no
1585 * segments. However, OS/2 does this as standard
1586 * practice, so the sanity check has been removed.
1588 * if (!*q) {
1589 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1590 * return 1;
1594 obj_idx = 1;
1595 for (grp = grphead; grp; grp = grp->next) {
1596 obj_idx++;
1597 if (!strcmp(grp->name, v)) {
1598 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1599 return 1;
1603 *grptail = grp = nasm_malloc(sizeof(*grp));
1604 grp->next = NULL;
1605 grptail = &grp->next;
1606 grp->index = seg_alloc();
1607 grp->obj_index = obj_idx;
1608 grp->nindices = grp->nentries = 0;
1609 grp->name = NULL;
1611 obj_grp_needs_update = grp;
1612 define_label(v, grp->index + 1, 0L, NULL, false, false);
1613 obj_grp_needs_update = NULL;
1615 while (*q) {
1616 p = q;
1617 while (*q && !nasm_isspace(*q))
1618 q++;
1619 if (nasm_isspace(*q)) {
1620 *q++ = '\0';
1621 while (*q && nasm_isspace(*q))
1622 q++;
1625 * Now p contains a segment name. Find it.
1627 for (seg = seghead; seg; seg = seg->next)
1628 if (!strcmp(seg->name, p))
1629 break;
1630 if (seg) {
1632 * We have a segment index. Shift a name entry
1633 * to the end of the array to make room.
1635 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1636 grp->segs[grp->nindices++].index = seg->obj_index;
1637 if (seg->grp)
1638 nasm_error(ERR_WARNING,
1639 "segment `%s' is already part of"
1640 " a group: first one takes precedence",
1641 seg->name);
1642 else
1643 seg->grp = grp;
1644 } else {
1646 * We have an as-yet undefined segment.
1647 * Remember its name, for later.
1649 grp->segs[grp->nentries++].name = nasm_strdup(p);
1654 * Walk through the list of externals with unresolved
1655 * default-WRT clauses, and resolve any that point at
1656 * this group.
1658 extp = &dws;
1659 while (*extp) {
1660 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1661 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1662 nasm_free((*extp)->defwrt_ptr.string);
1663 (*extp)->defwrt_type = DEFWRT_GROUP;
1664 (*extp)->defwrt_ptr.grp = grp;
1665 *extp = (*extp)->next_dws;
1666 } else
1667 extp = &(*extp)->next_dws;
1670 return 1;
1672 case D_UPPERCASE:
1673 obj_uppercase = true;
1674 return 1;
1676 case D_IMPORT:
1678 char *q, *extname, *libname, *impname;
1680 if (pass == 2)
1681 return 1; /* ignore in pass two */
1682 extname = q = value;
1683 while (*q && !nasm_isspace(*q))
1684 q++;
1685 if (nasm_isspace(*q)) {
1686 *q++ = '\0';
1687 while (*q && nasm_isspace(*q))
1688 q++;
1691 libname = q;
1692 while (*q && !nasm_isspace(*q))
1693 q++;
1694 if (nasm_isspace(*q)) {
1695 *q++ = '\0';
1696 while (*q && nasm_isspace(*q))
1697 q++;
1700 impname = q;
1702 if (!*extname || !*libname)
1703 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1704 " and library name");
1705 else {
1706 struct ImpDef *imp;
1707 bool err = false;
1709 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1710 imptail = &imp->next;
1711 imp->next = NULL;
1712 imp->extname = nasm_strdup(extname);
1713 imp->libname = nasm_strdup(libname);
1714 imp->impindex = readnum(impname, &err);
1715 if (!*impname || err)
1716 imp->impname = nasm_strdup(impname);
1717 else
1718 imp->impname = NULL;
1721 return 1;
1723 case D_EXPORT:
1725 char *q, *extname, *intname, *v;
1726 struct ExpDef *export;
1727 int flags = 0;
1728 unsigned int ordinal = 0;
1730 if (pass == 2)
1731 return 1; /* ignore in pass two */
1732 intname = q = value;
1733 while (*q && !nasm_isspace(*q))
1734 q++;
1735 if (nasm_isspace(*q)) {
1736 *q++ = '\0';
1737 while (*q && nasm_isspace(*q))
1738 q++;
1741 extname = q;
1742 while (*q && !nasm_isspace(*q))
1743 q++;
1744 if (nasm_isspace(*q)) {
1745 *q++ = '\0';
1746 while (*q && nasm_isspace(*q))
1747 q++;
1750 if (!*intname) {
1751 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1752 return 1;
1754 if (!*extname) {
1755 extname = intname;
1756 intname = "";
1758 while (*q) {
1759 v = q;
1760 while (*q && !nasm_isspace(*q))
1761 q++;
1762 if (nasm_isspace(*q)) {
1763 *q++ = '\0';
1764 while (*q && nasm_isspace(*q))
1765 q++;
1767 if (!nasm_stricmp(v, "resident"))
1768 flags |= EXPDEF_FLAG_RESIDENT;
1769 else if (!nasm_stricmp(v, "nodata"))
1770 flags |= EXPDEF_FLAG_NODATA;
1771 else if (!nasm_strnicmp(v, "parm=", 5)) {
1772 bool err = false;
1773 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1774 if (err) {
1775 nasm_error(ERR_NONFATAL,
1776 "value `%s' for `parm' is non-numeric", v + 5);
1777 return 1;
1779 } else {
1780 bool err = false;
1781 ordinal = readnum(v, &err);
1782 if (err) {
1783 nasm_error(ERR_NONFATAL,
1784 "unrecognised export qualifier `%s'", v);
1785 return 1;
1787 flags |= EXPDEF_FLAG_ORDINAL;
1791 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1792 exptail = &export->next;
1793 export->next = NULL;
1794 export->extname = nasm_strdup(extname);
1795 export->intname = nasm_strdup(intname);
1796 export->ordinal = ordinal;
1797 export->flags = flags;
1799 return 1;
1801 default:
1802 return 0;
1806 static void obj_sectalign(int32_t seg, unsigned int value)
1808 struct Segment *s;
1810 list_for_each(s, seghead) {
1811 if (s->index == seg)
1812 break;
1816 * it should not be too big value
1817 * and applied on non-absolute sections
1819 if (!s || !is_power2(value) ||
1820 value > 4096 || s->align >= SEG_ABS)
1821 return;
1824 * FIXME: No code duplication please
1825 * consider making helper for this
1826 * mapping since section handler has
1827 * to do the same
1829 switch (value) {
1830 case 8:
1831 value = 16;
1832 break;
1833 case 32:
1834 case 64:
1835 case 128:
1836 value = 256;
1837 break;
1838 case 512:
1839 case 1024:
1840 case 2048:
1841 value = 4096;
1842 break;
1845 if (s->align < (int)value)
1846 s->align = value;
1849 static int32_t obj_segbase(int32_t segment)
1851 struct Segment *seg;
1854 * Find the segment in our list.
1856 for (seg = seghead; seg; seg = seg->next)
1857 if (seg->index == segment - 1)
1858 break;
1860 if (!seg) {
1862 * Might be an external with a default WRT.
1864 int32_t i = segment / 2;
1865 struct ExtBack *eb = ebhead;
1866 struct External *e;
1868 while (i >= EXT_BLKSIZ) {
1869 if (eb)
1870 eb = eb->next;
1871 else
1872 break;
1873 i -= EXT_BLKSIZ;
1875 if (eb) {
1876 e = eb->exts[i];
1877 if (!e) {
1878 nasm_assert(pass0 == 0);
1879 /* Not available - can happen during optimization */
1880 return NO_SEG;
1883 switch (e->defwrt_type) {
1884 case DEFWRT_NONE:
1885 return segment; /* fine */
1886 case DEFWRT_SEGMENT:
1887 return e->defwrt_ptr.seg->index + 1;
1888 case DEFWRT_GROUP:
1889 return e->defwrt_ptr.grp->index + 1;
1890 default:
1891 return NO_SEG; /* can't tell what it is */
1895 return segment; /* not one of ours - leave it alone */
1898 if (seg->align >= SEG_ABS)
1899 return seg->align; /* absolute segment */
1900 if (seg->grp)
1901 return seg->grp->index + 1; /* grouped segment */
1903 return segment; /* no special treatment */
1906 static void obj_filename(char *inname, char *outname)
1908 strcpy(obj_infile, inname);
1909 standard_extension(inname, outname, ".obj");
1912 static void obj_write_file(int debuginfo)
1914 struct Segment *seg, *entry_seg_ptr = 0;
1915 struct FileName *fn;
1916 struct LineNumber *ln;
1917 struct Group *grp;
1918 struct Public *pub, *loc;
1919 struct External *ext;
1920 struct ImpDef *imp;
1921 struct ExpDef *export;
1922 int lname_idx;
1923 ObjRecord *orp;
1926 * Write the THEADR module header.
1928 orp = obj_new();
1929 orp->type = THEADR;
1930 obj_name(orp, obj_infile);
1931 obj_emit2(orp);
1934 * Write the NASM boast comment.
1936 orp->type = COMENT;
1937 obj_rword(orp, 0); /* comment type zero */
1938 obj_name(orp, nasm_comment);
1939 obj_emit2(orp);
1941 orp->type = COMENT;
1943 * Write the IMPDEF records, if any.
1945 for (imp = imphead; imp; imp = imp->next) {
1946 obj_rword(orp, 0xA0); /* comment class A0 */
1947 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1948 if (imp->impname)
1949 obj_byte(orp, 0); /* import by name */
1950 else
1951 obj_byte(orp, 1); /* import by ordinal */
1952 obj_name(orp, imp->extname);
1953 obj_name(orp, imp->libname);
1954 if (imp->impname)
1955 obj_name(orp, imp->impname);
1956 else
1957 obj_word(orp, imp->impindex);
1958 obj_emit2(orp);
1962 * Write the EXPDEF records, if any.
1964 for (export = exphead; export; export = export->next) {
1965 obj_rword(orp, 0xA0); /* comment class A0 */
1966 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1967 obj_byte(orp, export->flags);
1968 obj_name(orp, export->extname);
1969 obj_name(orp, export->intname);
1970 if (export->flags & EXPDEF_FLAG_ORDINAL)
1971 obj_word(orp, export->ordinal);
1972 obj_emit2(orp);
1975 /* we're using extended OMF if we put in debug info */
1976 if (debuginfo) {
1977 orp->type = COMENT;
1978 obj_byte(orp, 0x40);
1979 obj_byte(orp, dEXTENDED);
1980 obj_emit2(orp);
1984 * Write the first LNAMES record, containing LNAME one, which
1985 * is null. Also initialize the LNAME counter.
1987 orp->type = LNAMES;
1988 obj_byte(orp, 0);
1989 lname_idx = 1;
1991 * Write some LNAMES for the segment names
1993 for (seg = seghead; seg; seg = seg->next) {
1994 orp = obj_name(orp, seg->name);
1995 if (seg->segclass)
1996 orp = obj_name(orp, seg->segclass);
1997 if (seg->overlay)
1998 orp = obj_name(orp, seg->overlay);
1999 obj_commit(orp);
2002 * Write some LNAMES for the group names
2004 for (grp = grphead; grp; grp = grp->next) {
2005 orp = obj_name(orp, grp->name);
2006 obj_commit(orp);
2008 obj_emit(orp);
2011 * Write the SEGDEF records.
2013 orp->type = SEGDEF;
2014 for (seg = seghead; seg; seg = seg->next) {
2015 int acbp;
2016 uint32_t seglen = seg->currentpos;
2018 acbp = (seg->combine << 2); /* C field */
2020 if (seg->use32)
2021 acbp |= 0x01; /* P bit is Use32 flag */
2022 else if (seglen == 0x10000L) {
2023 seglen = 0; /* This special case may be needed for old linkers */
2024 acbp |= 0x02; /* B bit */
2027 /* A field */
2028 if (seg->align >= SEG_ABS)
2029 /* acbp |= 0x00 */ ;
2030 else if (seg->align >= 4096) {
2031 if (seg->align > 4096)
2032 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2033 " than OBJ format supports", seg->name);
2034 acbp |= 0xC0; /* PharLap extension */
2035 } else if (seg->align >= 256) {
2036 acbp |= 0x80;
2037 } else if (seg->align >= 16) {
2038 acbp |= 0x60;
2039 } else if (seg->align >= 4) {
2040 acbp |= 0xA0;
2041 } else if (seg->align >= 2) {
2042 acbp |= 0x40;
2043 } else
2044 acbp |= 0x20;
2046 obj_byte(orp, acbp);
2047 if (seg->align & SEG_ABS) {
2048 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2049 obj_byte(orp, 0); /* Offset */
2051 obj_x(orp, seglen);
2052 obj_index(orp, ++lname_idx);
2053 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2054 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2055 obj_emit2(orp);
2059 * Write the GRPDEF records.
2061 orp->type = GRPDEF;
2062 for (grp = grphead; grp; grp = grp->next) {
2063 int i;
2065 if (grp->nindices != grp->nentries) {
2066 for (i = grp->nindices; i < grp->nentries; i++) {
2067 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2068 " `%s'", grp->name, grp->segs[i].name);
2069 nasm_free(grp->segs[i].name);
2070 grp->segs[i].name = NULL;
2073 obj_index(orp, ++lname_idx);
2074 for (i = 0; i < grp->nindices; i++) {
2075 obj_byte(orp, 0xFF);
2076 obj_index(orp, grp->segs[i].index);
2078 obj_emit2(orp);
2082 * Write the PUBDEF records: first the ones in the segments,
2083 * then the far-absolutes.
2085 orp->type = PUBDEF;
2086 orp->ori = ori_pubdef;
2087 for (seg = seghead; seg; seg = seg->next) {
2088 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2089 orp->parm[1] = seg->obj_index;
2090 for (pub = seg->pubhead; pub; pub = pub->next) {
2091 orp = obj_name(orp, pub->name);
2092 orp = obj_x(orp, pub->offset);
2093 orp = obj_byte(orp, 0); /* type index */
2094 obj_commit(orp);
2096 obj_emit(orp);
2098 orp->parm[0] = 0;
2099 orp->parm[1] = 0;
2100 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2101 if (orp->parm[2] != (uint32_t)pub->segment) {
2102 obj_emit(orp);
2103 orp->parm[2] = pub->segment;
2105 orp = obj_name(orp, pub->name);
2106 orp = obj_x(orp, pub->offset);
2107 orp = obj_byte(orp, 0); /* type index */
2108 obj_commit(orp);
2110 obj_emit(orp);
2113 * Write the EXTDEF and COMDEF records, in order.
2115 orp->ori = ori_null;
2116 for (ext = exthead; ext; ext = ext->next) {
2117 if (ext->commonsize == 0) {
2118 if (orp->type != EXTDEF) {
2119 obj_emit(orp);
2120 orp->type = EXTDEF;
2122 orp = obj_name(orp, ext->name);
2123 orp = obj_index(orp, 0);
2124 } else {
2125 if (orp->type != COMDEF) {
2126 obj_emit(orp);
2127 orp->type = COMDEF;
2129 orp = obj_name(orp, ext->name);
2130 orp = obj_index(orp, 0);
2131 if (ext->commonelem) {
2132 orp = obj_byte(orp, 0x61); /* far communal */
2133 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2134 orp = obj_value(orp, ext->commonelem);
2135 } else {
2136 orp = obj_byte(orp, 0x62); /* near communal */
2137 orp = obj_value(orp, ext->commonsize);
2140 obj_commit(orp);
2142 obj_emit(orp);
2145 * Write a COMENT record stating that the linker's first pass
2146 * may stop processing at this point. Exception is if our
2147 * MODEND record specifies a start point, in which case,
2148 * according to some variants of the documentation, this COMENT
2149 * should be omitted. So we'll omit it just in case.
2150 * But, TASM puts it in all the time so if we are using
2151 * TASM debug stuff we are putting it in
2153 if (debuginfo || obj_entry_seg == NO_SEG) {
2154 orp->type = COMENT;
2155 obj_byte(orp, 0x40);
2156 obj_byte(orp, dLINKPASS);
2157 obj_byte(orp, 1);
2158 obj_emit2(orp);
2162 * 1) put out the compiler type
2163 * 2) Put out the type info. The only type we are using is near label #19
2165 if (debuginfo) {
2166 int i;
2167 struct Array *arrtmp = arrhead;
2168 orp->type = COMENT;
2169 obj_byte(orp, 0x40);
2170 obj_byte(orp, dCOMPDEF);
2171 obj_byte(orp, 4);
2172 obj_byte(orp, 0);
2173 obj_emit2(orp);
2175 obj_byte(orp, 0x40);
2176 obj_byte(orp, dTYPEDEF);
2177 obj_word(orp, 0x18); /* type # for linking */
2178 obj_word(orp, 6); /* size of type */
2179 obj_byte(orp, 0x2a); /* absolute type for debugging */
2180 obj_emit2(orp);
2181 obj_byte(orp, 0x40);
2182 obj_byte(orp, dTYPEDEF);
2183 obj_word(orp, 0x19); /* type # for linking */
2184 obj_word(orp, 0); /* size of type */
2185 obj_byte(orp, 0x24); /* absolute type for debugging */
2186 obj_byte(orp, 0); /* near/far specifier */
2187 obj_emit2(orp);
2188 obj_byte(orp, 0x40);
2189 obj_byte(orp, dTYPEDEF);
2190 obj_word(orp, 0x1A); /* type # for linking */
2191 obj_word(orp, 0); /* size of type */
2192 obj_byte(orp, 0x24); /* absolute type for debugging */
2193 obj_byte(orp, 1); /* near/far specifier */
2194 obj_emit2(orp);
2195 obj_byte(orp, 0x40);
2196 obj_byte(orp, dTYPEDEF);
2197 obj_word(orp, 0x1b); /* type # for linking */
2198 obj_word(orp, 0); /* size of type */
2199 obj_byte(orp, 0x23); /* absolute type for debugging */
2200 obj_byte(orp, 0);
2201 obj_byte(orp, 0);
2202 obj_byte(orp, 0);
2203 obj_emit2(orp);
2204 obj_byte(orp, 0x40);
2205 obj_byte(orp, dTYPEDEF);
2206 obj_word(orp, 0x1c); /* type # for linking */
2207 obj_word(orp, 0); /* size of type */
2208 obj_byte(orp, 0x23); /* absolute type for debugging */
2209 obj_byte(orp, 0);
2210 obj_byte(orp, 4);
2211 obj_byte(orp, 0);
2212 obj_emit2(orp);
2213 obj_byte(orp, 0x40);
2214 obj_byte(orp, dTYPEDEF);
2215 obj_word(orp, 0x1d); /* type # for linking */
2216 obj_word(orp, 0); /* size of type */
2217 obj_byte(orp, 0x23); /* absolute type for debugging */
2218 obj_byte(orp, 0);
2219 obj_byte(orp, 1);
2220 obj_byte(orp, 0);
2221 obj_emit2(orp);
2222 obj_byte(orp, 0x40);
2223 obj_byte(orp, dTYPEDEF);
2224 obj_word(orp, 0x1e); /* type # for linking */
2225 obj_word(orp, 0); /* size of type */
2226 obj_byte(orp, 0x23); /* absolute type for debugging */
2227 obj_byte(orp, 0);
2228 obj_byte(orp, 5);
2229 obj_byte(orp, 0);
2230 obj_emit2(orp);
2232 /* put out the array types */
2233 for (i = ARRAYBOT; i < arrindex; i++) {
2234 obj_byte(orp, 0x40);
2235 obj_byte(orp, dTYPEDEF);
2236 obj_word(orp, i); /* type # for linking */
2237 obj_word(orp, arrtmp->size); /* size of type */
2238 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2239 obj_byte(orp, arrtmp->basetype); /* base type */
2240 obj_emit2(orp);
2241 arrtmp = arrtmp->next;
2245 * write out line number info with a LINNUM record
2246 * switch records when we switch segments, and output the
2247 * file in a pseudo-TASM fashion. The record switch is naive; that
2248 * is that one file may have many records for the same segment
2249 * if there are lots of segment switches
2251 if (fnhead && debuginfo) {
2252 seg = fnhead->lnhead->segment;
2254 for (fn = fnhead; fn; fn = fn->next) {
2255 /* write out current file name */
2256 orp->type = COMENT;
2257 orp->ori = ori_null;
2258 obj_byte(orp, 0x40);
2259 obj_byte(orp, dFILNAME);
2260 obj_byte(orp, 0);
2261 obj_name(orp, fn->name);
2262 obj_dword(orp, 0);
2263 obj_emit2(orp);
2265 /* write out line numbers this file */
2267 orp->type = LINNUM;
2268 orp->ori = ori_linnum;
2269 for (ln = fn->lnhead; ln; ln = ln->next) {
2270 if (seg != ln->segment) {
2271 /* if we get here have to flush the buffer and start
2272 * a new record for a new segment
2274 seg = ln->segment;
2275 obj_emit(orp);
2277 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2278 orp->parm[1] = seg->obj_index;
2279 orp = obj_word(orp, ln->lineno);
2280 orp = obj_x(orp, ln->offset);
2281 obj_commit(orp);
2283 obj_emit(orp);
2287 * we are going to locate the entry point segment now
2288 * rather than wait until the MODEND record, because,
2289 * then we can output a special symbol to tell where the
2290 * entry point is.
2293 if (obj_entry_seg != NO_SEG) {
2294 for (seg = seghead; seg; seg = seg->next) {
2295 if (seg->index == obj_entry_seg) {
2296 entry_seg_ptr = seg;
2297 break;
2300 if (!seg)
2301 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2305 * get ready to put out symbol records
2307 orp->type = COMENT;
2308 orp->ori = ori_local;
2311 * put out a symbol for the entry point
2312 * no dots in this symbol, because, borland does
2313 * not (officially) support dots in label names
2314 * and I don't know what various versions of TLINK will do
2316 if (debuginfo && obj_entry_seg != NO_SEG) {
2317 orp = obj_name(orp, "start_of_program");
2318 orp = obj_word(orp, 0x19); /* type: near label */
2319 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2320 orp = obj_index(orp, seg->obj_index);
2321 orp = obj_x(orp, obj_entry_ofs);
2322 obj_commit(orp);
2326 * put out the local labels
2328 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2329 /* labels this seg */
2330 for (loc = seg->lochead; loc; loc = loc->next) {
2331 orp = obj_name(orp, loc->name);
2332 orp = obj_word(orp, loc->type);
2333 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2334 orp = obj_index(orp, seg->obj_index);
2335 orp = obj_x(orp, loc->offset);
2336 obj_commit(orp);
2339 if (orp->used)
2340 obj_emit(orp);
2343 * Write the LEDATA/FIXUPP pairs.
2345 for (seg = seghead; seg; seg = seg->next) {
2346 obj_emit(seg->orp);
2347 nasm_free(seg->orp);
2351 * Write the MODEND module end marker.
2353 orp->type = obj_use32 ? MODE32 : MODEND;
2354 orp->ori = ori_null;
2355 if (entry_seg_ptr) {
2356 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2357 obj_byte(orp, 0xC1);
2358 seg = entry_seg_ptr;
2359 if (seg->grp) {
2360 obj_byte(orp, 0x10);
2361 obj_index(orp, seg->grp->obj_index);
2362 } else {
2364 * the below changed to prevent TLINK crashing.
2365 * Previous more efficient version read:
2367 * obj_byte (orp, 0x50);
2369 obj_byte(orp, 0x00);
2370 obj_index(orp, seg->obj_index);
2372 obj_index(orp, seg->obj_index);
2373 obj_x(orp, obj_entry_ofs);
2374 } else
2375 obj_byte(orp, 0);
2376 obj_emit2(orp);
2377 nasm_free(orp);
2380 static void obj_fwrite(ObjRecord * orp)
2382 unsigned int cksum, len;
2383 uint8_t *ptr;
2385 cksum = orp->type;
2386 if (orp->x_size == 32)
2387 cksum |= 1;
2388 fputc(cksum, ofile);
2389 len = orp->committed + 1;
2390 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2391 fwriteint16_t(len, ofile);
2392 fwrite(orp->buf, 1, len - 1, ofile);
2393 for (ptr = orp->buf; --len; ptr++)
2394 cksum += *ptr;
2395 fputc((-cksum) & 0xFF, ofile);
2398 extern macros_t obj_stdmac[];
2400 void dbgbi_init(void)
2402 fnhead = NULL;
2403 fntail = &fnhead;
2404 arrindex = ARRAYBOT;
2405 arrhead = NULL;
2406 arrtail = &arrhead;
2408 static void dbgbi_cleanup(void)
2410 struct Segment *segtmp;
2411 while (fnhead) {
2412 struct FileName *fntemp = fnhead;
2413 while (fnhead->lnhead) {
2414 struct LineNumber *lntemp = fnhead->lnhead;
2415 fnhead->lnhead = lntemp->next;
2416 nasm_free(lntemp);
2418 fnhead = fnhead->next;
2419 nasm_free(fntemp->name);
2420 nasm_free(fntemp);
2422 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2423 while (segtmp->lochead) {
2424 struct Public *loctmp = segtmp->lochead;
2425 segtmp->lochead = loctmp->next;
2426 nasm_free(loctmp->name);
2427 nasm_free(loctmp);
2430 while (arrhead) {
2431 struct Array *arrtmp = arrhead;
2432 arrhead = arrhead->next;
2433 nasm_free(arrtmp);
2437 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2439 struct FileName *fn;
2440 struct LineNumber *ln;
2441 struct Segment *seg;
2443 if (segto == NO_SEG)
2444 return;
2447 * If `any_segs' is still false, we must define a default
2448 * segment.
2450 if (!any_segs) {
2451 int tempint; /* ignored */
2452 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2453 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
2457 * Find the segment we are targetting.
2459 for (seg = seghead; seg; seg = seg->next)
2460 if (seg->index == segto)
2461 break;
2462 if (!seg)
2463 nasm_error(ERR_PANIC, "lineno directed to nonexistent segment?");
2465 /* for (fn = fnhead; fn; fn = fnhead->next) */
2466 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2467 if (!nasm_stricmp(lnfname, fn->name))
2468 break;
2469 if (!fn) {
2470 fn = nasm_malloc(sizeof(*fn));
2471 fn->name = nasm_malloc(strlen(lnfname) + 1);
2472 strcpy(fn->name, lnfname);
2473 fn->lnhead = NULL;
2474 fn->lntail = &fn->lnhead;
2475 fn->next = NULL;
2476 *fntail = fn;
2477 fntail = &fn->next;
2479 ln = nasm_malloc(sizeof(*ln));
2480 ln->segment = seg;
2481 ln->offset = seg->currentpos;
2482 ln->lineno = lineno;
2483 ln->next = NULL;
2484 *fn->lntail = ln;
2485 fn->lntail = &ln->next;
2488 static void dbgbi_deflabel(char *name, int32_t segment,
2489 int64_t offset, int is_global, char *special)
2491 struct Segment *seg;
2493 (void)special;
2496 * If it's a special-retry from pass two, discard it.
2498 if (is_global == 3)
2499 return;
2502 * First check for the double-period, signifying something
2503 * unusual.
2505 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2506 return;
2510 * Case (i):
2512 if (obj_seg_needs_update) {
2513 return;
2514 } else if (obj_grp_needs_update) {
2515 return;
2517 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2518 return;
2520 if (segment >= SEG_ABS || segment == NO_SEG) {
2521 return;
2525 * If `any_segs' is still false, we might need to define a
2526 * default segment, if they're trying to declare a label in
2527 * `first_seg'. But the label should exist due to a prior
2528 * call to obj_deflabel so we can skip that.
2531 for (seg = seghead; seg; seg = seg->next)
2532 if (seg->index == segment) {
2533 struct Public *loc = nasm_malloc(sizeof(*loc));
2535 * Case (ii). Maybe MODPUB someday?
2537 last_defined = *seg->loctail = loc;
2538 seg->loctail = &loc->next;
2539 loc->next = NULL;
2540 loc->name = nasm_strdup(name);
2541 loc->offset = offset;
2544 static void dbgbi_typevalue(int32_t type)
2546 int vsize;
2547 int elem = TYM_ELEMENTS(type);
2548 type = TYM_TYPE(type);
2550 if (!last_defined)
2551 return;
2553 switch (type) {
2554 case TY_BYTE:
2555 last_defined->type = 8; /* uint8_t */
2556 vsize = 1;
2557 break;
2558 case TY_WORD:
2559 last_defined->type = 10; /* unsigned word */
2560 vsize = 2;
2561 break;
2562 case TY_DWORD:
2563 last_defined->type = 12; /* unsigned dword */
2564 vsize = 4;
2565 break;
2566 case TY_FLOAT:
2567 last_defined->type = 14; /* float */
2568 vsize = 4;
2569 break;
2570 case TY_QWORD:
2571 last_defined->type = 15; /* qword */
2572 vsize = 8;
2573 break;
2574 case TY_TBYTE:
2575 last_defined->type = 16; /* TBYTE */
2576 vsize = 10;
2577 break;
2578 default:
2579 last_defined->type = 0x19; /*label */
2580 vsize = 0;
2581 break;
2584 if (elem > 1) {
2585 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2586 int vtype = last_defined->type;
2587 arrtmp->size = vsize * elem;
2588 arrtmp->basetype = vtype;
2589 arrtmp->next = NULL;
2590 last_defined->type = arrindex++;
2591 *arrtail = arrtmp;
2592 arrtail = &(arrtmp->next);
2594 last_defined = NULL;
2596 static void dbgbi_output(int output_type, void *param)
2598 (void)output_type;
2599 (void)param;
2601 static struct dfmt borland_debug_form = {
2602 "Borland Debug Records",
2603 "borland",
2604 dbgbi_init,
2605 dbgbi_linnum,
2606 dbgbi_deflabel,
2607 null_debug_directive,
2608 dbgbi_typevalue,
2609 dbgbi_output,
2610 dbgbi_cleanup,
2613 static struct dfmt *borland_debug_arr[3] = {
2614 &borland_debug_form,
2615 &null_debug_form,
2616 NULL
2619 struct ofmt of_obj = {
2620 "MS-DOS 16-bit/32-bit OMF object files",
2621 "obj",
2623 borland_debug_arr,
2624 &borland_debug_form,
2625 obj_stdmac,
2626 obj_init,
2627 obj_set_info,
2628 obj_out,
2629 obj_deflabel,
2630 obj_segment,
2631 obj_sectalign,
2632 obj_segbase,
2633 obj_directive,
2634 obj_filename,
2635 obj_cleanup
2637 #endif /* OF_OBJ */