]>
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 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* outbin.c output routines for the Netwide Assembler to produce
26 * flat-form binary files
28 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
29 * Julian Hall. All rights reserved. The software is
30 * redistributable under the licence given in the file "Licence"
31 * distributed in the NASM archive.
48 static struct Section
{
53 static long bsslen
, bssindex
;
61 struct Section
*target
;
62 } *relocs
, **reloctail
;
64 static long data_align
, bss_align
;
66 static long start_point
;
68 static void add_reloc (struct Section
*s
, long bytes
, long secref
,
72 r
= *reloctail
= nasm_malloc(sizeof(struct Reloc
));
82 static void bin_init (FILE *afp
, efunc errfunc
, ldfunc ldef
, evalfunc eval
) {
86 (void) ldef
; /* placate optimisers */
88 start_point
= 0L; /* default */
89 textsect
.contents
= saa_init(1L);
90 datasect
.contents
= saa_init(1L);
91 textsect
.length
= datasect
.length
= 0;
92 textsect
.index
= seg_alloc();
93 datasect
.index
= seg_alloc();
95 bssindex
= seg_alloc();
98 data_align
= bss_align
= 4;
101 static void bin_cleanup (void) {
103 long datapos
, datagap
, bsspos
;
105 datapos
= start_point
+ textsect
.length
;
106 datapos
= (datapos
+ data_align
-1) & ~(data_align
-1);
107 datagap
= datapos
- (start_point
+ textsect
.length
);
108 bsspos
= datapos
+ datasect
.length
;
109 bsspos
= (bsspos
+ bss_align
-1) & ~(bss_align
-1);
111 saa_rewind (textsect
.contents
);
112 saa_rewind (datasect
.contents
);
114 for (r
= relocs
; r
; r
= r
->next
) {
115 unsigned char *p
, *q
, mydata
[4];
118 saa_fread (r
->target
->contents
, r
->posn
, mydata
, r
->bytes
);
122 l
+= ((long)*p
++) << 8;
124 l
+= ((long)*p
++) << 16;
125 l
+= ((long)*p
++) << 24;
129 if (r
->secref
== textsect
.index
)
131 else if (r
->secref
== datasect
.index
)
133 else if (r
->secref
== bssindex
)
136 if (r
->secrel
== textsect
.index
)
138 else if (r
->secrel
== datasect
.index
)
140 else if (r
->secrel
== bssindex
)
145 else if (r
->bytes
== 2)
149 saa_fwrite (r
->target
->contents
, r
->posn
, mydata
, r
->bytes
);
151 saa_fpwrite (textsect
.contents
, fp
);
152 if (datasect
.length
> 0) {
155 saa_fpwrite (datasect
.contents
, fp
);
158 saa_free (textsect
.contents
);
159 saa_free (datasect
.contents
);
167 static void bin_out (long segto
, void *data
, unsigned long type
,
168 long segment
, long wrt
) {
169 unsigned char *p
, mydata
[4];
174 wrt
= NO_SEG
; /* continue to do _something_ */
175 error (ERR_NONFATAL
, "WRT not supported by binary output format");
179 * handle absolute-assembly (structure definitions)
181 if (segto
== NO_SEG
) {
182 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
183 error (ERR_NONFATAL
, "attempt to assemble code in [ABSOLUTE]"
188 if (segto
== bssindex
) { /* BSS */
189 if ((type
& OUT_TYPMASK
) != OUT_RESERVE
)
190 error(ERR_WARNING
, "attempt to initialise memory in the"
191 " BSS section: ignored");
193 } else if (segto
== textsect
.index
) {
195 } else if (segto
== datasect
.index
) {
198 error(ERR_WARNING
, "attempt to assemble code in"
199 " segment %d: defaulting to `.text'", segto
);
203 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
204 if (segment
!= NO_SEG
&&
205 segment
!= textsect
.index
&&
206 segment
!= datasect
.index
&&
207 segment
!= bssindex
) {
209 error(ERR_NONFATAL
, "binary output format does not support"
210 " segment base references");
212 error(ERR_NONFATAL
, "binary output format does not support"
213 " external references");
217 if (segment
!= NO_SEG
)
218 add_reloc (s
, type
& OUT_SIZMASK
, segment
, -1L);
220 if ((type
& OUT_SIZMASK
) == 4)
221 WRITELONG (p
, *(long *)data
);
223 WRITESHORT (p
, *(long *)data
);
224 saa_wbytes (s
->contents
, mydata
, type
& OUT_SIZMASK
);
225 s
->length
+= type
& OUT_SIZMASK
;
227 bsslen
+= type
& OUT_SIZMASK
;
228 } else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
232 saa_wbytes (s
->contents
, data
, type
);
236 } else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
238 error(ERR_WARNING
, "uninitialised space declared in"
239 " %s section: zeroing",
240 (segto
== textsect
.index
? "code" : "data"));
244 saa_wbytes (s
->contents
, NULL
, type
);
248 } else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
249 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
250 realbytes
= ((type
& OUT_TYPMASK
) == OUT_REL4ADR
? 4 : 2);
251 if (segment
!= NO_SEG
&&
252 segment
!= textsect
.index
&&
253 segment
!= datasect
.index
&&
254 segment
!= bssindex
) {
256 error(ERR_NONFATAL
, "binary output format does not support"
257 " segment base references");
259 error(ERR_NONFATAL
, "binary output format does not support"
260 " external references");
264 add_reloc (s
, realbytes
, segment
, segto
);
267 WRITELONG (p
, *(long*)data
- realbytes
- s
->length
);
269 WRITESHORT (p
, *(long*)data
- realbytes
- s
->length
);
270 saa_wbytes (s
->contents
, mydata
, realbytes
);
271 s
->length
+= realbytes
;
277 static void bin_deflabel (char *name
, long segment
, long offset
,
278 int is_global
, char *special
) {
281 error (ERR_NONFATAL
, "binary format does not support any"
282 " special symbol types");
284 if (name
[0] == '.' && name
[1] == '.' && name
[2] != '@') {
285 error (ERR_NONFATAL
, "unrecognised special symbol `%s'", name
);
289 if (is_global
== 2) {
290 error (ERR_NONFATAL
, "binary output format does not support common"
295 static long bin_secname (char *name
, int pass
, int *bits
) {
301 * Default is 16 bits.
307 return textsect
.index
;
310 while (*p
&& !isspace(*p
)) p
++;
312 if (!strcmp(name
, ".text")) {
313 sec_index
= textsect
.index
;
315 } else if (!strcmp(name
, ".data")) {
316 sec_index
= datasect
.index
;
317 sec_align
= &data_align
;
318 } else if (!strcmp(name
, ".bss")) {
319 sec_index
= bssindex
;
320 sec_align
= &bss_align
;
325 if (!nasm_strnicmp(p
,"align=",6)) {
326 if (sec_align
== NULL
)
327 error(ERR_NONFATAL
, "cannot specify an alignment to"
328 " the `.text' section");
329 else if (p
[6+strspn(p
+6,"0123456789")])
330 error(ERR_NONFATAL
, "argument to `align' is not numeric");
332 unsigned int align
= atoi(p
+6);
333 if (!align
|| ((align
-1) & align
))
334 error(ERR_NONFATAL
, "argument to `align' is not a"
345 static long bin_segbase (long segment
) {
349 static int bin_directive (char *directive
, char *value
, int pass
) {
352 if (!strcmp(directive
, "org")) {
353 start_point
= readnum (value
, &rn_error
);
355 error (ERR_NONFATAL
, "argument to ORG should be numeric");
361 static void bin_filename (char *inname
, char *outname
, efunc error
) {
362 standard_extension (inname
, outname
, "", error
);
365 static char *bin_stdmac
[] = {
366 "%define __SECT__ [section .text]",
367 "%imacro org 1+.nolist",
373 struct ofmt of_bin
= {
374 "flat-form binary files (e.g. DOS .COM, .SYS)",