]>
git.saurik.com Git - apple/boot.git/blob - i386/nasm/outbin.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* outbin.c output routines for the Netwide Assembler to produce
25 * flat-form binary files
27 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
28 * Julian Hall. All rights reserved. The software is
29 * redistributable under the licence given in the file "Licence"
30 * distributed in the NASM archive.
47 static struct Section
{
52 static long bsslen
, bssindex
;
60 struct Section
*target
;
61 } *relocs
, **reloctail
;
63 static long data_align
, bss_align
;
65 static long start_point
;
67 static void add_reloc (struct Section
*s
, long bytes
, long secref
,
71 r
= *reloctail
= nasm_malloc(sizeof(struct Reloc
));
81 static void bin_init (FILE *afp
, efunc errfunc
, ldfunc ldef
, evalfunc eval
) {
85 (void) ldef
; /* placate optimisers */
87 start_point
= 0L; /* default */
88 textsect
.contents
= saa_init(1L);
89 datasect
.contents
= saa_init(1L);
90 textsect
.length
= datasect
.length
= 0;
91 textsect
.index
= seg_alloc();
92 datasect
.index
= seg_alloc();
94 bssindex
= seg_alloc();
97 data_align
= bss_align
= 4;
100 static void bin_cleanup (void) {
102 long datapos
, datagap
, bsspos
;
104 datapos
= start_point
+ textsect
.length
;
105 datapos
= (datapos
+ data_align
-1) & ~(data_align
-1);
106 datagap
= datapos
- (start_point
+ textsect
.length
);
107 bsspos
= datapos
+ datasect
.length
;
108 bsspos
= (bsspos
+ bss_align
-1) & ~(bss_align
-1);
110 saa_rewind (textsect
.contents
);
111 saa_rewind (datasect
.contents
);
113 for (r
= relocs
; r
; r
= r
->next
) {
114 unsigned char *p
, *q
, mydata
[4];
117 saa_fread (r
->target
->contents
, r
->posn
, mydata
, r
->bytes
);
121 l
+= ((long)*p
++) << 8;
123 l
+= ((long)*p
++) << 16;
124 l
+= ((long)*p
++) << 24;
128 if (r
->secref
== textsect
.index
)
130 else if (r
->secref
== datasect
.index
)
132 else if (r
->secref
== bssindex
)
135 if (r
->secrel
== textsect
.index
)
137 else if (r
->secrel
== datasect
.index
)
139 else if (r
->secrel
== bssindex
)
144 else if (r
->bytes
== 2)
148 saa_fwrite (r
->target
->contents
, r
->posn
, mydata
, r
->bytes
);
150 saa_fpwrite (textsect
.contents
, fp
);
151 if (datasect
.length
> 0) {
154 saa_fpwrite (datasect
.contents
, fp
);
157 saa_free (textsect
.contents
);
158 saa_free (datasect
.contents
);
166 static void bin_out (long segto
, void *data
, unsigned long type
,
167 long segment
, long wrt
) {
168 unsigned char *p
, mydata
[4];
173 wrt
= NO_SEG
; /* continue to do _something_ */
174 error (ERR_NONFATAL
, "WRT not supported by binary output format");
178 * handle absolute-assembly (structure definitions)
180 if (segto
== NO_SEG
) {
181 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
182 error (ERR_NONFATAL
, "attempt to assemble code in [ABSOLUTE]"
187 if (segto
== bssindex
) { /* BSS */
188 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
189 error(ERR_WARNING
, "attempt to initialise memory in the"
190 " BSS section: ignored");
192 } else if (segto
== textsect
.index
) {
194 } else if (segto
== datasect
.index
) {
197 error(ERR_WARNING
, "attempt to assemble code in"
198 " segment %d: defaulting to `.text'", segto
);
202 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
203 if (segment
!= NO_SEG
&&
204 segment
!= textsect
.index
&&
205 segment
!= datasect
.index
&&
206 segment
!= bssindex
) {
208 error(ERR_NONFATAL
, "binary output format does not support"
209 " segment base references");
211 error(ERR_NONFATAL
, "binary output format does not support"
212 " external references");
216 if (segment
!= NO_SEG
)
217 add_reloc (s
, type
& OUT_SIZMASK
, segment
, -1L);
219 if ((type
& OUT_SIZMASK
) == 4)
220 WRITELONG (p
, *(long *)data
);
222 WRITESHORT (p
, *(long *)data
);
223 saa_wbytes (s
->contents
, mydata
, type
& OUT_SIZMASK
);
224 s
->length
+= type
& OUT_SIZMASK
;
226 bsslen
+= type
& OUT_SIZMASK
;
227 } else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
231 saa_wbytes (s
->contents
, data
, type
);
235 } else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
237 error(ERR_WARNING
, "uninitialised space declared in"
238 " %s section: zeroing",
239 (segto
== textsect
.index
? "code" : "data"));
243 saa_wbytes (s
->contents
, NULL
, type
);
247 } else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
248 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
249 realbytes
= ((type
& OUT_TYPMASK
) == OUT_REL4ADR
? 4 : 2);
250 if (segment
!= NO_SEG
&&
251 segment
!= textsect
.index
&&
252 segment
!= datasect
.index
&&
253 segment
!= bssindex
) {
255 error(ERR_NONFATAL
, "binary output format does not support"
256 " segment base references");
258 error(ERR_NONFATAL
, "binary output format does not support"
259 " external references");
263 add_reloc (s
, realbytes
, segment
, segto
);
266 WRITELONG (p
, *(long*)data
- realbytes
- s
->length
);
268 WRITESHORT (p
, *(long*)data
- realbytes
- s
->length
);
269 saa_wbytes (s
->contents
, mydata
, realbytes
);
270 s
->length
+= realbytes
;
276 static void bin_deflabel (char *name
, long segment
, long offset
,
277 int is_global
, char *special
) {
280 error (ERR_NONFATAL
, "binary format does not support any"
281 " special symbol types");
283 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
284 error (ERR_NONFATAL
, "unrecognised special symbol `%s'", name
);
288 if (is_global
== 2) {
289 error (ERR_NONFATAL
, "binary output format does not support common"
294 static long bin_secname (char *name
, int pass
, int *bits
) {
300 * Default is 16 bits.
306 return textsect
.index
;
309 while (*p
&& !isspace(*p
)) p
++;
311 if (!strcmp(name
, ".text")) {
312 sec_index
= textsect
.index
;
314 } else if (!strcmp(name
, ".data")) {
315 sec_index
= datasect
.index
;
316 sec_align
= &data_align
;
317 } else if (!strcmp(name
, ".bss")) {
318 sec_index
= bssindex
;
319 sec_align
= &bss_align
;
324 if (!nasm_strnicmp(p
,"align=",6)) {
325 if (sec_align
== NULL
)
326 error(ERR_NONFATAL
, "cannot specify an alignment to"
327 " the `.text' section");
328 else if (p
[6+strspn(p
+6,"0123456789")])
329 error(ERR_NONFATAL
, "argument to `align' is not numeric");
331 unsigned int align
= atoi(p
+6);
332 if (!align
|| ((align
-1) & align
))
333 error(ERR_NONFATAL
, "argument to `align' is not a"
344 static long bin_segbase (long segment
) {
348 static int bin_directive (char *directive
, char *value
, int pass
) {
351 if (!strcmp(directive
, "org")) {
352 start_point
= readnum (value
, &rn_error
);
354 error (ERR_NONFATAL
, "argument to ORG should be numeric");
360 static void bin_filename (char *inname
, char *outname
, efunc error
) {
361 standard_extension (inname
, outname
, "", error
);
364 static char *bin_stdmac
[] = {
365 "%define __SECT__ [section .text]",
366 "%imacro org 1+.nolist",
372 struct ofmt of_bin
= {
373 "flat-form binary files (e.g. DOS .COM, .SYS)",