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.
24 * outobj.c is divided into two sections. The first section is low level
25 * routines for creating obj records; It has nearly zero NASM specific
26 * code. The second section is high level routines for processing calls and
27 * data structures from the rest of NASM into obj format.
29 * It should be easy (though not zero work) to lift the first section out for
30 * use as an obj file writer for some other assembler or compiler.
34 * These routines are built around the ObjRecord data struture. An ObjRecord
35 * holds an object file record that may be under construction or complete.
37 * A major function of these routines is to support continuation of an obj
38 * record into the next record when the maximum record size is exceeded. The
39 * high level code does not need to worry about where the record breaks occur.
40 * It does need to do some minor extra steps to make the automatic continuation
41 * work. Those steps may be skipped for records where the high level knows no
42 * continuation could be required.
44 * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
45 * is cleared by obj_clear.
47 * 2) The caller should fill in .type.
49 * 3) If the record is continuable and there is processing that must be done at
50 * the start of each record then the caller should fill in .ori with the
51 * address of the record initializer routine.
53 * 4) If the record is continuable and it should be saved (rather than emitted
54 * immediately) as each record is done, the caller should set .up to be a
55 * pointer to a location in which the caller keeps the master pointer to the
56 * ObjRecord. When the record is continued, the obj_bump routine will then
57 * allocate a new ObjRecord structure and update the master pointer.
59 * 5) If the .ori field was used then the caller should fill in the .parm with
60 * any data required by the initializer.
62 * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
63 * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
64 * data required for this record.
66 * 7) If the record is continuable, the caller should call obj_commit at each
67 * point where breaking the record is permitted.
69 * 8) To write out the record, the caller should call obj_emit2. If the
70 * caller has called obj_commit for all data written then he can get slightly
71 * faster code by calling obj_emit instead of obj_emit2.
73 * Most of these routines return an ObjRecord pointer. This will be the input
74 * pointer most of the time and will be the new location if the ObjRecord
75 * moved as a result of the call. The caller may ignore the return value in
76 * three cases: It is a "Never Reallocates" routine; or The caller knows
77 * continuation is not possible; or The caller uses the master pointer for the
81 #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
82 #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
84 #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
85 #define FIX_16_OFFSET 0x8400
86 #define FIX_16_SELECTOR 0x8800
87 #define FIX_32_POINTER 0x8C00
88 #define FIX_08_HIGH 0x9000
89 #define FIX_32_OFFSET 0xA400
90 #define FIX_48_POINTER 0xAC00
92 enum RecordID
{ /* record ID codes */
94 THEADR
= 0x80, /* module header */
95 COMENT
= 0x88, /* comment record */
97 LINNUM
= 0x94, /* line number record */
98 LNAMES
= 0x96, /* list of names */
100 SEGDEF
= 0x98, /* segment definition */
101 GRPDEF
= 0x9A, /* group definition */
102 EXTDEF
= 0x8C, /* external definition */
103 PUBDEF
= 0x90, /* public definition */
104 COMDEF
= 0xB0, /* common definition */
106 LEDATA
= 0xA0, /* logical enumerated data */
107 FIXUPP
= 0x9C, /* fixups (relocations) */
108 FIXU32
= 0x9D, /* 32-bit fixups (relocations) */
110 MODEND
= 0x8A, /* module end */
111 MODE32
= 0x8B /* module end for 32-bit objects */
114 enum ComentID
{ /* ID codes for comment records */
116 dEXTENDED
= 0xA1, /* tells that we are using translator-specific extensions */
117 dLINKPASS
= 0xA2, /* link pass 2 marker */
118 dTYPEDEF
= 0xE3, /* define a type */
119 dSYM
= 0xE6, /* symbol debug record */
120 dFILNAME
= 0xE8, /* file name record */
121 dCOMPDEF
= 0xEA /* compiler type info */
124 typedef struct ObjRecord ObjRecord
;
125 typedef void ORI(ObjRecord
* orp
);
128 ORI
*ori
; /* Initialization routine */
129 int used
; /* Current data size */
130 int committed
; /* Data size at last boundary */
131 int x_size
; /* (see obj_x) */
132 unsigned int type
; /* Record type */
133 ObjRecord
*child
; /* Associated record below this one */
134 ObjRecord
**up
; /* Master pointer to this ObjRecord */
135 ObjRecord
*back
; /* Previous part of this record */
136 uint32_t parm
[OBJ_PARMS
]; /* Parameters for ori routine */
137 uint8_t buf
[RECORD_MAX
+ 3];
140 static void obj_fwrite(ObjRecord
* orp
);
141 static void ori_ledata(ObjRecord
* orp
);
142 static void ori_pubdef(ObjRecord
* orp
);
143 static void ori_null(ObjRecord
* orp
);
144 static ObjRecord
*obj_commit(ObjRecord
* orp
);
146 static int obj_uppercase
; /* Flag: all names in uppercase */
147 static int obj_use32
; /* Flag: at least one segment is 32-bit */
150 * Clear an ObjRecord structure. (Never reallocates).
151 * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
153 static ObjRecord
*obj_clear(ObjRecord
* orp
)
165 * Emit an ObjRecord structure. (Never reallocates).
166 * The record is written out preceeded (recursively) by its previous part (if
167 * any) and followed (recursively) by its child (if any).
168 * The previous part and the child are freed. The main ObjRecord is cleared,
171 static ObjRecord
*obj_emit(ObjRecord
* orp
)
175 nasm_free(orp
->back
);
182 obj_emit(orp
->child
);
183 nasm_free(orp
->child
);
186 return (obj_clear(orp
));
190 * Commit and Emit a record. (Never reallocates).
192 static ObjRecord
*obj_emit2(ObjRecord
* orp
)
195 return (obj_emit(orp
));
199 * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
201 static ObjRecord
*obj_new(void)
205 orp
= obj_clear(nasm_malloc(sizeof(ObjRecord
)));
211 * Advance to the next record because the existing one is full or its x_size
213 * Any uncommited data is moved into the next record.
215 static ObjRecord
*obj_bump(ObjRecord
* orp
)
218 int used
= orp
->used
;
219 int committed
= orp
->committed
;
222 *orp
->up
= nxt
= obj_new();
224 nxt
->type
= orp
->type
;
227 memcpy(nxt
->parm
, orp
->parm
, sizeof(orp
->parm
));
235 nxt
->committed
= nxt
->used
;
236 memcpy(nxt
->buf
+ nxt
->committed
, orp
->buf
+ committed
, used
);
237 nxt
->used
= nxt
->committed
+ used
;
244 * Advance to the next record if necessary to allow the next field to fit.
246 static ObjRecord
*obj_check(ObjRecord
* orp
, int size
)
248 if (orp
->used
+ size
> RECORD_MAX
)
251 if (!orp
->committed
) {
254 orp
->committed
= orp
->used
;
261 * All data written so far is commited to the current record (won't be moved to
262 * the next record in case of continuation).
264 static ObjRecord
*obj_commit(ObjRecord
* orp
)
266 orp
->committed
= orp
->used
;
273 static ObjRecord
*obj_byte(ObjRecord
* orp
, uint8_t val
)
275 orp
= obj_check(orp
, 1);
276 orp
->buf
[orp
->used
] = val
;
284 static ObjRecord
*obj_word(ObjRecord
* orp
, unsigned int val
)
286 orp
= obj_check(orp
, 2);
287 orp
->buf
[orp
->used
] = val
;
288 orp
->buf
[orp
->used
+ 1] = val
>> 8;
294 * Write a reversed word
296 static ObjRecord
*obj_rword(ObjRecord
* orp
, unsigned int val
)
298 orp
= obj_check(orp
, 2);
299 orp
->buf
[orp
->used
] = val
>> 8;
300 orp
->buf
[orp
->used
+ 1] = val
;
308 static ObjRecord
*obj_dword(ObjRecord
* orp
, uint32_t val
)
310 orp
= obj_check(orp
, 4);
311 orp
->buf
[orp
->used
] = val
;
312 orp
->buf
[orp
->used
+ 1] = val
>> 8;
313 orp
->buf
[orp
->used
+ 2] = val
>> 16;
314 orp
->buf
[orp
->used
+ 3] = val
>> 24;
320 * All fields of "size x" in one obj record must be the same size (either 16
321 * bits or 32 bits). There is a one bit flag in each record which specifies
323 * This routine is used to force the current record to have the desired
324 * x_size. x_size is normally automatic (using obj_x), so that this
325 * routine should be used outside obj_x, only to provide compatibility with
326 * linkers that have bugs in their processing of the size bit.
329 static ObjRecord
*obj_force(ObjRecord
* orp
, int x
)
331 if (orp
->x_size
== (x
^ 48))
338 * This routine writes a field of size x. The caller does not need to worry at
339 * all about whether 16-bits or 32-bits are required.
341 static ObjRecord
*obj_x(ObjRecord
* orp
, uint32_t val
)
346 orp
= obj_force(orp
, 32);
347 if (orp
->x_size
== 32)
348 return (obj_dword(orp
, val
));
350 return (obj_word(orp
, val
));
356 static ObjRecord
*obj_index(ObjRecord
* orp
, unsigned int val
)
359 return (obj_byte(orp
, val
));
360 return (obj_word(orp
, (val
>> 8) | (val
<< 8) | 0x80));
364 * Writes a variable length value
366 static ObjRecord
*obj_value(ObjRecord
* orp
, uint32_t val
)
369 return (obj_byte(orp
, val
));
371 orp
= obj_byte(orp
, 129);
372 return (obj_word(orp
, val
));
375 return (obj_dword(orp
, (val
<< 8) + 132));
376 orp
= obj_byte(orp
, 136);
377 return (obj_dword(orp
, val
));
381 * Writes a counted string
383 static ObjRecord
*obj_name(ObjRecord
* orp
, char *name
)
385 int len
= strlen(name
);
388 orp
= obj_check(orp
, len
+ 1);
389 ptr
= orp
->buf
+ orp
->used
;
391 orp
->used
+= len
+ 1;
394 *ptr
++ = toupper(*name
);
397 memcpy(ptr
, name
, len
);
402 * Initializer for an LEDATA record.
404 * parm[1] = segment index
405 * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
406 * represent the offset that would be required if the record were split at the
408 * parm[2] is a copy of parm[0] as it was when the current record was initted.
410 static void ori_ledata(ObjRecord
* orp
)
412 obj_index(orp
, orp
->parm
[1]);
413 orp
->parm
[2] = orp
->parm
[0];
414 obj_x(orp
, orp
->parm
[0]);
418 * Initializer for a PUBDEF record.
419 * parm[0] = group index
420 * parm[1] = segment index
421 * parm[2] = frame (only used when both indexes are zero)
423 static void ori_pubdef(ObjRecord
* orp
)
425 obj_index(orp
, orp
->parm
[0]);
426 obj_index(orp
, orp
->parm
[1]);
427 if (!(orp
->parm
[0] | orp
->parm
[1]))
428 obj_word(orp
, orp
->parm
[2]);
432 * Initializer for a LINNUM record.
433 * parm[0] = group index
434 * parm[1] = segment index
436 static void ori_linnum(ObjRecord
* orp
)
438 obj_index(orp
, orp
->parm
[0]);
439 obj_index(orp
, orp
->parm
[1]);
443 * Initializer for a local vars record.
445 static void ori_local(ObjRecord
* orp
)
452 * Null initializer for records that continue without any header info
454 static void ori_null(ObjRecord
* orp
)
456 (void)orp
; /* Do nothing */
460 * This concludes the low level section of outobj.c
463 static char obj_infile
[FILENAME_MAX
];
466 static evalfunc evaluate
;
467 static ldfunc deflabel
;
469 static int32_t first_seg
;
474 #define GROUP_MAX 256 /* we won't _realistically_ have more
475 * than this many segs in a group */
476 #define EXT_BLKSIZ 256 /* block size for externals list */
478 struct Segment
; /* need to know these structs exist */
482 struct LineNumber
*next
;
483 struct Segment
*segment
;
488 static struct FileName
{
489 struct FileName
*next
;
491 struct LineNumber
*lnhead
, **lntail
;
495 static struct Array
{
499 } *arrhead
, **arrtail
;
501 #define ARRAYBOT 31 /* magic number for first array index */
503 static struct Public
{
507 int32_t segment
; /* only if it's far-absolute */
508 int type
; /* only for local debug syms */
509 } *fpubhead
, **fpubtail
, *last_defined
;
511 static struct External
{
512 struct External
*next
;
515 int32_t commonelem
; /* element size if FAR, else zero */
516 int index
; /* OBJ-file external index */
518 DEFWRT_NONE
, /* no unusual default-WRT */
519 DEFWRT_STRING
, /* a string we don't yet understand */
520 DEFWRT_SEGMENT
, /* a segment */
521 DEFWRT_GROUP
/* a group */
528 struct External
*next_dws
; /* next with DEFWRT_STRING */
529 } *exthead
, **exttail
, *dws
;
531 static int externals
;
533 static struct ExtBack
{
534 struct ExtBack
*next
;
535 struct External
*exts
[EXT_BLKSIZ
];
538 static struct Segment
{
539 struct Segment
*next
;
540 int32_t index
; /* the NASM segment id */
541 int32_t obj_index
; /* the OBJ-file segment index */
542 struct Group
*grp
; /* the group it beint32_ts to */
544 int32_t align
; /* can be SEG_ABS + absolute addr */
551 int32_t use32
; /* is this segment 32-bit? */
552 struct Public
*pubhead
, **pubtail
, *lochead
, **loctail
;
554 char *segclass
, *overlay
; /* `class' is a C++ keyword :-) */
556 } *seghead
, **segtail
, *obj_seg_needs_update
;
558 static struct Group
{
561 int32_t index
; /* NASM segment id */
562 int32_t obj_index
; /* OBJ-file group index */
563 int32_t nentries
; /* number of elements... */
564 int32_t nindices
; /* ...and number of index elts... */
568 } segs
[GROUP_MAX
]; /* ...in this */
569 } *grphead
, **grptail
, *obj_grp_needs_update
;
571 static struct ImpDef
{
575 unsigned int impindex
;
577 } *imphead
, **imptail
;
579 static struct ExpDef
{
583 unsigned int ordinal
;
585 } *exphead
, **exptail
;
587 #define EXPDEF_FLAG_ORDINAL 0x80
588 #define EXPDEF_FLAG_RESIDENT 0x40
589 #define EXPDEF_FLAG_NODATA 0x20
590 #define EXPDEF_MASK_PARMCNT 0x1F
592 static int32_t obj_entry_seg
, obj_entry_ofs
;
596 /* The current segment */
597 static struct Segment
*current_seg
;
599 static int32_t obj_segment(char *, int, int *);
600 static void obj_write_file(int debuginfo
);
601 static int obj_directive(char *, char *, int);
603 static void obj_init(FILE * fp
, efunc errfunc
, ldfunc ldef
, evalfunc eval
)
609 first_seg
= seg_alloc();
612 fpubtail
= &fpubhead
;
623 seghead
= obj_seg_needs_update
= NULL
;
625 grphead
= obj_grp_needs_update
= NULL
;
627 obj_entry_seg
= NO_SEG
;
628 obj_uppercase
= FALSE
;
633 of_obj
.current_dfmt
->init(&of_obj
, NULL
, fp
, errfunc
);
636 static int obj_set_info(enum geninfo type
, char **val
)
643 static void obj_cleanup(int debuginfo
)
645 obj_write_file(debuginfo
);
646 of_obj
.current_dfmt
->cleanup();
649 struct Segment
*segtmp
= seghead
;
650 seghead
= seghead
->next
;
651 while (segtmp
->pubhead
) {
652 struct Public
*pubtmp
= segtmp
->pubhead
;
653 segtmp
->pubhead
= pubtmp
->next
;
654 nasm_free(pubtmp
->name
);
657 nasm_free(segtmp
->segclass
);
658 nasm_free(segtmp
->overlay
);
662 struct Public
*pubtmp
= fpubhead
;
663 fpubhead
= fpubhead
->next
;
664 nasm_free(pubtmp
->name
);
668 struct External
*exttmp
= exthead
;
669 exthead
= exthead
->next
;
673 struct ImpDef
*imptmp
= imphead
;
674 imphead
= imphead
->next
;
675 nasm_free(imptmp
->extname
);
676 nasm_free(imptmp
->libname
);
677 nasm_free(imptmp
->impname
); /* nasm_free won't mind if it's NULL */
681 struct ExpDef
*exptmp
= exphead
;
682 exphead
= exphead
->next
;
683 nasm_free(exptmp
->extname
);
684 nasm_free(exptmp
->intname
);
688 struct ExtBack
*ebtmp
= ebhead
;
689 ebhead
= ebhead
->next
;
693 struct Group
*grptmp
= grphead
;
694 grphead
= grphead
->next
;
699 static void obj_ext_set_defwrt(struct External
*ext
, char *id
)
704 for (seg
= seghead
; seg
; seg
= seg
->next
)
705 if (!strcmp(seg
->name
, id
)) {
706 ext
->defwrt_type
= DEFWRT_SEGMENT
;
707 ext
->defwrt_ptr
.seg
= seg
;
712 for (grp
= grphead
; grp
; grp
= grp
->next
)
713 if (!strcmp(grp
->name
, id
)) {
714 ext
->defwrt_type
= DEFWRT_GROUP
;
715 ext
->defwrt_ptr
.grp
= grp
;
720 ext
->defwrt_type
= DEFWRT_STRING
;
721 ext
->defwrt_ptr
.string
= id
;
726 static void obj_deflabel(char *name
, int32_t segment
,
727 int32_t offset
, int is_global
, char *special
)
730 * We have three cases:
732 * (i) `segment' is a segment-base. If so, set the name field
733 * for the segment or group structure it refers to, and then
736 * (ii) `segment' is one of our segments, or a SEG_ABS segment.
737 * Save the label position for later output of a PUBDEF record.
738 * (Or a MODPUB, if we work out how.)
740 * (iii) `segment' is not one of our segments. Save the label
741 * position for later output of an EXTDEF, and also store a
742 * back-reference so that we can map later references to this
743 * segment number to the external index.
745 struct External
*ext
;
749 int used_special
= FALSE
; /* have we used the special text? */
751 #if defined(DEBUG) && DEBUG>2
753 " obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
754 name
, segment
, offset
, is_global
, special
);
758 * If it's a special-retry from pass two, discard it.
764 * First check for the double-period, signifying something
767 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
768 if (!strcmp(name
, "..start")) {
769 obj_entry_seg
= segment
;
770 obj_entry_ofs
= offset
;
773 error(ERR_NONFATAL
, "unrecognised special symbol `%s'", name
);
779 if (obj_seg_needs_update
) {
780 obj_seg_needs_update
->name
= name
;
782 } else if (obj_grp_needs_update
) {
783 obj_grp_needs_update
->name
= name
;
786 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
789 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
791 * SEG_ABS subcase of (ii).
796 pub
= *fpubtail
= nasm_malloc(sizeof(*pub
));
797 fpubtail
= &pub
->next
;
799 pub
->name
= nasm_strdup(name
);
800 pub
->offset
= offset
;
801 pub
->segment
= (segment
== NO_SEG
? 0 : segment
& ~SEG_ABS
);
804 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
805 " for this symbol type");
810 * If `any_segs' is still FALSE, we might need to define a
811 * default segment, if they're trying to declare a label in
814 if (!any_segs
&& segment
== first_seg
) {
815 int tempint
; /* ignored */
816 if (segment
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
817 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
820 for (seg
= seghead
; seg
&& is_global
; seg
= seg
->next
)
821 if (seg
->index
== segment
) {
822 struct Public
*loc
= nasm_malloc(sizeof(*loc
));
824 * Case (ii). Maybe MODPUB someday?
827 seg
->pubtail
= &loc
->next
;
829 loc
->name
= nasm_strdup(name
);
830 loc
->offset
= offset
;
834 "OBJ supports no special symbol features"
835 " for this symbol type");
843 ext
= *exttail
= nasm_malloc(sizeof(*ext
));
845 exttail
= &ext
->next
;
847 /* Place by default all externs into the current segment */
848 ext
->defwrt_type
= DEFWRT_NONE
;
850 /* 28-Apr-2002 - John Coffman
851 The following code was introduced on 12-Aug-2000, and breaks fixups
852 on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
853 (5.10). It was introduced after FIXUP32 was added, and may be needed
854 for 32-bit segments. The following will get 16-bit segments working
855 again, and maybe someone can correct the 'if' condition which is
861 if (current_seg
&& current_seg
->use32
) {
862 if (current_seg
->grp
) {
863 ext
->defwrt_type
= DEFWRT_GROUP
;
864 ext
->defwrt_ptr
.grp
= current_seg
->grp
;
866 ext
->defwrt_type
= DEFWRT_SEGMENT
;
867 ext
->defwrt_ptr
.seg
= current_seg
;
872 if (is_global
== 2) {
873 ext
->commonsize
= offset
;
874 ext
->commonelem
= 1; /* default FAR */
881 * Now process the special text, if any, to find default-WRT
882 * specifications and common-variable element-size and near/far
885 while (special
&& *special
) {
889 * We might have a default-WRT specification.
891 if (!nasm_strnicmp(special
, "wrt", 3)) {
895 special
+= strspn(special
, " \t");
896 p
= nasm_strndup(special
, len
= strcspn(special
, ":"));
897 obj_ext_set_defwrt(ext
, p
);
899 if (*special
&& *special
!= ':')
900 error(ERR_NONFATAL
, "`:' expected in special symbol"
901 " text for `%s'", ext
->name
);
902 else if (*special
== ':')
907 * The NEAR or FAR keywords specify nearness or
908 * farness. FAR gives default element size 1.
910 if (!nasm_strnicmp(special
, "far", 3)) {
915 "`%s': `far' keyword may only be applied"
916 " to common variables\n", ext
->name
);
918 special
+= strspn(special
, " \t");
919 } else if (!nasm_strnicmp(special
, "near", 4)) {
924 "`%s': `far' keyword may only be applied"
925 " to common variables\n", ext
->name
);
927 special
+= strspn(special
, " \t");
931 * If it's a common, and anything else remains on the line
932 * before a further colon, evaluate it as an expression and
933 * use that as the element size. Forward references aren't
939 if (ext
->commonsize
) {
941 struct tokenval tokval
;
944 stdscan_bufptr
= special
;
945 tokval
.t_type
= TOKEN_INVALID
;
946 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, error
, NULL
);
949 error(ERR_NONFATAL
, "cannot use relocatable"
950 " expression as common-variable element size");
952 ext
->commonelem
= reloc_value(e
);
954 special
= stdscan_bufptr
;
957 "`%s': element-size specifications only"
958 " apply to common variables", ext
->name
);
959 while (*special
&& *special
!= ':')
970 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
974 while (i
>= EXT_BLKSIZ
) {
978 eb
= *ebtail
= nasm_malloc(sizeof(*eb
));
985 ext
->index
= ++externals
;
987 if (special
&& !used_special
)
988 error(ERR_NONFATAL
, "OBJ supports no special symbol features"
989 " for this symbol type");
992 /* forward declaration */
993 static void obj_write_fixup(ObjRecord
* orp
, int bytes
,
994 int segrel
, int32_t seg
, int32_t wrt
,
995 struct Segment
*segto
);
997 static void obj_out(int32_t segto
, const void *data
, uint32_t type
,
998 int32_t segment
, int32_t wrt
)
1000 uint32_t size
, realtype
;
1001 const uint8_t *ucdata
;
1003 struct Segment
*seg
;
1007 * handle absolute-assembly (structure definitions)
1009 if (segto
== NO_SEG
) {
1010 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
1011 error(ERR_NONFATAL
, "attempt to assemble code in [ABSOLUTE]"
1017 * If `any_segs' is still FALSE, we must define a default
1021 int tempint
; /* ignored */
1022 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
1023 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
1027 * Find the segment we are targetting.
1029 for (seg
= seghead
; seg
; seg
= seg
->next
)
1030 if (seg
->index
== segto
)
1033 error(ERR_PANIC
, "code directed to nonexistent segment?");
1036 orp
->parm
[0] = seg
->currentpos
;
1038 size
= type
& OUT_SIZMASK
;
1039 realtype
= type
& OUT_TYPMASK
;
1040 if (realtype
== OUT_RAWDATA
) {
1044 orp
= obj_check(seg
->orp
, 1);
1045 len
= RECORD_MAX
- orp
->used
;
1048 memcpy(orp
->buf
+ orp
->used
, ucdata
, len
);
1049 orp
->committed
= orp
->used
+= len
;
1050 orp
->parm
[0] = seg
->currentpos
+= len
;
1054 } else if (realtype
== OUT_ADDRESS
|| realtype
== OUT_REL2ADR
||
1055 realtype
== OUT_REL4ADR
) {
1058 if (segment
== NO_SEG
&& realtype
!= OUT_ADDRESS
)
1059 error(ERR_NONFATAL
, "relative call to absolute address not"
1060 " supported by OBJ format");
1061 if (segment
>= SEG_ABS
)
1062 error(ERR_NONFATAL
, "far-absolute relocations not supported"
1064 ldata
= *(int32_t *)data
;
1065 if (realtype
== OUT_REL2ADR
) {
1066 ldata
+= (size
- 2);
1069 if (realtype
== OUT_REL4ADR
) {
1070 ldata
+= (size
- 4);
1074 orp
= obj_word(orp
, ldata
);
1076 orp
= obj_dword(orp
, ldata
);
1078 if (segment
< SEG_ABS
&& (segment
!= NO_SEG
&& segment
% 2) &&
1081 * This is a 4-byte segment-base relocation such as
1082 * `MOV EAX,SEG foo'. OBJ format can't actually handle
1083 * these, but if the constant term has the 16 low bits
1084 * zero, we can just apply a 2-byte segment-base
1085 * relocation to the low word instead.
1089 error(ERR_NONFATAL
, "OBJ format cannot handle complex"
1090 " dword-size segment base references");
1092 if (segment
!= NO_SEG
)
1093 obj_write_fixup(orp
, rsize
,
1094 (realtype
== OUT_ADDRESS
? 0x4000 : 0),
1096 seg
->currentpos
+= size
;
1097 } else if (realtype
== OUT_RESERVE
) {
1099 orp
= obj_bump(orp
);
1100 seg
->currentpos
+= size
;
1105 static void obj_write_fixup(ObjRecord
* orp
, int bytes
,
1106 int segrel
, int32_t seg
, int32_t wrt
,
1107 struct Segment
*segto
)
1113 struct Segment
*s
= NULL
;
1114 struct Group
*g
= NULL
;
1115 struct External
*e
= NULL
;
1119 error(ERR_NONFATAL
, "`obj' output driver does not support"
1120 " one-byte relocations");
1126 orp
->child
= forp
= obj_new();
1127 forp
->up
= &(orp
->child
);
1128 /* We should choose between FIXUPP and FIXU32 record type */
1129 /* If we're targeting a 32-bit segment, use a FIXU32 record */
1131 forp
->type
= FIXU32
;
1133 forp
->type
= FIXUPP
;
1138 locat
= FIX_16_SELECTOR
;
1141 error(ERR_PANIC
, "OBJ: 4-byte segment base fixup got"
1142 " through sanity check");
1145 locat
= (bytes
== 2) ? FIX_16_OFFSET
: FIX_32_OFFSET
;
1148 * There is a bug in tlink that makes it process self relative
1149 * fixups incorrectly if the x_size doesn't match the location
1152 forp
= obj_force(forp
, bytes
<< 3);
1155 forp
= obj_rword(forp
, locat
| segrel
| (orp
->parm
[0] - orp
->parm
[2]));
1157 tidx
= fidx
= -1, method
= 0; /* placate optimisers */
1160 * See if we can find the segment ID in our segment list. If
1161 * so, we have a T4 (LSEG) target.
1163 for (s
= seghead
; s
; s
= s
->next
)
1164 if (s
->index
== seg
)
1167 method
= 4, tidx
= s
->obj_index
;
1169 for (g
= grphead
; g
; g
= g
->next
)
1170 if (g
->index
== seg
)
1173 method
= 5, tidx
= g
->obj_index
;
1175 int32_t i
= seg
/ 2;
1176 struct ExtBack
*eb
= ebhead
;
1177 while (i
>= EXT_BLKSIZ
) {
1185 method
= 6, e
= eb
->exts
[i
], tidx
= e
->index
;
1188 "unrecognised segment value in obj_write_fixup");
1193 * If no WRT given, assume the natural default, which is method
1196 * - we are doing an OFFSET fixup for a grouped segment, in
1197 * which case we require F1 (group).
1199 * - we are doing an OFFSET fixup for an external with a
1200 * default WRT, in which case we must honour the default WRT.
1202 if (wrt
== NO_SEG
) {
1203 if (!base
&& s
&& s
->grp
)
1204 method
|= 0x10, fidx
= s
->grp
->obj_index
;
1205 else if (!base
&& e
&& e
->defwrt_type
!= DEFWRT_NONE
) {
1206 if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1207 method
|= 0x00, fidx
= e
->defwrt_ptr
.seg
->obj_index
;
1208 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1209 method
|= 0x10, fidx
= e
->defwrt_ptr
.grp
->obj_index
;
1211 error(ERR_NONFATAL
, "default WRT specification for"
1212 " external `%s' unresolved", e
->name
);
1213 method
|= 0x50, fidx
= -1; /* got to do _something_ */
1216 method
|= 0x50, fidx
= -1;
1219 * See if we can find the WRT-segment ID in our segment
1220 * list. If so, we have a F0 (LSEG) frame.
1222 for (s
= seghead
; s
; s
= s
->next
)
1223 if (s
->index
== wrt
- 1)
1226 method
|= 0x00, fidx
= s
->obj_index
;
1228 for (g
= grphead
; g
; g
= g
->next
)
1229 if (g
->index
== wrt
- 1)
1232 method
|= 0x10, fidx
= g
->obj_index
;
1234 int32_t i
= wrt
/ 2;
1235 struct ExtBack
*eb
= ebhead
;
1236 while (i
>= EXT_BLKSIZ
) {
1244 method
|= 0x20, fidx
= eb
->exts
[i
]->index
;
1247 "unrecognised WRT value in obj_write_fixup");
1252 forp
= obj_byte(forp
, method
);
1254 forp
= obj_index(forp
, fidx
);
1255 forp
= obj_index(forp
, tidx
);
1259 static int32_t obj_segment(char *name
, int pass
, int *bits
)
1262 * We call the label manager here to define a name for the new
1263 * segment, and when our _own_ label-definition stub gets
1264 * called in return, it should register the new segment name
1265 * using the pointer it gets passed. That way we save memory,
1266 * by sponging off the label manager.
1268 #if defined(DEBUG) && DEBUG>=3
1269 fprintf(stderr
, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1277 struct Segment
*seg
;
1279 struct External
**extp
;
1280 int obj_idx
, i
, attrs
, rn_error
;
1284 * Look for segment attributes.
1287 while (*name
== '.')
1288 name
++; /* hack, but a documented one */
1290 while (*p
&& !isspace(*p
))
1294 while (*p
&& isspace(*p
))
1298 while (*p
&& !isspace(*p
))
1302 while (*p
&& isspace(*p
))
1310 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1312 if (!strcmp(seg
->name
, name
)) {
1313 if (attrs
> 0 && pass
== 1)
1314 error(ERR_WARNING
, "segment attributes specified on"
1315 " redeclaration of segment: ignoring");
1325 *segtail
= seg
= nasm_malloc(sizeof(*seg
));
1327 segtail
= &seg
->next
;
1328 seg
->index
= (any_segs
? seg_alloc() : first_seg
);
1329 seg
->obj_index
= obj_idx
;
1333 seg
->currentpos
= 0;
1334 seg
->align
= 1; /* default */
1335 seg
->use32
= FALSE
; /* default */
1336 seg
->combine
= CMB_PUBLIC
; /* default */
1337 seg
->segclass
= seg
->overlay
= NULL
;
1338 seg
->pubhead
= NULL
;
1339 seg
->pubtail
= &seg
->pubhead
;
1340 seg
->lochead
= NULL
;
1341 seg
->loctail
= &seg
->lochead
;
1342 seg
->orp
= obj_new();
1343 seg
->orp
->up
= &(seg
->orp
);
1344 seg
->orp
->ori
= ori_ledata
;
1345 seg
->orp
->type
= LEDATA
;
1346 seg
->orp
->parm
[1] = obj_idx
;
1349 * Process the segment attributes.
1358 * `p' contains a segment attribute.
1360 if (!nasm_stricmp(p
, "private"))
1361 seg
->combine
= CMB_PRIVATE
;
1362 else if (!nasm_stricmp(p
, "public"))
1363 seg
->combine
= CMB_PUBLIC
;
1364 else if (!nasm_stricmp(p
, "common"))
1365 seg
->combine
= CMB_COMMON
;
1366 else if (!nasm_stricmp(p
, "stack"))
1367 seg
->combine
= CMB_STACK
;
1368 else if (!nasm_stricmp(p
, "use16"))
1370 else if (!nasm_stricmp(p
, "use32"))
1372 else if (!nasm_stricmp(p
, "flat")) {
1374 * This segment is an OS/2 FLAT segment. That means
1375 * that its default group is group FLAT, even if
1376 * the group FLAT does not explicitly _contain_ the
1379 * When we see this, we must create the group
1380 * `FLAT', containing no segments, if it does not
1381 * already exist; then we must set the default
1382 * group of this segment to be the FLAT group.
1385 for (grp
= grphead
; grp
; grp
= grp
->next
)
1386 if (!strcmp(grp
->name
, "FLAT"))
1389 obj_directive("group", "FLAT", 1);
1390 for (grp
= grphead
; grp
; grp
= grp
->next
)
1391 if (!strcmp(grp
->name
, "FLAT"))
1394 error(ERR_PANIC
, "failure to define FLAT?!");
1397 } else if (!nasm_strnicmp(p
, "class=", 6))
1398 seg
->segclass
= nasm_strdup(p
+ 6);
1399 else if (!nasm_strnicmp(p
, "overlay=", 8))
1400 seg
->overlay
= nasm_strdup(p
+ 8);
1401 else if (!nasm_strnicmp(p
, "align=", 6)) {
1402 seg
->align
= readnum(p
+ 6, &rn_error
);
1405 error(ERR_NONFATAL
, "segment alignment should be"
1408 switch ((int)seg
->align
) {
1413 case 256: /* PAGE */
1414 case 4096: /* PharLap extension */
1418 "OBJ format does not support alignment"
1419 " of 8: rounding up to 16");
1426 "OBJ format does not support alignment"
1427 " of %d: rounding up to 256", seg
->align
);
1434 "OBJ format does not support alignment"
1435 " of %d: rounding up to 4096", seg
->align
);
1439 error(ERR_NONFATAL
, "invalid alignment value %d",
1444 } else if (!nasm_strnicmp(p
, "absolute=", 9)) {
1445 seg
->align
= SEG_ABS
+ readnum(p
+ 9, &rn_error
);
1447 error(ERR_NONFATAL
, "argument to `absolute' segment"
1448 " attribute should be numeric");
1452 /* We need to know whenever we have at least one 32-bit segment */
1453 obj_use32
|= seg
->use32
;
1455 obj_seg_needs_update
= seg
;
1456 if (seg
->align
>= SEG_ABS
)
1457 deflabel(name
, NO_SEG
, seg
->align
- SEG_ABS
,
1458 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1460 deflabel(name
, seg
->index
+ 1, 0L,
1461 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1462 obj_seg_needs_update
= NULL
;
1465 * See if this segment is defined in any groups.
1467 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1468 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1469 if (!strcmp(grp
->segs
[i
].name
, seg
->name
)) {
1470 nasm_free(grp
->segs
[i
].name
);
1471 grp
->segs
[i
] = grp
->segs
[grp
->nindices
];
1472 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1475 "segment `%s' is already part of"
1476 " a group: first one takes precedence",
1485 * Walk through the list of externals with unresolved
1486 * default-WRT clauses, and resolve any that point at this
1491 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1492 !strcmp((*extp
)->defwrt_ptr
.string
, seg
->name
)) {
1493 nasm_free((*extp
)->defwrt_ptr
.string
);
1494 (*extp
)->defwrt_type
= DEFWRT_SEGMENT
;
1495 (*extp
)->defwrt_ptr
.seg
= seg
;
1496 *extp
= (*extp
)->next_dws
;
1498 extp
= &(*extp
)->next_dws
;
1510 static int obj_directive(char *directive
, char *value
, int pass
)
1512 if (!strcmp(directive
, "group")) {
1516 struct Segment
*seg
;
1517 struct External
**extp
;
1522 q
++; /* hack, but a documented one */
1524 while (*q
&& !isspace(*q
))
1528 while (*q
&& isspace(*q
))
1532 * Here we used to sanity-check the group directive to
1533 * ensure nobody tried to declare a group containing no
1534 * segments. However, OS/2 does this as standard
1535 * practice, so the sanity check has been removed.
1538 * error(ERR_NONFATAL,"GROUP directive contains no segments");
1544 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1546 if (!strcmp(grp
->name
, v
)) {
1547 error(ERR_NONFATAL
, "group `%s' defined twice", v
);
1552 *grptail
= grp
= nasm_malloc(sizeof(*grp
));
1554 grptail
= &grp
->next
;
1555 grp
->index
= seg_alloc();
1556 grp
->obj_index
= obj_idx
;
1557 grp
->nindices
= grp
->nentries
= 0;
1560 obj_grp_needs_update
= grp
;
1561 deflabel(v
, grp
->index
+ 1, 0L,
1562 NULL
, FALSE
, FALSE
, &of_obj
, error
);
1563 obj_grp_needs_update
= NULL
;
1567 while (*q
&& !isspace(*q
))
1571 while (*q
&& isspace(*q
))
1575 * Now p contains a segment name. Find it.
1577 for (seg
= seghead
; seg
; seg
= seg
->next
)
1578 if (!strcmp(seg
->name
, p
))
1582 * We have a segment index. Shift a name entry
1583 * to the end of the array to make room.
1585 grp
->segs
[grp
->nentries
++] = grp
->segs
[grp
->nindices
];
1586 grp
->segs
[grp
->nindices
++].index
= seg
->obj_index
;
1589 "segment `%s' is already part of"
1590 " a group: first one takes precedence",
1596 * We have an as-yet undefined segment.
1597 * Remember its name, for later.
1599 grp
->segs
[grp
->nentries
++].name
= nasm_strdup(p
);
1604 * Walk through the list of externals with unresolved
1605 * default-WRT clauses, and resolve any that point at
1610 if ((*extp
)->defwrt_type
== DEFWRT_STRING
&&
1611 !strcmp((*extp
)->defwrt_ptr
.string
, grp
->name
)) {
1612 nasm_free((*extp
)->defwrt_ptr
.string
);
1613 (*extp
)->defwrt_type
= DEFWRT_GROUP
;
1614 (*extp
)->defwrt_ptr
.grp
= grp
;
1615 *extp
= (*extp
)->next_dws
;
1617 extp
= &(*extp
)->next_dws
;
1622 if (!strcmp(directive
, "uppercase")) {
1623 obj_uppercase
= TRUE
;
1626 if (!strcmp(directive
, "import")) {
1627 char *q
, *extname
, *libname
, *impname
;
1630 return 1; /* ignore in pass two */
1631 extname
= q
= value
;
1632 while (*q
&& !isspace(*q
))
1636 while (*q
&& isspace(*q
))
1641 while (*q
&& !isspace(*q
))
1645 while (*q
&& isspace(*q
))
1651 if (!*extname
|| !*libname
)
1652 error(ERR_NONFATAL
, "`import' directive requires symbol name"
1653 " and library name");
1658 imp
= *imptail
= nasm_malloc(sizeof(struct ImpDef
));
1659 imptail
= &imp
->next
;
1661 imp
->extname
= nasm_strdup(extname
);
1662 imp
->libname
= nasm_strdup(libname
);
1663 imp
->impindex
= readnum(impname
, &err
);
1664 if (!*impname
|| err
)
1665 imp
->impname
= nasm_strdup(impname
);
1667 imp
->impname
= NULL
;
1672 if (!strcmp(directive
, "export")) {
1673 char *q
, *extname
, *intname
, *v
;
1674 struct ExpDef
*export
;
1676 unsigned int ordinal
= 0;
1679 return 1; /* ignore in pass two */
1680 intname
= q
= value
;
1681 while (*q
&& !isspace(*q
))
1685 while (*q
&& isspace(*q
))
1690 while (*q
&& !isspace(*q
))
1694 while (*q
&& isspace(*q
))
1699 error(ERR_NONFATAL
, "`export' directive requires export name");
1708 while (*q
&& !isspace(*q
))
1712 while (*q
&& isspace(*q
))
1715 if (!nasm_stricmp(v
, "resident"))
1716 flags
|= EXPDEF_FLAG_RESIDENT
;
1717 else if (!nasm_stricmp(v
, "nodata"))
1718 flags
|= EXPDEF_FLAG_NODATA
;
1719 else if (!nasm_strnicmp(v
, "parm=", 5)) {
1721 flags
|= EXPDEF_MASK_PARMCNT
& readnum(v
+ 5, &err
);
1724 "value `%s' for `parm' is non-numeric", v
+ 5);
1729 ordinal
= readnum(v
, &err
);
1732 "unrecognised export qualifier `%s'", v
);
1735 flags
|= EXPDEF_FLAG_ORDINAL
;
1739 export
= *exptail
= nasm_malloc(sizeof(struct ExpDef
));
1740 exptail
= &export
->next
;
1741 export
->next
= NULL
;
1742 export
->extname
= nasm_strdup(extname
);
1743 export
->intname
= nasm_strdup(intname
);
1744 export
->ordinal
= ordinal
;
1745 export
->flags
= flags
;
1752 static int32_t obj_segbase(int32_t segment
)
1754 struct Segment
*seg
;
1757 * Find the segment in our list.
1759 for (seg
= seghead
; seg
; seg
= seg
->next
)
1760 if (seg
->index
== segment
- 1)
1765 * Might be an external with a default WRT.
1767 int32_t i
= segment
/ 2;
1768 struct ExtBack
*eb
= ebhead
;
1771 while (i
>= EXT_BLKSIZ
) {
1780 if (e
->defwrt_type
== DEFWRT_NONE
)
1781 return segment
; /* fine */
1782 else if (e
->defwrt_type
== DEFWRT_SEGMENT
)
1783 return e
->defwrt_ptr
.seg
->index
+ 1;
1784 else if (e
->defwrt_type
== DEFWRT_GROUP
)
1785 return e
->defwrt_ptr
.grp
->index
+ 1;
1787 return NO_SEG
; /* can't tell what it is */
1790 return segment
; /* not one of ours - leave it alone */
1793 if (seg
->align
>= SEG_ABS
)
1794 return seg
->align
; /* absolute segment */
1796 return seg
->grp
->index
+ 1; /* grouped segment */
1798 return segment
; /* no special treatment */
1801 static void obj_filename(char *inname
, char *outname
, efunc lerror
)
1803 strcpy(obj_infile
, inname
);
1804 standard_extension(inname
, outname
, ".obj", lerror
);
1807 static void obj_write_file(int debuginfo
)
1809 struct Segment
*seg
, *entry_seg_ptr
= 0;
1810 struct FileName
*fn
;
1811 struct LineNumber
*ln
;
1813 struct Public
*pub
, *loc
;
1814 struct External
*ext
;
1816 struct ExpDef
*export
;
1817 static char boast
[] = "The Netwide Assembler " NASM_VER
;
1822 * Write the THEADR module header.
1826 obj_name(orp
, obj_infile
);
1830 * Write the NASM boast comment.
1833 obj_rword(orp
, 0); /* comment type zero */
1834 obj_name(orp
, boast
);
1839 * Write the IMPDEF records, if any.
1841 for (imp
= imphead
; imp
; imp
= imp
->next
) {
1842 obj_rword(orp
, 0xA0); /* comment class A0 */
1843 obj_byte(orp
, 1); /* subfunction 1: IMPDEF */
1845 obj_byte(orp
, 0); /* import by name */
1847 obj_byte(orp
, 1); /* import by ordinal */
1848 obj_name(orp
, imp
->extname
);
1849 obj_name(orp
, imp
->libname
);
1851 obj_name(orp
, imp
->impname
);
1853 obj_word(orp
, imp
->impindex
);
1858 * Write the EXPDEF records, if any.
1860 for (export
= exphead
; export
; export
= export
->next
) {
1861 obj_rword(orp
, 0xA0); /* comment class A0 */
1862 obj_byte(orp
, 2); /* subfunction 2: EXPDEF */
1863 obj_byte(orp
, export
->flags
);
1864 obj_name(orp
, export
->extname
);
1865 obj_name(orp
, export
->intname
);
1866 if (export
->flags
& EXPDEF_FLAG_ORDINAL
)
1867 obj_word(orp
, export
->ordinal
);
1871 /* we're using extended OMF if we put in debug info */
1874 obj_byte(orp
, 0x40);
1875 obj_byte(orp
, dEXTENDED
);
1880 * Write the first LNAMES record, containing LNAME one, which
1881 * is null. Also initialize the LNAME counter.
1887 * Write some LNAMES for the segment names
1889 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1890 orp
= obj_name(orp
, seg
->name
);
1892 orp
= obj_name(orp
, seg
->segclass
);
1894 orp
= obj_name(orp
, seg
->overlay
);
1898 * Write some LNAMES for the group names
1900 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1901 orp
= obj_name(orp
, grp
->name
);
1907 * Write the SEGDEF records.
1910 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1912 uint32_t seglen
= seg
->currentpos
;
1914 acbp
= (seg
->combine
<< 2); /* C field */
1917 acbp
|= 0x01; /* P bit is Use32 flag */
1918 else if (seglen
== 0x10000L
) {
1919 seglen
= 0; /* This special case may be needed for old linkers */
1920 acbp
|= 0x02; /* B bit */
1924 if (seg
->align
>= SEG_ABS
)
1925 /* acbp |= 0x00 */ ;
1926 else if (seg
->align
>= 4096) {
1927 if (seg
->align
> 4096)
1928 error(ERR_NONFATAL
, "segment `%s' requires more alignment"
1929 " than OBJ format supports", seg
->name
);
1930 acbp
|= 0xC0; /* PharLap extension */
1931 } else if (seg
->align
>= 256) {
1933 } else if (seg
->align
>= 16) {
1935 } else if (seg
->align
>= 4) {
1937 } else if (seg
->align
>= 2) {
1942 obj_byte(orp
, acbp
);
1943 if (seg
->align
& SEG_ABS
) {
1944 obj_x(orp
, seg
->align
- SEG_ABS
); /* Frame */
1945 obj_byte(orp
, 0); /* Offset */
1948 obj_index(orp
, ++lname_idx
);
1949 obj_index(orp
, seg
->segclass
? ++lname_idx
: 1);
1950 obj_index(orp
, seg
->overlay
? ++lname_idx
: 1);
1955 * Write the GRPDEF records.
1958 for (grp
= grphead
; grp
; grp
= grp
->next
) {
1961 if (grp
->nindices
!= grp
->nentries
) {
1962 for (i
= grp
->nindices
; i
< grp
->nentries
; i
++) {
1963 error(ERR_NONFATAL
, "group `%s' contains undefined segment"
1964 " `%s'", grp
->name
, grp
->segs
[i
].name
);
1965 nasm_free(grp
->segs
[i
].name
);
1966 grp
->segs
[i
].name
= NULL
;
1969 obj_index(orp
, ++lname_idx
);
1970 for (i
= 0; i
< grp
->nindices
; i
++) {
1971 obj_byte(orp
, 0xFF);
1972 obj_index(orp
, grp
->segs
[i
].index
);
1978 * Write the PUBDEF records: first the ones in the segments,
1979 * then the far-absolutes.
1982 orp
->ori
= ori_pubdef
;
1983 for (seg
= seghead
; seg
; seg
= seg
->next
) {
1984 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
1985 orp
->parm
[1] = seg
->obj_index
;
1986 for (pub
= seg
->pubhead
; pub
; pub
= pub
->next
) {
1987 orp
= obj_name(orp
, pub
->name
);
1988 orp
= obj_x(orp
, pub
->offset
);
1989 orp
= obj_byte(orp
, 0); /* type index */
1996 for (pub
= fpubhead
; pub
; pub
= pub
->next
) { /* pub-crawl :-) */
1997 if (orp
->parm
[2] != pub
->segment
) {
1999 orp
->parm
[2] = pub
->segment
;
2001 orp
= obj_name(orp
, pub
->name
);
2002 orp
= obj_x(orp
, pub
->offset
);
2003 orp
= obj_byte(orp
, 0); /* type index */
2009 * Write the EXTDEF and COMDEF records, in order.
2011 orp
->ori
= ori_null
;
2012 for (ext
= exthead
; ext
; ext
= ext
->next
) {
2013 if (ext
->commonsize
== 0) {
2014 if (orp
->type
!= EXTDEF
) {
2018 orp
= obj_name(orp
, ext
->name
);
2019 orp
= obj_index(orp
, 0);
2021 if (orp
->type
!= COMDEF
) {
2025 orp
= obj_name(orp
, ext
->name
);
2026 orp
= obj_index(orp
, 0);
2027 if (ext
->commonelem
) {
2028 orp
= obj_byte(orp
, 0x61); /* far communal */
2029 orp
= obj_value(orp
, (ext
->commonsize
/ ext
->commonelem
));
2030 orp
= obj_value(orp
, ext
->commonelem
);
2032 orp
= obj_byte(orp
, 0x62); /* near communal */
2033 orp
= obj_value(orp
, ext
->commonsize
);
2041 * Write a COMENT record stating that the linker's first pass
2042 * may stop processing at this point. Exception is if our
2043 * MODEND record specifies a start point, in which case,
2044 * according to some variants of the documentation, this COMENT
2045 * should be omitted. So we'll omit it just in case.
2046 * But, TASM puts it in all the time so if we are using
2047 * TASM debug stuff we are putting it in
2049 if (debuginfo
|| obj_entry_seg
== NO_SEG
) {
2051 obj_byte(orp
, 0x40);
2052 obj_byte(orp
, dLINKPASS
);
2058 * 1) put out the compiler type
2059 * 2) Put out the type info. The only type we are using is near label #19
2063 struct Array
*arrtmp
= arrhead
;
2065 obj_byte(orp
, 0x40);
2066 obj_byte(orp
, dCOMPDEF
);
2071 obj_byte(orp
, 0x40);
2072 obj_byte(orp
, dTYPEDEF
);
2073 obj_word(orp
, 0x18); /* type # for linking */
2074 obj_word(orp
, 6); /* size of type */
2075 obj_byte(orp
, 0x2a); /* absolute type for debugging */
2077 obj_byte(orp
, 0x40);
2078 obj_byte(orp
, dTYPEDEF
);
2079 obj_word(orp
, 0x19); /* type # for linking */
2080 obj_word(orp
, 0); /* size of type */
2081 obj_byte(orp
, 0x24); /* absolute type for debugging */
2082 obj_byte(orp
, 0); /* near/far specifier */
2084 obj_byte(orp
, 0x40);
2085 obj_byte(orp
, dTYPEDEF
);
2086 obj_word(orp
, 0x1A); /* type # for linking */
2087 obj_word(orp
, 0); /* size of type */
2088 obj_byte(orp
, 0x24); /* absolute type for debugging */
2089 obj_byte(orp
, 1); /* near/far specifier */
2091 obj_byte(orp
, 0x40);
2092 obj_byte(orp
, dTYPEDEF
);
2093 obj_word(orp
, 0x1b); /* type # for linking */
2094 obj_word(orp
, 0); /* size of type */
2095 obj_byte(orp
, 0x23); /* absolute type for debugging */
2100 obj_byte(orp
, 0x40);
2101 obj_byte(orp
, dTYPEDEF
);
2102 obj_word(orp
, 0x1c); /* type # for linking */
2103 obj_word(orp
, 0); /* size of type */
2104 obj_byte(orp
, 0x23); /* absolute type for debugging */
2109 obj_byte(orp
, 0x40);
2110 obj_byte(orp
, dTYPEDEF
);
2111 obj_word(orp
, 0x1d); /* type # for linking */
2112 obj_word(orp
, 0); /* size of type */
2113 obj_byte(orp
, 0x23); /* absolute type for debugging */
2118 obj_byte(orp
, 0x40);
2119 obj_byte(orp
, dTYPEDEF
);
2120 obj_word(orp
, 0x1e); /* type # for linking */
2121 obj_word(orp
, 0); /* size of type */
2122 obj_byte(orp
, 0x23); /* absolute type for debugging */
2128 /* put out the array types */
2129 for (i
= ARRAYBOT
; i
< arrindex
; i
++) {
2130 obj_byte(orp
, 0x40);
2131 obj_byte(orp
, dTYPEDEF
);
2132 obj_word(orp
, i
); /* type # for linking */
2133 obj_word(orp
, arrtmp
->size
); /* size of type */
2134 obj_byte(orp
, 0x1A); /* absolute type for debugging (array) */
2135 obj_byte(orp
, arrtmp
->basetype
); /* base type */
2137 arrtmp
= arrtmp
->next
;
2141 * write out line number info with a LINNUM record
2142 * switch records when we switch segments, and output the
2143 * file in a pseudo-TASM fashion. The record switch is naive; that
2144 * is that one file may have many records for the same segment
2145 * if there are lots of segment switches
2147 if (fnhead
&& debuginfo
) {
2148 seg
= fnhead
->lnhead
->segment
;
2150 for (fn
= fnhead
; fn
; fn
= fn
->next
) {
2151 /* write out current file name */
2153 orp
->ori
= ori_null
;
2154 obj_byte(orp
, 0x40);
2155 obj_byte(orp
, dFILNAME
);
2157 obj_name(orp
, fn
->name
);
2161 /* write out line numbers this file */
2164 orp
->ori
= ori_linnum
;
2165 for (ln
= fn
->lnhead
; ln
; ln
= ln
->next
) {
2166 if (seg
!= ln
->segment
) {
2167 /* if we get here have to flush the buffer and start
2168 * a new record for a new segment
2173 orp
->parm
[0] = seg
->grp
? seg
->grp
->obj_index
: 0;
2174 orp
->parm
[1] = seg
->obj_index
;
2175 orp
= obj_word(orp
, ln
->lineno
);
2176 orp
= obj_x(orp
, ln
->offset
);
2183 * we are going to locate the entry point segment now
2184 * rather than wait until the MODEND record, because,
2185 * then we can output a special symbol to tell where the
2189 if (obj_entry_seg
!= NO_SEG
) {
2190 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2191 if (seg
->index
== obj_entry_seg
) {
2192 entry_seg_ptr
= seg
;
2197 error(ERR_NONFATAL
, "entry point is not in this module");
2201 * get ready to put out symbol records
2204 orp
->ori
= ori_local
;
2207 * put out a symbol for the entry point
2208 * no dots in this symbol, because, borland does
2209 * not (officially) support dots in label names
2210 * and I don't know what various versions of TLINK will do
2212 if (debuginfo
&& obj_entry_seg
!= NO_SEG
) {
2213 orp
= obj_name(orp
, "start_of_program");
2214 orp
= obj_word(orp
, 0x19); /* type: near label */
2215 orp
= obj_index(orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2216 orp
= obj_index(orp
, seg
->obj_index
);
2217 orp
= obj_x(orp
, obj_entry_ofs
);
2222 * put out the local labels
2224 for (seg
= seghead
; seg
&& debuginfo
; seg
= seg
->next
) {
2225 /* labels this seg */
2226 for (loc
= seg
->lochead
; loc
; loc
= loc
->next
) {
2227 orp
= obj_name(orp
, loc
->name
);
2228 orp
= obj_word(orp
, loc
->type
);
2229 orp
= obj_index(orp
, seg
->grp
? seg
->grp
->obj_index
: 0);
2230 orp
= obj_index(orp
, seg
->obj_index
);
2231 orp
= obj_x(orp
, loc
->offset
);
2239 * Write the LEDATA/FIXUPP pairs.
2241 for (seg
= seghead
; seg
; seg
= seg
->next
) {
2243 nasm_free(seg
->orp
);
2247 * Write the MODEND module end marker.
2249 orp
->type
= obj_use32
? MODE32
: MODEND
;
2250 orp
->ori
= ori_null
;
2251 if (entry_seg_ptr
) {
2252 orp
->type
= entry_seg_ptr
->use32
? MODE32
: MODEND
;
2253 obj_byte(orp
, 0xC1);
2254 seg
= entry_seg_ptr
;
2256 obj_byte(orp
, 0x10);
2257 obj_index(orp
, seg
->grp
->obj_index
);
2260 * the below changed to prevent TLINK crashing.
2261 * Previous more efficient version read:
2263 * obj_byte (orp, 0x50);
2265 obj_byte(orp
, 0x00);
2266 obj_index(orp
, seg
->obj_index
);
2268 obj_index(orp
, seg
->obj_index
);
2269 obj_x(orp
, obj_entry_ofs
);
2276 static void obj_fwrite(ObjRecord
* orp
)
2278 unsigned int cksum
, len
;
2282 if (orp
->x_size
== 32)
2285 len
= orp
->committed
+ 1;
2286 cksum
+= (len
& 0xFF) + ((len
>> 8) & 0xFF);
2287 fwriteint16_t(len
, ofp
);
2288 fwrite(orp
->buf
, 1, len
- 1, ofp
);
2289 for (ptr
= orp
->buf
; --len
; ptr
++)
2291 fputc((-cksum
) & 0xFF, ofp
);
2294 static const char *obj_stdmac
[] = {
2295 "%define __SECT__ [section .text]",
2296 "%imacro group 1+.nolist",
2299 "%imacro uppercase 0+.nolist",
2302 "%imacro export 1+.nolist",
2305 "%imacro import 1+.nolist",
2308 "%macro __NASM_CDecl__ 1",
2313 void dbgbi_init(struct ofmt
*of
, void *id
, FILE * fp
, efunc error
)
2322 arrindex
= ARRAYBOT
;
2326 static void dbgbi_cleanup(void)
2328 struct Segment
*segtmp
;
2330 struct FileName
*fntemp
= fnhead
;
2331 while (fnhead
->lnhead
) {
2332 struct LineNumber
*lntemp
= fnhead
->lnhead
;
2333 fnhead
->lnhead
= lntemp
->next
;
2336 fnhead
= fnhead
->next
;
2337 nasm_free(fntemp
->name
);
2340 for (segtmp
= seghead
; segtmp
; segtmp
= segtmp
->next
) {
2341 while (segtmp
->lochead
) {
2342 struct Public
*loctmp
= segtmp
->lochead
;
2343 segtmp
->lochead
= loctmp
->next
;
2344 nasm_free(loctmp
->name
);
2349 struct Array
*arrtmp
= arrhead
;
2350 arrhead
= arrhead
->next
;
2355 static void dbgbi_linnum(const char *lnfname
, int32_t lineno
, int32_t segto
)
2357 struct FileName
*fn
;
2358 struct LineNumber
*ln
;
2359 struct Segment
*seg
;
2361 if (segto
== NO_SEG
)
2365 * If `any_segs' is still FALSE, we must define a default
2369 int tempint
; /* ignored */
2370 if (segto
!= obj_segment("__NASMDEFSEG", 2, &tempint
))
2371 error(ERR_PANIC
, "strange segment conditions in OBJ driver");
2375 * Find the segment we are targetting.
2377 for (seg
= seghead
; seg
; seg
= seg
->next
)
2378 if (seg
->index
== segto
)
2381 error(ERR_PANIC
, "lineno directed to nonexistent segment?");
2383 /* for (fn = fnhead; fn; fn = fnhead->next) */
2384 for (fn
= fnhead
; fn
; fn
= fn
->next
) /* fbk - Austin Lunnen - John Fine */
2385 if (!nasm_stricmp(lnfname
, fn
->name
))
2388 fn
= nasm_malloc(sizeof(*fn
));
2389 fn
->name
= nasm_malloc(strlen(lnfname
) + 1);
2390 strcpy(fn
->name
, lnfname
);
2392 fn
->lntail
= &fn
->lnhead
;
2397 ln
= nasm_malloc(sizeof(*ln
));
2399 ln
->offset
= seg
->currentpos
;
2400 ln
->lineno
= lineno
;
2403 fn
->lntail
= &ln
->next
;
2406 static void dbgbi_deflabel(char *name
, int32_t segment
,
2407 int32_t offset
, int is_global
, char *special
)
2409 struct Segment
*seg
;
2414 * If it's a special-retry from pass two, discard it.
2420 * First check for the double-period, signifying something
2423 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
2430 if (obj_seg_needs_update
) {
2432 } else if (obj_grp_needs_update
) {
2435 if (segment
< SEG_ABS
&& segment
!= NO_SEG
&& segment
% 2)
2438 if (segment
>= SEG_ABS
|| segment
== NO_SEG
) {
2443 * If `any_segs' is still FALSE, we might need to define a
2444 * default segment, if they're trying to declare a label in
2445 * `first_seg'. But the label should exist due to a prior
2446 * call to obj_deflabel so we can skip that.
2449 for (seg
= seghead
; seg
; seg
= seg
->next
)
2450 if (seg
->index
== segment
) {
2451 struct Public
*loc
= nasm_malloc(sizeof(*loc
));
2453 * Case (ii). Maybe MODPUB someday?
2455 last_defined
= *seg
->loctail
= loc
;
2456 seg
->loctail
= &loc
->next
;
2458 loc
->name
= nasm_strdup(name
);
2459 loc
->offset
= offset
;
2462 static void dbgbi_typevalue(int32_t type
)
2465 int elem
= TYM_ELEMENTS(type
);
2466 type
= TYM_TYPE(type
);
2473 last_defined
->type
= 8; /* uint8_t */
2477 last_defined
->type
= 10; /* unsigned word */
2481 last_defined
->type
= 12; /* unsigned dword */
2485 last_defined
->type
= 14; /* float */
2489 last_defined
->type
= 15; /* qword */
2493 last_defined
->type
= 16; /* TBYTE */
2497 last_defined
->type
= 0x19; /*label */
2503 struct Array
*arrtmp
= nasm_malloc(sizeof(*arrtmp
));
2504 int vtype
= last_defined
->type
;
2505 arrtmp
->size
= vsize
* elem
;
2506 arrtmp
->basetype
= vtype
;
2507 arrtmp
->next
= NULL
;
2508 last_defined
->type
= arrindex
++;
2510 arrtail
= &(arrtmp
->next
);
2512 last_defined
= NULL
;
2514 static void dbgbi_output(int output_type
, void *param
)
2519 static struct dfmt borland_debug_form
= {
2520 "Borland Debug Records",
2531 static struct dfmt
*borland_debug_arr
[3] = {
2532 &borland_debug_form
,
2537 struct ofmt of_obj
= {
2538 "MS-DOS 16-bit/32-bit OMF object files",