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 license given in the file "LICENSE"
7 * distributed in the NASM archive.
26 * outobj.c is divided into two sections. The first section is low level
27 * routines for creating obj records; It has nearly zero NASM specific
28 * code. The second section is high level routines for processing calls and
29 * data structures from the rest of NASM into obj format.
31 * It should be easy (though not zero work) to lift the first section out for
32 * use as an obj file writer for some other assembler or compiler.
36 * These routines are built around the ObjRecord data struture. An ObjRecord
37 * holds an object file record that may be under construction or complete.
39 * A major function of these routines is to support continuation of an obj
40 * record into the next record when the maximum record size is exceeded. The
41 * high level code does not need to worry about where the record breaks occur.
42 * It does need to do some minor extra steps to make the automatic continuation
43 * work. Those steps may be skipped for records where the high level knows no
44 * continuation could be required.
46 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
47 * is cleared by obj_clear.
49 * 2) The caller should fill in .type.
51 * 3) If the record is continuable and there is processing that must be done at
52 * the start of each record then the caller should fill in .ori with the
53 * address of the record initializer routine.
55 * 4) If the record is continuable and it should be saved (rather than emitted
56 * immediately) as each record is done, the caller should set .up to be a
57 * pointer to a location in which the caller keeps the master pointer to the
58 * ObjRecord. When the record is continued, the obj_bump routine will then
59 * allocate a new ObjRecord structure and update the master pointer.
61 * 5) If the .ori field was used then the caller should fill in the .parm with
62 * any data required by the initializer.
64 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
65 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
66 * data required for this record.
68 * 7) If the record is continuable, the caller should call obj_commit at each
69 * point where breaking the record is permitted.
71 * 8) To write out the record, the caller should call obj_emit2. If the
72 * caller has called obj_commit for all data written then he can get slightly
73 * faster code by calling obj_emit instead of obj_emit2.
75 * Most of these routines return an ObjRecord pointer. This will be the input
76 * pointer most of the time and will be the new location if the ObjRecord
77 * moved as a result of the call. The caller may ignore the return value in
78 * three cases: It is a "Never Reallocates" routine; or The caller knows
79 * continuation is not possible; or The caller uses the master pointer for the
83 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
84 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
86 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
87 #define FIX_16_OFFSET 0x8400
88 #define FIX_16_SELECTOR 0x8800
89 #define FIX_32_POINTER 0x8C00
90 #define FIX_08_HIGH 0x9000
91 #define FIX_32_OFFSET 0xA400
92 #define FIX_48_POINTER 0xAC00
94 enum RecordID
{ /* record ID codes */
96 THEADR
= 0x80, /* module header */
97 COMENT
= 0x88, /* comment record */
99 LINNUM
= 0x94, /* line number record */
100 LNAMES
= 0x96, /* list of names */
102 SEGDEF
= 0x98, /* segment definition */
103 GRPDEF
= 0x9A, /* group definition */
104 EXTDEF
= 0x8C, /* external definition */
105 PUBDEF
= 0x90, /* public definition */
106 COMDEF
= 0xB0, /* common definition */
108 LEDATA
= 0xA0, /* logical enumerated data */
109 FIXUPP
= 0x9C, /* fixups (relocations) */
110 FIXU32
= 0x9D, /* 32-bit fixups (relocations) */
112 MODEND
= 0x8A, /* module end */
113 MODE32
= 0x8B /* module end for 32-bit objects */
116 enum ComentID
{ /* ID codes for comment records */
118 dEXTENDED
= 0xA1, /* tells that we are using translator-specific extensions */
119 dLINKPASS
= 0xA2, /* link pass 2 marker */
120 dTYPEDEF
= 0xE3, /* define a type */
121 dSYM
= 0xE6, /* symbol debug record */
122 dFILNAME
= 0xE8, /* file name record */
123 dCOMPDEF
= 0xEA /* compiler type info */
126 typedef struct ObjRecord ObjRecord
;
127 typedef void ORI(ObjRecord
* orp
);
130 ORI
*ori
; /* Initialization routine */
131 int used
; /* Current data size */
132 int committed
; /* Data size at last boundary */
133 int x_size
; /* (see obj_x) */
134 unsigned int type
; /* Record type */
135 ObjRecord
*child
; /* Associated record below this one */
136 ObjRecord
**up
; /* Master pointer to this ObjRecord */
137 ObjRecord
*back
; /* Previous part of this record */
138 uint32_t parm
[OBJ_PARMS
]; /* Parameters for ori routine */
139 uint8_t buf
[RECORD_MAX
+ 3];
142 static void obj_fwrite(ObjRecord
* orp
);
143 static void ori_ledata(ObjRecord
* orp
);
144 static void ori_pubdef(ObjRecord
* orp
);
145 static void ori_null(ObjRecord
* orp
);
146 static ObjRecord
*obj_commit(ObjRecord
* orp
);
148 static bool obj_uppercase
; /* Flag: all names in uppercase */
149 static bool obj_use32
; /* Flag: at least one segment is 32-bit */
152 * Clear an ObjRecord structure. (Never reallocates).
153 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
155 static ObjRecord
*obj_clear(ObjRecord
* orp
)
167 * Emit an ObjRecord structure. (Never reallocates).
168 * The record is written out preceeded (recursively) by its previous part (if
169 * any) and followed (recursively) by its child (if any).
170 * The previous part and the child are freed. The main ObjRecord is cleared,
173 static ObjRecord
*obj_emit(ObjRecord
* orp
)
177 nasm_free(orp
->back
);
184 obj_emit(orp
->child
);
185 nasm_free(orp
->child
);
188 return (obj_clear(orp
));
192 * Commit and Emit a record. (Never reallocates).
194 static ObjRecord
*obj_emit2(ObjRecord
* orp
)
197 return (obj_emit(orp
));
201 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
203 static ObjRecord
*obj_new(void)
207 orp
= obj_clear(nasm_malloc(sizeof(ObjRecord
)));
213 * Advance to the next record because the existing one is full or its x_size
215 * Any uncommited data is moved into the next record.
217 static ObjRecord
*obj_bump(ObjRecord
* orp
)
220 int used
= orp
->used
;
221 int committed
= orp
->committed
;
224 *orp
->up
= nxt
= obj_new();
226 nxt
->type
= orp
->type
;
229 memcpy(nxt
->parm
, orp
->parm
, sizeof(orp
->parm
));
237 nxt
->committed
= nxt
->used
;
238 memcpy(nxt
->buf
+ nxt
->committed
, orp
->buf
+ committed
, used
);
239 nxt
->used
= nxt
->committed
+ used
;
246 * Advance to the next record if necessary to allow the next field to fit.
248 static ObjRecord
*obj_check(ObjRecord
* orp
, int size
)
250 if (orp
->used
+ size
> RECORD_MAX
)
253 if (!orp
->committed
) {
256 orp
->committed
= orp
->used
;
263 * All data written so far is commited to the current record (won't be moved to
264 * the next record in case of continuation).
266 static ObjRecord
*obj_commit(ObjRecord
* orp
)
268 orp
->committed
= orp
->used
;
275 static ObjRecord
*obj_byte(ObjRecord
* orp
, uint8_t val
)
277 orp
= obj_check(orp
, 1);
278 orp
->buf
[orp
->used
] = val
;
286 static ObjRecord
*obj_word(ObjRecord
* orp
, unsigned int val
)
288 orp
= obj_check(orp
, 2);
289 orp
->buf
[orp
->used
] = val
;
290 orp
->buf
[orp
->used
+ 1] = val
>> 8;
296 * Write a reversed word
298 static ObjRecord
*obj_rword(ObjRecord
* orp
, unsigned int val
)
300 orp
= obj_check(orp
, 2);
301 orp
->buf
[orp
->used
] = val
>> 8;
302 orp
->buf
[orp
->used
+ 1] = val
;
310 static ObjRecord
*obj_dword(ObjRecord
* orp
, uint32_t val
)
312 orp
= obj_check(orp
, 4);
313 orp
->buf
[orp
->used
] = val
;
314 orp
->buf
[orp
->used
+ 1] = val
>> 8;
315 orp
->buf
[orp
->used
+ 2] = val
>> 16;
316 orp
->buf
[orp
->used
+ 3] = val
>> 24;
322 * All fields of "size x" in one obj record must be the same size (either 16
323 * bits or 32 bits). There is a one bit flag in each record which specifies
325 * This routine is used to force the current record to have the desired
326 * x_size. x_size is normally automatic (using obj_x), so that this
327 * routine should be used outside obj_x, only to provide compatibility with
328 * linkers that have bugs in their processing of the size bit.
331 static ObjRecord
*obj_force(ObjRecord
* orp
, int x
)
333 if (orp
->x_size
== (x
^ 48))
340 * This routine writes a field of size x. The caller does not need to worry at
341 * all about whether 16-bits or 32-bits are required.
343 static ObjRecord
*obj_x(ObjRecord
* orp
, uint32_t val
)
348 orp
= obj_force(orp
, 32);
349 if (orp
->x_size
== 32) {
350 ObjRecord
*nxt
= obj_dword(orp
, val
);
351 nxt
->x_size
= 32; /* x_size is cleared when a record overflows */
355 return (obj_word(orp
, val
));
361 static ObjRecord
*obj_index(ObjRecord
* orp
, unsigned int val
)
364 return (obj_byte(orp
, val
));
365 return (obj_word(orp
, (val
>> 8) | (val
<< 8) | 0x80));
369 * Writes a variable length value
371 static ObjRecord
*obj_value(ObjRecord
* orp
, uint32_t val
)
374 return (obj_byte(orp
, val
));
376 orp
= obj_byte(orp
, 129);
377 return (obj_word(orp
, val
));
380 return (obj_dword(orp
, (val
<< 8) + 132));
381 orp
= obj_byte(orp
, 136);
382 return (obj_dword(orp
, val
));
386 * Writes a counted string
388 static ObjRecord
*obj_name(ObjRecord
* orp
, const char *name
)
390 int len
= strlen(name
);
393 orp
= obj_check(orp
, len
+ 1);
394 ptr
= orp
->buf
+ orp
->used
;
396 orp
->used
+= len
+ 1;
399 *ptr
++ = toupper(*name
);
402 memcpy(ptr
, name
, len
);
407 * Initializer for an LEDATA record.
409 * parm[1] = segment index
410 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
411 * represent the offset that would be required if the record were split at the
413 * parm[2] is a copy of parm[0] as it was when the current record was initted.
415 static void ori_ledata(ObjRecord
* orp
)
417 obj_index(orp
, orp
->parm
[1]);
418 orp
->parm
[2] = orp
->parm
[0];
419 obj_x(orp
, orp
->parm
[0]);
423 * Initializer for a PUBDEF record.
424 * parm[0] = group index
425 * parm[1] = segment index
426 * parm[2] = frame (only used when both indexes are zero)
428 static void ori_pubdef(ObjRecord
* orp
)
430 obj_index(orp
, orp
->parm
[0]);
431 obj_index(orp
, orp
->parm
[1]);
432 if (!(orp
->parm
[0] | orp
->parm
[1]))
433 obj_word(orp
, orp
->parm
[2]);
437 * Initializer for a LINNUM record.
438 * parm[0] = group index
439 * parm[1] = segment index
441 static void ori_linnum(ObjRecord
* orp
)
443 obj_index(orp
, orp
->parm
[0]);
444 obj_index(orp
, orp
->parm
[1]);
448 * Initializer for a local vars record.
450 static void ori_local(ObjRecord
* orp
)
457 * Null initializer for records that continue without any header info
459 static void ori_null(ObjRecord
* orp
)
461 (void)orp
; /* Do nothing */
465 * This concludes the low level section of outobj.c
468 static char obj_infile
[FILENAME_MAX
];
471 static evalfunc evaluate
;
472 static ldfunc deflabel
;
474 static int32_t first_seg
;
475 static bool any_segs
;
479 #define GROUP_MAX 256 /* we won't _realistically_ have more
480 * than this many segs in a group */
481 #define EXT_BLKSIZ 256 /* block size for externals list */
483 struct Segment
; /* need to know these structs exist */
487 struct LineNumber
*next
;
488 struct Segment
*segment
;
493 static struct FileName
{
494 struct FileName
*next
;
496 struct LineNumber
*lnhead
, **lntail
;
500 static struct Array
{
504 } *arrhead
, **arrtail
;
506 #define ARRAYBOT 31 /* magic number for first array index */
508 static struct Public
{
512 int32_t segment
; /* only if it's far-absolute */
513 int type
; /* only for local debug syms */
514 } *fpubhead
, **fpubtail
, *last_defined
;
516 static struct External
{
517 struct External
*next
;
520 int32_t commonelem
; /* element size if FAR, else zero */
521 int index
; /* OBJ-file external index */
523 DEFWRT_NONE
, /* no unusual default-WRT */
524 DEFWRT_STRING
, /* a string we don't yet understand */
525 DEFWRT_SEGMENT
, /* a segment */
526 DEFWRT_GROUP
/* a group */
533 struct External
*next_dws
; /* next with DEFWRT_STRING */
534 } *exthead
, **exttail
, *dws
;
536 static int externals
;
538 static struct ExtBack
{
539 struct ExtBack
*next
;
540 struct External
*exts
[EXT_BLKSIZ
];
543 static struct Segment
{
544 struct Segment
*next
;
545 int32_t index
; /* the NASM segment id */
546 int32_t obj_index
; /* the OBJ-file segment index */
547 struct Group
*grp
; /* the group it beint32_ts to */
549 int32_t align
; /* can be SEG_ABS + absolute addr */
556 bool use32
; /* is this segment 32-bit? */
557 struct Public
*pubhead
, **pubtail
, *lochead
, **loctail
;
559 char *segclass
, *overlay
; /* `class' is a C++ keyword :-) */
561 } *seghead
, **segtail
, *obj_seg_needs_update
;
563 static struct Group
{
566 int32_t index
; /* NASM segment id */
567 int32_t obj_index
; /* OBJ-file group index */
568 int32_t nentries
; /* number of elements... */
569 int32_t nindices
; /* ...and number of index elts... */
573 } segs
[GROUP_MAX
]; /* ...in this */
574 } *grphead
, **grptail
, *obj_grp_needs_update
;
576 static struct ImpDef
{
580 unsigned int impindex
;
582 } *imphead
, **imptail
;
584 static struct ExpDef
{
588 unsigned int ordinal
;
590 } *exphead
, **exptail
;
592 #define EXPDEF_FLAG_ORDINAL 0x80
593 #define EXPDEF_FLAG_RESIDENT 0x40
594 #define EXPDEF_FLAG_NODATA 0x20
595 #define EXPDEF_MASK_PARMCNT 0x1F
597 static int32_t obj_entry_seg
, obj_entry_ofs
;
601 /* The current segment */
602 static struct Segment
*current_seg
;
604 static int32_t obj_segment(char *, int, int *);
605 static void obj_write_file(int debuginfo
);
606 static int obj_directive(char *, char *, int);
608 static void obj_init(FILE * fp
, efunc errfunc
, ldfunc ldef
, evalfunc eval
)
614 first_seg
= seg_alloc();
617 fpubtail
= &fpubhead
;
628 seghead
= obj_seg_needs_update
= NULL
;
630 grphead
= obj_grp_needs_update
= NULL
;
632 obj_entry_seg
= NO_SEG
;
633 obj_uppercase
= false;
638 of_obj
.current_dfmt
->init(&of_obj
, NULL
, fp
, errfunc
);
641 static int obj_set_info(enum geninfo type
, char **val
)
648 static void obj_cleanup(int debuginfo
)
650 obj_write_file(debuginfo
);
651 of_obj
.current_dfmt
->cleanup();
654 struct Segment
*segtmp
= seghead
;
655 seghead
= seghead
->next
;
656 while (segtmp
->pubhead
) {
657 struct Public
*pubtmp
= segtmp
->pubhead
;
658 segtmp
->pubhead
= pubtmp
->next
;
659 nasm_free(pubtmp
->name
);
662 nasm_free(segtmp
->segclass
);
663 nasm_free(segtmp
->overlay
);
667 struct Public
*pubtmp
= fpubhead
;
668 fpubhead
= fpubhead
->next
;
669 nasm_free(pubtmp
->name
);
673 struct External
*exttmp
= exthead
;
674 exthead
= exthead
->next
;
678 struct ImpDef
*imptmp
= imphead
;
679 imphead
= imphead
->next
;
680 nasm_free(imptmp
->extname
);
681 nasm_free(imptmp
->libname
);
682 nasm_free(imptmp
->impname
); /* nasm_free won't mind if it's NULL */
686 struct ExpDef
*exptmp
= exphead
;
687 exphead
= exphead
->next
;
688 nasm_free(exptmp
->extname
);
689 nasm_free(exptmp
->intname
);
693 struct ExtBack
*ebtmp
= ebhead
;
694 ebhead
= ebhead
->next
;
698 struct Group
*grptmp
= grphead
;
699 grphead
= grphead
->next
;
704 static void obj_ext_set_defwrt(struct External
*ext
, char *id
)
709 for (seg
= seghead
; seg
; seg
= seg
->next
)
710 if (!strcmp(seg
->name
, id
)) {
711 ext
->defwrt_type
= DEFWRT_SEGMENT
;
712 ext
->defwrt_ptr
.seg
= seg
;
717 for (grp
= grphead
; grp
; grp
= grp
->next
)
718 if (!strcmp(grp
->name
, id
)) {
719 ext
->defwrt_type
= DEFWRT_GROUP
;
720 ext
->defwrt_ptr
.grp
= grp
;
725 ext
->defwrt_type
= DEFWRT_STRING
;
726 ext
->defwrt_ptr
.string
= id
;
731 static void obj_deflabel(char *name
, int32_t segment
,
732 int64_t offset
, int is_global
, char *special
)
735 * We have three cases:
737 * (i) `segment' is a segment-base. If so, set the name field
738 * for the segment or group structure it refers to, and then
741 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
742 * Save the label position for later output of a PUBDEF record.
743 * (Or a MODPUB, if we work out how.)
745 * (iii) `segment' is not one of our segments. Save the label
746 * position for later output of an EXTDEF, and also store a
747 * back-reference so that we can map later references to this
748 * segment number to the external index.
750 struct External
*ext
;
754 bool used_special
= false; /* have we used the special text? */
756 #if defined(DEBUG) && DEBUG>2
758 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
759 name
, segment
, offset
, is_global
, special
);
763 * If it's a special-retry from pass two, discard it.
769 * First check for the double-period, signifying something
772 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
773 if (!strcmp(name
, "..start")) {
774 obj_entry_seg
= segment
;
775 obj_entry_ofs
= offset
;
778 error(ERR_NONFATAL
, "unrecognised special symbol `%s'", name
);
784 if (obj_seg_needs_update
) {
785 obj_seg_needs_update
->name
= name
;
787 } else if (obj_grp_needs_update
) {
788 obj_grp_needs_update
->name
= name
;
791 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
794 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
796 * SEG_ABS subcase of (ii).
801 pub
= *fpubtail
= nasm_malloc(sizeof(*pub
));
802 fpubtail
= &pub
->next
;
804 pub
->name
= nasm_strdup(name
);
805 pub
->offset
= offset
;
806 pub
->segment
= (segment
== NO_SEG
? 0 : segment
& ~SEG_ABS
);
809 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
810 " for this symbol type");
815 * If `any_segs' is still false, we might need to define a
816 * default segment, if they're trying to declare a label in
819 if (!any_segs
&& segment
== first_seg
) {
820 int tempint
; /* ignored */
821 if (segment
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
822 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
825 for (seg
= seghead
; seg
&& is_global
; seg
= seg
->next
)
826 if (seg
->index
== segment
) {
827 struct Public
*loc
= nasm_malloc(sizeof(*loc
));
829 * Case (ii). Maybe MODPUB someday?
832 seg
->pubtail
= &loc
->next
;
834 loc
->name
= nasm_strdup(name
);
835 loc
->offset
= offset
;
839 "OBJ supports no special symbol features"
840 " for this symbol type");
848 ext
= *exttail
= nasm_malloc(sizeof(*ext
));
850 exttail
= &ext
->next
;
852 /* Place by default all externs into the current segment */
853 ext
->defwrt_type
= DEFWRT_NONE
;
855 /* 28-Apr-2002 - John Coffman
856 The following code was introduced on 12-Aug-2000, and breaks fixups
857 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
858 (5.10). It was introduced after FIXUP32 was added, and may be needed
859 for 32-bit segments. The following will get 16-bit segments working
860 again, and maybe someone can correct the 'if' condition which is
866 if (current_seg
&& current_seg
->use32
) {
867 if (current_seg
->grp
) {
868 ext
->defwrt_type
= DEFWRT_GROUP
;
869 ext
->defwrt_ptr
.grp
= current_seg
->grp
;
871 ext
->defwrt_type
= DEFWRT_SEGMENT
;
872 ext
->defwrt_ptr
.seg
= current_seg
;
877 if (is_global
== 2) {
878 ext
->commonsize
= offset
;
879 ext
->commonelem
= 1; /* default FAR */
886 * Now process the special text, if any, to find default-WRT
887 * specifications and common-variable element-size and near/far
890 while (special
&& *special
) {
894 * We might have a default-WRT specification.
896 if (!nasm_strnicmp(special
, "wrt", 3)) {
900 special
+= strspn(special
, " \t");
901 p
= nasm_strndup(special
, len
= strcspn(special
, ":"));
902 obj_ext_set_defwrt(ext
, p
);
904 if (*special
&& *special
!= ':')
905 error(ERR_NONFATAL
, "`:' expected in special symbol"
906 " text for `%s'", ext
->name
);
907 else if (*special
== ':')
912 * The NEAR or FAR keywords specify nearness or
913 * farness. FAR gives default element size 1.
915 if (!nasm_strnicmp(special
, "far", 3)) {
920 "`%s': `far' keyword may only be applied"
921 " to common variables\n", ext
->name
);
923 special
+= strspn(special
, " \t");
924 } else if (!nasm_strnicmp(special
, "near", 4)) {
929 "`%s': `far' keyword may only be applied"
930 " to common variables\n", ext
->name
);
932 special
+= strspn(special
, " \t");
936 * If it's a common, and anything else remains on the line
937 * before a further colon, evaluate it as an expression and
938 * use that as the element size. Forward references aren't
944 if (ext
->commonsize
) {
946 struct tokenval tokval
;
949 stdscan_bufptr
= special
;
950 tokval
.t_type
= TOKEN_INVALID
;
951 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, error
, NULL
);
954 error(ERR_NONFATAL
, "cannot use relocatable"
955 " expression as common-variable element size");
957 ext
->commonelem
= reloc_value(e
);
959 special
= stdscan_bufptr
;
962 "`%s': element-size specifications only"
963 " apply to common variables", ext
->name
);
964 while (*special
&& *special
!= ':')
975 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
979 while (i
>= EXT_BLKSIZ
) {
983 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
990 ext
->index
= ++externals
;
992 if (special
&& !used_special
)
993 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
994 " for this symbol type");
997 /* forward declaration */
998 static void obj_write_fixup(ObjRecord
* orp
, int bytes
,
999 int segrel
, int32_t seg
, int32_t wrt
,
1000 struct Segment
*segto
);
1002 static void obj_out(int32_t segto
, const void *data
,
1003 enum out_type type
, uint64_t size
,
1004 int32_t segment
, int32_t wrt
)
1006 const uint8_t *ucdata
;
1008 struct Segment
*seg
;
1012 * handle absolute-assembly (structure definitions)
1014 if (segto
== NO_SEG
) {
1015 if (type
!= OUT_RESERVE
)
1016 error(ERR_NONFATAL
, "attempt to assemble code in [ABSOLUTE]"
1022 * If `any_segs' is still false, we must define a default
1026 int tempint
; /* ignored */
1027 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
1028 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
1032 * Find the segment we are targetting.
1034 for (seg
= seghead
; seg
; seg
= seg
->next
)
1035 if (seg
->index
== segto
)
1038 error(ERR_PANIC
, "code directed to nonexistent segment?");
1041 orp
->parm
[0] = seg
->currentpos
;
1043 if (type
== OUT_RAWDATA
) {
1047 orp
= obj_check(seg
->orp
, 1);
1048 len
= RECORD_MAX
- orp
->used
;
1051 memcpy(orp
->buf
+ orp
->used
, ucdata
, len
);
1052 orp
->committed
= orp
->used
+= len
;
1053 orp
->parm
[0] = seg
->currentpos
+= len
;
1057 } else if (type
== OUT_ADDRESS
|| type
== OUT_REL2ADR
||
1058 type
== OUT_REL4ADR
) {
1061 if (segment
== NO_SEG
&& type
!= OUT_ADDRESS
)
1062 error(ERR_NONFATAL
, "relative call to absolute address not"
1063 " supported by OBJ format");
1064 if (segment
>= SEG_ABS
)
1065 error(ERR_NONFATAL
, "far-absolute relocations not supported"
1067 ldata
= *(int64_t *)data
;
1068 if (type
== OUT_REL2ADR
) {
1069 ldata
+= (size
- 2);
1071 } else if (type
== OUT_REL4ADR
) {
1072 ldata
+= (size
- 4);
1076 orp
= obj_word(orp
, ldata
);
1078 orp
= obj_dword(orp
, ldata
);
1080 if (segment
< SEG_ABS
&& (segment
!= NO_SEG
&& segment
% 2) &&
1083 * This is a 4-byte segment-base relocation such as
1084 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1085 * these, but if the constant term has the 16 low bits
1086 * zero, we can just apply a 2-byte segment-base
1087 * relocation to the low word instead.
1091 error(ERR_NONFATAL
, "OBJ format cannot handle complex"
1092 " dword-size segment base references");
1094 if (segment
!= NO_SEG
)
1095 obj_write_fixup(orp
, rsize
,
1096 (type
== OUT_ADDRESS
? 0x4000 : 0),
1098 seg
->currentpos
+= size
;
1099 } else if (type
== OUT_RESERVE
) {
1101 orp
= obj_bump(orp
);
1102 seg
->currentpos
+= size
;
1107 static void obj_write_fixup(ObjRecord
* orp
, int bytes
,
1108 int segrel
, int32_t seg
, int32_t wrt
,
1109 struct Segment
*segto
)
1115 struct Segment
*s
= NULL
;
1116 struct Group
*g
= NULL
;
1117 struct External
*e
= NULL
;
1121 error(ERR_NONFATAL
, "`obj' output driver does not support"
1122 " one-byte relocations");
1128 orp
->child
= forp
= obj_new();
1129 forp
->up
= &(orp
->child
);
1130 /* We should choose between FIXUPP and FIXU32 record type */
1131 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1133 forp
->type
= FIXU32
;
1135 forp
->type
= FIXUPP
;
1140 locat
= FIX_16_SELECTOR
;
1143 error(ERR_PANIC
, "OBJ: 4-byte segment base fixup got"
1144 " through sanity check");
1147 locat
= (bytes
== 2) ? FIX_16_OFFSET
: FIX_32_OFFSET
;
1150 * There is a bug in tlink that makes it process self relative
1151 * fixups incorrectly if the x_size doesn't match the location
1154 forp
= obj_force(forp
, bytes
<< 3);
1157 forp
= obj_rword(forp
, locat
| segrel
| (orp
->parm
[0] - orp
->parm
[2]));
1159 tidx
= fidx
= -1, method
= 0; /* placate optimisers */
1162 * See if we can find the segment ID in our segment list. If
1163 * so, we have a T4 (LSEG) target.
1165 for (s
= seghead
; s
; s
= s
->next
)
1166 if (s
->index
== seg
)
1169 method
= 4, tidx
= s
->obj_index
;
1171 for (g
= grphead
; g
; g
= g
->next
)
1172 if (g
->index
== seg
)
1175 method
= 5, tidx
= g
->obj_index
;
1177 int32_t i
= seg
/ 2;
1178 struct ExtBack
*eb
= ebhead
;
1179 while (i
>= EXT_BLKSIZ
) {
1187 method
= 6, e
= eb
->exts
[i
], tidx
= e
->index
;
1190 "unrecognised segment value in obj_write_fixup");
1195 * If no WRT given, assume the natural default, which is method
1198 * - we are doing an OFFSET fixup for a grouped segment, in
1199 * which case we require F1 (group).
1201 * - we are doing an OFFSET fixup for an external with a
1202 * default WRT, in which case we must honour the default WRT.
1204 if (wrt
== NO_SEG
) {
1205 if (!base
&& s
&& s
->grp
)
1206 method
|= 0x10, fidx
= s
->grp
->obj_index
;
1207 else if (!base
&& e
&& e
->defwrt_type
!= DEFWRT_NONE
) {
1208 if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1209 method
|= 0x00, fidx
= e
->defwrt_ptr
.seg
->obj_index
;
1210 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1211 method
|= 0x10, fidx
= e
->defwrt_ptr
.grp
->obj_index
;
1213 error(ERR_NONFATAL
, "default WRT specification for"
1214 " external `%s' unresolved", e
->name
);
1215 method
|= 0x50, fidx
= -1; /* got to do _something_ */
1218 method
|= 0x50, fidx
= -1;
1221 * See if we can find the WRT-segment ID in our segment
1222 * list. If so, we have a F0 (LSEG) frame.
1224 for (s
= seghead
; s
; s
= s
->next
)
1225 if (s
->index
== wrt
- 1)
1228 method
|= 0x00, fidx
= s
->obj_index
;
1230 for (g
= grphead
; g
; g
= g
->next
)
1231 if (g
->index
== wrt
- 1)
1234 method
|= 0x10, fidx
= g
->obj_index
;
1236 int32_t i
= wrt
/ 2;
1237 struct ExtBack
*eb
= ebhead
;
1238 while (i
>= EXT_BLKSIZ
) {
1246 method
|= 0x20, fidx
= eb
->exts
[i
]->index
;
1249 "unrecognised WRT value in obj_write_fixup");
1254 forp
= obj_byte(forp
, method
);
1256 forp
= obj_index(forp
, fidx
);
1257 forp
= obj_index(forp
, tidx
);
1261 static int32_t obj_segment(char *name
, int pass
, int *bits
)
1264 * We call the label manager here to define a name for the new
1265 * segment, and when our _own_ label-definition stub gets
1266 * called in return, it should register the new segment name
1267 * using the pointer it gets passed. That way we save memory,
1268 * by sponging off the label manager.
1270 #if defined(DEBUG) && DEBUG>=3
1271 fprintf(stderr
, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1279 struct Segment
*seg
;
1281 struct External
**extp
;
1282 int obj_idx
, i
, attrs
;
1287 * Look for segment attributes.
1290 while (*name
== '.')
1291 name
++; /* hack, but a documented one */
1293 while (*p
&& !nasm_isspace(*p
))
1297 while (*p
&& nasm_isspace(*p
))
1301 while (*p
&& !nasm_isspace(*p
))
1305 while (*p
&& nasm_isspace(*p
))
1313 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1315 if (!strcmp(seg
->name
, name
)) {
1316 if (attrs
> 0 && pass
== 1)
1317 error(ERR_WARNING
, "segment attributes specified on"
1318 " redeclaration of segment: ignoring");
1328 *segtail
= seg
= nasm_malloc(sizeof(*seg
));
1330 segtail
= &seg
->next
;
1331 seg
->index
= (any_segs
? seg_alloc() : first_seg
);
1332 seg
->obj_index
= obj_idx
;
1336 seg
->currentpos
= 0;
1337 seg
->align
= 1; /* default */
1338 seg
->use32
= false; /* default */
1339 seg
->combine
= CMB_PUBLIC
; /* default */
1340 seg
->segclass
= seg
->overlay
= NULL
;
1341 seg
->pubhead
= NULL
;
1342 seg
->pubtail
= &seg
->pubhead
;
1343 seg
->lochead
= NULL
;
1344 seg
->loctail
= &seg
->lochead
;
1345 seg
->orp
= obj_new();
1346 seg
->orp
->up
= &(seg
->orp
);
1347 seg
->orp
->ori
= ori_ledata
;
1348 seg
->orp
->type
= LEDATA
;
1349 seg
->orp
->parm
[1] = obj_idx
;
1352 * Process the segment attributes.
1361 * `p' contains a segment attribute.
1363 if (!nasm_stricmp(p
, "private"))
1364 seg
->combine
= CMB_PRIVATE
;
1365 else if (!nasm_stricmp(p
, "public"))
1366 seg
->combine
= CMB_PUBLIC
;
1367 else if (!nasm_stricmp(p
, "common"))
1368 seg
->combine
= CMB_COMMON
;
1369 else if (!nasm_stricmp(p
, "stack"))
1370 seg
->combine
= CMB_STACK
;
1371 else if (!nasm_stricmp(p
, "use16"))
1373 else if (!nasm_stricmp(p
, "use32"))
1375 else if (!nasm_stricmp(p
, "flat")) {
1377 * This segment is an OS/2 FLAT segment. That means
1378 * that its default group is group FLAT, even if
1379 * the group FLAT does not explicitly _contain_ the
1382 * When we see this, we must create the group
1383 * `FLAT', containing no segments, if it does not
1384 * already exist; then we must set the default
1385 * group of this segment to be the FLAT group.
1388 for (grp
= grphead
; grp
; grp
= grp
->next
)
1389 if (!strcmp(grp
->name
, "FLAT"))
1392 obj_directive("group", "FLAT", 1);
1393 for (grp
= grphead
; grp
; grp
= grp
->next
)
1394 if (!strcmp(grp
->name
, "FLAT"))
1397 error(ERR_PANIC
, "failure to define FLAT?!");
1400 } else if (!nasm_strnicmp(p
, "class=", 6))
1401 seg
->segclass
= nasm_strdup(p
+ 6);
1402 else if (!nasm_strnicmp(p
, "overlay=", 8))
1403 seg
->overlay
= nasm_strdup(p
+ 8);
1404 else if (!nasm_strnicmp(p
, "align=", 6)) {
1405 seg
->align
= readnum(p
+ 6, &rn_error
);
1408 error(ERR_NONFATAL
, "segment alignment should be"
1411 switch ((int)seg
->align
) {
1416 case 256: /* PAGE */
1417 case 4096: /* PharLap extension */
1421 "OBJ format does not support alignment"
1422 " of 8: rounding up to 16");
1429 "OBJ format does not support alignment"
1430 " of %d: rounding up to 256", seg
->align
);
1437 "OBJ format does not support alignment"
1438 " of %d: rounding up to 4096", seg
->align
);
1442 error(ERR_NONFATAL
, "invalid alignment value %d",
1447 } else if (!nasm_strnicmp(p
, "absolute=", 9)) {
1448 seg
->align
= SEG_ABS
+ readnum(p
+ 9, &rn_error
);
1450 error(ERR_NONFATAL
, "argument to `absolute' segment"
1451 " attribute should be numeric");
1455 /* We need to know whenever we have at least one 32-bit segment */
1456 obj_use32
|= seg
->use32
;
1458 obj_seg_needs_update
= seg
;
1459 if (seg
->align
>= SEG_ABS
)
1460 deflabel(name
, NO_SEG
, seg
->align
- SEG_ABS
,
1461 NULL
, false, false, &of_obj
, error
);
1463 deflabel(name
, seg
->index
+ 1, 0L,
1464 NULL
, false, false, &of_obj
, error
);
1465 obj_seg_needs_update
= NULL
;
1468 * See if this segment is defined in any groups.
1470 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1471 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1472 if (!strcmp(grp
->segs
[i
].name
, seg
->name
)) {
1473 nasm_free(grp
->segs
[i
].name
);
1474 grp
->segs
[i
] = grp
->segs
[grp
->nindices
];
1475 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1478 "segment `%s' is already part of"
1479 " a group: first one takes precedence",
1488 * Walk through the list of externals with unresolved
1489 * default-WRT clauses, and resolve any that point at this
1494 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1495 !strcmp((*extp
)->defwrt_ptr
.string
, seg
->name
)) {
1496 nasm_free((*extp
)->defwrt_ptr
.string
);
1497 (*extp
)->defwrt_type
= DEFWRT_SEGMENT
;
1498 (*extp
)->defwrt_ptr
.seg
= seg
;
1499 *extp
= (*extp
)->next_dws
;
1501 extp
= &(*extp
)->next_dws
;
1513 static int obj_directive(char *directive
, char *value
, int pass
)
1515 if (!strcmp(directive
, "group")) {
1519 struct Segment
*seg
;
1520 struct External
**extp
;
1525 q
++; /* hack, but a documented one */
1527 while (*q
&& !nasm_isspace(*q
))
1529 if (nasm_isspace(*q
)) {
1531 while (*q
&& nasm_isspace(*q
))
1535 * Here we used to sanity-check the group directive to
1536 * ensure nobody tried to declare a group containing no
1537 * segments. However, OS/2 does this as standard
1538 * practice, so the sanity check has been removed.
1541 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1547 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1549 if (!strcmp(grp
->name
, v
)) {
1550 error(ERR_NONFATAL
, "group `%s' defined twice", v
);
1555 *grptail
= grp
= nasm_malloc(sizeof(*grp
));
1557 grptail
= &grp
->next
;
1558 grp
->index
= seg_alloc();
1559 grp
->obj_index
= obj_idx
;
1560 grp
->nindices
= grp
->nentries
= 0;
1563 obj_grp_needs_update
= grp
;
1564 deflabel(v
, grp
->index
+ 1, 0L,
1565 NULL
, false, false, &of_obj
, error
);
1566 obj_grp_needs_update
= NULL
;
1570 while (*q
&& !nasm_isspace(*q
))
1572 if (nasm_isspace(*q
)) {
1574 while (*q
&& nasm_isspace(*q
))
1578 * Now p contains a segment name. Find it.
1580 for (seg
= seghead
; seg
; seg
= seg
->next
)
1581 if (!strcmp(seg
->name
, p
))
1585 * We have a segment index. Shift a name entry
1586 * to the end of the array to make room.
1588 grp
->segs
[grp
->nentries
++] = grp
->segs
[grp
->nindices
];
1589 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1592 "segment `%s' is already part of"
1593 " a group: first one takes precedence",
1599 * We have an as-yet undefined segment.
1600 * Remember its name, for later.
1602 grp
->segs
[grp
->nentries
++].name
= nasm_strdup(p
);
1607 * Walk through the list of externals with unresolved
1608 * default-WRT clauses, and resolve any that point at
1613 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1614 !strcmp((*extp
)->defwrt_ptr
.string
, grp
->name
)) {
1615 nasm_free((*extp
)->defwrt_ptr
.string
);
1616 (*extp
)->defwrt_type
= DEFWRT_GROUP
;
1617 (*extp
)->defwrt_ptr
.grp
= grp
;
1618 *extp
= (*extp
)->next_dws
;
1620 extp
= &(*extp
)->next_dws
;
1625 if (!strcmp(directive
, "uppercase")) {
1626 obj_uppercase
= true;
1629 if (!strcmp(directive
, "import")) {
1630 char *q
, *extname
, *libname
, *impname
;
1633 return 1; /* ignore in pass two */
1634 extname
= q
= value
;
1635 while (*q
&& !nasm_isspace(*q
))
1637 if (nasm_isspace(*q
)) {
1639 while (*q
&& nasm_isspace(*q
))
1644 while (*q
&& !nasm_isspace(*q
))
1646 if (nasm_isspace(*q
)) {
1648 while (*q
&& nasm_isspace(*q
))
1654 if (!*extname
|| !*libname
)
1655 error(ERR_NONFATAL
, "`import' directive requires symbol name"
1656 " and library name");
1661 imp
= *imptail
= nasm_malloc(sizeof(struct ImpDef
));
1662 imptail
= &imp
->next
;
1664 imp
->extname
= nasm_strdup(extname
);
1665 imp
->libname
= nasm_strdup(libname
);
1666 imp
->impindex
= readnum(impname
, &err
);
1667 if (!*impname
|| err
)
1668 imp
->impname
= nasm_strdup(impname
);
1670 imp
->impname
= NULL
;
1675 if (!strcmp(directive
, "export")) {
1676 char *q
, *extname
, *intname
, *v
;
1677 struct ExpDef
*export
;
1679 unsigned int ordinal
= 0;
1682 return 1; /* ignore in pass two */
1683 intname
= q
= value
;
1684 while (*q
&& !nasm_isspace(*q
))
1686 if (nasm_isspace(*q
)) {
1688 while (*q
&& nasm_isspace(*q
))
1693 while (*q
&& !nasm_isspace(*q
))
1695 if (nasm_isspace(*q
)) {
1697 while (*q
&& nasm_isspace(*q
))
1702 error(ERR_NONFATAL
, "`export' directive requires export name");
1711 while (*q
&& !nasm_isspace(*q
))
1713 if (nasm_isspace(*q
)) {
1715 while (*q
&& nasm_isspace(*q
))
1718 if (!nasm_stricmp(v
, "resident"))
1719 flags
|= EXPDEF_FLAG_RESIDENT
;
1720 else if (!nasm_stricmp(v
, "nodata"))
1721 flags
|= EXPDEF_FLAG_NODATA
;
1722 else if (!nasm_strnicmp(v
, "parm=", 5)) {
1724 flags
|= EXPDEF_MASK_PARMCNT
& readnum(v
+ 5, &err
);
1727 "value `%s' for `parm' is non-numeric", v
+ 5);
1732 ordinal
= readnum(v
, &err
);
1735 "unrecognised export qualifier `%s'", v
);
1738 flags
|= EXPDEF_FLAG_ORDINAL
;
1742 export
= *exptail
= nasm_malloc(sizeof(struct ExpDef
));
1743 exptail
= &export
->next
;
1744 export
->next
= NULL
;
1745 export
->extname
= nasm_strdup(extname
);
1746 export
->intname
= nasm_strdup(intname
);
1747 export
->ordinal
= ordinal
;
1748 export
->flags
= flags
;
1755 static int32_t obj_segbase(int32_t segment
)
1757 struct Segment
*seg
;
1760 * Find the segment in our list.
1762 for (seg
= seghead
; seg
; seg
= seg
->next
)
1763 if (seg
->index
== segment
- 1)
1768 * Might be an external with a default WRT.
1770 int32_t i
= segment
/ 2;
1771 struct ExtBack
*eb
= ebhead
;
1774 while (i
>= EXT_BLKSIZ
) {
1783 if (e
->defwrt_type
== DEFWRT_NONE
)
1784 return segment
; /* fine */
1785 else if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1786 return e
->defwrt_ptr
.seg
->index
+ 1;
1787 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1788 return e
->defwrt_ptr
.grp
->index
+ 1;
1790 return NO_SEG
; /* can't tell what it is */
1793 return segment
; /* not one of ours - leave it alone */
1796 if (seg
->align
>= SEG_ABS
)
1797 return seg
->align
; /* absolute segment */
1799 return seg
->grp
->index
+ 1; /* grouped segment */
1801 return segment
; /* no special treatment */
1804 static void obj_filename(char *inname
, char *outname
, efunc lerror
)
1806 strcpy(obj_infile
, inname
);
1807 standard_extension(inname
, outname
, ".obj", lerror
);
1810 static void obj_write_file(int debuginfo
)
1812 struct Segment
*seg
, *entry_seg_ptr
= 0;
1813 struct FileName
*fn
;
1814 struct LineNumber
*ln
;
1816 struct Public
*pub
, *loc
;
1817 struct External
*ext
;
1819 struct ExpDef
*export
;
1824 * Write the THEADR module header.
1828 obj_name(orp
, obj_infile
);
1832 * Write the NASM boast comment.
1835 obj_rword(orp
, 0); /* comment type zero */
1836 obj_name(orp
, nasm_comment
);
1841 * Write the IMPDEF records, if any.
1843 for (imp
= imphead
; imp
; imp
= imp
->next
) {
1844 obj_rword(orp
, 0xA0); /* comment class A0 */
1845 obj_byte(orp
, 1); /* subfunction 1: IMPDEF */
1847 obj_byte(orp
, 0); /* import by name */
1849 obj_byte(orp
, 1); /* import by ordinal */
1850 obj_name(orp
, imp
->extname
);
1851 obj_name(orp
, imp
->libname
);
1853 obj_name(orp
, imp
->impname
);
1855 obj_word(orp
, imp
->impindex
);
1860 * Write the EXPDEF records, if any.
1862 for (export
= exphead
; export
; export
= export
->next
) {
1863 obj_rword(orp
, 0xA0); /* comment class A0 */
1864 obj_byte(orp
, 2); /* subfunction 2: EXPDEF */
1865 obj_byte(orp
, export
->flags
);
1866 obj_name(orp
, export
->extname
);
1867 obj_name(orp
, export
->intname
);
1868 if (export
->flags
& EXPDEF_FLAG_ORDINAL
)
1869 obj_word(orp
, export
->ordinal
);
1873 /* we're using extended OMF if we put in debug info */
1876 obj_byte(orp
, 0x40);
1877 obj_byte(orp
, dEXTENDED
);
1882 * Write the first LNAMES record, containing LNAME one, which
1883 * is null. Also initialize the LNAME counter.
1889 * Write some LNAMES for the segment names
1891 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1892 orp
= obj_name(orp
, seg
->name
);
1894 orp
= obj_name(orp
, seg
->segclass
);
1896 orp
= obj_name(orp
, seg
->overlay
);
1900 * Write some LNAMES for the group names
1902 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1903 orp
= obj_name(orp
, grp
->name
);
1909 * Write the SEGDEF records.
1912 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1914 uint32_t seglen
= seg
->currentpos
;
1916 acbp
= (seg
->combine
<< 2); /* C field */
1919 acbp
|= 0x01; /* P bit is Use32 flag */
1920 else if (seglen
== 0x10000L
) {
1921 seglen
= 0; /* This special case may be needed for old linkers */
1922 acbp
|= 0x02; /* B bit */
1926 if (seg
->align
>= SEG_ABS
)
1927 /* acbp |= 0x00 */ ;
1928 else if (seg
->align
>= 4096) {
1929 if (seg
->align
> 4096)
1930 error(ERR_NONFATAL
, "segment `%s' requires more alignment"
1931 " than OBJ format supports", seg
->name
);
1932 acbp
|= 0xC0; /* PharLap extension */
1933 } else if (seg
->align
>= 256) {
1935 } else if (seg
->align
>= 16) {
1937 } else if (seg
->align
>= 4) {
1939 } else if (seg
->align
>= 2) {
1944 obj_byte(orp
, acbp
);
1945 if (seg
->align
& SEG_ABS
) {
1946 obj_x(orp
, seg
->align
- SEG_ABS
); /* Frame */
1947 obj_byte(orp
, 0); /* Offset */
1950 obj_index(orp
, ++lname_idx
);
1951 obj_index(orp
, seg
->segclass
? ++lname_idx
: 1);
1952 obj_index(orp
, seg
->overlay
? ++lname_idx
: 1);
1957 * Write the GRPDEF records.
1960 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1963 if (grp
->nindices
!= grp
->nentries
) {
1964 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1965 error(ERR_NONFATAL
, "group `%s' contains undefined segment"
1966 " `%s'", grp
->name
, grp
->segs
[i
].name
);
1967 nasm_free(grp
->segs
[i
].name
);
1968 grp
->segs
[i
].name
= NULL
;
1971 obj_index(orp
, ++lname_idx
);
1972 for (i
= 0; i
< grp
->nindices
; i
++) {
1973 obj_byte(orp
, 0xFF);
1974 obj_index(orp
, grp
->segs
[i
].index
);
1980 * Write the PUBDEF records: first the ones in the segments,
1981 * then the far-absolutes.
1984 orp
->ori
= ori_pubdef
;
1985 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1986 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
1987 orp
->parm
[1] = seg
->obj_index
;
1988 for (pub
= seg
->pubhead
; pub
; pub
= pub
->next
) {
1989 orp
= obj_name(orp
, pub
->name
);
1990 orp
= obj_x(orp
, pub
->offset
);
1991 orp
= obj_byte(orp
, 0); /* type index */
1998 for (pub
= fpubhead
; pub
; pub
= pub
->next
) { /* pub-crawl :-) */
1999 if (orp
->parm
[2] != (uint32_t)pub
->segment
) {
2001 orp
->parm
[2] = pub
->segment
;
2003 orp
= obj_name(orp
, pub
->name
);
2004 orp
= obj_x(orp
, pub
->offset
);
2005 orp
= obj_byte(orp
, 0); /* type index */
2011 * Write the EXTDEF and COMDEF records, in order.
2013 orp
->ori
= ori_null
;
2014 for (ext
= exthead
; ext
; ext
= ext
->next
) {
2015 if (ext
->commonsize
== 0) {
2016 if (orp
->type
!= EXTDEF
) {
2020 orp
= obj_name(orp
, ext
->name
);
2021 orp
= obj_index(orp
, 0);
2023 if (orp
->type
!= COMDEF
) {
2027 orp
= obj_name(orp
, ext
->name
);
2028 orp
= obj_index(orp
, 0);
2029 if (ext
->commonelem
) {
2030 orp
= obj_byte(orp
, 0x61); /* far communal */
2031 orp
= obj_value(orp
, (ext
->commonsize
/ ext
->commonelem
));
2032 orp
= obj_value(orp
, ext
->commonelem
);
2034 orp
= obj_byte(orp
, 0x62); /* near communal */
2035 orp
= obj_value(orp
, ext
->commonsize
);
2043 * Write a COMENT record stating that the linker's first pass
2044 * may stop processing at this point. Exception is if our
2045 * MODEND record specifies a start point, in which case,
2046 * according to some variants of the documentation, this COMENT
2047 * should be omitted. So we'll omit it just in case.
2048 * But, TASM puts it in all the time so if we are using
2049 * TASM debug stuff we are putting it in
2051 if (debuginfo
|| obj_entry_seg
== NO_SEG
) {
2053 obj_byte(orp
, 0x40);
2054 obj_byte(orp
, dLINKPASS
);
2060 * 1) put out the compiler type
2061 * 2) Put out the type info. The only type we are using is near label #19
2065 struct Array
*arrtmp
= arrhead
;
2067 obj_byte(orp
, 0x40);
2068 obj_byte(orp
, dCOMPDEF
);
2073 obj_byte(orp
, 0x40);
2074 obj_byte(orp
, dTYPEDEF
);
2075 obj_word(orp
, 0x18); /* type # for linking */
2076 obj_word(orp
, 6); /* size of type */
2077 obj_byte(orp
, 0x2a); /* absolute type for debugging */
2079 obj_byte(orp
, 0x40);
2080 obj_byte(orp
, dTYPEDEF
);
2081 obj_word(orp
, 0x19); /* type # for linking */
2082 obj_word(orp
, 0); /* size of type */
2083 obj_byte(orp
, 0x24); /* absolute type for debugging */
2084 obj_byte(orp
, 0); /* near/far specifier */
2086 obj_byte(orp
, 0x40);
2087 obj_byte(orp
, dTYPEDEF
);
2088 obj_word(orp
, 0x1A); /* type # for linking */
2089 obj_word(orp
, 0); /* size of type */
2090 obj_byte(orp
, 0x24); /* absolute type for debugging */
2091 obj_byte(orp
, 1); /* near/far specifier */
2093 obj_byte(orp
, 0x40);
2094 obj_byte(orp
, dTYPEDEF
);
2095 obj_word(orp
, 0x1b); /* type # for linking */
2096 obj_word(orp
, 0); /* size of type */
2097 obj_byte(orp
, 0x23); /* absolute type for debugging */
2102 obj_byte(orp
, 0x40);
2103 obj_byte(orp
, dTYPEDEF
);
2104 obj_word(orp
, 0x1c); /* type # for linking */
2105 obj_word(orp
, 0); /* size of type */
2106 obj_byte(orp
, 0x23); /* absolute type for debugging */
2111 obj_byte(orp
, 0x40);
2112 obj_byte(orp
, dTYPEDEF
);
2113 obj_word(orp
, 0x1d); /* type # for linking */
2114 obj_word(orp
, 0); /* size of type */
2115 obj_byte(orp
, 0x23); /* absolute type for debugging */
2120 obj_byte(orp
, 0x40);
2121 obj_byte(orp
, dTYPEDEF
);
2122 obj_word(orp
, 0x1e); /* type # for linking */
2123 obj_word(orp
, 0); /* size of type */
2124 obj_byte(orp
, 0x23); /* absolute type for debugging */
2130 /* put out the array types */
2131 for (i
= ARRAYBOT
; i
< arrindex
; i
++) {
2132 obj_byte(orp
, 0x40);
2133 obj_byte(orp
, dTYPEDEF
);
2134 obj_word(orp
, i
); /* type # for linking */
2135 obj_word(orp
, arrtmp
->size
); /* size of type */
2136 obj_byte(orp
, 0x1A); /* absolute type for debugging (array) */
2137 obj_byte(orp
, arrtmp
->basetype
); /* base type */
2139 arrtmp
= arrtmp
->next
;
2143 * write out line number info with a LINNUM record
2144 * switch records when we switch segments, and output the
2145 * file in a pseudo-TASM fashion. The record switch is naive; that
2146 * is that one file may have many records for the same segment
2147 * if there are lots of segment switches
2149 if (fnhead
&& debuginfo
) {
2150 seg
= fnhead
->lnhead
->segment
;
2152 for (fn
= fnhead
; fn
; fn
= fn
->next
) {
2153 /* write out current file name */
2155 orp
->ori
= ori_null
;
2156 obj_byte(orp
, 0x40);
2157 obj_byte(orp
, dFILNAME
);
2159 obj_name(orp
, fn
->name
);
2163 /* write out line numbers this file */
2166 orp
->ori
= ori_linnum
;
2167 for (ln
= fn
->lnhead
; ln
; ln
= ln
->next
) {
2168 if (seg
!= ln
->segment
) {
2169 /* if we get here have to flush the buffer and start
2170 * a new record for a new segment
2175 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
2176 orp
->parm
[1] = seg
->obj_index
;
2177 orp
= obj_word(orp
, ln
->lineno
);
2178 orp
= obj_x(orp
, ln
->offset
);
2185 * we are going to locate the entry point segment now
2186 * rather than wait until the MODEND record, because,
2187 * then we can output a special symbol to tell where the
2191 if (obj_entry_seg
!= NO_SEG
) {
2192 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2193 if (seg
->index
== obj_entry_seg
) {
2194 entry_seg_ptr
= seg
;
2199 error(ERR_NONFATAL
, "entry point is not in this module");
2203 * get ready to put out symbol records
2206 orp
->ori
= ori_local
;
2209 * put out a symbol for the entry point
2210 * no dots in this symbol, because, borland does
2211 * not (officially) support dots in label names
2212 * and I don't know what various versions of TLINK will do
2214 if (debuginfo
&& obj_entry_seg
!= NO_SEG
) {
2215 orp
= obj_name(orp
, "start_of_program");
2216 orp
= obj_word(orp
, 0x19); /* type: near label */
2217 orp
= obj_index(orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2218 orp
= obj_index(orp
, seg
->obj_index
);
2219 orp
= obj_x(orp
, obj_entry_ofs
);
2224 * put out the local labels
2226 for (seg
= seghead
; seg
&& debuginfo
; seg
= seg
->next
) {
2227 /* labels this seg */
2228 for (loc
= seg
->lochead
; loc
; loc
= loc
->next
) {
2229 orp
= obj_name(orp
, loc
->name
);
2230 orp
= obj_word(orp
, loc
->type
);
2231 orp
= obj_index(orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2232 orp
= obj_index(orp
, seg
->obj_index
);
2233 orp
= obj_x(orp
, loc
->offset
);
2241 * Write the LEDATA/FIXUPP pairs.
2243 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2245 nasm_free(seg
->orp
);
2249 * Write the MODEND module end marker.
2251 orp
->type
= obj_use32
? MODE32
: MODEND
;
2252 orp
->ori
= ori_null
;
2253 if (entry_seg_ptr
) {
2254 orp
->type
= entry_seg_ptr
->use32
? MODE32
: MODEND
;
2255 obj_byte(orp
, 0xC1);
2256 seg
= entry_seg_ptr
;
2258 obj_byte(orp
, 0x10);
2259 obj_index(orp
, seg
->grp
->obj_index
);
2262 * the below changed to prevent TLINK crashing.
2263 * Previous more efficient version read:
2265 * obj_byte (orp, 0x50);
2267 obj_byte(orp
, 0x00);
2268 obj_index(orp
, seg
->obj_index
);
2270 obj_index(orp
, seg
->obj_index
);
2271 obj_x(orp
, obj_entry_ofs
);
2278 static void obj_fwrite(ObjRecord
* orp
)
2280 unsigned int cksum
, len
;
2284 if (orp
->x_size
== 32)
2287 len
= orp
->committed
+ 1;
2288 cksum
+= (len
& 0xFF) + ((len
>> 8) & 0xFF);
2289 fwriteint16_t(len
, ofp
);
2290 fwrite(orp
->buf
, 1, len
- 1, ofp
);
2291 for (ptr
= orp
->buf
; --len
; ptr
++)
2293 fputc((-cksum
) & 0xFF, ofp
);
2296 extern macros_t obj_stdmac
[];
2298 void dbgbi_init(struct ofmt
*of
, void *id
, FILE * fp
, efunc error
)
2307 arrindex
= ARRAYBOT
;
2311 static void dbgbi_cleanup(void)
2313 struct Segment
*segtmp
;
2315 struct FileName
*fntemp
= fnhead
;
2316 while (fnhead
->lnhead
) {
2317 struct LineNumber
*lntemp
= fnhead
->lnhead
;
2318 fnhead
->lnhead
= lntemp
->next
;
2321 fnhead
= fnhead
->next
;
2322 nasm_free(fntemp
->name
);
2325 for (segtmp
= seghead
; segtmp
; segtmp
= segtmp
->next
) {
2326 while (segtmp
->lochead
) {
2327 struct Public
*loctmp
= segtmp
->lochead
;
2328 segtmp
->lochead
= loctmp
->next
;
2329 nasm_free(loctmp
->name
);
2334 struct Array
*arrtmp
= arrhead
;
2335 arrhead
= arrhead
->next
;
2340 static void dbgbi_linnum(const char *lnfname
, int32_t lineno
, int32_t segto
)
2342 struct FileName
*fn
;
2343 struct LineNumber
*ln
;
2344 struct Segment
*seg
;
2346 if (segto
== NO_SEG
)
2350 * If `any_segs' is still false, we must define a default
2354 int tempint
; /* ignored */
2355 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
2356 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
2360 * Find the segment we are targetting.
2362 for (seg
= seghead
; seg
; seg
= seg
->next
)
2363 if (seg
->index
== segto
)
2366 error(ERR_PANIC
, "lineno directed to nonexistent segment?");
2368 /* for (fn = fnhead; fn; fn = fnhead->next) */
2369 for (fn
= fnhead
; fn
; fn
= fn
->next
) /* fbk - Austin Lunnen - John Fine */
2370 if (!nasm_stricmp(lnfname
, fn
->name
))
2373 fn
= nasm_malloc(sizeof(*fn
));
2374 fn
->name
= nasm_malloc(strlen(lnfname
) + 1);
2375 strcpy(fn
->name
, lnfname
);
2377 fn
->lntail
= &fn
->lnhead
;
2382 ln
= nasm_malloc(sizeof(*ln
));
2384 ln
->offset
= seg
->currentpos
;
2385 ln
->lineno
= lineno
;
2388 fn
->lntail
= &ln
->next
;
2391 static void dbgbi_deflabel(char *name
, int32_t segment
,
2392 int64_t offset
, int is_global
, char *special
)
2394 struct Segment
*seg
;
2399 * If it's a special-retry from pass two, discard it.
2405 * First check for the double-period, signifying something
2408 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
2415 if (obj_seg_needs_update
) {
2417 } else if (obj_grp_needs_update
) {
2420 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
2423 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
2428 * If `any_segs' is still false, we might need to define a
2429 * default segment, if they're trying to declare a label in
2430 * `first_seg'. But the label should exist due to a prior
2431 * call to obj_deflabel so we can skip that.
2434 for (seg
= seghead
; seg
; seg
= seg
->next
)
2435 if (seg
->index
== segment
) {
2436 struct Public
*loc
= nasm_malloc(sizeof(*loc
));
2438 * Case (ii). Maybe MODPUB someday?
2440 last_defined
= *seg
->loctail
= loc
;
2441 seg
->loctail
= &loc
->next
;
2443 loc
->name
= nasm_strdup(name
);
2444 loc
->offset
= offset
;
2447 static void dbgbi_typevalue(int32_t type
)
2450 int elem
= TYM_ELEMENTS(type
);
2451 type
= TYM_TYPE(type
);
2458 last_defined
->type
= 8; /* uint8_t */
2462 last_defined
->type
= 10; /* unsigned word */
2466 last_defined
->type
= 12; /* unsigned dword */
2470 last_defined
->type
= 14; /* float */
2474 last_defined
->type
= 15; /* qword */
2478 last_defined
->type
= 16; /* TBYTE */
2482 last_defined
->type
= 0x19; /*label */
2488 struct Array
*arrtmp
= nasm_malloc(sizeof(*arrtmp
));
2489 int vtype
= last_defined
->type
;
2490 arrtmp
->size
= vsize
* elem
;
2491 arrtmp
->basetype
= vtype
;
2492 arrtmp
->next
= NULL
;
2493 last_defined
->type
= arrindex
++;
2495 arrtail
= &(arrtmp
->next
);
2497 last_defined
= NULL
;
2499 static void dbgbi_output(int output_type
, void *param
)
2504 static struct dfmt borland_debug_form
= {
2505 "Borland Debug Records",
2516 static struct dfmt
*borland_debug_arr
[3] = {
2517 &borland_debug_form
,
2522 struct ofmt of_obj
= {
2523 "MS-DOS 16-bit/32-bit OMF object files",
2527 &borland_debug_form
,