backend: move wrapper for legacy output functions to a library routine
[nasm.git] / output / outobj.c
blob6ae00f3b8dcd5a945f7e5fae9869940ed40d7216
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2016 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 <limits.h>
47 #include "nasm.h"
48 #include "nasmlib.h"
49 #include "stdscan.h"
50 #include "eval.h"
51 #include "ver.h"
53 #include "outform.h"
54 #include "outlib.h"
56 #ifdef OF_OBJ
59 * outobj.c is divided into two sections. The first section is low level
60 * routines for creating obj records; It has nearly zero NASM specific
61 * code. The second section is high level routines for processing calls and
62 * data structures from the rest of NASM into obj format.
64 * It should be easy (though not zero work) to lift the first section out for
65 * use as an obj file writer for some other assembler or compiler.
69 * These routines are built around the ObjRecord data struture. An ObjRecord
70 * holds an object file record that may be under construction or complete.
72 * A major function of these routines is to support continuation of an obj
73 * record into the next record when the maximum record size is exceeded. The
74 * high level code does not need to worry about where the record breaks occur.
75 * It does need to do some minor extra steps to make the automatic continuation
76 * work. Those steps may be skipped for records where the high level knows no
77 * continuation could be required.
79 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
80 * is cleared by obj_clear.
82 * 2) The caller should fill in .type.
84 * 3) If the record is continuable and there is processing that must be done at
85 * the start of each record then the caller should fill in .ori with the
86 * address of the record initializer routine.
88 * 4) If the record is continuable and it should be saved (rather than emitted
89 * immediately) as each record is done, the caller should set .up to be a
90 * pointer to a location in which the caller keeps the master pointer to the
91 * ObjRecord. When the record is continued, the obj_bump routine will then
92 * allocate a new ObjRecord structure and update the master pointer.
94 * 5) If the .ori field was used then the caller should fill in the .parm with
95 * any data required by the initializer.
97 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
98 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
99 * data required for this record.
101 * 7) If the record is continuable, the caller should call obj_commit at each
102 * point where breaking the record is permitted.
104 * 8) To write out the record, the caller should call obj_emit2. If the
105 * caller has called obj_commit for all data written then he can get slightly
106 * faster code by calling obj_emit instead of obj_emit2.
108 * Most of these routines return an ObjRecord pointer. This will be the input
109 * pointer most of the time and will be the new location if the ObjRecord
110 * moved as a result of the call. The caller may ignore the return value in
111 * three cases: It is a "Never Reallocates" routine; or The caller knows
112 * continuation is not possible; or The caller uses the master pointer for the
113 * next operation.
116 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
117 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
119 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
120 #define FIX_16_OFFSET 0x8400
121 #define FIX_16_SELECTOR 0x8800
122 #define FIX_32_POINTER 0x8C00
123 #define FIX_08_HIGH 0x9000
124 #define FIX_32_OFFSET 0xA400
125 #define FIX_48_POINTER 0xAC00
127 enum RecordID { /* record ID codes */
129 THEADR = 0x80, /* module header */
130 COMENT = 0x88, /* comment record */
132 LINNUM = 0x94, /* line number record */
133 LNAMES = 0x96, /* list of names */
135 SEGDEF = 0x98, /* segment definition */
136 GRPDEF = 0x9A, /* group definition */
137 EXTDEF = 0x8C, /* external definition */
138 PUBDEF = 0x90, /* public definition */
139 COMDEF = 0xB0, /* common definition */
141 LEDATA = 0xA0, /* logical enumerated data */
142 FIXUPP = 0x9C, /* fixups (relocations) */
143 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
145 MODEND = 0x8A, /* module end */
146 MODE32 = 0x8B /* module end for 32-bit objects */
149 enum ComentID { /* ID codes for comment records */
151 dEXTENDED = 0xA1, /* tells that we are using translator-specific extensions */
152 dLINKPASS = 0xA2, /* link pass 2 marker */
153 dTYPEDEF = 0xE3, /* define a type */
154 dSYM = 0xE6, /* symbol debug record */
155 dFILNAME = 0xE8, /* file name record */
156 dCOMPDEF = 0xEA /* compiler type info */
159 typedef struct ObjRecord ObjRecord;
160 typedef void ORI(ObjRecord * orp);
162 struct ObjRecord {
163 ORI *ori; /* Initialization routine */
164 int used; /* Current data size */
165 int committed; /* Data size at last boundary */
166 int x_size; /* (see obj_x) */
167 unsigned int type; /* Record type */
168 ObjRecord *child; /* Associated record below this one */
169 ObjRecord **up; /* Master pointer to this ObjRecord */
170 ObjRecord *back; /* Previous part of this record */
171 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
172 uint8_t buf[RECORD_MAX + 3];
175 static void obj_fwrite(ObjRecord * orp);
176 static void ori_ledata(ObjRecord * orp);
177 static void ori_pubdef(ObjRecord * orp);
178 static void ori_null(ObjRecord * orp);
179 static ObjRecord *obj_commit(ObjRecord * orp);
181 static bool obj_uppercase; /* Flag: all names in uppercase */
182 static bool obj_use32; /* Flag: at least one segment is 32-bit */
185 * Clear an ObjRecord structure. (Never reallocates).
186 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
188 static ObjRecord *obj_clear(ObjRecord * orp)
190 orp->used = 0;
191 orp->committed = 0;
192 orp->x_size = 0;
193 orp->child = NULL;
194 orp->up = NULL;
195 orp->back = NULL;
196 return (orp);
200 * Emit an ObjRecord structure. (Never reallocates).
201 * The record is written out preceeded (recursively) by its previous part (if
202 * any) and followed (recursively) by its child (if any).
203 * The previous part and the child are freed. The main ObjRecord is cleared,
204 * not freed.
206 static ObjRecord *obj_emit(ObjRecord * orp)
208 if (orp->back) {
209 obj_emit(orp->back);
210 nasm_free(orp->back);
213 if (orp->committed)
214 obj_fwrite(orp);
216 if (orp->child) {
217 obj_emit(orp->child);
218 nasm_free(orp->child);
221 return (obj_clear(orp));
225 * Commit and Emit a record. (Never reallocates).
227 static ObjRecord *obj_emit2(ObjRecord * orp)
229 obj_commit(orp);
230 return (obj_emit(orp));
234 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
236 static ObjRecord *obj_new(void)
238 ObjRecord *orp;
240 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
241 orp->ori = ori_null;
242 return (orp);
246 * Advance to the next record because the existing one is full or its x_size
247 * is incompatible.
248 * Any uncommited data is moved into the next record.
250 static ObjRecord *obj_bump(ObjRecord * orp)
252 ObjRecord *nxt;
253 int used = orp->used;
254 int committed = orp->committed;
256 if (orp->up) {
257 *orp->up = nxt = obj_new();
258 nxt->ori = orp->ori;
259 nxt->type = orp->type;
260 nxt->up = orp->up;
261 nxt->back = orp;
262 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
263 } else
264 nxt = obj_emit(orp);
266 used -= committed;
267 if (used) {
268 nxt->committed = 1;
269 nxt->ori(nxt);
270 nxt->committed = nxt->used;
271 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
272 nxt->used = nxt->committed + used;
275 return (nxt);
279 * Advance to the next record if necessary to allow the next field to fit.
281 static ObjRecord *obj_check(ObjRecord * orp, int size)
283 if (orp->used + size > RECORD_MAX)
284 orp = obj_bump(orp);
286 if (!orp->committed) {
287 orp->committed = 1;
288 orp->ori(orp);
289 orp->committed = orp->used;
292 return (orp);
296 * All data written so far is commited to the current record (won't be moved to
297 * the next record in case of continuation).
299 static ObjRecord *obj_commit(ObjRecord * orp)
301 orp->committed = orp->used;
302 return (orp);
306 * Write a byte
308 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
310 orp = obj_check(orp, 1);
311 orp->buf[orp->used] = val;
312 orp->used++;
313 return (orp);
317 * Write a word
319 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
321 orp = obj_check(orp, 2);
322 orp->buf[orp->used] = val;
323 orp->buf[orp->used + 1] = val >> 8;
324 orp->used += 2;
325 return (orp);
329 * Write a reversed word
331 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
333 orp = obj_check(orp, 2);
334 orp->buf[orp->used] = val >> 8;
335 orp->buf[orp->used + 1] = val;
336 orp->used += 2;
337 return (orp);
341 * Write a dword
343 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
345 orp = obj_check(orp, 4);
346 orp->buf[orp->used] = val;
347 orp->buf[orp->used + 1] = val >> 8;
348 orp->buf[orp->used + 2] = val >> 16;
349 orp->buf[orp->used + 3] = val >> 24;
350 orp->used += 4;
351 return (orp);
355 * All fields of "size x" in one obj record must be the same size (either 16
356 * bits or 32 bits). There is a one bit flag in each record which specifies
357 * which.
358 * This routine is used to force the current record to have the desired
359 * x_size. x_size is normally automatic (using obj_x), so that this
360 * routine should be used outside obj_x, only to provide compatibility with
361 * linkers that have bugs in their processing of the size bit.
364 static ObjRecord *obj_force(ObjRecord * orp, int x)
366 if (orp->x_size == (x ^ 48))
367 orp = obj_bump(orp);
368 orp->x_size = x;
369 return (orp);
373 * This routine writes a field of size x. The caller does not need to worry at
374 * all about whether 16-bits or 32-bits are required.
376 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
378 if (orp->type & 1)
379 orp->x_size = 32;
380 if (val > 0xFFFF)
381 orp = obj_force(orp, 32);
382 if (orp->x_size == 32) {
383 ObjRecord *nxt = obj_dword(orp, val);
384 nxt->x_size = 32; /* x_size is cleared when a record overflows */
385 return nxt;
387 orp->x_size = 16;
388 return (obj_word(orp, val));
392 * Writes an index
394 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
396 if (val < 128)
397 return (obj_byte(orp, val));
398 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
402 * Writes a variable length value
404 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
406 if (val <= 128)
407 return (obj_byte(orp, val));
408 if (val <= 0xFFFF) {
409 orp = obj_byte(orp, 129);
410 return (obj_word(orp, val));
412 if (val <= 0xFFFFFF)
413 return (obj_dword(orp, (val << 8) + 132));
414 orp = obj_byte(orp, 136);
415 return (obj_dword(orp, val));
419 * Writes a counted string
421 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
423 int len = strlen(name);
424 uint8_t *ptr;
426 orp = obj_check(orp, len + 1);
427 ptr = orp->buf + orp->used;
428 *ptr++ = len;
429 orp->used += len + 1;
430 if (obj_uppercase)
431 while (--len >= 0) {
432 *ptr++ = toupper(*name);
433 name++;
434 } else
435 memcpy(ptr, name, len);
436 return (orp);
440 * Initializer for an LEDATA record.
441 * parm[0] = offset
442 * parm[1] = segment index
443 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
444 * represent the offset that would be required if the record were split at the
445 * last commit point.
446 * parm[2] is a copy of parm[0] as it was when the current record was initted.
448 static void ori_ledata(ObjRecord * orp)
450 obj_index(orp, orp->parm[1]);
451 orp->parm[2] = orp->parm[0];
452 obj_x(orp, orp->parm[0]);
456 * Initializer for a PUBDEF record.
457 * parm[0] = group index
458 * parm[1] = segment index
459 * parm[2] = frame (only used when both indexes are zero)
461 static void ori_pubdef(ObjRecord * orp)
463 obj_index(orp, orp->parm[0]);
464 obj_index(orp, orp->parm[1]);
465 if (!(orp->parm[0] | orp->parm[1]))
466 obj_word(orp, orp->parm[2]);
470 * Initializer for a LINNUM record.
471 * parm[0] = group index
472 * parm[1] = segment index
474 static void ori_linnum(ObjRecord * orp)
476 obj_index(orp, orp->parm[0]);
477 obj_index(orp, orp->parm[1]);
481 * Initializer for a local vars record.
483 static void ori_local(ObjRecord * orp)
485 obj_byte(orp, 0x40);
486 obj_byte(orp, dSYM);
490 * Null initializer for records that continue without any header info
492 static void ori_null(ObjRecord * orp)
494 (void)orp; /* Do nothing */
498 * This concludes the low level section of outobj.c
501 static char obj_infile[FILENAME_MAX];
503 static int32_t first_seg;
504 static bool any_segs;
505 static int passtwo;
506 static int arrindex;
508 #define GROUP_MAX 256 /* we won't _realistically_ have more
509 * than this many segs in a group */
510 #define EXT_BLKSIZ 256 /* block size for externals list */
512 struct Segment; /* need to know these structs exist */
513 struct Group;
515 struct LineNumber {
516 struct LineNumber *next;
517 struct Segment *segment;
518 int32_t offset;
519 int32_t lineno;
522 static struct FileName {
523 struct FileName *next;
524 char *name;
525 struct LineNumber *lnhead, **lntail;
526 int index;
527 } *fnhead, **fntail;
529 static struct Array {
530 struct Array *next;
531 unsigned size;
532 int basetype;
533 } *arrhead, **arrtail;
535 #define ARRAYBOT 31 /* magic number for first array index */
537 static struct Public {
538 struct Public *next;
539 char *name;
540 int32_t offset;
541 int32_t segment; /* only if it's far-absolute */
542 int type; /* only for local debug syms */
543 } *fpubhead, **fpubtail, *last_defined;
545 static struct External {
546 struct External *next;
547 char *name;
548 int32_t commonsize;
549 int32_t commonelem; /* element size if FAR, else zero */
550 int index; /* OBJ-file external index */
551 enum {
552 DEFWRT_NONE, /* no unusual default-WRT */
553 DEFWRT_STRING, /* a string we don't yet understand */
554 DEFWRT_SEGMENT, /* a segment */
555 DEFWRT_GROUP /* a group */
556 } defwrt_type;
557 union {
558 char *string;
559 struct Segment *seg;
560 struct Group *grp;
561 } defwrt_ptr;
562 struct External *next_dws; /* next with DEFWRT_STRING */
563 } *exthead, **exttail, *dws;
565 static int externals;
567 static struct ExtBack {
568 struct ExtBack *next;
569 struct External *exts[EXT_BLKSIZ];
570 } *ebhead, **ebtail;
572 static struct Segment {
573 struct Segment *next;
574 char *name;
575 int32_t index; /* the NASM segment id */
576 int32_t obj_index; /* the OBJ-file segment index */
577 struct Group *grp; /* the group it beint32_ts to */
578 uint32_t currentpos;
579 int32_t align; /* can be SEG_ABS + absolute addr */
580 struct Public *pubhead, **pubtail, *lochead, **loctail;
581 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
582 ObjRecord *orp;
583 enum {
584 CMB_PRIVATE = 0,
585 CMB_PUBLIC = 2,
586 CMB_STACK = 5,
587 CMB_COMMON = 6
588 } combine;
589 bool use32; /* is this segment 32-bit? */
590 } *seghead, **segtail, *obj_seg_needs_update;
592 static struct Group {
593 struct Group *next;
594 char *name;
595 int32_t index; /* NASM segment id */
596 int32_t obj_index; /* OBJ-file group index */
597 int32_t nentries; /* number of elements... */
598 int32_t nindices; /* ...and number of index elts... */
599 union {
600 int32_t index;
601 char *name;
602 } segs[GROUP_MAX]; /* ...in this */
603 } *grphead, **grptail, *obj_grp_needs_update;
605 static struct ImpDef {
606 struct ImpDef *next;
607 char *extname;
608 char *libname;
609 unsigned int impindex;
610 char *impname;
611 } *imphead, **imptail;
613 static struct ExpDef {
614 struct ExpDef *next;
615 char *intname;
616 char *extname;
617 unsigned int ordinal;
618 int flags;
619 } *exphead, **exptail;
621 #define EXPDEF_FLAG_ORDINAL 0x80
622 #define EXPDEF_FLAG_RESIDENT 0x40
623 #define EXPDEF_FLAG_NODATA 0x20
624 #define EXPDEF_MASK_PARMCNT 0x1F
626 static int32_t obj_entry_seg, obj_entry_ofs;
628 const struct ofmt of_obj;
629 static const struct dfmt borland_debug_form;
631 /* The current segment */
632 static struct Segment *current_seg;
634 static int32_t obj_segment(char *, int, int *);
635 static void obj_write_file(void);
636 static int obj_directive(enum directives, char *, int);
638 static void obj_init(void)
640 first_seg = seg_alloc();
641 any_segs = false;
642 fpubhead = NULL;
643 fpubtail = &fpubhead;
644 exthead = NULL;
645 exttail = &exthead;
646 imphead = NULL;
647 imptail = &imphead;
648 exphead = NULL;
649 exptail = &exphead;
650 dws = NULL;
651 externals = 0;
652 ebhead = NULL;
653 ebtail = &ebhead;
654 seghead = obj_seg_needs_update = NULL;
655 segtail = &seghead;
656 grphead = obj_grp_needs_update = NULL;
657 grptail = &grphead;
658 obj_entry_seg = NO_SEG;
659 obj_uppercase = false;
660 obj_use32 = false;
661 passtwo = 0;
662 current_seg = NULL;
665 static int obj_set_info(enum geninfo type, char **val)
667 (void)type;
668 (void)val;
670 return 0;
673 static void obj_cleanup(void)
675 obj_write_file();
676 dfmt->cleanup();
677 while (seghead) {
678 struct Segment *segtmp = seghead;
679 seghead = seghead->next;
680 while (segtmp->pubhead) {
681 struct Public *pubtmp = segtmp->pubhead;
682 segtmp->pubhead = pubtmp->next;
683 nasm_free(pubtmp->name);
684 nasm_free(pubtmp);
686 nasm_free(segtmp->segclass);
687 nasm_free(segtmp->overlay);
688 nasm_free(segtmp);
690 while (fpubhead) {
691 struct Public *pubtmp = fpubhead;
692 fpubhead = fpubhead->next;
693 nasm_free(pubtmp->name);
694 nasm_free(pubtmp);
696 while (exthead) {
697 struct External *exttmp = exthead;
698 exthead = exthead->next;
699 nasm_free(exttmp);
701 while (imphead) {
702 struct ImpDef *imptmp = imphead;
703 imphead = imphead->next;
704 nasm_free(imptmp->extname);
705 nasm_free(imptmp->libname);
706 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
707 nasm_free(imptmp);
709 while (exphead) {
710 struct ExpDef *exptmp = exphead;
711 exphead = exphead->next;
712 nasm_free(exptmp->extname);
713 nasm_free(exptmp->intname);
714 nasm_free(exptmp);
716 while (ebhead) {
717 struct ExtBack *ebtmp = ebhead;
718 ebhead = ebhead->next;
719 nasm_free(ebtmp);
721 while (grphead) {
722 struct Group *grptmp = grphead;
723 grphead = grphead->next;
724 nasm_free(grptmp);
728 static void obj_ext_set_defwrt(struct External *ext, char *id)
730 struct Segment *seg;
731 struct Group *grp;
733 for (seg = seghead; seg; seg = seg->next)
734 if (!strcmp(seg->name, id)) {
735 ext->defwrt_type = DEFWRT_SEGMENT;
736 ext->defwrt_ptr.seg = seg;
737 nasm_free(id);
738 return;
741 for (grp = grphead; grp; grp = grp->next)
742 if (!strcmp(grp->name, id)) {
743 ext->defwrt_type = DEFWRT_GROUP;
744 ext->defwrt_ptr.grp = grp;
745 nasm_free(id);
746 return;
749 ext->defwrt_type = DEFWRT_STRING;
750 ext->defwrt_ptr.string = id;
751 ext->next_dws = dws;
752 dws = ext;
755 static void obj_deflabel(char *name, int32_t segment,
756 int64_t offset, int is_global, char *special)
759 * We have three cases:
761 * (i) `segment' is a segment-base. If so, set the name field
762 * for the segment or group structure it refers to, and then
763 * return.
765 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
766 * Save the label position for later output of a PUBDEF record.
767 * (Or a MODPUB, if we work out how.)
769 * (iii) `segment' is not one of our segments. Save the label
770 * position for later output of an EXTDEF, and also store a
771 * back-reference so that we can map later references to this
772 * segment number to the external index.
774 struct External *ext;
775 struct ExtBack *eb;
776 struct Segment *seg;
777 int i;
778 bool used_special = false; /* have we used the special text? */
780 #if defined(DEBUG) && DEBUG>2
781 nasm_error(ERR_DEBUG,
782 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
783 name, segment, offset, is_global, special);
784 #endif
787 * If it's a special-retry from pass two, discard it.
789 if (is_global == 3)
790 return;
793 * First check for the double-period, signifying something
794 * unusual.
796 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
797 if (!strcmp(name, "..start")) {
798 obj_entry_seg = segment;
799 obj_entry_ofs = offset;
800 return;
802 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
806 * Case (i):
808 if (obj_seg_needs_update) {
809 obj_seg_needs_update->name = name;
810 return;
811 } else if (obj_grp_needs_update) {
812 obj_grp_needs_update->name = name;
813 return;
815 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
816 return;
818 if (segment >= SEG_ABS || segment == NO_SEG) {
820 * SEG_ABS subcase of (ii).
822 if (is_global) {
823 struct Public *pub;
825 pub = *fpubtail = nasm_malloc(sizeof(*pub));
826 fpubtail = &pub->next;
827 pub->next = NULL;
828 pub->name = nasm_strdup(name);
829 pub->offset = offset;
830 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
832 if (special)
833 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
834 " for this symbol type");
835 return;
839 * If `any_segs' is still false, we might need to define a
840 * default segment, if they're trying to declare a label in
841 * `first_seg'.
843 if (!any_segs && segment == first_seg) {
844 int tempint; /* ignored */
845 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
846 nasm_panic(0, "strange segment conditions in OBJ driver");
849 for (seg = seghead; seg && is_global; seg = seg->next)
850 if (seg->index == segment) {
851 struct Public *loc = nasm_malloc(sizeof(*loc));
853 * Case (ii). Maybe MODPUB someday?
855 *seg->pubtail = loc;
856 seg->pubtail = &loc->next;
857 loc->next = NULL;
858 loc->name = nasm_strdup(name);
859 loc->offset = offset;
861 if (special)
862 nasm_error(ERR_NONFATAL,
863 "OBJ supports no special symbol features"
864 " for this symbol type");
865 return;
869 * Case (iii).
871 if (is_global) {
872 ext = *exttail = nasm_malloc(sizeof(*ext));
873 ext->next = NULL;
874 exttail = &ext->next;
875 ext->name = name;
876 /* Place by default all externs into the current segment */
877 ext->defwrt_type = DEFWRT_NONE;
879 /* 28-Apr-2002 - John Coffman
880 The following code was introduced on 12-Aug-2000, and breaks fixups
881 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
882 (5.10). It was introduced after FIXUP32 was added, and may be needed
883 for 32-bit segments. The following will get 16-bit segments working
884 again, and maybe someone can correct the 'if' condition which is
885 actually needed.
887 #if 0
888 if (current_seg) {
889 #else
890 if (current_seg && current_seg->use32) {
891 if (current_seg->grp) {
892 ext->defwrt_type = DEFWRT_GROUP;
893 ext->defwrt_ptr.grp = current_seg->grp;
894 } else {
895 ext->defwrt_type = DEFWRT_SEGMENT;
896 ext->defwrt_ptr.seg = current_seg;
899 #endif
901 if (is_global == 2) {
902 ext->commonsize = offset;
903 ext->commonelem = 1; /* default FAR */
904 } else
905 ext->commonsize = 0;
906 } else
907 return;
910 * Now process the special text, if any, to find default-WRT
911 * specifications and common-variable element-size and near/far
912 * specifications.
914 while (special && *special) {
915 used_special = true;
918 * We might have a default-WRT specification.
920 if (!nasm_strnicmp(special, "wrt", 3)) {
921 char *p;
922 int len;
923 special += 3;
924 special += strspn(special, " \t");
925 p = nasm_strndup(special, len = strcspn(special, ":"));
926 obj_ext_set_defwrt(ext, p);
927 special += len;
928 if (*special && *special != ':')
929 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
930 " text for `%s'", ext->name);
931 else if (*special == ':')
932 special++;
936 * The NEAR or FAR keywords specify nearness or
937 * farness. FAR gives default element size 1.
939 if (!nasm_strnicmp(special, "far", 3)) {
940 if (ext->commonsize)
941 ext->commonelem = 1;
942 else
943 nasm_error(ERR_NONFATAL,
944 "`%s': `far' keyword may only be applied"
945 " to common variables\n", ext->name);
946 special += 3;
947 special += strspn(special, " \t");
948 } else if (!nasm_strnicmp(special, "near", 4)) {
949 if (ext->commonsize)
950 ext->commonelem = 0;
951 else
952 nasm_error(ERR_NONFATAL,
953 "`%s': `far' keyword may only be applied"
954 " to common variables\n", ext->name);
955 special += 4;
956 special += strspn(special, " \t");
960 * If it's a common, and anything else remains on the line
961 * before a further colon, evaluate it as an expression and
962 * use that as the element size. Forward references aren't
963 * allowed.
965 if (*special == ':')
966 special++;
967 else if (*special) {
968 if (ext->commonsize) {
969 expr *e;
970 struct tokenval tokval;
972 stdscan_reset();
973 stdscan_set(special);
974 tokval.t_type = TOKEN_INVALID;
975 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
976 if (e) {
977 if (!is_simple(e))
978 nasm_error(ERR_NONFATAL, "cannot use relocatable"
979 " expression as common-variable element size");
980 else
981 ext->commonelem = reloc_value(e);
983 special = stdscan_get();
984 } else {
985 nasm_error(ERR_NONFATAL,
986 "`%s': element-size specifications only"
987 " apply to common variables", ext->name);
988 while (*special && *special != ':')
989 special++;
990 if (*special == ':')
991 special++;
996 i = segment / 2;
997 eb = ebhead;
998 if (!eb) {
999 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1000 eb->next = NULL;
1001 ebtail = &eb->next;
1003 while (i >= EXT_BLKSIZ) {
1004 if (eb && eb->next)
1005 eb = eb->next;
1006 else {
1007 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1008 eb->next = NULL;
1009 ebtail = &eb->next;
1011 i -= EXT_BLKSIZ;
1013 eb->exts[i] = ext;
1014 ext->index = ++externals;
1016 if (special && !used_special)
1017 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1018 " for this symbol type");
1021 /* forward declaration */
1022 static void obj_write_fixup(ObjRecord * orp, int bytes,
1023 int segrel, int32_t seg, int32_t wrt,
1024 struct Segment *segto);
1026 static void obj_out(int32_t segto, const void *data,
1027 enum out_type type, uint64_t size,
1028 int32_t segment, int32_t wrt)
1030 const uint8_t *ucdata;
1031 int32_t ldata;
1032 struct Segment *seg;
1033 ObjRecord *orp;
1036 * handle absolute-assembly (structure definitions)
1038 if (segto == NO_SEG) {
1039 if (type != OUT_RESERVE)
1040 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1041 " space");
1042 return;
1046 * If `any_segs' is still false, we must define a default
1047 * segment.
1049 if (!any_segs) {
1050 int tempint; /* ignored */
1051 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1052 nasm_panic(0, "strange segment conditions in OBJ driver");
1056 * Find the segment we are targetting.
1058 for (seg = seghead; seg; seg = seg->next)
1059 if (seg->index == segto)
1060 break;
1061 if (!seg)
1062 nasm_panic(0, "code directed to nonexistent segment?");
1064 orp = seg->orp;
1065 orp->parm[0] = seg->currentpos;
1067 switch (type) {
1068 case OUT_RAWDATA:
1069 ucdata = data;
1070 while (size > 0) {
1071 unsigned int len;
1072 orp = obj_check(seg->orp, 1);
1073 len = RECORD_MAX - orp->used;
1074 if (len > size)
1075 len = size;
1076 memcpy(orp->buf + orp->used, ucdata, len);
1077 orp->committed = orp->used += len;
1078 orp->parm[0] = seg->currentpos += len;
1079 ucdata += len;
1080 size -= len;
1082 break;
1084 case OUT_ADDRESS:
1085 case OUT_REL1ADR:
1086 case OUT_REL2ADR:
1087 case OUT_REL4ADR:
1088 case OUT_REL8ADR:
1090 int rsize;
1092 if (type == OUT_ADDRESS)
1093 size = abs((int)size);
1095 if (segment == NO_SEG && type != OUT_ADDRESS)
1096 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1097 " supported by OBJ format");
1098 if (segment >= SEG_ABS)
1099 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1100 " by OBJ format");
1102 ldata = *(int64_t *)data;
1103 if (type != OUT_ADDRESS) {
1105 * For 16-bit and 32-bit x86 code, the size and realsize() always
1106 * matches as only jumps, calls and loops uses PC relative
1107 * addressing and the address isn't followed by any other opcode
1108 * bytes. In 64-bit mode there is RIP relative addressing which
1109 * means the fixup location can be followed by an immediate value,
1110 * meaning that size > realsize().
1112 * When the CPU is calculating the effective address, it takes the
1113 * RIP at the end of the instruction and adds the fixed up relative
1114 * address value to it.
1116 * The linker's point of reference is the end of the fixup location
1117 * (which is the end of the instruction for Jcc, CALL, LOOP[cc]).
1118 * It is calculating distance between the target symbol and the end
1119 * of the fixup location, and add this to the displacement value we
1120 * are calculating here and storing at the fixup location.
1122 * To get the right effect, we need to _reduce_ the displacement
1123 * value by the number of bytes following the fixup.
1125 * Example:
1126 * data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
1127 * end of fixup at 0x054, end of instruction at 0x058.
1128 * => size = 8.
1129 * => realsize() -> 4
1130 * => CPU needs a value of: 0x100 - 0x058 = 0x0a8
1131 * => linker/loader will add: 0x100 - 0x054 = 0x0ac
1132 * => We must add an addend of -4.
1133 * => realsize() - size = -4.
1135 * The code used to do size - realsize() at least since v0.90,
1136 * probably because it wasn't needed...
1138 ldata -= size;
1139 size = realsize(type, size);
1140 ldata += size;
1143 if (size > UINT_MAX)
1144 size = 0;
1146 switch ((unsigned int)size) {
1147 default:
1148 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1149 "32-byte relocations");
1150 segment = NO_SEG; /* Don't actually generate a relocation */
1151 break;
1152 case 2:
1153 orp = obj_word(orp, ldata);
1154 break;
1155 case 4:
1156 orp = obj_dword(orp, ldata);
1157 break;
1160 rsize = size;
1161 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1162 size == 4) {
1164 * This is a 4-byte segment-base relocation such as
1165 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1166 * these, but if the constant term has the 16 low bits
1167 * zero, we can just apply a 2-byte segment-base
1168 * relocation to the low word instead.
1170 rsize = 2;
1171 if (ldata & 0xFFFF)
1172 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1173 " dword-size segment base references");
1175 if (segment != NO_SEG)
1176 obj_write_fixup(orp, rsize,
1177 (type == OUT_ADDRESS ? 0x4000 : 0),
1178 segment, wrt, seg);
1179 seg->currentpos += size;
1180 break;
1183 default:
1184 nasm_error(ERR_NONFATAL,
1185 "Relocation type not supported by output format");
1186 /* fall through */
1188 case OUT_RESERVE:
1189 if (orp->committed)
1190 orp = obj_bump(orp);
1191 seg->currentpos += size;
1192 break;
1194 obj_commit(orp);
1197 static void obj_write_fixup(ObjRecord * orp, int bytes,
1198 int segrel, int32_t seg, int32_t wrt,
1199 struct Segment *segto)
1201 unsigned locat;
1202 int method;
1203 int base;
1204 int32_t tidx, fidx;
1205 struct Segment *s = NULL;
1206 struct Group *g = NULL;
1207 struct External *e = NULL;
1208 ObjRecord *forp;
1210 if (bytes != 2 && bytes != 4) {
1211 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1212 " %d-bit relocations", bytes << 3);
1213 return;
1216 forp = orp->child;
1217 if (forp == NULL) {
1218 orp->child = forp = obj_new();
1219 forp->up = &(orp->child);
1220 /* We should choose between FIXUPP and FIXU32 record type */
1221 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1222 if (segto->use32)
1223 forp->type = FIXU32;
1224 else
1225 forp->type = FIXUPP;
1228 if (seg % 2) {
1229 base = true;
1230 locat = FIX_16_SELECTOR;
1231 seg--;
1232 if (bytes != 2)
1233 nasm_panic(0, "OBJ: 4-byte segment base fixup got"
1234 " through sanity check");
1235 } else {
1236 base = false;
1237 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1238 if (!segrel)
1240 * There is a bug in tlink that makes it process self relative
1241 * fixups incorrectly if the x_size doesn't match the location
1242 * size.
1244 forp = obj_force(forp, bytes << 3);
1247 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1249 tidx = fidx = -1, method = 0; /* placate optimisers */
1252 * See if we can find the segment ID in our segment list. If
1253 * so, we have a T4 (LSEG) target.
1255 for (s = seghead; s; s = s->next)
1256 if (s->index == seg)
1257 break;
1258 if (s)
1259 method = 4, tidx = s->obj_index;
1260 else {
1261 for (g = grphead; g; g = g->next)
1262 if (g->index == seg)
1263 break;
1264 if (g)
1265 method = 5, tidx = g->obj_index;
1266 else {
1267 int32_t i = seg / 2;
1268 struct ExtBack *eb = ebhead;
1269 while (i >= EXT_BLKSIZ) {
1270 if (eb)
1271 eb = eb->next;
1272 else
1273 break;
1274 i -= EXT_BLKSIZ;
1276 if (eb)
1277 method = 6, e = eb->exts[i], tidx = e->index;
1278 else
1279 nasm_panic(0,
1280 "unrecognised segment value in obj_write_fixup");
1285 * If no WRT given, assume the natural default, which is method
1286 * F5 unless:
1288 * - we are doing an OFFSET fixup for a grouped segment, in
1289 * which case we require F1 (group).
1291 * - we are doing an OFFSET fixup for an external with a
1292 * default WRT, in which case we must honour the default WRT.
1294 if (wrt == NO_SEG) {
1295 if (!base && s && s->grp)
1296 method |= 0x10, fidx = s->grp->obj_index;
1297 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1298 if (e->defwrt_type == DEFWRT_SEGMENT)
1299 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1300 else if (e->defwrt_type == DEFWRT_GROUP)
1301 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1302 else {
1303 nasm_error(ERR_NONFATAL, "default WRT specification for"
1304 " external `%s' unresolved", e->name);
1305 method |= 0x50, fidx = -1; /* got to do _something_ */
1307 } else
1308 method |= 0x50, fidx = -1;
1309 } else {
1311 * See if we can find the WRT-segment ID in our segment
1312 * list. If so, we have a F0 (LSEG) frame.
1314 for (s = seghead; s; s = s->next)
1315 if (s->index == wrt - 1)
1316 break;
1317 if (s)
1318 method |= 0x00, fidx = s->obj_index;
1319 else {
1320 for (g = grphead; g; g = g->next)
1321 if (g->index == wrt - 1)
1322 break;
1323 if (g)
1324 method |= 0x10, fidx = g->obj_index;
1325 else {
1326 int32_t i = wrt / 2;
1327 struct ExtBack *eb = ebhead;
1328 while (i >= EXT_BLKSIZ) {
1329 if (eb)
1330 eb = eb->next;
1331 else
1332 break;
1333 i -= EXT_BLKSIZ;
1335 if (eb)
1336 method |= 0x20, fidx = eb->exts[i]->index;
1337 else
1338 nasm_panic(0,
1339 "unrecognised WRT value in obj_write_fixup");
1344 forp = obj_byte(forp, method);
1345 if (fidx != -1)
1346 forp = obj_index(forp, fidx);
1347 forp = obj_index(forp, tidx);
1348 obj_commit(forp);
1351 static int32_t obj_segment(char *name, int pass, int *bits)
1354 * We call the label manager here to define a name for the new
1355 * segment, and when our _own_ label-definition stub gets
1356 * called in return, it should register the new segment name
1357 * using the pointer it gets passed. That way we save memory,
1358 * by sponging off the label manager.
1360 #if defined(DEBUG) && DEBUG>=3
1361 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1362 name, pass, *bits);
1363 #endif
1364 if (!name) {
1365 *bits = 16;
1366 current_seg = NULL;
1367 return first_seg;
1368 } else {
1369 struct Segment *seg;
1370 struct Group *grp;
1371 struct External **extp;
1372 int obj_idx, i, attrs;
1373 bool rn_error;
1374 char *p;
1377 * Look for segment attributes.
1379 attrs = 0;
1380 while (*name == '.')
1381 name++; /* hack, but a documented one */
1382 p = name;
1383 while (*p && !nasm_isspace(*p))
1384 p++;
1385 if (*p) {
1386 *p++ = '\0';
1387 while (*p && nasm_isspace(*p))
1388 *p++ = '\0';
1390 while (*p) {
1391 while (*p && !nasm_isspace(*p))
1392 p++;
1393 if (*p) {
1394 *p++ = '\0';
1395 while (*p && nasm_isspace(*p))
1396 *p++ = '\0';
1399 attrs++;
1402 obj_idx = 1;
1403 for (seg = seghead; seg; seg = seg->next) {
1404 obj_idx++;
1405 if (!strcmp(seg->name, name)) {
1406 if (attrs > 0 && pass == 1)
1407 nasm_error(ERR_WARNING, "segment attributes specified on"
1408 " redeclaration of segment: ignoring");
1409 if (seg->use32)
1410 *bits = 32;
1411 else
1412 *bits = 16;
1413 current_seg = seg;
1414 return seg->index;
1418 *segtail = seg = nasm_malloc(sizeof(*seg));
1419 seg->next = NULL;
1420 segtail = &seg->next;
1421 seg->index = (any_segs ? seg_alloc() : first_seg);
1422 seg->obj_index = obj_idx;
1423 seg->grp = NULL;
1424 any_segs = true;
1425 seg->name = NULL;
1426 seg->currentpos = 0;
1427 seg->align = 1; /* default */
1428 seg->use32 = false; /* default */
1429 seg->combine = CMB_PUBLIC; /* default */
1430 seg->segclass = seg->overlay = NULL;
1431 seg->pubhead = NULL;
1432 seg->pubtail = &seg->pubhead;
1433 seg->lochead = NULL;
1434 seg->loctail = &seg->lochead;
1435 seg->orp = obj_new();
1436 seg->orp->up = &(seg->orp);
1437 seg->orp->ori = ori_ledata;
1438 seg->orp->type = LEDATA;
1439 seg->orp->parm[1] = obj_idx;
1442 * Process the segment attributes.
1444 p = name;
1445 while (attrs--) {
1446 p += strlen(p);
1447 while (!*p)
1448 p++;
1451 * `p' contains a segment attribute.
1453 if (!nasm_stricmp(p, "private"))
1454 seg->combine = CMB_PRIVATE;
1455 else if (!nasm_stricmp(p, "public"))
1456 seg->combine = CMB_PUBLIC;
1457 else if (!nasm_stricmp(p, "common"))
1458 seg->combine = CMB_COMMON;
1459 else if (!nasm_stricmp(p, "stack"))
1460 seg->combine = CMB_STACK;
1461 else if (!nasm_stricmp(p, "use16"))
1462 seg->use32 = false;
1463 else if (!nasm_stricmp(p, "use32"))
1464 seg->use32 = true;
1465 else if (!nasm_stricmp(p, "flat")) {
1467 * This segment is an OS/2 FLAT segment. That means
1468 * that its default group is group FLAT, even if
1469 * the group FLAT does not explicitly _contain_ the
1470 * segment.
1472 * When we see this, we must create the group
1473 * `FLAT', containing no segments, if it does not
1474 * already exist; then we must set the default
1475 * group of this segment to be the FLAT group.
1477 struct Group *grp;
1478 for (grp = grphead; grp; grp = grp->next)
1479 if (!strcmp(grp->name, "FLAT"))
1480 break;
1481 if (!grp) {
1482 obj_directive(D_GROUP, "FLAT", 1);
1483 for (grp = grphead; grp; grp = grp->next)
1484 if (!strcmp(grp->name, "FLAT"))
1485 break;
1486 if (!grp)
1487 nasm_panic(0, "failure to define FLAT?!");
1489 seg->grp = grp;
1490 } else if (!nasm_strnicmp(p, "class=", 6))
1491 seg->segclass = nasm_strdup(p + 6);
1492 else if (!nasm_strnicmp(p, "overlay=", 8))
1493 seg->overlay = nasm_strdup(p + 8);
1494 else if (!nasm_strnicmp(p, "align=", 6)) {
1495 seg->align = readnum(p + 6, &rn_error);
1496 if (rn_error) {
1497 seg->align = 1;
1498 nasm_error(ERR_NONFATAL, "segment alignment should be"
1499 " numeric");
1501 switch ((int)seg->align) {
1502 case 1: /* BYTE */
1503 case 2: /* WORD */
1504 case 4: /* DWORD */
1505 case 16: /* PARA */
1506 case 256: /* PAGE */
1507 case 4096: /* PharLap extension */
1508 break;
1509 case 8:
1510 nasm_error(ERR_WARNING,
1511 "OBJ format does not support alignment"
1512 " of 8: rounding up to 16");
1513 seg->align = 16;
1514 break;
1515 case 32:
1516 case 64:
1517 case 128:
1518 nasm_error(ERR_WARNING,
1519 "OBJ format does not support alignment"
1520 " of %d: rounding up to 256", seg->align);
1521 seg->align = 256;
1522 break;
1523 case 512:
1524 case 1024:
1525 case 2048:
1526 nasm_error(ERR_WARNING,
1527 "OBJ format does not support alignment"
1528 " of %d: rounding up to 4096", seg->align);
1529 seg->align = 4096;
1530 break;
1531 default:
1532 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1533 seg->align);
1534 seg->align = 1;
1535 break;
1537 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1538 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1539 if (rn_error)
1540 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1541 " attribute should be numeric");
1545 /* We need to know whenever we have at least one 32-bit segment */
1546 obj_use32 |= seg->use32;
1548 obj_seg_needs_update = seg;
1549 if (seg->align >= SEG_ABS)
1550 define_label(name, NO_SEG, seg->align - SEG_ABS,
1551 NULL, false, false);
1552 else
1553 define_label(name, seg->index + 1, 0L,
1554 NULL, false, false);
1555 obj_seg_needs_update = NULL;
1558 * See if this segment is defined in any groups.
1560 for (grp = grphead; grp; grp = grp->next) {
1561 for (i = grp->nindices; i < grp->nentries; i++) {
1562 if (!strcmp(grp->segs[i].name, seg->name)) {
1563 nasm_free(grp->segs[i].name);
1564 grp->segs[i] = grp->segs[grp->nindices];
1565 grp->segs[grp->nindices++].index = seg->obj_index;
1566 if (seg->grp)
1567 nasm_error(ERR_WARNING,
1568 "segment `%s' is already part of"
1569 " a group: first one takes precedence",
1570 seg->name);
1571 else
1572 seg->grp = grp;
1578 * Walk through the list of externals with unresolved
1579 * default-WRT clauses, and resolve any that point at this
1580 * segment.
1582 extp = &dws;
1583 while (*extp) {
1584 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1585 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1586 nasm_free((*extp)->defwrt_ptr.string);
1587 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1588 (*extp)->defwrt_ptr.seg = seg;
1589 *extp = (*extp)->next_dws;
1590 } else
1591 extp = &(*extp)->next_dws;
1594 if (seg->use32)
1595 *bits = 32;
1596 else
1597 *bits = 16;
1598 current_seg = seg;
1599 return seg->index;
1603 static int obj_directive(enum directives directive, char *value, int pass)
1605 switch (directive) {
1606 case D_GROUP:
1608 char *p, *q, *v;
1609 if (pass == 1) {
1610 struct Group *grp;
1611 struct Segment *seg;
1612 struct External **extp;
1613 int obj_idx;
1615 q = value;
1616 while (*q == '.')
1617 q++; /* hack, but a documented one */
1618 v = q;
1619 while (*q && !nasm_isspace(*q))
1620 q++;
1621 if (nasm_isspace(*q)) {
1622 *q++ = '\0';
1623 while (*q && nasm_isspace(*q))
1624 q++;
1627 * Here we used to sanity-check the group directive to
1628 * ensure nobody tried to declare a group containing no
1629 * segments. However, OS/2 does this as standard
1630 * practice, so the sanity check has been removed.
1632 * if (!*q) {
1633 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1634 * return 1;
1638 obj_idx = 1;
1639 for (grp = grphead; grp; grp = grp->next) {
1640 obj_idx++;
1641 if (!strcmp(grp->name, v)) {
1642 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1643 return 1;
1647 *grptail = grp = nasm_malloc(sizeof(*grp));
1648 grp->next = NULL;
1649 grptail = &grp->next;
1650 grp->index = seg_alloc();
1651 grp->obj_index = obj_idx;
1652 grp->nindices = grp->nentries = 0;
1653 grp->name = NULL;
1655 obj_grp_needs_update = grp;
1656 define_label(v, grp->index + 1, 0L, NULL, false, false);
1657 obj_grp_needs_update = NULL;
1659 while (*q) {
1660 p = q;
1661 while (*q && !nasm_isspace(*q))
1662 q++;
1663 if (nasm_isspace(*q)) {
1664 *q++ = '\0';
1665 while (*q && nasm_isspace(*q))
1666 q++;
1669 * Now p contains a segment name. Find it.
1671 for (seg = seghead; seg; seg = seg->next)
1672 if (!strcmp(seg->name, p))
1673 break;
1674 if (seg) {
1676 * We have a segment index. Shift a name entry
1677 * to the end of the array to make room.
1679 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1680 grp->segs[grp->nindices++].index = seg->obj_index;
1681 if (seg->grp)
1682 nasm_error(ERR_WARNING,
1683 "segment `%s' is already part of"
1684 " a group: first one takes precedence",
1685 seg->name);
1686 else
1687 seg->grp = grp;
1688 } else {
1690 * We have an as-yet undefined segment.
1691 * Remember its name, for later.
1693 grp->segs[grp->nentries++].name = nasm_strdup(p);
1698 * Walk through the list of externals with unresolved
1699 * default-WRT clauses, and resolve any that point at
1700 * this group.
1702 extp = &dws;
1703 while (*extp) {
1704 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1705 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1706 nasm_free((*extp)->defwrt_ptr.string);
1707 (*extp)->defwrt_type = DEFWRT_GROUP;
1708 (*extp)->defwrt_ptr.grp = grp;
1709 *extp = (*extp)->next_dws;
1710 } else
1711 extp = &(*extp)->next_dws;
1714 return 1;
1716 case D_UPPERCASE:
1717 obj_uppercase = true;
1718 return 1;
1720 case D_IMPORT:
1722 char *q, *extname, *libname, *impname;
1724 if (pass == 2)
1725 return 1; /* ignore in pass two */
1726 extname = q = value;
1727 while (*q && !nasm_isspace(*q))
1728 q++;
1729 if (nasm_isspace(*q)) {
1730 *q++ = '\0';
1731 while (*q && nasm_isspace(*q))
1732 q++;
1735 libname = q;
1736 while (*q && !nasm_isspace(*q))
1737 q++;
1738 if (nasm_isspace(*q)) {
1739 *q++ = '\0';
1740 while (*q && nasm_isspace(*q))
1741 q++;
1744 impname = q;
1746 if (!*extname || !*libname)
1747 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1748 " and library name");
1749 else {
1750 struct ImpDef *imp;
1751 bool err = false;
1753 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1754 imptail = &imp->next;
1755 imp->next = NULL;
1756 imp->extname = nasm_strdup(extname);
1757 imp->libname = nasm_strdup(libname);
1758 imp->impindex = readnum(impname, &err);
1759 if (!*impname || err)
1760 imp->impname = nasm_strdup(impname);
1761 else
1762 imp->impname = NULL;
1765 return 1;
1767 case D_EXPORT:
1769 char *q, *extname, *intname, *v;
1770 struct ExpDef *export;
1771 int flags = 0;
1772 unsigned int ordinal = 0;
1774 if (pass == 2)
1775 return 1; /* ignore in pass two */
1776 intname = q = value;
1777 while (*q && !nasm_isspace(*q))
1778 q++;
1779 if (nasm_isspace(*q)) {
1780 *q++ = '\0';
1781 while (*q && nasm_isspace(*q))
1782 q++;
1785 extname = q;
1786 while (*q && !nasm_isspace(*q))
1787 q++;
1788 if (nasm_isspace(*q)) {
1789 *q++ = '\0';
1790 while (*q && nasm_isspace(*q))
1791 q++;
1794 if (!*intname) {
1795 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1796 return 1;
1798 if (!*extname) {
1799 extname = intname;
1800 intname = "";
1802 while (*q) {
1803 v = q;
1804 while (*q && !nasm_isspace(*q))
1805 q++;
1806 if (nasm_isspace(*q)) {
1807 *q++ = '\0';
1808 while (*q && nasm_isspace(*q))
1809 q++;
1811 if (!nasm_stricmp(v, "resident"))
1812 flags |= EXPDEF_FLAG_RESIDENT;
1813 else if (!nasm_stricmp(v, "nodata"))
1814 flags |= EXPDEF_FLAG_NODATA;
1815 else if (!nasm_strnicmp(v, "parm=", 5)) {
1816 bool err = false;
1817 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1818 if (err) {
1819 nasm_error(ERR_NONFATAL,
1820 "value `%s' for `parm' is non-numeric", v + 5);
1821 return 1;
1823 } else {
1824 bool err = false;
1825 ordinal = readnum(v, &err);
1826 if (err) {
1827 nasm_error(ERR_NONFATAL,
1828 "unrecognised export qualifier `%s'", v);
1829 return 1;
1831 flags |= EXPDEF_FLAG_ORDINAL;
1835 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1836 exptail = &export->next;
1837 export->next = NULL;
1838 export->extname = nasm_strdup(extname);
1839 export->intname = nasm_strdup(intname);
1840 export->ordinal = ordinal;
1841 export->flags = flags;
1843 return 1;
1845 default:
1846 return 0;
1850 static void obj_sectalign(int32_t seg, unsigned int value)
1852 struct Segment *s;
1854 list_for_each(s, seghead) {
1855 if (s->index == seg)
1856 break;
1860 * it should not be too big value
1861 * and applied on non-absolute sections
1863 if (!s || !is_power2(value) ||
1864 value > 4096 || s->align >= SEG_ABS)
1865 return;
1868 * FIXME: No code duplication please
1869 * consider making helper for this
1870 * mapping since section handler has
1871 * to do the same
1873 switch (value) {
1874 case 8:
1875 value = 16;
1876 break;
1877 case 32:
1878 case 64:
1879 case 128:
1880 value = 256;
1881 break;
1882 case 512:
1883 case 1024:
1884 case 2048:
1885 value = 4096;
1886 break;
1889 if (s->align < (int)value)
1890 s->align = value;
1893 static int32_t obj_segbase(int32_t segment)
1895 struct Segment *seg;
1898 * Find the segment in our list.
1900 for (seg = seghead; seg; seg = seg->next)
1901 if (seg->index == segment - 1)
1902 break;
1904 if (!seg) {
1906 * Might be an external with a default WRT.
1908 int32_t i = segment / 2;
1909 struct ExtBack *eb = ebhead;
1910 struct External *e;
1912 while (i >= EXT_BLKSIZ) {
1913 if (eb)
1914 eb = eb->next;
1915 else
1916 break;
1917 i -= EXT_BLKSIZ;
1919 if (eb) {
1920 e = eb->exts[i];
1921 if (!e) {
1922 nasm_assert(pass0 == 0);
1923 /* Not available - can happen during optimization */
1924 return NO_SEG;
1927 switch (e->defwrt_type) {
1928 case DEFWRT_NONE:
1929 return segment; /* fine */
1930 case DEFWRT_SEGMENT:
1931 return e->defwrt_ptr.seg->index + 1;
1932 case DEFWRT_GROUP:
1933 return e->defwrt_ptr.grp->index + 1;
1934 default:
1935 return NO_SEG; /* can't tell what it is */
1939 return segment; /* not one of ours - leave it alone */
1942 if (seg->align >= SEG_ABS)
1943 return seg->align; /* absolute segment */
1944 if (seg->grp)
1945 return seg->grp->index + 1; /* grouped segment */
1947 return segment; /* no special treatment */
1950 static void obj_filename(char *inname, char *outname)
1952 strcpy(obj_infile, inname);
1953 standard_extension(inname, outname, ".obj");
1956 static void obj_write_file(void)
1958 struct Segment *seg, *entry_seg_ptr = 0;
1959 struct FileName *fn;
1960 struct LineNumber *ln;
1961 struct Group *grp;
1962 struct Public *pub, *loc;
1963 struct External *ext;
1964 struct ImpDef *imp;
1965 struct ExpDef *export;
1966 int lname_idx;
1967 ObjRecord *orp;
1968 const bool debuginfo = (dfmt == &borland_debug_form);
1971 * Write the THEADR module header.
1973 orp = obj_new();
1974 orp->type = THEADR;
1975 obj_name(orp, obj_infile);
1976 obj_emit2(orp);
1979 * Write the NASM boast comment.
1981 orp->type = COMENT;
1982 obj_rword(orp, 0); /* comment type zero */
1983 obj_name(orp, nasm_comment);
1984 obj_emit2(orp);
1986 orp->type = COMENT;
1988 * Write the IMPDEF records, if any.
1990 for (imp = imphead; imp; imp = imp->next) {
1991 obj_rword(orp, 0xA0); /* comment class A0 */
1992 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1993 if (imp->impname)
1994 obj_byte(orp, 0); /* import by name */
1995 else
1996 obj_byte(orp, 1); /* import by ordinal */
1997 obj_name(orp, imp->extname);
1998 obj_name(orp, imp->libname);
1999 if (imp->impname)
2000 obj_name(orp, imp->impname);
2001 else
2002 obj_word(orp, imp->impindex);
2003 obj_emit2(orp);
2007 * Write the EXPDEF records, if any.
2009 for (export = exphead; export; export = export->next) {
2010 obj_rword(orp, 0xA0); /* comment class A0 */
2011 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
2012 obj_byte(orp, export->flags);
2013 obj_name(orp, export->extname);
2014 obj_name(orp, export->intname);
2015 if (export->flags & EXPDEF_FLAG_ORDINAL)
2016 obj_word(orp, export->ordinal);
2017 obj_emit2(orp);
2020 /* we're using extended OMF if we put in debug info */
2021 if (debuginfo) {
2022 orp->type = COMENT;
2023 obj_byte(orp, 0x40);
2024 obj_byte(orp, dEXTENDED);
2025 obj_emit2(orp);
2029 * Write the first LNAMES record, containing LNAME one, which
2030 * is null. Also initialize the LNAME counter.
2032 orp->type = LNAMES;
2033 obj_byte(orp, 0);
2034 lname_idx = 1;
2036 * Write some LNAMES for the segment names
2038 for (seg = seghead; seg; seg = seg->next) {
2039 orp = obj_name(orp, seg->name);
2040 if (seg->segclass)
2041 orp = obj_name(orp, seg->segclass);
2042 if (seg->overlay)
2043 orp = obj_name(orp, seg->overlay);
2044 obj_commit(orp);
2047 * Write some LNAMES for the group names
2049 for (grp = grphead; grp; grp = grp->next) {
2050 orp = obj_name(orp, grp->name);
2051 obj_commit(orp);
2053 obj_emit(orp);
2056 * Write the SEGDEF records.
2058 orp->type = SEGDEF;
2059 for (seg = seghead; seg; seg = seg->next) {
2060 int acbp;
2061 uint32_t seglen = seg->currentpos;
2063 acbp = (seg->combine << 2); /* C field */
2065 if (seg->use32)
2066 acbp |= 0x01; /* P bit is Use32 flag */
2067 else if (seglen == 0x10000L) {
2068 seglen = 0; /* This special case may be needed for old linkers */
2069 acbp |= 0x02; /* B bit */
2072 /* A field */
2073 if (seg->align >= SEG_ABS)
2074 /* acbp |= 0x00 */ ;
2075 else if (seg->align >= 4096) {
2076 if (seg->align > 4096)
2077 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2078 " than OBJ format supports", seg->name);
2079 acbp |= 0xC0; /* PharLap extension */
2080 } else if (seg->align >= 256) {
2081 acbp |= 0x80;
2082 } else if (seg->align >= 16) {
2083 acbp |= 0x60;
2084 } else if (seg->align >= 4) {
2085 acbp |= 0xA0;
2086 } else if (seg->align >= 2) {
2087 acbp |= 0x40;
2088 } else
2089 acbp |= 0x20;
2091 obj_byte(orp, acbp);
2092 if (seg->align & SEG_ABS) {
2093 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2094 obj_byte(orp, 0); /* Offset */
2096 obj_x(orp, seglen);
2097 obj_index(orp, ++lname_idx);
2098 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2099 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2100 obj_emit2(orp);
2104 * Write the GRPDEF records.
2106 orp->type = GRPDEF;
2107 for (grp = grphead; grp; grp = grp->next) {
2108 int i;
2110 if (grp->nindices != grp->nentries) {
2111 for (i = grp->nindices; i < grp->nentries; i++) {
2112 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2113 " `%s'", grp->name, grp->segs[i].name);
2114 nasm_free(grp->segs[i].name);
2115 grp->segs[i].name = NULL;
2118 obj_index(orp, ++lname_idx);
2119 for (i = 0; i < grp->nindices; i++) {
2120 obj_byte(orp, 0xFF);
2121 obj_index(orp, grp->segs[i].index);
2123 obj_emit2(orp);
2127 * Write the PUBDEF records: first the ones in the segments,
2128 * then the far-absolutes.
2130 orp->type = PUBDEF;
2131 orp->ori = ori_pubdef;
2132 for (seg = seghead; seg; seg = seg->next) {
2133 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2134 orp->parm[1] = seg->obj_index;
2135 for (pub = seg->pubhead; pub; pub = pub->next) {
2136 orp = obj_name(orp, pub->name);
2137 orp = obj_x(orp, pub->offset);
2138 orp = obj_byte(orp, 0); /* type index */
2139 obj_commit(orp);
2141 obj_emit(orp);
2143 orp->parm[0] = 0;
2144 orp->parm[1] = 0;
2145 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2146 if (orp->parm[2] != (uint32_t)pub->segment) {
2147 obj_emit(orp);
2148 orp->parm[2] = pub->segment;
2150 orp = obj_name(orp, pub->name);
2151 orp = obj_x(orp, pub->offset);
2152 orp = obj_byte(orp, 0); /* type index */
2153 obj_commit(orp);
2155 obj_emit(orp);
2158 * Write the EXTDEF and COMDEF records, in order.
2160 orp->ori = ori_null;
2161 for (ext = exthead; ext; ext = ext->next) {
2162 if (ext->commonsize == 0) {
2163 if (orp->type != EXTDEF) {
2164 obj_emit(orp);
2165 orp->type = EXTDEF;
2167 orp = obj_name(orp, ext->name);
2168 orp = obj_index(orp, 0);
2169 } else {
2170 if (orp->type != COMDEF) {
2171 obj_emit(orp);
2172 orp->type = COMDEF;
2174 orp = obj_name(orp, ext->name);
2175 orp = obj_index(orp, 0);
2176 if (ext->commonelem) {
2177 orp = obj_byte(orp, 0x61); /* far communal */
2178 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2179 orp = obj_value(orp, ext->commonelem);
2180 } else {
2181 orp = obj_byte(orp, 0x62); /* near communal */
2182 orp = obj_value(orp, ext->commonsize);
2185 obj_commit(orp);
2187 obj_emit(orp);
2190 * Write a COMENT record stating that the linker's first pass
2191 * may stop processing at this point. Exception is if our
2192 * MODEND record specifies a start point, in which case,
2193 * according to some variants of the documentation, this COMENT
2194 * should be omitted. So we'll omit it just in case.
2195 * But, TASM puts it in all the time so if we are using
2196 * TASM debug stuff we are putting it in
2198 if (debuginfo || obj_entry_seg == NO_SEG) {
2199 orp->type = COMENT;
2200 obj_byte(orp, 0x40);
2201 obj_byte(orp, dLINKPASS);
2202 obj_byte(orp, 1);
2203 obj_emit2(orp);
2207 * 1) put out the compiler type
2208 * 2) Put out the type info. The only type we are using is near label #19
2210 if (debuginfo) {
2211 int i;
2212 struct Array *arrtmp = arrhead;
2213 orp->type = COMENT;
2214 obj_byte(orp, 0x40);
2215 obj_byte(orp, dCOMPDEF);
2216 obj_byte(orp, 4);
2217 obj_byte(orp, 0);
2218 obj_emit2(orp);
2220 obj_byte(orp, 0x40);
2221 obj_byte(orp, dTYPEDEF);
2222 obj_word(orp, 0x18); /* type # for linking */
2223 obj_word(orp, 6); /* size of type */
2224 obj_byte(orp, 0x2a); /* absolute type for debugging */
2225 obj_emit2(orp);
2226 obj_byte(orp, 0x40);
2227 obj_byte(orp, dTYPEDEF);
2228 obj_word(orp, 0x19); /* type # for linking */
2229 obj_word(orp, 0); /* size of type */
2230 obj_byte(orp, 0x24); /* absolute type for debugging */
2231 obj_byte(orp, 0); /* near/far specifier */
2232 obj_emit2(orp);
2233 obj_byte(orp, 0x40);
2234 obj_byte(orp, dTYPEDEF);
2235 obj_word(orp, 0x1A); /* type # for linking */
2236 obj_word(orp, 0); /* size of type */
2237 obj_byte(orp, 0x24); /* absolute type for debugging */
2238 obj_byte(orp, 1); /* near/far specifier */
2239 obj_emit2(orp);
2240 obj_byte(orp, 0x40);
2241 obj_byte(orp, dTYPEDEF);
2242 obj_word(orp, 0x1b); /* type # for linking */
2243 obj_word(orp, 0); /* size of type */
2244 obj_byte(orp, 0x23); /* absolute type for debugging */
2245 obj_byte(orp, 0);
2246 obj_byte(orp, 0);
2247 obj_byte(orp, 0);
2248 obj_emit2(orp);
2249 obj_byte(orp, 0x40);
2250 obj_byte(orp, dTYPEDEF);
2251 obj_word(orp, 0x1c); /* type # for linking */
2252 obj_word(orp, 0); /* size of type */
2253 obj_byte(orp, 0x23); /* absolute type for debugging */
2254 obj_byte(orp, 0);
2255 obj_byte(orp, 4);
2256 obj_byte(orp, 0);
2257 obj_emit2(orp);
2258 obj_byte(orp, 0x40);
2259 obj_byte(orp, dTYPEDEF);
2260 obj_word(orp, 0x1d); /* type # for linking */
2261 obj_word(orp, 0); /* size of type */
2262 obj_byte(orp, 0x23); /* absolute type for debugging */
2263 obj_byte(orp, 0);
2264 obj_byte(orp, 1);
2265 obj_byte(orp, 0);
2266 obj_emit2(orp);
2267 obj_byte(orp, 0x40);
2268 obj_byte(orp, dTYPEDEF);
2269 obj_word(orp, 0x1e); /* type # for linking */
2270 obj_word(orp, 0); /* size of type */
2271 obj_byte(orp, 0x23); /* absolute type for debugging */
2272 obj_byte(orp, 0);
2273 obj_byte(orp, 5);
2274 obj_byte(orp, 0);
2275 obj_emit2(orp);
2277 /* put out the array types */
2278 for (i = ARRAYBOT; i < arrindex; i++) {
2279 obj_byte(orp, 0x40);
2280 obj_byte(orp, dTYPEDEF);
2281 obj_word(orp, i); /* type # for linking */
2282 obj_word(orp, arrtmp->size); /* size of type */
2283 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2284 obj_byte(orp, arrtmp->basetype); /* base type */
2285 obj_emit2(orp);
2286 arrtmp = arrtmp->next;
2290 * write out line number info with a LINNUM record
2291 * switch records when we switch segments, and output the
2292 * file in a pseudo-TASM fashion. The record switch is naive; that
2293 * is that one file may have many records for the same segment
2294 * if there are lots of segment switches
2296 if (fnhead && debuginfo) {
2297 seg = fnhead->lnhead->segment;
2299 for (fn = fnhead; fn; fn = fn->next) {
2300 /* write out current file name */
2301 orp->type = COMENT;
2302 orp->ori = ori_null;
2303 obj_byte(orp, 0x40);
2304 obj_byte(orp, dFILNAME);
2305 obj_byte(orp, 0);
2306 obj_name(orp, fn->name);
2307 obj_dword(orp, 0);
2308 obj_emit2(orp);
2310 /* write out line numbers this file */
2312 orp->type = LINNUM;
2313 orp->ori = ori_linnum;
2314 for (ln = fn->lnhead; ln; ln = ln->next) {
2315 if (seg != ln->segment) {
2316 /* if we get here have to flush the buffer and start
2317 * a new record for a new segment
2319 seg = ln->segment;
2320 obj_emit(orp);
2322 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2323 orp->parm[1] = seg->obj_index;
2324 orp = obj_word(orp, ln->lineno);
2325 orp = obj_x(orp, ln->offset);
2326 obj_commit(orp);
2328 obj_emit(orp);
2332 * we are going to locate the entry point segment now
2333 * rather than wait until the MODEND record, because,
2334 * then we can output a special symbol to tell where the
2335 * entry point is.
2338 if (obj_entry_seg != NO_SEG) {
2339 for (seg = seghead; seg; seg = seg->next) {
2340 if (seg->index == obj_entry_seg) {
2341 entry_seg_ptr = seg;
2342 break;
2345 if (!seg)
2346 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2350 * get ready to put out symbol records
2352 orp->type = COMENT;
2353 orp->ori = ori_local;
2356 * put out a symbol for the entry point
2357 * no dots in this symbol, because, borland does
2358 * not (officially) support dots in label names
2359 * and I don't know what various versions of TLINK will do
2361 if (debuginfo && obj_entry_seg != NO_SEG) {
2362 orp = obj_name(orp, "start_of_program");
2363 orp = obj_word(orp, 0x19); /* type: near label */
2364 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2365 orp = obj_index(orp, seg->obj_index);
2366 orp = obj_x(orp, obj_entry_ofs);
2367 obj_commit(orp);
2371 * put out the local labels
2373 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2374 /* labels this seg */
2375 for (loc = seg->lochead; loc; loc = loc->next) {
2376 orp = obj_name(orp, loc->name);
2377 orp = obj_word(orp, loc->type);
2378 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2379 orp = obj_index(orp, seg->obj_index);
2380 orp = obj_x(orp, loc->offset);
2381 obj_commit(orp);
2384 if (orp->used)
2385 obj_emit(orp);
2388 * Write the LEDATA/FIXUPP pairs.
2390 for (seg = seghead; seg; seg = seg->next) {
2391 obj_emit(seg->orp);
2392 nasm_free(seg->orp);
2396 * Write the MODEND module end marker.
2398 orp->type = obj_use32 ? MODE32 : MODEND;
2399 orp->ori = ori_null;
2400 if (entry_seg_ptr) {
2401 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2402 obj_byte(orp, 0xC1);
2403 seg = entry_seg_ptr;
2404 if (seg->grp) {
2405 obj_byte(orp, 0x10);
2406 obj_index(orp, seg->grp->obj_index);
2407 } else {
2409 * the below changed to prevent TLINK crashing.
2410 * Previous more efficient version read:
2412 * obj_byte (orp, 0x50);
2414 obj_byte(orp, 0x00);
2415 obj_index(orp, seg->obj_index);
2417 obj_index(orp, seg->obj_index);
2418 obj_x(orp, obj_entry_ofs);
2419 } else
2420 obj_byte(orp, 0);
2421 obj_emit2(orp);
2422 nasm_free(orp);
2425 static void obj_fwrite(ObjRecord * orp)
2427 unsigned int cksum, len;
2428 uint8_t *ptr;
2430 cksum = orp->type;
2431 if (orp->x_size == 32)
2432 cksum |= 1;
2433 fputc(cksum, ofile);
2434 len = orp->committed + 1;
2435 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2436 fwriteint16_t(len, ofile);
2437 nasm_write(orp->buf, len-1, ofile);
2438 for (ptr = orp->buf; --len; ptr++)
2439 cksum += *ptr;
2440 fputc((-cksum) & 0xFF, ofile);
2443 extern macros_t obj_stdmac[];
2445 static void dbgbi_init(void)
2447 fnhead = NULL;
2448 fntail = &fnhead;
2449 arrindex = ARRAYBOT;
2450 arrhead = NULL;
2451 arrtail = &arrhead;
2453 static void dbgbi_cleanup(void)
2455 struct Segment *segtmp;
2456 while (fnhead) {
2457 struct FileName *fntemp = fnhead;
2458 while (fnhead->lnhead) {
2459 struct LineNumber *lntemp = fnhead->lnhead;
2460 fnhead->lnhead = lntemp->next;
2461 nasm_free(lntemp);
2463 fnhead = fnhead->next;
2464 nasm_free(fntemp->name);
2465 nasm_free(fntemp);
2467 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2468 while (segtmp->lochead) {
2469 struct Public *loctmp = segtmp->lochead;
2470 segtmp->lochead = loctmp->next;
2471 nasm_free(loctmp->name);
2472 nasm_free(loctmp);
2475 while (arrhead) {
2476 struct Array *arrtmp = arrhead;
2477 arrhead = arrhead->next;
2478 nasm_free(arrtmp);
2482 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2484 struct FileName *fn;
2485 struct LineNumber *ln;
2486 struct Segment *seg;
2488 if (segto == NO_SEG)
2489 return;
2492 * If `any_segs' is still false, we must define a default
2493 * segment.
2495 if (!any_segs) {
2496 int tempint; /* ignored */
2497 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2498 nasm_panic(0, "strange segment conditions in OBJ driver");
2502 * Find the segment we are targetting.
2504 for (seg = seghead; seg; seg = seg->next)
2505 if (seg->index == segto)
2506 break;
2507 if (!seg)
2508 nasm_panic(0, "lineno directed to nonexistent segment?");
2510 /* for (fn = fnhead; fn; fn = fnhead->next) */
2511 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2512 if (!nasm_stricmp(lnfname, fn->name))
2513 break;
2514 if (!fn) {
2515 fn = nasm_malloc(sizeof(*fn));
2516 fn->name = nasm_malloc(strlen(lnfname) + 1);
2517 strcpy(fn->name, lnfname);
2518 fn->lnhead = NULL;
2519 fn->lntail = &fn->lnhead;
2520 fn->next = NULL;
2521 *fntail = fn;
2522 fntail = &fn->next;
2524 ln = nasm_malloc(sizeof(*ln));
2525 ln->segment = seg;
2526 ln->offset = seg->currentpos;
2527 ln->lineno = lineno;
2528 ln->next = NULL;
2529 *fn->lntail = ln;
2530 fn->lntail = &ln->next;
2533 static void dbgbi_deflabel(char *name, int32_t segment,
2534 int64_t offset, int is_global, char *special)
2536 struct Segment *seg;
2538 (void)special;
2541 * Note: ..[^@] special symbols are filtered in labels.c
2545 * If it's a special-retry from pass two, discard it.
2547 if (is_global == 3)
2548 return;
2551 * Case (i):
2553 if (obj_seg_needs_update) {
2554 return;
2555 } else if (obj_grp_needs_update) {
2556 return;
2558 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2559 return;
2561 if (segment >= SEG_ABS || segment == NO_SEG) {
2562 return;
2566 * If `any_segs' is still false, we might need to define a
2567 * default segment, if they're trying to declare a label in
2568 * `first_seg'. But the label should exist due to a prior
2569 * call to obj_deflabel so we can skip that.
2572 for (seg = seghead; seg; seg = seg->next)
2573 if (seg->index == segment) {
2574 struct Public *loc = nasm_malloc(sizeof(*loc));
2576 * Case (ii). Maybe MODPUB someday?
2578 last_defined = *seg->loctail = loc;
2579 seg->loctail = &loc->next;
2580 loc->next = NULL;
2581 loc->name = nasm_strdup(name);
2582 loc->offset = offset;
2585 static void dbgbi_typevalue(int32_t type)
2587 int vsize;
2588 int elem = TYM_ELEMENTS(type);
2589 type = TYM_TYPE(type);
2591 if (!last_defined)
2592 return;
2594 switch (type) {
2595 case TY_BYTE:
2596 last_defined->type = 8; /* uint8_t */
2597 vsize = 1;
2598 break;
2599 case TY_WORD:
2600 last_defined->type = 10; /* unsigned word */
2601 vsize = 2;
2602 break;
2603 case TY_DWORD:
2604 last_defined->type = 12; /* unsigned dword */
2605 vsize = 4;
2606 break;
2607 case TY_FLOAT:
2608 last_defined->type = 14; /* float */
2609 vsize = 4;
2610 break;
2611 case TY_QWORD:
2612 last_defined->type = 15; /* qword */
2613 vsize = 8;
2614 break;
2615 case TY_TBYTE:
2616 last_defined->type = 16; /* TBYTE */
2617 vsize = 10;
2618 break;
2619 default:
2620 last_defined->type = 0x19; /*label */
2621 vsize = 0;
2622 break;
2625 if (elem > 1) {
2626 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2627 int vtype = last_defined->type;
2628 arrtmp->size = vsize * elem;
2629 arrtmp->basetype = vtype;
2630 arrtmp->next = NULL;
2631 last_defined->type = arrindex++;
2632 *arrtail = arrtmp;
2633 arrtail = &(arrtmp->next);
2635 last_defined = NULL;
2637 static void dbgbi_output(int output_type, void *param)
2639 (void)output_type;
2640 (void)param;
2642 static const struct dfmt borland_debug_form = {
2643 "Borland Debug Records",
2644 "borland",
2645 dbgbi_init,
2646 dbgbi_linnum,
2647 dbgbi_deflabel,
2648 null_debug_directive,
2649 dbgbi_typevalue,
2650 dbgbi_output,
2651 dbgbi_cleanup,
2654 static const struct dfmt * const borland_debug_arr[3] = {
2655 &borland_debug_form,
2656 &null_debug_form,
2657 NULL
2660 const struct ofmt of_obj = {
2661 "MS-DOS 16-bit/32-bit OMF object files",
2662 "obj",
2665 borland_debug_arr,
2666 &borland_debug_form,
2667 obj_stdmac,
2668 obj_init,
2669 obj_set_info,
2670 nasm_do_legacy_output,
2671 obj_out,
2672 obj_deflabel,
2673 obj_segment,
2674 obj_sectalign,
2675 obj_segbase,
2676 obj_directive,
2677 obj_filename,
2678 obj_cleanup
2680 #endif /* OF_OBJ */