Commit | Line | Data |
---|---|---|
fb3be09b JG |
1 | /* BFD backend for local host's a.out binaries |
2 | Copyright (C) 1990-1991 Free Software Foundation, Inc. | |
3 | Written by Cygnus Support. Probably John Gilmore's fault. | |
c4cd3fc6 | 4 | |
fb3be09b | 5 | This file is part of BFD, the Binary File Descriptor library. |
c4cd3fc6 | 6 | |
fb3be09b | 7 | This program is free software; you can redistribute it and/or modify |
c4cd3fc6 | 8 | it under the terms of the GNU General Public License as published by |
fb3be09b JG |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. | |
c4cd3fc6 | 11 | |
fb3be09b | 12 | This program is distributed in the hope that it will be useful, |
c4cd3fc6 JG |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
fb3be09b JG |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
c4cd3fc6 JG |
20 | |
21 | #include <ansidecl.h> | |
7ed4093a | 22 | #include <sysdep.h> |
c4cd3fc6 JG |
23 | #include "bfd.h" |
24 | #include "libbfd.h" | |
25 | ||
26 | #include <a.out.h> | |
fb3be09b | 27 | #include "libaout.h" /* BFD a.out internal data structures */ |
c4cd3fc6 JG |
28 | |
29 | #include "trad-core.h" /* Traditional Unix core files */ | |
30 | ||
fb3be09b JG |
31 | /*======== This next section is stolen from ../include/a.out.gnu.h |
32 | ======== for all the losing Unix systems that don't provide these | |
33 | ======== macros. | |
34 | ||
35 | When porting to a new system, you must supply: | |
36 | ||
37 | HOST_PAGE_SIZE | |
38 | HOST_SEGMENT_SIZE | |
39 | HOST_MACHINE_ARCH (optional) | |
40 | HOST_MACHINE_MACHINE (optional) | |
41 | HOST_TEXT_START_ADDR | |
42 | HOST_STACK_END_ADDR | |
43 | ||
44 | in the ../include/h-systemname.h file. */ | |
45 | ||
46 | #define PAGE_SIZE HOST_PAGE_SIZE | |
47 | #define SEGMENT_SIZE HOST_SEGMENT_SIZE | |
48 | #define TEXT_START_ADDR HOST_TEXT_START_ADDR | |
49 | #define STACK_END_ADDR HOST_STACK_END_ADDR | |
50 | ||
51 | /*======== Stolen section begins below. =================================*/ | |
52 | ||
53 | #define a_info a_magic /* Old traditional Unix */ | |
c4cd3fc6 | 54 | |
fb3be09b JG |
55 | #define N_MAGIC(exec) ((exec).a_info & 0xffff) |
56 | #define N_SET_MAGIC(exec, magic) \ | |
57 | ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) | |
58 | ||
59 | /* Virtual Address of text segment from the a.out file. For OMAGIC, | |
60 | (almost always "unlinked .o's" these days), should be zero. | |
61 | For linked files, should reflect reality if we know it. */ | |
62 | ||
63 | #ifndef N_TXTADDR | |
64 | #define N_TXTADDR(x) (N_MAGIC(x)==OMAGIC? 0 : TEXT_START_ADDR) | |
65 | #endif | |
66 | ||
67 | #ifndef N_BADMAG | |
68 | #define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ | |
69 | && N_MAGIC(x) != NMAGIC \ | |
70 | && N_MAGIC(x) != ZMAGIC) | |
71 | #endif | |
72 | ||
73 | /* This complexity is for encapsulated COFF support */ | |
74 | #ifndef _N_HDROFF | |
75 | #define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec)) | |
76 | #endif | |
77 | ||
78 | #ifndef N_TXTOFF | |
79 | #define N_TXTOFF(x) (N_MAGIC(x) == ZMAGIC ? \ | |
80 | _N_HDROFF((x)) + sizeof (struct exec) : \ | |
81 | sizeof (struct exec)) | |
82 | #endif | |
83 | ||
84 | ||
85 | #ifndef N_DATOFF | |
86 | #define N_DATOFF(x) ( N_TXTOFF(x) + (x).a_text ) | |
87 | #endif | |
88 | ||
89 | #ifndef N_TRELOFF | |
90 | #define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) | |
91 | #endif | |
92 | ||
93 | #ifndef N_DRELOFF | |
94 | #define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) | |
95 | #endif | |
96 | ||
97 | #ifndef N_SYMOFF | |
98 | #define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) | |
99 | #endif | |
100 | ||
101 | #ifndef N_STROFF | |
102 | #define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) | |
103 | #endif | |
104 | ||
105 | /* Address of text segment in memory after it is loaded. */ | |
106 | #ifndef N_TXTADDR | |
107 | #define N_TXTADDR(x) 0 | |
108 | #endif | |
109 | ||
110 | #ifndef N_DATADDR | |
111 | #define N_DATADDR(x) \ | |
112 | (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) \ | |
113 | : (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1)))) | |
114 | #endif | |
115 | ||
116 | /* Address of bss segment in memory after it is loaded. */ | |
117 | #ifndef N_BSSADDR | |
118 | #define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) | |
119 | #endif | |
120 | ||
121 | ||
122 | static bfd_target *NAME(host_aout,callback) (); | |
c4cd3fc6 JG |
123 | |
124 | /*SUPPRESS558*/ | |
125 | /*SUPPRESS529*/ | |
126 | ||
127 | bfd_target * | |
fb3be09b JG |
128 | DEFUN(NAME(host_aout,object_p), (abfd), |
129 | bfd *abfd) | |
c4cd3fc6 JG |
130 | { |
131 | unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ | |
132 | unsigned long magic; /* Swapped magic number */ | |
133 | ||
134 | bfd_error = system_call_error; | |
135 | ||
136 | if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) != | |
137 | sizeof (magicbuf)) | |
138 | return 0; | |
fb3be09b | 139 | magic = bfd_h_get_32 (abfd, magicbuf); |
c4cd3fc6 JG |
140 | |
141 | if (N_BADMAG (*((struct exec *) &magic))) return 0; | |
142 | ||
fb3be09b | 143 | return NAME(aout,some_aout_object_p) (abfd, NAME(host_aout,callback)); |
c4cd3fc6 JG |
144 | } |
145 | ||
146 | /* Set parameters about this a.out file that are machine-dependent. | |
fb3be09b JG |
147 | This routine is called from NAME(some_aout_object_p) just before it returns. |
148 | */ | |
c4cd3fc6 JG |
149 | |
150 | static bfd_target * | |
fb3be09b JG |
151 | DEFUN(NAME(host_aout,callback), (abfd), |
152 | bfd *abfd) | |
c4cd3fc6 | 153 | { |
fb3be09b JG |
154 | /* exec_hdr (abfd), a "struct internal_exec *", is just an abstraction, |
155 | as far as the BFD a.out layer cares. We use it as a "struct exec *". | |
156 | This routine moves any data from the exec header, | |
157 | which is needed by the BFD code, out to places known to BFD. This | |
158 | allows the rest of the BFD code to not know or care about the structure | |
159 | of exec_hdr (abfd). */ | |
160 | struct exec *execp = (struct exec *)exec_hdr (abfd); | |
c4cd3fc6 JG |
161 | |
162 | /* The virtual memory addresses of the sections */ | |
163 | obj_datasec (abfd)->vma = N_DATADDR(*execp); | |
164 | obj_bsssec (abfd)->vma = N_BSSADDR(*execp); | |
165 | obj_textsec (abfd)->vma = N_TXTADDR(*execp); | |
166 | ||
167 | /* The file offsets of the sections */ | |
168 | obj_textsec (abfd)->filepos = N_TXTOFF(*execp); | |
169 | obj_datasec (abfd)->filepos = N_DATOFF(*execp); | |
170 | ||
171 | /* The file offsets of the relocation info */ | |
172 | obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); | |
173 | obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); | |
174 | ||
175 | /* The file offsets of the string table and symbol table. */ | |
176 | obj_str_filepos (abfd) = N_STROFF (*execp); | |
177 | obj_sym_filepos (abfd) = N_SYMOFF (*execp); | |
178 | ||
179 | #ifdef HOST_MACHINE_ARCH | |
180 | abfd->obj_arch = HOST_MACHINE_ARCH; | |
181 | #endif | |
182 | #ifdef HOST_MACHINE_MACHINE | |
183 | abfd->obj_machine = HOST_MACHINE_MACHINE; | |
184 | #endif | |
185 | ||
fb3be09b | 186 | obj_reloc_entry_size (abfd) = sizeof (struct relocation_info); |
c4cd3fc6 JG |
187 | return abfd->xvec; |
188 | } | |
189 | ||
190 | ||
191 | boolean | |
fb3be09b JG |
192 | DEFUN(NAME(host_aout,mkobject), (abfd), |
193 | bfd *abfd) | |
c4cd3fc6 | 194 | { |
fb3be09b JG |
195 | /* This struct is just for allocating two things with one zalloc, so |
196 | they will be freed together, without violating alignment constraints. */ | |
197 | struct aout_exec { | |
198 | struct aoutdata aoutdata; | |
199 | struct exec exec; | |
200 | } *rawptr; | |
c4cd3fc6 JG |
201 | |
202 | bfd_error = system_call_error; | |
203 | ||
204 | /* Use an intermediate variable for clarity */ | |
fb3be09b | 205 | rawptr = (struct aout_exec *)bfd_zalloc (abfd, sizeof (struct aout_exec)); |
c4cd3fc6 JG |
206 | |
207 | if (rawptr == NULL) { | |
208 | bfd_error = no_memory; | |
209 | return false; | |
210 | } | |
211 | ||
fb3be09b JG |
212 | set_tdata (abfd, &rawptr->aoutdata); |
213 | /* exec_hdr (abfd), a "struct internal_exec *", is just an abstraction, | |
214 | as far as the BFD a.out layer cares. We use it as a "struct exec *". */ | |
215 | exec_hdr (abfd) = (struct internal_exec *) &rawptr->exec; | |
c4cd3fc6 JG |
216 | |
217 | /* For simplicity's sake we just make all the sections right here. */ | |
218 | ||
219 | obj_textsec (abfd) = (asection *)NULL; | |
220 | obj_datasec (abfd) = (asection *)NULL; | |
221 | obj_bsssec (abfd) = (asection *)NULL; | |
222 | bfd_make_section (abfd, ".text"); | |
223 | bfd_make_section (abfd, ".data"); | |
224 | bfd_make_section (abfd, ".bss"); | |
225 | ||
226 | return true; | |
227 | } | |
228 | ||
229 | /* Write an object file in host a.out format. | |
230 | Section contents have already been written. We write the | |
231 | file header, symbols, and relocation. */ | |
232 | ||
233 | boolean | |
fb3be09b JG |
234 | DEFUN(NAME(host_aout,write_object_contents), (abfd), |
235 | bfd *abfd) | |
c4cd3fc6 JG |
236 | { |
237 | /* This works because we are on the host system */ | |
fb3be09b JG |
238 | #define EXEC_BYTES_SIZE (sizeof (struct exec)) |
239 | #define EXTERNAL_LIST_SIZE (sizeof (struct nlist)) | |
c4cd3fc6 JG |
240 | size_t data_pad = 0; |
241 | unsigned char exec_bytes[EXEC_BYTES_SIZE]; | |
fb3be09b | 242 | struct exec *execp = (struct exec *)exec_hdr (abfd); |
c4cd3fc6 JG |
243 | |
244 | execp->a_text = obj_textsec (abfd)->size; | |
245 | ||
fb3be09b JG |
246 | WRITE_HEADERS (abfd, execp); |
247 | return true; | |
248 | } | |
249 | \f | |
250 | /* We use BFD generic archive files. */ | |
251 | #define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file | |
252 | #define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt | |
9e2dad8e | 253 | #define aout_32_slurp_armap bfd_false |
fb3be09b | 254 | #define aout_32_slurp_extended_name_table bfd_true |
9e2dad8e JG |
255 | #define aout_32_write_armap (PROTO (boolean, (*), \ |
256 | (bfd *arch, unsigned int elength, struct orl *map, int orl_count, \ | |
257 | int stridx))) bfd_false | |
258 | #define aout_32_truncate_arname bfd_dont_truncate_arname | |
c4cd3fc6 | 259 | |
9e2dad8e JG |
260 | /* No core file defined here -- configure in trad-core.c separately. */ |
261 | #define aout_32_core_file_failing_command bfd_false | |
262 | #define aout_32_core_file_failing_signal bfd_false | |
263 | #define aout_32_core_file_matches_executable_p bfd_true | |
264 | #define some_kinda_core_file_p bfd_false | |
c4cd3fc6 | 265 | |
fb3be09b JG |
266 | #define aout_32_bfd_debug_info_start bfd_void |
267 | #define aout_32_bfd_debug_info_end bfd_void | |
268 | #define aout_32_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void | |
c4cd3fc6 | 269 | |
9e2dad8e JG |
270 | #define aout_64_openr_next_archived_file aout_32_openr_next_archived_file |
271 | #define aout_64_generic_stat_arch_elt aout_32_generic_stat_arch_elt | |
272 | #define aout_64_slurp_armap aout_32_slurp_armap | |
273 | #define aout_64_slurp_extended_name_table aout_32_slurp_extended_name_table | |
274 | #define aout_64_write_armap aout_32_write_armap | |
275 | #define aout_64_truncate_arname aout_32_truncate_arname | |
276 | ||
277 | #define aout_64_core_file_failing_command aout_32_core_file_failing_command | |
278 | #define aout_64_core_file_failing_signal aout_32_core_file_failing_signal | |
279 | #define aout_64_core_file_matches_executable_p aout_32_core_file_matches_executable_p | |
280 | ||
281 | #define aout_64_bfd_debug_info_start aout_32_bfd_debug_info_start | |
282 | #define aout_64_bfd_debug_info_end aout_32_bfd_debug_info_end | |
283 | #define aout_64_bfd_debug_info_accumulate aout_32_bfd_debug_info_accumulate | |
284 | ||
c4cd3fc6 | 285 | |
fb3be09b JG |
286 | /* We implement these routines ourselves, rather than using the generic |
287 | a.out versions. */ | |
288 | #define aout_write_object_contents host_write_object_contents | |
c4cd3fc6 JG |
289 | |
290 | bfd_target host_aout_big_vec = | |
fb3be09b JG |
291 | { |
292 | "a.out-host-big", | |
9e2dad8e | 293 | bfd_target_aout_flavour, |
fb3be09b JG |
294 | true, /* target byte order */ |
295 | true, /* target headers byte order */ | |
296 | (HAS_RELOC | EXEC_P | /* object flags */ | |
297 | HAS_LINENO | HAS_DEBUG | | |
298 | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), | |
299 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ | |
300 | ' ', /* ar_pad_char */ | |
301 | 16, /* ar_max_namelen */ | |
302 | 3, /* minimum alignment power */ | |
303 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */ | |
304 | _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */ | |
305 | ||
306 | {_bfd_dummy_target, NAME(host_aout,object_p), | |
9e2dad8e | 307 | bfd_generic_archive_p, some_kinda_core_file_p}, |
fb3be09b | 308 | {bfd_false, NAME(host_aout,mkobject), |
c4cd3fc6 | 309 | _bfd_generic_mkarchive, bfd_false}, |
fb3be09b | 310 | {bfd_false, NAME(host_aout,write_object_contents), /* bfd_write_contents */ |
c4cd3fc6 | 311 | _bfd_write_archive_contents, bfd_false}, |
fb3be09b JG |
312 | |
313 | JUMP_TABLE(JNAME(aout)) | |
c4cd3fc6 JG |
314 | }; |
315 | ||
316 | bfd_target host_aout_little_vec = | |
fb3be09b JG |
317 | { |
318 | "a.out-host-little", | |
9e2dad8e | 319 | bfd_target_aout_flavour, |
fb3be09b JG |
320 | false, /* target byte order */ |
321 | false, /* target headers byte order */ | |
322 | (HAS_RELOC | EXEC_P | /* object flags */ | |
323 | HAS_LINENO | HAS_DEBUG | | |
324 | HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), | |
325 | (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ | |
326 | ' ', /* ar_pad_char */ | |
327 | 16, /* ar_max_namelen */ | |
328 | 3, /* minimum alignment power */ | |
9e2dad8e JG |
329 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putb16, /* data */ |
330 | _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */ | |
fb3be09b JG |
331 | |
332 | {_bfd_dummy_target, NAME(host_aout,object_p), | |
9e2dad8e | 333 | bfd_generic_archive_p, some_kinda_core_file_p}, |
fb3be09b | 334 | {bfd_false, NAME(host_aout,mkobject), |
c4cd3fc6 | 335 | _bfd_generic_mkarchive, bfd_false}, |
fb3be09b | 336 | {bfd_false, NAME(host_aout,write_object_contents), /* bfd_write_contents */ |
c4cd3fc6 | 337 | _bfd_write_archive_contents, bfd_false}, |
fb3be09b JG |
338 | |
339 | JUMP_TABLE(JNAME(aout)) | |
c4cd3fc6 | 340 | }; |