* bfd.c: Remove strerror() to libiberty.
[external/binutils.git] / bfd / host-aout.c
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.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
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
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include <ansidecl.h>
22 #include <sysdep.h>
23 #include "bfd.h"
24 #include "libbfd.h"
25
26 #include <a.out.h>
27 #include "libaout.h"           /* BFD a.out internal data structures */
28
29 #include "trad-core.h"          /* Traditional Unix core files */
30
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 */
54
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) ();
123
124 /*SUPPRESS558*/
125 /*SUPPRESS529*/
126
127 bfd_target *
128 DEFUN(NAME(host_aout,object_p), (abfd),
129      bfd *abfd)
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;
139   magic = bfd_h_get_32 (abfd, magicbuf);
140
141   if (N_BADMAG (*((struct exec *) &magic))) return 0;
142
143   return NAME(aout,some_aout_object_p) (abfd, NAME(host_aout,callback));
144 }
145
146 /* Set parameters about this a.out file that are machine-dependent.
147    This routine is called from NAME(some_aout_object_p) just before it returns.
148    */
149
150 static bfd_target *
151 DEFUN(NAME(host_aout,callback), (abfd),
152      bfd *abfd)
153 {
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);
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
186   obj_reloc_entry_size (abfd) = sizeof (struct relocation_info);
187   return abfd->xvec;
188 }
189
190
191 boolean
192 DEFUN(NAME(host_aout,mkobject), (abfd),
193      bfd *abfd)
194 {
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;
201
202   bfd_error = system_call_error;
203
204   /* Use an intermediate variable for clarity */
205   rawptr = (struct aout_exec *)bfd_zalloc (abfd, sizeof (struct aout_exec));
206
207   if (rawptr == NULL) {
208     bfd_error = no_memory;
209     return false;
210   }
211
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;
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
234 DEFUN(NAME(host_aout,write_object_contents), (abfd),
235      bfd *abfd)
236 {
237 /* This works because we are on the host system */
238 #define EXEC_BYTES_SIZE         (sizeof (struct exec))
239 #define EXTERNAL_LIST_SIZE      (sizeof (struct nlist))
240   size_t data_pad = 0;
241   unsigned char exec_bytes[EXEC_BYTES_SIZE];
242   struct exec *execp = (struct exec *)exec_hdr (abfd);
243
244   execp->a_text = obj_textsec (abfd)->size;
245
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
253 #define aout_32_slurp_armap                     bfd_false
254 #define aout_32_slurp_extended_name_table       bfd_true
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
259
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
265
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
269
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
285
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
289
290 bfd_target host_aout_big_vec =
291   {
292     "a.out-host-big",
293     bfd_target_aout_flavour,
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),
307        bfd_generic_archive_p, some_kinda_core_file_p},
308       {bfd_false, NAME(host_aout,mkobject),
309        _bfd_generic_mkarchive, bfd_false},
310       {bfd_false, NAME(host_aout,write_object_contents), /* bfd_write_contents */
311        _bfd_write_archive_contents, bfd_false},
312     
313     JUMP_TABLE(JNAME(aout))
314 };
315
316 bfd_target host_aout_little_vec =
317   {
318     "a.out-host-little",
319     bfd_target_aout_flavour,
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 */
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 */
331     
332       {_bfd_dummy_target, NAME(host_aout,object_p),
333        bfd_generic_archive_p, some_kinda_core_file_p},
334       {bfd_false, NAME(host_aout,mkobject),
335        _bfd_generic_mkarchive, bfd_false},
336       {bfd_false, NAME(host_aout,write_object_contents), /* bfd_write_contents */
337        _bfd_write_archive_contents, bfd_false},
338     
339     JUMP_TABLE(JNAME(aout))
340 };