nasm.spec.in: add fontconfig as a built requirement
[nasm.git] / output / outobj.c
blobfaa89e1cf13e13055ce042c49b17e6e0af7f0c0a
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 "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 */
152 dEXTENDED = 0xA1, /* tells that we are using translator-specific extensions */
153 dLINKPASS = 0xA2, /* link pass 2 marker */
154 dTYPEDEF = 0xE3, /* define a type */
155 dSYM = 0xE6, /* symbol debug record */
156 dFILNAME = 0xE8, /* file name record */
157 dCOMPDEF = 0xEA /* compiler type info */
160 typedef struct ObjRecord ObjRecord;
161 typedef void ORI(ObjRecord * orp);
163 struct ObjRecord {
164 ORI *ori; /* Initialization routine */
165 int used; /* Current data size */
166 int committed; /* Data size at last boundary */
167 int x_size; /* (see obj_x) */
168 unsigned int type; /* Record type */
169 ObjRecord *child; /* Associated record below this one */
170 ObjRecord **up; /* Master pointer to this ObjRecord */
171 ObjRecord *back; /* Previous part of this record */
172 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
173 uint8_t buf[RECORD_MAX + 3];
176 static void obj_fwrite(ObjRecord * orp);
177 static void ori_ledata(ObjRecord * orp);
178 static void ori_pubdef(ObjRecord * orp);
179 static void ori_null(ObjRecord * orp);
180 static ObjRecord *obj_commit(ObjRecord * orp);
182 static bool obj_uppercase; /* Flag: all names in uppercase */
183 static bool obj_use32; /* Flag: at least one segment is 32-bit */
186 * Clear an ObjRecord structure. (Never reallocates).
187 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
189 static ObjRecord *obj_clear(ObjRecord * orp)
191 orp->used = 0;
192 orp->committed = 0;
193 orp->x_size = 0;
194 orp->child = NULL;
195 orp->up = NULL;
196 orp->back = NULL;
197 return (orp);
201 * Emit an ObjRecord structure. (Never reallocates).
202 * The record is written out preceeded (recursively) by its previous part (if
203 * any) and followed (recursively) by its child (if any).
204 * The previous part and the child are freed. The main ObjRecord is cleared,
205 * not freed.
207 static ObjRecord *obj_emit(ObjRecord * orp)
209 if (orp->back) {
210 obj_emit(orp->back);
211 nasm_free(orp->back);
214 if (orp->committed)
215 obj_fwrite(orp);
217 if (orp->child) {
218 obj_emit(orp->child);
219 nasm_free(orp->child);
222 return (obj_clear(orp));
226 * Commit and Emit a record. (Never reallocates).
228 static ObjRecord *obj_emit2(ObjRecord * orp)
230 obj_commit(orp);
231 return (obj_emit(orp));
235 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
237 static ObjRecord *obj_new(void)
239 ObjRecord *orp;
241 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
242 orp->ori = ori_null;
243 return (orp);
247 * Advance to the next record because the existing one is full or its x_size
248 * is incompatible.
249 * Any uncommited data is moved into the next record.
251 static ObjRecord *obj_bump(ObjRecord * orp)
253 ObjRecord *nxt;
254 int used = orp->used;
255 int committed = orp->committed;
257 if (orp->up) {
258 *orp->up = nxt = obj_new();
259 nxt->ori = orp->ori;
260 nxt->type = orp->type;
261 nxt->up = orp->up;
262 nxt->back = orp;
263 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
264 } else
265 nxt = obj_emit(orp);
267 used -= committed;
268 if (used) {
269 nxt->committed = 1;
270 nxt->ori(nxt);
271 nxt->committed = nxt->used;
272 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
273 nxt->used = nxt->committed + used;
276 return (nxt);
280 * Advance to the next record if necessary to allow the next field to fit.
282 static ObjRecord *obj_check(ObjRecord * orp, int size)
284 if (orp->used + size > RECORD_MAX)
285 orp = obj_bump(orp);
287 if (!orp->committed) {
288 orp->committed = 1;
289 orp->ori(orp);
290 orp->committed = orp->used;
293 return (orp);
297 * All data written so far is commited to the current record (won't be moved to
298 * the next record in case of continuation).
300 static ObjRecord *obj_commit(ObjRecord * orp)
302 orp->committed = orp->used;
303 return (orp);
307 * Write a byte
309 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
311 orp = obj_check(orp, 1);
312 orp->buf[orp->used] = val;
313 orp->used++;
314 return (orp);
318 * Write a word
320 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
322 orp = obj_check(orp, 2);
323 orp->buf[orp->used] = val;
324 orp->buf[orp->used + 1] = val >> 8;
325 orp->used += 2;
326 return (orp);
330 * Write a reversed word
332 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
334 orp = obj_check(orp, 2);
335 orp->buf[orp->used] = val >> 8;
336 orp->buf[orp->used + 1] = val;
337 orp->used += 2;
338 return (orp);
342 * Write a dword
344 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
346 orp = obj_check(orp, 4);
347 orp->buf[orp->used] = val;
348 orp->buf[orp->used + 1] = val >> 8;
349 orp->buf[orp->used + 2] = val >> 16;
350 orp->buf[orp->used + 3] = val >> 24;
351 orp->used += 4;
352 return (orp);
356 * All fields of "size x" in one obj record must be the same size (either 16
357 * bits or 32 bits). There is a one bit flag in each record which specifies
358 * which.
359 * This routine is used to force the current record to have the desired
360 * x_size. x_size is normally automatic (using obj_x), so that this
361 * routine should be used outside obj_x, only to provide compatibility with
362 * linkers that have bugs in their processing of the size bit.
365 static ObjRecord *obj_force(ObjRecord * orp, int x)
367 if (orp->x_size == (x ^ 48))
368 orp = obj_bump(orp);
369 orp->x_size = x;
370 return (orp);
374 * This routine writes a field of size x. The caller does not need to worry at
375 * all about whether 16-bits or 32-bits are required.
377 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
379 if (orp->type & 1)
380 orp->x_size = 32;
381 if (val > 0xFFFF)
382 orp = obj_force(orp, 32);
383 if (orp->x_size == 32) {
384 ObjRecord *nxt = obj_dword(orp, val);
385 nxt->x_size = 32; /* x_size is cleared when a record overflows */
386 return nxt;
388 orp->x_size = 16;
389 return (obj_word(orp, val));
393 * Writes an index
395 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
397 if (val < 128)
398 return (obj_byte(orp, val));
399 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
403 * Writes a variable length value
405 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
407 if (val <= 128)
408 return (obj_byte(orp, val));
409 if (val <= 0xFFFF) {
410 orp = obj_byte(orp, 129);
411 return (obj_word(orp, val));
413 if (val <= 0xFFFFFF)
414 return (obj_dword(orp, (val << 8) + 132));
415 orp = obj_byte(orp, 136);
416 return (obj_dword(orp, val));
420 * Writes a counted string
422 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
424 int len = strlen(name);
425 uint8_t *ptr;
427 orp = obj_check(orp, len + 1);
428 ptr = orp->buf + orp->used;
429 *ptr++ = len;
430 orp->used += len + 1;
431 if (obj_uppercase)
432 while (--len >= 0) {
433 *ptr++ = toupper(*name);
434 name++;
435 } else
436 memcpy(ptr, name, len);
437 return (orp);
441 * Initializer for an LEDATA record.
442 * parm[0] = offset
443 * parm[1] = segment index
444 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
445 * represent the offset that would be required if the record were split at the
446 * last commit point.
447 * parm[2] is a copy of parm[0] as it was when the current record was initted.
449 static void ori_ledata(ObjRecord * orp)
451 obj_index(orp, orp->parm[1]);
452 orp->parm[2] = orp->parm[0];
453 obj_x(orp, orp->parm[0]);
457 * Initializer for a PUBDEF record.
458 * parm[0] = group index
459 * parm[1] = segment index
460 * parm[2] = frame (only used when both indexes are zero)
462 static void ori_pubdef(ObjRecord * orp)
464 obj_index(orp, orp->parm[0]);
465 obj_index(orp, orp->parm[1]);
466 if (!(orp->parm[0] | orp->parm[1]))
467 obj_word(orp, orp->parm[2]);
471 * Initializer for a LINNUM record.
472 * parm[0] = group index
473 * parm[1] = segment index
475 static void ori_linnum(ObjRecord * orp)
477 obj_index(orp, orp->parm[0]);
478 obj_index(orp, orp->parm[1]);
482 * Initializer for a local vars record.
484 static void ori_local(ObjRecord * orp)
486 obj_byte(orp, 0x40);
487 obj_byte(orp, dSYM);
491 * Null initializer for records that continue without any header info
493 static void ori_null(ObjRecord * orp)
495 (void)orp; /* Do nothing */
499 * This concludes the low level section of outobj.c
502 static char obj_infile[FILENAME_MAX];
504 static int32_t first_seg;
505 static bool any_segs;
506 static int passtwo;
507 static int arrindex;
509 #define GROUP_MAX 256 /* we won't _realistically_ have more
510 * than this many segs in a group */
511 #define EXT_BLKSIZ 256 /* block size for externals list */
513 struct Segment; /* need to know these structs exist */
514 struct Group;
516 struct LineNumber {
517 struct LineNumber *next;
518 struct Segment *segment;
519 int32_t offset;
520 int32_t lineno;
523 static struct FileName {
524 struct FileName *next;
525 char *name;
526 struct LineNumber *lnhead, **lntail;
527 int index;
528 } *fnhead, **fntail;
530 static struct Array {
531 struct Array *next;
532 unsigned size;
533 int basetype;
534 } *arrhead, **arrtail;
536 #define ARRAYBOT 31 /* magic number for first array index */
538 static struct Public {
539 struct Public *next;
540 char *name;
541 int32_t offset;
542 int32_t segment; /* only if it's far-absolute */
543 int type; /* only for local debug syms */
544 } *fpubhead, **fpubtail, *last_defined;
546 static struct External {
547 struct External *next;
548 char *name;
549 int32_t commonsize;
550 int32_t commonelem; /* element size if FAR, else zero */
551 int index; /* OBJ-file external index */
552 enum {
553 DEFWRT_NONE, /* no unusual default-WRT */
554 DEFWRT_STRING, /* a string we don't yet understand */
555 DEFWRT_SEGMENT, /* a segment */
556 DEFWRT_GROUP /* a group */
557 } defwrt_type;
558 union {
559 char *string;
560 struct Segment *seg;
561 struct Group *grp;
562 } defwrt_ptr;
563 struct External *next_dws; /* next with DEFWRT_STRING */
564 } *exthead, **exttail, *dws;
566 static int externals;
568 static struct ExtBack {
569 struct ExtBack *next;
570 struct External *exts[EXT_BLKSIZ];
571 } *ebhead, **ebtail;
573 static struct Segment {
574 struct Segment *next;
575 char *name;
576 int32_t index; /* the NASM segment id */
577 int32_t obj_index; /* the OBJ-file segment index */
578 struct Group *grp; /* the group it beint32_ts to */
579 uint32_t currentpos;
580 int32_t align; /* can be SEG_ABS + absolute addr */
581 struct Public *pubhead, **pubtail, *lochead, **loctail;
582 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
583 ObjRecord *orp;
584 enum {
585 CMB_PRIVATE = 0,
586 CMB_PUBLIC = 2,
587 CMB_STACK = 5,
588 CMB_COMMON = 6
589 } combine;
590 bool use32; /* is this segment 32-bit? */
591 } *seghead, **segtail, *obj_seg_needs_update;
593 static struct Group {
594 struct Group *next;
595 char *name;
596 int32_t index; /* NASM segment id */
597 int32_t obj_index; /* OBJ-file group index */
598 int32_t nentries; /* number of elements... */
599 int32_t nindices; /* ...and number of index elts... */
600 union {
601 int32_t index;
602 char *name;
603 } segs[GROUP_MAX]; /* ...in this */
604 } *grphead, **grptail, *obj_grp_needs_update;
606 static struct ImpDef {
607 struct ImpDef *next;
608 char *extname;
609 char *libname;
610 unsigned int impindex;
611 char *impname;
612 } *imphead, **imptail;
614 static struct ExpDef {
615 struct ExpDef *next;
616 char *intname;
617 char *extname;
618 unsigned int ordinal;
619 int flags;
620 } *exphead, **exptail;
622 #define EXPDEF_FLAG_ORDINAL 0x80
623 #define EXPDEF_FLAG_RESIDENT 0x40
624 #define EXPDEF_FLAG_NODATA 0x20
625 #define EXPDEF_MASK_PARMCNT 0x1F
627 static int32_t obj_entry_seg, obj_entry_ofs;
629 const struct ofmt of_obj;
630 static const struct dfmt borland_debug_form;
632 /* The current segment */
633 static struct Segment *current_seg;
635 static int32_t obj_segment(char *, int, int *);
636 static void obj_write_file(void);
637 static enum directive_result obj_directive(enum directive, char *, int);
639 static void obj_init(void)
641 first_seg = seg_alloc();
642 any_segs = false;
643 fpubhead = NULL;
644 fpubtail = &fpubhead;
645 exthead = NULL;
646 exttail = &exthead;
647 imphead = NULL;
648 imptail = &imphead;
649 exphead = NULL;
650 exptail = &exphead;
651 dws = NULL;
652 externals = 0;
653 ebhead = NULL;
654 ebtail = &ebhead;
655 seghead = obj_seg_needs_update = NULL;
656 segtail = &seghead;
657 grphead = obj_grp_needs_update = NULL;
658 grptail = &grphead;
659 obj_entry_seg = NO_SEG;
660 obj_uppercase = false;
661 obj_use32 = false;
662 passtwo = 0;
663 current_seg = NULL;
666 static void obj_cleanup(void)
668 obj_write_file();
669 dfmt->cleanup();
670 while (seghead) {
671 struct Segment *segtmp = seghead;
672 seghead = seghead->next;
673 while (segtmp->pubhead) {
674 struct Public *pubtmp = segtmp->pubhead;
675 segtmp->pubhead = pubtmp->next;
676 nasm_free(pubtmp->name);
677 nasm_free(pubtmp);
679 nasm_free(segtmp->segclass);
680 nasm_free(segtmp->overlay);
681 nasm_free(segtmp);
683 while (fpubhead) {
684 struct Public *pubtmp = fpubhead;
685 fpubhead = fpubhead->next;
686 nasm_free(pubtmp->name);
687 nasm_free(pubtmp);
689 while (exthead) {
690 struct External *exttmp = exthead;
691 exthead = exthead->next;
692 nasm_free(exttmp);
694 while (imphead) {
695 struct ImpDef *imptmp = imphead;
696 imphead = imphead->next;
697 nasm_free(imptmp->extname);
698 nasm_free(imptmp->libname);
699 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
700 nasm_free(imptmp);
702 while (exphead) {
703 struct ExpDef *exptmp = exphead;
704 exphead = exphead->next;
705 nasm_free(exptmp->extname);
706 nasm_free(exptmp->intname);
707 nasm_free(exptmp);
709 while (ebhead) {
710 struct ExtBack *ebtmp = ebhead;
711 ebhead = ebhead->next;
712 nasm_free(ebtmp);
714 while (grphead) {
715 struct Group *grptmp = grphead;
716 grphead = grphead->next;
717 nasm_free(grptmp);
721 static void obj_ext_set_defwrt(struct External *ext, char *id)
723 struct Segment *seg;
724 struct Group *grp;
726 for (seg = seghead; seg; seg = seg->next)
727 if (!strcmp(seg->name, id)) {
728 ext->defwrt_type = DEFWRT_SEGMENT;
729 ext->defwrt_ptr.seg = seg;
730 nasm_free(id);
731 return;
734 for (grp = grphead; grp; grp = grp->next)
735 if (!strcmp(grp->name, id)) {
736 ext->defwrt_type = DEFWRT_GROUP;
737 ext->defwrt_ptr.grp = grp;
738 nasm_free(id);
739 return;
742 ext->defwrt_type = DEFWRT_STRING;
743 ext->defwrt_ptr.string = id;
744 ext->next_dws = dws;
745 dws = ext;
748 static void obj_deflabel(char *name, int32_t segment,
749 int64_t offset, int is_global, char *special)
752 * We have three cases:
754 * (i) `segment' is a segment-base. If so, set the name field
755 * for the segment or group structure it refers to, and then
756 * return.
758 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
759 * Save the label position for later output of a PUBDEF record.
760 * (Or a MODPUB, if we work out how.)
762 * (iii) `segment' is not one of our segments. Save the label
763 * position for later output of an EXTDEF, and also store a
764 * back-reference so that we can map later references to this
765 * segment number to the external index.
767 struct External *ext;
768 struct ExtBack *eb;
769 struct Segment *seg;
770 int i;
771 bool used_special = false; /* have we used the special text? */
773 #if defined(DEBUG) && DEBUG>2
774 nasm_error(ERR_DEBUG,
775 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
776 name, segment, offset, is_global, special);
777 #endif
780 * If it's a special-retry from pass two, discard it.
782 if (is_global == 3)
783 return;
786 * First check for the double-period, signifying something
787 * unusual.
789 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
790 if (!strcmp(name, "..start")) {
791 obj_entry_seg = segment;
792 obj_entry_ofs = offset;
793 return;
795 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
799 * Case (i):
801 if (obj_seg_needs_update) {
802 obj_seg_needs_update->name = name;
803 return;
804 } else if (obj_grp_needs_update) {
805 obj_grp_needs_update->name = name;
806 return;
808 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
809 return;
811 if (segment >= SEG_ABS || segment == NO_SEG) {
813 * SEG_ABS subcase of (ii).
815 if (is_global) {
816 struct Public *pub;
818 pub = *fpubtail = nasm_malloc(sizeof(*pub));
819 fpubtail = &pub->next;
820 pub->next = NULL;
821 pub->name = nasm_strdup(name);
822 pub->offset = offset;
823 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
825 if (special)
826 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
827 " for this symbol type");
828 return;
832 * If `any_segs' is still false, we might need to define a
833 * default segment, if they're trying to declare a label in
834 * `first_seg'.
836 if (!any_segs && segment == first_seg) {
837 int tempint; /* ignored */
838 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
839 nasm_panic(0, "strange segment conditions in OBJ driver");
842 for (seg = seghead; seg && is_global; seg = seg->next)
843 if (seg->index == segment) {
844 struct Public *loc = nasm_malloc(sizeof(*loc));
846 * Case (ii). Maybe MODPUB someday?
848 *seg->pubtail = loc;
849 seg->pubtail = &loc->next;
850 loc->next = NULL;
851 loc->name = nasm_strdup(name);
852 loc->offset = offset;
854 if (special)
855 nasm_error(ERR_NONFATAL,
856 "OBJ supports no special symbol features"
857 " for this symbol type");
858 return;
862 * Case (iii).
864 if (is_global) {
865 ext = *exttail = nasm_malloc(sizeof(*ext));
866 ext->next = NULL;
867 exttail = &ext->next;
868 ext->name = name;
869 /* Place by default all externs into the current segment */
870 ext->defwrt_type = DEFWRT_NONE;
872 /* 28-Apr-2002 - John Coffman
873 The following code was introduced on 12-Aug-2000, and breaks fixups
874 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
875 (5.10). It was introduced after FIXUP32 was added, and may be needed
876 for 32-bit segments. The following will get 16-bit segments working
877 again, and maybe someone can correct the 'if' condition which is
878 actually needed.
880 #if 0
881 if (current_seg) {
882 #else
883 if (current_seg && current_seg->use32) {
884 if (current_seg->grp) {
885 ext->defwrt_type = DEFWRT_GROUP;
886 ext->defwrt_ptr.grp = current_seg->grp;
887 } else {
888 ext->defwrt_type = DEFWRT_SEGMENT;
889 ext->defwrt_ptr.seg = current_seg;
892 #endif
894 if (is_global == 2) {
895 ext->commonsize = offset;
896 ext->commonelem = 1; /* default FAR */
897 } else
898 ext->commonsize = 0;
899 } else
900 return;
903 * Now process the special text, if any, to find default-WRT
904 * specifications and common-variable element-size and near/far
905 * specifications.
907 while (special && *special) {
908 used_special = true;
911 * We might have a default-WRT specification.
913 if (!nasm_strnicmp(special, "wrt", 3)) {
914 char *p;
915 int len;
916 special += 3;
917 special += strspn(special, " \t");
918 p = nasm_strndup(special, len = strcspn(special, ":"));
919 obj_ext_set_defwrt(ext, p);
920 special += len;
921 if (*special && *special != ':')
922 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
923 " text for `%s'", ext->name);
924 else if (*special == ':')
925 special++;
929 * The NEAR or FAR keywords specify nearness or
930 * farness. FAR gives default element size 1.
932 if (!nasm_strnicmp(special, "far", 3)) {
933 if (ext->commonsize)
934 ext->commonelem = 1;
935 else
936 nasm_error(ERR_NONFATAL,
937 "`%s': `far' keyword may only be applied"
938 " to common variables\n", ext->name);
939 special += 3;
940 special += strspn(special, " \t");
941 } else if (!nasm_strnicmp(special, "near", 4)) {
942 if (ext->commonsize)
943 ext->commonelem = 0;
944 else
945 nasm_error(ERR_NONFATAL,
946 "`%s': `far' keyword may only be applied"
947 " to common variables\n", ext->name);
948 special += 4;
949 special += strspn(special, " \t");
953 * If it's a common, and anything else remains on the line
954 * before a further colon, evaluate it as an expression and
955 * use that as the element size. Forward references aren't
956 * allowed.
958 if (*special == ':')
959 special++;
960 else if (*special) {
961 if (ext->commonsize) {
962 expr *e;
963 struct tokenval tokval;
965 stdscan_reset();
966 stdscan_set(special);
967 tokval.t_type = TOKEN_INVALID;
968 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
969 if (e) {
970 if (!is_simple(e))
971 nasm_error(ERR_NONFATAL, "cannot use relocatable"
972 " expression as common-variable element size");
973 else
974 ext->commonelem = reloc_value(e);
976 special = stdscan_get();
977 } else {
978 nasm_error(ERR_NONFATAL,
979 "`%s': element-size specifications only"
980 " apply to common variables", ext->name);
981 while (*special && *special != ':')
982 special++;
983 if (*special == ':')
984 special++;
989 i = segment / 2;
990 eb = ebhead;
991 if (!eb) {
992 eb = *ebtail = nasm_zalloc(sizeof(*eb));
993 eb->next = NULL;
994 ebtail = &eb->next;
996 while (i >= EXT_BLKSIZ) {
997 if (eb && eb->next)
998 eb = eb->next;
999 else {
1000 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1001 eb->next = NULL;
1002 ebtail = &eb->next;
1004 i -= EXT_BLKSIZ;
1006 eb->exts[i] = ext;
1007 ext->index = ++externals;
1009 if (special && !used_special)
1010 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1011 " for this symbol type");
1014 /* forward declaration */
1015 static void obj_write_fixup(ObjRecord * orp, int bytes,
1016 int segrel, int32_t seg, int32_t wrt,
1017 struct Segment *segto);
1019 static void obj_out(int32_t segto, const void *data,
1020 enum out_type type, uint64_t size,
1021 int32_t segment, int32_t wrt)
1023 const uint8_t *ucdata;
1024 int32_t ldata;
1025 struct Segment *seg;
1026 ObjRecord *orp;
1029 * handle absolute-assembly (structure definitions)
1031 if (segto == NO_SEG) {
1032 if (type != OUT_RESERVE)
1033 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1034 " space");
1035 return;
1039 * If `any_segs' is still false, we must define a default
1040 * segment.
1042 if (!any_segs) {
1043 int tempint; /* ignored */
1044 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1045 nasm_panic(0, "strange segment conditions in OBJ driver");
1049 * Find the segment we are targetting.
1051 for (seg = seghead; seg; seg = seg->next)
1052 if (seg->index == segto)
1053 break;
1054 if (!seg)
1055 nasm_panic(0, "code directed to nonexistent segment?");
1057 orp = seg->orp;
1058 orp->parm[0] = seg->currentpos;
1060 switch (type) {
1061 case OUT_RAWDATA:
1062 ucdata = data;
1063 while (size > 0) {
1064 unsigned int len;
1065 orp = obj_check(seg->orp, 1);
1066 len = RECORD_MAX - orp->used;
1067 if (len > size)
1068 len = size;
1069 memcpy(orp->buf + orp->used, ucdata, len);
1070 orp->committed = orp->used += len;
1071 orp->parm[0] = seg->currentpos += len;
1072 ucdata += len;
1073 size -= len;
1075 break;
1077 case OUT_ADDRESS:
1078 case OUT_REL1ADR:
1079 case OUT_REL2ADR:
1080 case OUT_REL4ADR:
1081 case OUT_REL8ADR:
1083 int rsize;
1085 if (type == OUT_ADDRESS)
1086 size = abs((int)size);
1088 if (segment == NO_SEG && type != OUT_ADDRESS)
1089 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1090 " supported by OBJ format");
1091 if (segment >= SEG_ABS)
1092 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1093 " by OBJ format");
1095 ldata = *(int64_t *)data;
1096 if (type != OUT_ADDRESS) {
1098 * For 16-bit and 32-bit x86 code, the size and realsize() always
1099 * matches as only jumps, calls and loops uses PC relative
1100 * addressing and the address isn't followed by any other opcode
1101 * bytes. In 64-bit mode there is RIP relative addressing which
1102 * means the fixup location can be followed by an immediate value,
1103 * meaning that size > realsize().
1105 * When the CPU is calculating the effective address, it takes the
1106 * RIP at the end of the instruction and adds the fixed up relative
1107 * address value to it.
1109 * The linker's point of reference is the end of the fixup location
1110 * (which is the end of the instruction for Jcc, CALL, LOOP[cc]).
1111 * It is calculating distance between the target symbol and the end
1112 * of the fixup location, and add this to the displacement value we
1113 * are calculating here and storing at the fixup location.
1115 * To get the right effect, we need to _reduce_ the displacement
1116 * value by the number of bytes following the fixup.
1118 * Example:
1119 * data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
1120 * end of fixup at 0x054, end of instruction at 0x058.
1121 * => size = 8.
1122 * => realsize() -> 4
1123 * => CPU needs a value of: 0x100 - 0x058 = 0x0a8
1124 * => linker/loader will add: 0x100 - 0x054 = 0x0ac
1125 * => We must add an addend of -4.
1126 * => realsize() - size = -4.
1128 * The code used to do size - realsize() at least since v0.90,
1129 * probably because it wasn't needed...
1131 ldata -= size;
1132 size = realsize(type, size);
1133 ldata += size;
1136 switch (size) {
1137 default:
1138 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1139 "32-byte relocations");
1140 segment = NO_SEG; /* Don't actually generate a relocation */
1141 break;
1142 case 2:
1143 orp = obj_word(orp, ldata);
1144 break;
1145 case 4:
1146 orp = obj_dword(orp, ldata);
1147 break;
1150 rsize = size;
1151 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1152 size == 4) {
1154 * This is a 4-byte segment-base relocation such as
1155 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1156 * these, but if the constant term has the 16 low bits
1157 * zero, we can just apply a 2-byte segment-base
1158 * relocation to the low word instead.
1160 rsize = 2;
1161 if (ldata & 0xFFFF)
1162 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1163 " dword-size segment base references");
1165 if (segment != NO_SEG)
1166 obj_write_fixup(orp, rsize,
1167 (type == OUT_ADDRESS ? 0x4000 : 0),
1168 segment, wrt, seg);
1169 seg->currentpos += size;
1170 break;
1173 default:
1174 nasm_error(ERR_NONFATAL,
1175 "Relocation type not supported by output format");
1176 /* fall through */
1178 case OUT_RESERVE:
1179 if (orp->committed)
1180 orp = obj_bump(orp);
1181 seg->currentpos += size;
1182 break;
1184 obj_commit(orp);
1187 static void obj_write_fixup(ObjRecord * orp, int bytes,
1188 int segrel, int32_t seg, int32_t wrt,
1189 struct Segment *segto)
1191 unsigned locat;
1192 int method;
1193 int base;
1194 int32_t tidx, fidx;
1195 struct Segment *s = NULL;
1196 struct Group *g = NULL;
1197 struct External *e = NULL;
1198 ObjRecord *forp;
1200 if (bytes != 2 && bytes != 4) {
1201 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1202 " %d-bit relocations", bytes << 3);
1203 return;
1206 forp = orp->child;
1207 if (forp == NULL) {
1208 orp->child = forp = obj_new();
1209 forp->up = &(orp->child);
1210 /* We should choose between FIXUPP and FIXU32 record type */
1211 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1212 if (segto->use32)
1213 forp->type = FIXU32;
1214 else
1215 forp->type = FIXUPP;
1218 if (seg % 2) {
1219 base = true;
1220 locat = FIX_16_SELECTOR;
1221 seg--;
1222 if (bytes != 2)
1223 nasm_panic(0, "OBJ: 4-byte segment base fixup got"
1224 " through sanity check");
1225 } else {
1226 base = false;
1227 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1228 if (!segrel)
1230 * There is a bug in tlink that makes it process self relative
1231 * fixups incorrectly if the x_size doesn't match the location
1232 * size.
1234 forp = obj_force(forp, bytes << 3);
1237 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1239 tidx = fidx = -1, method = 0; /* placate optimisers */
1242 * See if we can find the segment ID in our segment list. If
1243 * so, we have a T4 (LSEG) target.
1245 for (s = seghead; s; s = s->next)
1246 if (s->index == seg)
1247 break;
1248 if (s)
1249 method = 4, tidx = s->obj_index;
1250 else {
1251 for (g = grphead; g; g = g->next)
1252 if (g->index == seg)
1253 break;
1254 if (g)
1255 method = 5, tidx = g->obj_index;
1256 else {
1257 int32_t i = seg / 2;
1258 struct ExtBack *eb = ebhead;
1259 while (i >= EXT_BLKSIZ) {
1260 if (eb)
1261 eb = eb->next;
1262 else
1263 break;
1264 i -= EXT_BLKSIZ;
1266 if (eb)
1267 method = 6, e = eb->exts[i], tidx = e->index;
1268 else
1269 nasm_panic(0,
1270 "unrecognised segment value in obj_write_fixup");
1275 * If no WRT given, assume the natural default, which is method
1276 * F5 unless:
1278 * - we are doing an OFFSET fixup for a grouped segment, in
1279 * which case we require F1 (group).
1281 * - we are doing an OFFSET fixup for an external with a
1282 * default WRT, in which case we must honour the default WRT.
1284 if (wrt == NO_SEG) {
1285 if (!base && s && s->grp)
1286 method |= 0x10, fidx = s->grp->obj_index;
1287 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1288 if (e->defwrt_type == DEFWRT_SEGMENT)
1289 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1290 else if (e->defwrt_type == DEFWRT_GROUP)
1291 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1292 else {
1293 nasm_error(ERR_NONFATAL, "default WRT specification for"
1294 " external `%s' unresolved", e->name);
1295 method |= 0x50, fidx = -1; /* got to do _something_ */
1297 } else
1298 method |= 0x50, fidx = -1;
1299 } else {
1301 * See if we can find the WRT-segment ID in our segment
1302 * list. If so, we have a F0 (LSEG) frame.
1304 for (s = seghead; s; s = s->next)
1305 if (s->index == wrt - 1)
1306 break;
1307 if (s)
1308 method |= 0x00, fidx = s->obj_index;
1309 else {
1310 for (g = grphead; g; g = g->next)
1311 if (g->index == wrt - 1)
1312 break;
1313 if (g)
1314 method |= 0x10, fidx = g->obj_index;
1315 else {
1316 int32_t i = wrt / 2;
1317 struct ExtBack *eb = ebhead;
1318 while (i >= EXT_BLKSIZ) {
1319 if (eb)
1320 eb = eb->next;
1321 else
1322 break;
1323 i -= EXT_BLKSIZ;
1325 if (eb)
1326 method |= 0x20, fidx = eb->exts[i]->index;
1327 else
1328 nasm_panic(0,
1329 "unrecognised WRT value in obj_write_fixup");
1334 forp = obj_byte(forp, method);
1335 if (fidx != -1)
1336 forp = obj_index(forp, fidx);
1337 forp = obj_index(forp, tidx);
1338 obj_commit(forp);
1341 static int32_t obj_segment(char *name, int pass, int *bits)
1344 * We call the label manager here to define a name for the new
1345 * segment, and when our _own_ label-definition stub gets
1346 * called in return, it should register the new segment name
1347 * using the pointer it gets passed. That way we save memory,
1348 * by sponging off the label manager.
1350 #if defined(DEBUG) && DEBUG>=3
1351 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1352 name, pass, *bits);
1353 #endif
1354 if (!name) {
1355 *bits = 16;
1356 current_seg = NULL;
1357 return first_seg;
1358 } else {
1359 struct Segment *seg;
1360 struct Group *grp;
1361 struct External **extp;
1362 int obj_idx, i, attrs;
1363 bool rn_error;
1364 char *p;
1367 * Look for segment attributes.
1369 attrs = 0;
1370 while (*name == '.')
1371 name++; /* hack, but a documented one */
1372 p = name;
1373 while (*p && !nasm_isspace(*p))
1374 p++;
1375 if (*p) {
1376 *p++ = '\0';
1377 while (*p && nasm_isspace(*p))
1378 *p++ = '\0';
1380 while (*p) {
1381 while (*p && !nasm_isspace(*p))
1382 p++;
1383 if (*p) {
1384 *p++ = '\0';
1385 while (*p && nasm_isspace(*p))
1386 *p++ = '\0';
1389 attrs++;
1392 obj_idx = 1;
1393 for (seg = seghead; seg; seg = seg->next) {
1394 obj_idx++;
1395 if (!strcmp(seg->name, name)) {
1396 if (attrs > 0 && pass == 1)
1397 nasm_error(ERR_WARNING, "segment attributes specified on"
1398 " redeclaration of segment: ignoring");
1399 if (seg->use32)
1400 *bits = 32;
1401 else
1402 *bits = 16;
1403 current_seg = seg;
1404 return seg->index;
1408 *segtail = seg = nasm_malloc(sizeof(*seg));
1409 seg->next = NULL;
1410 segtail = &seg->next;
1411 seg->index = (any_segs ? seg_alloc() : first_seg);
1412 seg->obj_index = obj_idx;
1413 seg->grp = NULL;
1414 any_segs = true;
1415 seg->name = NULL;
1416 seg->currentpos = 0;
1417 seg->align = 1; /* default */
1418 seg->use32 = false; /* default */
1419 seg->combine = CMB_PUBLIC; /* default */
1420 seg->segclass = seg->overlay = NULL;
1421 seg->pubhead = NULL;
1422 seg->pubtail = &seg->pubhead;
1423 seg->lochead = NULL;
1424 seg->loctail = &seg->lochead;
1425 seg->orp = obj_new();
1426 seg->orp->up = &(seg->orp);
1427 seg->orp->ori = ori_ledata;
1428 seg->orp->type = LEDATA;
1429 seg->orp->parm[1] = obj_idx;
1432 * Process the segment attributes.
1434 p = name;
1435 while (attrs--) {
1436 p += strlen(p);
1437 while (!*p)
1438 p++;
1441 * `p' contains a segment attribute.
1443 if (!nasm_stricmp(p, "private"))
1444 seg->combine = CMB_PRIVATE;
1445 else if (!nasm_stricmp(p, "public"))
1446 seg->combine = CMB_PUBLIC;
1447 else if (!nasm_stricmp(p, "common"))
1448 seg->combine = CMB_COMMON;
1449 else if (!nasm_stricmp(p, "stack"))
1450 seg->combine = CMB_STACK;
1451 else if (!nasm_stricmp(p, "use16"))
1452 seg->use32 = false;
1453 else if (!nasm_stricmp(p, "use32"))
1454 seg->use32 = true;
1455 else if (!nasm_stricmp(p, "flat")) {
1457 * This segment is an OS/2 FLAT segment. That means
1458 * that its default group is group FLAT, even if
1459 * the group FLAT does not explicitly _contain_ the
1460 * segment.
1462 * When we see this, we must create the group
1463 * `FLAT', containing no segments, if it does not
1464 * already exist; then we must set the default
1465 * group of this segment to be the FLAT group.
1467 struct Group *grp;
1468 for (grp = grphead; grp; grp = grp->next)
1469 if (!strcmp(grp->name, "FLAT"))
1470 break;
1471 if (!grp) {
1472 obj_directive(D_GROUP, "FLAT", 1);
1473 for (grp = grphead; grp; grp = grp->next)
1474 if (!strcmp(grp->name, "FLAT"))
1475 break;
1476 if (!grp)
1477 nasm_panic(0, "failure to define FLAT?!");
1479 seg->grp = grp;
1480 } else if (!nasm_strnicmp(p, "class=", 6))
1481 seg->segclass = nasm_strdup(p + 6);
1482 else if (!nasm_strnicmp(p, "overlay=", 8))
1483 seg->overlay = nasm_strdup(p + 8);
1484 else if (!nasm_strnicmp(p, "align=", 6)) {
1485 seg->align = readnum(p + 6, &rn_error);
1486 if (rn_error) {
1487 seg->align = 1;
1488 nasm_error(ERR_NONFATAL, "segment alignment should be"
1489 " numeric");
1491 switch (seg->align) {
1492 case 1: /* BYTE */
1493 case 2: /* WORD */
1494 case 4: /* DWORD */
1495 case 16: /* PARA */
1496 case 256: /* PAGE */
1497 case 4096: /* PharLap extension */
1498 break;
1499 case 8:
1500 nasm_error(ERR_WARNING,
1501 "OBJ format does not support alignment"
1502 " of 8: rounding up to 16");
1503 seg->align = 16;
1504 break;
1505 case 32:
1506 case 64:
1507 case 128:
1508 nasm_error(ERR_WARNING,
1509 "OBJ format does not support alignment"
1510 " of %d: rounding up to 256", seg->align);
1511 seg->align = 256;
1512 break;
1513 case 512:
1514 case 1024:
1515 case 2048:
1516 nasm_error(ERR_WARNING,
1517 "OBJ format does not support alignment"
1518 " of %d: rounding up to 4096", seg->align);
1519 seg->align = 4096;
1520 break;
1521 default:
1522 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1523 seg->align);
1524 seg->align = 1;
1525 break;
1527 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1528 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1529 if (rn_error)
1530 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1531 " attribute should be numeric");
1535 /* We need to know whenever we have at least one 32-bit segment */
1536 obj_use32 |= seg->use32;
1538 obj_seg_needs_update = seg;
1539 if (seg->align >= SEG_ABS)
1540 define_label(name, NO_SEG, seg->align - SEG_ABS,
1541 NULL, false, false);
1542 else
1543 define_label(name, seg->index + 1, 0L,
1544 NULL, false, false);
1545 obj_seg_needs_update = NULL;
1548 * See if this segment is defined in any groups.
1550 for (grp = grphead; grp; grp = grp->next) {
1551 for (i = grp->nindices; i < grp->nentries; i++) {
1552 if (!strcmp(grp->segs[i].name, seg->name)) {
1553 nasm_free(grp->segs[i].name);
1554 grp->segs[i] = grp->segs[grp->nindices];
1555 grp->segs[grp->nindices++].index = seg->obj_index;
1556 if (seg->grp)
1557 nasm_error(ERR_WARNING,
1558 "segment `%s' is already part of"
1559 " a group: first one takes precedence",
1560 seg->name);
1561 else
1562 seg->grp = grp;
1568 * Walk through the list of externals with unresolved
1569 * default-WRT clauses, and resolve any that point at this
1570 * segment.
1572 extp = &dws;
1573 while (*extp) {
1574 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1575 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1576 nasm_free((*extp)->defwrt_ptr.string);
1577 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1578 (*extp)->defwrt_ptr.seg = seg;
1579 *extp = (*extp)->next_dws;
1580 } else
1581 extp = &(*extp)->next_dws;
1584 if (seg->use32)
1585 *bits = 32;
1586 else
1587 *bits = 16;
1588 current_seg = seg;
1589 return seg->index;
1593 static enum directive_result
1594 obj_directive(enum directive directive, char *value, int pass)
1596 switch (directive) {
1597 case D_GROUP:
1599 char *p, *q, *v;
1600 if (pass == 1) {
1601 struct Group *grp;
1602 struct Segment *seg;
1603 struct External **extp;
1604 int obj_idx;
1606 q = value;
1607 while (*q == '.')
1608 q++; /* hack, but a documented one */
1609 v = q;
1610 while (*q && !nasm_isspace(*q))
1611 q++;
1612 if (nasm_isspace(*q)) {
1613 *q++ = '\0';
1614 while (*q && nasm_isspace(*q))
1615 q++;
1618 * Here we used to sanity-check the group directive to
1619 * ensure nobody tried to declare a group containing no
1620 * segments. However, OS/2 does this as standard
1621 * practice, so the sanity check has been removed.
1623 * if (!*q) {
1624 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1625 * return DIRR_ERROR;
1629 obj_idx = 1;
1630 for (grp = grphead; grp; grp = grp->next) {
1631 obj_idx++;
1632 if (!strcmp(grp->name, v)) {
1633 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1634 return DIRR_ERROR;
1638 *grptail = grp = nasm_malloc(sizeof(*grp));
1639 grp->next = NULL;
1640 grptail = &grp->next;
1641 grp->index = seg_alloc();
1642 grp->obj_index = obj_idx;
1643 grp->nindices = grp->nentries = 0;
1644 grp->name = NULL;
1646 obj_grp_needs_update = grp;
1647 define_label(v, grp->index + 1, 0L, NULL, false, false);
1648 obj_grp_needs_update = NULL;
1650 while (*q) {
1651 p = q;
1652 while (*q && !nasm_isspace(*q))
1653 q++;
1654 if (nasm_isspace(*q)) {
1655 *q++ = '\0';
1656 while (*q && nasm_isspace(*q))
1657 q++;
1660 * Now p contains a segment name. Find it.
1662 for (seg = seghead; seg; seg = seg->next)
1663 if (!strcmp(seg->name, p))
1664 break;
1665 if (seg) {
1667 * We have a segment index. Shift a name entry
1668 * to the end of the array to make room.
1670 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1671 grp->segs[grp->nindices++].index = seg->obj_index;
1672 if (seg->grp)
1673 nasm_error(ERR_WARNING,
1674 "segment `%s' is already part of"
1675 " a group: first one takes precedence",
1676 seg->name);
1677 else
1678 seg->grp = grp;
1679 } else {
1681 * We have an as-yet undefined segment.
1682 * Remember its name, for later.
1684 grp->segs[grp->nentries++].name = nasm_strdup(p);
1689 * Walk through the list of externals with unresolved
1690 * default-WRT clauses, and resolve any that point at
1691 * this group.
1693 extp = &dws;
1694 while (*extp) {
1695 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1696 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1697 nasm_free((*extp)->defwrt_ptr.string);
1698 (*extp)->defwrt_type = DEFWRT_GROUP;
1699 (*extp)->defwrt_ptr.grp = grp;
1700 *extp = (*extp)->next_dws;
1701 } else
1702 extp = &(*extp)->next_dws;
1705 return DIRR_OK;
1707 case D_UPPERCASE:
1708 obj_uppercase = true;
1709 return DIRR_OK;
1711 case D_IMPORT:
1713 char *q, *extname, *libname, *impname;
1715 if (pass == 2)
1716 return 1; /* ignore in pass two */
1717 extname = q = value;
1718 while (*q && !nasm_isspace(*q))
1719 q++;
1720 if (nasm_isspace(*q)) {
1721 *q++ = '\0';
1722 while (*q && nasm_isspace(*q))
1723 q++;
1726 libname = q;
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 impname = q;
1737 if (!*extname || !*libname)
1738 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1739 " and library name");
1740 else {
1741 struct ImpDef *imp;
1742 bool err = false;
1744 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1745 imptail = &imp->next;
1746 imp->next = NULL;
1747 imp->extname = nasm_strdup(extname);
1748 imp->libname = nasm_strdup(libname);
1749 imp->impindex = readnum(impname, &err);
1750 if (!*impname || err)
1751 imp->impname = nasm_strdup(impname);
1752 else
1753 imp->impname = NULL;
1756 return DIRR_OK;
1758 case D_EXPORT:
1760 char *q, *extname, *intname, *v;
1761 struct ExpDef *export;
1762 int flags = 0;
1763 unsigned int ordinal = 0;
1765 if (pass == 2)
1766 return DIRR_OK; /* ignore in pass two */
1767 intname = q = value;
1768 while (*q && !nasm_isspace(*q))
1769 q++;
1770 if (nasm_isspace(*q)) {
1771 *q++ = '\0';
1772 while (*q && nasm_isspace(*q))
1773 q++;
1776 extname = q;
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 if (!*intname) {
1786 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1787 return DIRR_OK;
1789 if (!*extname) {
1790 extname = intname;
1791 intname = "";
1793 while (*q) {
1794 v = q;
1795 while (*q && !nasm_isspace(*q))
1796 q++;
1797 if (nasm_isspace(*q)) {
1798 *q++ = '\0';
1799 while (*q && nasm_isspace(*q))
1800 q++;
1802 if (!nasm_stricmp(v, "resident"))
1803 flags |= EXPDEF_FLAG_RESIDENT;
1804 else if (!nasm_stricmp(v, "nodata"))
1805 flags |= EXPDEF_FLAG_NODATA;
1806 else if (!nasm_strnicmp(v, "parm=", 5)) {
1807 bool err = false;
1808 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1809 if (err) {
1810 nasm_error(ERR_NONFATAL,
1811 "value `%s' for `parm' is non-numeric", v + 5);
1812 return DIRR_ERROR;
1814 } else {
1815 bool err = false;
1816 ordinal = readnum(v, &err);
1817 if (err) {
1818 nasm_error(ERR_NONFATAL,
1819 "unrecognised export qualifier `%s'", v);
1820 return DIRR_ERROR;
1822 flags |= EXPDEF_FLAG_ORDINAL;
1826 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1827 exptail = &export->next;
1828 export->next = NULL;
1829 export->extname = nasm_strdup(extname);
1830 export->intname = nasm_strdup(intname);
1831 export->ordinal = ordinal;
1832 export->flags = flags;
1834 return DIRR_OK;
1836 default:
1837 return DIRR_UNKNOWN;
1841 static void obj_sectalign(int32_t seg, unsigned int value)
1843 struct Segment *s;
1845 list_for_each(s, seghead) {
1846 if (s->index == seg)
1847 break;
1851 * it should not be too big value
1852 * and applied on non-absolute sections
1854 if (!s || !is_power2(value) ||
1855 value > 4096 || s->align >= SEG_ABS)
1856 return;
1859 * FIXME: No code duplication please
1860 * consider making helper for this
1861 * mapping since section handler has
1862 * to do the same
1864 switch (value) {
1865 case 8:
1866 value = 16;
1867 break;
1868 case 32:
1869 case 64:
1870 case 128:
1871 value = 256;
1872 break;
1873 case 512:
1874 case 1024:
1875 case 2048:
1876 value = 4096;
1877 break;
1880 if (s->align < (int)value)
1881 s->align = value;
1884 static int32_t obj_segbase(int32_t segment)
1886 struct Segment *seg;
1889 * Find the segment in our list.
1891 for (seg = seghead; seg; seg = seg->next)
1892 if (seg->index == segment - 1)
1893 break;
1895 if (!seg) {
1897 * Might be an external with a default WRT.
1899 int32_t i = segment / 2;
1900 struct ExtBack *eb = ebhead;
1901 struct External *e;
1903 while (i >= EXT_BLKSIZ) {
1904 if (eb)
1905 eb = eb->next;
1906 else
1907 break;
1908 i -= EXT_BLKSIZ;
1910 if (eb) {
1911 e = eb->exts[i];
1912 if (!e) {
1913 nasm_assert(pass0 == 0);
1914 /* Not available - can happen during optimization */
1915 return NO_SEG;
1918 switch (e->defwrt_type) {
1919 case DEFWRT_NONE:
1920 return segment; /* fine */
1921 case DEFWRT_SEGMENT:
1922 return e->defwrt_ptr.seg->index + 1;
1923 case DEFWRT_GROUP:
1924 return e->defwrt_ptr.grp->index + 1;
1925 default:
1926 return NO_SEG; /* can't tell what it is */
1930 return segment; /* not one of ours - leave it alone */
1933 if (seg->align >= SEG_ABS)
1934 return seg->align; /* absolute segment */
1935 if (seg->grp)
1936 return seg->grp->index + 1; /* grouped segment */
1938 return segment; /* no special treatment */
1941 static void obj_filename(char *inname, char *outname)
1943 strcpy(obj_infile, inname);
1944 standard_extension(inname, outname, ".obj");
1947 static void obj_write_file(void)
1949 struct Segment *seg, *entry_seg_ptr = 0;
1950 struct FileName *fn;
1951 struct LineNumber *ln;
1952 struct Group *grp;
1953 struct Public *pub, *loc;
1954 struct External *ext;
1955 struct ImpDef *imp;
1956 struct ExpDef *export;
1957 int lname_idx;
1958 ObjRecord *orp;
1959 const bool debuginfo = (dfmt == &borland_debug_form);
1962 * Write the THEADR module header.
1964 orp = obj_new();
1965 orp->type = THEADR;
1966 obj_name(orp, obj_infile);
1967 obj_emit2(orp);
1970 * Write the NASM boast comment.
1972 orp->type = COMENT;
1973 obj_rword(orp, 0); /* comment type zero */
1974 obj_name(orp, nasm_comment);
1975 obj_emit2(orp);
1977 orp->type = COMENT;
1979 * Write the IMPDEF records, if any.
1981 for (imp = imphead; imp; imp = imp->next) {
1982 obj_rword(orp, 0xA0); /* comment class A0 */
1983 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1984 if (imp->impname)
1985 obj_byte(orp, 0); /* import by name */
1986 else
1987 obj_byte(orp, 1); /* import by ordinal */
1988 obj_name(orp, imp->extname);
1989 obj_name(orp, imp->libname);
1990 if (imp->impname)
1991 obj_name(orp, imp->impname);
1992 else
1993 obj_word(orp, imp->impindex);
1994 obj_emit2(orp);
1998 * Write the EXPDEF records, if any.
2000 for (export = exphead; export; export = export->next) {
2001 obj_rword(orp, 0xA0); /* comment class A0 */
2002 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
2003 obj_byte(orp, export->flags);
2004 obj_name(orp, export->extname);
2005 obj_name(orp, export->intname);
2006 if (export->flags & EXPDEF_FLAG_ORDINAL)
2007 obj_word(orp, export->ordinal);
2008 obj_emit2(orp);
2011 /* we're using extended OMF if we put in debug info */
2012 if (debuginfo) {
2013 orp->type = COMENT;
2014 obj_byte(orp, 0x40);
2015 obj_byte(orp, dEXTENDED);
2016 obj_emit2(orp);
2020 * Write the first LNAMES record, containing LNAME one, which
2021 * is null. Also initialize the LNAME counter.
2023 orp->type = LNAMES;
2024 obj_byte(orp, 0);
2025 lname_idx = 1;
2027 * Write some LNAMES for the segment names
2029 for (seg = seghead; seg; seg = seg->next) {
2030 orp = obj_name(orp, seg->name);
2031 if (seg->segclass)
2032 orp = obj_name(orp, seg->segclass);
2033 if (seg->overlay)
2034 orp = obj_name(orp, seg->overlay);
2035 obj_commit(orp);
2038 * Write some LNAMES for the group names
2040 for (grp = grphead; grp; grp = grp->next) {
2041 orp = obj_name(orp, grp->name);
2042 obj_commit(orp);
2044 obj_emit(orp);
2047 * Write the SEGDEF records.
2049 orp->type = SEGDEF;
2050 for (seg = seghead; seg; seg = seg->next) {
2051 int acbp;
2052 uint32_t seglen = seg->currentpos;
2054 acbp = (seg->combine << 2); /* C field */
2056 if (seg->use32)
2057 acbp |= 0x01; /* P bit is Use32 flag */
2058 else if (seglen == 0x10000L) {
2059 seglen = 0; /* This special case may be needed for old linkers */
2060 acbp |= 0x02; /* B bit */
2063 /* A field */
2064 if (seg->align >= SEG_ABS)
2065 /* acbp |= 0x00 */ ;
2066 else if (seg->align >= 4096) {
2067 if (seg->align > 4096)
2068 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2069 " than OBJ format supports", seg->name);
2070 acbp |= 0xC0; /* PharLap extension */
2071 } else if (seg->align >= 256) {
2072 acbp |= 0x80;
2073 } else if (seg->align >= 16) {
2074 acbp |= 0x60;
2075 } else if (seg->align >= 4) {
2076 acbp |= 0xA0;
2077 } else if (seg->align >= 2) {
2078 acbp |= 0x40;
2079 } else
2080 acbp |= 0x20;
2082 obj_byte(orp, acbp);
2083 if (seg->align & SEG_ABS) {
2084 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2085 obj_byte(orp, 0); /* Offset */
2087 obj_x(orp, seglen);
2088 obj_index(orp, ++lname_idx);
2089 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2090 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2091 obj_emit2(orp);
2095 * Write the GRPDEF records.
2097 orp->type = GRPDEF;
2098 for (grp = grphead; grp; grp = grp->next) {
2099 int i;
2101 if (grp->nindices != grp->nentries) {
2102 for (i = grp->nindices; i < grp->nentries; i++) {
2103 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2104 " `%s'", grp->name, grp->segs[i].name);
2105 nasm_free(grp->segs[i].name);
2106 grp->segs[i].name = NULL;
2109 obj_index(orp, ++lname_idx);
2110 for (i = 0; i < grp->nindices; i++) {
2111 obj_byte(orp, 0xFF);
2112 obj_index(orp, grp->segs[i].index);
2114 obj_emit2(orp);
2118 * Write the PUBDEF records: first the ones in the segments,
2119 * then the far-absolutes.
2121 orp->type = PUBDEF;
2122 orp->ori = ori_pubdef;
2123 for (seg = seghead; seg; seg = seg->next) {
2124 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2125 orp->parm[1] = seg->obj_index;
2126 for (pub = seg->pubhead; pub; pub = pub->next) {
2127 orp = obj_name(orp, pub->name);
2128 orp = obj_x(orp, pub->offset);
2129 orp = obj_byte(orp, 0); /* type index */
2130 obj_commit(orp);
2132 obj_emit(orp);
2134 orp->parm[0] = 0;
2135 orp->parm[1] = 0;
2136 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2137 if (orp->parm[2] != (uint32_t)pub->segment) {
2138 obj_emit(orp);
2139 orp->parm[2] = pub->segment;
2141 orp = obj_name(orp, pub->name);
2142 orp = obj_x(orp, pub->offset);
2143 orp = obj_byte(orp, 0); /* type index */
2144 obj_commit(orp);
2146 obj_emit(orp);
2149 * Write the EXTDEF and COMDEF records, in order.
2151 orp->ori = ori_null;
2152 for (ext = exthead; ext; ext = ext->next) {
2153 if (ext->commonsize == 0) {
2154 if (orp->type != EXTDEF) {
2155 obj_emit(orp);
2156 orp->type = EXTDEF;
2158 orp = obj_name(orp, ext->name);
2159 orp = obj_index(orp, 0);
2160 } else {
2161 if (orp->type != COMDEF) {
2162 obj_emit(orp);
2163 orp->type = COMDEF;
2165 orp = obj_name(orp, ext->name);
2166 orp = obj_index(orp, 0);
2167 if (ext->commonelem) {
2168 orp = obj_byte(orp, 0x61); /* far communal */
2169 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2170 orp = obj_value(orp, ext->commonelem);
2171 } else {
2172 orp = obj_byte(orp, 0x62); /* near communal */
2173 orp = obj_value(orp, ext->commonsize);
2176 obj_commit(orp);
2178 obj_emit(orp);
2181 * Write a COMENT record stating that the linker's first pass
2182 * may stop processing at this point. Exception is if our
2183 * MODEND record specifies a start point, in which case,
2184 * according to some variants of the documentation, this COMENT
2185 * should be omitted. So we'll omit it just in case.
2186 * But, TASM puts it in all the time so if we are using
2187 * TASM debug stuff we are putting it in
2189 if (debuginfo || obj_entry_seg == NO_SEG) {
2190 orp->type = COMENT;
2191 obj_byte(orp, 0x40);
2192 obj_byte(orp, dLINKPASS);
2193 obj_byte(orp, 1);
2194 obj_emit2(orp);
2198 * 1) put out the compiler type
2199 * 2) Put out the type info. The only type we are using is near label #19
2201 if (debuginfo) {
2202 int i;
2203 struct Array *arrtmp = arrhead;
2204 orp->type = COMENT;
2205 obj_byte(orp, 0x40);
2206 obj_byte(orp, dCOMPDEF);
2207 obj_byte(orp, 4);
2208 obj_byte(orp, 0);
2209 obj_emit2(orp);
2211 obj_byte(orp, 0x40);
2212 obj_byte(orp, dTYPEDEF);
2213 obj_word(orp, 0x18); /* type # for linking */
2214 obj_word(orp, 6); /* size of type */
2215 obj_byte(orp, 0x2a); /* absolute type for debugging */
2216 obj_emit2(orp);
2217 obj_byte(orp, 0x40);
2218 obj_byte(orp, dTYPEDEF);
2219 obj_word(orp, 0x19); /* type # for linking */
2220 obj_word(orp, 0); /* size of type */
2221 obj_byte(orp, 0x24); /* absolute type for debugging */
2222 obj_byte(orp, 0); /* near/far specifier */
2223 obj_emit2(orp);
2224 obj_byte(orp, 0x40);
2225 obj_byte(orp, dTYPEDEF);
2226 obj_word(orp, 0x1A); /* type # for linking */
2227 obj_word(orp, 0); /* size of type */
2228 obj_byte(orp, 0x24); /* absolute type for debugging */
2229 obj_byte(orp, 1); /* near/far specifier */
2230 obj_emit2(orp);
2231 obj_byte(orp, 0x40);
2232 obj_byte(orp, dTYPEDEF);
2233 obj_word(orp, 0x1b); /* type # for linking */
2234 obj_word(orp, 0); /* size of type */
2235 obj_byte(orp, 0x23); /* absolute type for debugging */
2236 obj_byte(orp, 0);
2237 obj_byte(orp, 0);
2238 obj_byte(orp, 0);
2239 obj_emit2(orp);
2240 obj_byte(orp, 0x40);
2241 obj_byte(orp, dTYPEDEF);
2242 obj_word(orp, 0x1c); /* 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, 4);
2247 obj_byte(orp, 0);
2248 obj_emit2(orp);
2249 obj_byte(orp, 0x40);
2250 obj_byte(orp, dTYPEDEF);
2251 obj_word(orp, 0x1d); /* 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, 1);
2256 obj_byte(orp, 0);
2257 obj_emit2(orp);
2258 obj_byte(orp, 0x40);
2259 obj_byte(orp, dTYPEDEF);
2260 obj_word(orp, 0x1e); /* 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, 5);
2265 obj_byte(orp, 0);
2266 obj_emit2(orp);
2268 /* put out the array types */
2269 for (i = ARRAYBOT; i < arrindex; i++) {
2270 obj_byte(orp, 0x40);
2271 obj_byte(orp, dTYPEDEF);
2272 obj_word(orp, i); /* type # for linking */
2273 obj_word(orp, arrtmp->size); /* size of type */
2274 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2275 obj_byte(orp, arrtmp->basetype); /* base type */
2276 obj_emit2(orp);
2277 arrtmp = arrtmp->next;
2281 * write out line number info with a LINNUM record
2282 * switch records when we switch segments, and output the
2283 * file in a pseudo-TASM fashion. The record switch is naive; that
2284 * is that one file may have many records for the same segment
2285 * if there are lots of segment switches
2287 if (fnhead && debuginfo) {
2288 seg = fnhead->lnhead->segment;
2290 for (fn = fnhead; fn; fn = fn->next) {
2291 /* write out current file name */
2292 orp->type = COMENT;
2293 orp->ori = ori_null;
2294 obj_byte(orp, 0x40);
2295 obj_byte(orp, dFILNAME);
2296 obj_byte(orp, 0);
2297 obj_name(orp, fn->name);
2298 obj_dword(orp, 0);
2299 obj_emit2(orp);
2301 /* write out line numbers this file */
2303 orp->type = LINNUM;
2304 orp->ori = ori_linnum;
2305 for (ln = fn->lnhead; ln; ln = ln->next) {
2306 if (seg != ln->segment) {
2307 /* if we get here have to flush the buffer and start
2308 * a new record for a new segment
2310 seg = ln->segment;
2311 obj_emit(orp);
2313 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2314 orp->parm[1] = seg->obj_index;
2315 orp = obj_word(orp, ln->lineno);
2316 orp = obj_x(orp, ln->offset);
2317 obj_commit(orp);
2319 obj_emit(orp);
2323 * we are going to locate the entry point segment now
2324 * rather than wait until the MODEND record, because,
2325 * then we can output a special symbol to tell where the
2326 * entry point is.
2329 if (obj_entry_seg != NO_SEG) {
2330 for (seg = seghead; seg; seg = seg->next) {
2331 if (seg->index == obj_entry_seg) {
2332 entry_seg_ptr = seg;
2333 break;
2336 if (!seg)
2337 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2341 * get ready to put out symbol records
2343 orp->type = COMENT;
2344 orp->ori = ori_local;
2347 * put out a symbol for the entry point
2348 * no dots in this symbol, because, borland does
2349 * not (officially) support dots in label names
2350 * and I don't know what various versions of TLINK will do
2352 if (debuginfo && obj_entry_seg != NO_SEG) {
2353 orp = obj_name(orp, "start_of_program");
2354 orp = obj_word(orp, 0x19); /* type: near label */
2355 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2356 orp = obj_index(orp, seg->obj_index);
2357 orp = obj_x(orp, obj_entry_ofs);
2358 obj_commit(orp);
2362 * put out the local labels
2364 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2365 /* labels this seg */
2366 for (loc = seg->lochead; loc; loc = loc->next) {
2367 orp = obj_name(orp, loc->name);
2368 orp = obj_word(orp, loc->type);
2369 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2370 orp = obj_index(orp, seg->obj_index);
2371 orp = obj_x(orp, loc->offset);
2372 obj_commit(orp);
2375 if (orp->used)
2376 obj_emit(orp);
2379 * Write the LEDATA/FIXUPP pairs.
2381 for (seg = seghead; seg; seg = seg->next) {
2382 obj_emit(seg->orp);
2383 nasm_free(seg->orp);
2387 * Write the MODEND module end marker.
2389 orp->type = obj_use32 ? MODE32 : MODEND;
2390 orp->ori = ori_null;
2391 if (entry_seg_ptr) {
2392 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2393 obj_byte(orp, 0xC1);
2394 seg = entry_seg_ptr;
2395 if (seg->grp) {
2396 obj_byte(orp, 0x10);
2397 obj_index(orp, seg->grp->obj_index);
2398 } else {
2400 * the below changed to prevent TLINK crashing.
2401 * Previous more efficient version read:
2403 * obj_byte (orp, 0x50);
2405 obj_byte(orp, 0x00);
2406 obj_index(orp, seg->obj_index);
2408 obj_index(orp, seg->obj_index);
2409 obj_x(orp, obj_entry_ofs);
2410 } else
2411 obj_byte(orp, 0);
2412 obj_emit2(orp);
2413 nasm_free(orp);
2416 static void obj_fwrite(ObjRecord * orp)
2418 unsigned int cksum, len;
2419 uint8_t *ptr;
2421 cksum = orp->type;
2422 if (orp->x_size == 32)
2423 cksum |= 1;
2424 fputc(cksum, ofile);
2425 len = orp->committed + 1;
2426 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2427 fwriteint16_t(len, ofile);
2428 nasm_write(orp->buf, len-1, ofile);
2429 for (ptr = orp->buf; --len; ptr++)
2430 cksum += *ptr;
2431 fputc((-cksum) & 0xFF, ofile);
2434 extern macros_t obj_stdmac[];
2436 static void dbgbi_init(void)
2438 fnhead = NULL;
2439 fntail = &fnhead;
2440 arrindex = ARRAYBOT;
2441 arrhead = NULL;
2442 arrtail = &arrhead;
2444 static void dbgbi_cleanup(void)
2446 struct Segment *segtmp;
2447 while (fnhead) {
2448 struct FileName *fntemp = fnhead;
2449 while (fnhead->lnhead) {
2450 struct LineNumber *lntemp = fnhead->lnhead;
2451 fnhead->lnhead = lntemp->next;
2452 nasm_free(lntemp);
2454 fnhead = fnhead->next;
2455 nasm_free(fntemp->name);
2456 nasm_free(fntemp);
2458 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2459 while (segtmp->lochead) {
2460 struct Public *loctmp = segtmp->lochead;
2461 segtmp->lochead = loctmp->next;
2462 nasm_free(loctmp->name);
2463 nasm_free(loctmp);
2466 while (arrhead) {
2467 struct Array *arrtmp = arrhead;
2468 arrhead = arrhead->next;
2469 nasm_free(arrtmp);
2473 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2475 struct FileName *fn;
2476 struct LineNumber *ln;
2477 struct Segment *seg;
2479 if (segto == NO_SEG)
2480 return;
2483 * If `any_segs' is still false, we must define a default
2484 * segment.
2486 if (!any_segs) {
2487 int tempint; /* ignored */
2488 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2489 nasm_panic(0, "strange segment conditions in OBJ driver");
2493 * Find the segment we are targetting.
2495 for (seg = seghead; seg; seg = seg->next)
2496 if (seg->index == segto)
2497 break;
2498 if (!seg)
2499 nasm_panic(0, "lineno directed to nonexistent segment?");
2501 /* for (fn = fnhead; fn; fn = fnhead->next) */
2502 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2503 if (!nasm_stricmp(lnfname, fn->name))
2504 break;
2505 if (!fn) {
2506 fn = nasm_malloc(sizeof(*fn));
2507 fn->name = nasm_malloc(strlen(lnfname) + 1);
2508 strcpy(fn->name, lnfname);
2509 fn->lnhead = NULL;
2510 fn->lntail = &fn->lnhead;
2511 fn->next = NULL;
2512 *fntail = fn;
2513 fntail = &fn->next;
2515 ln = nasm_malloc(sizeof(*ln));
2516 ln->segment = seg;
2517 ln->offset = seg->currentpos;
2518 ln->lineno = lineno;
2519 ln->next = NULL;
2520 *fn->lntail = ln;
2521 fn->lntail = &ln->next;
2524 static void dbgbi_deflabel(char *name, int32_t segment,
2525 int64_t offset, int is_global, char *special)
2527 struct Segment *seg;
2529 (void)special;
2532 * Note: ..[^@] special symbols are filtered in labels.c
2536 * If it's a special-retry from pass two, discard it.
2538 if (is_global == 3)
2539 return;
2542 * Case (i):
2544 if (obj_seg_needs_update) {
2545 return;
2546 } else if (obj_grp_needs_update) {
2547 return;
2549 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2550 return;
2552 if (segment >= SEG_ABS || segment == NO_SEG) {
2553 return;
2557 * If `any_segs' is still false, we might need to define a
2558 * default segment, if they're trying to declare a label in
2559 * `first_seg'. But the label should exist due to a prior
2560 * call to obj_deflabel so we can skip that.
2563 for (seg = seghead; seg; seg = seg->next)
2564 if (seg->index == segment) {
2565 struct Public *loc = nasm_malloc(sizeof(*loc));
2567 * Case (ii). Maybe MODPUB someday?
2569 last_defined = *seg->loctail = loc;
2570 seg->loctail = &loc->next;
2571 loc->next = NULL;
2572 loc->name = nasm_strdup(name);
2573 loc->offset = offset;
2576 static void dbgbi_typevalue(int32_t type)
2578 int vsize;
2579 int elem = TYM_ELEMENTS(type);
2580 type = TYM_TYPE(type);
2582 if (!last_defined)
2583 return;
2585 switch (type) {
2586 case TY_BYTE:
2587 last_defined->type = 8; /* uint8_t */
2588 vsize = 1;
2589 break;
2590 case TY_WORD:
2591 last_defined->type = 10; /* unsigned word */
2592 vsize = 2;
2593 break;
2594 case TY_DWORD:
2595 last_defined->type = 12; /* unsigned dword */
2596 vsize = 4;
2597 break;
2598 case TY_FLOAT:
2599 last_defined->type = 14; /* float */
2600 vsize = 4;
2601 break;
2602 case TY_QWORD:
2603 last_defined->type = 15; /* qword */
2604 vsize = 8;
2605 break;
2606 case TY_TBYTE:
2607 last_defined->type = 16; /* TBYTE */
2608 vsize = 10;
2609 break;
2610 default:
2611 last_defined->type = 0x19; /*label */
2612 vsize = 0;
2613 break;
2616 if (elem > 1) {
2617 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2618 int vtype = last_defined->type;
2619 arrtmp->size = vsize * elem;
2620 arrtmp->basetype = vtype;
2621 arrtmp->next = NULL;
2622 last_defined->type = arrindex++;
2623 *arrtail = arrtmp;
2624 arrtail = &(arrtmp->next);
2626 last_defined = NULL;
2628 static void dbgbi_output(int output_type, void *param)
2630 (void)output_type;
2631 (void)param;
2633 static const struct dfmt borland_debug_form = {
2634 "Borland Debug Records",
2635 "borland",
2636 dbgbi_init,
2637 dbgbi_linnum,
2638 dbgbi_deflabel,
2639 null_debug_directive,
2640 dbgbi_typevalue,
2641 dbgbi_output,
2642 dbgbi_cleanup,
2643 NULL /* pragma list */
2646 static const struct dfmt * const borland_debug_arr[3] = {
2647 &borland_debug_form,
2648 &null_debug_form,
2649 NULL
2652 const struct ofmt of_obj = {
2653 "MS-DOS 16-bit/32-bit OMF object files",
2654 "obj",
2657 borland_debug_arr,
2658 &borland_debug_form,
2659 obj_stdmac,
2660 obj_init,
2661 nasm_do_legacy_output,
2662 obj_out,
2663 obj_deflabel,
2664 obj_segment,
2665 obj_sectalign,
2666 obj_segbase,
2667 obj_directive,
2668 obj_filename,
2669 obj_cleanup,
2670 NULL /* pragma list */
2672 #endif /* OF_OBJ */