Add new copyright headers to the output modules
[nasm/avx512.git] / output / outobj.c
blobc9e05c340131e88e2926dcd64aedecb009330230
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->defwrt_type == DEFWRT_NONE)
1812 return segment; /* fine */
1813 else if (e->defwrt_type == DEFWRT_SEGMENT)
1814 return e->defwrt_ptr.seg->index + 1;
1815 else if (e->defwrt_type == DEFWRT_GROUP)
1816 return e->defwrt_ptr.grp->index + 1;
1817 else
1818 return NO_SEG; /* can't tell what it is */
1821 return segment; /* not one of ours - leave it alone */
1824 if (seg->align >= SEG_ABS)
1825 return seg->align; /* absolute segment */
1826 if (seg->grp)
1827 return seg->grp->index + 1; /* grouped segment */
1829 return segment; /* no special treatment */
1832 static void obj_filename(char *inname, char *outname, efunc lerror)
1834 strcpy(obj_infile, inname);
1835 standard_extension(inname, outname, ".obj", lerror);
1838 static void obj_write_file(int debuginfo)
1840 struct Segment *seg, *entry_seg_ptr = 0;
1841 struct FileName *fn;
1842 struct LineNumber *ln;
1843 struct Group *grp;
1844 struct Public *pub, *loc;
1845 struct External *ext;
1846 struct ImpDef *imp;
1847 struct ExpDef *export;
1848 int lname_idx;
1849 ObjRecord *orp;
1852 * Write the THEADR module header.
1854 orp = obj_new();
1855 orp->type = THEADR;
1856 obj_name(orp, obj_infile);
1857 obj_emit2(orp);
1860 * Write the NASM boast comment.
1862 orp->type = COMENT;
1863 obj_rword(orp, 0); /* comment type zero */
1864 obj_name(orp, nasm_comment);
1865 obj_emit2(orp);
1867 orp->type = COMENT;
1869 * Write the IMPDEF records, if any.
1871 for (imp = imphead; imp; imp = imp->next) {
1872 obj_rword(orp, 0xA0); /* comment class A0 */
1873 obj_byte(orp, 1); /* subfunction 1: IMPDEF */
1874 if (imp->impname)
1875 obj_byte(orp, 0); /* import by name */
1876 else
1877 obj_byte(orp, 1); /* import by ordinal */
1878 obj_name(orp, imp->extname);
1879 obj_name(orp, imp->libname);
1880 if (imp->impname)
1881 obj_name(orp, imp->impname);
1882 else
1883 obj_word(orp, imp->impindex);
1884 obj_emit2(orp);
1888 * Write the EXPDEF records, if any.
1890 for (export = exphead; export; export = export->next) {
1891 obj_rword(orp, 0xA0); /* comment class A0 */
1892 obj_byte(orp, 2); /* subfunction 2: EXPDEF */
1893 obj_byte(orp, export->flags);
1894 obj_name(orp, export->extname);
1895 obj_name(orp, export->intname);
1896 if (export->flags & EXPDEF_FLAG_ORDINAL)
1897 obj_word(orp, export->ordinal);
1898 obj_emit2(orp);
1901 /* we're using extended OMF if we put in debug info */
1902 if (debuginfo) {
1903 orp->type = COMENT;
1904 obj_byte(orp, 0x40);
1905 obj_byte(orp, dEXTENDED);
1906 obj_emit2(orp);
1910 * Write the first LNAMES record, containing LNAME one, which
1911 * is null. Also initialize the LNAME counter.
1913 orp->type = LNAMES;
1914 obj_byte(orp, 0);
1915 lname_idx = 1;
1917 * Write some LNAMES for the segment names
1919 for (seg = seghead; seg; seg = seg->next) {
1920 orp = obj_name(orp, seg->name);
1921 if (seg->segclass)
1922 orp = obj_name(orp, seg->segclass);
1923 if (seg->overlay)
1924 orp = obj_name(orp, seg->overlay);
1925 obj_commit(orp);
1928 * Write some LNAMES for the group names
1930 for (grp = grphead; grp; grp = grp->next) {
1931 orp = obj_name(orp, grp->name);
1932 obj_commit(orp);
1934 obj_emit(orp);
1937 * Write the SEGDEF records.
1939 orp->type = SEGDEF;
1940 for (seg = seghead; seg; seg = seg->next) {
1941 int acbp;
1942 uint32_t seglen = seg->currentpos;
1944 acbp = (seg->combine << 2); /* C field */
1946 if (seg->use32)
1947 acbp |= 0x01; /* P bit is Use32 flag */
1948 else if (seglen == 0x10000L) {
1949 seglen = 0; /* This special case may be needed for old linkers */
1950 acbp |= 0x02; /* B bit */
1953 /* A field */
1954 if (seg->align >= SEG_ABS)
1955 /* acbp |= 0x00 */ ;
1956 else if (seg->align >= 4096) {
1957 if (seg->align > 4096)
1958 error(ERR_NONFATAL, "segment `%s' requires more alignment"
1959 " than OBJ format supports", seg->name);
1960 acbp |= 0xC0; /* PharLap extension */
1961 } else if (seg->align >= 256) {
1962 acbp |= 0x80;
1963 } else if (seg->align >= 16) {
1964 acbp |= 0x60;
1965 } else if (seg->align >= 4) {
1966 acbp |= 0xA0;
1967 } else if (seg->align >= 2) {
1968 acbp |= 0x40;
1969 } else
1970 acbp |= 0x20;
1972 obj_byte(orp, acbp);
1973 if (seg->align & SEG_ABS) {
1974 obj_x(orp, seg->align - SEG_ABS); /* Frame */
1975 obj_byte(orp, 0); /* Offset */
1977 obj_x(orp, seglen);
1978 obj_index(orp, ++lname_idx);
1979 obj_index(orp, seg->segclass ? ++lname_idx : 1);
1980 obj_index(orp, seg->overlay ? ++lname_idx : 1);
1981 obj_emit2(orp);
1985 * Write the GRPDEF records.
1987 orp->type = GRPDEF;
1988 for (grp = grphead; grp; grp = grp->next) {
1989 int i;
1991 if (grp->nindices != grp->nentries) {
1992 for (i = grp->nindices; i < grp->nentries; i++) {
1993 error(ERR_NONFATAL, "group `%s' contains undefined segment"
1994 " `%s'", grp->name, grp->segs[i].name);
1995 nasm_free(grp->segs[i].name);
1996 grp->segs[i].name = NULL;
1999 obj_index(orp, ++lname_idx);
2000 for (i = 0; i < grp->nindices; i++) {
2001 obj_byte(orp, 0xFF);
2002 obj_index(orp, grp->segs[i].index);
2004 obj_emit2(orp);
2008 * Write the PUBDEF records: first the ones in the segments,
2009 * then the far-absolutes.
2011 orp->type = PUBDEF;
2012 orp->ori = ori_pubdef;
2013 for (seg = seghead; seg; seg = seg->next) {
2014 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2015 orp->parm[1] = seg->obj_index;
2016 for (pub = seg->pubhead; pub; pub = pub->next) {
2017 orp = obj_name(orp, pub->name);
2018 orp = obj_x(orp, pub->offset);
2019 orp = obj_byte(orp, 0); /* type index */
2020 obj_commit(orp);
2022 obj_emit(orp);
2024 orp->parm[0] = 0;
2025 orp->parm[1] = 0;
2026 for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2027 if (orp->parm[2] != (uint32_t)pub->segment) {
2028 obj_emit(orp);
2029 orp->parm[2] = pub->segment;
2031 orp = obj_name(orp, pub->name);
2032 orp = obj_x(orp, pub->offset);
2033 orp = obj_byte(orp, 0); /* type index */
2034 obj_commit(orp);
2036 obj_emit(orp);
2039 * Write the EXTDEF and COMDEF records, in order.
2041 orp->ori = ori_null;
2042 for (ext = exthead; ext; ext = ext->next) {
2043 if (ext->commonsize == 0) {
2044 if (orp->type != EXTDEF) {
2045 obj_emit(orp);
2046 orp->type = EXTDEF;
2048 orp = obj_name(orp, ext->name);
2049 orp = obj_index(orp, 0);
2050 } else {
2051 if (orp->type != COMDEF) {
2052 obj_emit(orp);
2053 orp->type = COMDEF;
2055 orp = obj_name(orp, ext->name);
2056 orp = obj_index(orp, 0);
2057 if (ext->commonelem) {
2058 orp = obj_byte(orp, 0x61); /* far communal */
2059 orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2060 orp = obj_value(orp, ext->commonelem);
2061 } else {
2062 orp = obj_byte(orp, 0x62); /* near communal */
2063 orp = obj_value(orp, ext->commonsize);
2066 obj_commit(orp);
2068 obj_emit(orp);
2071 * Write a COMENT record stating that the linker's first pass
2072 * may stop processing at this point. Exception is if our
2073 * MODEND record specifies a start point, in which case,
2074 * according to some variants of the documentation, this COMENT
2075 * should be omitted. So we'll omit it just in case.
2076 * But, TASM puts it in all the time so if we are using
2077 * TASM debug stuff we are putting it in
2079 if (debuginfo || obj_entry_seg == NO_SEG) {
2080 orp->type = COMENT;
2081 obj_byte(orp, 0x40);
2082 obj_byte(orp, dLINKPASS);
2083 obj_byte(orp, 1);
2084 obj_emit2(orp);
2088 * 1) put out the compiler type
2089 * 2) Put out the type info. The only type we are using is near label #19
2091 if (debuginfo) {
2092 int i;
2093 struct Array *arrtmp = arrhead;
2094 orp->type = COMENT;
2095 obj_byte(orp, 0x40);
2096 obj_byte(orp, dCOMPDEF);
2097 obj_byte(orp, 4);
2098 obj_byte(orp, 0);
2099 obj_emit2(orp);
2101 obj_byte(orp, 0x40);
2102 obj_byte(orp, dTYPEDEF);
2103 obj_word(orp, 0x18); /* type # for linking */
2104 obj_word(orp, 6); /* size of type */
2105 obj_byte(orp, 0x2a); /* absolute type for debugging */
2106 obj_emit2(orp);
2107 obj_byte(orp, 0x40);
2108 obj_byte(orp, dTYPEDEF);
2109 obj_word(orp, 0x19); /* type # for linking */
2110 obj_word(orp, 0); /* size of type */
2111 obj_byte(orp, 0x24); /* absolute type for debugging */
2112 obj_byte(orp, 0); /* near/far specifier */
2113 obj_emit2(orp);
2114 obj_byte(orp, 0x40);
2115 obj_byte(orp, dTYPEDEF);
2116 obj_word(orp, 0x1A); /* type # for linking */
2117 obj_word(orp, 0); /* size of type */
2118 obj_byte(orp, 0x24); /* absolute type for debugging */
2119 obj_byte(orp, 1); /* near/far specifier */
2120 obj_emit2(orp);
2121 obj_byte(orp, 0x40);
2122 obj_byte(orp, dTYPEDEF);
2123 obj_word(orp, 0x1b); /* type # for linking */
2124 obj_word(orp, 0); /* size of type */
2125 obj_byte(orp, 0x23); /* absolute type for debugging */
2126 obj_byte(orp, 0);
2127 obj_byte(orp, 0);
2128 obj_byte(orp, 0);
2129 obj_emit2(orp);
2130 obj_byte(orp, 0x40);
2131 obj_byte(orp, dTYPEDEF);
2132 obj_word(orp, 0x1c); /* type # for linking */
2133 obj_word(orp, 0); /* size of type */
2134 obj_byte(orp, 0x23); /* absolute type for debugging */
2135 obj_byte(orp, 0);
2136 obj_byte(orp, 4);
2137 obj_byte(orp, 0);
2138 obj_emit2(orp);
2139 obj_byte(orp, 0x40);
2140 obj_byte(orp, dTYPEDEF);
2141 obj_word(orp, 0x1d); /* type # for linking */
2142 obj_word(orp, 0); /* size of type */
2143 obj_byte(orp, 0x23); /* absolute type for debugging */
2144 obj_byte(orp, 0);
2145 obj_byte(orp, 1);
2146 obj_byte(orp, 0);
2147 obj_emit2(orp);
2148 obj_byte(orp, 0x40);
2149 obj_byte(orp, dTYPEDEF);
2150 obj_word(orp, 0x1e); /* type # for linking */
2151 obj_word(orp, 0); /* size of type */
2152 obj_byte(orp, 0x23); /* absolute type for debugging */
2153 obj_byte(orp, 0);
2154 obj_byte(orp, 5);
2155 obj_byte(orp, 0);
2156 obj_emit2(orp);
2158 /* put out the array types */
2159 for (i = ARRAYBOT; i < arrindex; i++) {
2160 obj_byte(orp, 0x40);
2161 obj_byte(orp, dTYPEDEF);
2162 obj_word(orp, i); /* type # for linking */
2163 obj_word(orp, arrtmp->size); /* size of type */
2164 obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2165 obj_byte(orp, arrtmp->basetype); /* base type */
2166 obj_emit2(orp);
2167 arrtmp = arrtmp->next;
2171 * write out line number info with a LINNUM record
2172 * switch records when we switch segments, and output the
2173 * file in a pseudo-TASM fashion. The record switch is naive; that
2174 * is that one file may have many records for the same segment
2175 * if there are lots of segment switches
2177 if (fnhead && debuginfo) {
2178 seg = fnhead->lnhead->segment;
2180 for (fn = fnhead; fn; fn = fn->next) {
2181 /* write out current file name */
2182 orp->type = COMENT;
2183 orp->ori = ori_null;
2184 obj_byte(orp, 0x40);
2185 obj_byte(orp, dFILNAME);
2186 obj_byte(orp, 0);
2187 obj_name(orp, fn->name);
2188 obj_dword(orp, 0);
2189 obj_emit2(orp);
2191 /* write out line numbers this file */
2193 orp->type = LINNUM;
2194 orp->ori = ori_linnum;
2195 for (ln = fn->lnhead; ln; ln = ln->next) {
2196 if (seg != ln->segment) {
2197 /* if we get here have to flush the buffer and start
2198 * a new record for a new segment
2200 seg = ln->segment;
2201 obj_emit(orp);
2203 orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2204 orp->parm[1] = seg->obj_index;
2205 orp = obj_word(orp, ln->lineno);
2206 orp = obj_x(orp, ln->offset);
2207 obj_commit(orp);
2209 obj_emit(orp);
2213 * we are going to locate the entry point segment now
2214 * rather than wait until the MODEND record, because,
2215 * then we can output a special symbol to tell where the
2216 * entry point is.
2219 if (obj_entry_seg != NO_SEG) {
2220 for (seg = seghead; seg; seg = seg->next) {
2221 if (seg->index == obj_entry_seg) {
2222 entry_seg_ptr = seg;
2223 break;
2226 if (!seg)
2227 error(ERR_NONFATAL, "entry point is not in this module");
2231 * get ready to put out symbol records
2233 orp->type = COMENT;
2234 orp->ori = ori_local;
2237 * put out a symbol for the entry point
2238 * no dots in this symbol, because, borland does
2239 * not (officially) support dots in label names
2240 * and I don't know what various versions of TLINK will do
2242 if (debuginfo && obj_entry_seg != NO_SEG) {
2243 orp = obj_name(orp, "start_of_program");
2244 orp = obj_word(orp, 0x19); /* type: near label */
2245 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2246 orp = obj_index(orp, seg->obj_index);
2247 orp = obj_x(orp, obj_entry_ofs);
2248 obj_commit(orp);
2252 * put out the local labels
2254 for (seg = seghead; seg && debuginfo; seg = seg->next) {
2255 /* labels this seg */
2256 for (loc = seg->lochead; loc; loc = loc->next) {
2257 orp = obj_name(orp, loc->name);
2258 orp = obj_word(orp, loc->type);
2259 orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2260 orp = obj_index(orp, seg->obj_index);
2261 orp = obj_x(orp, loc->offset);
2262 obj_commit(orp);
2265 if (orp->used)
2266 obj_emit(orp);
2269 * Write the LEDATA/FIXUPP pairs.
2271 for (seg = seghead; seg; seg = seg->next) {
2272 obj_emit(seg->orp);
2273 nasm_free(seg->orp);
2277 * Write the MODEND module end marker.
2279 orp->type = obj_use32 ? MODE32 : MODEND;
2280 orp->ori = ori_null;
2281 if (entry_seg_ptr) {
2282 orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2283 obj_byte(orp, 0xC1);
2284 seg = entry_seg_ptr;
2285 if (seg->grp) {
2286 obj_byte(orp, 0x10);
2287 obj_index(orp, seg->grp->obj_index);
2288 } else {
2290 * the below changed to prevent TLINK crashing.
2291 * Previous more efficient version read:
2293 * obj_byte (orp, 0x50);
2295 obj_byte(orp, 0x00);
2296 obj_index(orp, seg->obj_index);
2298 obj_index(orp, seg->obj_index);
2299 obj_x(orp, obj_entry_ofs);
2300 } else
2301 obj_byte(orp, 0);
2302 obj_emit2(orp);
2303 nasm_free(orp);
2306 static void obj_fwrite(ObjRecord * orp)
2308 unsigned int cksum, len;
2309 uint8_t *ptr;
2311 cksum = orp->type;
2312 if (orp->x_size == 32)
2313 cksum |= 1;
2314 fputc(cksum, ofp);
2315 len = orp->committed + 1;
2316 cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2317 fwriteint16_t(len, ofp);
2318 fwrite(orp->buf, 1, len - 1, ofp);
2319 for (ptr = orp->buf; --len; ptr++)
2320 cksum += *ptr;
2321 fputc((-cksum) & 0xFF, ofp);
2324 extern macros_t obj_stdmac[];
2326 void dbgbi_init(struct ofmt *of, void *id, FILE * fp, efunc error)
2328 (void)of;
2329 (void)id;
2330 (void)fp;
2331 (void)error;
2333 fnhead = NULL;
2334 fntail = &fnhead;
2335 arrindex = ARRAYBOT;
2336 arrhead = NULL;
2337 arrtail = &arrhead;
2339 static void dbgbi_cleanup(void)
2341 struct Segment *segtmp;
2342 while (fnhead) {
2343 struct FileName *fntemp = fnhead;
2344 while (fnhead->lnhead) {
2345 struct LineNumber *lntemp = fnhead->lnhead;
2346 fnhead->lnhead = lntemp->next;
2347 nasm_free(lntemp);
2349 fnhead = fnhead->next;
2350 nasm_free(fntemp->name);
2351 nasm_free(fntemp);
2353 for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2354 while (segtmp->lochead) {
2355 struct Public *loctmp = segtmp->lochead;
2356 segtmp->lochead = loctmp->next;
2357 nasm_free(loctmp->name);
2358 nasm_free(loctmp);
2361 while (arrhead) {
2362 struct Array *arrtmp = arrhead;
2363 arrhead = arrhead->next;
2364 nasm_free(arrtmp);
2368 static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2370 struct FileName *fn;
2371 struct LineNumber *ln;
2372 struct Segment *seg;
2374 if (segto == NO_SEG)
2375 return;
2378 * If `any_segs' is still false, we must define a default
2379 * segment.
2381 if (!any_segs) {
2382 int tempint; /* ignored */
2383 if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2384 error(ERR_PANIC, "strange segment conditions in OBJ driver");
2388 * Find the segment we are targetting.
2390 for (seg = seghead; seg; seg = seg->next)
2391 if (seg->index == segto)
2392 break;
2393 if (!seg)
2394 error(ERR_PANIC, "lineno directed to nonexistent segment?");
2396 /* for (fn = fnhead; fn; fn = fnhead->next) */
2397 for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2398 if (!nasm_stricmp(lnfname, fn->name))
2399 break;
2400 if (!fn) {
2401 fn = nasm_malloc(sizeof(*fn));
2402 fn->name = nasm_malloc(strlen(lnfname) + 1);
2403 strcpy(fn->name, lnfname);
2404 fn->lnhead = NULL;
2405 fn->lntail = &fn->lnhead;
2406 fn->next = NULL;
2407 *fntail = fn;
2408 fntail = &fn->next;
2410 ln = nasm_malloc(sizeof(*ln));
2411 ln->segment = seg;
2412 ln->offset = seg->currentpos;
2413 ln->lineno = lineno;
2414 ln->next = NULL;
2415 *fn->lntail = ln;
2416 fn->lntail = &ln->next;
2419 static void dbgbi_deflabel(char *name, int32_t segment,
2420 int64_t offset, int is_global, char *special)
2422 struct Segment *seg;
2424 (void)special;
2427 * If it's a special-retry from pass two, discard it.
2429 if (is_global == 3)
2430 return;
2433 * First check for the double-period, signifying something
2434 * unusual.
2436 if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
2437 return;
2441 * Case (i):
2443 if (obj_seg_needs_update) {
2444 return;
2445 } else if (obj_grp_needs_update) {
2446 return;
2448 if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2449 return;
2451 if (segment >= SEG_ABS || segment == NO_SEG) {
2452 return;
2456 * If `any_segs' is still false, we might need to define a
2457 * default segment, if they're trying to declare a label in
2458 * `first_seg'. But the label should exist due to a prior
2459 * call to obj_deflabel so we can skip that.
2462 for (seg = seghead; seg; seg = seg->next)
2463 if (seg->index == segment) {
2464 struct Public *loc = nasm_malloc(sizeof(*loc));
2466 * Case (ii). Maybe MODPUB someday?
2468 last_defined = *seg->loctail = loc;
2469 seg->loctail = &loc->next;
2470 loc->next = NULL;
2471 loc->name = nasm_strdup(name);
2472 loc->offset = offset;
2475 static void dbgbi_typevalue(int32_t type)
2477 int vsize;
2478 int elem = TYM_ELEMENTS(type);
2479 type = TYM_TYPE(type);
2481 if (!last_defined)
2482 return;
2484 switch (type) {
2485 case TY_BYTE:
2486 last_defined->type = 8; /* uint8_t */
2487 vsize = 1;
2488 break;
2489 case TY_WORD:
2490 last_defined->type = 10; /* unsigned word */
2491 vsize = 2;
2492 break;
2493 case TY_DWORD:
2494 last_defined->type = 12; /* unsigned dword */
2495 vsize = 4;
2496 break;
2497 case TY_FLOAT:
2498 last_defined->type = 14; /* float */
2499 vsize = 4;
2500 break;
2501 case TY_QWORD:
2502 last_defined->type = 15; /* qword */
2503 vsize = 8;
2504 break;
2505 case TY_TBYTE:
2506 last_defined->type = 16; /* TBYTE */
2507 vsize = 10;
2508 break;
2509 default:
2510 last_defined->type = 0x19; /*label */
2511 vsize = 0;
2512 break;
2515 if (elem > 1) {
2516 struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2517 int vtype = last_defined->type;
2518 arrtmp->size = vsize * elem;
2519 arrtmp->basetype = vtype;
2520 arrtmp->next = NULL;
2521 last_defined->type = arrindex++;
2522 *arrtail = arrtmp;
2523 arrtail = &(arrtmp->next);
2525 last_defined = NULL;
2527 static void dbgbi_output(int output_type, void *param)
2529 (void)output_type;
2530 (void)param;
2532 static struct dfmt borland_debug_form = {
2533 "Borland Debug Records",
2534 "borland",
2535 dbgbi_init,
2536 dbgbi_linnum,
2537 dbgbi_deflabel,
2538 null_debug_routine,
2539 dbgbi_typevalue,
2540 dbgbi_output,
2541 dbgbi_cleanup,
2544 static struct dfmt *borland_debug_arr[3] = {
2545 &borland_debug_form,
2546 &null_debug_form,
2547 NULL
2550 struct ofmt of_obj = {
2551 "MS-DOS 16-bit/32-bit OMF object files",
2552 "obj",
2553 NULL,
2554 borland_debug_arr,
2555 &borland_debug_form,
2556 obj_stdmac,
2557 obj_init,
2558 obj_set_info,
2559 obj_out,
2560 obj_deflabel,
2561 obj_segment,
2562 obj_segbase,
2563 obj_directive,
2564 obj_filename,
2565 obj_cleanup
2567 #endif /* OF_OBJ */