disasm: ignore opcodes 370 and 371
[nasm/sigaren-mirror.git] / output / outobj.c
blob6fa54190f701ee54b7bf39c08ab33167846cd572
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2009 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;
629 /* The current segment */
630 static struct Segment *current_seg;
632 static int32_t obj_segment(char *, int, int *);
633 static void obj_write_file(int debuginfo);
634 static int obj_directive(enum directives, char *, int);
636 static void obj_init(void)
638 first_seg = seg_alloc();
639 any_segs = false;
640 fpubhead = NULL;
641 fpubtail = &fpubhead;
642 exthead = NULL;
643 exttail = &exthead;
644 imphead = NULL;
645 imptail = &imphead;
646 exphead = NULL;
647 exptail = &exphead;
648 dws = NULL;
649 externals = 0;
650 ebhead = NULL;
651 ebtail = &ebhead;
652 seghead = obj_seg_needs_update = NULL;
653 segtail = &seghead;
654 grphead = obj_grp_needs_update = NULL;
655 grptail = &grphead;
656 obj_entry_seg = NO_SEG;
657 obj_uppercase = false;
658 obj_use32 = false;
659 passtwo = 0;
660 current_seg = NULL;
663 static int obj_set_info(enum geninfo type, char **val)
665 (void)type;
666 (void)val;
668 return 0;
670 static void obj_cleanup(int debuginfo)
672 obj_write_file(debuginfo);
673 of_obj.current_dfmt->cleanup();
674 while (seghead) {
675 struct Segment *segtmp = seghead;
676 seghead = seghead->next;
677 while (segtmp->pubhead) {
678 struct Public *pubtmp = segtmp->pubhead;
679 segtmp->pubhead = pubtmp->next;
680 nasm_free(pubtmp->name);
681 nasm_free(pubtmp);
683 nasm_free(segtmp->segclass);
684 nasm_free(segtmp->overlay);
685 nasm_free(segtmp);
687 while (fpubhead) {
688 struct Public *pubtmp = fpubhead;
689 fpubhead = fpubhead->next;
690 nasm_free(pubtmp->name);
691 nasm_free(pubtmp);
693 while (exthead) {
694 struct External *exttmp = exthead;
695 exthead = exthead->next;
696 nasm_free(exttmp);
698 while (imphead) {
699 struct ImpDef *imptmp = imphead;
700 imphead = imphead->next;
701 nasm_free(imptmp->extname);
702 nasm_free(imptmp->libname);
703 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
704 nasm_free(imptmp);
706 while (exphead) {
707 struct ExpDef *exptmp = exphead;
708 exphead = exphead->next;
709 nasm_free(exptmp->extname);
710 nasm_free(exptmp->intname);
711 nasm_free(exptmp);
713 while (ebhead) {
714 struct ExtBack *ebtmp = ebhead;
715 ebhead = ebhead->next;
716 nasm_free(ebtmp);
718 while (grphead) {
719 struct Group *grptmp = grphead;
720 grphead = grphead->next;
721 nasm_free(grptmp);
725 static void obj_ext_set_defwrt(struct External *ext, char *id)
727 struct Segment *seg;
728 struct Group *grp;
730 for (seg = seghead; seg; seg = seg->next)
731 if (!strcmp(seg->name, id)) {
732 ext->defwrt_type = DEFWRT_SEGMENT;
733 ext->defwrt_ptr.seg = seg;
734 nasm_free(id);
735 return;
738 for (grp = grphead; grp; grp = grp->next)
739 if (!strcmp(grp->name, id)) {
740 ext->defwrt_type = DEFWRT_GROUP;
741 ext->defwrt_ptr.grp = grp;
742 nasm_free(id);
743 return;
746 ext->defwrt_type = DEFWRT_STRING;
747 ext->defwrt_ptr.string = id;
748 ext->next_dws = dws;
749 dws = ext;
752 static void obj_deflabel(char *name, int32_t segment,
753 int64_t offset, int is_global, char *special)
756 * We have three cases:
758 * (i) `segment' is a segment-base. If so, set the name field
759 * for the segment or group structure it refers to, and then
760 * return.
762 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
763 * Save the label position for later output of a PUBDEF record.
764 * (Or a MODPUB, if we work out how.)
766 * (iii) `segment' is not one of our segments. Save the label
767 * position for later output of an EXTDEF, and also store a
768 * back-reference so that we can map later references to this
769 * segment number to the external index.
771 struct External *ext;
772 struct ExtBack *eb;
773 struct Segment *seg;
774 int i;
775 bool used_special = false; /* have we used the special text? */
777 #if defined(DEBUG) && DEBUG>2
778 nasm_error(ERR_DEBUG,
779 " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
780 name, segment, offset, is_global, special);
781 #endif
784 * If it's a special-retry from pass two, discard it.
786 if (is_global == 3)
787 return;
790 * First check for the double-period, signifying something
791 * unusual.
793 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
794 if (!strcmp(name, "..start")) {
795 obj_entry_seg = segment;
796 obj_entry_ofs = offset;
797 return;
799 nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
803 * Case (i):
805 if (obj_seg_needs_update) {
806 obj_seg_needs_update->name = name;
807 return;
808 } else if (obj_grp_needs_update) {
809 obj_grp_needs_update->name = name;
810 return;
812 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
813 return;
815 if (segment >= SEG_ABS || segment == NO_SEG) {
817 * SEG_ABS subcase of (ii).
819 if (is_global) {
820 struct Public *pub;
822 pub = *fpubtail = nasm_malloc(sizeof(*pub));
823 fpubtail = &pub->next;
824 pub->next = NULL;
825 pub->name = nasm_strdup(name);
826 pub->offset = offset;
827 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
829 if (special)
830 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
831 " for this symbol type");
832 return;
836 * If `any_segs' is still false, we might need to define a
837 * default segment, if they're trying to declare a label in
838 * `first_seg'.
840 if (!any_segs && segment == first_seg) {
841 int tempint; /* ignored */
842 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
843 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
846 for (seg = seghead; seg && is_global; seg = seg->next)
847 if (seg->index == segment) {
848 struct Public *loc = nasm_malloc(sizeof(*loc));
850 * Case (ii). Maybe MODPUB someday?
852 *seg->pubtail = loc;
853 seg->pubtail = &loc->next;
854 loc->next = NULL;
855 loc->name = nasm_strdup(name);
856 loc->offset = offset;
858 if (special)
859 nasm_error(ERR_NONFATAL,
860 "OBJ supports no special symbol features"
861 " for this symbol type");
862 return;
866 * Case (iii).
868 if (is_global) {
869 ext = *exttail = nasm_malloc(sizeof(*ext));
870 ext->next = NULL;
871 exttail = &ext->next;
872 ext->name = name;
873 /* Place by default all externs into the current segment */
874 ext->defwrt_type = DEFWRT_NONE;
876 /* 28-Apr-2002 - John Coffman
877 The following code was introduced on 12-Aug-2000, and breaks fixups
878 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
879 (5.10). It was introduced after FIXUP32 was added, and may be needed
880 for 32-bit segments. The following will get 16-bit segments working
881 again, and maybe someone can correct the 'if' condition which is
882 actually needed.
884 #if 0
885 if (current_seg) {
886 #else
887 if (current_seg && current_seg->use32) {
888 if (current_seg->grp) {
889 ext->defwrt_type = DEFWRT_GROUP;
890 ext->defwrt_ptr.grp = current_seg->grp;
891 } else {
892 ext->defwrt_type = DEFWRT_SEGMENT;
893 ext->defwrt_ptr.seg = current_seg;
896 #endif
898 if (is_global == 2) {
899 ext->commonsize = offset;
900 ext->commonelem = 1; /* default FAR */
901 } else
902 ext->commonsize = 0;
903 } else
904 return;
907 * Now process the special text, if any, to find default-WRT
908 * specifications and common-variable element-size and near/far
909 * specifications.
911 while (special && *special) {
912 used_special = true;
915 * We might have a default-WRT specification.
917 if (!nasm_strnicmp(special, "wrt", 3)) {
918 char *p;
919 int len;
920 special += 3;
921 special += strspn(special, " \t");
922 p = nasm_strndup(special, len = strcspn(special, ":"));
923 obj_ext_set_defwrt(ext, p);
924 special += len;
925 if (*special && *special != ':')
926 nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
927 " text for `%s'", ext->name);
928 else if (*special == ':')
929 special++;
933 * The NEAR or FAR keywords specify nearness or
934 * farness. FAR gives default element size 1.
936 if (!nasm_strnicmp(special, "far", 3)) {
937 if (ext->commonsize)
938 ext->commonelem = 1;
939 else
940 nasm_error(ERR_NONFATAL,
941 "`%s': `far' keyword may only be applied"
942 " to common variables\n", ext->name);
943 special += 3;
944 special += strspn(special, " \t");
945 } else if (!nasm_strnicmp(special, "near", 4)) {
946 if (ext->commonsize)
947 ext->commonelem = 0;
948 else
949 nasm_error(ERR_NONFATAL,
950 "`%s': `far' keyword may only be applied"
951 " to common variables\n", ext->name);
952 special += 4;
953 special += strspn(special, " \t");
957 * If it's a common, and anything else remains on the line
958 * before a further colon, evaluate it as an expression and
959 * use that as the element size. Forward references aren't
960 * allowed.
962 if (*special == ':')
963 special++;
964 else if (*special) {
965 if (ext->commonsize) {
966 expr *e;
967 struct tokenval tokval;
969 stdscan_reset();
970 stdscan_set(special);
971 tokval.t_type = TOKEN_INVALID;
972 e = evaluate(stdscan, NULL, &tokval, NULL, 1, nasm_error, NULL);
973 if (e) {
974 if (!is_simple(e))
975 nasm_error(ERR_NONFATAL, "cannot use relocatable"
976 " expression as common-variable element size");
977 else
978 ext->commonelem = reloc_value(e);
980 special = stdscan_get();
981 } else {
982 nasm_error(ERR_NONFATAL,
983 "`%s': element-size specifications only"
984 " apply to common variables", ext->name);
985 while (*special && *special != ':')
986 special++;
987 if (*special == ':')
988 special++;
993 i = segment / 2;
994 eb = ebhead;
995 if (!eb) {
996 eb = *ebtail = nasm_zalloc(sizeof(*eb));
997 eb->next = NULL;
998 ebtail = &eb->next;
1000 while (i >= EXT_BLKSIZ) {
1001 if (eb && eb->next)
1002 eb = eb->next;
1003 else {
1004 eb = *ebtail = nasm_zalloc(sizeof(*eb));
1005 eb->next = NULL;
1006 ebtail = &eb->next;
1008 i -= EXT_BLKSIZ;
1010 eb->exts[i] = ext;
1011 ext->index = ++externals;
1013 if (special && !used_special)
1014 nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1015 " for this symbol type");
1018 /* forward declaration */
1019 static void obj_write_fixup(ObjRecord * orp, int bytes,
1020 int segrel, int32_t seg, int32_t wrt,
1021 struct Segment *segto);
1023 static void obj_out(int32_t segto, const void *data,
1024 enum out_type type, uint64_t size,
1025 int32_t segment, int32_t wrt)
1027 const uint8_t *ucdata;
1028 int32_t ldata;
1029 struct Segment *seg;
1030 ObjRecord *orp;
1033 * handle absolute-assembly (structure definitions)
1035 if (segto == NO_SEG) {
1036 if (type != OUT_RESERVE)
1037 nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1038 " space");
1039 return;
1043 * If `any_segs' is still false, we must define a default
1044 * segment.
1046 if (!any_segs) {
1047 int tempint; /* ignored */
1048 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1049 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
1053 * Find the segment we are targetting.
1055 for (seg = seghead; seg; seg = seg->next)
1056 if (seg->index == segto)
1057 break;
1058 if (!seg)
1059 nasm_error(ERR_PANIC, "code directed to nonexistent segment?");
1061 orp = seg->orp;
1062 orp->parm[0] = seg->currentpos;
1064 switch (type) {
1065 case OUT_RAWDATA:
1066 ucdata = data;
1067 while (size > 0) {
1068 unsigned int len;
1069 orp = obj_check(seg->orp, 1);
1070 len = RECORD_MAX - orp->used;
1071 if (len > size)
1072 len = size;
1073 memcpy(orp->buf + orp->used, ucdata, len);
1074 orp->committed = orp->used += len;
1075 orp->parm[0] = seg->currentpos += len;
1076 ucdata += len;
1077 size -= len;
1079 break;
1081 case OUT_ADDRESS:
1082 case OUT_REL1ADR:
1083 case OUT_REL2ADR:
1084 case OUT_REL4ADR:
1085 case OUT_REL8ADR:
1087 int rsize;
1089 if (segment == NO_SEG && type != OUT_ADDRESS)
1090 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1091 " supported by OBJ format");
1092 if (segment >= SEG_ABS)
1093 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1094 " by OBJ format");
1096 ldata = *(int64_t *)data;
1097 if (type != OUT_ADDRESS) {
1098 ldata += size;
1099 size = realsize(type, size);
1100 ldata -= size;
1103 if (size > UINT_MAX)
1104 size = 0;
1106 switch ((unsigned int)size) {
1107 default:
1108 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1109 "32-byte relocations");
1110 segment = NO_SEG; /* Don't actually generate a relocation */
1111 break;
1112 case 2:
1113 orp = obj_word(orp, ldata);
1114 break;
1115 case 4:
1116 orp = obj_dword(orp, ldata);
1117 break;
1120 rsize = size;
1121 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1122 size == 4) {
1124 * This is a 4-byte segment-base relocation such as
1125 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1126 * these, but if the constant term has the 16 low bits
1127 * zero, we can just apply a 2-byte segment-base
1128 * relocation to the low word instead.
1130 rsize = 2;
1131 if (ldata & 0xFFFF)
1132 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1133 " dword-size segment base references");
1135 if (segment != NO_SEG)
1136 obj_write_fixup(orp, rsize,
1137 (type == OUT_ADDRESS ? 0x4000 : 0),
1138 segment, wrt, seg);
1139 seg->currentpos += size;
1140 break;
1143 default:
1144 nasm_error(ERR_NONFATAL,
1145 "Relocation type not supported by output format");
1146 /* fall through */
1148 case OUT_RESERVE:
1149 if (orp->committed)
1150 orp = obj_bump(orp);
1151 seg->currentpos += size;
1152 break;
1154 obj_commit(orp);
1157 static void obj_write_fixup(ObjRecord * orp, int bytes,
1158 int segrel, int32_t seg, int32_t wrt,
1159 struct Segment *segto)
1161 unsigned locat;
1162 int method;
1163 int base;
1164 int32_t tidx, fidx;
1165 struct Segment *s = NULL;
1166 struct Group *g = NULL;
1167 struct External *e = NULL;
1168 ObjRecord *forp;
1170 if (bytes != 2 && bytes != 4) {
1171 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1172 " %d-bit relocations", bytes << 3);
1173 return;
1176 forp = orp->child;
1177 if (forp == NULL) {
1178 orp->child = forp = obj_new();
1179 forp->up = &(orp->child);
1180 /* We should choose between FIXUPP and FIXU32 record type */
1181 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1182 if (segto->use32)
1183 forp->type = FIXU32;
1184 else
1185 forp->type = FIXUPP;
1188 if (seg % 2) {
1189 base = true;
1190 locat = FIX_16_SELECTOR;
1191 seg--;
1192 if (bytes != 2)
1193 nasm_error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1194 " through sanity check");
1195 } else {
1196 base = false;
1197 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1198 if (!segrel)
1200 * There is a bug in tlink that makes it process self relative
1201 * fixups incorrectly if the x_size doesn't match the location
1202 * size.
1204 forp = obj_force(forp, bytes << 3);
1207 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1209 tidx = fidx = -1, method = 0; /* placate optimisers */
1212 * See if we can find the segment ID in our segment list. If
1213 * so, we have a T4 (LSEG) target.
1215 for (s = seghead; s; s = s->next)
1216 if (s->index == seg)
1217 break;
1218 if (s)
1219 method = 4, tidx = s->obj_index;
1220 else {
1221 for (g = grphead; g; g = g->next)
1222 if (g->index == seg)
1223 break;
1224 if (g)
1225 method = 5, tidx = g->obj_index;
1226 else {
1227 int32_t i = seg / 2;
1228 struct ExtBack *eb = ebhead;
1229 while (i >= EXT_BLKSIZ) {
1230 if (eb)
1231 eb = eb->next;
1232 else
1233 break;
1234 i -= EXT_BLKSIZ;
1236 if (eb)
1237 method = 6, e = eb->exts[i], tidx = e->index;
1238 else
1239 nasm_error(ERR_PANIC,
1240 "unrecognised segment value in obj_write_fixup");
1245 * If no WRT given, assume the natural default, which is method
1246 * F5 unless:
1248 * - we are doing an OFFSET fixup for a grouped segment, in
1249 * which case we require F1 (group).
1251 * - we are doing an OFFSET fixup for an external with a
1252 * default WRT, in which case we must honour the default WRT.
1254 if (wrt == NO_SEG) {
1255 if (!base && s && s->grp)
1256 method |= 0x10, fidx = s->grp->obj_index;
1257 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1258 if (e->defwrt_type == DEFWRT_SEGMENT)
1259 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1260 else if (e->defwrt_type == DEFWRT_GROUP)
1261 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1262 else {
1263 nasm_error(ERR_NONFATAL, "default WRT specification for"
1264 " external `%s' unresolved", e->name);
1265 method |= 0x50, fidx = -1; /* got to do _something_ */
1267 } else
1268 method |= 0x50, fidx = -1;
1269 } else {
1271 * See if we can find the WRT-segment ID in our segment
1272 * list. If so, we have a F0 (LSEG) frame.
1274 for (s = seghead; s; s = s->next)
1275 if (s->index == wrt - 1)
1276 break;
1277 if (s)
1278 method |= 0x00, fidx = s->obj_index;
1279 else {
1280 for (g = grphead; g; g = g->next)
1281 if (g->index == wrt - 1)
1282 break;
1283 if (g)
1284 method |= 0x10, fidx = g->obj_index;
1285 else {
1286 int32_t i = wrt / 2;
1287 struct ExtBack *eb = ebhead;
1288 while (i >= EXT_BLKSIZ) {
1289 if (eb)
1290 eb = eb->next;
1291 else
1292 break;
1293 i -= EXT_BLKSIZ;
1295 if (eb)
1296 method |= 0x20, fidx = eb->exts[i]->index;
1297 else
1298 nasm_error(ERR_PANIC,
1299 "unrecognised WRT value in obj_write_fixup");
1304 forp = obj_byte(forp, method);
1305 if (fidx != -1)
1306 forp = obj_index(forp, fidx);
1307 forp = obj_index(forp, tidx);
1308 obj_commit(forp);
1311 static int32_t obj_segment(char *name, int pass, int *bits)
1314 * We call the label manager here to define a name for the new
1315 * segment, and when our _own_ label-definition stub gets
1316 * called in return, it should register the new segment name
1317 * using the pointer it gets passed. That way we save memory,
1318 * by sponging off the label manager.
1320 #if defined(DEBUG) && DEBUG>=3
1321 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1322 name, pass, *bits);
1323 #endif
1324 if (!name) {
1325 *bits = 16;
1326 current_seg = NULL;
1327 return first_seg;
1328 } else {
1329 struct Segment *seg;
1330 struct Group *grp;
1331 struct External **extp;
1332 int obj_idx, i, attrs;
1333 bool rn_error;
1334 char *p;
1337 * Look for segment attributes.
1339 attrs = 0;
1340 while (*name == '.')
1341 name++; /* hack, but a documented one */
1342 p = name;
1343 while (*p && !nasm_isspace(*p))
1344 p++;
1345 if (*p) {
1346 *p++ = '\0';
1347 while (*p && nasm_isspace(*p))
1348 *p++ = '\0';
1350 while (*p) {
1351 while (*p && !nasm_isspace(*p))
1352 p++;
1353 if (*p) {
1354 *p++ = '\0';
1355 while (*p && nasm_isspace(*p))
1356 *p++ = '\0';
1359 attrs++;
1362 obj_idx = 1;
1363 for (seg = seghead; seg; seg = seg->next) {
1364 obj_idx++;
1365 if (!strcmp(seg->name, name)) {
1366 if (attrs > 0 && pass == 1)
1367 nasm_error(ERR_WARNING, "segment attributes specified on"
1368 " redeclaration of segment: ignoring");
1369 if (seg->use32)
1370 *bits = 32;
1371 else
1372 *bits = 16;
1373 current_seg = seg;
1374 return seg->index;
1378 *segtail = seg = nasm_malloc(sizeof(*seg));
1379 seg->next = NULL;
1380 segtail = &seg->next;
1381 seg->index = (any_segs ? seg_alloc() : first_seg);
1382 seg->obj_index = obj_idx;
1383 seg->grp = NULL;
1384 any_segs = true;
1385 seg->name = NULL;
1386 seg->currentpos = 0;
1387 seg->align = 1; /* default */
1388 seg->use32 = false; /* default */
1389 seg->combine = CMB_PUBLIC; /* default */
1390 seg->segclass = seg->overlay = NULL;
1391 seg->pubhead = NULL;
1392 seg->pubtail = &seg->pubhead;
1393 seg->lochead = NULL;
1394 seg->loctail = &seg->lochead;
1395 seg->orp = obj_new();
1396 seg->orp->up = &(seg->orp);
1397 seg->orp->ori = ori_ledata;
1398 seg->orp->type = LEDATA;
1399 seg->orp->parm[1] = obj_idx;
1402 * Process the segment attributes.
1404 p = name;
1405 while (attrs--) {
1406 p += strlen(p);
1407 while (!*p)
1408 p++;
1411 * `p' contains a segment attribute.
1413 if (!nasm_stricmp(p, "private"))
1414 seg->combine = CMB_PRIVATE;
1415 else if (!nasm_stricmp(p, "public"))
1416 seg->combine = CMB_PUBLIC;
1417 else if (!nasm_stricmp(p, "common"))
1418 seg->combine = CMB_COMMON;
1419 else if (!nasm_stricmp(p, "stack"))
1420 seg->combine = CMB_STACK;
1421 else if (!nasm_stricmp(p, "use16"))
1422 seg->use32 = false;
1423 else if (!nasm_stricmp(p, "use32"))
1424 seg->use32 = true;
1425 else if (!nasm_stricmp(p, "flat")) {
1427 * This segment is an OS/2 FLAT segment. That means
1428 * that its default group is group FLAT, even if
1429 * the group FLAT does not explicitly _contain_ the
1430 * segment.
1432 * When we see this, we must create the group
1433 * `FLAT', containing no segments, if it does not
1434 * already exist; then we must set the default
1435 * group of this segment to be the FLAT group.
1437 struct Group *grp;
1438 for (grp = grphead; grp; grp = grp->next)
1439 if (!strcmp(grp->name, "FLAT"))
1440 break;
1441 if (!grp) {
1442 obj_directive(D_GROUP, "FLAT", 1);
1443 for (grp = grphead; grp; grp = grp->next)
1444 if (!strcmp(grp->name, "FLAT"))
1445 break;
1446 if (!grp)
1447 nasm_error(ERR_PANIC, "failure to define FLAT?!");
1449 seg->grp = grp;
1450 } else if (!nasm_strnicmp(p, "class=", 6))
1451 seg->segclass = nasm_strdup(p + 6);
1452 else if (!nasm_strnicmp(p, "overlay=", 8))
1453 seg->overlay = nasm_strdup(p + 8);
1454 else if (!nasm_strnicmp(p, "align=", 6)) {
1455 seg->align = readnum(p + 6, &rn_error);
1456 if (rn_error) {
1457 seg->align = 1;
1458 nasm_error(ERR_NONFATAL, "segment alignment should be"
1459 " numeric");
1461 switch ((int)seg->align) {
1462 case 1: /* BYTE */
1463 case 2: /* WORD */
1464 case 4: /* DWORD */
1465 case 16: /* PARA */
1466 case 256: /* PAGE */
1467 case 4096: /* PharLap extension */
1468 break;
1469 case 8:
1470 nasm_error(ERR_WARNING,
1471 "OBJ format does not support alignment"
1472 " of 8: rounding up to 16");
1473 seg->align = 16;
1474 break;
1475 case 32:
1476 case 64:
1477 case 128:
1478 nasm_error(ERR_WARNING,
1479 "OBJ format does not support alignment"
1480 " of %d: rounding up to 256", seg->align);
1481 seg->align = 256;
1482 break;
1483 case 512:
1484 case 1024:
1485 case 2048:
1486 nasm_error(ERR_WARNING,
1487 "OBJ format does not support alignment"
1488 " of %d: rounding up to 4096", seg->align);
1489 seg->align = 4096;
1490 break;
1491 default:
1492 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1493 seg->align);
1494 seg->align = 1;
1495 break;
1497 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1498 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1499 if (rn_error)
1500 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1501 " attribute should be numeric");
1505 /* We need to know whenever we have at least one 32-bit segment */
1506 obj_use32 |= seg->use32;
1508 obj_seg_needs_update = seg;
1509 if (seg->align >= SEG_ABS)
1510 define_label(name, NO_SEG, seg->align - SEG_ABS,
1511 NULL, false, false);
1512 else
1513 define_label(name, seg->index + 1, 0L,
1514 NULL, false, false);
1515 obj_seg_needs_update = NULL;
1518 * See if this segment is defined in any groups.
1520 for (grp = grphead; grp; grp = grp->next) {
1521 for (i = grp->nindices; i < grp->nentries; i++) {
1522 if (!strcmp(grp->segs[i].name, seg->name)) {
1523 nasm_free(grp->segs[i].name);
1524 grp->segs[i] = grp->segs[grp->nindices];
1525 grp->segs[grp->nindices++].index = seg->obj_index;
1526 if (seg->grp)
1527 nasm_error(ERR_WARNING,
1528 "segment `%s' is already part of"
1529 " a group: first one takes precedence",
1530 seg->name);
1531 else
1532 seg->grp = grp;
1538 * Walk through the list of externals with unresolved
1539 * default-WRT clauses, and resolve any that point at this
1540 * segment.
1542 extp = &dws;
1543 while (*extp) {
1544 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1545 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1546 nasm_free((*extp)->defwrt_ptr.string);
1547 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1548 (*extp)->defwrt_ptr.seg = seg;
1549 *extp = (*extp)->next_dws;
1550 } else
1551 extp = &(*extp)->next_dws;
1554 if (seg->use32)
1555 *bits = 32;
1556 else
1557 *bits = 16;
1558 current_seg = seg;
1559 return seg->index;
1563 static int obj_directive(enum directives directive, char *value, int pass)
1565 switch (directive) {
1566 case D_GROUP:
1568 char *p, *q, *v;
1569 if (pass == 1) {
1570 struct Group *grp;
1571 struct Segment *seg;
1572 struct External **extp;
1573 int obj_idx;
1575 q = value;
1576 while (*q == '.')
1577 q++; /* hack, but a documented one */
1578 v = q;
1579 while (*q && !nasm_isspace(*q))
1580 q++;
1581 if (nasm_isspace(*q)) {
1582 *q++ = '\0';
1583 while (*q && nasm_isspace(*q))
1584 q++;
1587 * Here we used to sanity-check the group directive to
1588 * ensure nobody tried to declare a group containing no
1589 * segments. However, OS/2 does this as standard
1590 * practice, so the sanity check has been removed.
1592 * if (!*q) {
1593 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1594 * return 1;
1598 obj_idx = 1;
1599 for (grp = grphead; grp; grp = grp->next) {
1600 obj_idx++;
1601 if (!strcmp(grp->name, v)) {
1602 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1603 return 1;
1607 *grptail = grp = nasm_malloc(sizeof(*grp));
1608 grp->next = NULL;
1609 grptail = &grp->next;
1610 grp->index = seg_alloc();
1611 grp->obj_index = obj_idx;
1612 grp->nindices = grp->nentries = 0;
1613 grp->name = NULL;
1615 obj_grp_needs_update = grp;
1616 define_label(v, grp->index + 1, 0L, NULL, false, false);
1617 obj_grp_needs_update = NULL;
1619 while (*q) {
1620 p = q;
1621 while (*q && !nasm_isspace(*q))
1622 q++;
1623 if (nasm_isspace(*q)) {
1624 *q++ = '\0';
1625 while (*q && nasm_isspace(*q))
1626 q++;
1629 * Now p contains a segment name. Find it.
1631 for (seg = seghead; seg; seg = seg->next)
1632 if (!strcmp(seg->name, p))
1633 break;
1634 if (seg) {
1636 * We have a segment index. Shift a name entry
1637 * to the end of the array to make room.
1639 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1640 grp->segs[grp->nindices++].index = seg->obj_index;
1641 if (seg->grp)
1642 nasm_error(ERR_WARNING,
1643 "segment `%s' is already part of"
1644 " a group: first one takes precedence",
1645 seg->name);
1646 else
1647 seg->grp = grp;
1648 } else {
1650 * We have an as-yet undefined segment.
1651 * Remember its name, for later.
1653 grp->segs[grp->nentries++].name = nasm_strdup(p);
1658 * Walk through the list of externals with unresolved
1659 * default-WRT clauses, and resolve any that point at
1660 * this group.
1662 extp = &dws;
1663 while (*extp) {
1664 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1665 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1666 nasm_free((*extp)->defwrt_ptr.string);
1667 (*extp)->defwrt_type = DEFWRT_GROUP;
1668 (*extp)->defwrt_ptr.grp = grp;
1669 *extp = (*extp)->next_dws;
1670 } else
1671 extp = &(*extp)->next_dws;
1674 return 1;
1676 case D_UPPERCASE:
1677 obj_uppercase = true;
1678 return 1;
1680 case D_IMPORT:
1682 char *q, *extname, *libname, *impname;
1684 if (pass == 2)
1685 return 1; /* ignore in pass two */
1686 extname = q = value;
1687 while (*q && !nasm_isspace(*q))
1688 q++;
1689 if (nasm_isspace(*q)) {
1690 *q++ = '\0';
1691 while (*q && nasm_isspace(*q))
1692 q++;
1695 libname = q;
1696 while (*q && !nasm_isspace(*q))
1697 q++;
1698 if (nasm_isspace(*q)) {
1699 *q++ = '\0';
1700 while (*q && nasm_isspace(*q))
1701 q++;
1704 impname = q;
1706 if (!*extname || !*libname)
1707 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1708 " and library name");
1709 else {
1710 struct ImpDef *imp;
1711 bool err = false;
1713 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1714 imptail = &imp->next;
1715 imp->next = NULL;
1716 imp->extname = nasm_strdup(extname);
1717 imp->libname = nasm_strdup(libname);
1718 imp->impindex = readnum(impname, &err);
1719 if (!*impname || err)
1720 imp->impname = nasm_strdup(impname);
1721 else
1722 imp->impname = NULL;
1725 return 1;
1727 case D_EXPORT:
1729 char *q, *extname, *intname, *v;
1730 struct ExpDef *export;
1731 int flags = 0;
1732 unsigned int ordinal = 0;
1734 if (pass == 2)
1735 return 1; /* ignore in pass two */
1736 intname = q = value;
1737 while (*q && !nasm_isspace(*q))
1738 q++;
1739 if (nasm_isspace(*q)) {
1740 *q++ = '\0';
1741 while (*q && nasm_isspace(*q))
1742 q++;
1745 extname = q;
1746 while (*q && !nasm_isspace(*q))
1747 q++;
1748 if (nasm_isspace(*q)) {
1749 *q++ = '\0';
1750 while (*q && nasm_isspace(*q))
1751 q++;
1754 if (!*intname) {
1755 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1756 return 1;
1758 if (!*extname) {
1759 extname = intname;
1760 intname = "";
1762 while (*q) {
1763 v = q;
1764 while (*q && !nasm_isspace(*q))
1765 q++;
1766 if (nasm_isspace(*q)) {
1767 *q++ = '\0';
1768 while (*q && nasm_isspace(*q))
1769 q++;
1771 if (!nasm_stricmp(v, "resident"))
1772 flags |= EXPDEF_FLAG_RESIDENT;
1773 else if (!nasm_stricmp(v, "nodata"))
1774 flags |= EXPDEF_FLAG_NODATA;
1775 else if (!nasm_strnicmp(v, "parm=", 5)) {
1776 bool err = false;
1777 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1778 if (err) {
1779 nasm_error(ERR_NONFATAL,
1780 "value `%s' for `parm' is non-numeric", v + 5);
1781 return 1;
1783 } else {
1784 bool err = false;
1785 ordinal = readnum(v, &err);
1786 if (err) {
1787 nasm_error(ERR_NONFATAL,
1788 "unrecognised export qualifier `%s'", v);
1789 return 1;
1791 flags |= EXPDEF_FLAG_ORDINAL;
1795 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1796 exptail = &export->next;
1797 export->next = NULL;
1798 export->extname = nasm_strdup(extname);
1799 export->intname = nasm_strdup(intname);
1800 export->ordinal = ordinal;
1801 export->flags = flags;
1803 return 1;
1805 default:
1806 return 0;
1810 static void obj_sectalign(int32_t seg, unsigned int value)
1812 struct Segment *s;
1814 list_for_each(s, seghead) {
1815 if (s->index == seg)
1816 break;
1820 * it should not be too big value
1821 * and applied on non-absolute sections
1823 if (!s || !is_power2(value) ||
1824 value > 4096 || s->align >= SEG_ABS)
1825 return;
1828 * FIXME: No code duplication please
1829 * consider making helper for this
1830 * mapping since section handler has
1831 * to do the same
1833 switch (value) {
1834 case 8:
1835 value = 16;
1836 break;
1837 case 32:
1838 case 64:
1839 case 128:
1840 value = 256;
1841 break;
1842 case 512:
1843 case 1024:
1844 case 2048:
1845 value = 4096;
1846 break;
1849 if (s->align < (int)value)
1850 s->align = value;
1853 static int32_t obj_segbase(int32_t segment)
1855 struct Segment *seg;
1858 * Find the segment in our list.
1860 for (seg = seghead; seg; seg = seg->next)
1861 if (seg->index == segment - 1)
1862 break;
1864 if (!seg) {
1866 * Might be an external with a default WRT.
1868 int32_t i = segment / 2;
1869 struct ExtBack *eb = ebhead;
1870 struct External *e;
1872 while (i >= EXT_BLKSIZ) {
1873 if (eb)
1874 eb = eb->next;
1875 else
1876 break;
1877 i -= EXT_BLKSIZ;
1879 if (eb) {
1880 e = eb->exts[i];
1881 if (!e) {
1882 nasm_assert(pass0 == 0);
1883 /* Not available - can happen during optimization */
1884 return NO_SEG;
1887 switch (e->defwrt_type) {
1888 case DEFWRT_NONE:
1889 return segment; /* fine */
1890 case DEFWRT_SEGMENT:
1891 return e->defwrt_ptr.seg->index + 1;
1892 case DEFWRT_GROUP:
1893 return e->defwrt_ptr.grp->index + 1;
1894 default:
1895 return NO_SEG; /* can't tell what it is */
1899 return segment; /* not one of ours - leave it alone */
1902 if (seg->align >= SEG_ABS)
1903 return seg->align; /* absolute segment */
1904 if (seg->grp)
1905 return seg->grp->index + 1; /* grouped segment */
1907 return segment; /* no special treatment */
1910 static void obj_filename(char *inname, char *outname)
1912 strcpy(obj_infile, inname);
1913 standard_extension(inname, outname, ".obj");
1916 static void obj_write_file(int debuginfo)
1918 struct Segment *seg, *entry_seg_ptr = 0;
1919 struct FileName *fn;
1920 struct LineNumber *ln;
1921 struct Group *grp;
1922 struct Public *pub, *loc;
1923 struct External *ext;
1924 struct ImpDef *imp;
1925 struct ExpDef *export;
1926 int lname_idx;
1927 ObjRecord *orp;
1930 * Write the THEADR module header.
1932 orp = obj_new();
1933 orp->type = THEADR;
1934 obj_name(orp, obj_infile);
1935 obj_emit2(orp);
1938 * Write the NASM boast comment.
1940 orp->type = COMENT;
1941 obj_rword(orp, 0); /* comment type zero */
1942 obj_name(orp, nasm_comment);
1943 obj_emit2(orp);
1945 orp->type = COMENT;
1947 * Write the IMPDEF records, if any.
1949 for (imp = imphead; imp; imp = imp->next) {
1950 obj_rword(orp, 0xA0); /* comment class A0 */
1951 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1952 if (imp->impname)
1953 obj_byte(orp, 0); /* import by name */
1954 else
1955 obj_byte(orp, 1); /* import by ordinal */
1956 obj_name(orp, imp->extname);
1957 obj_name(orp, imp->libname);
1958 if (imp->impname)
1959 obj_name(orp, imp->impname);
1960 else
1961 obj_word(orp, imp->impindex);
1962 obj_emit2(orp);
1966 * Write the EXPDEF records, if any.
1968 for (export = exphead; export; export = export->next) {
1969 obj_rword(orp, 0xA0); /* comment class A0 */
1970 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1971 obj_byte(orp, export->flags);
1972 obj_name(orp, export->extname);
1973 obj_name(orp, export->intname);
1974 if (export->flags & EXPDEF_FLAG_ORDINAL)
1975 obj_word(orp, export->ordinal);
1976 obj_emit2(orp);
1979 /* we're using extended OMF if we put in debug info */
1980 if (debuginfo) {
1981 orp->type = COMENT;
1982 obj_byte(orp, 0x40);
1983 obj_byte(orp, dEXTENDED);
1984 obj_emit2(orp);
1988 * Write the first LNAMES record, containing LNAME one, which
1989 * is null. Also initialize the LNAME counter.
1991 orp->type = LNAMES;
1992 obj_byte(orp, 0);
1993 lname_idx = 1;
1995 * Write some LNAMES for the segment names
1997 for (seg = seghead; seg; seg = seg->next) {
1998 orp = obj_name(orp, seg->name);
1999 if (seg->segclass)
2000 orp = obj_name(orp, seg->segclass);
2001 if (seg->overlay)
2002 orp = obj_name(orp, seg->overlay);
2003 obj_commit(orp);
2006 * Write some LNAMES for the group names
2008 for (grp = grphead; grp; grp = grp->next) {
2009 orp = obj_name(orp, grp->name);
2010 obj_commit(orp);
2012 obj_emit(orp);
2015 * Write the SEGDEF records.
2017 orp->type = SEGDEF;
2018 for (seg = seghead; seg; seg = seg->next) {
2019 int acbp;
2020 uint32_t seglen = seg->currentpos;
2022 acbp = (seg->combine << 2); /* C field */
2024 if (seg->use32)
2025 acbp |= 0x01; /* P bit is Use32 flag */
2026 else if (seglen == 0x10000L) {
2027 seglen = 0; /* This special case may be needed for old linkers */
2028 acbp |= 0x02; /* B bit */
2031 /* A field */
2032 if (seg->align >= SEG_ABS)
2033 /* acbp |= 0x00 */ ;
2034 else if (seg->align >= 4096) {
2035 if (seg->align > 4096)
2036 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2037 " than OBJ format supports", seg->name);
2038 acbp |= 0xC0; /* PharLap extension */
2039 } else if (seg->align >= 256) {
2040 acbp |= 0x80;
2041 } else if (seg->align >= 16) {
2042 acbp |= 0x60;
2043 } else if (seg->align >= 4) {
2044 acbp |= 0xA0;
2045 } else if (seg->align >= 2) {
2046 acbp |= 0x40;
2047 } else
2048 acbp |= 0x20;
2050 obj_byte(orp, acbp);
2051 if (seg->align & SEG_ABS) {
2052 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2053 obj_byte(orp, 0); /* Offset */
2055 obj_x(orp, seglen);
2056 obj_index(orp, ++lname_idx);
2057 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2058 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2059 obj_emit2(orp);
2063 * Write the GRPDEF records.
2065 orp->type = GRPDEF;
2066 for (grp = grphead; grp; grp = grp->next) {
2067 int i;
2069 if (grp->nindices != grp->nentries) {
2070 for (i = grp->nindices; i < grp->nentries; i++) {
2071 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2072 " `%s'", grp->name, grp->segs[i].name);
2073 nasm_free(grp->segs[i].name);
2074 grp->segs[i].name = NULL;
2077 obj_index(orp, ++lname_idx);
2078 for (i = 0; i < grp->nindices; i++) {
2079 obj_byte(orp, 0xFF);
2080 obj_index(orp, grp->segs[i].index);
2082 obj_emit2(orp);
2086 * Write the PUBDEF records: first the ones in the segments,
2087 * then the far-absolutes.
2089 orp->type = PUBDEF;
2090 orp->ori = ori_pubdef;
2091 for (seg = seghead; seg; seg = seg->next) {
2092 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2093 orp->parm[1] = seg->obj_index;
2094 for (pub = seg->pubhead; pub; pub = pub->next) {
2095 orp = obj_name(orp, pub->name);
2096 orp = obj_x(orp, pub->offset);
2097 orp = obj_byte(orp, 0); /* type index */
2098 obj_commit(orp);
2100 obj_emit(orp);
2102 orp->parm[0] = 0;
2103 orp->parm[1] = 0;
2104 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2105 if (orp->parm[2] != (uint32_t)pub->segment) {
2106 obj_emit(orp);
2107 orp->parm[2] = pub->segment;
2109 orp = obj_name(orp, pub->name);
2110 orp = obj_x(orp, pub->offset);
2111 orp = obj_byte(orp, 0); /* type index */
2112 obj_commit(orp);
2114 obj_emit(orp);
2117 * Write the EXTDEF and COMDEF records, in order.
2119 orp->ori = ori_null;
2120 for (ext = exthead; ext; ext = ext->next) {
2121 if (ext->commonsize == 0) {
2122 if (orp->type != EXTDEF) {
2123 obj_emit(orp);
2124 orp->type = EXTDEF;
2126 orp = obj_name(orp, ext->name);
2127 orp = obj_index(orp, 0);
2128 } else {
2129 if (orp->type != COMDEF) {
2130 obj_emit(orp);
2131 orp->type = COMDEF;
2133 orp = obj_name(orp, ext->name);
2134 orp = obj_index(orp, 0);
2135 if (ext->commonelem) {
2136 orp = obj_byte(orp, 0x61); /* far communal */
2137 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2138 orp = obj_value(orp, ext->commonelem);
2139 } else {
2140 orp = obj_byte(orp, 0x62); /* near communal */
2141 orp = obj_value(orp, ext->commonsize);
2144 obj_commit(orp);
2146 obj_emit(orp);
2149 * Write a COMENT record stating that the linker's first pass
2150 * may stop processing at this point. Exception is if our
2151 * MODEND record specifies a start point, in which case,
2152 * according to some variants of the documentation, this COMENT
2153 * should be omitted. So we'll omit it just in case.
2154 * But, TASM puts it in all the time so if we are using
2155 * TASM debug stuff we are putting it in
2157 if (debuginfo || obj_entry_seg == NO_SEG) {
2158 orp->type = COMENT;
2159 obj_byte(orp, 0x40);
2160 obj_byte(orp, dLINKPASS);
2161 obj_byte(orp, 1);
2162 obj_emit2(orp);
2166 * 1) put out the compiler type
2167 * 2) Put out the type info. The only type we are using is near label #19
2169 if (debuginfo) {
2170 int i;
2171 struct Array *arrtmp = arrhead;
2172 orp->type = COMENT;
2173 obj_byte(orp, 0x40);
2174 obj_byte(orp, dCOMPDEF);
2175 obj_byte(orp, 4);
2176 obj_byte(orp, 0);
2177 obj_emit2(orp);
2179 obj_byte(orp, 0x40);
2180 obj_byte(orp, dTYPEDEF);
2181 obj_word(orp, 0x18); /* type # for linking */
2182 obj_word(orp, 6); /* size of type */
2183 obj_byte(orp, 0x2a); /* absolute type for debugging */
2184 obj_emit2(orp);
2185 obj_byte(orp, 0x40);
2186 obj_byte(orp, dTYPEDEF);
2187 obj_word(orp, 0x19); /* type # for linking */
2188 obj_word(orp, 0); /* size of type */
2189 obj_byte(orp, 0x24); /* absolute type for debugging */
2190 obj_byte(orp, 0); /* near/far specifier */
2191 obj_emit2(orp);
2192 obj_byte(orp, 0x40);
2193 obj_byte(orp, dTYPEDEF);
2194 obj_word(orp, 0x1A); /* type # for linking */
2195 obj_word(orp, 0); /* size of type */
2196 obj_byte(orp, 0x24); /* absolute type for debugging */
2197 obj_byte(orp, 1); /* near/far specifier */
2198 obj_emit2(orp);
2199 obj_byte(orp, 0x40);
2200 obj_byte(orp, dTYPEDEF);
2201 obj_word(orp, 0x1b); /* type # for linking */
2202 obj_word(orp, 0); /* size of type */
2203 obj_byte(orp, 0x23); /* absolute type for debugging */
2204 obj_byte(orp, 0);
2205 obj_byte(orp, 0);
2206 obj_byte(orp, 0);
2207 obj_emit2(orp);
2208 obj_byte(orp, 0x40);
2209 obj_byte(orp, dTYPEDEF);
2210 obj_word(orp, 0x1c); /* type # for linking */
2211 obj_word(orp, 0); /* size of type */
2212 obj_byte(orp, 0x23); /* absolute type for debugging */
2213 obj_byte(orp, 0);
2214 obj_byte(orp, 4);
2215 obj_byte(orp, 0);
2216 obj_emit2(orp);
2217 obj_byte(orp, 0x40);
2218 obj_byte(orp, dTYPEDEF);
2219 obj_word(orp, 0x1d); /* type # for linking */
2220 obj_word(orp, 0); /* size of type */
2221 obj_byte(orp, 0x23); /* absolute type for debugging */
2222 obj_byte(orp, 0);
2223 obj_byte(orp, 1);
2224 obj_byte(orp, 0);
2225 obj_emit2(orp);
2226 obj_byte(orp, 0x40);
2227 obj_byte(orp, dTYPEDEF);
2228 obj_word(orp, 0x1e); /* type # for linking */
2229 obj_word(orp, 0); /* size of type */
2230 obj_byte(orp, 0x23); /* absolute type for debugging */
2231 obj_byte(orp, 0);
2232 obj_byte(orp, 5);
2233 obj_byte(orp, 0);
2234 obj_emit2(orp);
2236 /* put out the array types */
2237 for (i = ARRAYBOT; i < arrindex; i++) {
2238 obj_byte(orp, 0x40);
2239 obj_byte(orp, dTYPEDEF);
2240 obj_word(orp, i); /* type # for linking */
2241 obj_word(orp, arrtmp->size); /* size of type */
2242 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2243 obj_byte(orp, arrtmp->basetype); /* base type */
2244 obj_emit2(orp);
2245 arrtmp = arrtmp->next;
2249 * write out line number info with a LINNUM record
2250 * switch records when we switch segments, and output the
2251 * file in a pseudo-TASM fashion. The record switch is naive; that
2252 * is that one file may have many records for the same segment
2253 * if there are lots of segment switches
2255 if (fnhead && debuginfo) {
2256 seg = fnhead->lnhead->segment;
2258 for (fn = fnhead; fn; fn = fn->next) {
2259 /* write out current file name */
2260 orp->type = COMENT;
2261 orp->ori = ori_null;
2262 obj_byte(orp, 0x40);
2263 obj_byte(orp, dFILNAME);
2264 obj_byte(orp, 0);
2265 obj_name(orp, fn->name);
2266 obj_dword(orp, 0);
2267 obj_emit2(orp);
2269 /* write out line numbers this file */
2271 orp->type = LINNUM;
2272 orp->ori = ori_linnum;
2273 for (ln = fn->lnhead; ln; ln = ln->next) {
2274 if (seg != ln->segment) {
2275 /* if we get here have to flush the buffer and start
2276 * a new record for a new segment
2278 seg = ln->segment;
2279 obj_emit(orp);
2281 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2282 orp->parm[1] = seg->obj_index;
2283 orp = obj_word(orp, ln->lineno);
2284 orp = obj_x(orp, ln->offset);
2285 obj_commit(orp);
2287 obj_emit(orp);
2291 * we are going to locate the entry point segment now
2292 * rather than wait until the MODEND record, because,
2293 * then we can output a special symbol to tell where the
2294 * entry point is.
2297 if (obj_entry_seg != NO_SEG) {
2298 for (seg = seghead; seg; seg = seg->next) {
2299 if (seg->index == obj_entry_seg) {
2300 entry_seg_ptr = seg;
2301 break;
2304 if (!seg)
2305 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2309 * get ready to put out symbol records
2311 orp->type = COMENT;
2312 orp->ori = ori_local;
2315 * put out a symbol for the entry point
2316 * no dots in this symbol, because, borland does
2317 * not (officially) support dots in label names
2318 * and I don't know what various versions of TLINK will do
2320 if (debuginfo && obj_entry_seg != NO_SEG) {
2321 orp = obj_name(orp, "start_of_program");
2322 orp = obj_word(orp, 0x19); /* type: near label */
2323 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2324 orp = obj_index(orp, seg->obj_index);
2325 orp = obj_x(orp, obj_entry_ofs);
2326 obj_commit(orp);
2330 * put out the local labels
2332 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2333 /* labels this seg */
2334 for (loc = seg->lochead; loc; loc = loc->next) {
2335 orp = obj_name(orp, loc->name);
2336 orp = obj_word(orp, loc->type);
2337 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2338 orp = obj_index(orp, seg->obj_index);
2339 orp = obj_x(orp, loc->offset);
2340 obj_commit(orp);
2343 if (orp->used)
2344 obj_emit(orp);
2347 * Write the LEDATA/FIXUPP pairs.
2349 for (seg = seghead; seg; seg = seg->next) {
2350 obj_emit(seg->orp);
2351 nasm_free(seg->orp);
2355 * Write the MODEND module end marker.
2357 orp->type = obj_use32 ? MODE32 : MODEND;
2358 orp->ori = ori_null;
2359 if (entry_seg_ptr) {
2360 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2361 obj_byte(orp, 0xC1);
2362 seg = entry_seg_ptr;
2363 if (seg->grp) {
2364 obj_byte(orp, 0x10);
2365 obj_index(orp, seg->grp->obj_index);
2366 } else {
2368 * the below changed to prevent TLINK crashing.
2369 * Previous more efficient version read:
2371 * obj_byte (orp, 0x50);
2373 obj_byte(orp, 0x00);
2374 obj_index(orp, seg->obj_index);
2376 obj_index(orp, seg->obj_index);
2377 obj_x(orp, obj_entry_ofs);
2378 } else
2379 obj_byte(orp, 0);
2380 obj_emit2(orp);
2381 nasm_free(orp);
2384 static void obj_fwrite(ObjRecord * orp)
2386 unsigned int cksum, len;
2387 uint8_t *ptr;
2389 cksum = orp->type;
2390 if (orp->x_size == 32)
2391 cksum |= 1;
2392 fputc(cksum, ofile);
2393 len = orp->committed + 1;
2394 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2395 fwriteint16_t(len, ofile);
2396 fwrite(orp->buf, 1, len - 1, ofile);
2397 for (ptr = orp->buf; --len; ptr++)
2398 cksum += *ptr;
2399 fputc((-cksum) & 0xFF, ofile);
2402 extern macros_t obj_stdmac[];
2404 void dbgbi_init(void)
2406 fnhead = NULL;
2407 fntail = &fnhead;
2408 arrindex = ARRAYBOT;
2409 arrhead = NULL;
2410 arrtail = &arrhead;
2412 static void dbgbi_cleanup(void)
2414 struct Segment *segtmp;
2415 while (fnhead) {
2416 struct FileName *fntemp = fnhead;
2417 while (fnhead->lnhead) {
2418 struct LineNumber *lntemp = fnhead->lnhead;
2419 fnhead->lnhead = lntemp->next;
2420 nasm_free(lntemp);
2422 fnhead = fnhead->next;
2423 nasm_free(fntemp->name);
2424 nasm_free(fntemp);
2426 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2427 while (segtmp->lochead) {
2428 struct Public *loctmp = segtmp->lochead;
2429 segtmp->lochead = loctmp->next;
2430 nasm_free(loctmp->name);
2431 nasm_free(loctmp);
2434 while (arrhead) {
2435 struct Array *arrtmp = arrhead;
2436 arrhead = arrhead->next;
2437 nasm_free(arrtmp);
2441 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2443 struct FileName *fn;
2444 struct LineNumber *ln;
2445 struct Segment *seg;
2447 if (segto == NO_SEG)
2448 return;
2451 * If `any_segs' is still false, we must define a default
2452 * segment.
2454 if (!any_segs) {
2455 int tempint; /* ignored */
2456 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2457 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
2461 * Find the segment we are targetting.
2463 for (seg = seghead; seg; seg = seg->next)
2464 if (seg->index == segto)
2465 break;
2466 if (!seg)
2467 nasm_error(ERR_PANIC, "lineno directed to nonexistent segment?");
2469 /* for (fn = fnhead; fn; fn = fnhead->next) */
2470 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2471 if (!nasm_stricmp(lnfname, fn->name))
2472 break;
2473 if (!fn) {
2474 fn = nasm_malloc(sizeof(*fn));
2475 fn->name = nasm_malloc(strlen(lnfname) + 1);
2476 strcpy(fn->name, lnfname);
2477 fn->lnhead = NULL;
2478 fn->lntail = &fn->lnhead;
2479 fn->next = NULL;
2480 *fntail = fn;
2481 fntail = &fn->next;
2483 ln = nasm_malloc(sizeof(*ln));
2484 ln->segment = seg;
2485 ln->offset = seg->currentpos;
2486 ln->lineno = lineno;
2487 ln->next = NULL;
2488 *fn->lntail = ln;
2489 fn->lntail = &ln->next;
2492 static void dbgbi_deflabel(char *name, int32_t segment,
2493 int64_t offset, int is_global, char *special)
2495 struct Segment *seg;
2497 (void)special;
2500 * If it's a special-retry from pass two, discard it.
2502 if (is_global == 3)
2503 return;
2506 * First check for the double-period, signifying something
2507 * unusual.
2509 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2510 return;
2514 * Case (i):
2516 if (obj_seg_needs_update) {
2517 return;
2518 } else if (obj_grp_needs_update) {
2519 return;
2521 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2522 return;
2524 if (segment >= SEG_ABS || segment == NO_SEG) {
2525 return;
2529 * If `any_segs' is still false, we might need to define a
2530 * default segment, if they're trying to declare a label in
2531 * `first_seg'. But the label should exist due to a prior
2532 * call to obj_deflabel so we can skip that.
2535 for (seg = seghead; seg; seg = seg->next)
2536 if (seg->index == segment) {
2537 struct Public *loc = nasm_malloc(sizeof(*loc));
2539 * Case (ii). Maybe MODPUB someday?
2541 last_defined = *seg->loctail = loc;
2542 seg->loctail = &loc->next;
2543 loc->next = NULL;
2544 loc->name = nasm_strdup(name);
2545 loc->offset = offset;
2548 static void dbgbi_typevalue(int32_t type)
2550 int vsize;
2551 int elem = TYM_ELEMENTS(type);
2552 type = TYM_TYPE(type);
2554 if (!last_defined)
2555 return;
2557 switch (type) {
2558 case TY_BYTE:
2559 last_defined->type = 8; /* uint8_t */
2560 vsize = 1;
2561 break;
2562 case TY_WORD:
2563 last_defined->type = 10; /* unsigned word */
2564 vsize = 2;
2565 break;
2566 case TY_DWORD:
2567 last_defined->type = 12; /* unsigned dword */
2568 vsize = 4;
2569 break;
2570 case TY_FLOAT:
2571 last_defined->type = 14; /* float */
2572 vsize = 4;
2573 break;
2574 case TY_QWORD:
2575 last_defined->type = 15; /* qword */
2576 vsize = 8;
2577 break;
2578 case TY_TBYTE:
2579 last_defined->type = 16; /* TBYTE */
2580 vsize = 10;
2581 break;
2582 default:
2583 last_defined->type = 0x19; /*label */
2584 vsize = 0;
2585 break;
2588 if (elem > 1) {
2589 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2590 int vtype = last_defined->type;
2591 arrtmp->size = vsize * elem;
2592 arrtmp->basetype = vtype;
2593 arrtmp->next = NULL;
2594 last_defined->type = arrindex++;
2595 *arrtail = arrtmp;
2596 arrtail = &(arrtmp->next);
2598 last_defined = NULL;
2600 static void dbgbi_output(int output_type, void *param)
2602 (void)output_type;
2603 (void)param;
2605 static struct dfmt borland_debug_form = {
2606 "Borland Debug Records",
2607 "borland",
2608 dbgbi_init,
2609 dbgbi_linnum,
2610 dbgbi_deflabel,
2611 null_debug_directive,
2612 dbgbi_typevalue,
2613 dbgbi_output,
2614 dbgbi_cleanup,
2617 static struct dfmt *borland_debug_arr[3] = {
2618 &borland_debug_form,
2619 &null_debug_form,
2620 NULL
2623 struct ofmt of_obj = {
2624 "MS-DOS 16-bit/32-bit OMF object files",
2625 "obj",
2627 borland_debug_arr,
2628 &borland_debug_form,
2629 obj_stdmac,
2630 obj_init,
2631 obj_set_info,
2632 obj_out,
2633 obj_deflabel,
2634 obj_segment,
2635 obj_sectalign,
2636 obj_segbase,
2637 obj_directive,
2638 obj_filename,
2639 obj_cleanup
2641 #endif /* OF_OBJ */