test: nasm-t -- Add multisection
[nasm.git] / output / outobj.c
blobb766c54c55c0f00ea9ff2206bedfe6d25f3d1fd8
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2017 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 "error.h"
50 #include "stdscan.h"
51 #include "eval.h"
52 #include "ver.h"
54 #include "outform.h"
55 #include "outlib.h"
57 #ifdef OF_OBJ
60 * outobj.c is divided into two sections. The first section is low level
61 * routines for creating obj records; It has nearly zero NASM specific
62 * code. The second section is high level routines for processing calls and
63 * data structures from the rest of NASM into obj format.
65 * It should be easy (though not zero work) to lift the first section out for
66 * use as an obj file writer for some other assembler or compiler.
70 * These routines are built around the ObjRecord data struture. An ObjRecord
71 * holds an object file record that may be under construction or complete.
73 * A major function of these routines is to support continuation of an obj
74 * record into the next record when the maximum record size is exceeded. The
75 * high level code does not need to worry about where the record breaks occur.
76 * It does need to do some minor extra steps to make the automatic continuation
77 * work. Those steps may be skipped for records where the high level knows no
78 * continuation could be required.
80 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
81 * is cleared by obj_clear.
83 * 2) The caller should fill in .type.
85 * 3) If the record is continuable and there is processing that must be done at
86 * the start of each record then the caller should fill in .ori with the
87 * address of the record initializer routine.
89 * 4) If the record is continuable and it should be saved (rather than emitted
90 * immediately) as each record is done, the caller should set .up to be a
91 * pointer to a location in which the caller keeps the master pointer to the
92 * ObjRecord. When the record is continued, the obj_bump routine will then
93 * allocate a new ObjRecord structure and update the master pointer.
95 * 5) If the .ori field was used then the caller should fill in the .parm with
96 * any data required by the initializer.
98 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
99 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
100 * data required for this record.
102 * 7) If the record is continuable, the caller should call obj_commit at each
103 * point where breaking the record is permitted.
105 * 8) To write out the record, the caller should call obj_emit2. If the
106 * caller has called obj_commit for all data written then he can get slightly
107 * faster code by calling obj_emit instead of obj_emit2.
109 * Most of these routines return an ObjRecord pointer. This will be the input
110 * pointer most of the time and will be the new location if the ObjRecord
111 * moved as a result of the call. The caller may ignore the return value in
112 * three cases: It is a "Never Reallocates" routine; or The caller knows
113 * continuation is not possible; or The caller uses the master pointer for the
114 * next operation.
117 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
118 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
120 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
121 #define FIX_16_OFFSET 0x8400
122 #define FIX_16_SELECTOR 0x8800
123 #define FIX_32_POINTER 0x8C00
124 #define FIX_08_HIGH 0x9000
125 #define FIX_32_OFFSET 0xA400
126 #define FIX_48_POINTER 0xAC00
128 enum RecordID { /* record ID codes */
130 THEADR = 0x80, /* module header */
131 COMENT = 0x88, /* comment record */
133 LINNUM = 0x94, /* line number record */
134 LNAMES = 0x96, /* list of names */
136 SEGDEF = 0x98, /* segment definition */
137 GRPDEF = 0x9A, /* group definition */
138 EXTDEF = 0x8C, /* external definition */
139 PUBDEF = 0x90, /* public definition */
140 COMDEF = 0xB0, /* common definition */
142 LEDATA = 0xA0, /* logical enumerated data */
143 FIXUPP = 0x9C, /* fixups (relocations) */
144 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
146 MODEND = 0x8A, /* module end */
147 MODE32 = 0x8B /* module end for 32-bit objects */
150 enum ComentID { /* ID codes for comment records */
151 dTRANSL = 0x0000, /* translator comment */
152 dOMFEXT = 0xC0A0, /* "OMF extension" */
153 dEXTENDED = 0xC0A1, /* translator-specific extensions */
154 dLINKPASS = 0x40A2, /* link pass 2 marker */
155 dTYPEDEF = 0xC0E3, /* define a type */
156 dSYM = 0xC0E6, /* symbol debug record */
157 dFILNAME = 0xC0E8, /* file name record */
158 dDEPFILE = 0xC0E9, /* dependency file */
159 dCOMPDEF = 0xC0EA /* compiler type info */
162 typedef struct ObjRecord ObjRecord;
163 typedef void ORI(ObjRecord * orp);
165 struct ObjRecord {
166 ORI *ori; /* Initialization routine */
167 int used; /* Current data size */
168 int committed; /* Data size at last boundary */
169 int x_size; /* (see obj_x) */
170 unsigned int type; /* Record type */
171 ObjRecord *child; /* Associated record below this one */
172 ObjRecord **up; /* Master pointer to this ObjRecord */
173 ObjRecord *back; /* Previous part of this record */
174 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
175 uint8_t buf[RECORD_MAX + 3];
178 static void obj_fwrite(ObjRecord * orp);
179 static void ori_ledata(ObjRecord * orp);
180 static void ori_pubdef(ObjRecord * orp);
181 static void ori_null(ObjRecord * orp);
182 static ObjRecord *obj_commit(ObjRecord * orp);
184 static bool obj_uppercase; /* Flag: all names in uppercase */
185 static bool obj_use32; /* Flag: at least one segment is 32-bit */
186 static bool obj_nodepend; /* Flag: don't emit file dependencies */
189 * Clear an ObjRecord structure. (Never reallocates).
190 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
192 static ObjRecord *obj_clear(ObjRecord * orp)
194 orp->used = 0;
195 orp->committed = 0;
196 orp->x_size = 0;
197 orp->child = NULL;
198 orp->up = NULL;
199 orp->back = NULL;
200 return (orp);
204 * Emit an ObjRecord structure. (Never reallocates).
205 * The record is written out preceeded (recursively) by its previous part (if
206 * any) and followed (recursively) by its child (if any).
207 * The previous part and the child are freed. The main ObjRecord is cleared,
208 * not freed.
210 static ObjRecord *obj_emit(ObjRecord * orp)
212 if (orp->back) {
213 obj_emit(orp->back);
214 nasm_free(orp->back);
217 if (orp->committed)
218 obj_fwrite(orp);
220 if (orp->child) {
221 obj_emit(orp->child);
222 nasm_free(orp->child);
225 return (obj_clear(orp));
229 * Commit and Emit a record. (Never reallocates).
231 static ObjRecord *obj_emit2(ObjRecord * orp)
233 obj_commit(orp);
234 return (obj_emit(orp));
238 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
240 static ObjRecord *obj_new(void)
242 ObjRecord *orp;
244 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
245 orp->ori = ori_null;
246 return (orp);
250 * Advance to the next record because the existing one is full or its x_size
251 * is incompatible.
252 * Any uncommited data is moved into the next record.
254 static ObjRecord *obj_bump(ObjRecord * orp)
256 ObjRecord *nxt;
257 int used = orp->used;
258 int committed = orp->committed;
260 if (orp->up) {
261 *orp->up = nxt = obj_new();
262 nxt->ori = orp->ori;
263 nxt->type = orp->type;
264 nxt->up = orp->up;
265 nxt->back = orp;
266 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
267 } else
268 nxt = obj_emit(orp);
270 used -= committed;
271 if (used) {
272 nxt->committed = 1;
273 nxt->ori(nxt);
274 nxt->committed = nxt->used;
275 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
276 nxt->used = nxt->committed + used;
279 return (nxt);
283 * Advance to the next record if necessary to allow the next field to fit.
285 static ObjRecord *obj_check(ObjRecord * orp, int size)
287 if (orp->used + size > RECORD_MAX)
288 orp = obj_bump(orp);
290 if (!orp->committed) {
291 orp->committed = 1;
292 orp->ori(orp);
293 orp->committed = orp->used;
296 return (orp);
300 * All data written so far is commited to the current record (won't be moved to
301 * the next record in case of continuation).
303 static ObjRecord *obj_commit(ObjRecord * orp)
305 orp->committed = orp->used;
306 return (orp);
310 * Write a byte
312 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
314 orp = obj_check(orp, 1);
315 orp->buf[orp->used] = val;
316 orp->used++;
317 return (orp);
321 * Write a word
323 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
325 orp = obj_check(orp, 2);
326 orp->buf[orp->used] = val;
327 orp->buf[orp->used + 1] = val >> 8;
328 orp->used += 2;
329 return (orp);
333 * Write a reversed word
335 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
337 orp = obj_check(orp, 2);
338 orp->buf[orp->used] = val >> 8;
339 orp->buf[orp->used + 1] = val;
340 orp->used += 2;
341 return (orp);
345 * Write a dword
347 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
349 orp = obj_check(orp, 4);
350 orp->buf[orp->used] = val;
351 orp->buf[orp->used + 1] = val >> 8;
352 orp->buf[orp->used + 2] = val >> 16;
353 orp->buf[orp->used + 3] = val >> 24;
354 orp->used += 4;
355 return (orp);
359 * All fields of "size x" in one obj record must be the same size (either 16
360 * bits or 32 bits). There is a one bit flag in each record which specifies
361 * which.
362 * This routine is used to force the current record to have the desired
363 * x_size. x_size is normally automatic (using obj_x), so that this
364 * routine should be used outside obj_x, only to provide compatibility with
365 * linkers that have bugs in their processing of the size bit.
368 static ObjRecord *obj_force(ObjRecord * orp, int x)
370 if (orp->x_size == (x ^ 48))
371 orp = obj_bump(orp);
372 orp->x_size = x;
373 return (orp);
377 * This routine writes a field of size x. The caller does not need to worry at
378 * all about whether 16-bits or 32-bits are required.
380 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
382 if (orp->type & 1)
383 orp->x_size = 32;
384 if (val > 0xFFFF)
385 orp = obj_force(orp, 32);
386 if (orp->x_size == 32) {
387 ObjRecord *nxt = obj_dword(orp, val);
388 nxt->x_size = 32; /* x_size is cleared when a record overflows */
389 return nxt;
391 orp->x_size = 16;
392 return (obj_word(orp, val));
396 * Writes an index
398 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
400 if (val < 128)
401 return (obj_byte(orp, val));
402 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
406 * Writes a variable length value
408 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
410 if (val <= 128)
411 return (obj_byte(orp, val));
412 if (val <= 0xFFFF) {
413 orp = obj_byte(orp, 129);
414 return (obj_word(orp, val));
416 if (val <= 0xFFFFFF)
417 return (obj_dword(orp, (val << 8) + 132));
418 orp = obj_byte(orp, 136);
419 return (obj_dword(orp, val));
423 * Writes a counted string
425 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
427 int len = strlen(name);
428 uint8_t *ptr;
430 orp = obj_check(orp, len + 1);
431 ptr = orp->buf + orp->used;
432 *ptr++ = len;
433 orp->used += len + 1;
434 if (obj_uppercase)
435 while (--len >= 0) {
436 *ptr++ = toupper(*name);
437 name++;
438 } else
439 memcpy(ptr, name, len);
440 return (orp);
444 * Initializer for an LEDATA record.
445 * parm[0] = offset
446 * parm[1] = segment index
447 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
448 * represent the offset that would be required if the record were split at the
449 * last commit point.
450 * parm[2] is a copy of parm[0] as it was when the current record was initted.
452 static void ori_ledata(ObjRecord * orp)
454 obj_index(orp, orp->parm[1]);
455 orp->parm[2] = orp->parm[0];
456 obj_x(orp, orp->parm[0]);
460 * Initializer for a PUBDEF record.
461 * parm[0] = group index
462 * parm[1] = segment index
463 * parm[2] = frame (only used when both indexes are zero)
465 static void ori_pubdef(ObjRecord * orp)
467 obj_index(orp, orp->parm[0]);
468 obj_index(orp, orp->parm[1]);
469 if (!(orp->parm[0] | orp->parm[1]))
470 obj_word(orp, orp->parm[2]);
474 * Initializer for a LINNUM record.
475 * parm[0] = group index
476 * parm[1] = segment index
478 static void ori_linnum(ObjRecord * orp)
480 obj_index(orp, orp->parm[0]);
481 obj_index(orp, orp->parm[1]);
485 * Initializer for a local vars record.
487 static void ori_local(ObjRecord * orp)
489 obj_rword(orp, dSYM);
493 * Null initializer for records that continue without any header info
495 static void ori_null(ObjRecord * orp)
497 (void)orp; /* Do nothing */
501 * This concludes the low level section of outobj.c
504 static char obj_infile[FILENAME_MAX];
506 static int32_t first_seg;
507 static bool any_segs;
508 static int passtwo;
509 static int arrindex;
511 #define GROUP_MAX 256 /* we won't _realistically_ have more
512 * than this many segs in a group */
513 #define EXT_BLKSIZ 256 /* block size for externals list */
515 struct Segment; /* need to know these structs exist */
516 struct Group;
518 struct LineNumber {
519 struct LineNumber *next;
520 struct Segment *segment;
521 int32_t offset;
522 int32_t lineno;
525 static struct FileName {
526 struct FileName *next;
527 char *name;
528 struct LineNumber *lnhead, **lntail;
529 int index;
530 } *fnhead, **fntail;
532 static struct Array {
533 struct Array *next;
534 unsigned size;
535 int basetype;
536 } *arrhead, **arrtail;
538 #define ARRAYBOT 31 /* magic number for first array index */
540 static struct Public {
541 struct Public *next;
542 char *name;
543 int32_t offset;
544 int32_t segment; /* only if it's far-absolute */
545 int type; /* only for local debug syms */
546 } *fpubhead, **fpubtail, *last_defined;
548 static struct External {
549 struct External *next;
550 char *name;
551 int32_t commonsize;
552 int32_t commonelem; /* element size if FAR, else zero */
553 int index; /* OBJ-file external index */
554 enum {
555 DEFWRT_NONE, /* no unusual default-WRT */
556 DEFWRT_STRING, /* a string we don't yet understand */
557 DEFWRT_SEGMENT, /* a segment */
558 DEFWRT_GROUP /* a group */
559 } defwrt_type;
560 union {
561 char *string;
562 struct Segment *seg;
563 struct Group *grp;
564 } defwrt_ptr;
565 struct External *next_dws; /* next with DEFWRT_STRING */
566 } *exthead, **exttail, *dws;
568 static int externals;
570 static struct ExtBack {
571 struct ExtBack *next;
572 struct External *exts[EXT_BLKSIZ];
573 } *ebhead, **ebtail;
575 static struct Segment {
576 struct Segment *next;
577 char *name;
578 int32_t index; /* the NASM segment id */
579 int32_t obj_index; /* the OBJ-file segment index */
580 struct Group *grp; /* the group it beint32_ts to */
581 uint32_t currentpos;
582 int32_t align; /* can be SEG_ABS + absolute addr */
583 struct Public *pubhead, **pubtail, *lochead, **loctail;
584 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
585 ObjRecord *orp;
586 enum {
587 CMB_PRIVATE = 0,
588 CMB_PUBLIC = 2,
589 CMB_STACK = 5,
590 CMB_COMMON = 6
591 } combine;
592 bool use32; /* is this segment 32-bit? */
593 } *seghead, **segtail, *obj_seg_needs_update;
595 static struct Group {
596 struct Group *next;
597 char *name;
598 int32_t index; /* NASM segment id */
599 int32_t obj_index; /* OBJ-file group index */
600 int32_t nentries; /* number of elements... */
601 int32_t nindices; /* ...and number of index elts... */
602 union {
603 int32_t index;
604 char *name;
605 } segs[GROUP_MAX]; /* ...in this */
606 } *grphead, **grptail, *obj_grp_needs_update;
608 static struct ImpDef {
609 struct ImpDef *next;
610 char *extname;
611 char *libname;
612 unsigned int impindex;
613 char *impname;
614 } *imphead, **imptail;
616 static struct ExpDef {
617 struct ExpDef *next;
618 char *intname;
619 char *extname;
620 unsigned int ordinal;
621 int flags;
622 } *exphead, **exptail;
624 #define EXPDEF_FLAG_ORDINAL 0x80
625 #define EXPDEF_FLAG_RESIDENT 0x40
626 #define EXPDEF_FLAG_NODATA 0x20
627 #define EXPDEF_MASK_PARMCNT 0x1F
629 static int32_t obj_entry_seg, obj_entry_ofs;
631 const struct ofmt of_obj;
632 static const struct dfmt borland_debug_form;
634 /* The current segment */
635 static struct Segment *current_seg;
637 static int32_t obj_segment(char *, int, int *);
638 static void obj_write_file(void);
639 static enum directive_result obj_directive(enum directive, char *, int);
641 static void obj_init(void)
643 strlcpy(obj_infile, inname, sizeof(obj_infile));
644 first_seg = seg_alloc();
645 any_segs = false;
646 fpubhead = NULL;
647 fpubtail = &fpubhead;
648 exthead = NULL;
649 exttail = &exthead;
650 imphead = NULL;
651 imptail = &imphead;
652 exphead = NULL;
653 exptail = &exphead;
654 dws = NULL;
655 externals = 0;
656 ebhead = NULL;
657 ebtail = &ebhead;
658 seghead = obj_seg_needs_update = NULL;
659 segtail = &seghead;
660 grphead = obj_grp_needs_update = NULL;
661 grptail = &grphead;
662 obj_entry_seg = NO_SEG;
663 obj_uppercase = false;
664 obj_use32 = false;
665 passtwo = 0;
666 current_seg = NULL;
669 static void obj_cleanup(void)
671 obj_write_file();
672 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_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, 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_zalloc(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_zalloc(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 * If `any_segs' is still false, we must define a default
1033 * segment.
1035 if (!any_segs) {
1036 int tempint; /* ignored */
1037 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1038 nasm_panic("strange segment conditions in OBJ driver");
1042 * Find the segment we are targetting.
1044 for (seg = seghead; seg; seg = seg->next)
1045 if (seg->index == segto)
1046 break;
1047 if (!seg)
1048 nasm_panic("code directed to nonexistent segment?");
1050 orp = seg->orp;
1051 orp->parm[0] = seg->currentpos;
1053 switch (type) {
1054 case OUT_RAWDATA:
1055 ucdata = data;
1056 while (size > 0) {
1057 unsigned int len;
1058 orp = obj_check(seg->orp, 1);
1059 len = RECORD_MAX - orp->used;
1060 if (len > size)
1061 len = size;
1062 memcpy(orp->buf + orp->used, ucdata, len);
1063 orp->committed = orp->used += len;
1064 orp->parm[0] = seg->currentpos += len;
1065 ucdata += len;
1066 size -= len;
1068 break;
1070 case OUT_ADDRESS:
1071 case OUT_REL1ADR:
1072 case OUT_REL2ADR:
1073 case OUT_REL4ADR:
1074 case OUT_REL8ADR:
1076 int rsize;
1078 if (type == OUT_ADDRESS)
1079 size = abs((int)size);
1081 if (segment == NO_SEG && type != OUT_ADDRESS)
1082 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1083 " supported by OBJ format");
1084 if (segment >= SEG_ABS)
1085 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1086 " by OBJ format");
1088 ldata = *(int64_t *)data;
1089 if (type != OUT_ADDRESS) {
1091 * For 16-bit and 32-bit x86 code, the size and realsize() always
1092 * matches as only jumps, calls and loops uses PC relative
1093 * addressing and the address isn't followed by any other opcode
1094 * bytes. In 64-bit mode there is RIP relative addressing which
1095 * means the fixup location can be followed by an immediate value,
1096 * meaning that size > realsize().
1098 * When the CPU is calculating the effective address, it takes the
1099 * RIP at the end of the instruction and adds the fixed up relative
1100 * address value to it.
1102 * The linker's point of reference is the end of the fixup location
1103 * (which is the end of the instruction for Jcc, CALL, LOOP[cc]).
1104 * It is calculating distance between the target symbol and the end
1105 * of the fixup location, and add this to the displacement value we
1106 * are calculating here and storing at the fixup location.
1108 * To get the right effect, we need to _reduce_ the displacement
1109 * value by the number of bytes following the fixup.
1111 * Example:
1112 * data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
1113 * end of fixup at 0x054, end of instruction at 0x058.
1114 * => size = 8.
1115 * => realsize() -> 4
1116 * => CPU needs a value of: 0x100 - 0x058 = 0x0a8
1117 * => linker/loader will add: 0x100 - 0x054 = 0x0ac
1118 * => We must add an addend of -4.
1119 * => realsize() - size = -4.
1121 * The code used to do size - realsize() at least since v0.90,
1122 * probably because it wasn't needed...
1124 ldata -= size;
1125 size = realsize(type, size);
1126 ldata += size;
1129 switch (size) {
1130 default:
1131 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1132 "32-byte relocations");
1133 segment = NO_SEG; /* Don't actually generate a relocation */
1134 break;
1135 case 2:
1136 orp = obj_word(orp, ldata);
1137 break;
1138 case 4:
1139 orp = obj_dword(orp, ldata);
1140 break;
1143 rsize = size;
1144 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1145 size == 4) {
1147 * This is a 4-byte segment-base relocation such as
1148 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1149 * these, but if the constant term has the 16 low bits
1150 * zero, we can just apply a 2-byte segment-base
1151 * relocation to the low word instead.
1153 rsize = 2;
1154 if (ldata & 0xFFFF)
1155 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1156 " dword-size segment base references");
1158 if (segment != NO_SEG)
1159 obj_write_fixup(orp, rsize,
1160 (type == OUT_ADDRESS ? 0x4000 : 0),
1161 segment, wrt, seg);
1162 seg->currentpos += size;
1163 break;
1166 default:
1167 nasm_error(ERR_NONFATAL,
1168 "Relocation type not supported by output format");
1169 /* fall through */
1171 case OUT_RESERVE:
1172 if (orp->committed)
1173 orp = obj_bump(orp);
1174 seg->currentpos += size;
1175 break;
1177 obj_commit(orp);
1180 static void obj_write_fixup(ObjRecord * orp, int bytes,
1181 int segrel, int32_t seg, int32_t wrt,
1182 struct Segment *segto)
1184 unsigned locat;
1185 int method;
1186 int base;
1187 int32_t tidx, fidx;
1188 struct Segment *s = NULL;
1189 struct Group *g = NULL;
1190 struct External *e = NULL;
1191 ObjRecord *forp;
1193 if (bytes != 2 && bytes != 4) {
1194 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1195 " %d-bit relocations", bytes << 3);
1196 return;
1199 forp = orp->child;
1200 if (forp == NULL) {
1201 orp->child = forp = obj_new();
1202 forp->up = &(orp->child);
1203 /* We should choose between FIXUPP and FIXU32 record type */
1204 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1205 if (segto->use32)
1206 forp->type = FIXU32;
1207 else
1208 forp->type = FIXUPP;
1211 if (seg % 2) {
1212 base = true;
1213 locat = FIX_16_SELECTOR;
1214 seg--;
1215 if (bytes != 2)
1216 nasm_panic("OBJ: 4-byte segment base fixup got"
1217 " through sanity check");
1218 } else {
1219 base = false;
1220 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1221 if (!segrel)
1223 * There is a bug in tlink that makes it process self relative
1224 * fixups incorrectly if the x_size doesn't match the location
1225 * size.
1227 forp = obj_force(forp, bytes << 3);
1230 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1232 tidx = fidx = -1, method = 0; /* placate optimisers */
1235 * See if we can find the segment ID in our segment list. If
1236 * so, we have a T4 (LSEG) target.
1238 for (s = seghead; s; s = s->next)
1239 if (s->index == seg)
1240 break;
1241 if (s)
1242 method = 4, tidx = s->obj_index;
1243 else {
1244 for (g = grphead; g; g = g->next)
1245 if (g->index == seg)
1246 break;
1247 if (g)
1248 method = 5, tidx = g->obj_index;
1249 else {
1250 int32_t i = seg / 2;
1251 struct ExtBack *eb = ebhead;
1252 while (i >= EXT_BLKSIZ) {
1253 if (eb)
1254 eb = eb->next;
1255 else
1256 break;
1257 i -= EXT_BLKSIZ;
1259 if (eb)
1260 method = 6, e = eb->exts[i], tidx = e->index;
1261 else
1262 nasm_panic("unrecognised segment value in obj_write_fixup");
1267 * If no WRT given, assume the natural default, which is method
1268 * F5 unless:
1270 * - we are doing an OFFSET fixup for a grouped segment, in
1271 * which case we require F1 (group).
1273 * - we are doing an OFFSET fixup for an external with a
1274 * default WRT, in which case we must honour the default WRT.
1276 if (wrt == NO_SEG) {
1277 if (!base && s && s->grp)
1278 method |= 0x10, fidx = s->grp->obj_index;
1279 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1280 if (e->defwrt_type == DEFWRT_SEGMENT)
1281 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1282 else if (e->defwrt_type == DEFWRT_GROUP)
1283 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1284 else {
1285 nasm_error(ERR_NONFATAL, "default WRT specification for"
1286 " external `%s' unresolved", e->name);
1287 method |= 0x50, fidx = -1; /* got to do _something_ */
1289 } else
1290 method |= 0x50, fidx = -1;
1291 } else {
1293 * See if we can find the WRT-segment ID in our segment
1294 * list. If so, we have a F0 (LSEG) frame.
1296 for (s = seghead; s; s = s->next)
1297 if (s->index == wrt - 1)
1298 break;
1299 if (s)
1300 method |= 0x00, fidx = s->obj_index;
1301 else {
1302 for (g = grphead; g; g = g->next)
1303 if (g->index == wrt - 1)
1304 break;
1305 if (g)
1306 method |= 0x10, fidx = g->obj_index;
1307 else {
1308 int32_t i = wrt / 2;
1309 struct ExtBack *eb = ebhead;
1310 while (i >= EXT_BLKSIZ) {
1311 if (eb)
1312 eb = eb->next;
1313 else
1314 break;
1315 i -= EXT_BLKSIZ;
1317 if (eb)
1318 method |= 0x20, fidx = eb->exts[i]->index;
1319 else
1320 nasm_panic("unrecognised WRT value in obj_write_fixup");
1325 forp = obj_byte(forp, method);
1326 if (fidx != -1)
1327 forp = obj_index(forp, fidx);
1328 forp = obj_index(forp, tidx);
1329 obj_commit(forp);
1332 static int32_t obj_segment(char *name, int pass, int *bits)
1335 * We call the label manager here to define a name for the new
1336 * segment, and when our _own_ label-definition stub gets
1337 * called in return, it should register the new segment name
1338 * using the pointer it gets passed. That way we save memory,
1339 * by sponging off the label manager.
1341 #if defined(DEBUG) && DEBUG>=3
1342 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1343 name, pass, *bits);
1344 #endif
1345 if (!name) {
1346 *bits = 16;
1347 current_seg = NULL;
1348 return first_seg;
1349 } else {
1350 struct Segment *seg;
1351 struct Group *grp;
1352 struct External **extp;
1353 int obj_idx, i, attrs;
1354 bool rn_error;
1355 char *p;
1358 * Look for segment attributes.
1360 attrs = 0;
1361 while (*name == '.')
1362 name++; /* hack, but a documented one */
1363 p = name;
1364 while (*p && !nasm_isspace(*p))
1365 p++;
1366 if (*p) {
1367 *p++ = '\0';
1368 while (*p && nasm_isspace(*p))
1369 *p++ = '\0';
1371 while (*p) {
1372 while (*p && !nasm_isspace(*p))
1373 p++;
1374 if (*p) {
1375 *p++ = '\0';
1376 while (*p && nasm_isspace(*p))
1377 *p++ = '\0';
1380 attrs++;
1383 for (seg = seghead, obj_idx = 1; ; seg = seg->next, obj_idx++) {
1384 if (!seg)
1385 break;
1387 if (!strcmp(seg->name, name)) {
1388 if (attrs > 0 && pass == 1)
1389 nasm_error(ERR_WARNING, "segment attributes specified on"
1390 " redeclaration of segment: ignoring");
1391 if (seg->use32)
1392 *bits = 32;
1393 else
1394 *bits = 16;
1395 current_seg = seg;
1396 return seg->index;
1400 *segtail = seg = nasm_malloc(sizeof(*seg));
1401 seg->next = NULL;
1402 segtail = &seg->next;
1403 seg->index = (any_segs ? seg_alloc() : first_seg);
1404 seg->obj_index = obj_idx;
1405 seg->grp = NULL;
1406 any_segs = true;
1407 seg->name = nasm_strdup(name);
1408 seg->currentpos = 0;
1409 seg->align = 1; /* default */
1410 seg->use32 = false; /* default */
1411 seg->combine = CMB_PUBLIC; /* default */
1412 seg->segclass = seg->overlay = NULL;
1413 seg->pubhead = NULL;
1414 seg->pubtail = &seg->pubhead;
1415 seg->lochead = NULL;
1416 seg->loctail = &seg->lochead;
1417 seg->orp = obj_new();
1418 seg->orp->up = &(seg->orp);
1419 seg->orp->ori = ori_ledata;
1420 seg->orp->type = LEDATA;
1421 seg->orp->parm[1] = obj_idx;
1424 * Process the segment attributes.
1426 p = name;
1427 while (attrs--) {
1428 p += strlen(p);
1429 while (!*p)
1430 p++;
1433 * `p' contains a segment attribute.
1435 if (!nasm_stricmp(p, "private"))
1436 seg->combine = CMB_PRIVATE;
1437 else if (!nasm_stricmp(p, "public"))
1438 seg->combine = CMB_PUBLIC;
1439 else if (!nasm_stricmp(p, "common"))
1440 seg->combine = CMB_COMMON;
1441 else if (!nasm_stricmp(p, "stack"))
1442 seg->combine = CMB_STACK;
1443 else if (!nasm_stricmp(p, "use16"))
1444 seg->use32 = false;
1445 else if (!nasm_stricmp(p, "use32"))
1446 seg->use32 = true;
1447 else if (!nasm_stricmp(p, "flat")) {
1449 * This segment is an OS/2 FLAT segment. That means
1450 * that its default group is group FLAT, even if
1451 * the group FLAT does not explicitly _contain_ the
1452 * segment.
1454 * When we see this, we must create the group
1455 * `FLAT', containing no segments, if it does not
1456 * already exist; then we must set the default
1457 * group of this segment to be the FLAT group.
1459 struct Group *grp;
1460 for (grp = grphead; grp; grp = grp->next)
1461 if (!strcmp(grp->name, "FLAT"))
1462 break;
1463 if (!grp) {
1464 obj_directive(D_GROUP, "FLAT", 1);
1465 for (grp = grphead; grp; grp = grp->next)
1466 if (!strcmp(grp->name, "FLAT"))
1467 break;
1468 if (!grp)
1469 nasm_panic("failure to define FLAT?!");
1471 seg->grp = grp;
1472 } else if (!nasm_strnicmp(p, "class=", 6))
1473 seg->segclass = nasm_strdup(p + 6);
1474 else if (!nasm_strnicmp(p, "overlay=", 8))
1475 seg->overlay = nasm_strdup(p + 8);
1476 else if (!nasm_strnicmp(p, "align=", 6)) {
1477 seg->align = readnum(p + 6, &rn_error);
1478 if (rn_error) {
1479 seg->align = 1;
1480 nasm_error(ERR_NONFATAL, "segment alignment should be"
1481 " numeric");
1483 switch (seg->align) {
1484 case 1: /* BYTE */
1485 case 2: /* WORD */
1486 case 4: /* DWORD */
1487 case 16: /* PARA */
1488 case 256: /* PAGE */
1489 case 4096: /* PharLap extension */
1490 break;
1491 case 8:
1492 nasm_error(ERR_WARNING,
1493 "OBJ format does not support alignment"
1494 " of 8: rounding up to 16");
1495 seg->align = 16;
1496 break;
1497 case 32:
1498 case 64:
1499 case 128:
1500 nasm_error(ERR_WARNING,
1501 "OBJ format does not support alignment"
1502 " of %d: rounding up to 256", seg->align);
1503 seg->align = 256;
1504 break;
1505 case 512:
1506 case 1024:
1507 case 2048:
1508 nasm_error(ERR_WARNING,
1509 "OBJ format does not support alignment"
1510 " of %d: rounding up to 4096", seg->align);
1511 seg->align = 4096;
1512 break;
1513 default:
1514 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1515 seg->align);
1516 seg->align = 1;
1517 break;
1519 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1520 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1521 if (rn_error)
1522 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1523 " attribute should be numeric");
1527 /* We need to know whenever we have at least one 32-bit segment */
1528 obj_use32 |= seg->use32;
1530 obj_seg_needs_update = seg;
1531 if (seg->align >= SEG_ABS)
1532 define_label(name, NO_SEG, seg->align - SEG_ABS, false);
1533 else
1534 define_label(name, seg->index + 1, 0L, false);
1535 obj_seg_needs_update = NULL;
1538 * See if this segment is defined in any groups.
1540 for (grp = grphead; grp; grp = grp->next) {
1541 for (i = grp->nindices; i < grp->nentries; i++) {
1542 if (!strcmp(grp->segs[i].name, seg->name)) {
1543 nasm_free(grp->segs[i].name);
1544 grp->segs[i] = grp->segs[grp->nindices];
1545 grp->segs[grp->nindices++].index = seg->obj_index;
1546 if (seg->grp)
1547 nasm_error(ERR_WARNING,
1548 "segment `%s' is already part of"
1549 " a group: first one takes precedence",
1550 seg->name);
1551 else
1552 seg->grp = grp;
1558 * Walk through the list of externals with unresolved
1559 * default-WRT clauses, and resolve any that point at this
1560 * segment.
1562 extp = &dws;
1563 while (*extp) {
1564 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1565 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1566 nasm_free((*extp)->defwrt_ptr.string);
1567 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1568 (*extp)->defwrt_ptr.seg = seg;
1569 *extp = (*extp)->next_dws;
1570 } else
1571 extp = &(*extp)->next_dws;
1574 if (seg->use32)
1575 *bits = 32;
1576 else
1577 *bits = 16;
1578 current_seg = seg;
1579 return seg->index;
1583 static enum directive_result
1584 obj_directive(enum directive directive, char *value, int pass)
1586 switch (directive) {
1587 case D_GROUP:
1589 char *p, *q, *v;
1590 if (pass == 1) {
1591 struct Group *grp;
1592 struct Segment *seg;
1593 struct External **extp;
1594 int obj_idx;
1596 q = value;
1597 while (*q == '.')
1598 q++; /* hack, but a documented one */
1599 v = q;
1600 while (*q && !nasm_isspace(*q))
1601 q++;
1602 if (nasm_isspace(*q)) {
1603 *q++ = '\0';
1604 while (*q && nasm_isspace(*q))
1605 q++;
1608 * Here we used to sanity-check the group directive to
1609 * ensure nobody tried to declare a group containing no
1610 * segments. However, OS/2 does this as standard
1611 * practice, so the sanity check has been removed.
1613 * if (!*q) {
1614 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1615 * return DIRR_ERROR;
1619 obj_idx = 1;
1620 for (grp = grphead; grp; grp = grp->next) {
1621 obj_idx++;
1622 if (!strcmp(grp->name, v)) {
1623 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1624 return DIRR_ERROR;
1628 *grptail = grp = nasm_malloc(sizeof(*grp));
1629 grp->next = NULL;
1630 grptail = &grp->next;
1631 grp->index = seg_alloc();
1632 grp->obj_index = obj_idx;
1633 grp->nindices = grp->nentries = 0;
1634 grp->name = NULL;
1636 obj_grp_needs_update = grp;
1637 backend_label(v, grp->index + 1, 0L);
1638 obj_grp_needs_update = NULL;
1640 while (*q) {
1641 p = q;
1642 while (*q && !nasm_isspace(*q))
1643 q++;
1644 if (nasm_isspace(*q)) {
1645 *q++ = '\0';
1646 while (*q && nasm_isspace(*q))
1647 q++;
1650 * Now p contains a segment name. Find it.
1652 for (seg = seghead; seg; seg = seg->next)
1653 if (!strcmp(seg->name, p))
1654 break;
1655 if (seg) {
1657 * We have a segment index. Shift a name entry
1658 * to the end of the array to make room.
1660 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1661 grp->segs[grp->nindices++].index = seg->obj_index;
1662 if (seg->grp)
1663 nasm_error(ERR_WARNING,
1664 "segment `%s' is already part of"
1665 " a group: first one takes precedence",
1666 seg->name);
1667 else
1668 seg->grp = grp;
1669 } else {
1671 * We have an as-yet undefined segment.
1672 * Remember its name, for later.
1674 grp->segs[grp->nentries++].name = nasm_strdup(p);
1679 * Walk through the list of externals with unresolved
1680 * default-WRT clauses, and resolve any that point at
1681 * this group.
1683 extp = &dws;
1684 while (*extp) {
1685 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1686 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1687 nasm_free((*extp)->defwrt_ptr.string);
1688 (*extp)->defwrt_type = DEFWRT_GROUP;
1689 (*extp)->defwrt_ptr.grp = grp;
1690 *extp = (*extp)->next_dws;
1691 } else
1692 extp = &(*extp)->next_dws;
1695 return DIRR_OK;
1697 case D_UPPERCASE:
1698 obj_uppercase = true;
1699 return DIRR_OK;
1701 case D_IMPORT:
1703 char *q, *extname, *libname, *impname;
1705 if (pass == 2)
1706 return 1; /* ignore in pass two */
1707 extname = q = value;
1708 while (*q && !nasm_isspace(*q))
1709 q++;
1710 if (nasm_isspace(*q)) {
1711 *q++ = '\0';
1712 while (*q && nasm_isspace(*q))
1713 q++;
1716 libname = q;
1717 while (*q && !nasm_isspace(*q))
1718 q++;
1719 if (nasm_isspace(*q)) {
1720 *q++ = '\0';
1721 while (*q && nasm_isspace(*q))
1722 q++;
1725 impname = q;
1727 if (!*extname || !*libname)
1728 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1729 " and library name");
1730 else {
1731 struct ImpDef *imp;
1732 bool err = false;
1734 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1735 imptail = &imp->next;
1736 imp->next = NULL;
1737 imp->extname = nasm_strdup(extname);
1738 imp->libname = nasm_strdup(libname);
1739 imp->impindex = readnum(impname, &err);
1740 if (!*impname || err)
1741 imp->impname = nasm_strdup(impname);
1742 else
1743 imp->impname = NULL;
1746 return DIRR_OK;
1748 case D_EXPORT:
1750 char *q, *extname, *intname, *v;
1751 struct ExpDef *export;
1752 int flags = 0;
1753 unsigned int ordinal = 0;
1755 if (pass == 2)
1756 return DIRR_OK; /* ignore in pass two */
1757 intname = q = value;
1758 while (*q && !nasm_isspace(*q))
1759 q++;
1760 if (nasm_isspace(*q)) {
1761 *q++ = '\0';
1762 while (*q && nasm_isspace(*q))
1763 q++;
1766 extname = q;
1767 while (*q && !nasm_isspace(*q))
1768 q++;
1769 if (nasm_isspace(*q)) {
1770 *q++ = '\0';
1771 while (*q && nasm_isspace(*q))
1772 q++;
1775 if (!*intname) {
1776 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1777 return DIRR_OK;
1779 if (!*extname) {
1780 extname = intname;
1781 intname = "";
1783 while (*q) {
1784 v = q;
1785 while (*q && !nasm_isspace(*q))
1786 q++;
1787 if (nasm_isspace(*q)) {
1788 *q++ = '\0';
1789 while (*q && nasm_isspace(*q))
1790 q++;
1792 if (!nasm_stricmp(v, "resident"))
1793 flags |= EXPDEF_FLAG_RESIDENT;
1794 else if (!nasm_stricmp(v, "nodata"))
1795 flags |= EXPDEF_FLAG_NODATA;
1796 else if (!nasm_strnicmp(v, "parm=", 5)) {
1797 bool err = false;
1798 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1799 if (err) {
1800 nasm_error(ERR_NONFATAL,
1801 "value `%s' for `parm' is non-numeric", v + 5);
1802 return DIRR_ERROR;
1804 } else {
1805 bool err = false;
1806 ordinal = readnum(v, &err);
1807 if (err) {
1808 nasm_error(ERR_NONFATAL,
1809 "unrecognised export qualifier `%s'", v);
1810 return DIRR_ERROR;
1812 flags |= EXPDEF_FLAG_ORDINAL;
1816 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1817 exptail = &export->next;
1818 export->next = NULL;
1819 export->extname = nasm_strdup(extname);
1820 export->intname = nasm_strdup(intname);
1821 export->ordinal = ordinal;
1822 export->flags = flags;
1824 return DIRR_OK;
1826 default:
1827 return DIRR_UNKNOWN;
1831 static void obj_sectalign(int32_t seg, unsigned int value)
1833 struct Segment *s;
1835 list_for_each(s, seghead) {
1836 if (s->index == seg)
1837 break;
1841 * it should not be too big value
1842 * and applied on non-absolute sections
1844 if (!s || !is_power2(value) ||
1845 value > 4096 || s->align >= SEG_ABS)
1846 return;
1849 * FIXME: No code duplication please
1850 * consider making helper for this
1851 * mapping since section handler has
1852 * to do the same
1854 switch (value) {
1855 case 8:
1856 value = 16;
1857 break;
1858 case 32:
1859 case 64:
1860 case 128:
1861 value = 256;
1862 break;
1863 case 512:
1864 case 1024:
1865 case 2048:
1866 value = 4096;
1867 break;
1870 if (s->align < (int)value)
1871 s->align = value;
1874 static int32_t obj_segbase(int32_t segment)
1876 struct Segment *seg;
1879 * Find the segment in our list.
1881 for (seg = seghead; seg; seg = seg->next)
1882 if (seg->index == segment - 1)
1883 break;
1885 if (!seg) {
1887 * Might be an external with a default WRT.
1889 int32_t i = segment / 2;
1890 struct ExtBack *eb = ebhead;
1891 struct External *e;
1893 while (i >= EXT_BLKSIZ) {
1894 if (eb)
1895 eb = eb->next;
1896 else
1897 break;
1898 i -= EXT_BLKSIZ;
1900 if (eb) {
1901 e = eb->exts[i];
1902 if (!e) {
1903 nasm_assert(pass0 == 0);
1904 /* Not available - can happen during optimization */
1905 return NO_SEG;
1908 switch (e->defwrt_type) {
1909 case DEFWRT_NONE:
1910 return segment; /* fine */
1911 case DEFWRT_SEGMENT:
1912 return e->defwrt_ptr.seg->index + 1;
1913 case DEFWRT_GROUP:
1914 return e->defwrt_ptr.grp->index + 1;
1915 default:
1916 return NO_SEG; /* can't tell what it is */
1920 return segment; /* not one of ours - leave it alone */
1923 if (seg->align >= SEG_ABS)
1924 return seg->align; /* absolute segment */
1925 if (seg->grp)
1926 return seg->grp->index + 1; /* grouped segment */
1928 return segment; /* no special treatment */
1931 /* Get a file timestamp in MS-DOS format */
1932 static uint32_t obj_file_timestamp(const char *pathname)
1934 time_t t;
1935 const struct tm *lt;
1937 if (!nasm_file_time(&t, pathname))
1938 return 0;
1940 lt = localtime(&t);
1941 if (!lt)
1942 return 0;
1944 if (lt->tm_year < 80 || lt->tm_year > 207)
1945 return 0; /* Only years 1980-2107 representable */
1947 return
1948 ((uint32_t)lt->tm_sec >> 1) +
1949 ((uint32_t)lt->tm_min << 5) +
1950 ((uint32_t)lt->tm_hour << 11) +
1951 ((uint32_t)lt->tm_mday << 16) +
1952 (((uint32_t)lt->tm_mon + 1) << 21) +
1953 (((uint32_t)lt->tm_year - 80) << 25);
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 struct strlist_entry *depfile;
1969 const bool debuginfo = (dfmt == &borland_debug_form);
1972 * Write the THEADR module header.
1974 orp = obj_new();
1975 orp->type = THEADR;
1976 obj_name(orp, obj_infile);
1977 obj_emit2(orp);
1980 * Write the NASM boast comment.
1982 orp->type = COMENT;
1983 obj_rword(orp, dTRANSL);
1984 obj_name(orp, nasm_comment);
1985 obj_emit2(orp);
1988 * Output file dependency information
1990 if (!obj_nodepend && depend_list) {
1991 list_for_each(depfile, depend_list->head) {
1992 uint32_t ts;
1994 ts = obj_file_timestamp(depfile->str);
1995 if (ts) {
1996 orp->type = COMENT;
1997 obj_rword(orp, dDEPFILE);
1998 obj_dword(orp, ts);
1999 obj_name(orp, depfile->str);
2000 obj_emit2(orp);
2005 orp->type = COMENT;
2007 * Write the IMPDEF records, if any.
2009 for (imp = imphead; imp; imp = imp->next) {
2010 obj_rword(orp, dOMFEXT);
2011 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
2012 if (imp->impname)
2013 obj_byte(orp, 0); /* import by name */
2014 else
2015 obj_byte(orp, 1); /* import by ordinal */
2016 obj_name(orp, imp->extname);
2017 obj_name(orp, imp->libname);
2018 if (imp->impname)
2019 obj_name(orp, imp->impname);
2020 else
2021 obj_word(orp, imp->impindex);
2022 obj_emit2(orp);
2026 * Write the EXPDEF records, if any.
2028 for (export = exphead; export; export = export->next) {
2029 obj_rword(orp, dOMFEXT);
2030 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
2031 obj_byte(orp, export->flags);
2032 obj_name(orp, export->extname);
2033 obj_name(orp, export->intname);
2034 if (export->flags & EXPDEF_FLAG_ORDINAL)
2035 obj_word(orp, export->ordinal);
2036 obj_emit2(orp);
2039 /* we're using extended OMF if we put in debug info */
2040 if (debuginfo) {
2041 orp->type = COMENT;
2042 obj_rword(orp, dEXTENDED);
2043 obj_emit2(orp);
2047 * Write the first LNAMES record, containing LNAME one, which
2048 * is null. Also initialize the LNAME counter.
2050 orp->type = LNAMES;
2051 obj_byte(orp, 0);
2052 lname_idx = 1;
2054 * Write some LNAMES for the segment names
2056 for (seg = seghead; seg; seg = seg->next) {
2057 orp = obj_name(orp, seg->name);
2058 if (seg->segclass)
2059 orp = obj_name(orp, seg->segclass);
2060 if (seg->overlay)
2061 orp = obj_name(orp, seg->overlay);
2062 obj_commit(orp);
2065 * Write some LNAMES for the group names
2067 for (grp = grphead; grp; grp = grp->next) {
2068 orp = obj_name(orp, grp->name);
2069 obj_commit(orp);
2071 obj_emit(orp);
2074 * Write the SEGDEF records.
2076 orp->type = SEGDEF;
2077 for (seg = seghead; seg; seg = seg->next) {
2078 int acbp;
2079 uint32_t seglen = seg->currentpos;
2081 acbp = (seg->combine << 2); /* C field */
2083 if (seg->use32)
2084 acbp |= 0x01; /* P bit is Use32 flag */
2085 else if (seglen == 0x10000L) {
2086 seglen = 0; /* This special case may be needed for old linkers */
2087 acbp |= 0x02; /* B bit */
2090 /* A field */
2091 if (seg->align >= SEG_ABS)
2092 /* acbp |= 0x00 */ ;
2093 else if (seg->align >= 4096) {
2094 if (seg->align > 4096)
2095 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2096 " than OBJ format supports", seg->name);
2097 acbp |= 0xC0; /* PharLap extension */
2098 } else if (seg->align >= 256) {
2099 acbp |= 0x80;
2100 } else if (seg->align >= 16) {
2101 acbp |= 0x60;
2102 } else if (seg->align >= 4) {
2103 acbp |= 0xA0;
2104 } else if (seg->align >= 2) {
2105 acbp |= 0x40;
2106 } else
2107 acbp |= 0x20;
2109 obj_byte(orp, acbp);
2110 if (seg->align & SEG_ABS) {
2111 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2112 obj_byte(orp, 0); /* Offset */
2114 obj_x(orp, seglen);
2115 obj_index(orp, ++lname_idx);
2116 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2117 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2118 obj_emit2(orp);
2122 * Write the GRPDEF records.
2124 orp->type = GRPDEF;
2125 for (grp = grphead; grp; grp = grp->next) {
2126 int i;
2128 if (grp->nindices != grp->nentries) {
2129 for (i = grp->nindices; i < grp->nentries; i++) {
2130 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2131 " `%s'", grp->name, grp->segs[i].name);
2132 nasm_free(grp->segs[i].name);
2133 grp->segs[i].name = NULL;
2136 obj_index(orp, ++lname_idx);
2137 for (i = 0; i < grp->nindices; i++) {
2138 obj_byte(orp, 0xFF);
2139 obj_index(orp, grp->segs[i].index);
2141 obj_emit2(orp);
2145 * Write the PUBDEF records: first the ones in the segments,
2146 * then the far-absolutes.
2148 orp->type = PUBDEF;
2149 orp->ori = ori_pubdef;
2150 for (seg = seghead; seg; seg = seg->next) {
2151 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2152 orp->parm[1] = seg->obj_index;
2153 for (pub = seg->pubhead; pub; pub = pub->next) {
2154 orp = obj_name(orp, pub->name);
2155 orp = obj_x(orp, pub->offset);
2156 orp = obj_byte(orp, 0); /* type index */
2157 obj_commit(orp);
2159 obj_emit(orp);
2161 orp->parm[0] = 0;
2162 orp->parm[1] = 0;
2163 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2164 if (orp->parm[2] != (uint32_t)pub->segment) {
2165 obj_emit(orp);
2166 orp->parm[2] = pub->segment;
2168 orp = obj_name(orp, pub->name);
2169 orp = obj_x(orp, pub->offset);
2170 orp = obj_byte(orp, 0); /* type index */
2171 obj_commit(orp);
2173 obj_emit(orp);
2176 * Write the EXTDEF and COMDEF records, in order.
2178 orp->ori = ori_null;
2179 for (ext = exthead; ext; ext = ext->next) {
2180 if (ext->commonsize == 0) {
2181 if (orp->type != EXTDEF) {
2182 obj_emit(orp);
2183 orp->type = EXTDEF;
2185 orp = obj_name(orp, ext->name);
2186 orp = obj_index(orp, 0);
2187 } else {
2188 if (orp->type != COMDEF) {
2189 obj_emit(orp);
2190 orp->type = COMDEF;
2192 orp = obj_name(orp, ext->name);
2193 orp = obj_index(orp, 0);
2194 if (ext->commonelem) {
2195 orp = obj_byte(orp, 0x61); /* far communal */
2196 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2197 orp = obj_value(orp, ext->commonelem);
2198 } else {
2199 orp = obj_byte(orp, 0x62); /* near communal */
2200 orp = obj_value(orp, ext->commonsize);
2203 obj_commit(orp);
2205 obj_emit(orp);
2208 * Write a COMENT record stating that the linker's first pass
2209 * may stop processing at this point. Exception is if our
2210 * MODEND record specifies a start point, in which case,
2211 * according to some variants of the documentation, this COMENT
2212 * should be omitted. So we'll omit it just in case.
2213 * But, TASM puts it in all the time so if we are using
2214 * TASM debug stuff we are putting it in
2216 if (debuginfo || obj_entry_seg == NO_SEG) {
2217 orp->type = COMENT;
2218 obj_rword(orp, dLINKPASS);
2219 obj_byte(orp, 1);
2220 obj_emit2(orp);
2224 * 1) put out the compiler type
2225 * 2) Put out the type info. The only type we are using is near label #19
2227 if (debuginfo) {
2228 int i;
2229 struct Array *arrtmp = arrhead;
2230 orp->type = COMENT;
2231 obj_rword(orp, dCOMPDEF);
2232 obj_byte(orp, 4);
2233 obj_byte(orp, 0);
2234 obj_emit2(orp);
2236 obj_rword(orp, dTYPEDEF);
2237 obj_word(orp, 0x18); /* type # for linking */
2238 obj_word(orp, 6); /* size of type */
2239 obj_byte(orp, 0x2a); /* absolute type for debugging */
2240 obj_emit2(orp);
2241 obj_rword(orp, dTYPEDEF);
2242 obj_word(orp, 0x19); /* type # for linking */
2243 obj_word(orp, 0); /* size of type */
2244 obj_byte(orp, 0x24); /* absolute type for debugging */
2245 obj_byte(orp, 0); /* near/far specifier */
2246 obj_emit2(orp);
2247 obj_rword(orp, dTYPEDEF);
2248 obj_word(orp, 0x1A); /* type # for linking */
2249 obj_word(orp, 0); /* size of type */
2250 obj_byte(orp, 0x24); /* absolute type for debugging */
2251 obj_byte(orp, 1); /* near/far specifier */
2252 obj_emit2(orp);
2253 obj_rword(orp, dTYPEDEF);
2254 obj_word(orp, 0x1b); /* type # for linking */
2255 obj_word(orp, 0); /* size of type */
2256 obj_byte(orp, 0x23); /* absolute type for debugging */
2257 obj_byte(orp, 0);
2258 obj_byte(orp, 0);
2259 obj_byte(orp, 0);
2260 obj_emit2(orp);
2261 obj_rword(orp, dTYPEDEF);
2262 obj_word(orp, 0x1c); /* type # for linking */
2263 obj_word(orp, 0); /* size of type */
2264 obj_byte(orp, 0x23); /* absolute type for debugging */
2265 obj_byte(orp, 0);
2266 obj_byte(orp, 4);
2267 obj_byte(orp, 0);
2268 obj_emit2(orp);
2269 obj_rword(orp, dTYPEDEF);
2270 obj_word(orp, 0x1d); /* type # for linking */
2271 obj_word(orp, 0); /* size of type */
2272 obj_byte(orp, 0x23); /* absolute type for debugging */
2273 obj_byte(orp, 0);
2274 obj_byte(orp, 1);
2275 obj_byte(orp, 0);
2276 obj_emit2(orp);
2277 obj_rword(orp, dTYPEDEF);
2278 obj_word(orp, 0x1e); /* type # for linking */
2279 obj_word(orp, 0); /* size of type */
2280 obj_byte(orp, 0x23); /* absolute type for debugging */
2281 obj_byte(orp, 0);
2282 obj_byte(orp, 5);
2283 obj_byte(orp, 0);
2284 obj_emit2(orp);
2286 /* put out the array types */
2287 for (i = ARRAYBOT; i < arrindex; i++) {
2288 obj_rword(orp, dTYPEDEF);
2289 obj_word(orp, i); /* type # for linking */
2290 obj_word(orp, arrtmp->size); /* size of type */
2291 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2292 obj_byte(orp, arrtmp->basetype); /* base type */
2293 obj_emit2(orp);
2294 arrtmp = arrtmp->next;
2298 * write out line number info with a LINNUM record
2299 * switch records when we switch segments, and output the
2300 * file in a pseudo-TASM fashion. The record switch is naive; that
2301 * is that one file may have many records for the same segment
2302 * if there are lots of segment switches
2304 if (fnhead && debuginfo) {
2305 seg = fnhead->lnhead->segment;
2307 for (fn = fnhead; fn; fn = fn->next) {
2308 /* write out current file name */
2309 orp->type = COMENT;
2310 orp->ori = ori_null;
2311 obj_rword(orp, dFILNAME);
2312 obj_byte(orp, 0);
2313 obj_name(orp, fn->name);
2314 obj_dword(orp, 0);
2315 obj_emit2(orp);
2317 /* write out line numbers this file */
2319 orp->type = LINNUM;
2320 orp->ori = ori_linnum;
2321 for (ln = fn->lnhead; ln; ln = ln->next) {
2322 if (seg != ln->segment) {
2323 /* if we get here have to flush the buffer and start
2324 * a new record for a new segment
2326 seg = ln->segment;
2327 obj_emit(orp);
2329 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2330 orp->parm[1] = seg->obj_index;
2331 orp = obj_word(orp, ln->lineno);
2332 orp = obj_x(orp, ln->offset);
2333 obj_commit(orp);
2335 obj_emit(orp);
2339 * we are going to locate the entry point segment now
2340 * rather than wait until the MODEND record, because,
2341 * then we can output a special symbol to tell where the
2342 * entry point is.
2345 if (obj_entry_seg != NO_SEG) {
2346 for (seg = seghead; seg; seg = seg->next) {
2347 if (seg->index == obj_entry_seg) {
2348 entry_seg_ptr = seg;
2349 break;
2352 if (!seg)
2353 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2357 * get ready to put out symbol records
2359 orp->type = COMENT;
2360 orp->ori = ori_local;
2363 * put out a symbol for the entry point
2364 * no dots in this symbol, because, borland does
2365 * not (officially) support dots in label names
2366 * and I don't know what various versions of TLINK will do
2368 if (debuginfo && obj_entry_seg != NO_SEG) {
2369 orp = obj_name(orp, "start_of_program");
2370 orp = obj_word(orp, 0x19); /* type: near label */
2371 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2372 orp = obj_index(orp, seg->obj_index);
2373 orp = obj_x(orp, obj_entry_ofs);
2374 obj_commit(orp);
2378 * put out the local labels
2380 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2381 /* labels this seg */
2382 for (loc = seg->lochead; loc; loc = loc->next) {
2383 orp = obj_name(orp, loc->name);
2384 orp = obj_word(orp, loc->type);
2385 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2386 orp = obj_index(orp, seg->obj_index);
2387 orp = obj_x(orp, loc->offset);
2388 obj_commit(orp);
2391 if (orp->used)
2392 obj_emit(orp);
2395 * Write the LEDATA/FIXUPP pairs.
2397 for (seg = seghead; seg; seg = seg->next) {
2398 obj_emit(seg->orp);
2399 nasm_free(seg->orp);
2403 * Write the MODEND module end marker.
2405 orp->type = obj_use32 ? MODE32 : MODEND;
2406 orp->ori = ori_null;
2407 if (entry_seg_ptr) {
2408 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2409 obj_byte(orp, 0xC1);
2410 seg = entry_seg_ptr;
2411 if (seg->grp) {
2412 obj_byte(orp, 0x10);
2413 obj_index(orp, seg->grp->obj_index);
2414 } else {
2416 * the below changed to prevent TLINK crashing.
2417 * Previous more efficient version read:
2419 * obj_byte (orp, 0x50);
2421 obj_byte(orp, 0x00);
2422 obj_index(orp, seg->obj_index);
2424 obj_index(orp, seg->obj_index);
2425 obj_x(orp, obj_entry_ofs);
2426 } else
2427 obj_byte(orp, 0);
2428 obj_emit2(orp);
2429 nasm_free(orp);
2432 static void obj_fwrite(ObjRecord * orp)
2434 unsigned int cksum, len;
2435 uint8_t *ptr;
2437 cksum = orp->type;
2438 if (orp->x_size == 32)
2439 cksum |= 1;
2440 fputc(cksum, ofile);
2441 len = orp->committed + 1;
2442 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2443 fwriteint16_t(len, ofile);
2444 nasm_write(orp->buf, len-1, ofile);
2445 for (ptr = orp->buf; --len; ptr++)
2446 cksum += *ptr;
2447 fputc((-cksum) & 0xFF, ofile);
2450 static enum directive_result
2451 obj_pragma(const struct pragma *pragma)
2453 switch (pragma->opcode) {
2454 case D_NODEPEND:
2455 obj_nodepend = true;
2456 break;
2458 default:
2459 break;
2462 return DIRR_OK;
2465 extern macros_t obj_stdmac[];
2467 static void dbgbi_init(void)
2469 fnhead = NULL;
2470 fntail = &fnhead;
2471 arrindex = ARRAYBOT;
2472 arrhead = NULL;
2473 arrtail = &arrhead;
2475 static void dbgbi_cleanup(void)
2477 struct Segment *segtmp;
2478 while (fnhead) {
2479 struct FileName *fntemp = fnhead;
2480 while (fnhead->lnhead) {
2481 struct LineNumber *lntemp = fnhead->lnhead;
2482 fnhead->lnhead = lntemp->next;
2483 nasm_free(lntemp);
2485 fnhead = fnhead->next;
2486 nasm_free(fntemp->name);
2487 nasm_free(fntemp);
2489 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2490 while (segtmp->lochead) {
2491 struct Public *loctmp = segtmp->lochead;
2492 segtmp->lochead = loctmp->next;
2493 nasm_free(loctmp->name);
2494 nasm_free(loctmp);
2497 while (arrhead) {
2498 struct Array *arrtmp = arrhead;
2499 arrhead = arrhead->next;
2500 nasm_free(arrtmp);
2504 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2506 struct FileName *fn;
2507 struct LineNumber *ln;
2508 struct Segment *seg;
2510 if (segto == NO_SEG)
2511 return;
2514 * If `any_segs' is still false, we must define a default
2515 * segment.
2517 if (!any_segs) {
2518 int tempint; /* ignored */
2519 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2520 nasm_panic("strange segment conditions in OBJ driver");
2524 * Find the segment we are targetting.
2526 for (seg = seghead; seg; seg = seg->next)
2527 if (seg->index == segto)
2528 break;
2529 if (!seg)
2530 nasm_panic("lineno directed to nonexistent segment?");
2532 /* for (fn = fnhead; fn; fn = fnhead->next) */
2533 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2534 if (!nasm_stricmp(lnfname, fn->name))
2535 break;
2536 if (!fn) {
2537 fn = nasm_malloc(sizeof(*fn));
2538 fn->name = nasm_malloc(strlen(lnfname) + 1);
2539 strcpy(fn->name, lnfname);
2540 fn->lnhead = NULL;
2541 fn->lntail = &fn->lnhead;
2542 fn->next = NULL;
2543 *fntail = fn;
2544 fntail = &fn->next;
2546 ln = nasm_malloc(sizeof(*ln));
2547 ln->segment = seg;
2548 ln->offset = seg->currentpos;
2549 ln->lineno = lineno;
2550 ln->next = NULL;
2551 *fn->lntail = ln;
2552 fn->lntail = &ln->next;
2555 static void dbgbi_deflabel(char *name, int32_t segment,
2556 int64_t offset, int is_global, char *special)
2558 struct Segment *seg;
2560 (void)special;
2563 * Note: ..[^@] special symbols are filtered in labels.c
2567 * If it's a special-retry from pass two, discard it.
2569 if (is_global == 3)
2570 return;
2573 * Case (i):
2575 if (obj_seg_needs_update) {
2576 return;
2577 } else if (obj_grp_needs_update) {
2578 return;
2580 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2581 return;
2583 if (segment >= SEG_ABS || segment == NO_SEG) {
2584 return;
2588 * If `any_segs' is still false, we might need to define a
2589 * default segment, if they're trying to declare a label in
2590 * `first_seg'. But the label should exist due to a prior
2591 * call to obj_deflabel so we can skip that.
2594 for (seg = seghead; seg; seg = seg->next)
2595 if (seg->index == segment) {
2596 struct Public *loc = nasm_malloc(sizeof(*loc));
2598 * Case (ii). Maybe MODPUB someday?
2600 last_defined = *seg->loctail = loc;
2601 seg->loctail = &loc->next;
2602 loc->next = NULL;
2603 loc->name = nasm_strdup(name);
2604 loc->offset = offset;
2607 static void dbgbi_typevalue(int32_t type)
2609 int vsize;
2610 int elem = TYM_ELEMENTS(type);
2611 type = TYM_TYPE(type);
2613 if (!last_defined)
2614 return;
2616 switch (type) {
2617 case TY_BYTE:
2618 last_defined->type = 8; /* uint8_t */
2619 vsize = 1;
2620 break;
2621 case TY_WORD:
2622 last_defined->type = 10; /* unsigned word */
2623 vsize = 2;
2624 break;
2625 case TY_DWORD:
2626 last_defined->type = 12; /* unsigned dword */
2627 vsize = 4;
2628 break;
2629 case TY_FLOAT:
2630 last_defined->type = 14; /* float */
2631 vsize = 4;
2632 break;
2633 case TY_QWORD:
2634 last_defined->type = 15; /* qword */
2635 vsize = 8;
2636 break;
2637 case TY_TBYTE:
2638 last_defined->type = 16; /* TBYTE */
2639 vsize = 10;
2640 break;
2641 default:
2642 last_defined->type = 0x19; /* label */
2643 vsize = 0;
2644 break;
2647 if (elem > 1) {
2648 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2649 int vtype = last_defined->type;
2650 arrtmp->size = vsize * elem;
2651 arrtmp->basetype = vtype;
2652 arrtmp->next = NULL;
2653 last_defined->type = arrindex++;
2654 *arrtail = arrtmp;
2655 arrtail = &(arrtmp->next);
2657 last_defined = NULL;
2659 static void dbgbi_output(int output_type, void *param)
2661 (void)output_type;
2662 (void)param;
2664 static const struct dfmt borland_debug_form = {
2665 "Borland Debug Records",
2666 "borland",
2667 dbgbi_init,
2668 dbgbi_linnum,
2669 dbgbi_deflabel,
2670 null_debug_directive,
2671 dbgbi_typevalue,
2672 dbgbi_output,
2673 dbgbi_cleanup,
2674 NULL /* pragma list */
2677 static const struct dfmt * const borland_debug_arr[3] = {
2678 &borland_debug_form,
2679 &null_debug_form,
2680 NULL
2683 static const struct pragma_facility obj_pragma_list[] = {
2684 { NULL, obj_pragma }
2687 const struct ofmt of_obj = {
2688 "MS-DOS 16-bit/32-bit OMF object files",
2689 "obj",
2690 ".obj",
2693 borland_debug_arr,
2694 &borland_debug_form,
2695 obj_stdmac,
2696 obj_init,
2697 null_reset,
2698 nasm_do_legacy_output,
2699 obj_out,
2700 obj_deflabel,
2701 obj_segment,
2702 NULL,
2703 obj_sectalign,
2704 obj_segbase,
2705 obj_directive,
2706 obj_cleanup,
2707 obj_pragma_list
2709 #endif /* OF_OBJ */