quote: use nasm_assert() instead of plain assert()
[nasm.git] / output / outobj.c
blob7eb21cd788389012db1bfabd64ccbc9c073de6a5
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(enum directives, 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 while (seghead) {
681 struct Segment *segtmp = seghead;
682 seghead = seghead->next;
683 while (segtmp->pubhead) {
684 struct Public *pubtmp = segtmp->pubhead;
685 segtmp->pubhead = pubtmp->next;
686 nasm_free(pubtmp->name);
687 nasm_free(pubtmp);
689 nasm_free(segtmp->segclass);
690 nasm_free(segtmp->overlay);
691 nasm_free(segtmp);
693 while (fpubhead) {
694 struct Public *pubtmp = fpubhead;
695 fpubhead = fpubhead->next;
696 nasm_free(pubtmp->name);
697 nasm_free(pubtmp);
699 while (exthead) {
700 struct External *exttmp = exthead;
701 exthead = exthead->next;
702 nasm_free(exttmp);
704 while (imphead) {
705 struct ImpDef *imptmp = imphead;
706 imphead = imphead->next;
707 nasm_free(imptmp->extname);
708 nasm_free(imptmp->libname);
709 nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
710 nasm_free(imptmp);
712 while (exphead) {
713 struct ExpDef *exptmp = exphead;
714 exphead = exphead->next;
715 nasm_free(exptmp->extname);
716 nasm_free(exptmp->intname);
717 nasm_free(exptmp);
719 while (ebhead) {
720 struct ExtBack *ebtmp = ebhead;
721 ebhead = ebhead->next;
722 nasm_free(ebtmp);
724 while (grphead) {
725 struct Group *grptmp = grphead;
726 grphead = grphead->next;
727 nasm_free(grptmp);
731 static void obj_ext_set_defwrt(struct External *ext, char *id)
733 struct Segment *seg;
734 struct Group *grp;
736 for (seg = seghead; seg; seg = seg->next)
737 if (!strcmp(seg->name, id)) {
738 ext->defwrt_type = DEFWRT_SEGMENT;
739 ext->defwrt_ptr.seg = seg;
740 nasm_free(id);
741 return;
744 for (grp = grphead; grp; grp = grp->next)
745 if (!strcmp(grp->name, id)) {
746 ext->defwrt_type = DEFWRT_GROUP;
747 ext->defwrt_ptr.grp = grp;
748 nasm_free(id);
749 return;
752 ext->defwrt_type = DEFWRT_STRING;
753 ext->defwrt_ptr.string = id;
754 ext->next_dws = dws;
755 dws = ext;
758 static void obj_deflabel(char *name, int32_t segment,
759 int64_t offset, int is_global, char *special)
762 * We have three cases:
764 * (i) `segment' is a segment-base. If so, set the name field
765 * for the segment or group structure it refers to, and then
766 * return.
768 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
769 * Save the label position for later output of a PUBDEF record.
770 * (Or a MODPUB, if we work out how.)
772 * (iii) `segment' is not one of our segments. Save the label
773 * position for later output of an EXTDEF, and also store a
774 * back-reference so that we can map later references to this
775 * segment number to the external index.
777 struct External *ext;
778 struct ExtBack *eb;
779 struct Segment *seg;
780 int i;
781 bool used_special = false; /* have we used the special text? */
783 #if defined(DEBUG) && DEBUG>2
784 fprintf(stderr,
785 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
786 name, segment, offset, is_global, special);
787 #endif
790 * If it's a special-retry from pass two, discard it.
792 if (is_global == 3)
793 return;
796 * First check for the double-period, signifying something
797 * unusual.
799 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
800 if (!strcmp(name, "..start")) {
801 obj_entry_seg = segment;
802 obj_entry_ofs = offset;
803 return;
805 error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
809 * Case (i):
811 if (obj_seg_needs_update) {
812 obj_seg_needs_update->name = name;
813 return;
814 } else if (obj_grp_needs_update) {
815 obj_grp_needs_update->name = name;
816 return;
818 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
819 return;
821 if (segment >= SEG_ABS || segment == NO_SEG) {
823 * SEG_ABS subcase of (ii).
825 if (is_global) {
826 struct Public *pub;
828 pub = *fpubtail = nasm_malloc(sizeof(*pub));
829 fpubtail = &pub->next;
830 pub->next = NULL;
831 pub->name = nasm_strdup(name);
832 pub->offset = offset;
833 pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
835 if (special)
836 error(ERR_NONFATAL, "OBJ supports no special symbol features"
837 " for this symbol type");
838 return;
842 * If `any_segs' is still false, we might need to define a
843 * default segment, if they're trying to declare a label in
844 * `first_seg'.
846 if (!any_segs && segment == first_seg) {
847 int tempint; /* ignored */
848 if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
849 error(ERR_PANIC, "strange segment conditions in OBJ driver");
852 for (seg = seghead; seg && is_global; seg = seg->next)
853 if (seg->index == segment) {
854 struct Public *loc = nasm_malloc(sizeof(*loc));
856 * Case (ii). Maybe MODPUB someday?
858 *seg->pubtail = loc;
859 seg->pubtail = &loc->next;
860 loc->next = NULL;
861 loc->name = nasm_strdup(name);
862 loc->offset = offset;
864 if (special)
865 error(ERR_NONFATAL,
866 "OBJ supports no special symbol features"
867 " for this symbol type");
868 return;
872 * Case (iii).
874 if (is_global) {
875 ext = *exttail = nasm_malloc(sizeof(*ext));
876 ext->next = NULL;
877 exttail = &ext->next;
878 ext->name = name;
879 /* Place by default all externs into the current segment */
880 ext->defwrt_type = DEFWRT_NONE;
882 /* 28-Apr-2002 - John Coffman
883 The following code was introduced on 12-Aug-2000, and breaks fixups
884 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
885 (5.10). It was introduced after FIXUP32 was added, and may be needed
886 for 32-bit segments. The following will get 16-bit segments working
887 again, and maybe someone can correct the 'if' condition which is
888 actually needed.
890 #if 0
891 if (current_seg) {
892 #else
893 if (current_seg && current_seg->use32) {
894 if (current_seg->grp) {
895 ext->defwrt_type = DEFWRT_GROUP;
896 ext->defwrt_ptr.grp = current_seg->grp;
897 } else {
898 ext->defwrt_type = DEFWRT_SEGMENT;
899 ext->defwrt_ptr.seg = current_seg;
902 #endif
904 if (is_global == 2) {
905 ext->commonsize = offset;
906 ext->commonelem = 1; /* default FAR */
907 } else
908 ext->commonsize = 0;
909 } else
910 return;
913 * Now process the special text, if any, to find default-WRT
914 * specifications and common-variable element-size and near/far
915 * specifications.
917 while (special && *special) {
918 used_special = true;
921 * We might have a default-WRT specification.
923 if (!nasm_strnicmp(special, "wrt", 3)) {
924 char *p;
925 int len;
926 special += 3;
927 special += strspn(special, " \t");
928 p = nasm_strndup(special, len = strcspn(special, ":"));
929 obj_ext_set_defwrt(ext, p);
930 special += len;
931 if (*special && *special != ':')
932 error(ERR_NONFATAL, "`:' expected in special symbol"
933 " text for `%s'", ext->name);
934 else if (*special == ':')
935 special++;
939 * The NEAR or FAR keywords specify nearness or
940 * farness. FAR gives default element size 1.
942 if (!nasm_strnicmp(special, "far", 3)) {
943 if (ext->commonsize)
944 ext->commonelem = 1;
945 else
946 error(ERR_NONFATAL,
947 "`%s': `far' keyword may only be applied"
948 " to common variables\n", ext->name);
949 special += 3;
950 special += strspn(special, " \t");
951 } else if (!nasm_strnicmp(special, "near", 4)) {
952 if (ext->commonsize)
953 ext->commonelem = 0;
954 else
955 error(ERR_NONFATAL,
956 "`%s': `far' keyword may only be applied"
957 " to common variables\n", ext->name);
958 special += 4;
959 special += strspn(special, " \t");
963 * If it's a common, and anything else remains on the line
964 * before a further colon, evaluate it as an expression and
965 * use that as the element size. Forward references aren't
966 * allowed.
968 if (*special == ':')
969 special++;
970 else if (*special) {
971 if (ext->commonsize) {
972 expr *e;
973 struct tokenval tokval;
975 stdscan_reset();
976 stdscan_bufptr = special;
977 tokval.t_type = TOKEN_INVALID;
978 e = evaluate(stdscan, NULL, &tokval, NULL, 1, error, NULL);
979 if (e) {
980 if (!is_simple(e))
981 error(ERR_NONFATAL, "cannot use relocatable"
982 " expression as common-variable element size");
983 else
984 ext->commonelem = reloc_value(e);
986 special = stdscan_bufptr;
987 } else {
988 error(ERR_NONFATAL,
989 "`%s': element-size specifications only"
990 " apply to common variables", ext->name);
991 while (*special && *special != ':')
992 special++;
993 if (*special == ':')
994 special++;
999 i = segment / 2;
1000 eb = ebhead;
1001 if (!eb) {
1002 eb = *ebtail = nasm_malloc(sizeof(*eb));
1003 eb->next = NULL;
1004 ebtail = &eb->next;
1006 while (i >= EXT_BLKSIZ) {
1007 if (eb && eb->next)
1008 eb = eb->next;
1009 else {
1010 eb = *ebtail = nasm_malloc(sizeof(*eb));
1011 eb->next = NULL;
1012 ebtail = &eb->next;
1014 i -= EXT_BLKSIZ;
1016 eb->exts[i] = ext;
1017 ext->index = ++externals;
1019 if (special && !used_special)
1020 error(ERR_NONFATAL, "OBJ supports no special symbol features"
1021 " for this symbol type");
1024 /* forward declaration */
1025 static void obj_write_fixup(ObjRecord * orp, int bytes,
1026 int segrel, int32_t seg, int32_t wrt,
1027 struct Segment *segto);
1029 static void obj_out(int32_t segto, const void *data,
1030 enum out_type type, uint64_t size,
1031 int32_t segment, int32_t wrt)
1033 const uint8_t *ucdata;
1034 int32_t ldata;
1035 struct Segment *seg;
1036 ObjRecord *orp;
1039 * handle absolute-assembly (structure definitions)
1041 if (segto == NO_SEG) {
1042 if (type != OUT_RESERVE)
1043 error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1044 " space");
1045 return;
1049 * If `any_segs' is still false, we must define a default
1050 * segment.
1052 if (!any_segs) {
1053 int tempint; /* ignored */
1054 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1055 error(ERR_PANIC, "strange segment conditions in OBJ driver");
1059 * Find the segment we are targetting.
1061 for (seg = seghead; seg; seg = seg->next)
1062 if (seg->index == segto)
1063 break;
1064 if (!seg)
1065 error(ERR_PANIC, "code directed to nonexistent segment?");
1067 orp = seg->orp;
1068 orp->parm[0] = seg->currentpos;
1070 if (type == OUT_RAWDATA) {
1071 ucdata = data;
1072 while (size > 0) {
1073 unsigned int len;
1074 orp = obj_check(seg->orp, 1);
1075 len = RECORD_MAX - orp->used;
1076 if (len > size)
1077 len = size;
1078 memcpy(orp->buf + orp->used, ucdata, len);
1079 orp->committed = orp->used += len;
1080 orp->parm[0] = seg->currentpos += len;
1081 ucdata += len;
1082 size -= len;
1084 } else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
1085 type == OUT_REL4ADR) {
1086 int rsize;
1088 if (segment == NO_SEG && type != OUT_ADDRESS)
1089 error(ERR_NONFATAL, "relative call to absolute address not"
1090 " supported by OBJ format");
1091 if (segment >= SEG_ABS)
1092 error(ERR_NONFATAL, "far-absolute relocations not supported"
1093 " by OBJ format");
1094 ldata = *(int64_t *)data;
1095 if (type == OUT_REL2ADR) {
1096 ldata += (size - 2);
1097 size = 2;
1098 } else if (type == OUT_REL4ADR) {
1099 ldata += (size - 4);
1100 size = 4;
1102 if (size == 2)
1103 orp = obj_word(orp, ldata);
1104 else
1105 orp = obj_dword(orp, ldata);
1106 rsize = size;
1107 if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1108 size == 4) {
1110 * This is a 4-byte segment-base relocation such as
1111 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1112 * these, but if the constant term has the 16 low bits
1113 * zero, we can just apply a 2-byte segment-base
1114 * relocation to the low word instead.
1116 rsize = 2;
1117 if (ldata & 0xFFFF)
1118 error(ERR_NONFATAL, "OBJ format cannot handle complex"
1119 " dword-size segment base references");
1121 if (segment != NO_SEG)
1122 obj_write_fixup(orp, rsize,
1123 (type == OUT_ADDRESS ? 0x4000 : 0),
1124 segment, wrt, seg);
1125 seg->currentpos += size;
1126 } else if (type == OUT_RESERVE) {
1127 if (orp->committed)
1128 orp = obj_bump(orp);
1129 seg->currentpos += size;
1131 obj_commit(orp);
1134 static void obj_write_fixup(ObjRecord * orp, int bytes,
1135 int segrel, int32_t seg, int32_t wrt,
1136 struct Segment *segto)
1138 unsigned locat;
1139 int method;
1140 int base;
1141 int32_t tidx, fidx;
1142 struct Segment *s = NULL;
1143 struct Group *g = NULL;
1144 struct External *e = NULL;
1145 ObjRecord *forp;
1147 if (bytes == 1) {
1148 error(ERR_NONFATAL, "`obj' output driver does not support"
1149 " one-byte relocations");
1150 return;
1153 forp = orp->child;
1154 if (forp == NULL) {
1155 orp->child = forp = obj_new();
1156 forp->up = &(orp->child);
1157 /* We should choose between FIXUPP and FIXU32 record type */
1158 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1159 if (segto->use32)
1160 forp->type = FIXU32;
1161 else
1162 forp->type = FIXUPP;
1165 if (seg % 2) {
1166 base = true;
1167 locat = FIX_16_SELECTOR;
1168 seg--;
1169 if (bytes != 2)
1170 error(ERR_PANIC, "OBJ: 4-byte segment base fixup got"
1171 " through sanity check");
1172 } else {
1173 base = false;
1174 locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1175 if (!segrel)
1177 * There is a bug in tlink that makes it process self relative
1178 * fixups incorrectly if the x_size doesn't match the location
1179 * size.
1181 forp = obj_force(forp, bytes << 3);
1184 forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1186 tidx = fidx = -1, method = 0; /* placate optimisers */
1189 * See if we can find the segment ID in our segment list. If
1190 * so, we have a T4 (LSEG) target.
1192 for (s = seghead; s; s = s->next)
1193 if (s->index == seg)
1194 break;
1195 if (s)
1196 method = 4, tidx = s->obj_index;
1197 else {
1198 for (g = grphead; g; g = g->next)
1199 if (g->index == seg)
1200 break;
1201 if (g)
1202 method = 5, tidx = g->obj_index;
1203 else {
1204 int32_t i = seg / 2;
1205 struct ExtBack *eb = ebhead;
1206 while (i >= EXT_BLKSIZ) {
1207 if (eb)
1208 eb = eb->next;
1209 else
1210 break;
1211 i -= EXT_BLKSIZ;
1213 if (eb)
1214 method = 6, e = eb->exts[i], tidx = e->index;
1215 else
1216 error(ERR_PANIC,
1217 "unrecognised segment value in obj_write_fixup");
1222 * If no WRT given, assume the natural default, which is method
1223 * F5 unless:
1225 * - we are doing an OFFSET fixup for a grouped segment, in
1226 * which case we require F1 (group).
1228 * - we are doing an OFFSET fixup for an external with a
1229 * default WRT, in which case we must honour the default WRT.
1231 if (wrt == NO_SEG) {
1232 if (!base && s && s->grp)
1233 method |= 0x10, fidx = s->grp->obj_index;
1234 else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1235 if (e->defwrt_type == DEFWRT_SEGMENT)
1236 method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1237 else if (e->defwrt_type == DEFWRT_GROUP)
1238 method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1239 else {
1240 error(ERR_NONFATAL, "default WRT specification for"
1241 " external `%s' unresolved", e->name);
1242 method |= 0x50, fidx = -1; /* got to do _something_ */
1244 } else
1245 method |= 0x50, fidx = -1;
1246 } else {
1248 * See if we can find the WRT-segment ID in our segment
1249 * list. If so, we have a F0 (LSEG) frame.
1251 for (s = seghead; s; s = s->next)
1252 if (s->index == wrt - 1)
1253 break;
1254 if (s)
1255 method |= 0x00, fidx = s->obj_index;
1256 else {
1257 for (g = grphead; g; g = g->next)
1258 if (g->index == wrt - 1)
1259 break;
1260 if (g)
1261 method |= 0x10, fidx = g->obj_index;
1262 else {
1263 int32_t i = wrt / 2;
1264 struct ExtBack *eb = ebhead;
1265 while (i >= EXT_BLKSIZ) {
1266 if (eb)
1267 eb = eb->next;
1268 else
1269 break;
1270 i -= EXT_BLKSIZ;
1272 if (eb)
1273 method |= 0x20, fidx = eb->exts[i]->index;
1274 else
1275 error(ERR_PANIC,
1276 "unrecognised WRT value in obj_write_fixup");
1281 forp = obj_byte(forp, method);
1282 if (fidx != -1)
1283 forp = obj_index(forp, fidx);
1284 forp = obj_index(forp, tidx);
1285 obj_commit(forp);
1288 static int32_t obj_segment(char *name, int pass, int *bits)
1291 * We call the label manager here to define a name for the new
1292 * segment, and when our _own_ label-definition stub gets
1293 * called in return, it should register the new segment name
1294 * using the pointer it gets passed. That way we save memory,
1295 * by sponging off the label manager.
1297 #if defined(DEBUG) && DEBUG>=3
1298 fprintf(stderr, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1299 name, pass, *bits);
1300 #endif
1301 if (!name) {
1302 *bits = 16;
1303 current_seg = NULL;
1304 return first_seg;
1305 } else {
1306 struct Segment *seg;
1307 struct Group *grp;
1308 struct External **extp;
1309 int obj_idx, i, attrs;
1310 bool rn_error;
1311 char *p;
1314 * Look for segment attributes.
1316 attrs = 0;
1317 while (*name == '.')
1318 name++; /* hack, but a documented one */
1319 p = name;
1320 while (*p && !nasm_isspace(*p))
1321 p++;
1322 if (*p) {
1323 *p++ = '\0';
1324 while (*p && nasm_isspace(*p))
1325 *p++ = '\0';
1327 while (*p) {
1328 while (*p && !nasm_isspace(*p))
1329 p++;
1330 if (*p) {
1331 *p++ = '\0';
1332 while (*p && nasm_isspace(*p))
1333 *p++ = '\0';
1336 attrs++;
1339 obj_idx = 1;
1340 for (seg = seghead; seg; seg = seg->next) {
1341 obj_idx++;
1342 if (!strcmp(seg->name, name)) {
1343 if (attrs > 0 && pass == 1)
1344 error(ERR_WARNING, "segment attributes specified on"
1345 " redeclaration of segment: ignoring");
1346 if (seg->use32)
1347 *bits = 32;
1348 else
1349 *bits = 16;
1350 current_seg = seg;
1351 return seg->index;
1355 *segtail = seg = nasm_malloc(sizeof(*seg));
1356 seg->next = NULL;
1357 segtail = &seg->next;
1358 seg->index = (any_segs ? seg_alloc() : first_seg);
1359 seg->obj_index = obj_idx;
1360 seg->grp = NULL;
1361 any_segs = true;
1362 seg->name = NULL;
1363 seg->currentpos = 0;
1364 seg->align = 1; /* default */
1365 seg->use32 = false; /* default */
1366 seg->combine = CMB_PUBLIC; /* default */
1367 seg->segclass = seg->overlay = NULL;
1368 seg->pubhead = NULL;
1369 seg->pubtail = &seg->pubhead;
1370 seg->lochead = NULL;
1371 seg->loctail = &seg->lochead;
1372 seg->orp = obj_new();
1373 seg->orp->up = &(seg->orp);
1374 seg->orp->ori = ori_ledata;
1375 seg->orp->type = LEDATA;
1376 seg->orp->parm[1] = obj_idx;
1379 * Process the segment attributes.
1381 p = name;
1382 while (attrs--) {
1383 p += strlen(p);
1384 while (!*p)
1385 p++;
1388 * `p' contains a segment attribute.
1390 if (!nasm_stricmp(p, "private"))
1391 seg->combine = CMB_PRIVATE;
1392 else if (!nasm_stricmp(p, "public"))
1393 seg->combine = CMB_PUBLIC;
1394 else if (!nasm_stricmp(p, "common"))
1395 seg->combine = CMB_COMMON;
1396 else if (!nasm_stricmp(p, "stack"))
1397 seg->combine = CMB_STACK;
1398 else if (!nasm_stricmp(p, "use16"))
1399 seg->use32 = false;
1400 else if (!nasm_stricmp(p, "use32"))
1401 seg->use32 = true;
1402 else if (!nasm_stricmp(p, "flat")) {
1404 * This segment is an OS/2 FLAT segment. That means
1405 * that its default group is group FLAT, even if
1406 * the group FLAT does not explicitly _contain_ the
1407 * segment.
1409 * When we see this, we must create the group
1410 * `FLAT', containing no segments, if it does not
1411 * already exist; then we must set the default
1412 * group of this segment to be the FLAT group.
1414 struct Group *grp;
1415 for (grp = grphead; grp; grp = grp->next)
1416 if (!strcmp(grp->name, "FLAT"))
1417 break;
1418 if (!grp) {
1419 obj_directive(D_GROUP, "FLAT", 1);
1420 for (grp = grphead; grp; grp = grp->next)
1421 if (!strcmp(grp->name, "FLAT"))
1422 break;
1423 if (!grp)
1424 error(ERR_PANIC, "failure to define FLAT?!");
1426 seg->grp = grp;
1427 } else if (!nasm_strnicmp(p, "class=", 6))
1428 seg->segclass = nasm_strdup(p + 6);
1429 else if (!nasm_strnicmp(p, "overlay=", 8))
1430 seg->overlay = nasm_strdup(p + 8);
1431 else if (!nasm_strnicmp(p, "align=", 6)) {
1432 seg->align = readnum(p + 6, &rn_error);
1433 if (rn_error) {
1434 seg->align = 1;
1435 error(ERR_NONFATAL, "segment alignment should be"
1436 " numeric");
1438 switch ((int)seg->align) {
1439 case 1: /* BYTE */
1440 case 2: /* WORD */
1441 case 4: /* DWORD */
1442 case 16: /* PARA */
1443 case 256: /* PAGE */
1444 case 4096: /* PharLap extension */
1445 break;
1446 case 8:
1447 error(ERR_WARNING,
1448 "OBJ format does not support alignment"
1449 " of 8: rounding up to 16");
1450 seg->align = 16;
1451 break;
1452 case 32:
1453 case 64:
1454 case 128:
1455 error(ERR_WARNING,
1456 "OBJ format does not support alignment"
1457 " of %d: rounding up to 256", seg->align);
1458 seg->align = 256;
1459 break;
1460 case 512:
1461 case 1024:
1462 case 2048:
1463 error(ERR_WARNING,
1464 "OBJ format does not support alignment"
1465 " of %d: rounding up to 4096", seg->align);
1466 seg->align = 4096;
1467 break;
1468 default:
1469 error(ERR_NONFATAL, "invalid alignment value %d",
1470 seg->align);
1471 seg->align = 1;
1472 break;
1474 } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1475 seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1476 if (rn_error)
1477 error(ERR_NONFATAL, "argument to `absolute' segment"
1478 " attribute should be numeric");
1482 /* We need to know whenever we have at least one 32-bit segment */
1483 obj_use32 |= seg->use32;
1485 obj_seg_needs_update = seg;
1486 if (seg->align >= SEG_ABS)
1487 deflabel(name, NO_SEG, seg->align - SEG_ABS,
1488 NULL, false, false, &of_obj, error);
1489 else
1490 deflabel(name, seg->index + 1, 0L,
1491 NULL, false, false, &of_obj, error);
1492 obj_seg_needs_update = NULL;
1495 * See if this segment is defined in any groups.
1497 for (grp = grphead; grp; grp = grp->next) {
1498 for (i = grp->nindices; i < grp->nentries; i++) {
1499 if (!strcmp(grp->segs[i].name, seg->name)) {
1500 nasm_free(grp->segs[i].name);
1501 grp->segs[i] = grp->segs[grp->nindices];
1502 grp->segs[grp->nindices++].index = seg->obj_index;
1503 if (seg->grp)
1504 error(ERR_WARNING,
1505 "segment `%s' is already part of"
1506 " a group: first one takes precedence",
1507 seg->name);
1508 else
1509 seg->grp = grp;
1515 * Walk through the list of externals with unresolved
1516 * default-WRT clauses, and resolve any that point at this
1517 * segment.
1519 extp = &dws;
1520 while (*extp) {
1521 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1522 !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1523 nasm_free((*extp)->defwrt_ptr.string);
1524 (*extp)->defwrt_type = DEFWRT_SEGMENT;
1525 (*extp)->defwrt_ptr.seg = seg;
1526 *extp = (*extp)->next_dws;
1527 } else
1528 extp = &(*extp)->next_dws;
1531 if (seg->use32)
1532 *bits = 32;
1533 else
1534 *bits = 16;
1535 current_seg = seg;
1536 return seg->index;
1540 static int obj_directive(enum directives directive, char *value, int pass)
1542 switch (directive) {
1543 case D_GROUP:
1545 char *p, *q, *v;
1546 if (pass == 1) {
1547 struct Group *grp;
1548 struct Segment *seg;
1549 struct External **extp;
1550 int obj_idx;
1552 q = value;
1553 while (*q == '.')
1554 q++; /* hack, but a documented one */
1555 v = q;
1556 while (*q && !nasm_isspace(*q))
1557 q++;
1558 if (nasm_isspace(*q)) {
1559 *q++ = '\0';
1560 while (*q && nasm_isspace(*q))
1561 q++;
1564 * Here we used to sanity-check the group directive to
1565 * ensure nobody tried to declare a group containing no
1566 * segments. However, OS/2 does this as standard
1567 * practice, so the sanity check has been removed.
1569 * if (!*q) {
1570 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1571 * return 1;
1575 obj_idx = 1;
1576 for (grp = grphead; grp; grp = grp->next) {
1577 obj_idx++;
1578 if (!strcmp(grp->name, v)) {
1579 error(ERR_NONFATAL, "group `%s' defined twice", v);
1580 return 1;
1584 *grptail = grp = nasm_malloc(sizeof(*grp));
1585 grp->next = NULL;
1586 grptail = &grp->next;
1587 grp->index = seg_alloc();
1588 grp->obj_index = obj_idx;
1589 grp->nindices = grp->nentries = 0;
1590 grp->name = NULL;
1592 obj_grp_needs_update = grp;
1593 deflabel(v, grp->index + 1, 0L,
1594 NULL, false, false, &of_obj, error);
1595 obj_grp_needs_update = NULL;
1597 while (*q) {
1598 p = q;
1599 while (*q && !nasm_isspace(*q))
1600 q++;
1601 if (nasm_isspace(*q)) {
1602 *q++ = '\0';
1603 while (*q && nasm_isspace(*q))
1604 q++;
1607 * Now p contains a segment name. Find it.
1609 for (seg = seghead; seg; seg = seg->next)
1610 if (!strcmp(seg->name, p))
1611 break;
1612 if (seg) {
1614 * We have a segment index. Shift a name entry
1615 * to the end of the array to make room.
1617 grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1618 grp->segs[grp->nindices++].index = seg->obj_index;
1619 if (seg->grp)
1620 error(ERR_WARNING,
1621 "segment `%s' is already part of"
1622 " a group: first one takes precedence",
1623 seg->name);
1624 else
1625 seg->grp = grp;
1626 } else {
1628 * We have an as-yet undefined segment.
1629 * Remember its name, for later.
1631 grp->segs[grp->nentries++].name = nasm_strdup(p);
1636 * Walk through the list of externals with unresolved
1637 * default-WRT clauses, and resolve any that point at
1638 * this group.
1640 extp = &dws;
1641 while (*extp) {
1642 if ((*extp)->defwrt_type == DEFWRT_STRING &&
1643 !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1644 nasm_free((*extp)->defwrt_ptr.string);
1645 (*extp)->defwrt_type = DEFWRT_GROUP;
1646 (*extp)->defwrt_ptr.grp = grp;
1647 *extp = (*extp)->next_dws;
1648 } else
1649 extp = &(*extp)->next_dws;
1652 return 1;
1654 case D_UPPERCASE:
1655 obj_uppercase = true;
1656 return 1;
1658 case D_IMPORT:
1660 char *q, *extname, *libname, *impname;
1662 if (pass == 2)
1663 return 1; /* ignore in pass two */
1664 extname = q = value;
1665 while (*q && !nasm_isspace(*q))
1666 q++;
1667 if (nasm_isspace(*q)) {
1668 *q++ = '\0';
1669 while (*q && nasm_isspace(*q))
1670 q++;
1673 libname = q;
1674 while (*q && !nasm_isspace(*q))
1675 q++;
1676 if (nasm_isspace(*q)) {
1677 *q++ = '\0';
1678 while (*q && nasm_isspace(*q))
1679 q++;
1682 impname = q;
1684 if (!*extname || !*libname)
1685 error(ERR_NONFATAL, "`import' directive requires symbol name"
1686 " and library name");
1687 else {
1688 struct ImpDef *imp;
1689 bool err = false;
1691 imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1692 imptail = &imp->next;
1693 imp->next = NULL;
1694 imp->extname = nasm_strdup(extname);
1695 imp->libname = nasm_strdup(libname);
1696 imp->impindex = readnum(impname, &err);
1697 if (!*impname || err)
1698 imp->impname = nasm_strdup(impname);
1699 else
1700 imp->impname = NULL;
1703 return 1;
1705 case D_EXPORT:
1707 char *q, *extname, *intname, *v;
1708 struct ExpDef *export;
1709 int flags = 0;
1710 unsigned int ordinal = 0;
1712 if (pass == 2)
1713 return 1; /* ignore in pass two */
1714 intname = q = value;
1715 while (*q && !nasm_isspace(*q))
1716 q++;
1717 if (nasm_isspace(*q)) {
1718 *q++ = '\0';
1719 while (*q && nasm_isspace(*q))
1720 q++;
1723 extname = q;
1724 while (*q && !nasm_isspace(*q))
1725 q++;
1726 if (nasm_isspace(*q)) {
1727 *q++ = '\0';
1728 while (*q && nasm_isspace(*q))
1729 q++;
1732 if (!*intname) {
1733 error(ERR_NONFATAL, "`export' directive requires export name");
1734 return 1;
1736 if (!*extname) {
1737 extname = intname;
1738 intname = "";
1740 while (*q) {
1741 v = q;
1742 while (*q && !nasm_isspace(*q))
1743 q++;
1744 if (nasm_isspace(*q)) {
1745 *q++ = '\0';
1746 while (*q && nasm_isspace(*q))
1747 q++;
1749 if (!nasm_stricmp(v, "resident"))
1750 flags |= EXPDEF_FLAG_RESIDENT;
1751 else if (!nasm_stricmp(v, "nodata"))
1752 flags |= EXPDEF_FLAG_NODATA;
1753 else if (!nasm_strnicmp(v, "parm=", 5)) {
1754 bool err = false;
1755 flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1756 if (err) {
1757 error(ERR_NONFATAL,
1758 "value `%s' for `parm' is non-numeric", v + 5);
1759 return 1;
1761 } else {
1762 bool err = false;
1763 ordinal = readnum(v, &err);
1764 if (err) {
1765 error(ERR_NONFATAL,
1766 "unrecognised export qualifier `%s'", v);
1767 return 1;
1769 flags |= EXPDEF_FLAG_ORDINAL;
1773 export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1774 exptail = &export->next;
1775 export->next = NULL;
1776 export->extname = nasm_strdup(extname);
1777 export->intname = nasm_strdup(intname);
1778 export->ordinal = ordinal;
1779 export->flags = flags;
1781 return 1;
1783 default:
1784 return 0;
1788 static int32_t obj_segbase(int32_t segment)
1790 struct Segment *seg;
1793 * Find the segment in our list.
1795 for (seg = seghead; seg; seg = seg->next)
1796 if (seg->index == segment - 1)
1797 break;
1799 if (!seg) {
1801 * Might be an external with a default WRT.
1803 int32_t i = segment / 2;
1804 struct ExtBack *eb = ebhead;
1805 struct External *e;
1807 while (i >= EXT_BLKSIZ) {
1808 if (eb)
1809 eb = eb->next;
1810 else
1811 break;
1812 i -= EXT_BLKSIZ;
1814 if (eb) {
1815 e = eb->exts[i];
1816 if (!e) {
1817 nasm_assert(pass0 == 0);
1818 /* Not available - can happen during optimization */
1819 return NO_SEG;
1822 switch (e->defwrt_type) {
1823 case DEFWRT_NONE:
1824 return segment; /* fine */
1825 case DEFWRT_SEGMENT:
1826 return e->defwrt_ptr.seg->index + 1;
1827 case DEFWRT_GROUP:
1828 return e->defwrt_ptr.grp->index + 1;
1829 default:
1830 return NO_SEG; /* can't tell what it is */
1834 return segment; /* not one of ours - leave it alone */
1837 if (seg->align >= SEG_ABS)
1838 return seg->align; /* absolute segment */
1839 if (seg->grp)
1840 return seg->grp->index + 1; /* grouped segment */
1842 return segment; /* no special treatment */
1845 static void obj_filename(char *inname, char *outname, efunc lerror)
1847 strcpy(obj_infile, inname);
1848 standard_extension(inname, outname, ".obj", lerror);
1851 static void obj_write_file(int debuginfo)
1853 struct Segment *seg, *entry_seg_ptr = 0;
1854 struct FileName *fn;
1855 struct LineNumber *ln;
1856 struct Group *grp;
1857 struct Public *pub, *loc;
1858 struct External *ext;
1859 struct ImpDef *imp;
1860 struct ExpDef *export;
1861 int lname_idx;
1862 ObjRecord *orp;
1865 * Write the THEADR module header.
1867 orp = obj_new();
1868 orp->type = THEADR;
1869 obj_name(orp, obj_infile);
1870 obj_emit2(orp);
1873 * Write the NASM boast comment.
1875 orp->type = COMENT;
1876 obj_rword(orp, 0); /* comment type zero */
1877 obj_name(orp, nasm_comment);
1878 obj_emit2(orp);
1880 orp->type = COMENT;
1882 * Write the IMPDEF records, if any.
1884 for (imp = imphead; imp; imp = imp->next) {
1885 obj_rword(orp, 0xA0); /* comment class A0 */
1886 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1887 if (imp->impname)
1888 obj_byte(orp, 0); /* import by name */
1889 else
1890 obj_byte(orp, 1); /* import by ordinal */
1891 obj_name(orp, imp->extname);
1892 obj_name(orp, imp->libname);
1893 if (imp->impname)
1894 obj_name(orp, imp->impname);
1895 else
1896 obj_word(orp, imp->impindex);
1897 obj_emit2(orp);
1901 * Write the EXPDEF records, if any.
1903 for (export = exphead; export; export = export->next) {
1904 obj_rword(orp, 0xA0); /* comment class A0 */
1905 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1906 obj_byte(orp, export->flags);
1907 obj_name(orp, export->extname);
1908 obj_name(orp, export->intname);
1909 if (export->flags & EXPDEF_FLAG_ORDINAL)
1910 obj_word(orp, export->ordinal);
1911 obj_emit2(orp);
1914 /* we're using extended OMF if we put in debug info */
1915 if (debuginfo) {
1916 orp->type = COMENT;
1917 obj_byte(orp, 0x40);
1918 obj_byte(orp, dEXTENDED);
1919 obj_emit2(orp);
1923 * Write the first LNAMES record, containing LNAME one, which
1924 * is null. Also initialize the LNAME counter.
1926 orp->type = LNAMES;
1927 obj_byte(orp, 0);
1928 lname_idx = 1;
1930 * Write some LNAMES for the segment names
1932 for (seg = seghead; seg; seg = seg->next) {
1933 orp = obj_name(orp, seg->name);
1934 if (seg->segclass)
1935 orp = obj_name(orp, seg->segclass);
1936 if (seg->overlay)
1937 orp = obj_name(orp, seg->overlay);
1938 obj_commit(orp);
1941 * Write some LNAMES for the group names
1943 for (grp = grphead; grp; grp = grp->next) {
1944 orp = obj_name(orp, grp->name);
1945 obj_commit(orp);
1947 obj_emit(orp);
1950 * Write the SEGDEF records.
1952 orp->type = SEGDEF;
1953 for (seg = seghead; seg; seg = seg->next) {
1954 int acbp;
1955 uint32_t seglen = seg->currentpos;
1957 acbp = (seg->combine << 2); /* C field */
1959 if (seg->use32)
1960 acbp |= 0x01; /* P bit is Use32 flag */
1961 else if (seglen == 0x10000L) {
1962 seglen = 0; /* This special case may be needed for old linkers */
1963 acbp |= 0x02; /* B bit */
1966 /* A field */
1967 if (seg->align >= SEG_ABS)
1968 /* acbp |= 0x00 */ ;
1969 else if (seg->align >= 4096) {
1970 if (seg->align > 4096)
1971 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1972 " than OBJ format supports", seg->name);
1973 acbp |= 0xC0; /* PharLap extension */
1974 } else if (seg->align >= 256) {
1975 acbp |= 0x80;
1976 } else if (seg->align >= 16) {
1977 acbp |= 0x60;
1978 } else if (seg->align >= 4) {
1979 acbp |= 0xA0;
1980 } else if (seg->align >= 2) {
1981 acbp |= 0x40;
1982 } else
1983 acbp |= 0x20;
1985 obj_byte(orp, acbp);
1986 if (seg->align & SEG_ABS) {
1987 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1988 obj_byte(orp, 0); /* Offset */
1990 obj_x(orp, seglen);
1991 obj_index(orp, ++lname_idx);
1992 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1993 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1994 obj_emit2(orp);
1998 * Write the GRPDEF records.
2000 orp->type = GRPDEF;
2001 for (grp = grphead; grp; grp = grp->next) {
2002 int i;
2004 if (grp->nindices != grp->nentries) {
2005 for (i = grp->nindices; i < grp->nentries; i++) {
2006 error(ERR_NONFATAL, "group `%s' contains undefined segment"
2007 " `%s'", grp->name, grp->segs[i].name);
2008 nasm_free(grp->segs[i].name);
2009 grp->segs[i].name = NULL;
2012 obj_index(orp, ++lname_idx);
2013 for (i = 0; i < grp->nindices; i++) {
2014 obj_byte(orp, 0xFF);
2015 obj_index(orp, grp->segs[i].index);
2017 obj_emit2(orp);
2021 * Write the PUBDEF records: first the ones in the segments,
2022 * then the far-absolutes.
2024 orp->type = PUBDEF;
2025 orp->ori = ori_pubdef;
2026 for (seg = seghead; seg; seg = seg->next) {
2027 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2028 orp->parm[1] = seg->obj_index;
2029 for (pub = seg->pubhead; pub; pub = pub->next) {
2030 orp = obj_name(orp, pub->name);
2031 orp = obj_x(orp, pub->offset);
2032 orp = obj_byte(orp, 0); /* type index */
2033 obj_commit(orp);
2035 obj_emit(orp);
2037 orp->parm[0] = 0;
2038 orp->parm[1] = 0;
2039 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2040 if (orp->parm[2] != (uint32_t)pub->segment) {
2041 obj_emit(orp);
2042 orp->parm[2] = pub->segment;
2044 orp = obj_name(orp, pub->name);
2045 orp = obj_x(orp, pub->offset);
2046 orp = obj_byte(orp, 0); /* type index */
2047 obj_commit(orp);
2049 obj_emit(orp);
2052 * Write the EXTDEF and COMDEF records, in order.
2054 orp->ori = ori_null;
2055 for (ext = exthead; ext; ext = ext->next) {
2056 if (ext->commonsize == 0) {
2057 if (orp->type != EXTDEF) {
2058 obj_emit(orp);
2059 orp->type = EXTDEF;
2061 orp = obj_name(orp, ext->name);
2062 orp = obj_index(orp, 0);
2063 } else {
2064 if (orp->type != COMDEF) {
2065 obj_emit(orp);
2066 orp->type = COMDEF;
2068 orp = obj_name(orp, ext->name);
2069 orp = obj_index(orp, 0);
2070 if (ext->commonelem) {
2071 orp = obj_byte(orp, 0x61); /* far communal */
2072 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2073 orp = obj_value(orp, ext->commonelem);
2074 } else {
2075 orp = obj_byte(orp, 0x62); /* near communal */
2076 orp = obj_value(orp, ext->commonsize);
2079 obj_commit(orp);
2081 obj_emit(orp);
2084 * Write a COMENT record stating that the linker's first pass
2085 * may stop processing at this point. Exception is if our
2086 * MODEND record specifies a start point, in which case,
2087 * according to some variants of the documentation, this COMENT
2088 * should be omitted. So we'll omit it just in case.
2089 * But, TASM puts it in all the time so if we are using
2090 * TASM debug stuff we are putting it in
2092 if (debuginfo || obj_entry_seg == NO_SEG) {
2093 orp->type = COMENT;
2094 obj_byte(orp, 0x40);
2095 obj_byte(orp, dLINKPASS);
2096 obj_byte(orp, 1);
2097 obj_emit2(orp);
2101 * 1) put out the compiler type
2102 * 2) Put out the type info. The only type we are using is near label #19
2104 if (debuginfo) {
2105 int i;
2106 struct Array *arrtmp = arrhead;
2107 orp->type = COMENT;
2108 obj_byte(orp, 0x40);
2109 obj_byte(orp, dCOMPDEF);
2110 obj_byte(orp, 4);
2111 obj_byte(orp, 0);
2112 obj_emit2(orp);
2114 obj_byte(orp, 0x40);
2115 obj_byte(orp, dTYPEDEF);
2116 obj_word(orp, 0x18); /* type # for linking */
2117 obj_word(orp, 6); /* size of type */
2118 obj_byte(orp, 0x2a); /* absolute type for debugging */
2119 obj_emit2(orp);
2120 obj_byte(orp, 0x40);
2121 obj_byte(orp, dTYPEDEF);
2122 obj_word(orp, 0x19); /* type # for linking */
2123 obj_word(orp, 0); /* size of type */
2124 obj_byte(orp, 0x24); /* absolute type for debugging */
2125 obj_byte(orp, 0); /* near/far specifier */
2126 obj_emit2(orp);
2127 obj_byte(orp, 0x40);
2128 obj_byte(orp, dTYPEDEF);
2129 obj_word(orp, 0x1A); /* type # for linking */
2130 obj_word(orp, 0); /* size of type */
2131 obj_byte(orp, 0x24); /* absolute type for debugging */
2132 obj_byte(orp, 1); /* near/far specifier */
2133 obj_emit2(orp);
2134 obj_byte(orp, 0x40);
2135 obj_byte(orp, dTYPEDEF);
2136 obj_word(orp, 0x1b); /* type # for linking */
2137 obj_word(orp, 0); /* size of type */
2138 obj_byte(orp, 0x23); /* absolute type for debugging */
2139 obj_byte(orp, 0);
2140 obj_byte(orp, 0);
2141 obj_byte(orp, 0);
2142 obj_emit2(orp);
2143 obj_byte(orp, 0x40);
2144 obj_byte(orp, dTYPEDEF);
2145 obj_word(orp, 0x1c); /* type # for linking */
2146 obj_word(orp, 0); /* size of type */
2147 obj_byte(orp, 0x23); /* absolute type for debugging */
2148 obj_byte(orp, 0);
2149 obj_byte(orp, 4);
2150 obj_byte(orp, 0);
2151 obj_emit2(orp);
2152 obj_byte(orp, 0x40);
2153 obj_byte(orp, dTYPEDEF);
2154 obj_word(orp, 0x1d); /* type # for linking */
2155 obj_word(orp, 0); /* size of type */
2156 obj_byte(orp, 0x23); /* absolute type for debugging */
2157 obj_byte(orp, 0);
2158 obj_byte(orp, 1);
2159 obj_byte(orp, 0);
2160 obj_emit2(orp);
2161 obj_byte(orp, 0x40);
2162 obj_byte(orp, dTYPEDEF);
2163 obj_word(orp, 0x1e); /* type # for linking */
2164 obj_word(orp, 0); /* size of type */
2165 obj_byte(orp, 0x23); /* absolute type for debugging */
2166 obj_byte(orp, 0);
2167 obj_byte(orp, 5);
2168 obj_byte(orp, 0);
2169 obj_emit2(orp);
2171 /* put out the array types */
2172 for (i = ARRAYBOT; i < arrindex; i++) {
2173 obj_byte(orp, 0x40);
2174 obj_byte(orp, dTYPEDEF);
2175 obj_word(orp, i); /* type # for linking */
2176 obj_word(orp, arrtmp->size); /* size of type */
2177 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2178 obj_byte(orp, arrtmp->basetype); /* base type */
2179 obj_emit2(orp);
2180 arrtmp = arrtmp->next;
2184 * write out line number info with a LINNUM record
2185 * switch records when we switch segments, and output the
2186 * file in a pseudo-TASM fashion. The record switch is naive; that
2187 * is that one file may have many records for the same segment
2188 * if there are lots of segment switches
2190 if (fnhead && debuginfo) {
2191 seg = fnhead->lnhead->segment;
2193 for (fn = fnhead; fn; fn = fn->next) {
2194 /* write out current file name */
2195 orp->type = COMENT;
2196 orp->ori = ori_null;
2197 obj_byte(orp, 0x40);
2198 obj_byte(orp, dFILNAME);
2199 obj_byte(orp, 0);
2200 obj_name(orp, fn->name);
2201 obj_dword(orp, 0);
2202 obj_emit2(orp);
2204 /* write out line numbers this file */
2206 orp->type = LINNUM;
2207 orp->ori = ori_linnum;
2208 for (ln = fn->lnhead; ln; ln = ln->next) {
2209 if (seg != ln->segment) {
2210 /* if we get here have to flush the buffer and start
2211 * a new record for a new segment
2213 seg = ln->segment;
2214 obj_emit(orp);
2216 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2217 orp->parm[1] = seg->obj_index;
2218 orp = obj_word(orp, ln->lineno);
2219 orp = obj_x(orp, ln->offset);
2220 obj_commit(orp);
2222 obj_emit(orp);
2226 * we are going to locate the entry point segment now
2227 * rather than wait until the MODEND record, because,
2228 * then we can output a special symbol to tell where the
2229 * entry point is.
2232 if (obj_entry_seg != NO_SEG) {
2233 for (seg = seghead; seg; seg = seg->next) {
2234 if (seg->index == obj_entry_seg) {
2235 entry_seg_ptr = seg;
2236 break;
2239 if (!seg)
2240 error(ERR_NONFATAL, "entry point is not in this module");
2244 * get ready to put out symbol records
2246 orp->type = COMENT;
2247 orp->ori = ori_local;
2250 * put out a symbol for the entry point
2251 * no dots in this symbol, because, borland does
2252 * not (officially) support dots in label names
2253 * and I don't know what various versions of TLINK will do
2255 if (debuginfo && obj_entry_seg != NO_SEG) {
2256 orp = obj_name(orp, "start_of_program");
2257 orp = obj_word(orp, 0x19); /* type: near label */
2258 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2259 orp = obj_index(orp, seg->obj_index);
2260 orp = obj_x(orp, obj_entry_ofs);
2261 obj_commit(orp);
2265 * put out the local labels
2267 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2268 /* labels this seg */
2269 for (loc = seg->lochead; loc; loc = loc->next) {
2270 orp = obj_name(orp, loc->name);
2271 orp = obj_word(orp, loc->type);
2272 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2273 orp = obj_index(orp, seg->obj_index);
2274 orp = obj_x(orp, loc->offset);
2275 obj_commit(orp);
2278 if (orp->used)
2279 obj_emit(orp);
2282 * Write the LEDATA/FIXUPP pairs.
2284 for (seg = seghead; seg; seg = seg->next) {
2285 obj_emit(seg->orp);
2286 nasm_free(seg->orp);
2290 * Write the MODEND module end marker.
2292 orp->type = obj_use32 ? MODE32 : MODEND;
2293 orp->ori = ori_null;
2294 if (entry_seg_ptr) {
2295 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2296 obj_byte(orp, 0xC1);
2297 seg = entry_seg_ptr;
2298 if (seg->grp) {
2299 obj_byte(orp, 0x10);
2300 obj_index(orp, seg->grp->obj_index);
2301 } else {
2303 * the below changed to prevent TLINK crashing.
2304 * Previous more efficient version read:
2306 * obj_byte (orp, 0x50);
2308 obj_byte(orp, 0x00);
2309 obj_index(orp, seg->obj_index);
2311 obj_index(orp, seg->obj_index);
2312 obj_x(orp, obj_entry_ofs);
2313 } else
2314 obj_byte(orp, 0);
2315 obj_emit2(orp);
2316 nasm_free(orp);
2319 static void obj_fwrite(ObjRecord * orp)
2321 unsigned int cksum, len;
2322 uint8_t *ptr;
2324 cksum = orp->type;
2325 if (orp->x_size == 32)
2326 cksum |= 1;
2327 fputc(cksum, ofp);
2328 len = orp->committed + 1;
2329 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2330 fwriteint16_t(len, ofp);
2331 fwrite(orp->buf, 1, len - 1, ofp);
2332 for (ptr = orp->buf; --len; ptr++)
2333 cksum += *ptr;
2334 fputc((-cksum) & 0xFF, ofp);
2337 extern macros_t obj_stdmac[];
2339 void dbgbi_init(struct ofmt *of, void *id, FILE * fp, efunc error)
2341 (void)of;
2342 (void)id;
2343 (void)fp;
2344 (void)error;
2346 fnhead = NULL;
2347 fntail = &fnhead;
2348 arrindex = ARRAYBOT;
2349 arrhead = NULL;
2350 arrtail = &arrhead;
2352 static void dbgbi_cleanup(void)
2354 struct Segment *segtmp;
2355 while (fnhead) {
2356 struct FileName *fntemp = fnhead;
2357 while (fnhead->lnhead) {
2358 struct LineNumber *lntemp = fnhead->lnhead;
2359 fnhead->lnhead = lntemp->next;
2360 nasm_free(lntemp);
2362 fnhead = fnhead->next;
2363 nasm_free(fntemp->name);
2364 nasm_free(fntemp);
2366 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2367 while (segtmp->lochead) {
2368 struct Public *loctmp = segtmp->lochead;
2369 segtmp->lochead = loctmp->next;
2370 nasm_free(loctmp->name);
2371 nasm_free(loctmp);
2374 while (arrhead) {
2375 struct Array *arrtmp = arrhead;
2376 arrhead = arrhead->next;
2377 nasm_free(arrtmp);
2381 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2383 struct FileName *fn;
2384 struct LineNumber *ln;
2385 struct Segment *seg;
2387 if (segto == NO_SEG)
2388 return;
2391 * If `any_segs' is still false, we must define a default
2392 * segment.
2394 if (!any_segs) {
2395 int tempint; /* ignored */
2396 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2397 error(ERR_PANIC, "strange segment conditions in OBJ driver");
2401 * Find the segment we are targetting.
2403 for (seg = seghead; seg; seg = seg->next)
2404 if (seg->index == segto)
2405 break;
2406 if (!seg)
2407 error(ERR_PANIC, "lineno directed to nonexistent segment?");
2409 /* for (fn = fnhead; fn; fn = fnhead->next) */
2410 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2411 if (!nasm_stricmp(lnfname, fn->name))
2412 break;
2413 if (!fn) {
2414 fn = nasm_malloc(sizeof(*fn));
2415 fn->name = nasm_malloc(strlen(lnfname) + 1);
2416 strcpy(fn->name, lnfname);
2417 fn->lnhead = NULL;
2418 fn->lntail = &fn->lnhead;
2419 fn->next = NULL;
2420 *fntail = fn;
2421 fntail = &fn->next;
2423 ln = nasm_malloc(sizeof(*ln));
2424 ln->segment = seg;
2425 ln->offset = seg->currentpos;
2426 ln->lineno = lineno;
2427 ln->next = NULL;
2428 *fn->lntail = ln;
2429 fn->lntail = &ln->next;
2432 static void dbgbi_deflabel(char *name, int32_t segment,
2433 int64_t offset, int is_global, char *special)
2435 struct Segment *seg;
2437 (void)special;
2440 * If it's a special-retry from pass two, discard it.
2442 if (is_global == 3)
2443 return;
2446 * First check for the double-period, signifying something
2447 * unusual.
2449 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2450 return;
2454 * Case (i):
2456 if (obj_seg_needs_update) {
2457 return;
2458 } else if (obj_grp_needs_update) {
2459 return;
2461 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2462 return;
2464 if (segment >= SEG_ABS || segment == NO_SEG) {
2465 return;
2469 * If `any_segs' is still false, we might need to define a
2470 * default segment, if they're trying to declare a label in
2471 * `first_seg'. But the label should exist due to a prior
2472 * call to obj_deflabel so we can skip that.
2475 for (seg = seghead; seg; seg = seg->next)
2476 if (seg->index == segment) {
2477 struct Public *loc = nasm_malloc(sizeof(*loc));
2479 * Case (ii). Maybe MODPUB someday?
2481 last_defined = *seg->loctail = loc;
2482 seg->loctail = &loc->next;
2483 loc->next = NULL;
2484 loc->name = nasm_strdup(name);
2485 loc->offset = offset;
2488 static void dbgbi_typevalue(int32_t type)
2490 int vsize;
2491 int elem = TYM_ELEMENTS(type);
2492 type = TYM_TYPE(type);
2494 if (!last_defined)
2495 return;
2497 switch (type) {
2498 case TY_BYTE:
2499 last_defined->type = 8; /* uint8_t */
2500 vsize = 1;
2501 break;
2502 case TY_WORD:
2503 last_defined->type = 10; /* unsigned word */
2504 vsize = 2;
2505 break;
2506 case TY_DWORD:
2507 last_defined->type = 12; /* unsigned dword */
2508 vsize = 4;
2509 break;
2510 case TY_FLOAT:
2511 last_defined->type = 14; /* float */
2512 vsize = 4;
2513 break;
2514 case TY_QWORD:
2515 last_defined->type = 15; /* qword */
2516 vsize = 8;
2517 break;
2518 case TY_TBYTE:
2519 last_defined->type = 16; /* TBYTE */
2520 vsize = 10;
2521 break;
2522 default:
2523 last_defined->type = 0x19; /*label */
2524 vsize = 0;
2525 break;
2528 if (elem > 1) {
2529 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2530 int vtype = last_defined->type;
2531 arrtmp->size = vsize * elem;
2532 arrtmp->basetype = vtype;
2533 arrtmp->next = NULL;
2534 last_defined->type = arrindex++;
2535 *arrtail = arrtmp;
2536 arrtail = &(arrtmp->next);
2538 last_defined = NULL;
2540 static void dbgbi_output(int output_type, void *param)
2542 (void)output_type;
2543 (void)param;
2545 static struct dfmt borland_debug_form = {
2546 "Borland Debug Records",
2547 "borland",
2548 dbgbi_init,
2549 dbgbi_linnum,
2550 dbgbi_deflabel,
2551 null_debug_routine,
2552 dbgbi_typevalue,
2553 dbgbi_output,
2554 dbgbi_cleanup,
2557 static struct dfmt *borland_debug_arr[3] = {
2558 &borland_debug_form,
2559 &null_debug_form,
2560 NULL
2563 struct ofmt of_obj = {
2564 "MS-DOS 16-bit/32-bit OMF object files",
2565 "obj",
2567 borland_debug_arr,
2568 &borland_debug_form,
2569 obj_stdmac,
2570 obj_init,
2571 obj_set_info,
2572 obj_out,
2573 obj_deflabel,
2574 obj_segment,
2575 obj_segbase,
2576 obj_directive,
2577 obj_filename,
2578 obj_cleanup
2580 #endif /* OF_OBJ */