Add a generic pragma-handling infrastructure
[nasm.git] / output / outobj.c
blob39712a74323a8de65807f09dbc7e58e24bd7b90e
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 int obj_directive(enum directives, 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 int obj_set_info(enum geninfo type, char **val)
668 (void)type;
669 (void)val;
671 return 0;
674 static void obj_cleanup(void)
676 obj_write_file();
677 dfmt->cleanup();
678 while (seghead) {
679 struct Segment *segtmp = seghead;
680 seghead = seghead->next;
681 while (segtmp->pubhead) {
682 struct Public *pubtmp = segtmp->pubhead;
683 segtmp->pubhead = pubtmp->next;
684 nasm_free(pubtmp->name);
685 nasm_free(pubtmp);
687 nasm_free(segtmp->segclass);
688 nasm_free(segtmp->overlay);
689 nasm_free(segtmp);
691 while (fpubhead) {
692 struct Public *pubtmp = fpubhead;
693 fpubhead = fpubhead->next;
694 nasm_free(pubtmp->name);
695 nasm_free(pubtmp);
697 while (exthead) {
698 struct External *exttmp = exthead;
699 exthead = exthead->next;
700 nasm_free(exttmp);
702 while (imphead) {
703 struct ImpDef *imptmp = imphead;
704 imphead = imphead->next;
705 nasm_free(imptmp->extname);
706 nasm_free(imptmp->libname);
707 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
708 nasm_free(imptmp);
710 while (exphead) {
711 struct ExpDef *exptmp = exphead;
712 exphead = exphead->next;
713 nasm_free(exptmp->extname);
714 nasm_free(exptmp->intname);
715 nasm_free(exptmp);
717 while (ebhead) {
718 struct ExtBack *ebtmp = ebhead;
719 ebhead = ebhead->next;
720 nasm_free(ebtmp);
722 while (grphead) {
723 struct Group *grptmp = grphead;
724 grphead = grphead->next;
725 nasm_free(grptmp);
729 static void obj_ext_set_defwrt(struct External *ext, char *id)
731 struct Segment *seg;
732 struct Group *grp;
734 for (seg = seghead; seg; seg = seg->next)
735 if (!strcmp(seg->name, id)) {
736 ext->defwrt_type = DEFWRT_SEGMENT;
737 ext->defwrt_ptr.seg = seg;
738 nasm_free(id);
739 return;
742 for (grp = grphead; grp; grp = grp->next)
743 if (!strcmp(grp->name, id)) {
744 ext->defwrt_type = DEFWRT_GROUP;
745 ext->defwrt_ptr.grp = grp;
746 nasm_free(id);
747 return;
750 ext->defwrt_type = DEFWRT_STRING;
751 ext->defwrt_ptr.string = id;
752 ext->next_dws = dws;
753 dws = ext;
756 static void obj_deflabel(char *name, int32_t segment,
757 int64_t offset, int is_global, char *special)
760 * We have three cases:
762 * (i) `segment' is a segment-base. If so, set the name field
763 * for the segment or group structure it refers to, and then
764 * return.
766 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
767 * Save the label position for later output of a PUBDEF record.
768 * (Or a MODPUB, if we work out how.)
770 * (iii) `segment' is not one of our segments. Save the label
771 * position for later output of an EXTDEF, and also store a
772 * back-reference so that we can map later references to this
773 * segment number to the external index.
775 struct External *ext;
776 struct ExtBack *eb;
777 struct Segment *seg;
778 int i;
779 bool used_special = false; /* have we used the special text? */
781 #if defined(DEBUG) && DEBUG>2
782 nasm_error(ERR_DEBUG,
783 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
784 name, segment, offset, is_global, special);
785 #endif
788 * If it's a special-retry from pass two, discard it.
790 if (is_global == 3)
791 return;
794 * First check for the double-period, signifying something
795 * unusual.
797 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
798 if (!strcmp(name, "..start")) {
799 obj_entry_seg = segment;
800 obj_entry_ofs = offset;
801 return;
803 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
807 * Case (i):
809 if (obj_seg_needs_update) {
810 obj_seg_needs_update->name = name;
811 return;
812 } else if (obj_grp_needs_update) {
813 obj_grp_needs_update->name = name;
814 return;
816 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
817 return;
819 if (segment >= SEG_ABS || segment == NO_SEG) {
821 * SEG_ABS subcase of (ii).
823 if (is_global) {
824 struct Public *pub;
826 pub = *fpubtail = nasm_malloc(sizeof(*pub));
827 fpubtail = &pub->next;
828 pub->next = NULL;
829 pub->name = nasm_strdup(name);
830 pub->offset = offset;
831 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
833 if (special)
834 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
835 " for this symbol type");
836 return;
840 * If `any_segs' is still false, we might need to define a
841 * default segment, if they're trying to declare a label in
842 * `first_seg'.
844 if (!any_segs && segment == first_seg) {
845 int tempint; /* ignored */
846 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
847 nasm_panic(0, "strange segment conditions in OBJ driver");
850 for (seg = seghead; seg && is_global; seg = seg->next)
851 if (seg->index == segment) {
852 struct Public *loc = nasm_malloc(sizeof(*loc));
854 * Case (ii). Maybe MODPUB someday?
856 *seg->pubtail = loc;
857 seg->pubtail = &loc->next;
858 loc->next = NULL;
859 loc->name = nasm_strdup(name);
860 loc->offset = offset;
862 if (special)
863 nasm_error(ERR_NONFATAL,
864 "OBJ supports no special symbol features"
865 " for this symbol type");
866 return;
870 * Case (iii).
872 if (is_global) {
873 ext = *exttail = nasm_malloc(sizeof(*ext));
874 ext->next = NULL;
875 exttail = &ext->next;
876 ext->name = name;
877 /* Place by default all externs into the current segment */
878 ext->defwrt_type = DEFWRT_NONE;
880 /* 28-Apr-2002 - John Coffman
881 The following code was introduced on 12-Aug-2000, and breaks fixups
882 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
883 (5.10). It was introduced after FIXUP32 was added, and may be needed
884 for 32-bit segments. The following will get 16-bit segments working
885 again, and maybe someone can correct the 'if' condition which is
886 actually needed.
888 #if 0
889 if (current_seg) {
890 #else
891 if (current_seg && current_seg->use32) {
892 if (current_seg->grp) {
893 ext->defwrt_type = DEFWRT_GROUP;
894 ext->defwrt_ptr.grp = current_seg->grp;
895 } else {
896 ext->defwrt_type = DEFWRT_SEGMENT;
897 ext->defwrt_ptr.seg = current_seg;
900 #endif
902 if (is_global == 2) {
903 ext->commonsize = offset;
904 ext->commonelem = 1; /* default FAR */
905 } else
906 ext->commonsize = 0;
907 } else
908 return;
911 * Now process the special text, if any, to find default-WRT
912 * specifications and common-variable element-size and near/far
913 * specifications.
915 while (special && *special) {
916 used_special = true;
919 * We might have a default-WRT specification.
921 if (!nasm_strnicmp(special, "wrt", 3)) {
922 char *p;
923 int len;
924 special += 3;
925 special += strspn(special, " \t");
926 p = nasm_strndup(special, len = strcspn(special, ":"));
927 obj_ext_set_defwrt(ext, p);
928 special += len;
929 if (*special && *special != ':')
930 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
931 " text for `%s'", ext->name);
932 else if (*special == ':')
933 special++;
937 * The NEAR or FAR keywords specify nearness or
938 * farness. FAR gives default element size 1.
940 if (!nasm_strnicmp(special, "far", 3)) {
941 if (ext->commonsize)
942 ext->commonelem = 1;
943 else
944 nasm_error(ERR_NONFATAL,
945 "`%s': `far' keyword may only be applied"
946 " to common variables\n", ext->name);
947 special += 3;
948 special += strspn(special, " \t");
949 } else if (!nasm_strnicmp(special, "near", 4)) {
950 if (ext->commonsize)
951 ext->commonelem = 0;
952 else
953 nasm_error(ERR_NONFATAL,
954 "`%s': `far' keyword may only be applied"
955 " to common variables\n", ext->name);
956 special += 4;
957 special += strspn(special, " \t");
961 * If it's a common, and anything else remains on the line
962 * before a further colon, evaluate it as an expression and
963 * use that as the element size. Forward references aren't
964 * allowed.
966 if (*special == ':')
967 special++;
968 else if (*special) {
969 if (ext->commonsize) {
970 expr *e;
971 struct tokenval tokval;
973 stdscan_reset();
974 stdscan_set(special);
975 tokval.t_type = TOKEN_INVALID;
976 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
977 if (e) {
978 if (!is_simple(e))
979 nasm_error(ERR_NONFATAL, "cannot use relocatable"
980 " expression as common-variable element size");
981 else
982 ext->commonelem = reloc_value(e);
984 special = stdscan_get();
985 } else {
986 nasm_error(ERR_NONFATAL,
987 "`%s': element-size specifications only"
988 " apply to common variables", ext->name);
989 while (*special && *special != ':')
990 special++;
991 if (*special == ':')
992 special++;
997 i = segment / 2;
998 eb = ebhead;
999 if (!eb) {
1000 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1001 eb->next = NULL;
1002 ebtail = &eb->next;
1004 while (i >= EXT_BLKSIZ) {
1005 if (eb && eb->next)
1006 eb = eb->next;
1007 else {
1008 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1009 eb->next = NULL;
1010 ebtail = &eb->next;
1012 i -= EXT_BLKSIZ;
1014 eb->exts[i] = ext;
1015 ext->index = ++externals;
1017 if (special && !used_special)
1018 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1019 " for this symbol type");
1022 /* forward declaration */
1023 static void obj_write_fixup(ObjRecord * orp, int bytes,
1024 int segrel, int32_t seg, int32_t wrt,
1025 struct Segment *segto);
1027 static void obj_out(int32_t segto, const void *data,
1028 enum out_type type, uint64_t size,
1029 int32_t segment, int32_t wrt)
1031 const uint8_t *ucdata;
1032 int32_t ldata;
1033 struct Segment *seg;
1034 ObjRecord *orp;
1037 * handle absolute-assembly (structure definitions)
1039 if (segto == NO_SEG) {
1040 if (type != OUT_RESERVE)
1041 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1042 " space");
1043 return;
1047 * If `any_segs' is still false, we must define a default
1048 * segment.
1050 if (!any_segs) {
1051 int tempint; /* ignored */
1052 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1053 nasm_panic(0, "strange segment conditions in OBJ driver");
1057 * Find the segment we are targetting.
1059 for (seg = seghead; seg; seg = seg->next)
1060 if (seg->index == segto)
1061 break;
1062 if (!seg)
1063 nasm_panic(0, "code directed to nonexistent segment?");
1065 orp = seg->orp;
1066 orp->parm[0] = seg->currentpos;
1068 switch (type) {
1069 case OUT_RAWDATA:
1070 ucdata = data;
1071 while (size > 0) {
1072 unsigned int len;
1073 orp = obj_check(seg->orp, 1);
1074 len = RECORD_MAX - orp->used;
1075 if (len > size)
1076 len = size;
1077 memcpy(orp->buf + orp->used, ucdata, len);
1078 orp->committed = orp->used += len;
1079 orp->parm[0] = seg->currentpos += len;
1080 ucdata += len;
1081 size -= len;
1083 break;
1085 case OUT_ADDRESS:
1086 case OUT_REL1ADR:
1087 case OUT_REL2ADR:
1088 case OUT_REL4ADR:
1089 case OUT_REL8ADR:
1091 int rsize;
1093 if (type == OUT_ADDRESS)
1094 size = abs((int)size);
1096 if (segment == NO_SEG && type != OUT_ADDRESS)
1097 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1098 " supported by OBJ format");
1099 if (segment >= SEG_ABS)
1100 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1101 " by OBJ format");
1103 ldata = *(int64_t *)data;
1104 if (type != OUT_ADDRESS) {
1106 * For 16-bit and 32-bit x86 code, the size and realsize() always
1107 * matches as only jumps, calls and loops uses PC relative
1108 * addressing and the address isn't followed by any other opcode
1109 * bytes. In 64-bit mode there is RIP relative addressing which
1110 * means the fixup location can be followed by an immediate value,
1111 * meaning that size > realsize().
1113 * When the CPU is calculating the effective address, it takes the
1114 * RIP at the end of the instruction and adds the fixed up relative
1115 * address value to it.
1117 * The linker's point of reference is the end of the fixup location
1118 * (which is the end of the instruction for Jcc, CALL, LOOP[cc]).
1119 * It is calculating distance between the target symbol and the end
1120 * of the fixup location, and add this to the displacement value we
1121 * are calculating here and storing at the fixup location.
1123 * To get the right effect, we need to _reduce_ the displacement
1124 * value by the number of bytes following the fixup.
1126 * Example:
1127 * data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
1128 * end of fixup at 0x054, end of instruction at 0x058.
1129 * => size = 8.
1130 * => realsize() -> 4
1131 * => CPU needs a value of: 0x100 - 0x058 = 0x0a8
1132 * => linker/loader will add: 0x100 - 0x054 = 0x0ac
1133 * => We must add an addend of -4.
1134 * => realsize() - size = -4.
1136 * The code used to do size - realsize() at least since v0.90,
1137 * probably because it wasn't needed...
1139 ldata -= size;
1140 size = realsize(type, size);
1141 ldata += size;
1144 switch (size) {
1145 default:
1146 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1147 "32-byte relocations");
1148 segment = NO_SEG; /* Don't actually generate a relocation */
1149 break;
1150 case 2:
1151 orp = obj_word(orp, ldata);
1152 break;
1153 case 4:
1154 orp = obj_dword(orp, ldata);
1155 break;
1158 rsize = size;
1159 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1160 size == 4) {
1162 * This is a 4-byte segment-base relocation such as
1163 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1164 * these, but if the constant term has the 16 low bits
1165 * zero, we can just apply a 2-byte segment-base
1166 * relocation to the low word instead.
1168 rsize = 2;
1169 if (ldata & 0xFFFF)
1170 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1171 " dword-size segment base references");
1173 if (segment != NO_SEG)
1174 obj_write_fixup(orp, rsize,
1175 (type == OUT_ADDRESS ? 0x4000 : 0),
1176 segment, wrt, seg);
1177 seg->currentpos += size;
1178 break;
1181 default:
1182 nasm_error(ERR_NONFATAL,
1183 "Relocation type not supported by output format");
1184 /* fall through */
1186 case OUT_RESERVE:
1187 if (orp->committed)
1188 orp = obj_bump(orp);
1189 seg->currentpos += size;
1190 break;
1192 obj_commit(orp);
1195 static void obj_write_fixup(ObjRecord * orp, int bytes,
1196 int segrel, int32_t seg, int32_t wrt,
1197 struct Segment *segto)
1199 unsigned locat;
1200 int method;
1201 int base;
1202 int32_t tidx, fidx;
1203 struct Segment *s = NULL;
1204 struct Group *g = NULL;
1205 struct External *e = NULL;
1206 ObjRecord *forp;
1208 if (bytes != 2 && bytes != 4) {
1209 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1210 " %d-bit relocations", bytes << 3);
1211 return;
1214 forp = orp->child;
1215 if (forp == NULL) {
1216 orp->child = forp = obj_new();
1217 forp->up = &(orp->child);
1218 /* We should choose between FIXUPP and FIXU32 record type */
1219 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1220 if (segto->use32)
1221 forp->type = FIXU32;
1222 else
1223 forp->type = FIXUPP;
1226 if (seg % 2) {
1227 base = true;
1228 locat = FIX_16_SELECTOR;
1229 seg--;
1230 if (bytes != 2)
1231 nasm_panic(0, "OBJ: 4-byte segment base fixup got"
1232 " through sanity check");
1233 } else {
1234 base = false;
1235 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1236 if (!segrel)
1238 * There is a bug in tlink that makes it process self relative
1239 * fixups incorrectly if the x_size doesn't match the location
1240 * size.
1242 forp = obj_force(forp, bytes << 3);
1245 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1247 tidx = fidx = -1, method = 0; /* placate optimisers */
1250 * See if we can find the segment ID in our segment list. If
1251 * so, we have a T4 (LSEG) target.
1253 for (s = seghead; s; s = s->next)
1254 if (s->index == seg)
1255 break;
1256 if (s)
1257 method = 4, tidx = s->obj_index;
1258 else {
1259 for (g = grphead; g; g = g->next)
1260 if (g->index == seg)
1261 break;
1262 if (g)
1263 method = 5, tidx = g->obj_index;
1264 else {
1265 int32_t i = seg / 2;
1266 struct ExtBack *eb = ebhead;
1267 while (i >= EXT_BLKSIZ) {
1268 if (eb)
1269 eb = eb->next;
1270 else
1271 break;
1272 i -= EXT_BLKSIZ;
1274 if (eb)
1275 method = 6, e = eb->exts[i], tidx = e->index;
1276 else
1277 nasm_panic(0,
1278 "unrecognised segment value in obj_write_fixup");
1283 * If no WRT given, assume the natural default, which is method
1284 * F5 unless:
1286 * - we are doing an OFFSET fixup for a grouped segment, in
1287 * which case we require F1 (group).
1289 * - we are doing an OFFSET fixup for an external with a
1290 * default WRT, in which case we must honour the default WRT.
1292 if (wrt == NO_SEG) {
1293 if (!base && s && s->grp)
1294 method |= 0x10, fidx = s->grp->obj_index;
1295 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1296 if (e->defwrt_type == DEFWRT_SEGMENT)
1297 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1298 else if (e->defwrt_type == DEFWRT_GROUP)
1299 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1300 else {
1301 nasm_error(ERR_NONFATAL, "default WRT specification for"
1302 " external `%s' unresolved", e->name);
1303 method |= 0x50, fidx = -1; /* got to do _something_ */
1305 } else
1306 method |= 0x50, fidx = -1;
1307 } else {
1309 * See if we can find the WRT-segment ID in our segment
1310 * list. If so, we have a F0 (LSEG) frame.
1312 for (s = seghead; s; s = s->next)
1313 if (s->index == wrt - 1)
1314 break;
1315 if (s)
1316 method |= 0x00, fidx = s->obj_index;
1317 else {
1318 for (g = grphead; g; g = g->next)
1319 if (g->index == wrt - 1)
1320 break;
1321 if (g)
1322 method |= 0x10, fidx = g->obj_index;
1323 else {
1324 int32_t i = wrt / 2;
1325 struct ExtBack *eb = ebhead;
1326 while (i >= EXT_BLKSIZ) {
1327 if (eb)
1328 eb = eb->next;
1329 else
1330 break;
1331 i -= EXT_BLKSIZ;
1333 if (eb)
1334 method |= 0x20, fidx = eb->exts[i]->index;
1335 else
1336 nasm_panic(0,
1337 "unrecognised WRT value in obj_write_fixup");
1342 forp = obj_byte(forp, method);
1343 if (fidx != -1)
1344 forp = obj_index(forp, fidx);
1345 forp = obj_index(forp, tidx);
1346 obj_commit(forp);
1349 static int32_t obj_segment(char *name, int pass, int *bits)
1352 * We call the label manager here to define a name for the new
1353 * segment, and when our _own_ label-definition stub gets
1354 * called in return, it should register the new segment name
1355 * using the pointer it gets passed. That way we save memory,
1356 * by sponging off the label manager.
1358 #if defined(DEBUG) && DEBUG>=3
1359 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1360 name, pass, *bits);
1361 #endif
1362 if (!name) {
1363 *bits = 16;
1364 current_seg = NULL;
1365 return first_seg;
1366 } else {
1367 struct Segment *seg;
1368 struct Group *grp;
1369 struct External **extp;
1370 int obj_idx, i, attrs;
1371 bool rn_error;
1372 char *p;
1375 * Look for segment attributes.
1377 attrs = 0;
1378 while (*name == '.')
1379 name++; /* hack, but a documented one */
1380 p = name;
1381 while (*p && !nasm_isspace(*p))
1382 p++;
1383 if (*p) {
1384 *p++ = '\0';
1385 while (*p && nasm_isspace(*p))
1386 *p++ = '\0';
1388 while (*p) {
1389 while (*p && !nasm_isspace(*p))
1390 p++;
1391 if (*p) {
1392 *p++ = '\0';
1393 while (*p && nasm_isspace(*p))
1394 *p++ = '\0';
1397 attrs++;
1400 obj_idx = 1;
1401 for (seg = seghead; seg; seg = seg->next) {
1402 obj_idx++;
1403 if (!strcmp(seg->name, name)) {
1404 if (attrs > 0 && pass == 1)
1405 nasm_error(ERR_WARNING, "segment attributes specified on"
1406 " redeclaration of segment: ignoring");
1407 if (seg->use32)
1408 *bits = 32;
1409 else
1410 *bits = 16;
1411 current_seg = seg;
1412 return seg->index;
1416 *segtail = seg = nasm_malloc(sizeof(*seg));
1417 seg->next = NULL;
1418 segtail = &seg->next;
1419 seg->index = (any_segs ? seg_alloc() : first_seg);
1420 seg->obj_index = obj_idx;
1421 seg->grp = NULL;
1422 any_segs = true;
1423 seg->name = NULL;
1424 seg->currentpos = 0;
1425 seg->align = 1; /* default */
1426 seg->use32 = false; /* default */
1427 seg->combine = CMB_PUBLIC; /* default */
1428 seg->segclass = seg->overlay = NULL;
1429 seg->pubhead = NULL;
1430 seg->pubtail = &seg->pubhead;
1431 seg->lochead = NULL;
1432 seg->loctail = &seg->lochead;
1433 seg->orp = obj_new();
1434 seg->orp->up = &(seg->orp);
1435 seg->orp->ori = ori_ledata;
1436 seg->orp->type = LEDATA;
1437 seg->orp->parm[1] = obj_idx;
1440 * Process the segment attributes.
1442 p = name;
1443 while (attrs--) {
1444 p += strlen(p);
1445 while (!*p)
1446 p++;
1449 * `p' contains a segment attribute.
1451 if (!nasm_stricmp(p, "private"))
1452 seg->combine = CMB_PRIVATE;
1453 else if (!nasm_stricmp(p, "public"))
1454 seg->combine = CMB_PUBLIC;
1455 else if (!nasm_stricmp(p, "common"))
1456 seg->combine = CMB_COMMON;
1457 else if (!nasm_stricmp(p, "stack"))
1458 seg->combine = CMB_STACK;
1459 else if (!nasm_stricmp(p, "use16"))
1460 seg->use32 = false;
1461 else if (!nasm_stricmp(p, "use32"))
1462 seg->use32 = true;
1463 else if (!nasm_stricmp(p, "flat")) {
1465 * This segment is an OS/2 FLAT segment. That means
1466 * that its default group is group FLAT, even if
1467 * the group FLAT does not explicitly _contain_ the
1468 * segment.
1470 * When we see this, we must create the group
1471 * `FLAT', containing no segments, if it does not
1472 * already exist; then we must set the default
1473 * group of this segment to be the FLAT group.
1475 struct Group *grp;
1476 for (grp = grphead; grp; grp = grp->next)
1477 if (!strcmp(grp->name, "FLAT"))
1478 break;
1479 if (!grp) {
1480 obj_directive(D_GROUP, "FLAT", 1);
1481 for (grp = grphead; grp; grp = grp->next)
1482 if (!strcmp(grp->name, "FLAT"))
1483 break;
1484 if (!grp)
1485 nasm_panic(0, "failure to define FLAT?!");
1487 seg->grp = grp;
1488 } else if (!nasm_strnicmp(p, "class=", 6))
1489 seg->segclass = nasm_strdup(p + 6);
1490 else if (!nasm_strnicmp(p, "overlay=", 8))
1491 seg->overlay = nasm_strdup(p + 8);
1492 else if (!nasm_strnicmp(p, "align=", 6)) {
1493 seg->align = readnum(p + 6, &rn_error);
1494 if (rn_error) {
1495 seg->align = 1;
1496 nasm_error(ERR_NONFATAL, "segment alignment should be"
1497 " numeric");
1499 switch (seg->align) {
1500 case 1: /* BYTE */
1501 case 2: /* WORD */
1502 case 4: /* DWORD */
1503 case 16: /* PARA */
1504 case 256: /* PAGE */
1505 case 4096: /* PharLap extension */
1506 break;
1507 case 8:
1508 nasm_error(ERR_WARNING,
1509 "OBJ format does not support alignment"
1510 " of 8: rounding up to 16");
1511 seg->align = 16;
1512 break;
1513 case 32:
1514 case 64:
1515 case 128:
1516 nasm_error(ERR_WARNING,
1517 "OBJ format does not support alignment"
1518 " of %d: rounding up to 256", seg->align);
1519 seg->align = 256;
1520 break;
1521 case 512:
1522 case 1024:
1523 case 2048:
1524 nasm_error(ERR_WARNING,
1525 "OBJ format does not support alignment"
1526 " of %d: rounding up to 4096", seg->align);
1527 seg->align = 4096;
1528 break;
1529 default:
1530 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1531 seg->align);
1532 seg->align = 1;
1533 break;
1535 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1536 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1537 if (rn_error)
1538 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1539 " attribute should be numeric");
1543 /* We need to know whenever we have at least one 32-bit segment */
1544 obj_use32 |= seg->use32;
1546 obj_seg_needs_update = seg;
1547 if (seg->align >= SEG_ABS)
1548 define_label(name, NO_SEG, seg->align - SEG_ABS,
1549 NULL, false, false);
1550 else
1551 define_label(name, seg->index + 1, 0L,
1552 NULL, false, false);
1553 obj_seg_needs_update = NULL;
1556 * See if this segment is defined in any groups.
1558 for (grp = grphead; grp; grp = grp->next) {
1559 for (i = grp->nindices; i < grp->nentries; i++) {
1560 if (!strcmp(grp->segs[i].name, seg->name)) {
1561 nasm_free(grp->segs[i].name);
1562 grp->segs[i] = grp->segs[grp->nindices];
1563 grp->segs[grp->nindices++].index = seg->obj_index;
1564 if (seg->grp)
1565 nasm_error(ERR_WARNING,
1566 "segment `%s' is already part of"
1567 " a group: first one takes precedence",
1568 seg->name);
1569 else
1570 seg->grp = grp;
1576 * Walk through the list of externals with unresolved
1577 * default-WRT clauses, and resolve any that point at this
1578 * segment.
1580 extp = &dws;
1581 while (*extp) {
1582 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1583 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1584 nasm_free((*extp)->defwrt_ptr.string);
1585 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1586 (*extp)->defwrt_ptr.seg = seg;
1587 *extp = (*extp)->next_dws;
1588 } else
1589 extp = &(*extp)->next_dws;
1592 if (seg->use32)
1593 *bits = 32;
1594 else
1595 *bits = 16;
1596 current_seg = seg;
1597 return seg->index;
1601 static int obj_directive(enum directives directive, char *value, int pass)
1603 switch (directive) {
1604 case D_GROUP:
1606 char *p, *q, *v;
1607 if (pass == 1) {
1608 struct Group *grp;
1609 struct Segment *seg;
1610 struct External **extp;
1611 int obj_idx;
1613 q = value;
1614 while (*q == '.')
1615 q++; /* hack, but a documented one */
1616 v = q;
1617 while (*q && !nasm_isspace(*q))
1618 q++;
1619 if (nasm_isspace(*q)) {
1620 *q++ = '\0';
1621 while (*q && nasm_isspace(*q))
1622 q++;
1625 * Here we used to sanity-check the group directive to
1626 * ensure nobody tried to declare a group containing no
1627 * segments. However, OS/2 does this as standard
1628 * practice, so the sanity check has been removed.
1630 * if (!*q) {
1631 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1632 * return 1;
1636 obj_idx = 1;
1637 for (grp = grphead; grp; grp = grp->next) {
1638 obj_idx++;
1639 if (!strcmp(grp->name, v)) {
1640 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1641 return 1;
1645 *grptail = grp = nasm_malloc(sizeof(*grp));
1646 grp->next = NULL;
1647 grptail = &grp->next;
1648 grp->index = seg_alloc();
1649 grp->obj_index = obj_idx;
1650 grp->nindices = grp->nentries = 0;
1651 grp->name = NULL;
1653 obj_grp_needs_update = grp;
1654 define_label(v, grp->index + 1, 0L, NULL, false, false);
1655 obj_grp_needs_update = NULL;
1657 while (*q) {
1658 p = q;
1659 while (*q && !nasm_isspace(*q))
1660 q++;
1661 if (nasm_isspace(*q)) {
1662 *q++ = '\0';
1663 while (*q && nasm_isspace(*q))
1664 q++;
1667 * Now p contains a segment name. Find it.
1669 for (seg = seghead; seg; seg = seg->next)
1670 if (!strcmp(seg->name, p))
1671 break;
1672 if (seg) {
1674 * We have a segment index. Shift a name entry
1675 * to the end of the array to make room.
1677 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1678 grp->segs[grp->nindices++].index = seg->obj_index;
1679 if (seg->grp)
1680 nasm_error(ERR_WARNING,
1681 "segment `%s' is already part of"
1682 " a group: first one takes precedence",
1683 seg->name);
1684 else
1685 seg->grp = grp;
1686 } else {
1688 * We have an as-yet undefined segment.
1689 * Remember its name, for later.
1691 grp->segs[grp->nentries++].name = nasm_strdup(p);
1696 * Walk through the list of externals with unresolved
1697 * default-WRT clauses, and resolve any that point at
1698 * this group.
1700 extp = &dws;
1701 while (*extp) {
1702 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1703 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1704 nasm_free((*extp)->defwrt_ptr.string);
1705 (*extp)->defwrt_type = DEFWRT_GROUP;
1706 (*extp)->defwrt_ptr.grp = grp;
1707 *extp = (*extp)->next_dws;
1708 } else
1709 extp = &(*extp)->next_dws;
1712 return 1;
1714 case D_UPPERCASE:
1715 obj_uppercase = true;
1716 return 1;
1718 case D_IMPORT:
1720 char *q, *extname, *libname, *impname;
1722 if (pass == 2)
1723 return 1; /* ignore in pass two */
1724 extname = q = value;
1725 while (*q && !nasm_isspace(*q))
1726 q++;
1727 if (nasm_isspace(*q)) {
1728 *q++ = '\0';
1729 while (*q && nasm_isspace(*q))
1730 q++;
1733 libname = q;
1734 while (*q && !nasm_isspace(*q))
1735 q++;
1736 if (nasm_isspace(*q)) {
1737 *q++ = '\0';
1738 while (*q && nasm_isspace(*q))
1739 q++;
1742 impname = q;
1744 if (!*extname || !*libname)
1745 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1746 " and library name");
1747 else {
1748 struct ImpDef *imp;
1749 bool err = false;
1751 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1752 imptail = &imp->next;
1753 imp->next = NULL;
1754 imp->extname = nasm_strdup(extname);
1755 imp->libname = nasm_strdup(libname);
1756 imp->impindex = readnum(impname, &err);
1757 if (!*impname || err)
1758 imp->impname = nasm_strdup(impname);
1759 else
1760 imp->impname = NULL;
1763 return 1;
1765 case D_EXPORT:
1767 char *q, *extname, *intname, *v;
1768 struct ExpDef *export;
1769 int flags = 0;
1770 unsigned int ordinal = 0;
1772 if (pass == 2)
1773 return 1; /* ignore in pass two */
1774 intname = q = value;
1775 while (*q && !nasm_isspace(*q))
1776 q++;
1777 if (nasm_isspace(*q)) {
1778 *q++ = '\0';
1779 while (*q && nasm_isspace(*q))
1780 q++;
1783 extname = q;
1784 while (*q && !nasm_isspace(*q))
1785 q++;
1786 if (nasm_isspace(*q)) {
1787 *q++ = '\0';
1788 while (*q && nasm_isspace(*q))
1789 q++;
1792 if (!*intname) {
1793 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1794 return 1;
1796 if (!*extname) {
1797 extname = intname;
1798 intname = "";
1800 while (*q) {
1801 v = q;
1802 while (*q && !nasm_isspace(*q))
1803 q++;
1804 if (nasm_isspace(*q)) {
1805 *q++ = '\0';
1806 while (*q && nasm_isspace(*q))
1807 q++;
1809 if (!nasm_stricmp(v, "resident"))
1810 flags |= EXPDEF_FLAG_RESIDENT;
1811 else if (!nasm_stricmp(v, "nodata"))
1812 flags |= EXPDEF_FLAG_NODATA;
1813 else if (!nasm_strnicmp(v, "parm=", 5)) {
1814 bool err = false;
1815 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1816 if (err) {
1817 nasm_error(ERR_NONFATAL,
1818 "value `%s' for `parm' is non-numeric", v + 5);
1819 return 1;
1821 } else {
1822 bool err = false;
1823 ordinal = readnum(v, &err);
1824 if (err) {
1825 nasm_error(ERR_NONFATAL,
1826 "unrecognised export qualifier `%s'", v);
1827 return 1;
1829 flags |= EXPDEF_FLAG_ORDINAL;
1833 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1834 exptail = &export->next;
1835 export->next = NULL;
1836 export->extname = nasm_strdup(extname);
1837 export->intname = nasm_strdup(intname);
1838 export->ordinal = ordinal;
1839 export->flags = flags;
1841 return 1;
1843 default:
1844 return 0;
1848 static void obj_sectalign(int32_t seg, unsigned int value)
1850 struct Segment *s;
1852 list_for_each(s, seghead) {
1853 if (s->index == seg)
1854 break;
1858 * it should not be too big value
1859 * and applied on non-absolute sections
1861 if (!s || !is_power2(value) ||
1862 value > 4096 || s->align >= SEG_ABS)
1863 return;
1866 * FIXME: No code duplication please
1867 * consider making helper for this
1868 * mapping since section handler has
1869 * to do the same
1871 switch (value) {
1872 case 8:
1873 value = 16;
1874 break;
1875 case 32:
1876 case 64:
1877 case 128:
1878 value = 256;
1879 break;
1880 case 512:
1881 case 1024:
1882 case 2048:
1883 value = 4096;
1884 break;
1887 if (s->align < (int)value)
1888 s->align = value;
1891 static int32_t obj_segbase(int32_t segment)
1893 struct Segment *seg;
1896 * Find the segment in our list.
1898 for (seg = seghead; seg; seg = seg->next)
1899 if (seg->index == segment - 1)
1900 break;
1902 if (!seg) {
1904 * Might be an external with a default WRT.
1906 int32_t i = segment / 2;
1907 struct ExtBack *eb = ebhead;
1908 struct External *e;
1910 while (i >= EXT_BLKSIZ) {
1911 if (eb)
1912 eb = eb->next;
1913 else
1914 break;
1915 i -= EXT_BLKSIZ;
1917 if (eb) {
1918 e = eb->exts[i];
1919 if (!e) {
1920 nasm_assert(pass0 == 0);
1921 /* Not available - can happen during optimization */
1922 return NO_SEG;
1925 switch (e->defwrt_type) {
1926 case DEFWRT_NONE:
1927 return segment; /* fine */
1928 case DEFWRT_SEGMENT:
1929 return e->defwrt_ptr.seg->index + 1;
1930 case DEFWRT_GROUP:
1931 return e->defwrt_ptr.grp->index + 1;
1932 default:
1933 return NO_SEG; /* can't tell what it is */
1937 return segment; /* not one of ours - leave it alone */
1940 if (seg->align >= SEG_ABS)
1941 return seg->align; /* absolute segment */
1942 if (seg->grp)
1943 return seg->grp->index + 1; /* grouped segment */
1945 return segment; /* no special treatment */
1948 static void obj_filename(char *inname, char *outname)
1950 strcpy(obj_infile, inname);
1951 standard_extension(inname, outname, ".obj");
1954 static void obj_write_file(void)
1956 struct Segment *seg, *entry_seg_ptr = 0;
1957 struct FileName *fn;
1958 struct LineNumber *ln;
1959 struct Group *grp;
1960 struct Public *pub, *loc;
1961 struct External *ext;
1962 struct ImpDef *imp;
1963 struct ExpDef *export;
1964 int lname_idx;
1965 ObjRecord *orp;
1966 const bool debuginfo = (dfmt == &borland_debug_form);
1969 * Write the THEADR module header.
1971 orp = obj_new();
1972 orp->type = THEADR;
1973 obj_name(orp, obj_infile);
1974 obj_emit2(orp);
1977 * Write the NASM boast comment.
1979 orp->type = COMENT;
1980 obj_rword(orp, 0); /* comment type zero */
1981 obj_name(orp, nasm_comment);
1982 obj_emit2(orp);
1984 orp->type = COMENT;
1986 * Write the IMPDEF records, if any.
1988 for (imp = imphead; imp; imp = imp->next) {
1989 obj_rword(orp, 0xA0); /* comment class A0 */
1990 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1991 if (imp->impname)
1992 obj_byte(orp, 0); /* import by name */
1993 else
1994 obj_byte(orp, 1); /* import by ordinal */
1995 obj_name(orp, imp->extname);
1996 obj_name(orp, imp->libname);
1997 if (imp->impname)
1998 obj_name(orp, imp->impname);
1999 else
2000 obj_word(orp, imp->impindex);
2001 obj_emit2(orp);
2005 * Write the EXPDEF records, if any.
2007 for (export = exphead; export; export = export->next) {
2008 obj_rword(orp, 0xA0); /* comment class A0 */
2009 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
2010 obj_byte(orp, export->flags);
2011 obj_name(orp, export->extname);
2012 obj_name(orp, export->intname);
2013 if (export->flags & EXPDEF_FLAG_ORDINAL)
2014 obj_word(orp, export->ordinal);
2015 obj_emit2(orp);
2018 /* we're using extended OMF if we put in debug info */
2019 if (debuginfo) {
2020 orp->type = COMENT;
2021 obj_byte(orp, 0x40);
2022 obj_byte(orp, dEXTENDED);
2023 obj_emit2(orp);
2027 * Write the first LNAMES record, containing LNAME one, which
2028 * is null. Also initialize the LNAME counter.
2030 orp->type = LNAMES;
2031 obj_byte(orp, 0);
2032 lname_idx = 1;
2034 * Write some LNAMES for the segment names
2036 for (seg = seghead; seg; seg = seg->next) {
2037 orp = obj_name(orp, seg->name);
2038 if (seg->segclass)
2039 orp = obj_name(orp, seg->segclass);
2040 if (seg->overlay)
2041 orp = obj_name(orp, seg->overlay);
2042 obj_commit(orp);
2045 * Write some LNAMES for the group names
2047 for (grp = grphead; grp; grp = grp->next) {
2048 orp = obj_name(orp, grp->name);
2049 obj_commit(orp);
2051 obj_emit(orp);
2054 * Write the SEGDEF records.
2056 orp->type = SEGDEF;
2057 for (seg = seghead; seg; seg = seg->next) {
2058 int acbp;
2059 uint32_t seglen = seg->currentpos;
2061 acbp = (seg->combine << 2); /* C field */
2063 if (seg->use32)
2064 acbp |= 0x01; /* P bit is Use32 flag */
2065 else if (seglen == 0x10000L) {
2066 seglen = 0; /* This special case may be needed for old linkers */
2067 acbp |= 0x02; /* B bit */
2070 /* A field */
2071 if (seg->align >= SEG_ABS)
2072 /* acbp |= 0x00 */ ;
2073 else if (seg->align >= 4096) {
2074 if (seg->align > 4096)
2075 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2076 " than OBJ format supports", seg->name);
2077 acbp |= 0xC0; /* PharLap extension */
2078 } else if (seg->align >= 256) {
2079 acbp |= 0x80;
2080 } else if (seg->align >= 16) {
2081 acbp |= 0x60;
2082 } else if (seg->align >= 4) {
2083 acbp |= 0xA0;
2084 } else if (seg->align >= 2) {
2085 acbp |= 0x40;
2086 } else
2087 acbp |= 0x20;
2089 obj_byte(orp, acbp);
2090 if (seg->align & SEG_ABS) {
2091 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2092 obj_byte(orp, 0); /* Offset */
2094 obj_x(orp, seglen);
2095 obj_index(orp, ++lname_idx);
2096 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2097 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2098 obj_emit2(orp);
2102 * Write the GRPDEF records.
2104 orp->type = GRPDEF;
2105 for (grp = grphead; grp; grp = grp->next) {
2106 int i;
2108 if (grp->nindices != grp->nentries) {
2109 for (i = grp->nindices; i < grp->nentries; i++) {
2110 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2111 " `%s'", grp->name, grp->segs[i].name);
2112 nasm_free(grp->segs[i].name);
2113 grp->segs[i].name = NULL;
2116 obj_index(orp, ++lname_idx);
2117 for (i = 0; i < grp->nindices; i++) {
2118 obj_byte(orp, 0xFF);
2119 obj_index(orp, grp->segs[i].index);
2121 obj_emit2(orp);
2125 * Write the PUBDEF records: first the ones in the segments,
2126 * then the far-absolutes.
2128 orp->type = PUBDEF;
2129 orp->ori = ori_pubdef;
2130 for (seg = seghead; seg; seg = seg->next) {
2131 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2132 orp->parm[1] = seg->obj_index;
2133 for (pub = seg->pubhead; pub; pub = pub->next) {
2134 orp = obj_name(orp, pub->name);
2135 orp = obj_x(orp, pub->offset);
2136 orp = obj_byte(orp, 0); /* type index */
2137 obj_commit(orp);
2139 obj_emit(orp);
2141 orp->parm[0] = 0;
2142 orp->parm[1] = 0;
2143 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2144 if (orp->parm[2] != (uint32_t)pub->segment) {
2145 obj_emit(orp);
2146 orp->parm[2] = pub->segment;
2148 orp = obj_name(orp, pub->name);
2149 orp = obj_x(orp, pub->offset);
2150 orp = obj_byte(orp, 0); /* type index */
2151 obj_commit(orp);
2153 obj_emit(orp);
2156 * Write the EXTDEF and COMDEF records, in order.
2158 orp->ori = ori_null;
2159 for (ext = exthead; ext; ext = ext->next) {
2160 if (ext->commonsize == 0) {
2161 if (orp->type != EXTDEF) {
2162 obj_emit(orp);
2163 orp->type = EXTDEF;
2165 orp = obj_name(orp, ext->name);
2166 orp = obj_index(orp, 0);
2167 } else {
2168 if (orp->type != COMDEF) {
2169 obj_emit(orp);
2170 orp->type = COMDEF;
2172 orp = obj_name(orp, ext->name);
2173 orp = obj_index(orp, 0);
2174 if (ext->commonelem) {
2175 orp = obj_byte(orp, 0x61); /* far communal */
2176 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2177 orp = obj_value(orp, ext->commonelem);
2178 } else {
2179 orp = obj_byte(orp, 0x62); /* near communal */
2180 orp = obj_value(orp, ext->commonsize);
2183 obj_commit(orp);
2185 obj_emit(orp);
2188 * Write a COMENT record stating that the linker's first pass
2189 * may stop processing at this point. Exception is if our
2190 * MODEND record specifies a start point, in which case,
2191 * according to some variants of the documentation, this COMENT
2192 * should be omitted. So we'll omit it just in case.
2193 * But, TASM puts it in all the time so if we are using
2194 * TASM debug stuff we are putting it in
2196 if (debuginfo || obj_entry_seg == NO_SEG) {
2197 orp->type = COMENT;
2198 obj_byte(orp, 0x40);
2199 obj_byte(orp, dLINKPASS);
2200 obj_byte(orp, 1);
2201 obj_emit2(orp);
2205 * 1) put out the compiler type
2206 * 2) Put out the type info. The only type we are using is near label #19
2208 if (debuginfo) {
2209 int i;
2210 struct Array *arrtmp = arrhead;
2211 orp->type = COMENT;
2212 obj_byte(orp, 0x40);
2213 obj_byte(orp, dCOMPDEF);
2214 obj_byte(orp, 4);
2215 obj_byte(orp, 0);
2216 obj_emit2(orp);
2218 obj_byte(orp, 0x40);
2219 obj_byte(orp, dTYPEDEF);
2220 obj_word(orp, 0x18); /* type # for linking */
2221 obj_word(orp, 6); /* size of type */
2222 obj_byte(orp, 0x2a); /* absolute type for debugging */
2223 obj_emit2(orp);
2224 obj_byte(orp, 0x40);
2225 obj_byte(orp, dTYPEDEF);
2226 obj_word(orp, 0x19); /* type # for linking */
2227 obj_word(orp, 0); /* size of type */
2228 obj_byte(orp, 0x24); /* absolute type for debugging */
2229 obj_byte(orp, 0); /* near/far specifier */
2230 obj_emit2(orp);
2231 obj_byte(orp, 0x40);
2232 obj_byte(orp, dTYPEDEF);
2233 obj_word(orp, 0x1A); /* type # for linking */
2234 obj_word(orp, 0); /* size of type */
2235 obj_byte(orp, 0x24); /* absolute type for debugging */
2236 obj_byte(orp, 1); /* near/far specifier */
2237 obj_emit2(orp);
2238 obj_byte(orp, 0x40);
2239 obj_byte(orp, dTYPEDEF);
2240 obj_word(orp, 0x1b); /* type # for linking */
2241 obj_word(orp, 0); /* size of type */
2242 obj_byte(orp, 0x23); /* absolute type for debugging */
2243 obj_byte(orp, 0);
2244 obj_byte(orp, 0);
2245 obj_byte(orp, 0);
2246 obj_emit2(orp);
2247 obj_byte(orp, 0x40);
2248 obj_byte(orp, dTYPEDEF);
2249 obj_word(orp, 0x1c); /* type # for linking */
2250 obj_word(orp, 0); /* size of type */
2251 obj_byte(orp, 0x23); /* absolute type for debugging */
2252 obj_byte(orp, 0);
2253 obj_byte(orp, 4);
2254 obj_byte(orp, 0);
2255 obj_emit2(orp);
2256 obj_byte(orp, 0x40);
2257 obj_byte(orp, dTYPEDEF);
2258 obj_word(orp, 0x1d); /* type # for linking */
2259 obj_word(orp, 0); /* size of type */
2260 obj_byte(orp, 0x23); /* absolute type for debugging */
2261 obj_byte(orp, 0);
2262 obj_byte(orp, 1);
2263 obj_byte(orp, 0);
2264 obj_emit2(orp);
2265 obj_byte(orp, 0x40);
2266 obj_byte(orp, dTYPEDEF);
2267 obj_word(orp, 0x1e); /* type # for linking */
2268 obj_word(orp, 0); /* size of type */
2269 obj_byte(orp, 0x23); /* absolute type for debugging */
2270 obj_byte(orp, 0);
2271 obj_byte(orp, 5);
2272 obj_byte(orp, 0);
2273 obj_emit2(orp);
2275 /* put out the array types */
2276 for (i = ARRAYBOT; i < arrindex; i++) {
2277 obj_byte(orp, 0x40);
2278 obj_byte(orp, dTYPEDEF);
2279 obj_word(orp, i); /* type # for linking */
2280 obj_word(orp, arrtmp->size); /* size of type */
2281 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2282 obj_byte(orp, arrtmp->basetype); /* base type */
2283 obj_emit2(orp);
2284 arrtmp = arrtmp->next;
2288 * write out line number info with a LINNUM record
2289 * switch records when we switch segments, and output the
2290 * file in a pseudo-TASM fashion. The record switch is naive; that
2291 * is that one file may have many records for the same segment
2292 * if there are lots of segment switches
2294 if (fnhead && debuginfo) {
2295 seg = fnhead->lnhead->segment;
2297 for (fn = fnhead; fn; fn = fn->next) {
2298 /* write out current file name */
2299 orp->type = COMENT;
2300 orp->ori = ori_null;
2301 obj_byte(orp, 0x40);
2302 obj_byte(orp, dFILNAME);
2303 obj_byte(orp, 0);
2304 obj_name(orp, fn->name);
2305 obj_dword(orp, 0);
2306 obj_emit2(orp);
2308 /* write out line numbers this file */
2310 orp->type = LINNUM;
2311 orp->ori = ori_linnum;
2312 for (ln = fn->lnhead; ln; ln = ln->next) {
2313 if (seg != ln->segment) {
2314 /* if we get here have to flush the buffer and start
2315 * a new record for a new segment
2317 seg = ln->segment;
2318 obj_emit(orp);
2320 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2321 orp->parm[1] = seg->obj_index;
2322 orp = obj_word(orp, ln->lineno);
2323 orp = obj_x(orp, ln->offset);
2324 obj_commit(orp);
2326 obj_emit(orp);
2330 * we are going to locate the entry point segment now
2331 * rather than wait until the MODEND record, because,
2332 * then we can output a special symbol to tell where the
2333 * entry point is.
2336 if (obj_entry_seg != NO_SEG) {
2337 for (seg = seghead; seg; seg = seg->next) {
2338 if (seg->index == obj_entry_seg) {
2339 entry_seg_ptr = seg;
2340 break;
2343 if (!seg)
2344 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2348 * get ready to put out symbol records
2350 orp->type = COMENT;
2351 orp->ori = ori_local;
2354 * put out a symbol for the entry point
2355 * no dots in this symbol, because, borland does
2356 * not (officially) support dots in label names
2357 * and I don't know what various versions of TLINK will do
2359 if (debuginfo && obj_entry_seg != NO_SEG) {
2360 orp = obj_name(orp, "start_of_program");
2361 orp = obj_word(orp, 0x19); /* type: near label */
2362 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2363 orp = obj_index(orp, seg->obj_index);
2364 orp = obj_x(orp, obj_entry_ofs);
2365 obj_commit(orp);
2369 * put out the local labels
2371 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2372 /* labels this seg */
2373 for (loc = seg->lochead; loc; loc = loc->next) {
2374 orp = obj_name(orp, loc->name);
2375 orp = obj_word(orp, loc->type);
2376 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2377 orp = obj_index(orp, seg->obj_index);
2378 orp = obj_x(orp, loc->offset);
2379 obj_commit(orp);
2382 if (orp->used)
2383 obj_emit(orp);
2386 * Write the LEDATA/FIXUPP pairs.
2388 for (seg = seghead; seg; seg = seg->next) {
2389 obj_emit(seg->orp);
2390 nasm_free(seg->orp);
2394 * Write the MODEND module end marker.
2396 orp->type = obj_use32 ? MODE32 : MODEND;
2397 orp->ori = ori_null;
2398 if (entry_seg_ptr) {
2399 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2400 obj_byte(orp, 0xC1);
2401 seg = entry_seg_ptr;
2402 if (seg->grp) {
2403 obj_byte(orp, 0x10);
2404 obj_index(orp, seg->grp->obj_index);
2405 } else {
2407 * the below changed to prevent TLINK crashing.
2408 * Previous more efficient version read:
2410 * obj_byte (orp, 0x50);
2412 obj_byte(orp, 0x00);
2413 obj_index(orp, seg->obj_index);
2415 obj_index(orp, seg->obj_index);
2416 obj_x(orp, obj_entry_ofs);
2417 } else
2418 obj_byte(orp, 0);
2419 obj_emit2(orp);
2420 nasm_free(orp);
2423 static void obj_fwrite(ObjRecord * orp)
2425 unsigned int cksum, len;
2426 uint8_t *ptr;
2428 cksum = orp->type;
2429 if (orp->x_size == 32)
2430 cksum |= 1;
2431 fputc(cksum, ofile);
2432 len = orp->committed + 1;
2433 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2434 fwriteint16_t(len, ofile);
2435 nasm_write(orp->buf, len-1, ofile);
2436 for (ptr = orp->buf; --len; ptr++)
2437 cksum += *ptr;
2438 fputc((-cksum) & 0xFF, ofile);
2441 extern macros_t obj_stdmac[];
2443 static void dbgbi_init(void)
2445 fnhead = NULL;
2446 fntail = &fnhead;
2447 arrindex = ARRAYBOT;
2448 arrhead = NULL;
2449 arrtail = &arrhead;
2451 static void dbgbi_cleanup(void)
2453 struct Segment *segtmp;
2454 while (fnhead) {
2455 struct FileName *fntemp = fnhead;
2456 while (fnhead->lnhead) {
2457 struct LineNumber *lntemp = fnhead->lnhead;
2458 fnhead->lnhead = lntemp->next;
2459 nasm_free(lntemp);
2461 fnhead = fnhead->next;
2462 nasm_free(fntemp->name);
2463 nasm_free(fntemp);
2465 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2466 while (segtmp->lochead) {
2467 struct Public *loctmp = segtmp->lochead;
2468 segtmp->lochead = loctmp->next;
2469 nasm_free(loctmp->name);
2470 nasm_free(loctmp);
2473 while (arrhead) {
2474 struct Array *arrtmp = arrhead;
2475 arrhead = arrhead->next;
2476 nasm_free(arrtmp);
2480 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2482 struct FileName *fn;
2483 struct LineNumber *ln;
2484 struct Segment *seg;
2486 if (segto == NO_SEG)
2487 return;
2490 * If `any_segs' is still false, we must define a default
2491 * segment.
2493 if (!any_segs) {
2494 int tempint; /* ignored */
2495 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2496 nasm_panic(0, "strange segment conditions in OBJ driver");
2500 * Find the segment we are targetting.
2502 for (seg = seghead; seg; seg = seg->next)
2503 if (seg->index == segto)
2504 break;
2505 if (!seg)
2506 nasm_panic(0, "lineno directed to nonexistent segment?");
2508 /* for (fn = fnhead; fn; fn = fnhead->next) */
2509 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2510 if (!nasm_stricmp(lnfname, fn->name))
2511 break;
2512 if (!fn) {
2513 fn = nasm_malloc(sizeof(*fn));
2514 fn->name = nasm_malloc(strlen(lnfname) + 1);
2515 strcpy(fn->name, lnfname);
2516 fn->lnhead = NULL;
2517 fn->lntail = &fn->lnhead;
2518 fn->next = NULL;
2519 *fntail = fn;
2520 fntail = &fn->next;
2522 ln = nasm_malloc(sizeof(*ln));
2523 ln->segment = seg;
2524 ln->offset = seg->currentpos;
2525 ln->lineno = lineno;
2526 ln->next = NULL;
2527 *fn->lntail = ln;
2528 fn->lntail = &ln->next;
2531 static void dbgbi_deflabel(char *name, int32_t segment,
2532 int64_t offset, int is_global, char *special)
2534 struct Segment *seg;
2536 (void)special;
2539 * Note: ..[^@] special symbols are filtered in labels.c
2543 * If it's a special-retry from pass two, discard it.
2545 if (is_global == 3)
2546 return;
2549 * Case (i):
2551 if (obj_seg_needs_update) {
2552 return;
2553 } else if (obj_grp_needs_update) {
2554 return;
2556 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2557 return;
2559 if (segment >= SEG_ABS || segment == NO_SEG) {
2560 return;
2564 * If `any_segs' is still false, we might need to define a
2565 * default segment, if they're trying to declare a label in
2566 * `first_seg'. But the label should exist due to a prior
2567 * call to obj_deflabel so we can skip that.
2570 for (seg = seghead; seg; seg = seg->next)
2571 if (seg->index == segment) {
2572 struct Public *loc = nasm_malloc(sizeof(*loc));
2574 * Case (ii). Maybe MODPUB someday?
2576 last_defined = *seg->loctail = loc;
2577 seg->loctail = &loc->next;
2578 loc->next = NULL;
2579 loc->name = nasm_strdup(name);
2580 loc->offset = offset;
2583 static void dbgbi_typevalue(int32_t type)
2585 int vsize;
2586 int elem = TYM_ELEMENTS(type);
2587 type = TYM_TYPE(type);
2589 if (!last_defined)
2590 return;
2592 switch (type) {
2593 case TY_BYTE:
2594 last_defined->type = 8; /* uint8_t */
2595 vsize = 1;
2596 break;
2597 case TY_WORD:
2598 last_defined->type = 10; /* unsigned word */
2599 vsize = 2;
2600 break;
2601 case TY_DWORD:
2602 last_defined->type = 12; /* unsigned dword */
2603 vsize = 4;
2604 break;
2605 case TY_FLOAT:
2606 last_defined->type = 14; /* float */
2607 vsize = 4;
2608 break;
2609 case TY_QWORD:
2610 last_defined->type = 15; /* qword */
2611 vsize = 8;
2612 break;
2613 case TY_TBYTE:
2614 last_defined->type = 16; /* TBYTE */
2615 vsize = 10;
2616 break;
2617 default:
2618 last_defined->type = 0x19; /*label */
2619 vsize = 0;
2620 break;
2623 if (elem > 1) {
2624 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2625 int vtype = last_defined->type;
2626 arrtmp->size = vsize * elem;
2627 arrtmp->basetype = vtype;
2628 arrtmp->next = NULL;
2629 last_defined->type = arrindex++;
2630 *arrtail = arrtmp;
2631 arrtail = &(arrtmp->next);
2633 last_defined = NULL;
2635 static void dbgbi_output(int output_type, void *param)
2637 (void)output_type;
2638 (void)param;
2640 static const struct dfmt borland_debug_form = {
2641 "Borland Debug Records",
2642 "borland",
2643 dbgbi_init,
2644 dbgbi_linnum,
2645 dbgbi_deflabel,
2646 null_debug_directive,
2647 dbgbi_typevalue,
2648 dbgbi_output,
2649 dbgbi_cleanup,
2650 NULL /* pragma list */
2653 static const struct dfmt * const borland_debug_arr[3] = {
2654 &borland_debug_form,
2655 &null_debug_form,
2656 NULL
2659 const struct ofmt of_obj = {
2660 "MS-DOS 16-bit/32-bit OMF object files",
2661 "obj",
2664 borland_debug_arr,
2665 &borland_debug_form,
2666 obj_stdmac,
2667 obj_init,
2668 obj_set_info,
2669 nasm_do_legacy_output,
2670 obj_out,
2671 obj_deflabel,
2672 obj_segment,
2673 obj_sectalign,
2674 obj_segbase,
2675 obj_directive,
2676 obj_filename,
2677 obj_cleanup,
2678 NULL /* pragma list */
2680 #endif /* OF_OBJ */