1 /* A.out "format 1" file handling code
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
25 #include <a.out.sun4.h>
33 The file @code{aoutf1.h} contains the code for BFD's
34 a.out back end. Control over the generated back end is given by these
35 two preprocessor names:
38 This value should be either 32 or 64, depending upon the size of an
39 int in the target format. It changes the sizes of the structs which
40 perform the memory/disk mapping of structures.
42 The 64 bit backend may only be used if the host compiler supports 64
43 ints (eg long long with gcc), by defining the name @code{HOST_64_BIT} in @code{bfd.h}.
44 With this name defined, @emph{all} bfd operations are performed with 64bit
45 arithmetic, not just those to a 64bit target.
48 The name put into the target vector.
54 void (*bfd_error_trap
)();
56 static bfd_target
*sunos4_callback ();
62 DEFUN(NAME(sunos
,object_p
), (abfd
),
65 struct external_exec exec_bytes
; /* Raw exec header from file */
66 struct internal_exec exec
; /* Cleaned-up exec header */
68 if (bfd_read ((PTR
) &exec_bytes
, 1, EXEC_BYTES_SIZE
, abfd
)
70 bfd_error
= wrong_format
;
74 exec
.a_info
= bfd_h_get_32 (abfd
, exec_bytes
.e_info
);
76 if (N_BADMAG (exec
)) return 0;
78 NAME(aout
,swap_exec_header_in
)(abfd
, &exec_bytes
, &exec
);
80 return NAME(aout
,some_aout_object_p
) (abfd
, &exec
, sunos4_callback
);
83 /* Determine the size of a relocation entry, based on the architecture */
85 DEFUN(choose_reloc_size
,(abfd
),
88 switch (bfd_get_arch(abfd
)) {
91 obj_reloc_entry_size (abfd
) = RELOC_EXT_SIZE
;
94 obj_reloc_entry_size (abfd
) = RELOC_STD_SIZE
;
99 /* Set parameters about this a.out file that are machine-dependent.
100 This routine is called from some_aout_object_p just before it returns. */
103 sunos4_callback (abfd
)
106 struct internal_exec
*execp
= exec_hdr (abfd
);
107 enum bfd_architecture arch
;
110 WORK_OUT_FILE_POSITIONS(abfd
, execp
);
112 /* Determine the architecture and machine type of the object file. */
113 switch (N_MACHTYPE (*exec_hdr (abfd
))) {
116 arch
= bfd_arch_unknown
;
122 arch
= bfd_arch_m68k
;
128 arch
= bfd_arch_m68k
;
133 arch
= bfd_arch_sparc
;
138 arch
= bfd_arch_i386
;
143 arch
= bfd_arch_a29k
;
148 arch
= bfd_arch_m68k
;
153 arch
= bfd_arch_obscure
;
157 bfd_set_arch_mach(abfd
, arch
, machine
);
158 choose_reloc_size(abfd
);
159 adata(abfd
)->page_size
= PAGE_SIZE
;
161 adata(abfd
)->segment_size
= SEGMENT_SIZE
;
163 adata(abfd
)->segment_size
= PAGE_SIZE
;
165 adata(abfd
)->exec_bytes_size
= EXEC_BYTES_SIZE
;
172 DEFUN(sunos_mkobject
,(abfd
),
175 if (NAME(aout
,mkobject
)(abfd
) == false)
177 adata(abfd
)->page_size
= PAGE_SIZE
;
179 adata(abfd
)->page_size
= SEGMENT_SIZE
;
181 adata(abfd
)->segment_size
= PAGE_SIZE
;
183 adata(abfd
)->exec_bytes_size
= EXEC_BYTES_SIZE
;
187 /* Write an object file in SunOS format.
188 Section contents have already been written. We write the
189 file header, symbols, and relocation. */
192 DEFUN(NAME(aout
,sunos4_write_object_contents
),
196 bfd_size_type data_pad
= 0;
197 struct external_exec exec_bytes
;
198 struct internal_exec
*execp
= exec_hdr (abfd
);
200 execp
->a_text
= obj_textsec (abfd
)->size
;
202 /* Magic number, maestro, please! */
203 switch (bfd_get_arch(abfd
)) {
205 switch (bfd_get_mach(abfd
)) {
207 N_SET_MACHTYPE(*execp
, M_68010
);
211 N_SET_MACHTYPE(*execp
, M_68020
);
216 N_SET_MACHTYPE(*execp
, M_SPARC
);
219 N_SET_MACHTYPE(*execp
, M_386
);
222 N_SET_MACHTYPE(*execp
, M_29K
);
225 N_SET_MACHTYPE(*execp
, M_UNKNOWN
);
228 choose_reloc_size(abfd
);
231 N_SET_FLAGS (*execp
, 0x1);
233 WRITE_HEADERS(abfd
, execp
);
240 #define CORE_MAGIC 0x080456
241 #define CORE_NAMELEN 16
243 /* The core structure is taken from the Sun documentation.
244 Unfortunately, they don't document the FPA structure, or at least I
245 can't find it easily. Fortunately the core header contains its own
246 length. So this shouldn't cause problems, except for c_ucode, which
247 so far we don't use but is easy to find with a little arithmetic. */
249 /* But the reg structure can be gotten from the SPARC processor handbook.
250 This really should be in a GNU include file though so that gdb can use
274 /* Taken from Sun documentation: */
276 /* FIXME: It's worse than we expect. This struct contains TWO substructs
277 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
278 even portably access the stuff in between! */
280 struct external_sparc_core
{
281 int c_magic
; /* Corefile magic number */
282 int c_len
; /* Sizeof (struct core) */
283 #define SPARC_CORE_LEN 432
284 int c_regs
[19]; /* General purpose registers -- MACHDEP SIZE */
285 struct external_exec c_aouthdr
; /* A.out header */
286 int c_signo
; /* Killing signal, if any */
287 int c_tsize
; /* Text size (bytes) */
288 int c_dsize
; /* Data size (bytes) */
289 int c_ssize
; /* Stack size (bytes) */
290 char c_cmdname
[CORE_NAMELEN
+ 1]; /* Command name */
291 double fp_stuff
[1]; /* external FPU state (size unknown by us) */
292 /* The type "double" is critical here, for alignment.
293 SunOS declares a struct here, but the struct's alignment
294 is double since it contains doubles. */
295 int c_ucode
; /* Exception no. from u_code */
296 /* (this member is not accessible by name since we don't
297 portably know the size of fp_stuff.) */
300 struct external_sun3_core
{
301 int c_magic
; /* Corefile magic number */
302 int c_len
; /* Sizeof (struct core) */
303 #define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */
304 int c_regs
[18]; /* General purpose registers -- MACHDEP SIZE */
305 struct external_exec c_aouthdr
; /* A.out header */
306 int c_signo
; /* Killing signal, if any */
307 int c_tsize
; /* Text size (bytes) */
308 int c_dsize
; /* Data size (bytes) */
309 int c_ssize
; /* Stack size (bytes) */
310 char c_cmdname
[CORE_NAMELEN
+ 1]; /* Command name */
311 double fp_stuff
[1]; /* external FPU state (size unknown by us) */
312 /* The type "double" is critical here, for alignment.
313 SunOS declares a struct here, but the struct's alignment
314 is double since it contains doubles. */
315 int c_ucode
; /* Exception no. from u_code */
316 /* (this member is not accessible by name since we don't
317 portably know the size of fp_stuff.) */
320 struct internal_sunos_core
{
321 int c_magic
; /* Corefile magic number */
322 int c_len
; /* Sizeof (struct core) */
323 long c_regs_pos
; /* file offset of General purpose registers */
324 int c_regs_size
; /* size of General purpose registers */
325 struct internal_exec c_aouthdr
; /* A.out header */
326 int c_signo
; /* Killing signal, if any */
327 int c_tsize
; /* Text size (bytes) */
328 int c_dsize
; /* Data size (bytes) */
329 int c_ssize
; /* Stack size (bytes) */
330 long c_stacktop
; /* Stack top (address) */
331 char c_cmdname
[CORE_NAMELEN
+ 1]; /* Command name */
332 long fp_stuff_pos
; /* file offset of external FPU state (regs) */
333 int fp_stuff_size
; /* Size of it */
334 int c_ucode
; /* Exception no. from u_code */
337 /* byte-swap in the Sun-3 core structure */
339 DEFUN(swapcore_sun3
,(abfd
, ext
, intcore
),
342 struct internal_sunos_core
*intcore
)
344 struct external_sun3_core
*extcore
= (struct external_sun3_core
*)ext
;
346 intcore
->c_magic
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_magic
);
347 intcore
->c_len
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_len
);
348 intcore
->c_regs_pos
= (long) (((struct external_sun3_core
*)0)->c_regs
);
349 intcore
->c_regs_size
= sizeof (extcore
->c_regs
);
350 NAME(aout
,swap_exec_header_in
)(abfd
, &extcore
->c_aouthdr
,&intcore
->c_aouthdr
);
351 intcore
->c_signo
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_signo
);
352 intcore
->c_tsize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_tsize
);
353 intcore
->c_dsize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_dsize
);
354 intcore
->c_ssize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_ssize
);
355 bcopy (extcore
->c_cmdname
, intcore
->c_cmdname
, sizeof (intcore
->c_cmdname
));
356 intcore
->fp_stuff_pos
= (long) (((struct external_sun3_core
*)0)->fp_stuff
);
357 /* FP stuff takes up whole rest of struct, except c_ucode. */
358 intcore
->fp_stuff_size
= intcore
->c_len
- (sizeof extcore
->c_ucode
) -
359 (file_ptr
)(((struct external_sun3_core
*)0)->fp_stuff
);
360 /* Ucode is the last thing in the struct -- just before the end */
363 intcore
->c_len
- sizeof (extcore
->c_ucode
) + (unsigned char *)extcore
);
364 intcore
->c_stacktop
= 0x0E000000; /* By experimentation */
368 /* byte-swap in the Sparc core structure */
370 DEFUN(swapcore_sparc
,(abfd
, ext
, intcore
),
373 struct internal_sunos_core
*intcore
)
375 struct external_sparc_core
*extcore
= (struct external_sparc_core
*)ext
;
377 intcore
->c_magic
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_magic
);
378 intcore
->c_len
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_len
);
379 intcore
->c_regs_pos
= (long) (((struct external_sparc_core
*)0)->c_regs
);
380 intcore
->c_regs_size
= sizeof (extcore
->c_regs
);
381 NAME(aout
,swap_exec_header_in
)(abfd
, &extcore
->c_aouthdr
,&intcore
->c_aouthdr
);
382 intcore
->c_signo
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_signo
);
383 intcore
->c_tsize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_tsize
);
384 intcore
->c_dsize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_dsize
);
385 intcore
->c_ssize
= bfd_h_get_32 (abfd
, (unsigned char *)&extcore
->c_ssize
);
386 bcopy (extcore
->c_cmdname
, intcore
->c_cmdname
, sizeof (intcore
->c_cmdname
));
387 intcore
->fp_stuff_pos
= (long) (((struct external_sparc_core
*)0)->fp_stuff
);
388 /* FP stuff takes up whole rest of struct, except c_ucode. */
389 intcore
->fp_stuff_size
= intcore
->c_len
- (sizeof extcore
->c_ucode
) -
390 (file_ptr
)(((struct external_sparc_core
*)0)->fp_stuff
);
391 /* Ucode is the last thing in the struct -- just before the end */
394 intcore
->c_len
- sizeof (extcore
->c_ucode
) + (unsigned char *)extcore
);
395 /* Supposedly the user stack grows downward from the bottom of kernel memory.
396 Presuming that this remains true, this definition will work. */
397 #define SPARC_USRSTACK (-(128*1024*1024))
398 intcore
->c_stacktop
= SPARC_USRSTACK
; /* By experimentation */
401 /* need this cast because ptr is really void * */
402 #define core_hdr(bfd) (((struct suncoredata *) (bfd->tdata))->hdr)
403 #define core_datasec(bfd) (((struct suncoredata *) ((bfd)->tdata))->data_section)
404 #define core_stacksec(bfd) (((struct suncoredata*)((bfd)->tdata))->stack_section)
405 #define core_regsec(bfd) (((struct suncoredata *) ((bfd)->tdata))->reg_section)
406 #define core_reg2sec(bfd) (((struct suncoredata *) ((bfd)->tdata))->reg2_section)
408 /* These are stored in the bfd's tdata */
410 struct internal_sunos_core
*hdr
; /* core file header */
411 asection
*data_section
;
412 asection
*stack_section
;
413 asection
*reg_section
;
414 asection
*reg2_section
;
418 DEFUN(sunos4_core_file_p
,(abfd
),
421 unsigned char longbuf
[4]; /* Raw bytes of various header fields */
424 struct internal_sunos_core
*core
;
427 struct suncoredata suncoredata
;
428 struct internal_sunos_core internal_sunos_core
;
429 char external_core
[1];
432 bfd_error
= system_call_error
;
434 if (bfd_read ((PTR
)longbuf
, 1, sizeof (longbuf
), abfd
) !=
437 core_mag
= bfd_h_get_32 (abfd
, longbuf
);
439 if (core_mag
!= CORE_MAGIC
) return 0;
441 /* SunOS core headers can vary in length; second word is size; */
442 if (bfd_read ((PTR
)longbuf
, 1, sizeof (longbuf
), abfd
) !=
445 core_size
= bfd_h_get_32 (abfd
, longbuf
);
447 if (core_size
> 20000)
450 if (bfd_seek (abfd
, 0L, false) < 0) return 0;
452 mergem
= (struct mergem
*)bfd_zalloc (abfd
, core_size
+ sizeof (struct mergem
));
453 if (mergem
== NULL
) {
454 bfd_error
= no_memory
;
458 extcore
= mergem
->external_core
;
460 if ((bfd_read ((PTR
) extcore
, 1, core_size
, abfd
)) != core_size
) {
461 bfd_error
= system_call_error
;
462 bfd_release (abfd
, (char *)mergem
);
466 /* Validate that it's a core file we know how to handle, due to sun
467 botching the positioning of registers and other fields in a machine
469 core
= &mergem
->internal_sunos_core
;
472 swapcore_sparc (abfd
, extcore
, core
);
475 swapcore_sun3 (abfd
, extcore
, core
);
478 bfd_error
= system_call_error
; /* FIXME */
479 bfd_release (abfd
, (char *)mergem
);
483 set_tdata (abfd
, &mergem
->suncoredata
);
484 core_hdr (abfd
) = core
;
486 /* create the sections. This is raunchy, but bfd_close wants to reclaim
488 core_stacksec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
489 if (core_stacksec (abfd
) == NULL
) {
491 bfd_error
= no_memory
;
492 bfd_release (abfd
, (char *)mergem
);
495 core_datasec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
496 if (core_datasec (abfd
) == NULL
) {
498 bfd_release (abfd
, core_stacksec (abfd
));
501 core_regsec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
502 if (core_regsec (abfd
) == NULL
) {
504 bfd_release (abfd
, core_datasec (abfd
));
507 core_reg2sec (abfd
) = (asection
*) bfd_zalloc (abfd
, sizeof (asection
));
508 if (core_reg2sec (abfd
) == NULL
) {
509 bfd_release (abfd
, core_regsec (abfd
));
513 core_stacksec (abfd
)->name
= ".stack";
514 core_datasec (abfd
)->name
= ".data";
515 core_regsec (abfd
)->name
= ".reg";
516 core_reg2sec (abfd
)->name
= ".reg2";
518 core_stacksec (abfd
)->flags
= SEC_ALLOC
+ SEC_LOAD
+ SEC_HAS_CONTENTS
;
519 core_datasec (abfd
)->flags
= SEC_ALLOC
+ SEC_LOAD
+ SEC_HAS_CONTENTS
;
520 core_regsec (abfd
)->flags
= SEC_ALLOC
+ SEC_HAS_CONTENTS
;
521 core_reg2sec (abfd
)->flags
= SEC_ALLOC
+ SEC_HAS_CONTENTS
;
523 core_stacksec (abfd
)->size
= core
->c_ssize
;
524 core_datasec (abfd
)->size
= core
->c_dsize
;
525 core_regsec (abfd
)->size
= core
->c_regs_size
;
526 core_reg2sec (abfd
)->size
= core
->fp_stuff_size
;
528 core_stacksec (abfd
)->vma
= (core
->c_stacktop
- core
->c_ssize
);
529 core_datasec (abfd
)->vma
= N_DATADDR(core
->c_aouthdr
);
530 core_regsec (abfd
)->vma
= 0;
531 core_reg2sec (abfd
)->vma
= 0;
533 core_stacksec (abfd
)->filepos
= core
->c_len
+ core
->c_dsize
;
534 core_datasec (abfd
)->filepos
= core
->c_len
;
535 /* We'll access the regs afresh in the core file, like any section: */
536 core_regsec (abfd
)->filepos
= (file_ptr
)core
->c_regs_pos
;
537 core_reg2sec (abfd
)->filepos
= (file_ptr
)core
->fp_stuff_pos
;
539 /* Align to word at least */
540 core_stacksec (abfd
)->alignment_power
= 2;
541 core_datasec (abfd
)->alignment_power
= 2;
542 core_regsec (abfd
)->alignment_power
= 2;
543 core_reg2sec (abfd
)->alignment_power
= 2;
545 abfd
->sections
= core_stacksec (abfd
);
546 core_stacksec (abfd
)->next
= core_datasec (abfd
);
547 core_datasec (abfd
)->next
= core_regsec (abfd
);
548 core_regsec (abfd
)->next
= core_reg2sec (abfd
);
550 abfd
->section_count
= 4;
555 static char *sunos4_core_file_failing_command (abfd
)
558 return core_hdr (abfd
)->c_cmdname
;
562 DEFUN(sunos4_core_file_failing_signal
,(abfd
),
565 return core_hdr (abfd
)->c_signo
;
569 DEFUN(sunos4_core_file_matches_executable_p
, (core_bfd
, exec_bfd
),
573 if (core_bfd
->xvec
!= exec_bfd
->xvec
) {
574 bfd_error
= system_call_error
;
578 return (bcmp ((char *)&core_hdr (core_bfd
)->c_aouthdr
,
579 (char *) exec_hdr (exec_bfd
),
580 sizeof (struct internal_exec
)) == 0) ? true : false;
583 /* We use BFD generic archive files. */
584 #define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
585 #define aout_32_generic_stat_arch_elt bfd_generic_stat_arch_elt
586 #define aout_32_slurp_armap bfd_slurp_bsd_armap
587 #define aout_32_slurp_extended_name_table bfd_true
588 #define aout_32_write_armap bsd_write_armap
589 #define aout_32_truncate_arname bfd_bsd_truncate_arname
590 #define aout_32_machine_type sunos_machine_type
592 #define aout_32_core_file_failing_command sunos4_core_file_failing_command
593 #define aout_32_core_file_failing_signal sunos4_core_file_failing_signal
594 #define aout_32_core_file_matches_executable_p sunos4_core_file_matches_executable_p
597 #define aout_64_openr_next_archived_file bfd_generic_openr_next_archived_file
598 #define aout_64_generic_stat_arch_elt bfd_generic_stat_arch_elt
599 #define aout_64_slurp_armap bfd_slurp_bsd_armap
600 #define aout_64_slurp_extended_name_table bfd_true
601 #define aout_64_write_armap bsd_write_armap
602 #define aout_64_truncate_arname bfd_bsd_truncate_arname
603 #define aout_64_machine_type sunos_machine_type
605 #define aout_64_core_file_failing_command sunos4_core_file_failing_command
606 #define aout_64_core_file_failing_signal sunos4_core_file_failing_signal
607 #define aout_64_core_file_matches_executable_p sunos4_core_file_matches_executable_p
609 #define aout_64_bfd_debug_info_start bfd_void
610 #define aout_64_bfd_debug_info_end bfd_void
611 #define aout_64_bfd_debug_info_accumulate bfd_void
613 #define aout_32_bfd_debug_info_start bfd_void
614 #define aout_32_bfd_debug_info_end bfd_void
615 #define aout_32_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
619 /* We implement these routines ourselves, rather than using the generic
621 #define aout_write_object_contents sunos4_write_object_contents
626 bfd_target_aout_flavour
,
627 true, /* target byte order */
628 true, /* target headers byte order */
629 (HAS_RELOC
| EXEC_P
| /* object flags */
630 HAS_LINENO
| HAS_DEBUG
|
631 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
632 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
633 ' ', /* ar_pad_char */
634 16, /* ar_max_namelen */
635 3, /* minimum alignment power */
636 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* data */
637 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* hdrs */
639 {_bfd_dummy_target
, NAME(sunos
,object_p
),
640 bfd_generic_archive_p
, sunos4_core_file_p
},
641 {bfd_false
, sunos_mkobject
,
642 _bfd_generic_mkarchive
, bfd_false
},
643 {bfd_false
, NAME(aout
,sunos4_write_object_contents
), /* bfd_write_contents */
644 _bfd_write_archive_contents
, bfd_false
},
646 JUMP_TABLE(JNAME(aout
))