Change rights 644 to 755
[nasm/github.git] / output / outobj.c
blob6b173eb97c3fc55cb1962f0b3c5ce6d2fbe723f5
1 /* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2014 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 (type == OUT_ADDRESS)
1090 size = abs(size);
1092 if (segment == NO_SEG && type != OUT_ADDRESS)
1093 nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1094 " supported by OBJ format");
1095 if (segment >= SEG_ABS)
1096 nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1097 " by OBJ format");
1099 ldata = *(int64_t *)data;
1100 if (type != OUT_ADDRESS) {
1101 ldata += size;
1102 size = realsize(type, size);
1103 ldata -= size;
1106 if (size > UINT_MAX)
1107 size = 0;
1109 switch ((unsigned int)size) {
1110 default:
1111 nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1112 "32-byte relocations");
1113 segment = NO_SEG; /* Don't actually generate a relocation */
1114 break;
1115 case 2:
1116 orp = obj_word(orp, ldata);
1117 break;
1118 case 4:
1119 orp = obj_dword(orp, ldata);
1120 break;
1123 rsize = size;
1124 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1125 size == 4) {
1127 * This is a 4-byte segment-base relocation such as
1128 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1129 * these, but if the constant term has the 16 low bits
1130 * zero, we can just apply a 2-byte segment-base
1131 * relocation to the low word instead.
1133 rsize = 2;
1134 if (ldata & 0xFFFF)
1135 nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1136 " dword-size segment base references");
1138 if (segment != NO_SEG)
1139 obj_write_fixup(orp, rsize,
1140 (type == OUT_ADDRESS ? 0x4000 : 0),
1141 segment, wrt, seg);
1142 seg->currentpos += size;
1143 break;
1146 default:
1147 nasm_error(ERR_NONFATAL,
1148 "Relocation type not supported by output format");
1149 /* fall through */
1151 case OUT_RESERVE:
1152 if (orp->committed)
1153 orp = obj_bump(orp);
1154 seg->currentpos += size;
1155 break;
1157 obj_commit(orp);
1160 static void obj_write_fixup(ObjRecord * orp, int bytes,
1161 int segrel, int32_t seg, int32_t wrt,
1162 struct Segment *segto)
1164 unsigned locat;
1165 int method;
1166 int base;
1167 int32_t tidx, fidx;
1168 struct Segment *s = NULL;
1169 struct Group *g = NULL;
1170 struct External *e = NULL;
1171 ObjRecord *forp;
1173 if (bytes != 2 && bytes != 4) {
1174 nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1175 " %d-bit relocations", bytes << 3);
1176 return;
1179 forp = orp->child;
1180 if (forp == NULL) {
1181 orp->child = forp = obj_new();
1182 forp->up = &(orp->child);
1183 /* We should choose between FIXUPP and FIXU32 record type */
1184 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1185 if (segto->use32)
1186 forp->type = FIXU32;
1187 else
1188 forp->type = FIXUPP;
1191 if (seg % 2) {
1192 base = true;
1193 locat = FIX_16_SELECTOR;
1194 seg--;
1195 if (bytes != 2)
1196 nasm_error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1197 " through sanity check");
1198 } else {
1199 base = false;
1200 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1201 if (!segrel)
1203 * There is a bug in tlink that makes it process self relative
1204 * fixups incorrectly if the x_size doesn't match the location
1205 * size.
1207 forp = obj_force(forp, bytes << 3);
1210 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1212 tidx = fidx = -1, method = 0; /* placate optimisers */
1215 * See if we can find the segment ID in our segment list. If
1216 * so, we have a T4 (LSEG) target.
1218 for (s = seghead; s; s = s->next)
1219 if (s->index == seg)
1220 break;
1221 if (s)
1222 method = 4, tidx = s->obj_index;
1223 else {
1224 for (g = grphead; g; g = g->next)
1225 if (g->index == seg)
1226 break;
1227 if (g)
1228 method = 5, tidx = g->obj_index;
1229 else {
1230 int32_t i = seg / 2;
1231 struct ExtBack *eb = ebhead;
1232 while (i >= EXT_BLKSIZ) {
1233 if (eb)
1234 eb = eb->next;
1235 else
1236 break;
1237 i -= EXT_BLKSIZ;
1239 if (eb)
1240 method = 6, e = eb->exts[i], tidx = e->index;
1241 else
1242 nasm_error(ERR_PANIC,
1243 "unrecognised segment value in obj_write_fixup");
1248 * If no WRT given, assume the natural default, which is method
1249 * F5 unless:
1251 * - we are doing an OFFSET fixup for a grouped segment, in
1252 * which case we require F1 (group).
1254 * - we are doing an OFFSET fixup for an external with a
1255 * default WRT, in which case we must honour the default WRT.
1257 if (wrt == NO_SEG) {
1258 if (!base && s && s->grp)
1259 method |= 0x10, fidx = s->grp->obj_index;
1260 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1261 if (e->defwrt_type == DEFWRT_SEGMENT)
1262 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1263 else if (e->defwrt_type == DEFWRT_GROUP)
1264 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1265 else {
1266 nasm_error(ERR_NONFATAL, "default WRT specification for"
1267 " external `%s' unresolved", e->name);
1268 method |= 0x50, fidx = -1; /* got to do _something_ */
1270 } else
1271 method |= 0x50, fidx = -1;
1272 } else {
1274 * See if we can find the WRT-segment ID in our segment
1275 * list. If so, we have a F0 (LSEG) frame.
1277 for (s = seghead; s; s = s->next)
1278 if (s->index == wrt - 1)
1279 break;
1280 if (s)
1281 method |= 0x00, fidx = s->obj_index;
1282 else {
1283 for (g = grphead; g; g = g->next)
1284 if (g->index == wrt - 1)
1285 break;
1286 if (g)
1287 method |= 0x10, fidx = g->obj_index;
1288 else {
1289 int32_t i = wrt / 2;
1290 struct ExtBack *eb = ebhead;
1291 while (i >= EXT_BLKSIZ) {
1292 if (eb)
1293 eb = eb->next;
1294 else
1295 break;
1296 i -= EXT_BLKSIZ;
1298 if (eb)
1299 method |= 0x20, fidx = eb->exts[i]->index;
1300 else
1301 nasm_error(ERR_PANIC,
1302 "unrecognised WRT value in obj_write_fixup");
1307 forp = obj_byte(forp, method);
1308 if (fidx != -1)
1309 forp = obj_index(forp, fidx);
1310 forp = obj_index(forp, tidx);
1311 obj_commit(forp);
1314 static int32_t obj_segment(char *name, int pass, int *bits)
1317 * We call the label manager here to define a name for the new
1318 * segment, and when our _own_ label-definition stub gets
1319 * called in return, it should register the new segment name
1320 * using the pointer it gets passed. That way we save memory,
1321 * by sponging off the label manager.
1323 #if defined(DEBUG) && DEBUG>=3
1324 nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1325 name, pass, *bits);
1326 #endif
1327 if (!name) {
1328 *bits = 16;
1329 current_seg = NULL;
1330 return first_seg;
1331 } else {
1332 struct Segment *seg;
1333 struct Group *grp;
1334 struct External **extp;
1335 int obj_idx, i, attrs;
1336 bool rn_error;
1337 char *p;
1340 * Look for segment attributes.
1342 attrs = 0;
1343 while (*name == '.')
1344 name++; /* hack, but a documented one */
1345 p = name;
1346 while (*p && !nasm_isspace(*p))
1347 p++;
1348 if (*p) {
1349 *p++ = '\0';
1350 while (*p && nasm_isspace(*p))
1351 *p++ = '\0';
1353 while (*p) {
1354 while (*p && !nasm_isspace(*p))
1355 p++;
1356 if (*p) {
1357 *p++ = '\0';
1358 while (*p && nasm_isspace(*p))
1359 *p++ = '\0';
1362 attrs++;
1365 obj_idx = 1;
1366 for (seg = seghead; seg; seg = seg->next) {
1367 obj_idx++;
1368 if (!strcmp(seg->name, name)) {
1369 if (attrs > 0 && pass == 1)
1370 nasm_error(ERR_WARNING, "segment attributes specified on"
1371 " redeclaration of segment: ignoring");
1372 if (seg->use32)
1373 *bits = 32;
1374 else
1375 *bits = 16;
1376 current_seg = seg;
1377 return seg->index;
1381 *segtail = seg = nasm_malloc(sizeof(*seg));
1382 seg->next = NULL;
1383 segtail = &seg->next;
1384 seg->index = (any_segs ? seg_alloc() : first_seg);
1385 seg->obj_index = obj_idx;
1386 seg->grp = NULL;
1387 any_segs = true;
1388 seg->name = NULL;
1389 seg->currentpos = 0;
1390 seg->align = 1; /* default */
1391 seg->use32 = false; /* default */
1392 seg->combine = CMB_PUBLIC; /* default */
1393 seg->segclass = seg->overlay = NULL;
1394 seg->pubhead = NULL;
1395 seg->pubtail = &seg->pubhead;
1396 seg->lochead = NULL;
1397 seg->loctail = &seg->lochead;
1398 seg->orp = obj_new();
1399 seg->orp->up = &(seg->orp);
1400 seg->orp->ori = ori_ledata;
1401 seg->orp->type = LEDATA;
1402 seg->orp->parm[1] = obj_idx;
1405 * Process the segment attributes.
1407 p = name;
1408 while (attrs--) {
1409 p += strlen(p);
1410 while (!*p)
1411 p++;
1414 * `p' contains a segment attribute.
1416 if (!nasm_stricmp(p, "private"))
1417 seg->combine = CMB_PRIVATE;
1418 else if (!nasm_stricmp(p, "public"))
1419 seg->combine = CMB_PUBLIC;
1420 else if (!nasm_stricmp(p, "common"))
1421 seg->combine = CMB_COMMON;
1422 else if (!nasm_stricmp(p, "stack"))
1423 seg->combine = CMB_STACK;
1424 else if (!nasm_stricmp(p, "use16"))
1425 seg->use32 = false;
1426 else if (!nasm_stricmp(p, "use32"))
1427 seg->use32 = true;
1428 else if (!nasm_stricmp(p, "flat")) {
1430 * This segment is an OS/2 FLAT segment. That means
1431 * that its default group is group FLAT, even if
1432 * the group FLAT does not explicitly _contain_ the
1433 * segment.
1435 * When we see this, we must create the group
1436 * `FLAT', containing no segments, if it does not
1437 * already exist; then we must set the default
1438 * group of this segment to be the FLAT group.
1440 struct Group *grp;
1441 for (grp = grphead; grp; grp = grp->next)
1442 if (!strcmp(grp->name, "FLAT"))
1443 break;
1444 if (!grp) {
1445 obj_directive(D_GROUP, "FLAT", 1);
1446 for (grp = grphead; grp; grp = grp->next)
1447 if (!strcmp(grp->name, "FLAT"))
1448 break;
1449 if (!grp)
1450 nasm_error(ERR_PANIC, "failure to define FLAT?!");
1452 seg->grp = grp;
1453 } else if (!nasm_strnicmp(p, "class=", 6))
1454 seg->segclass = nasm_strdup(p + 6);
1455 else if (!nasm_strnicmp(p, "overlay=", 8))
1456 seg->overlay = nasm_strdup(p + 8);
1457 else if (!nasm_strnicmp(p, "align=", 6)) {
1458 seg->align = readnum(p + 6, &rn_error);
1459 if (rn_error) {
1460 seg->align = 1;
1461 nasm_error(ERR_NONFATAL, "segment alignment should be"
1462 " numeric");
1464 switch ((int)seg->align) {
1465 case 1: /* BYTE */
1466 case 2: /* WORD */
1467 case 4: /* DWORD */
1468 case 16: /* PARA */
1469 case 256: /* PAGE */
1470 case 4096: /* PharLap extension */
1471 break;
1472 case 8:
1473 nasm_error(ERR_WARNING,
1474 "OBJ format does not support alignment"
1475 " of 8: rounding up to 16");
1476 seg->align = 16;
1477 break;
1478 case 32:
1479 case 64:
1480 case 128:
1481 nasm_error(ERR_WARNING,
1482 "OBJ format does not support alignment"
1483 " of %d: rounding up to 256", seg->align);
1484 seg->align = 256;
1485 break;
1486 case 512:
1487 case 1024:
1488 case 2048:
1489 nasm_error(ERR_WARNING,
1490 "OBJ format does not support alignment"
1491 " of %d: rounding up to 4096", seg->align);
1492 seg->align = 4096;
1493 break;
1494 default:
1495 nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1496 seg->align);
1497 seg->align = 1;
1498 break;
1500 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1501 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1502 if (rn_error)
1503 nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1504 " attribute should be numeric");
1508 /* We need to know whenever we have at least one 32-bit segment */
1509 obj_use32 |= seg->use32;
1511 obj_seg_needs_update = seg;
1512 if (seg->align >= SEG_ABS)
1513 define_label(name, NO_SEG, seg->align - SEG_ABS,
1514 NULL, false, false);
1515 else
1516 define_label(name, seg->index + 1, 0L,
1517 NULL, false, false);
1518 obj_seg_needs_update = NULL;
1521 * See if this segment is defined in any groups.
1523 for (grp = grphead; grp; grp = grp->next) {
1524 for (i = grp->nindices; i < grp->nentries; i++) {
1525 if (!strcmp(grp->segs[i].name, seg->name)) {
1526 nasm_free(grp->segs[i].name);
1527 grp->segs[i] = grp->segs[grp->nindices];
1528 grp->segs[grp->nindices++].index = seg->obj_index;
1529 if (seg->grp)
1530 nasm_error(ERR_WARNING,
1531 "segment `%s' is already part of"
1532 " a group: first one takes precedence",
1533 seg->name);
1534 else
1535 seg->grp = grp;
1541 * Walk through the list of externals with unresolved
1542 * default-WRT clauses, and resolve any that point at this
1543 * segment.
1545 extp = &dws;
1546 while (*extp) {
1547 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1548 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1549 nasm_free((*extp)->defwrt_ptr.string);
1550 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1551 (*extp)->defwrt_ptr.seg = seg;
1552 *extp = (*extp)->next_dws;
1553 } else
1554 extp = &(*extp)->next_dws;
1557 if (seg->use32)
1558 *bits = 32;
1559 else
1560 *bits = 16;
1561 current_seg = seg;
1562 return seg->index;
1566 static int obj_directive(enum directives directive, char *value, int pass)
1568 switch (directive) {
1569 case D_GROUP:
1571 char *p, *q, *v;
1572 if (pass == 1) {
1573 struct Group *grp;
1574 struct Segment *seg;
1575 struct External **extp;
1576 int obj_idx;
1578 q = value;
1579 while (*q == '.')
1580 q++; /* hack, but a documented one */
1581 v = q;
1582 while (*q && !nasm_isspace(*q))
1583 q++;
1584 if (nasm_isspace(*q)) {
1585 *q++ = '\0';
1586 while (*q && nasm_isspace(*q))
1587 q++;
1590 * Here we used to sanity-check the group directive to
1591 * ensure nobody tried to declare a group containing no
1592 * segments. However, OS/2 does this as standard
1593 * practice, so the sanity check has been removed.
1595 * if (!*q) {
1596 * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1597 * return 1;
1601 obj_idx = 1;
1602 for (grp = grphead; grp; grp = grp->next) {
1603 obj_idx++;
1604 if (!strcmp(grp->name, v)) {
1605 nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1606 return 1;
1610 *grptail = grp = nasm_malloc(sizeof(*grp));
1611 grp->next = NULL;
1612 grptail = &grp->next;
1613 grp->index = seg_alloc();
1614 grp->obj_index = obj_idx;
1615 grp->nindices = grp->nentries = 0;
1616 grp->name = NULL;
1618 obj_grp_needs_update = grp;
1619 define_label(v, grp->index + 1, 0L, NULL, false, false);
1620 obj_grp_needs_update = NULL;
1622 while (*q) {
1623 p = q;
1624 while (*q && !nasm_isspace(*q))
1625 q++;
1626 if (nasm_isspace(*q)) {
1627 *q++ = '\0';
1628 while (*q && nasm_isspace(*q))
1629 q++;
1632 * Now p contains a segment name. Find it.
1634 for (seg = seghead; seg; seg = seg->next)
1635 if (!strcmp(seg->name, p))
1636 break;
1637 if (seg) {
1639 * We have a segment index. Shift a name entry
1640 * to the end of the array to make room.
1642 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1643 grp->segs[grp->nindices++].index = seg->obj_index;
1644 if (seg->grp)
1645 nasm_error(ERR_WARNING,
1646 "segment `%s' is already part of"
1647 " a group: first one takes precedence",
1648 seg->name);
1649 else
1650 seg->grp = grp;
1651 } else {
1653 * We have an as-yet undefined segment.
1654 * Remember its name, for later.
1656 grp->segs[grp->nentries++].name = nasm_strdup(p);
1661 * Walk through the list of externals with unresolved
1662 * default-WRT clauses, and resolve any that point at
1663 * this group.
1665 extp = &dws;
1666 while (*extp) {
1667 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1668 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1669 nasm_free((*extp)->defwrt_ptr.string);
1670 (*extp)->defwrt_type = DEFWRT_GROUP;
1671 (*extp)->defwrt_ptr.grp = grp;
1672 *extp = (*extp)->next_dws;
1673 } else
1674 extp = &(*extp)->next_dws;
1677 return 1;
1679 case D_UPPERCASE:
1680 obj_uppercase = true;
1681 return 1;
1683 case D_IMPORT:
1685 char *q, *extname, *libname, *impname;
1687 if (pass == 2)
1688 return 1; /* ignore in pass two */
1689 extname = q = value;
1690 while (*q && !nasm_isspace(*q))
1691 q++;
1692 if (nasm_isspace(*q)) {
1693 *q++ = '\0';
1694 while (*q && nasm_isspace(*q))
1695 q++;
1698 libname = q;
1699 while (*q && !nasm_isspace(*q))
1700 q++;
1701 if (nasm_isspace(*q)) {
1702 *q++ = '\0';
1703 while (*q && nasm_isspace(*q))
1704 q++;
1707 impname = q;
1709 if (!*extname || !*libname)
1710 nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1711 " and library name");
1712 else {
1713 struct ImpDef *imp;
1714 bool err = false;
1716 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1717 imptail = &imp->next;
1718 imp->next = NULL;
1719 imp->extname = nasm_strdup(extname);
1720 imp->libname = nasm_strdup(libname);
1721 imp->impindex = readnum(impname, &err);
1722 if (!*impname || err)
1723 imp->impname = nasm_strdup(impname);
1724 else
1725 imp->impname = NULL;
1728 return 1;
1730 case D_EXPORT:
1732 char *q, *extname, *intname, *v;
1733 struct ExpDef *export;
1734 int flags = 0;
1735 unsigned int ordinal = 0;
1737 if (pass == 2)
1738 return 1; /* ignore in pass two */
1739 intname = q = value;
1740 while (*q && !nasm_isspace(*q))
1741 q++;
1742 if (nasm_isspace(*q)) {
1743 *q++ = '\0';
1744 while (*q && nasm_isspace(*q))
1745 q++;
1748 extname = q;
1749 while (*q && !nasm_isspace(*q))
1750 q++;
1751 if (nasm_isspace(*q)) {
1752 *q++ = '\0';
1753 while (*q && nasm_isspace(*q))
1754 q++;
1757 if (!*intname) {
1758 nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1759 return 1;
1761 if (!*extname) {
1762 extname = intname;
1763 intname = "";
1765 while (*q) {
1766 v = q;
1767 while (*q && !nasm_isspace(*q))
1768 q++;
1769 if (nasm_isspace(*q)) {
1770 *q++ = '\0';
1771 while (*q && nasm_isspace(*q))
1772 q++;
1774 if (!nasm_stricmp(v, "resident"))
1775 flags |= EXPDEF_FLAG_RESIDENT;
1776 else if (!nasm_stricmp(v, "nodata"))
1777 flags |= EXPDEF_FLAG_NODATA;
1778 else if (!nasm_strnicmp(v, "parm=", 5)) {
1779 bool err = false;
1780 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1781 if (err) {
1782 nasm_error(ERR_NONFATAL,
1783 "value `%s' for `parm' is non-numeric", v + 5);
1784 return 1;
1786 } else {
1787 bool err = false;
1788 ordinal = readnum(v, &err);
1789 if (err) {
1790 nasm_error(ERR_NONFATAL,
1791 "unrecognised export qualifier `%s'", v);
1792 return 1;
1794 flags |= EXPDEF_FLAG_ORDINAL;
1798 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1799 exptail = &export->next;
1800 export->next = NULL;
1801 export->extname = nasm_strdup(extname);
1802 export->intname = nasm_strdup(intname);
1803 export->ordinal = ordinal;
1804 export->flags = flags;
1806 return 1;
1808 default:
1809 return 0;
1813 static void obj_sectalign(int32_t seg, unsigned int value)
1815 struct Segment *s;
1817 list_for_each(s, seghead) {
1818 if (s->index == seg)
1819 break;
1823 * it should not be too big value
1824 * and applied on non-absolute sections
1826 if (!s || !is_power2(value) ||
1827 value > 4096 || s->align >= SEG_ABS)
1828 return;
1831 * FIXME: No code duplication please
1832 * consider making helper for this
1833 * mapping since section handler has
1834 * to do the same
1836 switch (value) {
1837 case 8:
1838 value = 16;
1839 break;
1840 case 32:
1841 case 64:
1842 case 128:
1843 value = 256;
1844 break;
1845 case 512:
1846 case 1024:
1847 case 2048:
1848 value = 4096;
1849 break;
1852 if (s->align < (int)value)
1853 s->align = value;
1856 static int32_t obj_segbase(int32_t segment)
1858 struct Segment *seg;
1861 * Find the segment in our list.
1863 for (seg = seghead; seg; seg = seg->next)
1864 if (seg->index == segment - 1)
1865 break;
1867 if (!seg) {
1869 * Might be an external with a default WRT.
1871 int32_t i = segment / 2;
1872 struct ExtBack *eb = ebhead;
1873 struct External *e;
1875 while (i >= EXT_BLKSIZ) {
1876 if (eb)
1877 eb = eb->next;
1878 else
1879 break;
1880 i -= EXT_BLKSIZ;
1882 if (eb) {
1883 e = eb->exts[i];
1884 if (!e) {
1885 nasm_assert(pass0 == 0);
1886 /* Not available - can happen during optimization */
1887 return NO_SEG;
1890 switch (e->defwrt_type) {
1891 case DEFWRT_NONE:
1892 return segment; /* fine */
1893 case DEFWRT_SEGMENT:
1894 return e->defwrt_ptr.seg->index + 1;
1895 case DEFWRT_GROUP:
1896 return e->defwrt_ptr.grp->index + 1;
1897 default:
1898 return NO_SEG; /* can't tell what it is */
1902 return segment; /* not one of ours - leave it alone */
1905 if (seg->align >= SEG_ABS)
1906 return seg->align; /* absolute segment */
1907 if (seg->grp)
1908 return seg->grp->index + 1; /* grouped segment */
1910 return segment; /* no special treatment */
1913 static void obj_filename(char *inname, char *outname)
1915 strcpy(obj_infile, inname);
1916 standard_extension(inname, outname, ".obj");
1919 static void obj_write_file(int debuginfo)
1921 struct Segment *seg, *entry_seg_ptr = 0;
1922 struct FileName *fn;
1923 struct LineNumber *ln;
1924 struct Group *grp;
1925 struct Public *pub, *loc;
1926 struct External *ext;
1927 struct ImpDef *imp;
1928 struct ExpDef *export;
1929 int lname_idx;
1930 ObjRecord *orp;
1933 * Write the THEADR module header.
1935 orp = obj_new();
1936 orp->type = THEADR;
1937 obj_name(orp, obj_infile);
1938 obj_emit2(orp);
1941 * Write the NASM boast comment.
1943 orp->type = COMENT;
1944 obj_rword(orp, 0); /* comment type zero */
1945 obj_name(orp, nasm_comment);
1946 obj_emit2(orp);
1948 orp->type = COMENT;
1950 * Write the IMPDEF records, if any.
1952 for (imp = imphead; imp; imp = imp->next) {
1953 obj_rword(orp, 0xA0); /* comment class A0 */
1954 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1955 if (imp->impname)
1956 obj_byte(orp, 0); /* import by name */
1957 else
1958 obj_byte(orp, 1); /* import by ordinal */
1959 obj_name(orp, imp->extname);
1960 obj_name(orp, imp->libname);
1961 if (imp->impname)
1962 obj_name(orp, imp->impname);
1963 else
1964 obj_word(orp, imp->impindex);
1965 obj_emit2(orp);
1969 * Write the EXPDEF records, if any.
1971 for (export = exphead; export; export = export->next) {
1972 obj_rword(orp, 0xA0); /* comment class A0 */
1973 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1974 obj_byte(orp, export->flags);
1975 obj_name(orp, export->extname);
1976 obj_name(orp, export->intname);
1977 if (export->flags & EXPDEF_FLAG_ORDINAL)
1978 obj_word(orp, export->ordinal);
1979 obj_emit2(orp);
1982 /* we're using extended OMF if we put in debug info */
1983 if (debuginfo) {
1984 orp->type = COMENT;
1985 obj_byte(orp, 0x40);
1986 obj_byte(orp, dEXTENDED);
1987 obj_emit2(orp);
1991 * Write the first LNAMES record, containing LNAME one, which
1992 * is null. Also initialize the LNAME counter.
1994 orp->type = LNAMES;
1995 obj_byte(orp, 0);
1996 lname_idx = 1;
1998 * Write some LNAMES for the segment names
2000 for (seg = seghead; seg; seg = seg->next) {
2001 orp = obj_name(orp, seg->name);
2002 if (seg->segclass)
2003 orp = obj_name(orp, seg->segclass);
2004 if (seg->overlay)
2005 orp = obj_name(orp, seg->overlay);
2006 obj_commit(orp);
2009 * Write some LNAMES for the group names
2011 for (grp = grphead; grp; grp = grp->next) {
2012 orp = obj_name(orp, grp->name);
2013 obj_commit(orp);
2015 obj_emit(orp);
2018 * Write the SEGDEF records.
2020 orp->type = SEGDEF;
2021 for (seg = seghead; seg; seg = seg->next) {
2022 int acbp;
2023 uint32_t seglen = seg->currentpos;
2025 acbp = (seg->combine << 2); /* C field */
2027 if (seg->use32)
2028 acbp |= 0x01; /* P bit is Use32 flag */
2029 else if (seglen == 0x10000L) {
2030 seglen = 0; /* This special case may be needed for old linkers */
2031 acbp |= 0x02; /* B bit */
2034 /* A field */
2035 if (seg->align >= SEG_ABS)
2036 /* acbp |= 0x00 */ ;
2037 else if (seg->align >= 4096) {
2038 if (seg->align > 4096)
2039 nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2040 " than OBJ format supports", seg->name);
2041 acbp |= 0xC0; /* PharLap extension */
2042 } else if (seg->align >= 256) {
2043 acbp |= 0x80;
2044 } else if (seg->align >= 16) {
2045 acbp |= 0x60;
2046 } else if (seg->align >= 4) {
2047 acbp |= 0xA0;
2048 } else if (seg->align >= 2) {
2049 acbp |= 0x40;
2050 } else
2051 acbp |= 0x20;
2053 obj_byte(orp, acbp);
2054 if (seg->align & SEG_ABS) {
2055 obj_x(orp, seg->align - SEG_ABS); /* Frame */
2056 obj_byte(orp, 0); /* Offset */
2058 obj_x(orp, seglen);
2059 obj_index(orp, ++lname_idx);
2060 obj_index(orp, seg->segclass ? ++lname_idx : 1);
2061 obj_index(orp, seg->overlay ? ++lname_idx : 1);
2062 obj_emit2(orp);
2066 * Write the GRPDEF records.
2068 orp->type = GRPDEF;
2069 for (grp = grphead; grp; grp = grp->next) {
2070 int i;
2072 if (grp->nindices != grp->nentries) {
2073 for (i = grp->nindices; i < grp->nentries; i++) {
2074 nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2075 " `%s'", grp->name, grp->segs[i].name);
2076 nasm_free(grp->segs[i].name);
2077 grp->segs[i].name = NULL;
2080 obj_index(orp, ++lname_idx);
2081 for (i = 0; i < grp->nindices; i++) {
2082 obj_byte(orp, 0xFF);
2083 obj_index(orp, grp->segs[i].index);
2085 obj_emit2(orp);
2089 * Write the PUBDEF records: first the ones in the segments,
2090 * then the far-absolutes.
2092 orp->type = PUBDEF;
2093 orp->ori = ori_pubdef;
2094 for (seg = seghead; seg; seg = seg->next) {
2095 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2096 orp->parm[1] = seg->obj_index;
2097 for (pub = seg->pubhead; pub; pub = pub->next) {
2098 orp = obj_name(orp, pub->name);
2099 orp = obj_x(orp, pub->offset);
2100 orp = obj_byte(orp, 0); /* type index */
2101 obj_commit(orp);
2103 obj_emit(orp);
2105 orp->parm[0] = 0;
2106 orp->parm[1] = 0;
2107 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2108 if (orp->parm[2] != (uint32_t)pub->segment) {
2109 obj_emit(orp);
2110 orp->parm[2] = pub->segment;
2112 orp = obj_name(orp, pub->name);
2113 orp = obj_x(orp, pub->offset);
2114 orp = obj_byte(orp, 0); /* type index */
2115 obj_commit(orp);
2117 obj_emit(orp);
2120 * Write the EXTDEF and COMDEF records, in order.
2122 orp->ori = ori_null;
2123 for (ext = exthead; ext; ext = ext->next) {
2124 if (ext->commonsize == 0) {
2125 if (orp->type != EXTDEF) {
2126 obj_emit(orp);
2127 orp->type = EXTDEF;
2129 orp = obj_name(orp, ext->name);
2130 orp = obj_index(orp, 0);
2131 } else {
2132 if (orp->type != COMDEF) {
2133 obj_emit(orp);
2134 orp->type = COMDEF;
2136 orp = obj_name(orp, ext->name);
2137 orp = obj_index(orp, 0);
2138 if (ext->commonelem) {
2139 orp = obj_byte(orp, 0x61); /* far communal */
2140 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2141 orp = obj_value(orp, ext->commonelem);
2142 } else {
2143 orp = obj_byte(orp, 0x62); /* near communal */
2144 orp = obj_value(orp, ext->commonsize);
2147 obj_commit(orp);
2149 obj_emit(orp);
2152 * Write a COMENT record stating that the linker's first pass
2153 * may stop processing at this point. Exception is if our
2154 * MODEND record specifies a start point, in which case,
2155 * according to some variants of the documentation, this COMENT
2156 * should be omitted. So we'll omit it just in case.
2157 * But, TASM puts it in all the time so if we are using
2158 * TASM debug stuff we are putting it in
2160 if (debuginfo || obj_entry_seg == NO_SEG) {
2161 orp->type = COMENT;
2162 obj_byte(orp, 0x40);
2163 obj_byte(orp, dLINKPASS);
2164 obj_byte(orp, 1);
2165 obj_emit2(orp);
2169 * 1) put out the compiler type
2170 * 2) Put out the type info. The only type we are using is near label #19
2172 if (debuginfo) {
2173 int i;
2174 struct Array *arrtmp = arrhead;
2175 orp->type = COMENT;
2176 obj_byte(orp, 0x40);
2177 obj_byte(orp, dCOMPDEF);
2178 obj_byte(orp, 4);
2179 obj_byte(orp, 0);
2180 obj_emit2(orp);
2182 obj_byte(orp, 0x40);
2183 obj_byte(orp, dTYPEDEF);
2184 obj_word(orp, 0x18); /* type # for linking */
2185 obj_word(orp, 6); /* size of type */
2186 obj_byte(orp, 0x2a); /* absolute type for debugging */
2187 obj_emit2(orp);
2188 obj_byte(orp, 0x40);
2189 obj_byte(orp, dTYPEDEF);
2190 obj_word(orp, 0x19); /* type # for linking */
2191 obj_word(orp, 0); /* size of type */
2192 obj_byte(orp, 0x24); /* absolute type for debugging */
2193 obj_byte(orp, 0); /* near/far specifier */
2194 obj_emit2(orp);
2195 obj_byte(orp, 0x40);
2196 obj_byte(orp, dTYPEDEF);
2197 obj_word(orp, 0x1A); /* type # for linking */
2198 obj_word(orp, 0); /* size of type */
2199 obj_byte(orp, 0x24); /* absolute type for debugging */
2200 obj_byte(orp, 1); /* near/far specifier */
2201 obj_emit2(orp);
2202 obj_byte(orp, 0x40);
2203 obj_byte(orp, dTYPEDEF);
2204 obj_word(orp, 0x1b); /* type # for linking */
2205 obj_word(orp, 0); /* size of type */
2206 obj_byte(orp, 0x23); /* absolute type for debugging */
2207 obj_byte(orp, 0);
2208 obj_byte(orp, 0);
2209 obj_byte(orp, 0);
2210 obj_emit2(orp);
2211 obj_byte(orp, 0x40);
2212 obj_byte(orp, dTYPEDEF);
2213 obj_word(orp, 0x1c); /* type # for linking */
2214 obj_word(orp, 0); /* size of type */
2215 obj_byte(orp, 0x23); /* absolute type for debugging */
2216 obj_byte(orp, 0);
2217 obj_byte(orp, 4);
2218 obj_byte(orp, 0);
2219 obj_emit2(orp);
2220 obj_byte(orp, 0x40);
2221 obj_byte(orp, dTYPEDEF);
2222 obj_word(orp, 0x1d); /* type # for linking */
2223 obj_word(orp, 0); /* size of type */
2224 obj_byte(orp, 0x23); /* absolute type for debugging */
2225 obj_byte(orp, 0);
2226 obj_byte(orp, 1);
2227 obj_byte(orp, 0);
2228 obj_emit2(orp);
2229 obj_byte(orp, 0x40);
2230 obj_byte(orp, dTYPEDEF);
2231 obj_word(orp, 0x1e); /* type # for linking */
2232 obj_word(orp, 0); /* size of type */
2233 obj_byte(orp, 0x23); /* absolute type for debugging */
2234 obj_byte(orp, 0);
2235 obj_byte(orp, 5);
2236 obj_byte(orp, 0);
2237 obj_emit2(orp);
2239 /* put out the array types */
2240 for (i = ARRAYBOT; i < arrindex; i++) {
2241 obj_byte(orp, 0x40);
2242 obj_byte(orp, dTYPEDEF);
2243 obj_word(orp, i); /* type # for linking */
2244 obj_word(orp, arrtmp->size); /* size of type */
2245 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2246 obj_byte(orp, arrtmp->basetype); /* base type */
2247 obj_emit2(orp);
2248 arrtmp = arrtmp->next;
2252 * write out line number info with a LINNUM record
2253 * switch records when we switch segments, and output the
2254 * file in a pseudo-TASM fashion. The record switch is naive; that
2255 * is that one file may have many records for the same segment
2256 * if there are lots of segment switches
2258 if (fnhead && debuginfo) {
2259 seg = fnhead->lnhead->segment;
2261 for (fn = fnhead; fn; fn = fn->next) {
2262 /* write out current file name */
2263 orp->type = COMENT;
2264 orp->ori = ori_null;
2265 obj_byte(orp, 0x40);
2266 obj_byte(orp, dFILNAME);
2267 obj_byte(orp, 0);
2268 obj_name(orp, fn->name);
2269 obj_dword(orp, 0);
2270 obj_emit2(orp);
2272 /* write out line numbers this file */
2274 orp->type = LINNUM;
2275 orp->ori = ori_linnum;
2276 for (ln = fn->lnhead; ln; ln = ln->next) {
2277 if (seg != ln->segment) {
2278 /* if we get here have to flush the buffer and start
2279 * a new record for a new segment
2281 seg = ln->segment;
2282 obj_emit(orp);
2284 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2285 orp->parm[1] = seg->obj_index;
2286 orp = obj_word(orp, ln->lineno);
2287 orp = obj_x(orp, ln->offset);
2288 obj_commit(orp);
2290 obj_emit(orp);
2294 * we are going to locate the entry point segment now
2295 * rather than wait until the MODEND record, because,
2296 * then we can output a special symbol to tell where the
2297 * entry point is.
2300 if (obj_entry_seg != NO_SEG) {
2301 for (seg = seghead; seg; seg = seg->next) {
2302 if (seg->index == obj_entry_seg) {
2303 entry_seg_ptr = seg;
2304 break;
2307 if (!seg)
2308 nasm_error(ERR_NONFATAL, "entry point is not in this module");
2312 * get ready to put out symbol records
2314 orp->type = COMENT;
2315 orp->ori = ori_local;
2318 * put out a symbol for the entry point
2319 * no dots in this symbol, because, borland does
2320 * not (officially) support dots in label names
2321 * and I don't know what various versions of TLINK will do
2323 if (debuginfo && obj_entry_seg != NO_SEG) {
2324 orp = obj_name(orp, "start_of_program");
2325 orp = obj_word(orp, 0x19); /* type: near label */
2326 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2327 orp = obj_index(orp, seg->obj_index);
2328 orp = obj_x(orp, obj_entry_ofs);
2329 obj_commit(orp);
2333 * put out the local labels
2335 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2336 /* labels this seg */
2337 for (loc = seg->lochead; loc; loc = loc->next) {
2338 orp = obj_name(orp, loc->name);
2339 orp = obj_word(orp, loc->type);
2340 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2341 orp = obj_index(orp, seg->obj_index);
2342 orp = obj_x(orp, loc->offset);
2343 obj_commit(orp);
2346 if (orp->used)
2347 obj_emit(orp);
2350 * Write the LEDATA/FIXUPP pairs.
2352 for (seg = seghead; seg; seg = seg->next) {
2353 obj_emit(seg->orp);
2354 nasm_free(seg->orp);
2358 * Write the MODEND module end marker.
2360 orp->type = obj_use32 ? MODE32 : MODEND;
2361 orp->ori = ori_null;
2362 if (entry_seg_ptr) {
2363 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2364 obj_byte(orp, 0xC1);
2365 seg = entry_seg_ptr;
2366 if (seg->grp) {
2367 obj_byte(orp, 0x10);
2368 obj_index(orp, seg->grp->obj_index);
2369 } else {
2371 * the below changed to prevent TLINK crashing.
2372 * Previous more efficient version read:
2374 * obj_byte (orp, 0x50);
2376 obj_byte(orp, 0x00);
2377 obj_index(orp, seg->obj_index);
2379 obj_index(orp, seg->obj_index);
2380 obj_x(orp, obj_entry_ofs);
2381 } else
2382 obj_byte(orp, 0);
2383 obj_emit2(orp);
2384 nasm_free(orp);
2387 static void obj_fwrite(ObjRecord * orp)
2389 unsigned int cksum, len;
2390 uint8_t *ptr;
2392 cksum = orp->type;
2393 if (orp->x_size == 32)
2394 cksum |= 1;
2395 fputc(cksum, ofile);
2396 len = orp->committed + 1;
2397 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2398 fwriteint16_t(len, ofile);
2399 nasm_write(orp->buf, len-1, ofile);
2400 for (ptr = orp->buf; --len; ptr++)
2401 cksum += *ptr;
2402 fputc((-cksum) & 0xFF, ofile);
2405 extern macros_t obj_stdmac[];
2407 static void dbgbi_init(void)
2409 fnhead = NULL;
2410 fntail = &fnhead;
2411 arrindex = ARRAYBOT;
2412 arrhead = NULL;
2413 arrtail = &arrhead;
2415 static void dbgbi_cleanup(void)
2417 struct Segment *segtmp;
2418 while (fnhead) {
2419 struct FileName *fntemp = fnhead;
2420 while (fnhead->lnhead) {
2421 struct LineNumber *lntemp = fnhead->lnhead;
2422 fnhead->lnhead = lntemp->next;
2423 nasm_free(lntemp);
2425 fnhead = fnhead->next;
2426 nasm_free(fntemp->name);
2427 nasm_free(fntemp);
2429 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2430 while (segtmp->lochead) {
2431 struct Public *loctmp = segtmp->lochead;
2432 segtmp->lochead = loctmp->next;
2433 nasm_free(loctmp->name);
2434 nasm_free(loctmp);
2437 while (arrhead) {
2438 struct Array *arrtmp = arrhead;
2439 arrhead = arrhead->next;
2440 nasm_free(arrtmp);
2444 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2446 struct FileName *fn;
2447 struct LineNumber *ln;
2448 struct Segment *seg;
2450 if (segto == NO_SEG)
2451 return;
2454 * If `any_segs' is still false, we must define a default
2455 * segment.
2457 if (!any_segs) {
2458 int tempint; /* ignored */
2459 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2460 nasm_error(ERR_PANIC, "strange segment conditions in OBJ driver");
2464 * Find the segment we are targetting.
2466 for (seg = seghead; seg; seg = seg->next)
2467 if (seg->index == segto)
2468 break;
2469 if (!seg)
2470 nasm_error(ERR_PANIC, "lineno directed to nonexistent segment?");
2472 /* for (fn = fnhead; fn; fn = fnhead->next) */
2473 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2474 if (!nasm_stricmp(lnfname, fn->name))
2475 break;
2476 if (!fn) {
2477 fn = nasm_malloc(sizeof(*fn));
2478 fn->name = nasm_malloc(strlen(lnfname) + 1);
2479 strcpy(fn->name, lnfname);
2480 fn->lnhead = NULL;
2481 fn->lntail = &fn->lnhead;
2482 fn->next = NULL;
2483 *fntail = fn;
2484 fntail = &fn->next;
2486 ln = nasm_malloc(sizeof(*ln));
2487 ln->segment = seg;
2488 ln->offset = seg->currentpos;
2489 ln->lineno = lineno;
2490 ln->next = NULL;
2491 *fn->lntail = ln;
2492 fn->lntail = &ln->next;
2495 static void dbgbi_deflabel(char *name, int32_t segment,
2496 int64_t offset, int is_global, char *special)
2498 struct Segment *seg;
2500 (void)special;
2503 * If it's a special-retry from pass two, discard it.
2505 if (is_global == 3)
2506 return;
2509 * First check for the double-period, signifying something
2510 * unusual.
2512 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2513 return;
2517 * Case (i):
2519 if (obj_seg_needs_update) {
2520 return;
2521 } else if (obj_grp_needs_update) {
2522 return;
2524 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2525 return;
2527 if (segment >= SEG_ABS || segment == NO_SEG) {
2528 return;
2532 * If `any_segs' is still false, we might need to define a
2533 * default segment, if they're trying to declare a label in
2534 * `first_seg'. But the label should exist due to a prior
2535 * call to obj_deflabel so we can skip that.
2538 for (seg = seghead; seg; seg = seg->next)
2539 if (seg->index == segment) {
2540 struct Public *loc = nasm_malloc(sizeof(*loc));
2542 * Case (ii). Maybe MODPUB someday?
2544 last_defined = *seg->loctail = loc;
2545 seg->loctail = &loc->next;
2546 loc->next = NULL;
2547 loc->name = nasm_strdup(name);
2548 loc->offset = offset;
2551 static void dbgbi_typevalue(int32_t type)
2553 int vsize;
2554 int elem = TYM_ELEMENTS(type);
2555 type = TYM_TYPE(type);
2557 if (!last_defined)
2558 return;
2560 switch (type) {
2561 case TY_BYTE:
2562 last_defined->type = 8; /* uint8_t */
2563 vsize = 1;
2564 break;
2565 case TY_WORD:
2566 last_defined->type = 10; /* unsigned word */
2567 vsize = 2;
2568 break;
2569 case TY_DWORD:
2570 last_defined->type = 12; /* unsigned dword */
2571 vsize = 4;
2572 break;
2573 case TY_FLOAT:
2574 last_defined->type = 14; /* float */
2575 vsize = 4;
2576 break;
2577 case TY_QWORD:
2578 last_defined->type = 15; /* qword */
2579 vsize = 8;
2580 break;
2581 case TY_TBYTE:
2582 last_defined->type = 16; /* TBYTE */
2583 vsize = 10;
2584 break;
2585 default:
2586 last_defined->type = 0x19; /*label */
2587 vsize = 0;
2588 break;
2591 if (elem > 1) {
2592 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2593 int vtype = last_defined->type;
2594 arrtmp->size = vsize * elem;
2595 arrtmp->basetype = vtype;
2596 arrtmp->next = NULL;
2597 last_defined->type = arrindex++;
2598 *arrtail = arrtmp;
2599 arrtail = &(arrtmp->next);
2601 last_defined = NULL;
2603 static void dbgbi_output(int output_type, void *param)
2605 (void)output_type;
2606 (void)param;
2608 static struct dfmt borland_debug_form = {
2609 "Borland Debug Records",
2610 "borland",
2611 dbgbi_init,
2612 dbgbi_linnum,
2613 dbgbi_deflabel,
2614 null_debug_directive,
2615 dbgbi_typevalue,
2616 dbgbi_output,
2617 dbgbi_cleanup,
2620 static struct dfmt *borland_debug_arr[3] = {
2621 &borland_debug_form,
2622 &null_debug_form,
2623 NULL
2626 struct ofmt of_obj = {
2627 "MS-DOS 16-bit/32-bit OMF object files",
2628 "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 */