Show the expanded macro stack when displaying diagnostics
[nasm.git] / output / outobj.c
blobc82b5c263f20c1cc0e7fc1be03adc261cb14b2da
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 <inttypes.h>
46 #include <limits.h>
48 #include "nasm.h"
49 #include "nasmlib.h"
50 #include "stdscan.h"
51 #include "eval.h"
52 #include "output/outform.h"
53 #include "output/outlib.h"
55 #ifdef OF_OBJ
58 * outobj.c is divided into two sections. The first section is low level
59 * routines for creating obj records; It has nearly zero NASM specific
60 * code. The second section is high level routines for processing calls and
61 * data structures from the rest of NASM into obj format.
63 * It should be easy (though not zero work) to lift the first section out for
64 * use as an obj file writer for some other assembler or compiler.
68 * These routines are built around the ObjRecord data struture. An ObjRecord
69 * holds an object file record that may be under construction or complete.
71 * A major function of these routines is to support continuation of an obj
72 * record into the next record when the maximum record size is exceeded. The
73 * high level code does not need to worry about where the record breaks occur.
74 * It does need to do some minor extra steps to make the automatic continuation
75 * work. Those steps may be skipped for records where the high level knows no
76 * continuation could be required.
78 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
79 * is cleared by obj_clear.
81 * 2) The caller should fill in .type.
83 * 3) If the record is continuable and there is processing that must be done at
84 * the start of each record then the caller should fill in .ori with the
85 * address of the record initializer routine.
87 * 4) If the record is continuable and it should be saved (rather than emitted
88 * immediately) as each record is done, the caller should set .up to be a
89 * pointer to a location in which the caller keeps the master pointer to the
90 * ObjRecord. When the record is continued, the obj_bump routine will then
91 * allocate a new ObjRecord structure and update the master pointer.
93 * 5) If the .ori field was used then the caller should fill in the .parm with
94 * any data required by the initializer.
96 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
97 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
98 * data required for this record.
100 * 7) If the record is continuable, the caller should call obj_commit at each
101 * point where breaking the record is permitted.
103 * 8) To write out the record, the caller should call obj_emit2. If the
104 * caller has called obj_commit for all data written then he can get slightly
105 * faster code by calling obj_emit instead of obj_emit2.
107 * Most of these routines return an ObjRecord pointer. This will be the input
108 * pointer most of the time and will be the new location if the ObjRecord
109 * moved as a result of the call. The caller may ignore the return value in
110 * three cases: It is a "Never Reallocates" routine; or The caller knows
111 * continuation is not possible; or The caller uses the master pointer for the
112 * next operation.
115 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
116 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
118 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
119 #define FIX_16_OFFSET 0x8400
120 #define FIX_16_SELECTOR 0x8800
121 #define FIX_32_POINTER 0x8C00
122 #define FIX_08_HIGH 0x9000
123 #define FIX_32_OFFSET 0xA400
124 #define FIX_48_POINTER 0xAC00
126 enum RecordID { /* record ID codes */
128 THEADR = 0x80, /* module header */
129 COMENT = 0x88, /* comment record */
131 LINNUM = 0x94, /* line number record */
132 LNAMES = 0x96, /* list of names */
134 SEGDEF = 0x98, /* segment definition */
135 GRPDEF = 0x9A, /* group definition */
136 EXTDEF = 0x8C, /* external definition */
137 PUBDEF = 0x90, /* public definition */
138 COMDEF = 0xB0, /* common definition */
140 LEDATA = 0xA0, /* logical enumerated data */
141 FIXUPP = 0x9C, /* fixups (relocations) */
142 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
144 MODEND = 0x8A, /* module end */
145 MODE32 = 0x8B /* module end for 32-bit objects */
148 enum ComentID { /* ID codes for comment records */
150 dEXTENDED = 0xA1, /* tells that we are using translator-specific extensions */
151 dLINKPASS = 0xA2, /* link pass 2 marker */
152 dTYPEDEF = 0xE3, /* define a type */
153 dSYM = 0xE6, /* symbol debug record */
154 dFILNAME = 0xE8, /* file name record */
155 dCOMPDEF = 0xEA /* compiler type info */
158 typedef struct ObjRecord ObjRecord;
159 typedef void ORI(ObjRecord * orp);
161 struct ObjRecord {
162 ORI *ori; /* Initialization routine */
163 int used; /* Current data size */
164 int committed; /* Data size at last boundary */
165 int x_size; /* (see obj_x) */
166 unsigned int type; /* Record type */
167 ObjRecord *child; /* Associated record below this one */
168 ObjRecord **up; /* Master pointer to this ObjRecord */
169 ObjRecord *back; /* Previous part of this record */
170 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
171 uint8_t buf[RECORD_MAX + 3];
174 static void obj_fwrite(ObjRecord * orp);
175 static void ori_ledata(ObjRecord * orp);
176 static void ori_pubdef(ObjRecord * orp);
177 static void ori_null(ObjRecord * orp);
178 static ObjRecord *obj_commit(ObjRecord * orp);
180 static bool obj_uppercase; /* Flag: all names in uppercase */
181 static bool obj_use32; /* Flag: at least one segment is 32-bit */
184 * Clear an ObjRecord structure. (Never reallocates).
185 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
187 static ObjRecord *obj_clear(ObjRecord * orp)
189 orp->used = 0;
190 orp->committed = 0;
191 orp->x_size = 0;
192 orp->child = NULL;
193 orp->up = NULL;
194 orp->back = NULL;
195 return (orp);
199 * Emit an ObjRecord structure. (Never reallocates).
200 * The record is written out preceeded (recursively) by its previous part (if
201 * any) and followed (recursively) by its child (if any).
202 * The previous part and the child are freed. The main ObjRecord is cleared,
203 * not freed.
205 static ObjRecord *obj_emit(ObjRecord * orp)
207 if (orp->back) {
208 obj_emit(orp->back);
209 nasm_free(orp->back);
212 if (orp->committed)
213 obj_fwrite(orp);
215 if (orp->child) {
216 obj_emit(orp->child);
217 nasm_free(orp->child);
220 return (obj_clear(orp));
224 * Commit and Emit a record. (Never reallocates).
226 static ObjRecord *obj_emit2(ObjRecord * orp)
228 obj_commit(orp);
229 return (obj_emit(orp));
233 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
235 static ObjRecord *obj_new(void)
237 ObjRecord *orp;
239 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
240 orp->ori = ori_null;
241 return (orp);
245 * Advance to the next record because the existing one is full or its x_size
246 * is incompatible.
247 * Any uncommited data is moved into the next record.
249 static ObjRecord *obj_bump(ObjRecord * orp)
251 ObjRecord *nxt;
252 int used = orp->used;
253 int committed = orp->committed;
255 if (orp->up) {
256 *orp->up = nxt = obj_new();
257 nxt->ori = orp->ori;
258 nxt->type = orp->type;
259 nxt->up = orp->up;
260 nxt->back = orp;
261 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
262 } else
263 nxt = obj_emit(orp);
265 used -= committed;
266 if (used) {
267 nxt->committed = 1;
268 nxt->ori(nxt);
269 nxt->committed = nxt->used;
270 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
271 nxt->used = nxt->committed + used;
274 return (nxt);
278 * Advance to the next record if necessary to allow the next field to fit.
280 static ObjRecord *obj_check(ObjRecord * orp, int size)
282 if (orp->used + size > RECORD_MAX)
283 orp = obj_bump(orp);
285 if (!orp->committed) {
286 orp->committed = 1;
287 orp->ori(orp);
288 orp->committed = orp->used;
291 return (orp);
295 * All data written so far is commited to the current record (won't be moved to
296 * the next record in case of continuation).
298 static ObjRecord *obj_commit(ObjRecord * orp)
300 orp->committed = orp->used;
301 return (orp);
305 * Write a byte
307 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
309 orp = obj_check(orp, 1);
310 orp->buf[orp->used] = val;
311 orp->used++;
312 return (orp);
316 * Write a word
318 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
320 orp = obj_check(orp, 2);
321 orp->buf[orp->used] = val;
322 orp->buf[orp->used + 1] = val >> 8;
323 orp->used += 2;
324 return (orp);
328 * Write a reversed word
330 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
332 orp = obj_check(orp, 2);
333 orp->buf[orp->used] = val >> 8;
334 orp->buf[orp->used + 1] = val;
335 orp->used += 2;
336 return (orp);
340 * Write a dword
342 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
344 orp = obj_check(orp, 4);
345 orp->buf[orp->used] = val;
346 orp->buf[orp->used + 1] = val >> 8;
347 orp->buf[orp->used + 2] = val >> 16;
348 orp->buf[orp->used + 3] = val >> 24;
349 orp->used += 4;
350 return (orp);
354 * All fields of "size x" in one obj record must be the same size (either 16
355 * bits or 32 bits). There is a one bit flag in each record which specifies
356 * which.
357 * This routine is used to force the current record to have the desired
358 * x_size. x_size is normally automatic (using obj_x), so that this
359 * routine should be used outside obj_x, only to provide compatibility with
360 * linkers that have bugs in their processing of the size bit.
363 static ObjRecord *obj_force(ObjRecord * orp, int x)
365 if (orp->x_size == (x ^ 48))
366 orp = obj_bump(orp);
367 orp->x_size = x;
368 return (orp);
372 * This routine writes a field of size x. The caller does not need to worry at
373 * all about whether 16-bits or 32-bits are required.
375 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
377 if (orp->type & 1)
378 orp->x_size = 32;
379 if (val > 0xFFFF)
380 orp = obj_force(orp, 32);
381 if (orp->x_size == 32) {
382 ObjRecord *nxt = obj_dword(orp, val);
383 nxt->x_size = 32; /* x_size is cleared when a record overflows */
384 return nxt;
386 orp->x_size = 16;
387 return (obj_word(orp, val));
391 * Writes an index
393 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
395 if (val < 128)
396 return (obj_byte(orp, val));
397 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
401 * Writes a variable length value
403 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
405 if (val <= 128)
406 return (obj_byte(orp, val));
407 if (val <= 0xFFFF) {
408 orp = obj_byte(orp, 129);
409 return (obj_word(orp, val));
411 if (val <= 0xFFFFFF)
412 return (obj_dword(orp, (val << 8) + 132));
413 orp = obj_byte(orp, 136);
414 return (obj_dword(orp, val));
418 * Writes a counted string
420 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
422 int len = strlen(name);
423 uint8_t *ptr;
425 orp = obj_check(orp, len + 1);
426 ptr = orp->buf + orp->used;
427 *ptr++ = len;
428 orp->used += len + 1;
429 if (obj_uppercase)
430 while (--len >= 0) {
431 *ptr++ = toupper(*name);
432 name++;
433 } else
434 memcpy(ptr, name, len);
435 return (orp);
439 * Initializer for an LEDATA record.
440 * parm[0] = offset
441 * parm[1] = segment index
442 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
443 * represent the offset that would be required if the record were split at the
444 * last commit point.
445 * parm[2] is a copy of parm[0] as it was when the current record was initted.
447 static void ori_ledata(ObjRecord * orp)
449 obj_index(orp, orp->parm[1]);
450 orp->parm[2] = orp->parm[0];
451 obj_x(orp, orp->parm[0]);
455 * Initializer for a PUBDEF record.
456 * parm[0] = group index
457 * parm[1] = segment index
458 * parm[2] = frame (only used when both indexes are zero)
460 static void ori_pubdef(ObjRecord * orp)
462 obj_index(orp, orp->parm[0]);
463 obj_index(orp, orp->parm[1]);
464 if (!(orp->parm[0] | orp->parm[1]))
465 obj_word(orp, orp->parm[2]);
469 * Initializer for a LINNUM record.
470 * parm[0] = group index
471 * parm[1] = segment index
473 static void ori_linnum(ObjRecord * orp)
475 obj_index(orp, orp->parm[0]);
476 obj_index(orp, orp->parm[1]);
480 * Initializer for a local vars record.
482 static void ori_local(ObjRecord * orp)
484 obj_byte(orp, 0x40);
485 obj_byte(orp, dSYM);
489 * Null initializer for records that continue without any header info
491 static void ori_null(ObjRecord * orp)
493 (void)orp; /* Do nothing */
497 * This concludes the low level section of outobj.c
500 static char obj_infile[FILENAME_MAX];
502 static int32_t first_seg;
503 static bool any_segs;
504 static int passtwo;
505 static int arrindex;
507 #define GROUP_MAX 256 /* we won't _realistically_ have more
508 * than this many segs in a group */
509 #define EXT_BLKSIZ 256 /* block size for externals list */
511 struct Segment; /* need to know these structs exist */
512 struct Group;
514 struct LineNumber {
515 struct LineNumber *next;
516 struct Segment *segment;
517 int32_t offset;
518 int32_t lineno;
521 static struct FileName {
522 struct FileName *next;
523 char *name;
524 struct LineNumber *lnhead, **lntail;
525 int index;
526 } *fnhead, **fntail;
528 static struct Array {
529 struct Array *next;
530 unsigned size;
531 int basetype;
532 } *arrhead, **arrtail;
534 #define ARRAYBOT 31 /* magic number for first array index */
536 static struct Public {
537 struct Public *next;
538 char *name;
539 int32_t offset;
540 int32_t segment; /* only if it's far-absolute */
541 int type; /* only for local debug syms */
542 } *fpubhead, **fpubtail, *last_defined;
544 static struct External {
545 struct External *next;
546 char *name;
547 int32_t commonsize;
548 int32_t commonelem; /* element size if FAR, else zero */
549 int index; /* OBJ-file external index */
550 enum {
551 DEFWRT_NONE, /* no unusual default-WRT */
552 DEFWRT_STRING, /* a string we don't yet understand */
553 DEFWRT_SEGMENT, /* a segment */
554 DEFWRT_GROUP /* a group */
555 } defwrt_type;
556 union {
557 char *string;
558 struct Segment *seg;
559 struct Group *grp;
560 } defwrt_ptr;
561 struct External *next_dws; /* next with DEFWRT_STRING */
562 } *exthead, **exttail, *dws;
564 static int externals;
566 static struct ExtBack {
567 struct ExtBack *next;
568 struct External *exts[EXT_BLKSIZ];
569 } *ebhead, **ebtail;
571 static struct Segment {
572 struct Segment *next;
573 char *name;
574 int32_t index; /* the NASM segment id */
575 int32_t obj_index; /* the OBJ-file segment index */
576 struct Group *grp; /* the group it beint32_ts to */
577 uint32_t currentpos;
578 int32_t align; /* can be SEG_ABS + absolute addr */
579 struct Public *pubhead, **pubtail, *lochead, **loctail;
580 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
581 ObjRecord *orp;
582 enum {
583 CMB_PRIVATE = 0,
584 CMB_PUBLIC = 2,
585 CMB_STACK = 5,
586 CMB_COMMON = 6
587 } combine;
588 bool use32; /* is this segment 32-bit? */
589 } *seghead, **segtail, *obj_seg_needs_update;
591 static struct Group {
592 struct Group *next;
593 char *name;
594 int32_t index; /* NASM segment id */
595 int32_t obj_index; /* OBJ-file group index */
596 int32_t nentries; /* number of elements... */
597 int32_t nindices; /* ...and number of index elts... */
598 union {
599 int32_t index;
600 char *name;
601 } segs[GROUP_MAX]; /* ...in this */
602 } *grphead, **grptail, *obj_grp_needs_update;
604 static struct ImpDef {
605 struct ImpDef *next;
606 char *extname;
607 char *libname;
608 unsigned int impindex;
609 char *impname;
610 } *imphead, **imptail;
612 static struct ExpDef {
613 struct ExpDef *next;
614 char *intname;
615 char *extname;
616 unsigned int ordinal;
617 int flags;
618 } *exphead, **exptail;
620 #define EXPDEF_FLAG_ORDINAL 0x80
621 #define EXPDEF_FLAG_RESIDENT 0x40
622 #define EXPDEF_FLAG_NODATA 0x20
623 #define EXPDEF_MASK_PARMCNT 0x1F
625 static int32_t obj_entry_seg, obj_entry_ofs;
627 struct ofmt of_obj;
628 static struct dfmt borland_debug_form;
630 /* The current segment */
631 static struct Segment *current_seg;
633 static int32_t obj_segment(char *, int, int *);
634 static void obj_write_file(void);
635 static int obj_directive(enum directives, char *, int);
637 static void obj_init(void)
639 first_seg = seg_alloc();
640 any_segs = false;
641 fpubhead = NULL;
642 fpubtail = &fpubhead;
643 exthead = NULL;
644 exttail = &exthead;
645 imphead = NULL;
646 imptail = &imphead;
647 exphead = NULL;
648 exptail = &exphead;
649 dws = NULL;
650 externals = 0;
651 ebhead = NULL;
652 ebtail = &ebhead;
653 seghead = obj_seg_needs_update = NULL;
654 segtail = &seghead;
655 grphead = obj_grp_needs_update = NULL;
656 grptail = &grphead;
657 obj_entry_seg = NO_SEG;
658 obj_uppercase = false;
659 obj_use32 = false;
660 passtwo = 0;
661 current_seg = NULL;
664 static int obj_set_info(enum geninfo type, char **val)
666 (void)type;
667 (void)val;
669 return 0;
672 static void obj_cleanup(void)
674 obj_write_file();
675 dfmt->cleanup();
676 while (seghead) {
677 struct Segment *segtmp = seghead;
678 seghead = seghead->next;
679 while (segtmp->pubhead) {
680 struct Public *pubtmp = segtmp->pubhead;
681 segtmp->pubhead = pubtmp->next;
682 nasm_free(pubtmp->name);
683 nasm_free(pubtmp);
685 nasm_free(segtmp->segclass);
686 nasm_free(segtmp->overlay);
687 nasm_free(segtmp);
689 while (fpubhead) {
690 struct Public *pubtmp = fpubhead;
691 fpubhead = fpubhead->next;
692 nasm_free(pubtmp->name);
693 nasm_free(pubtmp);
695 while (exthead) {
696 struct External *exttmp = exthead;
697 exthead = exthead->next;
698 nasm_free(exttmp);
700 while (imphead) {
701 struct ImpDef *imptmp = imphead;
702 imphead = imphead->next;
703 nasm_free(imptmp->extname);
704 nasm_free(imptmp->libname);
705 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
706 nasm_free(imptmp);
708 while (exphead) {
709 struct ExpDef *exptmp = exphead;
710 exphead = exphead->next;
711 nasm_free(exptmp->extname);
712 nasm_free(exptmp->intname);
713 nasm_free(exptmp);
715 while (ebhead) {
716 struct ExtBack *ebtmp = ebhead;
717 ebhead = ebhead->next;
718 nasm_free(ebtmp);
720 while (grphead) {
721 struct Group *grptmp = grphead;
722 grphead = grphead->next;
723 nasm_free(grptmp);
727 static void obj_ext_set_defwrt(struct External *ext, char *id)
729 struct Segment *seg;
730 struct Group *grp;
732 for (seg = seghead; seg; seg = seg->next)
733 if (!strcmp(seg->name, id)) {
734 ext->defwrt_type = DEFWRT_SEGMENT;
735 ext->defwrt_ptr.seg = seg;
736 nasm_free(id);
737 return;
740 for (grp = grphead; grp; grp = grp->next)
741 if (!strcmp(grp->name, id)) {
742 ext->defwrt_type = DEFWRT_GROUP;
743 ext->defwrt_ptr.grp = grp;
744 nasm_free(id);
745 return;
748 ext->defwrt_type = DEFWRT_STRING;
749 ext->defwrt_ptr.string = id;
750 ext->next_dws = dws;
751 dws = ext;
754 static void obj_deflabel(char *name, int32_t segment,
755 int64_t offset, int is_global, char *special)
758 * We have three cases:
760 * (i) `segment' is a segment-base. If so, set the name field
761 * for the segment or group structure it refers to, and then
762 * return.
764 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
765 * Save the label position for later output of a PUBDEF record.
766 * (Or a MODPUB, if we work out how.)
768 * (iii) `segment' is not one of our segments. Save the label
769 * position for later output of an EXTDEF, and also store a
770 * back-reference so that we can map later references to this
771 * segment number to the external index.
773 struct External *ext;
774 struct ExtBack *eb;
775 struct Segment *seg;
776 int i;
777 bool used_special = false; /* have we used the special text? */
779 #if defined(DEBUG) && DEBUG>2
780 nasm_error(ERR_DEBUG,
781 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
782 name, segment, offset, is_global, special);
783 #endif
786 * If it's a special-retry from pass two, discard it.
788 if (is_global == 3)
789 return;
792 * First check for the double-period, signifying something
793 * unusual.
795 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
796 if (!strcmp(name, "..start")) {
797 obj_entry_seg = segment;
798 obj_entry_ofs = offset;
799 return;
801 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
805 * Case (i):
807 if (obj_seg_needs_update) {
808 obj_seg_needs_update->name = name;
809 return;
810 } else if (obj_grp_needs_update) {
811 obj_grp_needs_update->name = name;
812 return;
814 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
815 return;
817 if (segment >= SEG_ABS || segment == NO_SEG) {
819 * SEG_ABS subcase of (ii).
821 if (is_global) {
822 struct Public *pub;
824 pub = *fpubtail = nasm_malloc(sizeof(*pub));
825 fpubtail = &pub->next;
826 pub->next = NULL;
827 pub->name = nasm_strdup(name);
828 pub->offset = offset;
829 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
831 if (special)
832 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
833 " for this symbol type");
834 return;
838 * If `any_segs' is still false, we might need to define a
839 * default segment, if they're trying to declare a label in
840 * `first_seg'.
842 if (!any_segs && segment == first_seg) {
843 int tempint; /* ignored */
844 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
845 nasm_panic(0, "strange segment conditions in OBJ driver");
848 for (seg = seghead; seg && is_global; seg = seg->next)
849 if (seg->index == segment) {
850 struct Public *loc = nasm_malloc(sizeof(*loc));
852 * Case (ii). Maybe MODPUB someday?
854 *seg->pubtail = loc;
855 seg->pubtail = &loc->next;
856 loc->next = NULL;
857 loc->name = nasm_strdup(name);
858 loc->offset = offset;
860 if (special)
861 nasm_error(ERR_NONFATAL,
862 "OBJ supports no special symbol features"
863 " for this symbol type");
864 return;
868 * Case (iii).
870 if (is_global) {
871 ext = *exttail = nasm_malloc(sizeof(*ext));
872 ext->next = NULL;
873 exttail = &ext->next;
874 ext->name = name;
875 /* Place by default all externs into the current segment */
876 ext->defwrt_type = DEFWRT_NONE;
878 /* 28-Apr-2002 - John Coffman
879 The following code was introduced on 12-Aug-2000, and breaks fixups
880 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
881 (5.10). It was introduced after FIXUP32 was added, and may be needed
882 for 32-bit segments. The following will get 16-bit segments working
883 again, and maybe someone can correct the 'if' condition which is
884 actually needed.
886 #if 0
887 if (current_seg) {
888 #else
889 if (current_seg && current_seg->use32) {
890 if (current_seg->grp) {
891 ext->defwrt_type = DEFWRT_GROUP;
892 ext->defwrt_ptr.grp = current_seg->grp;
893 } else {
894 ext->defwrt_type = DEFWRT_SEGMENT;
895 ext->defwrt_ptr.seg = current_seg;
898 #endif
900 if (is_global == 2) {
901 ext->commonsize = offset;
902 ext->commonelem = 1; /* default FAR */
903 } else
904 ext->commonsize = 0;
905 } else
906 return;
909 * Now process the special text, if any, to find default-WRT
910 * specifications and common-variable element-size and near/far
911 * specifications.
913 while (special && *special) {
914 used_special = true;
917 * We might have a default-WRT specification.
919 if (!nasm_strnicmp(special, "wrt", 3)) {
920 char *p;
921 int len;
922 special += 3;
923 special += strspn(special, " \t");
924 p = nasm_strndup(special, len = strcspn(special, ":"));
925 obj_ext_set_defwrt(ext, p);
926 special += len;
927 if (*special && *special != ':')
928 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
929 " text for `%s'", ext->name);
930 else if (*special == ':')
931 special++;
935 * The NEAR or FAR keywords specify nearness or
936 * farness. FAR gives default element size 1.
938 if (!nasm_strnicmp(special, "far", 3)) {
939 if (ext->commonsize)
940 ext->commonelem = 1;
941 else
942 nasm_error(ERR_NONFATAL,
943 "`%s': `far' keyword may only be applied"
944 " to common variables\n", ext->name);
945 special += 3;
946 special += strspn(special, " \t");
947 } else if (!nasm_strnicmp(special, "near", 4)) {
948 if (ext->commonsize)
949 ext->commonelem = 0;
950 else
951 nasm_error(ERR_NONFATAL,
952 "`%s': `far' keyword may only be applied"
953 " to common variables\n", ext->name);
954 special += 4;
955 special += strspn(special, " \t");
959 * If it's a common, and anything else remains on the line
960 * before a further colon, evaluate it as an expression and
961 * use that as the element size. Forward references aren't
962 * allowed.
964 if (*special == ':')
965 special++;
966 else if (*special) {
967 if (ext->commonsize) {
968 expr *e;
969 struct tokenval tokval;
971 stdscan_reset();
972 stdscan_set(special);
973 tokval.t_type = TOKEN_INVALID;
974 e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
975 if (e) {
976 if (!is_simple(e))
977 nasm_error(ERR_NONFATAL, "cannot use relocatable"
978 " expression as common-variable element size");
979 else
980 ext->commonelem = reloc_value(e);
982 special = stdscan_get();
983 } else {
984 nasm_error(ERR_NONFATAL,
985 "`%s': element-size specifications only"
986 " apply to common variables", ext->name);
987 while (*special && *special != ':')
988 special++;
989 if (*special == ':')
990 special++;
995 i = segment / 2;
996 eb = ebhead;
997 if (!eb) {
998 eb = *ebtail = nasm_zalloc(sizeof(*eb));
999 eb->next = NULL;
1000 ebtail = &eb->next;
1002 while (i >= EXT_BLKSIZ) {
1003 if (eb && eb->next)
1004 eb = eb->next;
1005 else {
1006 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1007 eb->next = NULL;
1008 ebtail = &eb->next;
1010 i -= EXT_BLKSIZ;
1012 eb->exts[i] = ext;
1013 ext->index = ++externals;
1015 if (special && !used_special)
1016 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1017 " for this symbol type");
1020 /* forward declaration */
1021 static void obj_write_fixup(ObjRecord * orp, int bytes,
1022 int segrel, int32_t seg, int32_t wrt,
1023 struct Segment *segto);
1025 static void obj_out(int32_t segto, const void *data,
1026 enum out_type type, uint64_t size,
1027 int32_t segment, int32_t wrt)
1029 const uint8_t *ucdata;
1030 int32_t ldata;
1031 struct Segment *seg;
1032 ObjRecord *orp;
1035 * handle absolute-assembly (structure definitions)
1037 if (segto == NO_SEG) {
1038 if (type != OUT_RESERVE)
1039 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1040 " space");
1041 return;
1045 * If `any_segs' is still false, we must define a default
1046 * segment.
1048 if (!any_segs) {
1049 int tempint; /* ignored */
1050 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1051 nasm_panic(0, "strange segment conditions in OBJ driver");
1055 * Find the segment we are targetting.
1057 for (seg = seghead; seg; seg = seg->next)
1058 if (seg->index == segto)
1059 break;
1060 if (!seg)
1061 nasm_panic(0, "code directed to nonexistent segment?");
1063 orp = seg->orp;
1064 orp->parm[0] = seg->currentpos;
1066 switch (type) {
1067 case OUT_RAWDATA:
1068 ucdata = data;
1069 while (size > 0) {
1070 unsigned int len;
1071 orp = obj_check(seg->orp, 1);
1072 len = RECORD_MAX - orp->used;
1073 if (len > size)
1074 len = size;
1075 memcpy(orp->buf + orp->used, ucdata, len);
1076 orp->committed = orp->used += len;
1077 orp->parm[0] = seg->currentpos += len;
1078 ucdata += len;
1079 size -= len;
1081 break;
1083 case OUT_ADDRESS:
1084 case OUT_REL1ADR:
1085 case OUT_REL2ADR:
1086 case OUT_REL4ADR:
1087 case OUT_REL8ADR:
1089 int rsize;
1091 if (type == OUT_ADDRESS)
1092 size = abs((int)size);
1094 if (segment == NO_SEG && type != OUT_ADDRESS)
1095 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1096 " supported by OBJ format");
1097 if (segment >= SEG_ABS)
1098 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1099 " by OBJ format");
1101 ldata = *(int64_t *)data;
1102 if (type != OUT_ADDRESS) {
1103 ldata += size;
1104 size = realsize(type, size);
1105 ldata -= size;
1108 if (size > UINT_MAX)
1109 size = 0;
1111 switch ((unsigned int)size) {
1112 default:
1113 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1114 "32-byte relocations");
1115 segment = NO_SEG; /* Don't actually generate a relocation */
1116 break;
1117 case 2:
1118 orp = obj_word(orp, ldata);
1119 break;
1120 case 4:
1121 orp = obj_dword(orp, ldata);
1122 break;
1125 rsize = size;
1126 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1127 size == 4) {
1129 * This is a 4-byte segment-base relocation such as
1130 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1131 * these, but if the constant term has the 16 low bits
1132 * zero, we can just apply a 2-byte segment-base
1133 * relocation to the low word instead.
1135 rsize = 2;
1136 if (ldata & 0xFFFF)
1137 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1138 " dword-size segment base references");
1140 if (segment != NO_SEG)
1141 obj_write_fixup(orp, rsize,
1142 (type == OUT_ADDRESS ? 0x4000 : 0),
1143 segment, wrt, seg);
1144 seg->currentpos += size;
1145 break;
1148 default:
1149 nasm_error(ERR_NONFATAL,
1150 "Relocation type not supported by output format");
1151 /* fall through */
1153 case OUT_RESERVE:
1154 if (orp->committed)
1155 orp = obj_bump(orp);
1156 seg->currentpos += size;
1157 break;
1159 obj_commit(orp);
1162 static void obj_write_fixup(ObjRecord * orp, int bytes,
1163 int segrel, int32_t seg, int32_t wrt,
1164 struct Segment *segto)
1166 unsigned locat;
1167 int method;
1168 int base;
1169 int32_t tidx, fidx;
1170 struct Segment *s = NULL;
1171 struct Group *g = NULL;
1172 struct External *e = NULL;
1173 ObjRecord *forp;
1175 if (bytes != 2 && bytes != 4) {
1176 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1177 " %d-bit relocations", bytes << 3);
1178 return;
1181 forp = orp->child;
1182 if (forp == NULL) {
1183 orp->child = forp = obj_new();
1184 forp->up = &(orp->child);
1185 /* We should choose between FIXUPP and FIXU32 record type */
1186 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1187 if (segto->use32)
1188 forp->type = FIXU32;
1189 else
1190 forp->type = FIXUPP;
1193 if (seg % 2) {
1194 base = true;
1195 locat = FIX_16_SELECTOR;
1196 seg--;
1197 if (bytes != 2)
1198 nasm_panic(0, "OBJ: 4-byte segment base fixup got"
1199 " through sanity check");
1200 } else {
1201 base = false;
1202 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1203 if (!segrel)
1205 * There is a bug in tlink that makes it process self relative
1206 * fixups incorrectly if the x_size doesn't match the location
1207 * size.
1209 forp = obj_force(forp, bytes << 3);
1212 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1214 tidx = fidx = -1, method = 0; /* placate optimisers */
1217 * See if we can find the segment ID in our segment list. If
1218 * so, we have a T4 (LSEG) target.
1220 for (s = seghead; s; s = s->next)
1221 if (s->index == seg)
1222 break;
1223 if (s)
1224 method = 4, tidx = s->obj_index;
1225 else {
1226 for (g = grphead; g; g = g->next)
1227 if (g->index == seg)
1228 break;
1229 if (g)
1230 method = 5, tidx = g->obj_index;
1231 else {
1232 int32_t i = seg / 2;
1233 struct ExtBack *eb = ebhead;
1234 while (i >= EXT_BLKSIZ) {
1235 if (eb)
1236 eb = eb->next;
1237 else
1238 break;
1239 i -= EXT_BLKSIZ;
1241 if (eb)
1242 method = 6, e = eb->exts[i], tidx = e->index;
1243 else
1244 nasm_panic(0,
1245 "unrecognised segment value in obj_write_fixup");
1250 * If no WRT given, assume the natural default, which is method
1251 * F5 unless:
1253 * - we are doing an OFFSET fixup for a grouped segment, in
1254 * which case we require F1 (group).
1256 * - we are doing an OFFSET fixup for an external with a
1257 * default WRT, in which case we must honour the default WRT.
1259 if (wrt == NO_SEG) {
1260 if (!base && s && s->grp)
1261 method |= 0x10, fidx = s->grp->obj_index;
1262 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1263 if (e->defwrt_type == DEFWRT_SEGMENT)
1264 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1265 else if (e->defwrt_type == DEFWRT_GROUP)
1266 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1267 else {
1268 nasm_error(ERR_NONFATAL, "default WRT specification for"
1269 " external `%s' unresolved", e->name);
1270 method |= 0x50, fidx = -1; /* got to do _something_ */
1272 } else
1273 method |= 0x50, fidx = -1;
1274 } else {
1276 * See if we can find the WRT-segment ID in our segment
1277 * list. If so, we have a F0 (LSEG) frame.
1279 for (s = seghead; s; s = s->next)
1280 if (s->index == wrt - 1)
1281 break;
1282 if (s)
1283 method |= 0x00, fidx = s->obj_index;
1284 else {
1285 for (g = grphead; g; g = g->next)
1286 if (g->index == wrt - 1)
1287 break;
1288 if (g)
1289 method |= 0x10, fidx = g->obj_index;
1290 else {
1291 int32_t i = wrt / 2;
1292 struct ExtBack *eb = ebhead;
1293 while (i >= EXT_BLKSIZ) {
1294 if (eb)
1295 eb = eb->next;
1296 else
1297 break;
1298 i -= EXT_BLKSIZ;
1300 if (eb)
1301 method |= 0x20, fidx = eb->exts[i]->index;
1302 else
1303 nasm_panic(0,
1304 "unrecognised WRT value in obj_write_fixup");
1309 forp = obj_byte(forp, method);
1310 if (fidx != -1)
1311 forp = obj_index(forp, fidx);
1312 forp = obj_index(forp, tidx);
1313 obj_commit(forp);
1316 static int32_t obj_segment(char *name, int pass, int *bits)
1319 * We call the label manager here to define a name for the new
1320 * segment, and when our _own_ label-definition stub gets
1321 * called in return, it should register the new segment name
1322 * using the pointer it gets passed. That way we save memory,
1323 * by sponging off the label manager.
1325 #if defined(DEBUG) && DEBUG>=3
1326 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1327 name, pass, *bits);
1328 #endif
1329 if (!name) {
1330 *bits = 16;
1331 current_seg = NULL;
1332 return first_seg;
1333 } else {
1334 struct Segment *seg;
1335 struct Group *grp;
1336 struct External **extp;
1337 int obj_idx, i, attrs;
1338 bool rn_error;
1339 char *p;
1342 * Look for segment attributes.
1344 attrs = 0;
1345 while (*name == '.')
1346 name++; /* hack, but a documented one */
1347 p = name;
1348 while (*p && !nasm_isspace(*p))
1349 p++;
1350 if (*p) {
1351 *p++ = '\0';
1352 while (*p && nasm_isspace(*p))
1353 *p++ = '\0';
1355 while (*p) {
1356 while (*p && !nasm_isspace(*p))
1357 p++;
1358 if (*p) {
1359 *p++ = '\0';
1360 while (*p && nasm_isspace(*p))
1361 *p++ = '\0';
1364 attrs++;
1367 obj_idx = 1;
1368 for (seg = seghead; seg; seg = seg->next) {
1369 obj_idx++;
1370 if (!strcmp(seg->name, name)) {
1371 if (attrs > 0 && pass == 1)
1372 nasm_error(ERR_WARNING, "segment attributes specified on"
1373 " redeclaration of segment: ignoring");
1374 if (seg->use32)
1375 *bits = 32;
1376 else
1377 *bits = 16;
1378 current_seg = seg;
1379 return seg->index;
1383 *segtail = seg = nasm_malloc(sizeof(*seg));
1384 seg->next = NULL;
1385 segtail = &seg->next;
1386 seg->index = (any_segs ? seg_alloc() : first_seg);
1387 seg->obj_index = obj_idx;
1388 seg->grp = NULL;
1389 any_segs = true;
1390 seg->name = NULL;
1391 seg->currentpos = 0;
1392 seg->align = 1; /* default */
1393 seg->use32 = false; /* default */
1394 seg->combine = CMB_PUBLIC; /* default */
1395 seg->segclass = seg->overlay = NULL;
1396 seg->pubhead = NULL;
1397 seg->pubtail = &seg->pubhead;
1398 seg->lochead = NULL;
1399 seg->loctail = &seg->lochead;
1400 seg->orp = obj_new();
1401 seg->orp->up = &(seg->orp);
1402 seg->orp->ori = ori_ledata;
1403 seg->orp->type = LEDATA;
1404 seg->orp->parm[1] = obj_idx;
1407 * Process the segment attributes.
1409 p = name;
1410 while (attrs--) {
1411 p += strlen(p);
1412 while (!*p)
1413 p++;
1416 * `p' contains a segment attribute.
1418 if (!nasm_stricmp(p, "private"))
1419 seg->combine = CMB_PRIVATE;
1420 else if (!nasm_stricmp(p, "public"))
1421 seg->combine = CMB_PUBLIC;
1422 else if (!nasm_stricmp(p, "common"))
1423 seg->combine = CMB_COMMON;
1424 else if (!nasm_stricmp(p, "stack"))
1425 seg->combine = CMB_STACK;
1426 else if (!nasm_stricmp(p, "use16"))
1427 seg->use32 = false;
1428 else if (!nasm_stricmp(p, "use32"))
1429 seg->use32 = true;
1430 else if (!nasm_stricmp(p, "flat")) {
1432 * This segment is an OS/2 FLAT segment. That means
1433 * that its default group is group FLAT, even if
1434 * the group FLAT does not explicitly _contain_ the
1435 * segment.
1437 * When we see this, we must create the group
1438 * `FLAT', containing no segments, if it does not
1439 * already exist; then we must set the default
1440 * group of this segment to be the FLAT group.
1442 struct Group *grp;
1443 for (grp = grphead; grp; grp = grp->next)
1444 if (!strcmp(grp->name, "FLAT"))
1445 break;
1446 if (!grp) {
1447 obj_directive(D_GROUP, "FLAT", 1);
1448 for (grp = grphead; grp; grp = grp->next)
1449 if (!strcmp(grp->name, "FLAT"))
1450 break;
1451 if (!grp)
1452 nasm_panic(0, "failure to define FLAT?!");
1454 seg->grp = grp;
1455 } else if (!nasm_strnicmp(p, "class=", 6))
1456 seg->segclass = nasm_strdup(p + 6);
1457 else if (!nasm_strnicmp(p, "overlay=", 8))
1458 seg->overlay = nasm_strdup(p + 8);
1459 else if (!nasm_strnicmp(p, "align=", 6)) {
1460 seg->align = readnum(p + 6, &rn_error);
1461 if (rn_error) {
1462 seg->align = 1;
1463 nasm_error(ERR_NONFATAL, "segment alignment should be"
1464 " numeric");
1466 switch ((int)seg->align) {
1467 case 1: /* BYTE */
1468 case 2: /* WORD */
1469 case 4: /* DWORD */
1470 case 16: /* PARA */
1471 case 256: /* PAGE */
1472 case 4096: /* PharLap extension */
1473 break;
1474 case 8:
1475 nasm_error(ERR_WARNING,
1476 "OBJ format does not support alignment"
1477 " of 8: rounding up to 16");
1478 seg->align = 16;
1479 break;
1480 case 32:
1481 case 64:
1482 case 128:
1483 nasm_error(ERR_WARNING,
1484 "OBJ format does not support alignment"
1485 " of %d: rounding up to 256", seg->align);
1486 seg->align = 256;
1487 break;
1488 case 512:
1489 case 1024:
1490 case 2048:
1491 nasm_error(ERR_WARNING,
1492 "OBJ format does not support alignment"
1493 " of %d: rounding up to 4096", seg->align);
1494 seg->align = 4096;
1495 break;
1496 default:
1497 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1498 seg->align);
1499 seg->align = 1;
1500 break;
1502 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1503 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1504 if (rn_error)
1505 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1506 " attribute should be numeric");
1510 /* We need to know whenever we have at least one 32-bit segment */
1511 obj_use32 |= seg->use32;
1513 obj_seg_needs_update = seg;
1514 if (seg->align >= SEG_ABS)
1515 define_label(name, NO_SEG, seg->align - SEG_ABS,
1516 NULL, false, false);
1517 else
1518 define_label(name, seg->index + 1, 0L,
1519 NULL, false, false);
1520 obj_seg_needs_update = NULL;
1523 * See if this segment is defined in any groups.
1525 for (grp = grphead; grp; grp = grp->next) {
1526 for (i = grp->nindices; i < grp->nentries; i++) {
1527 if (!strcmp(grp->segs[i].name, seg->name)) {
1528 nasm_free(grp->segs[i].name);
1529 grp->segs[i] = grp->segs[grp->nindices];
1530 grp->segs[grp->nindices++].index = seg->obj_index;
1531 if (seg->grp)
1532 nasm_error(ERR_WARNING,
1533 "segment `%s' is already part of"
1534 " a group: first one takes precedence",
1535 seg->name);
1536 else
1537 seg->grp = grp;
1543 * Walk through the list of externals with unresolved
1544 * default-WRT clauses, and resolve any that point at this
1545 * segment.
1547 extp = &dws;
1548 while (*extp) {
1549 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1550 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1551 nasm_free((*extp)->defwrt_ptr.string);
1552 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1553 (*extp)->defwrt_ptr.seg = seg;
1554 *extp = (*extp)->next_dws;
1555 } else
1556 extp = &(*extp)->next_dws;
1559 if (seg->use32)
1560 *bits = 32;
1561 else
1562 *bits = 16;
1563 current_seg = seg;
1564 return seg->index;
1568 static int obj_directive(enum directives directive, char *value, int pass)
1570 switch (directive) {
1571 case D_GROUP:
1573 char *p, *q, *v;
1574 if (pass == 1) {
1575 struct Group *grp;
1576 struct Segment *seg;
1577 struct External **extp;
1578 int obj_idx;
1580 q = value;
1581 while (*q == '.')
1582 q++; /* hack, but a documented one */
1583 v = q;
1584 while (*q && !nasm_isspace(*q))
1585 q++;
1586 if (nasm_isspace(*q)) {
1587 *q++ = '\0';
1588 while (*q && nasm_isspace(*q))
1589 q++;
1592 * Here we used to sanity-check the group directive to
1593 * ensure nobody tried to declare a group containing no
1594 * segments. However, OS/2 does this as standard
1595 * practice, so the sanity check has been removed.
1597 * if (!*q) {
1598 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1599 * return 1;
1603 obj_idx = 1;
1604 for (grp = grphead; grp; grp = grp->next) {
1605 obj_idx++;
1606 if (!strcmp(grp->name, v)) {
1607 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1608 return 1;
1612 *grptail = grp = nasm_malloc(sizeof(*grp));
1613 grp->next = NULL;
1614 grptail = &grp->next;
1615 grp->index = seg_alloc();
1616 grp->obj_index = obj_idx;
1617 grp->nindices = grp->nentries = 0;
1618 grp->name = NULL;
1620 obj_grp_needs_update = grp;
1621 define_label(v, grp->index + 1, 0L, NULL, false, false);
1622 obj_grp_needs_update = NULL;
1624 while (*q) {
1625 p = q;
1626 while (*q && !nasm_isspace(*q))
1627 q++;
1628 if (nasm_isspace(*q)) {
1629 *q++ = '\0';
1630 while (*q && nasm_isspace(*q))
1631 q++;
1634 * Now p contains a segment name. Find it.
1636 for (seg = seghead; seg; seg = seg->next)
1637 if (!strcmp(seg->name, p))
1638 break;
1639 if (seg) {
1641 * We have a segment index. Shift a name entry
1642 * to the end of the array to make room.
1644 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1645 grp->segs[grp->nindices++].index = seg->obj_index;
1646 if (seg->grp)
1647 nasm_error(ERR_WARNING,
1648 "segment `%s' is already part of"
1649 " a group: first one takes precedence",
1650 seg->name);
1651 else
1652 seg->grp = grp;
1653 } else {
1655 * We have an as-yet undefined segment.
1656 * Remember its name, for later.
1658 grp->segs[grp->nentries++].name = nasm_strdup(p);
1663 * Walk through the list of externals with unresolved
1664 * default-WRT clauses, and resolve any that point at
1665 * this group.
1667 extp = &dws;
1668 while (*extp) {
1669 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1670 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1671 nasm_free((*extp)->defwrt_ptr.string);
1672 (*extp)->defwrt_type = DEFWRT_GROUP;
1673 (*extp)->defwrt_ptr.grp = grp;
1674 *extp = (*extp)->next_dws;
1675 } else
1676 extp = &(*extp)->next_dws;
1679 return 1;
1681 case D_UPPERCASE:
1682 obj_uppercase = true;
1683 return 1;
1685 case D_IMPORT:
1687 char *q, *extname, *libname, *impname;
1689 if (pass == 2)
1690 return 1; /* ignore in pass two */
1691 extname = q = value;
1692 while (*q && !nasm_isspace(*q))
1693 q++;
1694 if (nasm_isspace(*q)) {
1695 *q++ = '\0';
1696 while (*q && nasm_isspace(*q))
1697 q++;
1700 libname = q;
1701 while (*q && !nasm_isspace(*q))
1702 q++;
1703 if (nasm_isspace(*q)) {
1704 *q++ = '\0';
1705 while (*q && nasm_isspace(*q))
1706 q++;
1709 impname = q;
1711 if (!*extname || !*libname)
1712 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1713 " and library name");
1714 else {
1715 struct ImpDef *imp;
1716 bool err = false;
1718 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1719 imptail = &imp->next;
1720 imp->next = NULL;
1721 imp->extname = nasm_strdup(extname);
1722 imp->libname = nasm_strdup(libname);
1723 imp->impindex = readnum(impname, &err);
1724 if (!*impname || err)
1725 imp->impname = nasm_strdup(impname);
1726 else
1727 imp->impname = NULL;
1730 return 1;
1732 case D_EXPORT:
1734 char *q, *extname, *intname, *v;
1735 struct ExpDef *export;
1736 int flags = 0;
1737 unsigned int ordinal = 0;
1739 if (pass == 2)
1740 return 1; /* ignore in pass two */
1741 intname = q = value;
1742 while (*q && !nasm_isspace(*q))
1743 q++;
1744 if (nasm_isspace(*q)) {
1745 *q++ = '\0';
1746 while (*q && nasm_isspace(*q))
1747 q++;
1750 extname = q;
1751 while (*q && !nasm_isspace(*q))
1752 q++;
1753 if (nasm_isspace(*q)) {
1754 *q++ = '\0';
1755 while (*q && nasm_isspace(*q))
1756 q++;
1759 if (!*intname) {
1760 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1761 return 1;
1763 if (!*extname) {
1764 extname = intname;
1765 intname = "";
1767 while (*q) {
1768 v = q;
1769 while (*q && !nasm_isspace(*q))
1770 q++;
1771 if (nasm_isspace(*q)) {
1772 *q++ = '\0';
1773 while (*q && nasm_isspace(*q))
1774 q++;
1776 if (!nasm_stricmp(v, "resident"))
1777 flags |= EXPDEF_FLAG_RESIDENT;
1778 else if (!nasm_stricmp(v, "nodata"))
1779 flags |= EXPDEF_FLAG_NODATA;
1780 else if (!nasm_strnicmp(v, "parm=", 5)) {
1781 bool err = false;
1782 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1783 if (err) {
1784 nasm_error(ERR_NONFATAL,
1785 "value `%s' for `parm' is non-numeric", v + 5);
1786 return 1;
1788 } else {
1789 bool err = false;
1790 ordinal = readnum(v, &err);
1791 if (err) {
1792 nasm_error(ERR_NONFATAL,
1793 "unrecognised export qualifier `%s'", v);
1794 return 1;
1796 flags |= EXPDEF_FLAG_ORDINAL;
1800 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1801 exptail = &export->next;
1802 export->next = NULL;
1803 export->extname = nasm_strdup(extname);
1804 export->intname = nasm_strdup(intname);
1805 export->ordinal = ordinal;
1806 export->flags = flags;
1808 return 1;
1810 default:
1811 return 0;
1815 static void obj_sectalign(int32_t seg, unsigned int value)
1817 struct Segment *s;
1819 list_for_each(s, seghead) {
1820 if (s->index == seg)
1821 break;
1825 * it should not be too big value
1826 * and applied on non-absolute sections
1828 if (!s || !is_power2(value) ||
1829 value > 4096 || s->align >= SEG_ABS)
1830 return;
1833 * FIXME: No code duplication please
1834 * consider making helper for this
1835 * mapping since section handler has
1836 * to do the same
1838 switch (value) {
1839 case 8:
1840 value = 16;
1841 break;
1842 case 32:
1843 case 64:
1844 case 128:
1845 value = 256;
1846 break;
1847 case 512:
1848 case 1024:
1849 case 2048:
1850 value = 4096;
1851 break;
1854 if (s->align < (int)value)
1855 s->align = value;
1858 static int32_t obj_segbase(int32_t segment)
1860 struct Segment *seg;
1863 * Find the segment in our list.
1865 for (seg = seghead; seg; seg = seg->next)
1866 if (seg->index == segment - 1)
1867 break;
1869 if (!seg) {
1871 * Might be an external with a default WRT.
1873 int32_t i = segment / 2;
1874 struct ExtBack *eb = ebhead;
1875 struct External *e;
1877 while (i >= EXT_BLKSIZ) {
1878 if (eb)
1879 eb = eb->next;
1880 else
1881 break;
1882 i -= EXT_BLKSIZ;
1884 if (eb) {
1885 e = eb->exts[i];
1886 if (!e) {
1887 nasm_assert(pass0 == 0);
1888 /* Not available - can happen during optimization */
1889 return NO_SEG;
1892 switch (e->defwrt_type) {
1893 case DEFWRT_NONE:
1894 return segment; /* fine */
1895 case DEFWRT_SEGMENT:
1896 return e->defwrt_ptr.seg->index + 1;
1897 case DEFWRT_GROUP:
1898 return e->defwrt_ptr.grp->index + 1;
1899 default:
1900 return NO_SEG; /* can't tell what it is */
1904 return segment; /* not one of ours - leave it alone */
1907 if (seg->align >= SEG_ABS)
1908 return seg->align; /* absolute segment */
1909 if (seg->grp)
1910 return seg->grp->index + 1; /* grouped segment */
1912 return segment; /* no special treatment */
1915 static void obj_filename(char *inname, char *outname)
1917 strcpy(obj_infile, inname);
1918 standard_extension(inname, outname, ".obj");
1921 static void obj_write_file(void)
1923 struct Segment *seg, *entry_seg_ptr = 0;
1924 struct FileName *fn;
1925 struct LineNumber *ln;
1926 struct Group *grp;
1927 struct Public *pub, *loc;
1928 struct External *ext;
1929 struct ImpDef *imp;
1930 struct ExpDef *export;
1931 int lname_idx;
1932 ObjRecord *orp;
1933 const bool debuginfo = (dfmt == &borland_debug_form);
1936 * Write the THEADR module header.
1938 orp = obj_new();
1939 orp->type = THEADR;
1940 obj_name(orp, obj_infile);
1941 obj_emit2(orp);
1944 * Write the NASM boast comment.
1946 orp->type = COMENT;
1947 obj_rword(orp, 0); /* comment type zero */
1948 obj_name(orp, nasm_comment);
1949 obj_emit2(orp);
1951 orp->type = COMENT;
1953 * Write the IMPDEF records, if any.
1955 for (imp = imphead; imp; imp = imp->next) {
1956 obj_rword(orp, 0xA0); /* comment class A0 */
1957 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1958 if (imp->impname)
1959 obj_byte(orp, 0); /* import by name */
1960 else
1961 obj_byte(orp, 1); /* import by ordinal */
1962 obj_name(orp, imp->extname);
1963 obj_name(orp, imp->libname);
1964 if (imp->impname)
1965 obj_name(orp, imp->impname);
1966 else
1967 obj_word(orp, imp->impindex);
1968 obj_emit2(orp);
1972 * Write the EXPDEF records, if any.
1974 for (export = exphead; export; export = export->next) {
1975 obj_rword(orp, 0xA0); /* comment class A0 */
1976 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1977 obj_byte(orp, export->flags);
1978 obj_name(orp, export->extname);
1979 obj_name(orp, export->intname);
1980 if (export->flags & EXPDEF_FLAG_ORDINAL)
1981 obj_word(orp, export->ordinal);
1982 obj_emit2(orp);
1985 /* we're using extended OMF if we put in debug info */
1986 if (debuginfo) {
1987 orp->type = COMENT;
1988 obj_byte(orp, 0x40);
1989 obj_byte(orp, dEXTENDED);
1990 obj_emit2(orp);
1994 * Write the first LNAMES record, containing LNAME one, which
1995 * is null. Also initialize the LNAME counter.
1997 orp->type = LNAMES;
1998 obj_byte(orp, 0);
1999 lname_idx = 1;
2001 * Write some LNAMES for the segment names
2003 for (seg = seghead; seg; seg = seg->next) {
2004 orp = obj_name(orp, seg->name);
2005 if (seg->segclass)
2006 orp = obj_name(orp, seg->segclass);
2007 if (seg->overlay)
2008 orp = obj_name(orp, seg->overlay);
2009 obj_commit(orp);
2012 * Write some LNAMES for the group names
2014 for (grp = grphead; grp; grp = grp->next) {
2015 orp = obj_name(orp, grp->name);
2016 obj_commit(orp);
2018 obj_emit(orp);
2021 * Write the SEGDEF records.
2023 orp->type = SEGDEF;
2024 for (seg = seghead; seg; seg = seg->next) {
2025 int acbp;
2026 uint32_t seglen = seg->currentpos;
2028 acbp = (seg->combine << 2); /* C field */
2030 if (seg->use32)
2031 acbp |= 0x01; /* P bit is Use32 flag */
2032 else if (seglen == 0x10000L) {
2033 seglen = 0; /* This special case may be needed for old linkers */
2034 acbp |= 0x02; /* B bit */
2037 /* A field */
2038 if (seg->align >= SEG_ABS)
2039 /* acbp |= 0x00 */ ;
2040 else if (seg->align >= 4096) {
2041 if (seg->align > 4096)
2042 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2043 " than OBJ format supports", seg->name);
2044 acbp |= 0xC0; /* PharLap extension */
2045 } else if (seg->align >= 256) {
2046 acbp |= 0x80;
2047 } else if (seg->align >= 16) {
2048 acbp |= 0x60;
2049 } else if (seg->align >= 4) {
2050 acbp |= 0xA0;
2051 } else if (seg->align >= 2) {
2052 acbp |= 0x40;
2053 } else
2054 acbp |= 0x20;
2056 obj_byte(orp, acbp);
2057 if (seg->align & SEG_ABS) {
2058 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2059 obj_byte(orp, 0); /* Offset */
2061 obj_x(orp, seglen);
2062 obj_index(orp, ++lname_idx);
2063 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2064 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2065 obj_emit2(orp);
2069 * Write the GRPDEF records.
2071 orp->type = GRPDEF;
2072 for (grp = grphead; grp; grp = grp->next) {
2073 int i;
2075 if (grp->nindices != grp->nentries) {
2076 for (i = grp->nindices; i < grp->nentries; i++) {
2077 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2078 " `%s'", grp->name, grp->segs[i].name);
2079 nasm_free(grp->segs[i].name);
2080 grp->segs[i].name = NULL;
2083 obj_index(orp, ++lname_idx);
2084 for (i = 0; i < grp->nindices; i++) {
2085 obj_byte(orp, 0xFF);
2086 obj_index(orp, grp->segs[i].index);
2088 obj_emit2(orp);
2092 * Write the PUBDEF records: first the ones in the segments,
2093 * then the far-absolutes.
2095 orp->type = PUBDEF;
2096 orp->ori = ori_pubdef;
2097 for (seg = seghead; seg; seg = seg->next) {
2098 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2099 orp->parm[1] = seg->obj_index;
2100 for (pub = seg->pubhead; pub; pub = pub->next) {
2101 orp = obj_name(orp, pub->name);
2102 orp = obj_x(orp, pub->offset);
2103 orp = obj_byte(orp, 0); /* type index */
2104 obj_commit(orp);
2106 obj_emit(orp);
2108 orp->parm[0] = 0;
2109 orp->parm[1] = 0;
2110 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2111 if (orp->parm[2] != (uint32_t)pub->segment) {
2112 obj_emit(orp);
2113 orp->parm[2] = pub->segment;
2115 orp = obj_name(orp, pub->name);
2116 orp = obj_x(orp, pub->offset);
2117 orp = obj_byte(orp, 0); /* type index */
2118 obj_commit(orp);
2120 obj_emit(orp);
2123 * Write the EXTDEF and COMDEF records, in order.
2125 orp->ori = ori_null;
2126 for (ext = exthead; ext; ext = ext->next) {
2127 if (ext->commonsize == 0) {
2128 if (orp->type != EXTDEF) {
2129 obj_emit(orp);
2130 orp->type = EXTDEF;
2132 orp = obj_name(orp, ext->name);
2133 orp = obj_index(orp, 0);
2134 } else {
2135 if (orp->type != COMDEF) {
2136 obj_emit(orp);
2137 orp->type = COMDEF;
2139 orp = obj_name(orp, ext->name);
2140 orp = obj_index(orp, 0);
2141 if (ext->commonelem) {
2142 orp = obj_byte(orp, 0x61); /* far communal */
2143 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2144 orp = obj_value(orp, ext->commonelem);
2145 } else {
2146 orp = obj_byte(orp, 0x62); /* near communal */
2147 orp = obj_value(orp, ext->commonsize);
2150 obj_commit(orp);
2152 obj_emit(orp);
2155 * Write a COMENT record stating that the linker's first pass
2156 * may stop processing at this point. Exception is if our
2157 * MODEND record specifies a start point, in which case,
2158 * according to some variants of the documentation, this COMENT
2159 * should be omitted. So we'll omit it just in case.
2160 * But, TASM puts it in all the time so if we are using
2161 * TASM debug stuff we are putting it in
2163 if (debuginfo || obj_entry_seg == NO_SEG) {
2164 orp->type = COMENT;
2165 obj_byte(orp, 0x40);
2166 obj_byte(orp, dLINKPASS);
2167 obj_byte(orp, 1);
2168 obj_emit2(orp);
2172 * 1) put out the compiler type
2173 * 2) Put out the type info. The only type we are using is near label #19
2175 if (debuginfo) {
2176 int i;
2177 struct Array *arrtmp = arrhead;
2178 orp->type = COMENT;
2179 obj_byte(orp, 0x40);
2180 obj_byte(orp, dCOMPDEF);
2181 obj_byte(orp, 4);
2182 obj_byte(orp, 0);
2183 obj_emit2(orp);
2185 obj_byte(orp, 0x40);
2186 obj_byte(orp, dTYPEDEF);
2187 obj_word(orp, 0x18); /* type # for linking */
2188 obj_word(orp, 6); /* size of type */
2189 obj_byte(orp, 0x2a); /* absolute type for debugging */
2190 obj_emit2(orp);
2191 obj_byte(orp, 0x40);
2192 obj_byte(orp, dTYPEDEF);
2193 obj_word(orp, 0x19); /* type # for linking */
2194 obj_word(orp, 0); /* size of type */
2195 obj_byte(orp, 0x24); /* absolute type for debugging */
2196 obj_byte(orp, 0); /* near/far specifier */
2197 obj_emit2(orp);
2198 obj_byte(orp, 0x40);
2199 obj_byte(orp, dTYPEDEF);
2200 obj_word(orp, 0x1A); /* type # for linking */
2201 obj_word(orp, 0); /* size of type */
2202 obj_byte(orp, 0x24); /* absolute type for debugging */
2203 obj_byte(orp, 1); /* near/far specifier */
2204 obj_emit2(orp);
2205 obj_byte(orp, 0x40);
2206 obj_byte(orp, dTYPEDEF);
2207 obj_word(orp, 0x1b); /* type # for linking */
2208 obj_word(orp, 0); /* size of type */
2209 obj_byte(orp, 0x23); /* absolute type for debugging */
2210 obj_byte(orp, 0);
2211 obj_byte(orp, 0);
2212 obj_byte(orp, 0);
2213 obj_emit2(orp);
2214 obj_byte(orp, 0x40);
2215 obj_byte(orp, dTYPEDEF);
2216 obj_word(orp, 0x1c); /* type # for linking */
2217 obj_word(orp, 0); /* size of type */
2218 obj_byte(orp, 0x23); /* absolute type for debugging */
2219 obj_byte(orp, 0);
2220 obj_byte(orp, 4);
2221 obj_byte(orp, 0);
2222 obj_emit2(orp);
2223 obj_byte(orp, 0x40);
2224 obj_byte(orp, dTYPEDEF);
2225 obj_word(orp, 0x1d); /* type # for linking */
2226 obj_word(orp, 0); /* size of type */
2227 obj_byte(orp, 0x23); /* absolute type for debugging */
2228 obj_byte(orp, 0);
2229 obj_byte(orp, 1);
2230 obj_byte(orp, 0);
2231 obj_emit2(orp);
2232 obj_byte(orp, 0x40);
2233 obj_byte(orp, dTYPEDEF);
2234 obj_word(orp, 0x1e); /* type # for linking */
2235 obj_word(orp, 0); /* size of type */
2236 obj_byte(orp, 0x23); /* absolute type for debugging */
2237 obj_byte(orp, 0);
2238 obj_byte(orp, 5);
2239 obj_byte(orp, 0);
2240 obj_emit2(orp);
2242 /* put out the array types */
2243 for (i = ARRAYBOT; i < arrindex; i++) {
2244 obj_byte(orp, 0x40);
2245 obj_byte(orp, dTYPEDEF);
2246 obj_word(orp, i); /* type # for linking */
2247 obj_word(orp, arrtmp->size); /* size of type */
2248 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2249 obj_byte(orp, arrtmp->basetype); /* base type */
2250 obj_emit2(orp);
2251 arrtmp = arrtmp->next;
2255 * write out line number info with a LINNUM record
2256 * switch records when we switch segments, and output the
2257 * file in a pseudo-TASM fashion. The record switch is naive; that
2258 * is that one file may have many records for the same segment
2259 * if there are lots of segment switches
2261 if (fnhead && debuginfo) {
2262 seg = fnhead->lnhead->segment;
2264 for (fn = fnhead; fn; fn = fn->next) {
2265 /* write out current file name */
2266 orp->type = COMENT;
2267 orp->ori = ori_null;
2268 obj_byte(orp, 0x40);
2269 obj_byte(orp, dFILNAME);
2270 obj_byte(orp, 0);
2271 obj_name(orp, fn->name);
2272 obj_dword(orp, 0);
2273 obj_emit2(orp);
2275 /* write out line numbers this file */
2277 orp->type = LINNUM;
2278 orp->ori = ori_linnum;
2279 for (ln = fn->lnhead; ln; ln = ln->next) {
2280 if (seg != ln->segment) {
2281 /* if we get here have to flush the buffer and start
2282 * a new record for a new segment
2284 seg = ln->segment;
2285 obj_emit(orp);
2287 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2288 orp->parm[1] = seg->obj_index;
2289 orp = obj_word(orp, ln->lineno);
2290 orp = obj_x(orp, ln->offset);
2291 obj_commit(orp);
2293 obj_emit(orp);
2297 * we are going to locate the entry point segment now
2298 * rather than wait until the MODEND record, because,
2299 * then we can output a special symbol to tell where the
2300 * entry point is.
2303 if (obj_entry_seg != NO_SEG) {
2304 for (seg = seghead; seg; seg = seg->next) {
2305 if (seg->index == obj_entry_seg) {
2306 entry_seg_ptr = seg;
2307 break;
2310 if (!seg)
2311 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2315 * get ready to put out symbol records
2317 orp->type = COMENT;
2318 orp->ori = ori_local;
2321 * put out a symbol for the entry point
2322 * no dots in this symbol, because, borland does
2323 * not (officially) support dots in label names
2324 * and I don't know what various versions of TLINK will do
2326 if (debuginfo && obj_entry_seg != NO_SEG) {
2327 orp = obj_name(orp, "start_of_program");
2328 orp = obj_word(orp, 0x19); /* type: near label */
2329 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2330 orp = obj_index(orp, seg->obj_index);
2331 orp = obj_x(orp, obj_entry_ofs);
2332 obj_commit(orp);
2336 * put out the local labels
2338 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2339 /* labels this seg */
2340 for (loc = seg->lochead; loc; loc = loc->next) {
2341 orp = obj_name(orp, loc->name);
2342 orp = obj_word(orp, loc->type);
2343 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2344 orp = obj_index(orp, seg->obj_index);
2345 orp = obj_x(orp, loc->offset);
2346 obj_commit(orp);
2349 if (orp->used)
2350 obj_emit(orp);
2353 * Write the LEDATA/FIXUPP pairs.
2355 for (seg = seghead; seg; seg = seg->next) {
2356 obj_emit(seg->orp);
2357 nasm_free(seg->orp);
2361 * Write the MODEND module end marker.
2363 orp->type = obj_use32 ? MODE32 : MODEND;
2364 orp->ori = ori_null;
2365 if (entry_seg_ptr) {
2366 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2367 obj_byte(orp, 0xC1);
2368 seg = entry_seg_ptr;
2369 if (seg->grp) {
2370 obj_byte(orp, 0x10);
2371 obj_index(orp, seg->grp->obj_index);
2372 } else {
2374 * the below changed to prevent TLINK crashing.
2375 * Previous more efficient version read:
2377 * obj_byte (orp, 0x50);
2379 obj_byte(orp, 0x00);
2380 obj_index(orp, seg->obj_index);
2382 obj_index(orp, seg->obj_index);
2383 obj_x(orp, obj_entry_ofs);
2384 } else
2385 obj_byte(orp, 0);
2386 obj_emit2(orp);
2387 nasm_free(orp);
2390 static void obj_fwrite(ObjRecord * orp)
2392 unsigned int cksum, len;
2393 uint8_t *ptr;
2395 cksum = orp->type;
2396 if (orp->x_size == 32)
2397 cksum |= 1;
2398 fputc(cksum, ofile);
2399 len = orp->committed + 1;
2400 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2401 fwriteint16_t(len, ofile);
2402 nasm_write(orp->buf, len-1, ofile);
2403 for (ptr = orp->buf; --len; ptr++)
2404 cksum += *ptr;
2405 fputc((-cksum) & 0xFF, ofile);
2408 extern macros_t obj_stdmac[];
2410 static void dbgbi_init(void)
2412 fnhead = NULL;
2413 fntail = &fnhead;
2414 arrindex = ARRAYBOT;
2415 arrhead = NULL;
2416 arrtail = &arrhead;
2418 static void dbgbi_cleanup(void)
2420 struct Segment *segtmp;
2421 while (fnhead) {
2422 struct FileName *fntemp = fnhead;
2423 while (fnhead->lnhead) {
2424 struct LineNumber *lntemp = fnhead->lnhead;
2425 fnhead->lnhead = lntemp->next;
2426 nasm_free(lntemp);
2428 fnhead = fnhead->next;
2429 nasm_free(fntemp->name);
2430 nasm_free(fntemp);
2432 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2433 while (segtmp->lochead) {
2434 struct Public *loctmp = segtmp->lochead;
2435 segtmp->lochead = loctmp->next;
2436 nasm_free(loctmp->name);
2437 nasm_free(loctmp);
2440 while (arrhead) {
2441 struct Array *arrtmp = arrhead;
2442 arrhead = arrhead->next;
2443 nasm_free(arrtmp);
2447 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2449 struct FileName *fn;
2450 struct LineNumber *ln;
2451 struct Segment *seg;
2453 if (segto == NO_SEG)
2454 return;
2457 * If `any_segs' is still false, we must define a default
2458 * segment.
2460 if (!any_segs) {
2461 int tempint; /* ignored */
2462 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2463 nasm_panic(0, "strange segment conditions in OBJ driver");
2467 * Find the segment we are targetting.
2469 for (seg = seghead; seg; seg = seg->next)
2470 if (seg->index == segto)
2471 break;
2472 if (!seg)
2473 nasm_panic(0, "lineno directed to nonexistent segment?");
2475 /* for (fn = fnhead; fn; fn = fnhead->next) */
2476 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2477 if (!nasm_stricmp(lnfname, fn->name))
2478 break;
2479 if (!fn) {
2480 fn = nasm_malloc(sizeof(*fn));
2481 fn->name = nasm_malloc(strlen(lnfname) + 1);
2482 strcpy(fn->name, lnfname);
2483 fn->lnhead = NULL;
2484 fn->lntail = &fn->lnhead;
2485 fn->next = NULL;
2486 *fntail = fn;
2487 fntail = &fn->next;
2489 ln = nasm_malloc(sizeof(*ln));
2490 ln->segment = seg;
2491 ln->offset = seg->currentpos;
2492 ln->lineno = lineno;
2493 ln->next = NULL;
2494 *fn->lntail = ln;
2495 fn->lntail = &ln->next;
2498 static void dbgbi_deflabel(char *name, int32_t segment,
2499 int64_t offset, int is_global, char *special)
2501 struct Segment *seg;
2503 (void)special;
2506 * Note: ..[^@] special symbols are filtered in labels.c
2510 * If it's a special-retry from pass two, discard it.
2512 if (is_global == 3)
2513 return;
2516 * Case (i):
2518 if (obj_seg_needs_update) {
2519 return;
2520 } else if (obj_grp_needs_update) {
2521 return;
2523 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2524 return;
2526 if (segment >= SEG_ABS || segment == NO_SEG) {
2527 return;
2531 * If `any_segs' is still false, we might need to define a
2532 * default segment, if they're trying to declare a label in
2533 * `first_seg'. But the label should exist due to a prior
2534 * call to obj_deflabel so we can skip that.
2537 for (seg = seghead; seg; seg = seg->next)
2538 if (seg->index == segment) {
2539 struct Public *loc = nasm_malloc(sizeof(*loc));
2541 * Case (ii). Maybe MODPUB someday?
2543 last_defined = *seg->loctail = loc;
2544 seg->loctail = &loc->next;
2545 loc->next = NULL;
2546 loc->name = nasm_strdup(name);
2547 loc->offset = offset;
2550 static void dbgbi_typevalue(int32_t type)
2552 int vsize;
2553 int elem = TYM_ELEMENTS(type);
2554 type = TYM_TYPE(type);
2556 if (!last_defined)
2557 return;
2559 switch (type) {
2560 case TY_BYTE:
2561 last_defined->type = 8; /* uint8_t */
2562 vsize = 1;
2563 break;
2564 case TY_WORD:
2565 last_defined->type = 10; /* unsigned word */
2566 vsize = 2;
2567 break;
2568 case TY_DWORD:
2569 last_defined->type = 12; /* unsigned dword */
2570 vsize = 4;
2571 break;
2572 case TY_FLOAT:
2573 last_defined->type = 14; /* float */
2574 vsize = 4;
2575 break;
2576 case TY_QWORD:
2577 last_defined->type = 15; /* qword */
2578 vsize = 8;
2579 break;
2580 case TY_TBYTE:
2581 last_defined->type = 16; /* TBYTE */
2582 vsize = 10;
2583 break;
2584 default:
2585 last_defined->type = 0x19; /*label */
2586 vsize = 0;
2587 break;
2590 if (elem > 1) {
2591 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2592 int vtype = last_defined->type;
2593 arrtmp->size = vsize * elem;
2594 arrtmp->basetype = vtype;
2595 arrtmp->next = NULL;
2596 last_defined->type = arrindex++;
2597 *arrtail = arrtmp;
2598 arrtail = &(arrtmp->next);
2600 last_defined = NULL;
2602 static void dbgbi_output(int output_type, void *param)
2604 (void)output_type;
2605 (void)param;
2607 static struct dfmt borland_debug_form = {
2608 "Borland Debug Records",
2609 "borland",
2610 dbgbi_init,
2611 dbgbi_linnum,
2612 dbgbi_deflabel,
2613 null_debug_directive,
2614 dbgbi_typevalue,
2615 dbgbi_output,
2616 dbgbi_cleanup,
2619 static struct dfmt *borland_debug_arr[3] = {
2620 &borland_debug_form,
2621 &null_debug_form,
2622 NULL
2625 struct ofmt of_obj = {
2626 "MS-DOS 16-bit/32-bit OMF object files",
2627 "obj",
2630 borland_debug_arr,
2631 &borland_debug_form,
2632 obj_stdmac,
2633 obj_init,
2634 obj_set_info,
2635 obj_out,
2636 obj_deflabel,
2637 obj_segment,
2638 obj_sectalign,
2639 obj_segbase,
2640 obj_directive,
2641 obj_filename,
2642 obj_cleanup
2644 #endif /* OF_OBJ */