1 /* outobj.c output routines for the Netwide Assembler to produce
4 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5 * Julian Hall. All rights reserved. The software is
6 * redistributable under the licence given in the file "Licence"
7 * distributed in the NASM archive.
22 * outobj.c is divided into two sections. The first section is low level
23 * routines for creating obj records; It has nearly zero NASM specific
24 * code. The second section is high level routines for processing calls and
25 * data structures from the rest of NASM into obj format.
27 * It should be easy (though not zero work) to lift the first section out for
28 * use as an obj file writer for some other assembler or compiler.
32 * These routines are built around the ObjRecord data struture. An ObjRecord
33 * holds an object file record that may be under construction or complete.
35 * A major function of these routines is to support continuation of an obj
36 * record into the next record when the maximum record size is exceeded. The
37 * high level code does not need to worry about where the record breaks occur.
38 * It does need to do some minor extra steps to make the automatic continuation
39 * work. Those steps may be skipped for records where the high level knows no
40 * continuation could be required.
42 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
43 * is cleared by obj_clear.
45 * 2) The caller should fill in .type.
47 * 3) If the record is continuable and there is processing that must be done at
48 * the start of each record then the caller should fill in .ori with the
49 * address of the record initializer routine.
51 * 4) If the record is continuable and it should be saved (rather than emitted
52 * immediately) as each record is done, the caller should set .up to be a
53 * pointer to a location in which the caller keeps the master pointer to the
54 * ObjRecord. When the record is continued, the obj_bump routine will then
55 * allocate a new ObjRecord structure and update the master pointer.
57 * 5) If the .ori field was used then the caller should fill in the .parm with
58 * any data required by the initializer.
60 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
61 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
62 * data required for this record.
64 * 7) If the record is continuable, the caller should call obj_commit at each
65 * point where breaking the record is permitted.
67 * 8) To write out the record, the caller should call obj_emit2. If the
68 * caller has called obj_commit for all data written then he can get slightly
69 * faster code by calling obj_emit instead of obj_emit2.
71 * Most of these routines return an ObjRecord pointer. This will be the input
72 * pointer most of the time and will be the new location if the ObjRecord
73 * moved as a result of the call. The caller may ignore the return value in
74 * three cases: It is a "Never Reallocates" routine; or The caller knows
75 * continuation is not possible; or The caller uses the master pointer for the
79 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
80 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
82 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
83 #define FIX_16_OFFSET 0x8400
84 #define FIX_16_SELECTOR 0x8800
85 #define FIX_32_POINTER 0x8C00
86 #define FIX_08_HIGH 0x9000
87 #define FIX_32_OFFSET 0xA400
88 #define FIX_48_POINTER 0xAC00
90 enum RecordID
{ /* record ID codes */
92 THEADR
= 0x80, /* module header */
93 COMENT
= 0x88, /* comment record */
95 LINNUM
= 0x94, /* line number record */
96 LNAMES
= 0x96, /* list of names */
98 SEGDEF
= 0x98, /* segment definition */
99 GRPDEF
= 0x9A, /* group definition */
100 EXTDEF
= 0x8C, /* external definition */
101 PUBDEF
= 0x90, /* public definition */
102 COMDEF
= 0xB0, /* common definition */
104 LEDATA
= 0xA0, /* logical enumerated data */
105 FIXUPP
= 0x9C, /* fixups (relocations) */
106 FIXU32
= 0x9D, /* 32-bit fixups (relocations) */
108 MODEND
= 0x8A, /* module end */
109 MODE32
= 0x8B /* module end for 32-bit objects */
112 enum ComentID
{ /* ID codes for comment records */
114 dEXTENDED
= 0xA1, /* tells that we are using translator-specific extensions */
115 dLINKPASS
= 0xA2, /* link pass 2 marker */
116 dTYPEDEF
= 0xE3, /* define a type */
117 dSYM
= 0xE6, /* symbol debug record */
118 dFILNAME
= 0xE8, /* file name record */
119 dCOMPDEF
= 0xEA /* compiler type info */
123 typedef struct ObjRecord ObjRecord
;
124 typedef void ORI(ObjRecord
*orp
);
127 ORI
*ori
; /* Initialization routine */
128 int used
; /* Current data size */
129 int committed
; /* Data size at last boundary */
130 int x_size
; /* (see obj_x) */
131 unsigned int type
; /* Record type */
132 ObjRecord
*child
; /* Associated record below this one */
133 ObjRecord
**up
; /* Master pointer to this ObjRecord */
134 ObjRecord
*back
; /* Previous part of this record */
135 unsigned long parm
[OBJ_PARMS
]; /* Parameters for ori routine */
136 unsigned char buf
[RECORD_MAX
+3];
139 static void obj_fwrite(ObjRecord
*orp
);
140 static void ori_ledata(ObjRecord
*orp
);
141 static void ori_pubdef(ObjRecord
*orp
);
142 static void ori_null(ObjRecord
*orp
);
143 static ObjRecord
*obj_commit(ObjRecord
*orp
);
145 static int obj_uppercase
; /* Flag: all names in uppercase */
146 static int obj_use32
; /* Flag: at least one segment is 32-bit */
149 * Clear an ObjRecord structure. (Never reallocates).
150 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
152 static ObjRecord
*obj_clear(ObjRecord
*orp
)
164 * Emit an ObjRecord structure. (Never reallocates).
165 * The record is written out preceeded (recursively) by its previous part (if
166 * any) and followed (recursively) by its child (if any).
167 * The previous part and the child are freed. The main ObjRecord is cleared,
170 static ObjRecord
*obj_emit(ObjRecord
*orp
)
174 nasm_free(orp
->back
);
181 obj_emit(orp
->child
);
182 nasm_free(orp
->child
);
185 return (obj_clear(orp
));
189 * Commit and Emit a record. (Never reallocates).
191 static ObjRecord
*obj_emit2(ObjRecord
*orp
)
194 return (obj_emit(orp
));
198 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
200 static ObjRecord
*obj_new(void)
204 orp
= obj_clear( nasm_malloc(sizeof(ObjRecord
)) );
210 * Advance to the next record because the existing one is full or its x_size
212 * Any uncommited data is moved into the next record.
214 static ObjRecord
*obj_bump(ObjRecord
*orp
)
217 int used
= orp
->used
;
218 int committed
= orp
->committed
;
221 *orp
->up
= nxt
= obj_new();
223 nxt
->type
= orp
->type
;
226 memcpy( nxt
->parm
, orp
->parm
, sizeof(orp
->parm
));
234 nxt
->committed
= nxt
->used
;
235 memcpy( nxt
->buf
+ nxt
->committed
, orp
->buf
+ committed
, used
);
236 nxt
->used
= nxt
->committed
+ used
;
243 * Advance to the next record if necessary to allow the next field to fit.
245 static ObjRecord
*obj_check(ObjRecord
*orp
, int size
)
247 if (orp
->used
+ size
> RECORD_MAX
)
250 if (!orp
->committed
) {
253 orp
->committed
= orp
->used
;
260 * All data written so far is commited to the current record (won't be moved to
261 * the next record in case of continuation).
263 static ObjRecord
*obj_commit(ObjRecord
*orp
)
265 orp
->committed
= orp
->used
;
272 static ObjRecord
*obj_byte(ObjRecord
*orp
, unsigned char val
)
274 orp
= obj_check(orp
, 1);
275 orp
->buf
[orp
->used
] = val
;
283 static ObjRecord
*obj_word(ObjRecord
*orp
, unsigned int val
)
285 orp
= obj_check(orp
, 2);
286 orp
->buf
[orp
->used
] = val
;
287 orp
->buf
[orp
->used
+1] = val
>> 8;
293 * Write a reversed word
295 static ObjRecord
*obj_rword(ObjRecord
*orp
, unsigned int val
)
297 orp
= obj_check(orp
, 2);
298 orp
->buf
[orp
->used
] = val
>> 8;
299 orp
->buf
[orp
->used
+1] = val
;
307 static ObjRecord
*obj_dword(ObjRecord
*orp
, unsigned long val
)
309 orp
= obj_check(orp
, 4);
310 orp
->buf
[orp
->used
] = val
;
311 orp
->buf
[orp
->used
+1] = val
>> 8;
312 orp
->buf
[orp
->used
+2] = val
>> 16;
313 orp
->buf
[orp
->used
+3] = val
>> 24;
319 * All fields of "size x" in one obj record must be the same size (either 16
320 * bits or 32 bits). There is a one bit flag in each record which specifies
322 * This routine is used to force the current record to have the desired
323 * x_size. x_size is normally automatic (using obj_x), so that this
324 * routine should be used outside obj_x, only to provide compatibility with
325 * linkers that have bugs in their processing of the size bit.
328 static ObjRecord
*obj_force(ObjRecord
*orp
, int x
)
330 if (orp
->x_size
== (x
^48))
337 * This routine writes a field of size x. The caller does not need to worry at
338 * all about whether 16-bits or 32-bits are required.
340 static ObjRecord
*obj_x(ObjRecord
*orp
, unsigned long val
)
345 orp
= obj_force(orp
, 32);
346 if (orp
->x_size
== 32)
347 return (obj_dword(orp
, val
));
349 return (obj_word(orp
, val
));
355 static ObjRecord
*obj_index(ObjRecord
*orp
, unsigned int val
)
358 return ( obj_byte(orp
, val
) );
359 return (obj_word(orp
, (val
>>8) | (val
<<8) | 0x80));
363 * Writes a variable length value
365 static ObjRecord
*obj_value(ObjRecord
*orp
, unsigned long val
)
368 return ( obj_byte(orp
, val
) );
370 orp
= obj_byte(orp
, 129);
371 return ( obj_word(orp
, val
) );
374 return ( obj_dword(orp
, (val
<<8) + 132 ) );
375 orp
= obj_byte(orp
, 136);
376 return ( obj_dword(orp
, val
) );
380 * Writes a counted string
382 static ObjRecord
*obj_name(ObjRecord
*orp
, char *name
)
384 int len
= strlen(name
);
387 orp
= obj_check(orp
, len
+1);
388 ptr
= orp
->buf
+ orp
->used
;
393 *ptr
++ = toupper(*name
);
396 memcpy(ptr
, name
, len
);
401 * Initializer for an LEDATA record.
403 * parm[1] = segment index
404 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
405 * represent the offset that would be required if the record were split at the
407 * parm[2] is a copy of parm[0] as it was when the current record was initted.
409 static void ori_ledata(ObjRecord
*orp
)
411 obj_index (orp
, orp
->parm
[1]);
412 orp
->parm
[2] = orp
->parm
[0];
413 obj_x (orp
, orp
->parm
[0]);
417 * Initializer for a PUBDEF record.
418 * parm[0] = group index
419 * parm[1] = segment index
420 * parm[2] = frame (only used when both indexes are zero)
422 static void ori_pubdef(ObjRecord
*orp
)
424 obj_index (orp
, orp
->parm
[0]);
425 obj_index (orp
, orp
->parm
[1]);
426 if ( !(orp
->parm
[0] | orp
->parm
[1]) )
427 obj_word (orp
, orp
->parm
[2]);
431 * Initializer for a LINNUM record.
432 * parm[0] = group index
433 * parm[1] = segment index
435 static void ori_linnum(ObjRecord
*orp
)
437 obj_index (orp
, orp
->parm
[0]);
438 obj_index (orp
, orp
->parm
[1]);
441 * Initializer for a local vars record.
443 static void ori_local(ObjRecord
*orp
)
445 obj_byte (orp
, 0x40);
446 obj_byte (orp
, dSYM
);
450 * Null initializer for records that continue without any header info
452 static void ori_null(ObjRecord
*orp
)
454 (void) orp
; /* Do nothing */
458 * This concludes the low level section of outobj.c
461 static char obj_infile
[FILENAME_MAX
];
464 static evalfunc evaluate
;
465 static ldfunc deflabel
;
467 static long first_seg
;
472 #define GROUP_MAX 256 /* we won't _realistically_ have more
473 * than this many segs in a group */
474 #define EXT_BLKSIZ 256 /* block size for externals list */
476 struct Segment
; /* need to know these structs exist */
480 struct LineNumber
*next
;
481 struct Segment
*segment
;
486 static struct FileName
{
487 struct FileName
*next
;
489 struct LineNumber
*lnhead
, **lntail
;
493 static struct Array
{
497 } *arrhead
, **arrtail
;
499 #define ARRAYBOT 31 /* magic number for first array index */
502 static struct Public
{
506 long segment
; /* only if it's far-absolute */
507 int type
; /* only for local debug syms */
508 } *fpubhead
, **fpubtail
, *last_defined
;
510 static struct External
{
511 struct External
*next
;
514 long commonelem
; /* element size if FAR, else zero */
515 int index
; /* OBJ-file external index */
517 DEFWRT_NONE
, /* no unusual default-WRT */
518 DEFWRT_STRING
, /* a string we don't yet understand */
519 DEFWRT_SEGMENT
, /* a segment */
520 DEFWRT_GROUP
/* a group */
527 struct External
*next_dws
; /* next with DEFWRT_STRING */
528 } *exthead
, **exttail
, *dws
;
530 static int externals
;
532 static struct ExtBack
{
533 struct ExtBack
*next
;
534 struct External
*exts
[EXT_BLKSIZ
];
537 static struct Segment
{
538 struct Segment
*next
;
539 long index
; /* the NASM segment id */
540 long obj_index
; /* the OBJ-file segment index */
541 struct Group
*grp
; /* the group it belongs to */
542 unsigned long currentpos
;
543 long align
; /* can be SEG_ABS + absolute addr */
550 long use32
; /* is this segment 32-bit? */
551 struct Public
*pubhead
, **pubtail
, *lochead
, **loctail
;
553 char *segclass
, *overlay
; /* `class' is a C++ keyword :-) */
555 } *seghead
, **segtail
, *obj_seg_needs_update
;
557 static struct Group
{
560 long index
; /* NASM segment id */
561 long obj_index
; /* OBJ-file group index */
562 long nentries
; /* number of elements... */
563 long nindices
; /* ...and number of index elts... */
567 } segs
[GROUP_MAX
]; /* ...in this */
568 } *grphead
, **grptail
, *obj_grp_needs_update
;
570 static struct ImpDef
{
574 unsigned int impindex
;
576 } *imphead
, **imptail
;
578 static struct ExpDef
{
582 unsigned int ordinal
;
584 } *exphead
, **exptail
;
586 #define EXPDEF_FLAG_ORDINAL 0x80
587 #define EXPDEF_FLAG_RESIDENT 0x40
588 #define EXPDEF_FLAG_NODATA 0x20
589 #define EXPDEF_MASK_PARMCNT 0x1F
591 static long obj_entry_seg
, obj_entry_ofs
;
595 /* The current segment */
596 static struct Segment
*current_seg
;
598 static long obj_segment (char *, int, int *);
599 static void obj_write_file(int debuginfo
);
600 static int obj_directive (char *, char *, int);
602 static void obj_init (FILE *fp
, efunc errfunc
, ldfunc ldef
, evalfunc eval
)
608 first_seg
= seg_alloc();
611 fpubtail
= &fpubhead
;
622 seghead
= obj_seg_needs_update
= NULL
;
624 grphead
= obj_grp_needs_update
= NULL
;
626 obj_entry_seg
= NO_SEG
;
627 obj_uppercase
= FALSE
;
632 of_obj
.current_dfmt
->init (&of_obj
,NULL
,fp
,errfunc
);
635 static int obj_set_info(enum geninfo type
, char **val
)
642 static void obj_cleanup (int debuginfo
)
644 obj_write_file(debuginfo
);
645 of_obj
.current_dfmt
->cleanup();
648 struct Segment
*segtmp
= seghead
;
649 seghead
= seghead
->next
;
650 while (segtmp
->pubhead
) {
651 struct Public
*pubtmp
= segtmp
->pubhead
;
652 segtmp
->pubhead
= pubtmp
->next
;
653 nasm_free (pubtmp
->name
);
656 nasm_free (segtmp
->segclass
);
657 nasm_free (segtmp
->overlay
);
661 struct Public
*pubtmp
= fpubhead
;
662 fpubhead
= fpubhead
->next
;
663 nasm_free (pubtmp
->name
);
667 struct External
*exttmp
= exthead
;
668 exthead
= exthead
->next
;
672 struct ImpDef
*imptmp
= imphead
;
673 imphead
= imphead
->next
;
674 nasm_free (imptmp
->extname
);
675 nasm_free (imptmp
->libname
);
676 nasm_free (imptmp
->impname
); /* nasm_free won't mind if it's NULL */
680 struct ExpDef
*exptmp
= exphead
;
681 exphead
= exphead
->next
;
682 nasm_free (exptmp
->extname
);
683 nasm_free (exptmp
->intname
);
687 struct ExtBack
*ebtmp
= ebhead
;
688 ebhead
= ebhead
->next
;
692 struct Group
*grptmp
= grphead
;
693 grphead
= grphead
->next
;
698 static void obj_ext_set_defwrt (struct External
*ext
, char *id
)
703 for (seg
= seghead
; seg
; seg
= seg
->next
)
704 if (!strcmp(seg
->name
, id
)) {
705 ext
->defwrt_type
= DEFWRT_SEGMENT
;
706 ext
->defwrt_ptr
.seg
= seg
;
711 for (grp
= grphead
; grp
; grp
= grp
->next
)
712 if (!strcmp(grp
->name
, id
)) {
713 ext
->defwrt_type
= DEFWRT_GROUP
;
714 ext
->defwrt_ptr
.grp
= grp
;
719 ext
->defwrt_type
= DEFWRT_STRING
;
720 ext
->defwrt_ptr
.string
= id
;
725 static void obj_deflabel (char *name
, long segment
,
726 long offset
, int is_global
, char *special
)
729 * We have three cases:
731 * (i) `segment' is a segment-base. If so, set the name field
732 * for the segment or group structure it refers to, and then
735 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
736 * Save the label position for later output of a PUBDEF record.
737 * (Or a MODPUB, if we work out how.)
739 * (iii) `segment' is not one of our segments. Save the label
740 * position for later output of an EXTDEF, and also store a
741 * back-reference so that we can map later references to this
742 * segment number to the external index.
744 struct External
*ext
;
748 int used_special
= FALSE
; /* have we used the special text? */
750 #if defined(DEBUG) && DEBUG>2
751 fprintf(stderr
, " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
752 name
, segment
, offset
, is_global
, special
);
756 * If it's a special-retry from pass two, discard it.
762 * First check for the double-period, signifying something
765 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
766 if (!strcmp(name
, "..start")) {
767 obj_entry_seg
= segment
;
768 obj_entry_ofs
= offset
;
771 error (ERR_NONFATAL
, "unrecognised special symbol `%s'", name
);
777 if (obj_seg_needs_update
) {
778 obj_seg_needs_update
->name
= name
;
780 } else if (obj_grp_needs_update
) {
781 obj_grp_needs_update
->name
= name
;
784 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
787 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
789 * SEG_ABS subcase of (ii).
794 pub
= *fpubtail
= nasm_malloc(sizeof(*pub
));
795 fpubtail
= &pub
->next
;
797 pub
->name
= nasm_strdup(name
);
798 pub
->offset
= offset
;
799 pub
->segment
= (segment
== NO_SEG
? 0 : segment
& ~SEG_ABS
);
802 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
803 " for this symbol type");
808 * If `any_segs' is still FALSE, we might need to define a
809 * default segment, if they're trying to declare a label in
812 if (!any_segs
&& segment
== first_seg
) {
813 int tempint
; /* ignored */
814 if (segment
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
815 error (ERR_PANIC
, "strange segment conditions in OBJ driver");
818 for (seg
= seghead
; seg
&& is_global
; seg
= seg
->next
)
819 if (seg
->index
== segment
) {
820 struct Public
*loc
= nasm_malloc (sizeof(*loc
));
822 * Case (ii). Maybe MODPUB someday?
825 seg
->pubtail
= &loc
->next
;
827 loc
->name
= nasm_strdup(name
);
828 loc
->offset
= offset
;
831 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
832 " for this symbol type");
840 ext
= *exttail
= nasm_malloc(sizeof(*ext
));
842 exttail
= &ext
->next
;
844 /* Place by default all externs into the current segment */
845 ext
->defwrt_type
= DEFWRT_NONE
;
847 /* 28-Apr-2002 - John Coffman
848 The following code was introduced on 12-Aug-2000, and breaks fixups
849 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
850 (5.10). It was introduced after FIXUP32 was added, and may be needed
851 for 32-bit segments. The following will get 16-bit segments working
852 again, and maybe someone can correct the 'if' condition which is
858 if (current_seg
&& current_seg
->use32
) {
859 if (current_seg
->grp
) {
860 ext
->defwrt_type
= DEFWRT_GROUP
;
861 ext
->defwrt_ptr
.grp
= current_seg
->grp
;
863 ext
->defwrt_type
= DEFWRT_SEGMENT
;
864 ext
->defwrt_ptr
.seg
= current_seg
;
869 if (is_global
== 2) {
870 ext
->commonsize
= offset
;
871 ext
->commonelem
= 1; /* default FAR */
879 * Now process the special text, if any, to find default-WRT
880 * specifications and common-variable element-size and near/far
883 while (special
&& *special
) {
887 * We might have a default-WRT specification.
889 if (!nasm_strnicmp(special
, "wrt", 3)) {
893 special
+= strspn(special
, " \t");
894 p
= nasm_strndup(special
, len
= strcspn(special
, ":"));
895 obj_ext_set_defwrt (ext
, p
);
897 if (*special
&& *special
!= ':')
898 error(ERR_NONFATAL
, "`:' expected in special symbol"
899 " text for `%s'", ext
->name
);
900 else if (*special
== ':')
905 * The NEAR or FAR keywords specify nearness or
906 * farness. FAR gives default element size 1.
908 if (!nasm_strnicmp(special
, "far", 3)) {
912 error(ERR_NONFATAL
, "`%s': `far' keyword may only be applied"
913 " to common variables\n", ext
->name
);
915 special
+= strspn(special
, " \t");
916 } else if (!nasm_strnicmp(special
, "near", 4)) {
920 error(ERR_NONFATAL
, "`%s': `far' keyword may only be applied"
921 " to common variables\n", ext
->name
);
923 special
+= strspn(special
, " \t");
927 * If it's a common, and anything else remains on the line
928 * before a further colon, evaluate it as an expression and
929 * use that as the element size. Forward references aren't
935 if (ext
->commonsize
) {
937 struct tokenval tokval
;
940 stdscan_bufptr
= special
;
941 tokval
.t_type
= TOKEN_INVALID
;
942 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, error
, NULL
);
945 error (ERR_NONFATAL
, "cannot use relocatable"
946 " expression as common-variable element size");
948 ext
->commonelem
= reloc_value(e
);
950 special
= stdscan_bufptr
;
952 error (ERR_NONFATAL
, "`%s': element-size specifications only"
953 " apply to common variables", ext
->name
);
954 while (*special
&& *special
!= ':')
965 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
969 while (i
>= EXT_BLKSIZ
) {
973 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
980 ext
->index
= ++externals
;
982 if (special
&& !used_special
)
983 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
984 " for this symbol type");
987 /* forward declaration */
988 static void obj_write_fixup (ObjRecord
*orp
, int bytes
,
989 int segrel
, long seg
, long wrt
, struct Segment
*segto
);
991 static void obj_out (long segto
, const void *data
, unsigned long type
,
992 long segment
, long wrt
)
994 unsigned long size
, realtype
;
995 const unsigned char *ucdata
;
1001 * handle absolute-assembly (structure definitions)
1003 if (segto
== NO_SEG
) {
1004 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
1005 error (ERR_NONFATAL
, "attempt to assemble code in [ABSOLUTE]"
1011 * If `any_segs' is still FALSE, we must define a default
1015 int tempint
; /* ignored */
1016 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
1017 error (ERR_PANIC
, "strange segment conditions in OBJ driver");
1021 * Find the segment we are targetting.
1023 for (seg
= seghead
; seg
; seg
= seg
->next
)
1024 if (seg
->index
== segto
)
1027 error (ERR_PANIC
, "code directed to nonexistent segment?");
1030 orp
->parm
[0] = seg
->currentpos
;
1032 size
= type
& OUT_SIZMASK
;
1033 realtype
= type
& OUT_TYPMASK
;
1034 if (realtype
== OUT_RAWDATA
) {
1038 orp
= obj_check(seg
->orp
, 1);
1039 len
= RECORD_MAX
- orp
->used
;
1042 memcpy (orp
->buf
+orp
->used
, ucdata
, len
);
1043 orp
->committed
= orp
->used
+= len
;
1044 orp
->parm
[0] = seg
->currentpos
+= len
;
1049 else if (realtype
== OUT_ADDRESS
|| realtype
== OUT_REL2ADR
||
1050 realtype
== OUT_REL4ADR
)
1054 if (segment
== NO_SEG
&& realtype
!= OUT_ADDRESS
)
1055 error(ERR_NONFATAL
, "relative call to absolute address not"
1056 " supported by OBJ format");
1057 if (segment
>= SEG_ABS
)
1058 error(ERR_NONFATAL
, "far-absolute relocations not supported"
1060 ldata
= *(long *)data
;
1061 if (realtype
== OUT_REL2ADR
) {
1065 if (realtype
== OUT_REL4ADR
) {
1070 orp
= obj_word (orp
, ldata
);
1072 orp
= obj_dword (orp
, ldata
);
1074 if (segment
< SEG_ABS
&& (segment
!= NO_SEG
&& segment
% 2) &&
1077 * This is a 4-byte segment-base relocation such as
1078 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1079 * these, but if the constant term has the 16 low bits
1080 * zero, we can just apply a 2-byte segment-base
1081 * relocation to the low word instead.
1085 error(ERR_NONFATAL
, "OBJ format cannot handle complex"
1086 " dword-size segment base references");
1088 if (segment
!= NO_SEG
)
1089 obj_write_fixup (orp
, rsize
,
1090 (realtype
== OUT_ADDRESS
? 0x4000 : 0),
1092 seg
->currentpos
+= size
;
1093 } else if (realtype
== OUT_RESERVE
) {
1095 orp
= obj_bump(orp
);
1096 seg
->currentpos
+= size
;
1101 static void obj_write_fixup (ObjRecord
*orp
, int bytes
,
1102 int segrel
, long seg
, long wrt
, struct Segment
*segto
)
1108 struct Segment
*s
= NULL
;
1109 struct Group
*g
= NULL
;
1110 struct External
*e
= NULL
;
1114 error(ERR_NONFATAL
, "`obj' output driver does not support"
1115 " one-byte relocations");
1121 orp
->child
= forp
= obj_new();
1122 forp
->up
= &(orp
->child
);
1123 /* We should choose between FIXUPP and FIXU32 record type */
1124 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1126 forp
->type
= FIXU32
;
1128 forp
->type
= FIXUPP
;
1133 locat
= FIX_16_SELECTOR
;
1136 error(ERR_PANIC
, "OBJ: 4-byte segment base fixup got"
1137 " through sanity check");
1141 locat
= (bytes
== 2) ? FIX_16_OFFSET
: FIX_32_OFFSET
;
1144 * There is a bug in tlink that makes it process self relative
1145 * fixups incorrectly if the x_size doesn't match the location
1148 forp
= obj_force(forp
, bytes
<<3);
1151 forp
= obj_rword (forp
, locat
| segrel
| (orp
->parm
[0]-orp
->parm
[2]));
1153 tidx
= fidx
= -1, method
= 0; /* placate optimisers */
1156 * See if we can find the segment ID in our segment list. If
1157 * so, we have a T4 (LSEG) target.
1159 for (s
= seghead
; s
; s
= s
->next
)
1160 if (s
->index
== seg
)
1163 method
= 4, tidx
= s
->obj_index
;
1165 for (g
= grphead
; g
; g
= g
->next
)
1166 if (g
->index
== seg
)
1169 method
= 5, tidx
= g
->obj_index
;
1172 struct ExtBack
*eb
= ebhead
;
1173 while (i
> EXT_BLKSIZ
) {
1181 method
= 6, e
= eb
->exts
[i
], tidx
= e
->index
;
1184 "unrecognised segment value in obj_write_fixup");
1189 * If no WRT given, assume the natural default, which is method
1192 * - we are doing an OFFSET fixup for a grouped segment, in
1193 * which case we require F1 (group).
1195 * - we are doing an OFFSET fixup for an external with a
1196 * default WRT, in which case we must honour the default WRT.
1198 if (wrt
== NO_SEG
) {
1199 if (!base
&& s
&& s
->grp
)
1200 method
|= 0x10, fidx
= s
->grp
->obj_index
;
1201 else if (!base
&& e
&& e
->defwrt_type
!= DEFWRT_NONE
) {
1202 if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1203 method
|= 0x00, fidx
= e
->defwrt_ptr
.seg
->obj_index
;
1204 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1205 method
|= 0x10, fidx
= e
->defwrt_ptr
.grp
->obj_index
;
1207 error(ERR_NONFATAL
, "default WRT specification for"
1208 " external `%s' unresolved", e
->name
);
1209 method
|= 0x50, fidx
= -1; /* got to do _something_ */
1212 method
|= 0x50, fidx
= -1;
1215 * See if we can find the WRT-segment ID in our segment
1216 * list. If so, we have a F0 (LSEG) frame.
1218 for (s
= seghead
; s
; s
= s
->next
)
1219 if (s
->index
== wrt
-1)
1222 method
|= 0x00, fidx
= s
->obj_index
;
1224 for (g
= grphead
; g
; g
= g
->next
)
1225 if (g
->index
== wrt
-1)
1228 method
|= 0x10, fidx
= g
->obj_index
;
1231 struct ExtBack
*eb
= ebhead
;
1232 while (i
> EXT_BLKSIZ
) {
1240 method
|= 0x20, fidx
= eb
->exts
[i
]->index
;
1243 "unrecognised WRT value in obj_write_fixup");
1248 forp
= obj_byte (forp
, method
);
1250 forp
= obj_index (forp
, fidx
);
1251 forp
= obj_index (forp
, tidx
);
1255 static long obj_segment (char *name
, int pass
, int *bits
)
1258 * We call the label manager here to define a name for the new
1259 * segment, and when our _own_ label-definition stub gets
1260 * called in return, it should register the new segment name
1261 * using the pointer it gets passed. That way we save memory,
1262 * by sponging off the label manager.
1264 #if defined(DEBUG) && DEBUG>=3
1265 fprintf(stderr
," obj_segment: < %s >, pass=%d, *bits=%d\n",
1273 struct Segment
*seg
;
1275 struct External
**extp
;
1276 int obj_idx
, i
, attrs
, rn_error
;
1280 * Look for segment attributes.
1283 while (*name
== '.')
1284 name
++; /* hack, but a documented one */
1286 while (*p
&& !isspace(*p
))
1290 while (*p
&& isspace(*p
))
1294 while (*p
&& !isspace(*p
))
1298 while (*p
&& isspace(*p
))
1306 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1308 if (!strcmp(seg
->name
, name
)) {
1309 if (attrs
> 0 && pass
== 1)
1310 error(ERR_WARNING
, "segment attributes specified on"
1311 " redeclaration of segment: ignoring");
1321 *segtail
= seg
= nasm_malloc(sizeof(*seg
));
1323 segtail
= &seg
->next
;
1324 seg
->index
= (any_segs
? seg_alloc() : first_seg
);
1325 seg
->obj_index
= obj_idx
;
1329 seg
->currentpos
= 0;
1330 seg
->align
= 1; /* default */
1331 seg
->use32
= FALSE
; /* default */
1332 seg
->combine
= CMB_PUBLIC
; /* default */
1333 seg
->segclass
= seg
->overlay
= NULL
;
1334 seg
->pubhead
= NULL
;
1335 seg
->pubtail
= &seg
->pubhead
;
1336 seg
->lochead
= NULL
;
1337 seg
->loctail
= &seg
->lochead
;
1338 seg
->orp
= obj_new();
1339 seg
->orp
->up
= &(seg
->orp
);
1340 seg
->orp
->ori
= ori_ledata
;
1341 seg
->orp
->type
= LEDATA
;
1342 seg
->orp
->parm
[1] = obj_idx
;
1345 * Process the segment attributes.
1353 * `p' contains a segment attribute.
1355 if (!nasm_stricmp(p
, "private"))
1356 seg
->combine
= CMB_PRIVATE
;
1357 else if (!nasm_stricmp(p
, "public"))
1358 seg
->combine
= CMB_PUBLIC
;
1359 else if (!nasm_stricmp(p
, "common"))
1360 seg
->combine
= CMB_COMMON
;
1361 else if (!nasm_stricmp(p
, "stack"))
1362 seg
->combine
= CMB_STACK
;
1363 else if (!nasm_stricmp(p
, "use16"))
1365 else if (!nasm_stricmp(p
, "use32"))
1367 else if (!nasm_stricmp(p
, "flat")) {
1369 * This segment is an OS/2 FLAT segment. That means
1370 * that its default group is group FLAT, even if
1371 * the group FLAT does not explicitly _contain_ the
1374 * When we see this, we must create the group
1375 * `FLAT', containing no segments, if it does not
1376 * already exist; then we must set the default
1377 * group of this segment to be the FLAT group.
1380 for (grp
= grphead
; grp
; grp
= grp
->next
)
1381 if (!strcmp(grp
->name
, "FLAT"))
1384 obj_directive ("group", "FLAT", 1);
1385 for (grp
= grphead
; grp
; grp
= grp
->next
)
1386 if (!strcmp(grp
->name
, "FLAT"))
1389 error (ERR_PANIC
, "failure to define FLAT?!");
1392 } else if (!nasm_strnicmp(p
, "class=", 6))
1393 seg
->segclass
= nasm_strdup(p
+6);
1394 else if (!nasm_strnicmp(p
, "overlay=", 8))
1395 seg
->overlay
= nasm_strdup(p
+8);
1396 else if (!nasm_strnicmp(p
, "align=", 6)) {
1397 seg
->align
= readnum(p
+6, &rn_error
);
1400 error (ERR_NONFATAL
, "segment alignment should be"
1403 switch ((int) seg
->align
) {
1408 case 256: /* PAGE */
1409 case 4096: /* PharLap extension */
1412 error(ERR_WARNING
, "OBJ format does not support alignment"
1413 " of 8: rounding up to 16");
1419 error(ERR_WARNING
, "OBJ format does not support alignment"
1420 " of %d: rounding up to 256", seg
->align
);
1426 error(ERR_WARNING
, "OBJ format does not support alignment"
1427 " of %d: rounding up to 4096", seg
->align
);
1431 error(ERR_NONFATAL
, "invalid alignment value %d",
1436 } else if (!nasm_strnicmp(p
, "absolute=", 9)) {
1437 seg
->align
= SEG_ABS
+ readnum(p
+9, &rn_error
);
1439 error (ERR_NONFATAL
, "argument to `absolute' segment"
1440 " attribute should be numeric");
1444 /* We need to know whenever we have at least one 32-bit segment */
1445 obj_use32
|= seg
->use32
;
1447 obj_seg_needs_update
= seg
;
1448 if (seg
->align
>= SEG_ABS
)
1449 deflabel (name
, NO_SEG
, seg
->align
- SEG_ABS
,
1450 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1452 deflabel (name
, seg
->index
+1, 0L,
1453 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1454 obj_seg_needs_update
= NULL
;
1457 * See if this segment is defined in any groups.
1459 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1460 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1461 if (!strcmp(grp
->segs
[i
].name
, seg
->name
)) {
1462 nasm_free (grp
->segs
[i
].name
);
1463 grp
->segs
[i
] = grp
->segs
[grp
->nindices
];
1464 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1466 error(ERR_WARNING
, "segment `%s' is already part of"
1467 " a group: first one takes precedence",
1476 * Walk through the list of externals with unresolved
1477 * default-WRT clauses, and resolve any that point at this
1482 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1483 !strcmp((*extp
)->defwrt_ptr
.string
, seg
->name
)) {
1484 nasm_free((*extp
)->defwrt_ptr
.string
);
1485 (*extp
)->defwrt_type
= DEFWRT_SEGMENT
;
1486 (*extp
)->defwrt_ptr
.seg
= seg
;
1487 *extp
= (*extp
)->next_dws
;
1489 extp
= &(*extp
)->next_dws
;
1501 static int obj_directive (char *directive
, char *value
, int pass
)
1503 if (!strcmp(directive
, "group")) {
1507 struct Segment
*seg
;
1508 struct External
**extp
;
1513 q
++; /* hack, but a documented one */
1515 while (*q
&& !isspace(*q
))
1519 while (*q
&& isspace(*q
))
1523 * Here we used to sanity-check the group directive to
1524 * ensure nobody tried to declare a group containing no
1525 * segments. However, OS/2 does this as standard
1526 * practice, so the sanity check has been removed.
1529 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1535 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1537 if (!strcmp(grp
->name
, v
)) {
1538 error(ERR_NONFATAL
, "group `%s' defined twice", v
);
1543 *grptail
= grp
= nasm_malloc(sizeof(*grp
));
1545 grptail
= &grp
->next
;
1546 grp
->index
= seg_alloc();
1547 grp
->obj_index
= obj_idx
;
1548 grp
->nindices
= grp
->nentries
= 0;
1551 obj_grp_needs_update
= grp
;
1552 deflabel (v
, grp
->index
+1, 0L,
1553 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1554 obj_grp_needs_update
= NULL
;
1558 while (*q
&& !isspace(*q
))
1562 while (*q
&& isspace(*q
))
1566 * Now p contains a segment name. Find it.
1568 for (seg
= seghead
; seg
; seg
= seg
->next
)
1569 if (!strcmp(seg
->name
, p
))
1573 * We have a segment index. Shift a name entry
1574 * to the end of the array to make room.
1576 grp
->segs
[grp
->nentries
++] = grp
->segs
[grp
->nindices
];
1577 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1579 error(ERR_WARNING
, "segment `%s' is already part of"
1580 " a group: first one takes precedence",
1586 * We have an as-yet undefined segment.
1587 * Remember its name, for later.
1589 grp
->segs
[grp
->nentries
++].name
= nasm_strdup(p
);
1594 * Walk through the list of externals with unresolved
1595 * default-WRT clauses, and resolve any that point at
1600 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1601 !strcmp((*extp
)->defwrt_ptr
.string
, grp
->name
)) {
1602 nasm_free((*extp
)->defwrt_ptr
.string
);
1603 (*extp
)->defwrt_type
= DEFWRT_GROUP
;
1604 (*extp
)->defwrt_ptr
.grp
= grp
;
1605 *extp
= (*extp
)->next_dws
;
1607 extp
= &(*extp
)->next_dws
;
1612 if (!strcmp(directive
, "uppercase")) {
1613 obj_uppercase
= TRUE
;
1616 if (!strcmp(directive
, "import")) {
1617 char *q
, *extname
, *libname
, *impname
;
1620 return 1; /* ignore in pass two */
1621 extname
= q
= value
;
1622 while (*q
&& !isspace(*q
))
1626 while (*q
&& isspace(*q
))
1631 while (*q
&& !isspace(*q
))
1635 while (*q
&& isspace(*q
))
1641 if (!*extname
|| !*libname
)
1642 error(ERR_NONFATAL
, "`import' directive requires symbol name"
1643 " and library name");
1648 imp
= *imptail
= nasm_malloc(sizeof(struct ImpDef
));
1649 imptail
= &imp
->next
;
1651 imp
->extname
= nasm_strdup(extname
);
1652 imp
->libname
= nasm_strdup(libname
);
1653 imp
->impindex
= readnum(impname
, &err
);
1654 if (!*impname
|| err
)
1655 imp
->impname
= nasm_strdup(impname
);
1657 imp
->impname
= NULL
;
1662 if (!strcmp(directive
, "export")) {
1663 char *q
, *extname
, *intname
, *v
;
1664 struct ExpDef
*export
;
1666 unsigned int ordinal
= 0;
1669 return 1; /* ignore in pass two */
1670 intname
= q
= value
;
1671 while (*q
&& !isspace(*q
))
1675 while (*q
&& isspace(*q
))
1680 while (*q
&& !isspace(*q
))
1684 while (*q
&& isspace(*q
))
1689 error(ERR_NONFATAL
, "`export' directive requires export name");
1698 while (*q
&& !isspace(*q
))
1702 while (*q
&& isspace(*q
))
1705 if (!nasm_stricmp(v
, "resident"))
1706 flags
|= EXPDEF_FLAG_RESIDENT
;
1707 else if (!nasm_stricmp(v
, "nodata"))
1708 flags
|= EXPDEF_FLAG_NODATA
;
1709 else if (!nasm_strnicmp(v
, "parm=", 5)) {
1711 flags
|= EXPDEF_MASK_PARMCNT
& readnum(v
+5, &err
);
1714 "value `%s' for `parm' is non-numeric", v
+5);
1719 ordinal
= readnum(v
, &err
);
1721 error(ERR_NONFATAL
, "unrecognised export qualifier `%s'",
1725 flags
|= EXPDEF_FLAG_ORDINAL
;
1729 export
= *exptail
= nasm_malloc(sizeof(struct ExpDef
));
1730 exptail
= &export
->next
;
1731 export
->next
= NULL
;
1732 export
->extname
= nasm_strdup(extname
);
1733 export
->intname
= nasm_strdup(intname
);
1734 export
->ordinal
= ordinal
;
1735 export
->flags
= flags
;
1742 static long obj_segbase (long segment
)
1744 struct Segment
*seg
;
1747 * Find the segment in our list.
1749 for (seg
= seghead
; seg
; seg
= seg
->next
)
1750 if (seg
->index
== segment
-1)
1755 * Might be an external with a default WRT.
1758 struct ExtBack
*eb
= ebhead
;
1761 while (i
> EXT_BLKSIZ
) {
1770 if (e
->defwrt_type
== DEFWRT_NONE
)
1771 return segment
; /* fine */
1772 else if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1773 return e
->defwrt_ptr
.seg
->index
+1;
1774 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1775 return e
->defwrt_ptr
.grp
->index
+1;
1777 return NO_SEG
; /* can't tell what it is */
1780 return segment
; /* not one of ours - leave it alone */
1783 if (seg
->align
>= SEG_ABS
)
1784 return seg
->align
; /* absolute segment */
1786 return seg
->grp
->index
+1; /* grouped segment */
1788 return segment
; /* no special treatment */
1791 static void obj_filename (char *inname
, char *outname
, efunc lerror
)
1793 strcpy(obj_infile
, inname
);
1794 standard_extension (inname
, outname
, ".obj", lerror
);
1797 static void obj_write_file (int debuginfo
)
1799 struct Segment
*seg
, *entry_seg_ptr
= 0;
1800 struct FileName
*fn
;
1801 struct LineNumber
*ln
;
1803 struct Public
*pub
, *loc
;
1804 struct External
*ext
;
1806 struct ExpDef
*export
;
1807 static char boast
[] = "The Netwide Assembler " NASM_VER
;
1812 * Write the THEADR module header.
1816 obj_name (orp
, obj_infile
);
1820 * Write the NASM boast comment.
1823 obj_rword (orp
, 0); /* comment type zero */
1824 obj_name (orp
, boast
);
1829 * Write the IMPDEF records, if any.
1831 for (imp
= imphead
; imp
; imp
= imp
->next
) {
1832 obj_rword (orp
, 0xA0); /* comment class A0 */
1833 obj_byte (orp
, 1); /* subfunction 1: IMPDEF */
1835 obj_byte (orp
, 0); /* import by name */
1837 obj_byte (orp
, 1); /* import by ordinal */
1838 obj_name (orp
, imp
->extname
);
1839 obj_name (orp
, imp
->libname
);
1841 obj_name (orp
, imp
->impname
);
1843 obj_word (orp
, imp
->impindex
);
1848 * Write the EXPDEF records, if any.
1850 for (export
= exphead
; export
; export
= export
->next
) {
1851 obj_rword (orp
, 0xA0); /* comment class A0 */
1852 obj_byte (orp
, 2); /* subfunction 2: EXPDEF */
1853 obj_byte (orp
, export
->flags
);
1854 obj_name (orp
, export
->extname
);
1855 obj_name (orp
, export
->intname
);
1856 if (export
->flags
& EXPDEF_FLAG_ORDINAL
)
1857 obj_word (orp
, export
->ordinal
);
1861 /* we're using extended OMF if we put in debug info*/
1864 obj_byte (orp
, 0x40);
1865 obj_byte (orp
, dEXTENDED
);
1870 * Write the first LNAMES record, containing LNAME one, which
1871 * is null. Also initialise the LNAME counter.
1877 * Write some LNAMES for the segment names
1879 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1880 orp
= obj_name (orp
, seg
->name
);
1882 orp
= obj_name (orp
, seg
->segclass
);
1884 orp
= obj_name (orp
, seg
->overlay
);
1888 * Write some LNAMES for the group names
1890 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1891 orp
= obj_name (orp
, grp
->name
);
1898 * Write the SEGDEF records.
1901 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1903 unsigned long seglen
= seg
->currentpos
;
1905 acbp
= (seg
->combine
<< 2); /* C field */
1908 acbp
|= 0x01; /* P bit is Use32 flag */
1909 else if (seglen
== 0x10000L
) {
1910 seglen
= 0; /* This special case may be needed for old linkers */
1911 acbp
|= 0x02; /* B bit */
1916 if (seg
->align
>= SEG_ABS
)
1918 else if (seg
->align
>= 4096) {
1919 if (seg
->align
> 4096)
1920 error(ERR_NONFATAL
, "segment `%s' requires more alignment"
1921 " than OBJ format supports", seg
->name
);
1922 acbp
|= 0xC0; /* PharLap extension */
1923 } else if (seg
->align
>= 256) {
1925 } else if (seg
->align
>= 16) {
1927 } else if (seg
->align
>= 4) {
1929 } else if (seg
->align
>= 2) {
1934 obj_byte (orp
, acbp
);
1935 if (seg
->align
& SEG_ABS
) {
1936 obj_x (orp
, seg
->align
- SEG_ABS
); /* Frame */
1937 obj_byte (orp
, 0); /* Offset */
1939 obj_x (orp
, seglen
);
1940 obj_index (orp
, ++lname_idx
);
1941 obj_index (orp
, seg
->segclass
? ++lname_idx
: 1);
1942 obj_index (orp
, seg
->overlay
? ++lname_idx
: 1);
1947 * Write the GRPDEF records.
1950 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1953 if (grp
->nindices
!= grp
->nentries
) {
1954 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1955 error(ERR_NONFATAL
, "group `%s' contains undefined segment"
1956 " `%s'", grp
->name
, grp
->segs
[i
].name
);
1957 nasm_free (grp
->segs
[i
].name
);
1958 grp
->segs
[i
].name
= NULL
;
1961 obj_index (orp
, ++lname_idx
);
1962 for (i
= 0; i
< grp
->nindices
; i
++) {
1963 obj_byte (orp
, 0xFF);
1964 obj_index (orp
, grp
->segs
[i
].index
);
1970 * Write the PUBDEF records: first the ones in the segments,
1971 * then the far-absolutes.
1974 orp
->ori
= ori_pubdef
;
1975 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1976 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
1977 orp
->parm
[1] = seg
->obj_index
;
1978 for (pub
= seg
->pubhead
; pub
; pub
= pub
->next
) {
1979 orp
= obj_name (orp
, pub
->name
);
1980 orp
= obj_x (orp
, pub
->offset
);
1981 orp
= obj_byte (orp
, 0); /* type index */
1988 for (pub
= fpubhead
; pub
; pub
= pub
->next
) { /* pub-crawl :-) */
1989 if (orp
->parm
[2] != pub
->segment
) {
1991 orp
->parm
[2] = pub
->segment
;
1993 orp
= obj_name (orp
, pub
->name
);
1994 orp
= obj_x (orp
, pub
->offset
);
1995 orp
= obj_byte (orp
, 0); /* type index */
2001 * Write the EXTDEF and COMDEF records, in order.
2003 orp
->ori
= ori_null
;
2004 for (ext
= exthead
; ext
; ext
= ext
->next
) {
2005 if (ext
->commonsize
== 0) {
2006 if (orp
->type
!= EXTDEF
) {
2010 orp
= obj_name (orp
, ext
->name
);
2011 orp
= obj_index (orp
, 0);
2013 if (orp
->type
!= COMDEF
) {
2017 orp
= obj_name (orp
, ext
->name
);
2018 orp
= obj_index (orp
, 0);
2019 if (ext
->commonelem
) {
2020 orp
= obj_byte (orp
, 0x61);/* far communal */
2021 orp
= obj_value (orp
, (ext
->commonsize
/ ext
->commonelem
));
2022 orp
= obj_value (orp
, ext
->commonelem
);
2024 orp
= obj_byte (orp
, 0x62);/* near communal */
2025 orp
= obj_value (orp
, ext
->commonsize
);
2033 * Write a COMENT record stating that the linker's first pass
2034 * may stop processing at this point. Exception is if our
2035 * MODEND record specifies a start point, in which case,
2036 * according to some variants of the documentation, this COMENT
2037 * should be omitted. So we'll omit it just in case.
2038 * But, TASM puts it in all the time so if we are using
2039 * TASM debug stuff we are putting it in
2041 if (debuginfo
|| obj_entry_seg
== NO_SEG
) {
2043 obj_byte (orp
, 0x40);
2044 obj_byte (orp
, dLINKPASS
);
2050 * 1) put out the compiler type
2051 * 2) Put out the type info. The only type we are using is near label #19
2055 struct Array
*arrtmp
= arrhead
;
2057 obj_byte (orp
, 0x40);
2058 obj_byte (orp
, dCOMPDEF
);
2063 obj_byte (orp
, 0x40);
2064 obj_byte (orp
, dTYPEDEF
);
2065 obj_word (orp
, 0x18); /* type # for linking */
2066 obj_word (orp
, 6); /* size of type */
2067 obj_byte (orp
, 0x2a); /* absolute type for debugging */
2069 obj_byte (orp
, 0x40);
2070 obj_byte (orp
, dTYPEDEF
);
2071 obj_word (orp
, 0x19); /* type # for linking */
2072 obj_word (orp
, 0); /* size of type */
2073 obj_byte (orp
, 0x24); /* absolute type for debugging */
2074 obj_byte (orp
, 0); /* near/far specifier */
2076 obj_byte (orp
, 0x40);
2077 obj_byte (orp
, dTYPEDEF
);
2078 obj_word (orp
, 0x1A); /* type # for linking */
2079 obj_word (orp
, 0); /* size of type */
2080 obj_byte (orp
, 0x24); /* absolute type for debugging */
2081 obj_byte (orp
, 1); /* near/far specifier */
2083 obj_byte (orp
, 0x40);
2084 obj_byte (orp
, dTYPEDEF
);
2085 obj_word (orp
, 0x1b); /* type # for linking */
2086 obj_word (orp
, 0); /* size of type */
2087 obj_byte (orp
, 0x23); /* absolute type for debugging */
2092 obj_byte (orp
, 0x40);
2093 obj_byte (orp
, dTYPEDEF
);
2094 obj_word (orp
, 0x1c); /* type # for linking */
2095 obj_word (orp
, 0); /* size of type */
2096 obj_byte (orp
, 0x23); /* absolute type for debugging */
2101 obj_byte (orp
, 0x40);
2102 obj_byte (orp
, dTYPEDEF
);
2103 obj_word (orp
, 0x1d); /* type # for linking */
2104 obj_word (orp
, 0); /* size of type */
2105 obj_byte (orp
, 0x23); /* absolute type for debugging */
2110 obj_byte (orp
, 0x40);
2111 obj_byte (orp
, dTYPEDEF
);
2112 obj_word (orp
, 0x1e); /* type # for linking */
2113 obj_word (orp
, 0); /* size of type */
2114 obj_byte (orp
, 0x23); /* absolute type for debugging */
2120 /* put out the array types */
2121 for (i
= ARRAYBOT
; i
< arrindex
; i
++) {
2122 obj_byte (orp
, 0x40);
2123 obj_byte (orp
, dTYPEDEF
);
2124 obj_word (orp
, i
); /* type # for linking */
2125 obj_word (orp
, arrtmp
->size
); /* size of type */
2126 obj_byte (orp
, 0x1A); /* absolute type for debugging (array)*/
2127 obj_byte (orp
, arrtmp
->basetype
); /* base type */
2129 arrtmp
= arrtmp
->next
;
2133 * write out line number info with a LINNUM record
2134 * switch records when we switch segments, and output the
2135 * file in a pseudo-TASM fashion. The record switch is naive; that
2136 * is that one file may have many records for the same segment
2137 * if there are lots of segment switches
2139 if (fnhead
&& debuginfo
) {
2140 seg
= fnhead
->lnhead
->segment
;
2142 for (fn
= fnhead
; fn
; fn
= fn
->next
) {
2143 /* write out current file name */
2145 orp
->ori
= ori_null
;
2146 obj_byte (orp
, 0x40);
2147 obj_byte (orp
, dFILNAME
);
2149 obj_name( orp
,fn
->name
);
2153 /* write out line numbers this file */
2156 orp
->ori
= ori_linnum
;
2157 for (ln
= fn
->lnhead
; ln
; ln
= ln
->next
) {
2158 if (seg
!= ln
->segment
) {
2159 /* if we get here have to flush the buffer and start
2160 * a new record for a new segment
2165 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
2166 orp
->parm
[1] = seg
->obj_index
;
2167 orp
= obj_word(orp
, ln
->lineno
);
2168 orp
= obj_x(orp
, ln
->offset
);
2175 * we are going to locate the entry point segment now
2176 * rather than wait until the MODEND record, because,
2177 * then we can output a special symbol to tell where the
2181 if (obj_entry_seg
!= NO_SEG
) {
2182 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2183 if (seg
->index
== obj_entry_seg
) {
2184 entry_seg_ptr
= seg
;
2189 error(ERR_NONFATAL
, "entry point is not in this module");
2193 * get ready to put out symbol records
2196 orp
->ori
= ori_local
;
2199 * put out a symbol for the entry point
2200 * no dots in this symbol, because, borland does
2201 * not (officially) support dots in label names
2202 * and I don't know what various versions of TLINK will do
2204 if (debuginfo
&& obj_entry_seg
!= NO_SEG
) {
2205 orp
= obj_name (orp
,"start_of_program");
2206 orp
= obj_word (orp
,0x19); /* type: near label */
2207 orp
= obj_index (orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2208 orp
= obj_index (orp
, seg
->obj_index
);
2209 orp
= obj_x (orp
, obj_entry_ofs
);
2214 * put out the local labels
2216 for (seg
= seghead
; seg
&& debuginfo
; seg
= seg
->next
) {
2217 /* labels this seg */
2218 for (loc
= seg
->lochead
; loc
; loc
= loc
->next
) {
2219 orp
= obj_name (orp
,loc
->name
);
2220 orp
= obj_word (orp
, loc
->type
);
2221 orp
= obj_index (orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2222 orp
= obj_index (orp
, seg
->obj_index
);
2223 orp
= obj_x (orp
,loc
->offset
);
2231 * Write the LEDATA/FIXUPP pairs.
2233 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2234 obj_emit (seg
->orp
);
2235 nasm_free (seg
->orp
);
2239 * Write the MODEND module end marker.
2241 orp
->type
= obj_use32
? MODE32
: MODEND
;
2242 orp
->ori
= ori_null
;
2243 if (entry_seg_ptr
) {
2244 orp
->type
= entry_seg_ptr
->use32
? MODE32
: MODEND
;
2245 obj_byte (orp
, 0xC1);
2246 seg
= entry_seg_ptr
;
2248 obj_byte (orp
, 0x10);
2249 obj_index (orp
, seg
->grp
->obj_index
);
2252 * the below changed to prevent TLINK crashing.
2253 * Previous more efficient version read:
2255 * obj_byte (orp, 0x50);
2257 obj_byte (orp
, 0x00);
2258 obj_index (orp
, seg
->obj_index
);
2260 obj_index (orp
, seg
->obj_index
);
2261 obj_x (orp
, obj_entry_ofs
);
2268 void obj_fwrite(ObjRecord
*orp
)
2270 unsigned int cksum
, len
;
2274 if (orp
->x_size
== 32)
2277 len
= orp
->committed
+1;
2278 cksum
+= (len
& 0xFF) + ((len
>>8) & 0xFF);
2279 fwriteshort (len
, ofp
);
2280 fwrite (orp
->buf
, 1, len
-1, ofp
);
2281 for (ptr
=orp
->buf
; --len
; ptr
++)
2283 fputc ( (-cksum
) & 0xFF, ofp
);
2286 static const char *obj_stdmac
[] = {
2287 "%define __SECT__ [section .text]",
2288 "%imacro group 1+.nolist",
2291 "%imacro uppercase 0+.nolist",
2294 "%imacro export 1+.nolist",
2297 "%imacro import 1+.nolist",
2300 "%macro __NASM_CDecl__ 1",
2305 void dbgbi_init(struct ofmt
* of
, void * id
, FILE * fp
, efunc error
)
2314 arrindex
= ARRAYBOT
;
2318 static void dbgbi_cleanup(void)
2320 struct Segment
*segtmp
;
2322 struct FileName
*fntemp
= fnhead
;
2323 while (fnhead
->lnhead
) {
2324 struct LineNumber
*lntemp
= fnhead
->lnhead
;
2325 fnhead
->lnhead
= lntemp
->next
;
2328 fnhead
= fnhead
->next
;
2329 nasm_free (fntemp
->name
);
2332 for (segtmp
=seghead
; segtmp
; segtmp
=segtmp
->next
) {
2333 while (segtmp
->lochead
) {
2334 struct Public
*loctmp
= segtmp
->lochead
;
2335 segtmp
->lochead
= loctmp
->next
;
2336 nasm_free (loctmp
->name
);
2341 struct Array
*arrtmp
= arrhead
;
2342 arrhead
= arrhead
->next
;
2347 static void dbgbi_linnum (const char *lnfname
, long lineno
, long segto
)
2349 struct FileName
*fn
;
2350 struct LineNumber
*ln
;
2351 struct Segment
*seg
;
2353 if (segto
== NO_SEG
)
2357 * If `any_segs' is still FALSE, we must define a default
2361 int tempint
; /* ignored */
2362 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
2363 error (ERR_PANIC
, "strange segment conditions in OBJ driver");
2367 * Find the segment we are targetting.
2369 for (seg
= seghead
; seg
; seg
= seg
->next
)
2370 if (seg
->index
== segto
)
2373 error (ERR_PANIC
, "lineno directed to nonexistent segment?");
2375 /* for (fn = fnhead; fn; fn = fnhead->next) */
2376 for (fn
= fnhead
; fn
; fn
= fn
->next
) /* fbk - Austin Lunnen - John Fine*/
2377 if (!nasm_stricmp(lnfname
,fn
->name
))
2380 fn
= nasm_malloc ( sizeof( *fn
));
2381 fn
->name
= nasm_malloc ( strlen(lnfname
) + 1) ;
2382 strcpy (fn
->name
,lnfname
);
2384 fn
->lntail
= & fn
->lnhead
;
2389 ln
= nasm_malloc ( sizeof( *ln
));
2391 ln
->offset
= seg
->currentpos
;
2392 ln
->lineno
= lineno
;
2395 fn
->lntail
= &ln
->next
;
2398 static void dbgbi_deflabel (char *name
, long segment
,
2399 long offset
, int is_global
, char *special
)
2401 struct Segment
*seg
;
2406 * If it's a special-retry from pass two, discard it.
2412 * First check for the double-period, signifying something
2415 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
2422 if (obj_seg_needs_update
) {
2424 } else if (obj_grp_needs_update
) {
2427 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
2430 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
2435 * If `any_segs' is still FALSE, we might need to define a
2436 * default segment, if they're trying to declare a label in
2437 * `first_seg'. But the label should exist due to a prior
2438 * call to obj_deflabel so we can skip that.
2441 for (seg
= seghead
; seg
; seg
= seg
->next
)
2442 if (seg
->index
== segment
) {
2443 struct Public
*loc
= nasm_malloc (sizeof(*loc
));
2445 * Case (ii). Maybe MODPUB someday?
2447 last_defined
= *seg
->loctail
= loc
;
2448 seg
->loctail
= &loc
->next
;
2450 loc
->name
= nasm_strdup(name
);
2451 loc
->offset
= offset
;
2454 static void dbgbi_typevalue (long type
)
2457 int elem
= TYM_ELEMENTS(type
);
2458 type
= TYM_TYPE(type
);
2465 last_defined
->type
= 8; /* unsigned char */
2469 last_defined
->type
= 10; /* unsigned word */
2473 last_defined
->type
= 12; /* unsigned dword */
2477 last_defined
->type
= 14; /* float */
2481 last_defined
->type
= 15; /* qword */
2485 last_defined
->type
= 16; /* TBYTE */
2489 last_defined
->type
= 0x19; /*label */
2495 struct Array
*arrtmp
= nasm_malloc (sizeof(*arrtmp
));
2496 int vtype
= last_defined
->type
;
2497 arrtmp
->size
= vsize
* elem
;
2498 arrtmp
->basetype
= vtype
;
2499 arrtmp
->next
= NULL
;
2500 last_defined
->type
= arrindex
++;
2502 arrtail
= & (arrtmp
->next
);
2504 last_defined
= NULL
;
2506 static void dbgbi_output (int output_type
, void *param
)
2511 static struct dfmt borland_debug_form
= {
2512 "Borland Debug Records",
2523 static struct dfmt
*borland_debug_arr
[3] = {
2524 &borland_debug_form
,
2529 struct ofmt of_obj
= {
2530 "MS-DOS 16-bit/32-bit OMF object files",