outcoff: fix invalid reference to ofmt
[nasm.git] / output / outobj.c
blob73bec3ccb9e0954149bea8a50486d7f3d6fe18e6
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>
47 #include "nasm.h"
48 #include "nasmlib.h"
49 #include "stdscan.h"
50 #include "output/outform.h"
51 #include "output/outlib.h"
53 #ifdef OF_OBJ
56 * outobj.c is divided into two sections. The first section is low level
57 * routines for creating obj records; It has nearly zero NASM specific
58 * code. The second section is high level routines for processing calls and
59 * data structures from the rest of NASM into obj format.
61 * It should be easy (though not zero work) to lift the first section out for
62 * use as an obj file writer for some other assembler or compiler.
66 * These routines are built around the ObjRecord data struture. An ObjRecord
67 * holds an object file record that may be under construction or complete.
69 * A major function of these routines is to support continuation of an obj
70 * record into the next record when the maximum record size is exceeded. The
71 * high level code does not need to worry about where the record breaks occur.
72 * It does need to do some minor extra steps to make the automatic continuation
73 * work. Those steps may be skipped for records where the high level knows no
74 * continuation could be required.
76 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
77 * is cleared by obj_clear.
79 * 2) The caller should fill in .type.
81 * 3) If the record is continuable and there is processing that must be done at
82 * the start of each record then the caller should fill in .ori with the
83 * address of the record initializer routine.
85 * 4) If the record is continuable and it should be saved (rather than emitted
86 * immediately) as each record is done, the caller should set .up to be a
87 * pointer to a location in which the caller keeps the master pointer to the
88 * ObjRecord. When the record is continued, the obj_bump routine will then
89 * allocate a new ObjRecord structure and update the master pointer.
91 * 5) If the .ori field was used then the caller should fill in the .parm with
92 * any data required by the initializer.
94 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
95 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
96 * data required for this record.
98 * 7) If the record is continuable, the caller should call obj_commit at each
99 * point where breaking the record is permitted.
101 * 8) To write out the record, the caller should call obj_emit2. If the
102 * caller has called obj_commit for all data written then he can get slightly
103 * faster code by calling obj_emit instead of obj_emit2.
105 * Most of these routines return an ObjRecord pointer. This will be the input
106 * pointer most of the time and will be the new location if the ObjRecord
107 * moved as a result of the call. The caller may ignore the return value in
108 * three cases: It is a "Never Reallocates" routine; or The caller knows
109 * continuation is not possible; or The caller uses the master pointer for the
110 * next operation.
113 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
114 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
116 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
117 #define FIX_16_OFFSET 0x8400
118 #define FIX_16_SELECTOR 0x8800
119 #define FIX_32_POINTER 0x8C00
120 #define FIX_08_HIGH 0x9000
121 #define FIX_32_OFFSET 0xA400
122 #define FIX_48_POINTER 0xAC00
124 enum RecordID { /* record ID codes */
126 THEADR = 0x80, /* module header */
127 COMENT = 0x88, /* comment record */
129 LINNUM = 0x94, /* line number record */
130 LNAMES = 0x96, /* list of names */
132 SEGDEF = 0x98, /* segment definition */
133 GRPDEF = 0x9A, /* group definition */
134 EXTDEF = 0x8C, /* external definition */
135 PUBDEF = 0x90, /* public definition */
136 COMDEF = 0xB0, /* common definition */
138 LEDATA = 0xA0, /* logical enumerated data */
139 FIXUPP = 0x9C, /* fixups (relocations) */
140 FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
142 MODEND = 0x8A, /* module end */
143 MODE32 = 0x8B /* module end for 32-bit objects */
146 enum ComentID { /* ID codes for comment records */
148 dEXTENDED = 0xA1, /* tells that we are using translator-specific extensions */
149 dLINKPASS = 0xA2, /* link pass 2 marker */
150 dTYPEDEF = 0xE3, /* define a type */
151 dSYM = 0xE6, /* symbol debug record */
152 dFILNAME = 0xE8, /* file name record */
153 dCOMPDEF = 0xEA /* compiler type info */
156 typedef struct ObjRecord ObjRecord;
157 typedef void ORI(ObjRecord * orp);
159 struct ObjRecord {
160 ORI *ori; /* Initialization routine */
161 int used; /* Current data size */
162 int committed; /* Data size at last boundary */
163 int x_size; /* (see obj_x) */
164 unsigned int type; /* Record type */
165 ObjRecord *child; /* Associated record below this one */
166 ObjRecord **up; /* Master pointer to this ObjRecord */
167 ObjRecord *back; /* Previous part of this record */
168 uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
169 uint8_t buf[RECORD_MAX + 3];
172 static void obj_fwrite(ObjRecord * orp);
173 static void ori_ledata(ObjRecord * orp);
174 static void ori_pubdef(ObjRecord * orp);
175 static void ori_null(ObjRecord * orp);
176 static ObjRecord *obj_commit(ObjRecord * orp);
178 static bool obj_uppercase; /* Flag: all names in uppercase */
179 static bool obj_use32; /* Flag: at least one segment is 32-bit */
182 * Clear an ObjRecord structure. (Never reallocates).
183 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
185 static ObjRecord *obj_clear(ObjRecord * orp)
187 orp->used = 0;
188 orp->committed = 0;
189 orp->x_size = 0;
190 orp->child = NULL;
191 orp->up = NULL;
192 orp->back = NULL;
193 return (orp);
197 * Emit an ObjRecord structure. (Never reallocates).
198 * The record is written out preceeded (recursively) by its previous part (if
199 * any) and followed (recursively) by its child (if any).
200 * The previous part and the child are freed. The main ObjRecord is cleared,
201 * not freed.
203 static ObjRecord *obj_emit(ObjRecord * orp)
205 if (orp->back) {
206 obj_emit(orp->back);
207 nasm_free(orp->back);
210 if (orp->committed)
211 obj_fwrite(orp);
213 if (orp->child) {
214 obj_emit(orp->child);
215 nasm_free(orp->child);
218 return (obj_clear(orp));
222 * Commit and Emit a record. (Never reallocates).
224 static ObjRecord *obj_emit2(ObjRecord * orp)
226 obj_commit(orp);
227 return (obj_emit(orp));
231 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
233 static ObjRecord *obj_new(void)
235 ObjRecord *orp;
237 orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
238 orp->ori = ori_null;
239 return (orp);
243 * Advance to the next record because the existing one is full or its x_size
244 * is incompatible.
245 * Any uncommited data is moved into the next record.
247 static ObjRecord *obj_bump(ObjRecord * orp)
249 ObjRecord *nxt;
250 int used = orp->used;
251 int committed = orp->committed;
253 if (orp->up) {
254 *orp->up = nxt = obj_new();
255 nxt->ori = orp->ori;
256 nxt->type = orp->type;
257 nxt->up = orp->up;
258 nxt->back = orp;
259 memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
260 } else
261 nxt = obj_emit(orp);
263 used -= committed;
264 if (used) {
265 nxt->committed = 1;
266 nxt->ori(nxt);
267 nxt->committed = nxt->used;
268 memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
269 nxt->used = nxt->committed + used;
272 return (nxt);
276 * Advance to the next record if necessary to allow the next field to fit.
278 static ObjRecord *obj_check(ObjRecord * orp, int size)
280 if (orp->used + size > RECORD_MAX)
281 orp = obj_bump(orp);
283 if (!orp->committed) {
284 orp->committed = 1;
285 orp->ori(orp);
286 orp->committed = orp->used;
289 return (orp);
293 * All data written so far is commited to the current record (won't be moved to
294 * the next record in case of continuation).
296 static ObjRecord *obj_commit(ObjRecord * orp)
298 orp->committed = orp->used;
299 return (orp);
303 * Write a byte
305 static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
307 orp = obj_check(orp, 1);
308 orp->buf[orp->used] = val;
309 orp->used++;
310 return (orp);
314 * Write a word
316 static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
318 orp = obj_check(orp, 2);
319 orp->buf[orp->used] = val;
320 orp->buf[orp->used + 1] = val >> 8;
321 orp->used += 2;
322 return (orp);
326 * Write a reversed word
328 static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
330 orp = obj_check(orp, 2);
331 orp->buf[orp->used] = val >> 8;
332 orp->buf[orp->used + 1] = val;
333 orp->used += 2;
334 return (orp);
338 * Write a dword
340 static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
342 orp = obj_check(orp, 4);
343 orp->buf[orp->used] = val;
344 orp->buf[orp->used + 1] = val >> 8;
345 orp->buf[orp->used + 2] = val >> 16;
346 orp->buf[orp->used + 3] = val >> 24;
347 orp->used += 4;
348 return (orp);
352 * All fields of "size x" in one obj record must be the same size (either 16
353 * bits or 32 bits). There is a one bit flag in each record which specifies
354 * which.
355 * This routine is used to force the current record to have the desired
356 * x_size. x_size is normally automatic (using obj_x), so that this
357 * routine should be used outside obj_x, only to provide compatibility with
358 * linkers that have bugs in their processing of the size bit.
361 static ObjRecord *obj_force(ObjRecord * orp, int x)
363 if (orp->x_size == (x ^ 48))
364 orp = obj_bump(orp);
365 orp->x_size = x;
366 return (orp);
370 * This routine writes a field of size x. The caller does not need to worry at
371 * all about whether 16-bits or 32-bits are required.
373 static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
375 if (orp->type & 1)
376 orp->x_size = 32;
377 if (val > 0xFFFF)
378 orp = obj_force(orp, 32);
379 if (orp->x_size == 32) {
380 ObjRecord *nxt = obj_dword(orp, val);
381 nxt->x_size = 32; /* x_size is cleared when a record overflows */
382 return nxt;
384 orp->x_size = 16;
385 return (obj_word(orp, val));
389 * Writes an index
391 static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
393 if (val < 128)
394 return (obj_byte(orp, val));
395 return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
399 * Writes a variable length value
401 static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
403 if (val <= 128)
404 return (obj_byte(orp, val));
405 if (val <= 0xFFFF) {
406 orp = obj_byte(orp, 129);
407 return (obj_word(orp, val));
409 if (val <= 0xFFFFFF)
410 return (obj_dword(orp, (val << 8) + 132));
411 orp = obj_byte(orp, 136);
412 return (obj_dword(orp, val));
416 * Writes a counted string
418 static ObjRecord *obj_name(ObjRecord * orp, const char *name)
420 int len = strlen(name);
421 uint8_t *ptr;
423 orp = obj_check(orp, len + 1);
424 ptr = orp->buf + orp->used;
425 *ptr++ = len;
426 orp->used += len + 1;
427 if (obj_uppercase)
428 while (--len >= 0) {
429 *ptr++ = toupper(*name);
430 name++;
431 } else
432 memcpy(ptr, name, len);
433 return (orp);
437 * Initializer for an LEDATA record.
438 * parm[0] = offset
439 * parm[1] = segment index
440 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
441 * represent the offset that would be required if the record were split at the
442 * last commit point.
443 * parm[2] is a copy of parm[0] as it was when the current record was initted.
445 static void ori_ledata(ObjRecord * orp)
447 obj_index(orp, orp->parm[1]);
448 orp->parm[2] = orp->parm[0];
449 obj_x(orp, orp->parm[0]);
453 * Initializer for a PUBDEF record.
454 * parm[0] = group index
455 * parm[1] = segment index
456 * parm[2] = frame (only used when both indexes are zero)
458 static void ori_pubdef(ObjRecord * orp)
460 obj_index(orp, orp->parm[0]);
461 obj_index(orp, orp->parm[1]);
462 if (!(orp->parm[0] | orp->parm[1]))
463 obj_word(orp, orp->parm[2]);
467 * Initializer for a LINNUM record.
468 * parm[0] = group index
469 * parm[1] = segment index
471 static void ori_linnum(ObjRecord * orp)
473 obj_index(orp, orp->parm[0]);
474 obj_index(orp, orp->parm[1]);
478 * Initializer for a local vars record.
480 static void ori_local(ObjRecord * orp)
482 obj_byte(orp, 0x40);
483 obj_byte(orp, dSYM);
487 * Null initializer for records that continue without any header info
489 static void ori_null(ObjRecord * orp)
491 (void)orp; /* Do nothing */
495 * This concludes the low level section of outobj.c
498 static char obj_infile[FILENAME_MAX];
500 static efunc error;
501 static evalfunc evaluate;
502 static ldfunc deflabel;
503 static FILE *ofp;
504 static int32_t first_seg;
505 static bool any_segs;
506 static int passtwo;
507 static int arrindex;
509 #define GROUP_MAX 256 /* we won't _realistically_ have more
510 * than this many segs in a group */
511 #define EXT_BLKSIZ 256 /* block size for externals list */
513 struct Segment; /* need to know these structs exist */
514 struct Group;
516 struct LineNumber {
517 struct LineNumber *next;
518 struct Segment *segment;
519 int32_t offset;
520 int32_t lineno;
523 static struct FileName {
524 struct FileName *next;
525 char *name;
526 struct LineNumber *lnhead, **lntail;
527 int index;
528 } *fnhead, **fntail;
530 static struct Array {
531 struct Array *next;
532 unsigned size;
533 int basetype;
534 } *arrhead, **arrtail;
536 #define ARRAYBOT 31 /* magic number for first array index */
538 static struct Public {
539 struct Public *next;
540 char *name;
541 int32_t offset;
542 int32_t segment; /* only if it's far-absolute */
543 int type; /* only for local debug syms */
544 } *fpubhead, **fpubtail, *last_defined;
546 static struct External {
547 struct External *next;
548 char *name;
549 int32_t commonsize;
550 int32_t commonelem; /* element size if FAR, else zero */
551 int index; /* OBJ-file external index */
552 enum {
553 DEFWRT_NONE, /* no unusual default-WRT */
554 DEFWRT_STRING, /* a string we don't yet understand */
555 DEFWRT_SEGMENT, /* a segment */
556 DEFWRT_GROUP /* a group */
557 } defwrt_type;
558 union {
559 char *string;
560 struct Segment *seg;
561 struct Group *grp;
562 } defwrt_ptr;
563 struct External *next_dws; /* next with DEFWRT_STRING */
564 } *exthead, **exttail, *dws;
566 static int externals;
568 static struct ExtBack {
569 struct ExtBack *next;
570 struct External *exts[EXT_BLKSIZ];
571 } *ebhead, **ebtail;
573 static struct Segment {
574 struct Segment *next;
575 int32_t index; /* the NASM segment id */
576 int32_t obj_index; /* the OBJ-file segment index */
577 struct Group *grp; /* the group it beint32_ts to */
578 uint32_t currentpos;
579 int32_t align; /* can be SEG_ABS + absolute addr */
580 enum {
581 CMB_PRIVATE = 0,
582 CMB_PUBLIC = 2,
583 CMB_STACK = 5,
584 CMB_COMMON = 6
585 } combine;
586 bool use32; /* is this segment 32-bit? */
587 struct Public *pubhead, **pubtail, *lochead, **loctail;
588 char *name;
589 char *segclass, *overlay; /* `class' is a C++ keyword :-) */
590 ObjRecord *orp;
591 } *seghead, **segtail, *obj_seg_needs_update;
593 static struct Group {
594 struct Group *next;
595 char *name;
596 int32_t index; /* NASM segment id */
597 int32_t obj_index; /* OBJ-file group index */
598 int32_t nentries; /* number of elements... */
599 int32_t nindices; /* ...and number of index elts... */
600 union {
601 int32_t index;
602 char *name;
603 } segs[GROUP_MAX]; /* ...in this */
604 } *grphead, **grptail, *obj_grp_needs_update;
606 static struct ImpDef {
607 struct ImpDef *next;
608 char *extname;
609 char *libname;
610 unsigned int impindex;
611 char *impname;
612 } *imphead, **imptail;
614 static struct ExpDef {
615 struct ExpDef *next;
616 char *intname;
617 char *extname;
618 unsigned int ordinal;
619 int flags;
620 } *exphead, **exptail;
622 #define EXPDEF_FLAG_ORDINAL 0x80
623 #define EXPDEF_FLAG_RESIDENT 0x40
624 #define EXPDEF_FLAG_NODATA 0x20
625 #define EXPDEF_MASK_PARMCNT 0x1F
627 static int32_t obj_entry_seg, obj_entry_ofs;
629 struct ofmt of_obj;
631 /* The current segment */
632 static struct Segment *current_seg;
634 static int32_t obj_segment(char *, int, int *);
635 static void obj_write_file(int debuginfo);
636 static int obj_directive(char *, char *, int);
638 static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
640 ofp = fp;
641 error = errfunc;
642 evaluate = eval;
643 deflabel = ldef;
644 first_seg = seg_alloc();
645 any_segs = false;
646 fpubhead = NULL;
647 fpubtail = &fpubhead;
648 exthead = NULL;
649 exttail = &exthead;
650 imphead = NULL;
651 imptail = &imphead;
652 exphead = NULL;
653 exptail = &exphead;
654 dws = NULL;
655 externals = 0;
656 ebhead = NULL;
657 ebtail = &ebhead;
658 seghead = obj_seg_needs_update = NULL;
659 segtail = &seghead;
660 grphead = obj_grp_needs_update = NULL;
661 grptail = &grphead;
662 obj_entry_seg = NO_SEG;
663 obj_uppercase = false;
664 obj_use32 = false;
665 passtwo = 0;
666 current_seg = NULL;
669 static int obj_set_info(enum geninfo type, char **val)
671 (void)type;
672 (void)val;
674 return 0;
676 static void obj_cleanup(int debuginfo)
678 obj_write_file(debuginfo);
679 of_obj.current_dfmt->cleanup();
680 fclose(ofp);
681 while (seghead) {
682 struct Segment *segtmp = seghead;
683 seghead = seghead->next;
684 while (segtmp->pubhead) {
685 struct Public *pubtmp = segtmp->pubhead;
686 segtmp->pubhead = pubtmp->next;
687 nasm_free(pubtmp->name);
688 nasm_free(pubtmp);
690 nasm_free(segtmp->segclass);
691 nasm_free(segtmp->overlay);
692 nasm_free(segtmp);
694 while (fpubhead) {
695 struct Public *pubtmp = fpubhead;
696 fpubhead = fpubhead->next;
697 nasm_free(pubtmp->name);
698 nasm_free(pubtmp);
700 while (exthead) {
701 struct External *exttmp = exthead;
702 exthead = exthead->next;
703 nasm_free(exttmp);
705 while (imphead) {
706 struct ImpDef *imptmp = imphead;
707 imphead = imphead->next;
708 nasm_free(imptmp->extname);
709 nasm_free(imptmp->libname);
710 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
711 nasm_free(imptmp);
713 while (exphead) {
714 struct ExpDef *exptmp = exphead;
715 exphead = exphead->next;
716 nasm_free(exptmp->extname);
717 nasm_free(exptmp->intname);
718 nasm_free(exptmp);
720 while (ebhead) {
721 struct ExtBack *ebtmp = ebhead;
722 ebhead = ebhead->next;
723 nasm_free(ebtmp);
725 while (grphead) {
726 struct Group *grptmp = grphead;
727 grphead = grphead->next;
728 nasm_free(grptmp);
732 static void obj_ext_set_defwrt(struct External *ext, char *id)
734 struct Segment *seg;
735 struct Group *grp;
737 for (seg = seghead; seg; seg = seg->next)
738 if (!strcmp(seg->name, id)) {
739 ext->defwrt_type = DEFWRT_SEGMENT;
740 ext->defwrt_ptr.seg = seg;
741 nasm_free(id);
742 return;
745 for (grp = grphead; grp; grp = grp->next)
746 if (!strcmp(grp->name, id)) {
747 ext->defwrt_type = DEFWRT_GROUP;
748 ext->defwrt_ptr.grp = grp;
749 nasm_free(id);
750 return;
753 ext->defwrt_type = DEFWRT_STRING;
754 ext->defwrt_ptr.string = id;
755 ext->next_dws = dws;
756 dws = ext;
759 static void obj_deflabel(char *name, int32_t segment,
760 int64_t offset, int is_global, char *special)
763 * We have three cases:
765 * (i) `segment' is a segment-base. If so, set the name field
766 * for the segment or group structure it refers to, and then
767 * return.
769 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
770 * Save the label position for later output of a PUBDEF record.
771 * (Or a MODPUB, if we work out how.)
773 * (iii) `segment' is not one of our segments. Save the label
774 * position for later output of an EXTDEF, and also store a
775 * back-reference so that we can map later references to this
776 * segment number to the external index.
778 struct External *ext;
779 struct ExtBack *eb;
780 struct Segment *seg;
781 int i;
782 bool used_special = false; /* have we used the special text? */
784 #if defined(DEBUG) && DEBUG>2
785 fprintf(stderr,
786 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
787 name, segment, offset, is_global, special);
788 #endif
791 * If it's a special-retry from pass two, discard it.
793 if (is_global == 3)
794 return;
797 * First check for the double-period, signifying something
798 * unusual.
800 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
801 if (!strcmp(name, "..start")) {
802 obj_entry_seg = segment;
803 obj_entry_ofs = offset;
804 return;
806 error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
810 * Case (i):
812 if (obj_seg_needs_update) {
813 obj_seg_needs_update->name = name;
814 return;
815 } else if (obj_grp_needs_update) {
816 obj_grp_needs_update->name = name;
817 return;
819 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
820 return;
822 if (segment >= SEG_ABS || segment == NO_SEG) {
824 * SEG_ABS subcase of (ii).
826 if (is_global) {
827 struct Public *pub;
829 pub = *fpubtail = nasm_malloc(sizeof(*pub));
830 fpubtail = &pub->next;
831 pub->next = NULL;
832 pub->name = nasm_strdup(name);
833 pub->offset = offset;
834 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
836 if (special)
837 error(ERR_NONFATAL, "OBJ supports no special symbol features"
838 " for this symbol type");
839 return;
843 * If `any_segs' is still false, we might need to define a
844 * default segment, if they're trying to declare a label in
845 * `first_seg'.
847 if (!any_segs && segment == first_seg) {
848 int tempint; /* ignored */
849 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
850 error(ERR_PANIC, "strange segment conditions in OBJ driver");
853 for (seg = seghead; seg && is_global; seg = seg->next)
854 if (seg->index == segment) {
855 struct Public *loc = nasm_malloc(sizeof(*loc));
857 * Case (ii). Maybe MODPUB someday?
859 *seg->pubtail = loc;
860 seg->pubtail = &loc->next;
861 loc->next = NULL;
862 loc->name = nasm_strdup(name);
863 loc->offset = offset;
865 if (special)
866 error(ERR_NONFATAL,
867 "OBJ supports no special symbol features"
868 " for this symbol type");
869 return;
873 * Case (iii).
875 if (is_global) {
876 ext = *exttail = nasm_malloc(sizeof(*ext));
877 ext->next = NULL;
878 exttail = &ext->next;
879 ext->name = name;
880 /* Place by default all externs into the current segment */
881 ext->defwrt_type = DEFWRT_NONE;
883 /* 28-Apr-2002 - John Coffman
884 The following code was introduced on 12-Aug-2000, and breaks fixups
885 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
886 (5.10). It was introduced after FIXUP32 was added, and may be needed
887 for 32-bit segments. The following will get 16-bit segments working
888 again, and maybe someone can correct the 'if' condition which is
889 actually needed.
891 #if 0
892 if (current_seg) {
893 #else
894 if (current_seg && current_seg->use32) {
895 if (current_seg->grp) {
896 ext->defwrt_type = DEFWRT_GROUP;
897 ext->defwrt_ptr.grp = current_seg->grp;
898 } else {
899 ext->defwrt_type = DEFWRT_SEGMENT;
900 ext->defwrt_ptr.seg = current_seg;
903 #endif
905 if (is_global == 2) {
906 ext->commonsize = offset;
907 ext->commonelem = 1; /* default FAR */
908 } else
909 ext->commonsize = 0;
910 } else
911 return;
914 * Now process the special text, if any, to find default-WRT
915 * specifications and common-variable element-size and near/far
916 * specifications.
918 while (special && *special) {
919 used_special = true;
922 * We might have a default-WRT specification.
924 if (!nasm_strnicmp(special, "wrt", 3)) {
925 char *p;
926 int len;
927 special += 3;
928 special += strspn(special, " \t");
929 p = nasm_strndup(special, len = strcspn(special, ":"));
930 obj_ext_set_defwrt(ext, p);
931 special += len;
932 if (*special && *special != ':')
933 error(ERR_NONFATAL, "`:' expected in special symbol"
934 " text for `%s'", ext->name);
935 else if (*special == ':')
936 special++;
940 * The NEAR or FAR keywords specify nearness or
941 * farness. FAR gives default element size 1.
943 if (!nasm_strnicmp(special, "far", 3)) {
944 if (ext->commonsize)
945 ext->commonelem = 1;
946 else
947 error(ERR_NONFATAL,
948 "`%s': `far' keyword may only be applied"
949 " to common variables\n", ext->name);
950 special += 3;
951 special += strspn(special, " \t");
952 } else if (!nasm_strnicmp(special, "near", 4)) {
953 if (ext->commonsize)
954 ext->commonelem = 0;
955 else
956 error(ERR_NONFATAL,
957 "`%s': `far' keyword may only be applied"
958 " to common variables\n", ext->name);
959 special += 4;
960 special += strspn(special, " \t");
964 * If it's a common, and anything else remains on the line
965 * before a further colon, evaluate it as an expression and
966 * use that as the element size. Forward references aren't
967 * allowed.
969 if (*special == ':')
970 special++;
971 else if (*special) {
972 if (ext->commonsize) {
973 expr *e;
974 struct tokenval tokval;
976 stdscan_reset();
977 stdscan_bufptr = special;
978 tokval.t_type = TOKEN_INVALID;
979 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
980 if (e) {
981 if (!is_simple(e))
982 error(ERR_NONFATAL, "cannot use relocatable"
983 " expression as common-variable element size");
984 else
985 ext->commonelem = reloc_value(e);
987 special = stdscan_bufptr;
988 } else {
989 error(ERR_NONFATAL,
990 "`%s': element-size specifications only"
991 " apply to common variables", ext->name);
992 while (*special && *special != ':')
993 special++;
994 if (*special == ':')
995 special++;
1000 i = segment / 2;
1001 eb = ebhead;
1002 if (!eb) {
1003 eb = *ebtail = nasm_malloc(sizeof(*eb));
1004 eb->next = NULL;
1005 ebtail = &eb->next;
1007 while (i >= EXT_BLKSIZ) {
1008 if (eb && eb->next)
1009 eb = eb->next;
1010 else {
1011 eb = *ebtail = nasm_malloc(sizeof(*eb));
1012 eb->next = NULL;
1013 ebtail = &eb->next;
1015 i -= EXT_BLKSIZ;
1017 eb->exts[i] = ext;
1018 ext->index = ++externals;
1020 if (special && !used_special)
1021 error(ERR_NONFATAL, "OBJ supports no special symbol features"
1022 " for this symbol type");
1025 /* forward declaration */
1026 static void obj_write_fixup(ObjRecord * orp, int bytes,
1027 int segrel, int32_t seg, int32_t wrt,
1028 struct Segment *segto);
1030 static void obj_out(int32_t segto, const void *data,
1031 enum out_type type, uint64_t size,
1032 int32_t segment, int32_t wrt)
1034 const uint8_t *ucdata;
1035 int32_t ldata;
1036 struct Segment *seg;
1037 ObjRecord *orp;
1040 * handle absolute-assembly (structure definitions)
1042 if (segto == NO_SEG) {
1043 if (type != OUT_RESERVE)
1044 error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1045 " space");
1046 return;
1050 * If `any_segs' is still false, we must define a default
1051 * segment.
1053 if (!any_segs) {
1054 int tempint; /* ignored */
1055 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1056 error(ERR_PANIC, "strange segment conditions in OBJ driver");
1060 * Find the segment we are targetting.
1062 for (seg = seghead; seg; seg = seg->next)
1063 if (seg->index == segto)
1064 break;
1065 if (!seg)
1066 error(ERR_PANIC, "code directed to nonexistent segment?");
1068 orp = seg->orp;
1069 orp->parm[0] = seg->currentpos;
1071 if (type == OUT_RAWDATA) {
1072 ucdata = data;
1073 while (size > 0) {
1074 unsigned int len;
1075 orp = obj_check(seg->orp, 1);
1076 len = RECORD_MAX - orp->used;
1077 if (len > size)
1078 len = size;
1079 memcpy(orp->buf + orp->used, ucdata, len);
1080 orp->committed = orp->used += len;
1081 orp->parm[0] = seg->currentpos += len;
1082 ucdata += len;
1083 size -= len;
1085 } else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
1086 type == OUT_REL4ADR) {
1087 int rsize;
1089 if (segment == NO_SEG && type != OUT_ADDRESS)
1090 error(ERR_NONFATAL, "relative call to absolute address not"
1091 " supported by OBJ format");
1092 if (segment >= SEG_ABS)
1093 error(ERR_NONFATAL, "far-absolute relocations not supported"
1094 " by OBJ format");
1095 ldata = *(int64_t *)data;
1096 if (type == OUT_REL2ADR) {
1097 ldata += (size - 2);
1098 size = 2;
1099 } else if (type == OUT_REL4ADR) {
1100 ldata += (size - 4);
1101 size = 4;
1103 if (size == 2)
1104 orp = obj_word(orp, ldata);
1105 else
1106 orp = obj_dword(orp, ldata);
1107 rsize = size;
1108 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1109 size == 4) {
1111 * This is a 4-byte segment-base relocation such as
1112 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1113 * these, but if the constant term has the 16 low bits
1114 * zero, we can just apply a 2-byte segment-base
1115 * relocation to the low word instead.
1117 rsize = 2;
1118 if (ldata & 0xFFFF)
1119 error(ERR_NONFATAL, "OBJ format cannot handle complex"
1120 " dword-size segment base references");
1122 if (segment != NO_SEG)
1123 obj_write_fixup(orp, rsize,
1124 (type == OUT_ADDRESS ? 0x4000 : 0),
1125 segment, wrt, seg);
1126 seg->currentpos += size;
1127 } else if (type == OUT_RESERVE) {
1128 if (orp->committed)
1129 orp = obj_bump(orp);
1130 seg->currentpos += size;
1132 obj_commit(orp);
1135 static void obj_write_fixup(ObjRecord * orp, int bytes,
1136 int segrel, int32_t seg, int32_t wrt,
1137 struct Segment *segto)
1139 unsigned locat;
1140 int method;
1141 int base;
1142 int32_t tidx, fidx;
1143 struct Segment *s = NULL;
1144 struct Group *g = NULL;
1145 struct External *e = NULL;
1146 ObjRecord *forp;
1148 if (bytes == 1) {
1149 error(ERR_NONFATAL, "`obj' output driver does not support"
1150 " one-byte relocations");
1151 return;
1154 forp = orp->child;
1155 if (forp == NULL) {
1156 orp->child = forp = obj_new();
1157 forp->up = &(orp->child);
1158 /* We should choose between FIXUPP and FIXU32 record type */
1159 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1160 if (segto->use32)
1161 forp->type = FIXU32;
1162 else
1163 forp->type = FIXUPP;
1166 if (seg % 2) {
1167 base = true;
1168 locat = FIX_16_SELECTOR;
1169 seg--;
1170 if (bytes != 2)
1171 error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1172 " through sanity check");
1173 } else {
1174 base = false;
1175 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1176 if (!segrel)
1178 * There is a bug in tlink that makes it process self relative
1179 * fixups incorrectly if the x_size doesn't match the location
1180 * size.
1182 forp = obj_force(forp, bytes << 3);
1185 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1187 tidx = fidx = -1, method = 0; /* placate optimisers */
1190 * See if we can find the segment ID in our segment list. If
1191 * so, we have a T4 (LSEG) target.
1193 for (s = seghead; s; s = s->next)
1194 if (s->index == seg)
1195 break;
1196 if (s)
1197 method = 4, tidx = s->obj_index;
1198 else {
1199 for (g = grphead; g; g = g->next)
1200 if (g->index == seg)
1201 break;
1202 if (g)
1203 method = 5, tidx = g->obj_index;
1204 else {
1205 int32_t i = seg / 2;
1206 struct ExtBack *eb = ebhead;
1207 while (i >= EXT_BLKSIZ) {
1208 if (eb)
1209 eb = eb->next;
1210 else
1211 break;
1212 i -= EXT_BLKSIZ;
1214 if (eb)
1215 method = 6, e = eb->exts[i], tidx = e->index;
1216 else
1217 error(ERR_PANIC,
1218 "unrecognised segment value in obj_write_fixup");
1223 * If no WRT given, assume the natural default, which is method
1224 * F5 unless:
1226 * - we are doing an OFFSET fixup for a grouped segment, in
1227 * which case we require F1 (group).
1229 * - we are doing an OFFSET fixup for an external with a
1230 * default WRT, in which case we must honour the default WRT.
1232 if (wrt == NO_SEG) {
1233 if (!base && s && s->grp)
1234 method |= 0x10, fidx = s->grp->obj_index;
1235 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1236 if (e->defwrt_type == DEFWRT_SEGMENT)
1237 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1238 else if (e->defwrt_type == DEFWRT_GROUP)
1239 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1240 else {
1241 error(ERR_NONFATAL, "default WRT specification for"
1242 " external `%s' unresolved", e->name);
1243 method |= 0x50, fidx = -1; /* got to do _something_ */
1245 } else
1246 method |= 0x50, fidx = -1;
1247 } else {
1249 * See if we can find the WRT-segment ID in our segment
1250 * list. If so, we have a F0 (LSEG) frame.
1252 for (s = seghead; s; s = s->next)
1253 if (s->index == wrt - 1)
1254 break;
1255 if (s)
1256 method |= 0x00, fidx = s->obj_index;
1257 else {
1258 for (g = grphead; g; g = g->next)
1259 if (g->index == wrt - 1)
1260 break;
1261 if (g)
1262 method |= 0x10, fidx = g->obj_index;
1263 else {
1264 int32_t i = wrt / 2;
1265 struct ExtBack *eb = ebhead;
1266 while (i >= EXT_BLKSIZ) {
1267 if (eb)
1268 eb = eb->next;
1269 else
1270 break;
1271 i -= EXT_BLKSIZ;
1273 if (eb)
1274 method |= 0x20, fidx = eb->exts[i]->index;
1275 else
1276 error(ERR_PANIC,
1277 "unrecognised WRT value in obj_write_fixup");
1282 forp = obj_byte(forp, method);
1283 if (fidx != -1)
1284 forp = obj_index(forp, fidx);
1285 forp = obj_index(forp, tidx);
1286 obj_commit(forp);
1289 static int32_t obj_segment(char *name, int pass, int *bits)
1292 * We call the label manager here to define a name for the new
1293 * segment, and when our _own_ label-definition stub gets
1294 * called in return, it should register the new segment name
1295 * using the pointer it gets passed. That way we save memory,
1296 * by sponging off the label manager.
1298 #if defined(DEBUG) && DEBUG>=3
1299 fprintf(stderr, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1300 name, pass, *bits);
1301 #endif
1302 if (!name) {
1303 *bits = 16;
1304 current_seg = NULL;
1305 return first_seg;
1306 } else {
1307 struct Segment *seg;
1308 struct Group *grp;
1309 struct External **extp;
1310 int obj_idx, i, attrs;
1311 bool rn_error;
1312 char *p;
1315 * Look for segment attributes.
1317 attrs = 0;
1318 while (*name == '.')
1319 name++; /* hack, but a documented one */
1320 p = name;
1321 while (*p && !nasm_isspace(*p))
1322 p++;
1323 if (*p) {
1324 *p++ = '\0';
1325 while (*p && nasm_isspace(*p))
1326 *p++ = '\0';
1328 while (*p) {
1329 while (*p && !nasm_isspace(*p))
1330 p++;
1331 if (*p) {
1332 *p++ = '\0';
1333 while (*p && nasm_isspace(*p))
1334 *p++ = '\0';
1337 attrs++;
1340 obj_idx = 1;
1341 for (seg = seghead; seg; seg = seg->next) {
1342 obj_idx++;
1343 if (!strcmp(seg->name, name)) {
1344 if (attrs > 0 && pass == 1)
1345 error(ERR_WARNING, "segment attributes specified on"
1346 " redeclaration of segment: ignoring");
1347 if (seg->use32)
1348 *bits = 32;
1349 else
1350 *bits = 16;
1351 current_seg = seg;
1352 return seg->index;
1356 *segtail = seg = nasm_malloc(sizeof(*seg));
1357 seg->next = NULL;
1358 segtail = &seg->next;
1359 seg->index = (any_segs ? seg_alloc() : first_seg);
1360 seg->obj_index = obj_idx;
1361 seg->grp = NULL;
1362 any_segs = true;
1363 seg->name = NULL;
1364 seg->currentpos = 0;
1365 seg->align = 1; /* default */
1366 seg->use32 = false; /* default */
1367 seg->combine = CMB_PUBLIC; /* default */
1368 seg->segclass = seg->overlay = NULL;
1369 seg->pubhead = NULL;
1370 seg->pubtail = &seg->pubhead;
1371 seg->lochead = NULL;
1372 seg->loctail = &seg->lochead;
1373 seg->orp = obj_new();
1374 seg->orp->up = &(seg->orp);
1375 seg->orp->ori = ori_ledata;
1376 seg->orp->type = LEDATA;
1377 seg->orp->parm[1] = obj_idx;
1380 * Process the segment attributes.
1382 p = name;
1383 while (attrs--) {
1384 p += strlen(p);
1385 while (!*p)
1386 p++;
1389 * `p' contains a segment attribute.
1391 if (!nasm_stricmp(p, "private"))
1392 seg->combine = CMB_PRIVATE;
1393 else if (!nasm_stricmp(p, "public"))
1394 seg->combine = CMB_PUBLIC;
1395 else if (!nasm_stricmp(p, "common"))
1396 seg->combine = CMB_COMMON;
1397 else if (!nasm_stricmp(p, "stack"))
1398 seg->combine = CMB_STACK;
1399 else if (!nasm_stricmp(p, "use16"))
1400 seg->use32 = false;
1401 else if (!nasm_stricmp(p, "use32"))
1402 seg->use32 = true;
1403 else if (!nasm_stricmp(p, "flat")) {
1405 * This segment is an OS/2 FLAT segment. That means
1406 * that its default group is group FLAT, even if
1407 * the group FLAT does not explicitly _contain_ the
1408 * segment.
1410 * When we see this, we must create the group
1411 * `FLAT', containing no segments, if it does not
1412 * already exist; then we must set the default
1413 * group of this segment to be the FLAT group.
1415 struct Group *grp;
1416 for (grp = grphead; grp; grp = grp->next)
1417 if (!strcmp(grp->name, "FLAT"))
1418 break;
1419 if (!grp) {
1420 obj_directive("group", "FLAT", 1);
1421 for (grp = grphead; grp; grp = grp->next)
1422 if (!strcmp(grp->name, "FLAT"))
1423 break;
1424 if (!grp)
1425 error(ERR_PANIC, "failure to define FLAT?!");
1427 seg->grp = grp;
1428 } else if (!nasm_strnicmp(p, "class=", 6))
1429 seg->segclass = nasm_strdup(p + 6);
1430 else if (!nasm_strnicmp(p, "overlay=", 8))
1431 seg->overlay = nasm_strdup(p + 8);
1432 else if (!nasm_strnicmp(p, "align=", 6)) {
1433 seg->align = readnum(p + 6, &rn_error);
1434 if (rn_error) {
1435 seg->align = 1;
1436 error(ERR_NONFATAL, "segment alignment should be"
1437 " numeric");
1439 switch ((int)seg->align) {
1440 case 1: /* BYTE */
1441 case 2: /* WORD */
1442 case 4: /* DWORD */
1443 case 16: /* PARA */
1444 case 256: /* PAGE */
1445 case 4096: /* PharLap extension */
1446 break;
1447 case 8:
1448 error(ERR_WARNING,
1449 "OBJ format does not support alignment"
1450 " of 8: rounding up to 16");
1451 seg->align = 16;
1452 break;
1453 case 32:
1454 case 64:
1455 case 128:
1456 error(ERR_WARNING,
1457 "OBJ format does not support alignment"
1458 " of %d: rounding up to 256", seg->align);
1459 seg->align = 256;
1460 break;
1461 case 512:
1462 case 1024:
1463 case 2048:
1464 error(ERR_WARNING,
1465 "OBJ format does not support alignment"
1466 " of %d: rounding up to 4096", seg->align);
1467 seg->align = 4096;
1468 break;
1469 default:
1470 error(ERR_NONFATAL, "invalid alignment value %d",
1471 seg->align);
1472 seg->align = 1;
1473 break;
1475 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1476 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1477 if (rn_error)
1478 error(ERR_NONFATAL, "argument to `absolute' segment"
1479 " attribute should be numeric");
1483 /* We need to know whenever we have at least one 32-bit segment */
1484 obj_use32 |= seg->use32;
1486 obj_seg_needs_update = seg;
1487 if (seg->align >= SEG_ABS)
1488 deflabel(name, NO_SEG, seg->align - SEG_ABS,
1489 NULL, false, false, &of_obj, error);
1490 else
1491 deflabel(name, seg->index + 1, 0L,
1492 NULL, false, false, &of_obj, error);
1493 obj_seg_needs_update = NULL;
1496 * See if this segment is defined in any groups.
1498 for (grp = grphead; grp; grp = grp->next) {
1499 for (i = grp->nindices; i < grp->nentries; i++) {
1500 if (!strcmp(grp->segs[i].name, seg->name)) {
1501 nasm_free(grp->segs[i].name);
1502 grp->segs[i] = grp->segs[grp->nindices];
1503 grp->segs[grp->nindices++].index = seg->obj_index;
1504 if (seg->grp)
1505 error(ERR_WARNING,
1506 "segment `%s' is already part of"
1507 " a group: first one takes precedence",
1508 seg->name);
1509 else
1510 seg->grp = grp;
1516 * Walk through the list of externals with unresolved
1517 * default-WRT clauses, and resolve any that point at this
1518 * segment.
1520 extp = &dws;
1521 while (*extp) {
1522 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1523 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1524 nasm_free((*extp)->defwrt_ptr.string);
1525 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1526 (*extp)->defwrt_ptr.seg = seg;
1527 *extp = (*extp)->next_dws;
1528 } else
1529 extp = &(*extp)->next_dws;
1532 if (seg->use32)
1533 *bits = 32;
1534 else
1535 *bits = 16;
1536 current_seg = seg;
1537 return seg->index;
1541 static int obj_directive(char *directive, char *value, int pass)
1543 if (!strcmp(directive, "group")) {
1544 char *p, *q, *v;
1545 if (pass == 1) {
1546 struct Group *grp;
1547 struct Segment *seg;
1548 struct External **extp;
1549 int obj_idx;
1551 q = value;
1552 while (*q == '.')
1553 q++; /* hack, but a documented one */
1554 v = q;
1555 while (*q && !nasm_isspace(*q))
1556 q++;
1557 if (nasm_isspace(*q)) {
1558 *q++ = '\0';
1559 while (*q && nasm_isspace(*q))
1560 q++;
1563 * Here we used to sanity-check the group directive to
1564 * ensure nobody tried to declare a group containing no
1565 * segments. However, OS/2 does this as standard
1566 * practice, so the sanity check has been removed.
1568 * if (!*q) {
1569 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1570 * return 1;
1574 obj_idx = 1;
1575 for (grp = grphead; grp; grp = grp->next) {
1576 obj_idx++;
1577 if (!strcmp(grp->name, v)) {
1578 error(ERR_NONFATAL, "group `%s' defined twice", v);
1579 return 1;
1583 *grptail = grp = nasm_malloc(sizeof(*grp));
1584 grp->next = NULL;
1585 grptail = &grp->next;
1586 grp->index = seg_alloc();
1587 grp->obj_index = obj_idx;
1588 grp->nindices = grp->nentries = 0;
1589 grp->name = NULL;
1591 obj_grp_needs_update = grp;
1592 deflabel(v, grp->index + 1, 0L,
1593 NULL, false, false, &of_obj, error);
1594 obj_grp_needs_update = NULL;
1596 while (*q) {
1597 p = q;
1598 while (*q && !nasm_isspace(*q))
1599 q++;
1600 if (nasm_isspace(*q)) {
1601 *q++ = '\0';
1602 while (*q && nasm_isspace(*q))
1603 q++;
1606 * Now p contains a segment name. Find it.
1608 for (seg = seghead; seg; seg = seg->next)
1609 if (!strcmp(seg->name, p))
1610 break;
1611 if (seg) {
1613 * We have a segment index. Shift a name entry
1614 * to the end of the array to make room.
1616 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1617 grp->segs[grp->nindices++].index = seg->obj_index;
1618 if (seg->grp)
1619 error(ERR_WARNING,
1620 "segment `%s' is already part of"
1621 " a group: first one takes precedence",
1622 seg->name);
1623 else
1624 seg->grp = grp;
1625 } else {
1627 * We have an as-yet undefined segment.
1628 * Remember its name, for later.
1630 grp->segs[grp->nentries++].name = nasm_strdup(p);
1635 * Walk through the list of externals with unresolved
1636 * default-WRT clauses, and resolve any that point at
1637 * this group.
1639 extp = &dws;
1640 while (*extp) {
1641 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1642 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1643 nasm_free((*extp)->defwrt_ptr.string);
1644 (*extp)->defwrt_type = DEFWRT_GROUP;
1645 (*extp)->defwrt_ptr.grp = grp;
1646 *extp = (*extp)->next_dws;
1647 } else
1648 extp = &(*extp)->next_dws;
1651 return 1;
1653 if (!strcmp(directive, "uppercase")) {
1654 obj_uppercase = true;
1655 return 1;
1657 if (!strcmp(directive, "import")) {
1658 char *q, *extname, *libname, *impname;
1660 if (pass == 2)
1661 return 1; /* ignore in pass two */
1662 extname = q = value;
1663 while (*q && !nasm_isspace(*q))
1664 q++;
1665 if (nasm_isspace(*q)) {
1666 *q++ = '\0';
1667 while (*q && nasm_isspace(*q))
1668 q++;
1671 libname = q;
1672 while (*q && !nasm_isspace(*q))
1673 q++;
1674 if (nasm_isspace(*q)) {
1675 *q++ = '\0';
1676 while (*q && nasm_isspace(*q))
1677 q++;
1680 impname = q;
1682 if (!*extname || !*libname)
1683 error(ERR_NONFATAL, "`import' directive requires symbol name"
1684 " and library name");
1685 else {
1686 struct ImpDef *imp;
1687 bool err = false;
1689 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1690 imptail = &imp->next;
1691 imp->next = NULL;
1692 imp->extname = nasm_strdup(extname);
1693 imp->libname = nasm_strdup(libname);
1694 imp->impindex = readnum(impname, &err);
1695 if (!*impname || err)
1696 imp->impname = nasm_strdup(impname);
1697 else
1698 imp->impname = NULL;
1701 return 1;
1703 if (!strcmp(directive, "export")) {
1704 char *q, *extname, *intname, *v;
1705 struct ExpDef *export;
1706 int flags = 0;
1707 unsigned int ordinal = 0;
1709 if (pass == 2)
1710 return 1; /* ignore in pass two */
1711 intname = q = value;
1712 while (*q && !nasm_isspace(*q))
1713 q++;
1714 if (nasm_isspace(*q)) {
1715 *q++ = '\0';
1716 while (*q && nasm_isspace(*q))
1717 q++;
1720 extname = q;
1721 while (*q && !nasm_isspace(*q))
1722 q++;
1723 if (nasm_isspace(*q)) {
1724 *q++ = '\0';
1725 while (*q && nasm_isspace(*q))
1726 q++;
1729 if (!*intname) {
1730 error(ERR_NONFATAL, "`export' directive requires export name");
1731 return 1;
1733 if (!*extname) {
1734 extname = intname;
1735 intname = "";
1737 while (*q) {
1738 v = q;
1739 while (*q && !nasm_isspace(*q))
1740 q++;
1741 if (nasm_isspace(*q)) {
1742 *q++ = '\0';
1743 while (*q && nasm_isspace(*q))
1744 q++;
1746 if (!nasm_stricmp(v, "resident"))
1747 flags |= EXPDEF_FLAG_RESIDENT;
1748 else if (!nasm_stricmp(v, "nodata"))
1749 flags |= EXPDEF_FLAG_NODATA;
1750 else if (!nasm_strnicmp(v, "parm=", 5)) {
1751 bool err = false;
1752 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1753 if (err) {
1754 error(ERR_NONFATAL,
1755 "value `%s' for `parm' is non-numeric", v + 5);
1756 return 1;
1758 } else {
1759 bool err = false;
1760 ordinal = readnum(v, &err);
1761 if (err) {
1762 error(ERR_NONFATAL,
1763 "unrecognised export qualifier `%s'", v);
1764 return 1;
1766 flags |= EXPDEF_FLAG_ORDINAL;
1770 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1771 exptail = &export->next;
1772 export->next = NULL;
1773 export->extname = nasm_strdup(extname);
1774 export->intname = nasm_strdup(intname);
1775 export->ordinal = ordinal;
1776 export->flags = flags;
1778 return 1;
1780 return 0;
1783 static int32_t obj_segbase(int32_t segment)
1785 struct Segment *seg;
1788 * Find the segment in our list.
1790 for (seg = seghead; seg; seg = seg->next)
1791 if (seg->index == segment - 1)
1792 break;
1794 if (!seg) {
1796 * Might be an external with a default WRT.
1798 int32_t i = segment / 2;
1799 struct ExtBack *eb = ebhead;
1800 struct External *e;
1802 while (i >= EXT_BLKSIZ) {
1803 if (eb)
1804 eb = eb->next;
1805 else
1806 break;
1807 i -= EXT_BLKSIZ;
1809 if (eb) {
1810 e = eb->exts[i];
1811 if (!e) {
1812 nasm_assert(pass0 == 0);
1813 /* Not available - can happen during optimization */
1814 return NO_SEG;
1817 switch (e->defwrt_type) {
1818 case DEFWRT_NONE:
1819 return segment; /* fine */
1820 case DEFWRT_SEGMENT:
1821 return e->defwrt_ptr.seg->index + 1;
1822 case DEFWRT_GROUP:
1823 return e->defwrt_ptr.grp->index + 1;
1824 default:
1825 return NO_SEG; /* can't tell what it is */
1829 return segment; /* not one of ours - leave it alone */
1832 if (seg->align >= SEG_ABS)
1833 return seg->align; /* absolute segment */
1834 if (seg->grp)
1835 return seg->grp->index + 1; /* grouped segment */
1837 return segment; /* no special treatment */
1840 static void obj_filename(char *inname, char *outname, efunc lerror)
1842 strcpy(obj_infile, inname);
1843 standard_extension(inname, outname, ".obj", lerror);
1846 static void obj_write_file(int debuginfo)
1848 struct Segment *seg, *entry_seg_ptr = 0;
1849 struct FileName *fn;
1850 struct LineNumber *ln;
1851 struct Group *grp;
1852 struct Public *pub, *loc;
1853 struct External *ext;
1854 struct ImpDef *imp;
1855 struct ExpDef *export;
1856 int lname_idx;
1857 ObjRecord *orp;
1860 * Write the THEADR module header.
1862 orp = obj_new();
1863 orp->type = THEADR;
1864 obj_name(orp, obj_infile);
1865 obj_emit2(orp);
1868 * Write the NASM boast comment.
1870 orp->type = COMENT;
1871 obj_rword(orp, 0); /* comment type zero */
1872 obj_name(orp, nasm_comment);
1873 obj_emit2(orp);
1875 orp->type = COMENT;
1877 * Write the IMPDEF records, if any.
1879 for (imp = imphead; imp; imp = imp->next) {
1880 obj_rword(orp, 0xA0); /* comment class A0 */
1881 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1882 if (imp->impname)
1883 obj_byte(orp, 0); /* import by name */
1884 else
1885 obj_byte(orp, 1); /* import by ordinal */
1886 obj_name(orp, imp->extname);
1887 obj_name(orp, imp->libname);
1888 if (imp->impname)
1889 obj_name(orp, imp->impname);
1890 else
1891 obj_word(orp, imp->impindex);
1892 obj_emit2(orp);
1896 * Write the EXPDEF records, if any.
1898 for (export = exphead; export; export = export->next) {
1899 obj_rword(orp, 0xA0); /* comment class A0 */
1900 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1901 obj_byte(orp, export->flags);
1902 obj_name(orp, export->extname);
1903 obj_name(orp, export->intname);
1904 if (export->flags & EXPDEF_FLAG_ORDINAL)
1905 obj_word(orp, export->ordinal);
1906 obj_emit2(orp);
1909 /* we're using extended OMF if we put in debug info */
1910 if (debuginfo) {
1911 orp->type = COMENT;
1912 obj_byte(orp, 0x40);
1913 obj_byte(orp, dEXTENDED);
1914 obj_emit2(orp);
1918 * Write the first LNAMES record, containing LNAME one, which
1919 * is null. Also initialize the LNAME counter.
1921 orp->type = LNAMES;
1922 obj_byte(orp, 0);
1923 lname_idx = 1;
1925 * Write some LNAMES for the segment names
1927 for (seg = seghead; seg; seg = seg->next) {
1928 orp = obj_name(orp, seg->name);
1929 if (seg->segclass)
1930 orp = obj_name(orp, seg->segclass);
1931 if (seg->overlay)
1932 orp = obj_name(orp, seg->overlay);
1933 obj_commit(orp);
1936 * Write some LNAMES for the group names
1938 for (grp = grphead; grp; grp = grp->next) {
1939 orp = obj_name(orp, grp->name);
1940 obj_commit(orp);
1942 obj_emit(orp);
1945 * Write the SEGDEF records.
1947 orp->type = SEGDEF;
1948 for (seg = seghead; seg; seg = seg->next) {
1949 int acbp;
1950 uint32_t seglen = seg->currentpos;
1952 acbp = (seg->combine << 2); /* C field */
1954 if (seg->use32)
1955 acbp |= 0x01; /* P bit is Use32 flag */
1956 else if (seglen == 0x10000L) {
1957 seglen = 0; /* This special case may be needed for old linkers */
1958 acbp |= 0x02; /* B bit */
1961 /* A field */
1962 if (seg->align >= SEG_ABS)
1963 /* acbp |= 0x00 */ ;
1964 else if (seg->align >= 4096) {
1965 if (seg->align > 4096)
1966 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1967 " than OBJ format supports", seg->name);
1968 acbp |= 0xC0; /* PharLap extension */
1969 } else if (seg->align >= 256) {
1970 acbp |= 0x80;
1971 } else if (seg->align >= 16) {
1972 acbp |= 0x60;
1973 } else if (seg->align >= 4) {
1974 acbp |= 0xA0;
1975 } else if (seg->align >= 2) {
1976 acbp |= 0x40;
1977 } else
1978 acbp |= 0x20;
1980 obj_byte(orp, acbp);
1981 if (seg->align & SEG_ABS) {
1982 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1983 obj_byte(orp, 0); /* Offset */
1985 obj_x(orp, seglen);
1986 obj_index(orp, ++lname_idx);
1987 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1988 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1989 obj_emit2(orp);
1993 * Write the GRPDEF records.
1995 orp->type = GRPDEF;
1996 for (grp = grphead; grp; grp = grp->next) {
1997 int i;
1999 if (grp->nindices != grp->nentries) {
2000 for (i = grp->nindices; i < grp->nentries; i++) {
2001 error(ERR_NONFATAL, "group `%s' contains undefined segment"
2002 " `%s'", grp->name, grp->segs[i].name);
2003 nasm_free(grp->segs[i].name);
2004 grp->segs[i].name = NULL;
2007 obj_index(orp, ++lname_idx);
2008 for (i = 0; i < grp->nindices; i++) {
2009 obj_byte(orp, 0xFF);
2010 obj_index(orp, grp->segs[i].index);
2012 obj_emit2(orp);
2016 * Write the PUBDEF records: first the ones in the segments,
2017 * then the far-absolutes.
2019 orp->type = PUBDEF;
2020 orp->ori = ori_pubdef;
2021 for (seg = seghead; seg; seg = seg->next) {
2022 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2023 orp->parm[1] = seg->obj_index;
2024 for (pub = seg->pubhead; pub; pub = pub->next) {
2025 orp = obj_name(orp, pub->name);
2026 orp = obj_x(orp, pub->offset);
2027 orp = obj_byte(orp, 0); /* type index */
2028 obj_commit(orp);
2030 obj_emit(orp);
2032 orp->parm[0] = 0;
2033 orp->parm[1] = 0;
2034 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2035 if (orp->parm[2] != (uint32_t)pub->segment) {
2036 obj_emit(orp);
2037 orp->parm[2] = pub->segment;
2039 orp = obj_name(orp, pub->name);
2040 orp = obj_x(orp, pub->offset);
2041 orp = obj_byte(orp, 0); /* type index */
2042 obj_commit(orp);
2044 obj_emit(orp);
2047 * Write the EXTDEF and COMDEF records, in order.
2049 orp->ori = ori_null;
2050 for (ext = exthead; ext; ext = ext->next) {
2051 if (ext->commonsize == 0) {
2052 if (orp->type != EXTDEF) {
2053 obj_emit(orp);
2054 orp->type = EXTDEF;
2056 orp = obj_name(orp, ext->name);
2057 orp = obj_index(orp, 0);
2058 } else {
2059 if (orp->type != COMDEF) {
2060 obj_emit(orp);
2061 orp->type = COMDEF;
2063 orp = obj_name(orp, ext->name);
2064 orp = obj_index(orp, 0);
2065 if (ext->commonelem) {
2066 orp = obj_byte(orp, 0x61); /* far communal */
2067 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2068 orp = obj_value(orp, ext->commonelem);
2069 } else {
2070 orp = obj_byte(orp, 0x62); /* near communal */
2071 orp = obj_value(orp, ext->commonsize);
2074 obj_commit(orp);
2076 obj_emit(orp);
2079 * Write a COMENT record stating that the linker's first pass
2080 * may stop processing at this point. Exception is if our
2081 * MODEND record specifies a start point, in which case,
2082 * according to some variants of the documentation, this COMENT
2083 * should be omitted. So we'll omit it just in case.
2084 * But, TASM puts it in all the time so if we are using
2085 * TASM debug stuff we are putting it in
2087 if (debuginfo || obj_entry_seg == NO_SEG) {
2088 orp->type = COMENT;
2089 obj_byte(orp, 0x40);
2090 obj_byte(orp, dLINKPASS);
2091 obj_byte(orp, 1);
2092 obj_emit2(orp);
2096 * 1) put out the compiler type
2097 * 2) Put out the type info. The only type we are using is near label #19
2099 if (debuginfo) {
2100 int i;
2101 struct Array *arrtmp = arrhead;
2102 orp->type = COMENT;
2103 obj_byte(orp, 0x40);
2104 obj_byte(orp, dCOMPDEF);
2105 obj_byte(orp, 4);
2106 obj_byte(orp, 0);
2107 obj_emit2(orp);
2109 obj_byte(orp, 0x40);
2110 obj_byte(orp, dTYPEDEF);
2111 obj_word(orp, 0x18); /* type # for linking */
2112 obj_word(orp, 6); /* size of type */
2113 obj_byte(orp, 0x2a); /* absolute type for debugging */
2114 obj_emit2(orp);
2115 obj_byte(orp, 0x40);
2116 obj_byte(orp, dTYPEDEF);
2117 obj_word(orp, 0x19); /* type # for linking */
2118 obj_word(orp, 0); /* size of type */
2119 obj_byte(orp, 0x24); /* absolute type for debugging */
2120 obj_byte(orp, 0); /* near/far specifier */
2121 obj_emit2(orp);
2122 obj_byte(orp, 0x40);
2123 obj_byte(orp, dTYPEDEF);
2124 obj_word(orp, 0x1A); /* type # for linking */
2125 obj_word(orp, 0); /* size of type */
2126 obj_byte(orp, 0x24); /* absolute type for debugging */
2127 obj_byte(orp, 1); /* near/far specifier */
2128 obj_emit2(orp);
2129 obj_byte(orp, 0x40);
2130 obj_byte(orp, dTYPEDEF);
2131 obj_word(orp, 0x1b); /* type # for linking */
2132 obj_word(orp, 0); /* size of type */
2133 obj_byte(orp, 0x23); /* absolute type for debugging */
2134 obj_byte(orp, 0);
2135 obj_byte(orp, 0);
2136 obj_byte(orp, 0);
2137 obj_emit2(orp);
2138 obj_byte(orp, 0x40);
2139 obj_byte(orp, dTYPEDEF);
2140 obj_word(orp, 0x1c); /* type # for linking */
2141 obj_word(orp, 0); /* size of type */
2142 obj_byte(orp, 0x23); /* absolute type for debugging */
2143 obj_byte(orp, 0);
2144 obj_byte(orp, 4);
2145 obj_byte(orp, 0);
2146 obj_emit2(orp);
2147 obj_byte(orp, 0x40);
2148 obj_byte(orp, dTYPEDEF);
2149 obj_word(orp, 0x1d); /* type # for linking */
2150 obj_word(orp, 0); /* size of type */
2151 obj_byte(orp, 0x23); /* absolute type for debugging */
2152 obj_byte(orp, 0);
2153 obj_byte(orp, 1);
2154 obj_byte(orp, 0);
2155 obj_emit2(orp);
2156 obj_byte(orp, 0x40);
2157 obj_byte(orp, dTYPEDEF);
2158 obj_word(orp, 0x1e); /* type # for linking */
2159 obj_word(orp, 0); /* size of type */
2160 obj_byte(orp, 0x23); /* absolute type for debugging */
2161 obj_byte(orp, 0);
2162 obj_byte(orp, 5);
2163 obj_byte(orp, 0);
2164 obj_emit2(orp);
2166 /* put out the array types */
2167 for (i = ARRAYBOT; i < arrindex; i++) {
2168 obj_byte(orp, 0x40);
2169 obj_byte(orp, dTYPEDEF);
2170 obj_word(orp, i); /* type # for linking */
2171 obj_word(orp, arrtmp->size); /* size of type */
2172 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2173 obj_byte(orp, arrtmp->basetype); /* base type */
2174 obj_emit2(orp);
2175 arrtmp = arrtmp->next;
2179 * write out line number info with a LINNUM record
2180 * switch records when we switch segments, and output the
2181 * file in a pseudo-TASM fashion. The record switch is naive; that
2182 * is that one file may have many records for the same segment
2183 * if there are lots of segment switches
2185 if (fnhead && debuginfo) {
2186 seg = fnhead->lnhead->segment;
2188 for (fn = fnhead; fn; fn = fn->next) {
2189 /* write out current file name */
2190 orp->type = COMENT;
2191 orp->ori = ori_null;
2192 obj_byte(orp, 0x40);
2193 obj_byte(orp, dFILNAME);
2194 obj_byte(orp, 0);
2195 obj_name(orp, fn->name);
2196 obj_dword(orp, 0);
2197 obj_emit2(orp);
2199 /* write out line numbers this file */
2201 orp->type = LINNUM;
2202 orp->ori = ori_linnum;
2203 for (ln = fn->lnhead; ln; ln = ln->next) {
2204 if (seg != ln->segment) {
2205 /* if we get here have to flush the buffer and start
2206 * a new record for a new segment
2208 seg = ln->segment;
2209 obj_emit(orp);
2211 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2212 orp->parm[1] = seg->obj_index;
2213 orp = obj_word(orp, ln->lineno);
2214 orp = obj_x(orp, ln->offset);
2215 obj_commit(orp);
2217 obj_emit(orp);
2221 * we are going to locate the entry point segment now
2222 * rather than wait until the MODEND record, because,
2223 * then we can output a special symbol to tell where the
2224 * entry point is.
2227 if (obj_entry_seg != NO_SEG) {
2228 for (seg = seghead; seg; seg = seg->next) {
2229 if (seg->index == obj_entry_seg) {
2230 entry_seg_ptr = seg;
2231 break;
2234 if (!seg)
2235 error(ERR_NONFATAL, "entry point is not in this module");
2239 * get ready to put out symbol records
2241 orp->type = COMENT;
2242 orp->ori = ori_local;
2245 * put out a symbol for the entry point
2246 * no dots in this symbol, because, borland does
2247 * not (officially) support dots in label names
2248 * and I don't know what various versions of TLINK will do
2250 if (debuginfo && obj_entry_seg != NO_SEG) {
2251 orp = obj_name(orp, "start_of_program");
2252 orp = obj_word(orp, 0x19); /* type: near label */
2253 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2254 orp = obj_index(orp, seg->obj_index);
2255 orp = obj_x(orp, obj_entry_ofs);
2256 obj_commit(orp);
2260 * put out the local labels
2262 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2263 /* labels this seg */
2264 for (loc = seg->lochead; loc; loc = loc->next) {
2265 orp = obj_name(orp, loc->name);
2266 orp = obj_word(orp, loc->type);
2267 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2268 orp = obj_index(orp, seg->obj_index);
2269 orp = obj_x(orp, loc->offset);
2270 obj_commit(orp);
2273 if (orp->used)
2274 obj_emit(orp);
2277 * Write the LEDATA/FIXUPP pairs.
2279 for (seg = seghead; seg; seg = seg->next) {
2280 obj_emit(seg->orp);
2281 nasm_free(seg->orp);
2285 * Write the MODEND module end marker.
2287 orp->type = obj_use32 ? MODE32 : MODEND;
2288 orp->ori = ori_null;
2289 if (entry_seg_ptr) {
2290 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2291 obj_byte(orp, 0xC1);
2292 seg = entry_seg_ptr;
2293 if (seg->grp) {
2294 obj_byte(orp, 0x10);
2295 obj_index(orp, seg->grp->obj_index);
2296 } else {
2298 * the below changed to prevent TLINK crashing.
2299 * Previous more efficient version read:
2301 * obj_byte (orp, 0x50);
2303 obj_byte(orp, 0x00);
2304 obj_index(orp, seg->obj_index);
2306 obj_index(orp, seg->obj_index);
2307 obj_x(orp, obj_entry_ofs);
2308 } else
2309 obj_byte(orp, 0);
2310 obj_emit2(orp);
2311 nasm_free(orp);
2314 static void obj_fwrite(ObjRecord * orp)
2316 unsigned int cksum, len;
2317 uint8_t *ptr;
2319 cksum = orp->type;
2320 if (orp->x_size == 32)
2321 cksum |= 1;
2322 fputc(cksum, ofp);
2323 len = orp->committed + 1;
2324 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2325 fwriteint16_t(len, ofp);
2326 fwrite(orp->buf, 1, len - 1, ofp);
2327 for (ptr = orp->buf; --len; ptr++)
2328 cksum += *ptr;
2329 fputc((-cksum) & 0xFF, ofp);
2332 extern macros_t obj_stdmac[];
2334 void dbgbi_init(struct ofmt *of, void *id, FILE * fp, efunc error)
2336 (void)of;
2337 (void)id;
2338 (void)fp;
2339 (void)error;
2341 fnhead = NULL;
2342 fntail = &fnhead;
2343 arrindex = ARRAYBOT;
2344 arrhead = NULL;
2345 arrtail = &arrhead;
2347 static void dbgbi_cleanup(void)
2349 struct Segment *segtmp;
2350 while (fnhead) {
2351 struct FileName *fntemp = fnhead;
2352 while (fnhead->lnhead) {
2353 struct LineNumber *lntemp = fnhead->lnhead;
2354 fnhead->lnhead = lntemp->next;
2355 nasm_free(lntemp);
2357 fnhead = fnhead->next;
2358 nasm_free(fntemp->name);
2359 nasm_free(fntemp);
2361 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2362 while (segtmp->lochead) {
2363 struct Public *loctmp = segtmp->lochead;
2364 segtmp->lochead = loctmp->next;
2365 nasm_free(loctmp->name);
2366 nasm_free(loctmp);
2369 while (arrhead) {
2370 struct Array *arrtmp = arrhead;
2371 arrhead = arrhead->next;
2372 nasm_free(arrtmp);
2376 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2378 struct FileName *fn;
2379 struct LineNumber *ln;
2380 struct Segment *seg;
2382 if (segto == NO_SEG)
2383 return;
2386 * If `any_segs' is still false, we must define a default
2387 * segment.
2389 if (!any_segs) {
2390 int tempint; /* ignored */
2391 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2392 error(ERR_PANIC, "strange segment conditions in OBJ driver");
2396 * Find the segment we are targetting.
2398 for (seg = seghead; seg; seg = seg->next)
2399 if (seg->index == segto)
2400 break;
2401 if (!seg)
2402 error(ERR_PANIC, "lineno directed to nonexistent segment?");
2404 /* for (fn = fnhead; fn; fn = fnhead->next) */
2405 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2406 if (!nasm_stricmp(lnfname, fn->name))
2407 break;
2408 if (!fn) {
2409 fn = nasm_malloc(sizeof(*fn));
2410 fn->name = nasm_malloc(strlen(lnfname) + 1);
2411 strcpy(fn->name, lnfname);
2412 fn->lnhead = NULL;
2413 fn->lntail = &fn->lnhead;
2414 fn->next = NULL;
2415 *fntail = fn;
2416 fntail = &fn->next;
2418 ln = nasm_malloc(sizeof(*ln));
2419 ln->segment = seg;
2420 ln->offset = seg->currentpos;
2421 ln->lineno = lineno;
2422 ln->next = NULL;
2423 *fn->lntail = ln;
2424 fn->lntail = &ln->next;
2427 static void dbgbi_deflabel(char *name, int32_t segment,
2428 int64_t offset, int is_global, char *special)
2430 struct Segment *seg;
2432 (void)special;
2435 * If it's a special-retry from pass two, discard it.
2437 if (is_global == 3)
2438 return;
2441 * First check for the double-period, signifying something
2442 * unusual.
2444 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2445 return;
2449 * Case (i):
2451 if (obj_seg_needs_update) {
2452 return;
2453 } else if (obj_grp_needs_update) {
2454 return;
2456 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2457 return;
2459 if (segment >= SEG_ABS || segment == NO_SEG) {
2460 return;
2464 * If `any_segs' is still false, we might need to define a
2465 * default segment, if they're trying to declare a label in
2466 * `first_seg'. But the label should exist due to a prior
2467 * call to obj_deflabel so we can skip that.
2470 for (seg = seghead; seg; seg = seg->next)
2471 if (seg->index == segment) {
2472 struct Public *loc = nasm_malloc(sizeof(*loc));
2474 * Case (ii). Maybe MODPUB someday?
2476 last_defined = *seg->loctail = loc;
2477 seg->loctail = &loc->next;
2478 loc->next = NULL;
2479 loc->name = nasm_strdup(name);
2480 loc->offset = offset;
2483 static void dbgbi_typevalue(int32_t type)
2485 int vsize;
2486 int elem = TYM_ELEMENTS(type);
2487 type = TYM_TYPE(type);
2489 if (!last_defined)
2490 return;
2492 switch (type) {
2493 case TY_BYTE:
2494 last_defined->type = 8; /* uint8_t */
2495 vsize = 1;
2496 break;
2497 case TY_WORD:
2498 last_defined->type = 10; /* unsigned word */
2499 vsize = 2;
2500 break;
2501 case TY_DWORD:
2502 last_defined->type = 12; /* unsigned dword */
2503 vsize = 4;
2504 break;
2505 case TY_FLOAT:
2506 last_defined->type = 14; /* float */
2507 vsize = 4;
2508 break;
2509 case TY_QWORD:
2510 last_defined->type = 15; /* qword */
2511 vsize = 8;
2512 break;
2513 case TY_TBYTE:
2514 last_defined->type = 16; /* TBYTE */
2515 vsize = 10;
2516 break;
2517 default:
2518 last_defined->type = 0x19; /*label */
2519 vsize = 0;
2520 break;
2523 if (elem > 1) {
2524 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2525 int vtype = last_defined->type;
2526 arrtmp->size = vsize * elem;
2527 arrtmp->basetype = vtype;
2528 arrtmp->next = NULL;
2529 last_defined->type = arrindex++;
2530 *arrtail = arrtmp;
2531 arrtail = &(arrtmp->next);
2533 last_defined = NULL;
2535 static void dbgbi_output(int output_type, void *param)
2537 (void)output_type;
2538 (void)param;
2540 static struct dfmt borland_debug_form = {
2541 "Borland Debug Records",
2542 "borland",
2543 dbgbi_init,
2544 dbgbi_linnum,
2545 dbgbi_deflabel,
2546 null_debug_routine,
2547 dbgbi_typevalue,
2548 dbgbi_output,
2549 dbgbi_cleanup,
2552 static struct dfmt *borland_debug_arr[3] = {
2553 &borland_debug_form,
2554 &null_debug_form,
2555 NULL
2558 struct ofmt of_obj = {
2559 "MS-DOS 16-bit/32-bit OMF object files",
2560 "obj",
2562 borland_debug_arr,
2563 &borland_debug_form,
2564 obj_stdmac,
2565 obj_init,
2566 obj_set_info,
2567 obj_out,
2568 obj_deflabel,
2569 obj_segment,
2570 obj_segbase,
2571 obj_directive,
2572 obj_filename,
2573 obj_cleanup
2575 #endif /* OF_OBJ */