diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-01-21 06:29:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-01-21 06:29:21 +0000 |
commit | 0ee75d02e516e8ee40f45733855771936ed30490 (patch) | |
tree | ba4c096f9693c37e70dd9de71f69222a16c09ce9 /bfd/sunos.c | |
parent | 5e6cd559cfa7fd45d9f128903d1f42344bcfd03d (diff) | |
download | gdb-0ee75d02e516e8ee40f45733855771936ed30490.zip gdb-0ee75d02e516e8ee40f45733855771936ed30490.tar.gz gdb-0ee75d02e516e8ee40f45733855771936ed30490.tar.bz2 |
* syms.c (BSF_DYNAMIC): New symbol flag.
(bfd_print_symbol_vandf): Print it.
* bfd-in2.h: Rebuilt.
* libaout.h (struct aout_backend_data): New read_dynamic_symbols
and read_dynamic_relocs fields.
(struct aoutdata): New dynamic_info field.
(obj_aout_dynamic_info): New accessor macro.
* sunos.c (struct sunos_dynamic_info): New structure.
(sunos_read_dynamic_info, MY(read_dynamic_symbols),
MY(read_dynamic_relocs)): New functions to read dynamic symbols
and relocs.
* aoutx.h (NAME(aout,some_aout_object_p)): If the object is
dynamically linked, set SEC_RELOC for both the .text and .data
sections.
(translate_from_native_sym_flags): Don't set BSF_LOCAL for an
undefined symbol.
(translate_symbol_table): New function, split out of
slurp_symbol_table; set the BSF_DYNAMIC flag appropriately.
(NAME(aout,slurp_symbol_table)): Read dynamic symbols, if any.
(NAME(aout,slurp_reloc_table)): Read dynamic relocs, if any.
(NAME(aout,get_reloc_upper_bound)): Include dynamic reloc count in
return value.
* aoutf1.h (NAME(aout,sunos4_write_object_contents)): Don't write
out dynamic symbols or relocs against reloc symbols, since they
are already in the .text section and we wouldn't know where to
write them anyhow.
(sunos4_aout_backend): Initialize read_dynamic_symbols and
read_dynamic_relocs fields.
* aout-target.h (MY(backend_data)): Initialize
read_dynamic_symbols and read_dynamic_relocs fields.
Diffstat (limited to 'bfd/sunos.c')
-rw-r--r-- | bfd/sunos.c | 816 |
1 files changed, 242 insertions, 574 deletions
diff --git a/bfd/sunos.c b/bfd/sunos.c index a451a48..7f62a33 100644 --- a/bfd/sunos.c +++ b/bfd/sunos.c @@ -1,627 +1,295 @@ -/* BFD backend for sunos binaries */ +/* BFD backend for SunOS binaries. + Copyright (C) 1990-1991 Free Software Foundation, Inc. + Written by Cygnus Support. -/* Copyright (C) 1990, 1991 Free Software Foundation, Inc. +This file is part of BFD, the Binary File Descriptor library. -This file is part of BFD, the Binary File Diddler. - -BFD is free software; you can redistribute it and/or modify +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. -BFD is distributed in the hope that it will be useful, +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with BFD; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ */ +#define ARCH 32 +#define TARGETNAME "a.out-sunos-big" +#define MY(OP) CAT(sunos_big_,OP) -#include <ansidecl.h> -#include "sysdep.h" #include "bfd.h" -#include "libbfd.h" - -#include "a.out.sun4.h" -#include "a.out.gnu.h" -#include "stab.gnu.h" -#include "ar.h" -#include "liba.out.h" /* BFD a.out internal data structures */ - -void (*bfd_error_trap)(); - -static bfd_target *sunos4_callback (); -/*SUPPRESS558*/ -/*SUPPRESS529*/ +/* Static routines defined in this file. */ -bfd_target * -sunos4_object_p (abfd) - bfd *abfd; -{ - unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ - unsigned long magic; /* Swapped magic number */ +struct external_nlist; - bfd_error = system_call_error; +static boolean sunos_read_dynamic_info PARAMS ((bfd *)); +static bfd_size_type MY(read_dynamic_symbols) + PARAMS ((bfd *, struct external_nlist **, char **, bfd_size_type *)); +static bfd_size_type MY(read_dynamic_relocs) PARAMS ((bfd *, PTR *)); - if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) != - sizeof (magicbuf)) - return 0; - magic = bfd_h_getlong (abfd, magicbuf); +#define MY_read_dynamic_symbols MY(read_dynamic_symbols) +#define MY_read_dynamic_relocs MY(read_dynamic_relocs) - if (N_BADMAG (*((struct exec *) &magic))) return 0; +/* Include the usual a.out support. */ +#include "aoutf1.h" - return some_aout_object_p (abfd, sunos4_callback); -} +/* SunOS shared library support. We store a pointer to this structure + in obj_aout_dynamic_info (abfd). */ - /* Determine the size of a relocation entry, based on the architecture */ -static void -DEFUN(choose_reloc_size,(abfd), -bfd *abfd) - { - switch (abfd->obj_arch) { - case bfd_arch_sparc: - case bfd_arch_a29k: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } - } - -/* Set parameters about this a.out file that are machine-dependent. - This routine is called from some_aout_object_p just before it returns. */ - -static bfd_target * -sunos4_callback (abfd) - bfd *abfd; +struct sunos_dynamic_info { - struct exec *execp = exec_hdr (abfd); - - /* The virtual memory addresses of the sections */ - obj_datasec (abfd)->vma = N_DATADDR(*execp); - obj_bsssec (abfd)->vma = N_BSSADDR(*execp); - obj_textsec (abfd)->vma = N_TXTADDR(*execp); - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = EXEC_BYTES_SIZE; /*N_TXTOFF(*execp);*/ - obj_datasec (abfd)->filepos = N_DATOFF(*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); - - /* The file offsets of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - - - /* Determine the architecture and machine type of the object file. */ - switch (N_MACHTYPE (*exec_hdr (abfd))) { - - case M_UNKNOWN: - abfd->obj_arch = bfd_arch_unknown; - abfd->obj_machine = 0; - break; - - case M_68010: - abfd->obj_arch = bfd_arch_m68k; - abfd->obj_machine = 68010; - break; - - case M_68020: - abfd->obj_arch = bfd_arch_m68k; - abfd->obj_machine = 68020; - break; - - case M_SPARC: - abfd->obj_arch = bfd_arch_sparc; - abfd->obj_machine = 0; - break; - - case M_386: - abfd->obj_arch = bfd_arch_i386; - abfd->obj_machine = 0; - break; - - case M_29K: - abfd->obj_arch = bfd_arch_a29k; - abfd->obj_machine = 0; - break; - - default: - abfd->obj_arch = bfd_arch_obscure; - abfd->obj_machine = 0; - break; - } - - choose_reloc_size(abfd); - return abfd->xvec; -} + /* Whether we found any dynamic information. */ + boolean valid; + /* Dynamic information. */ + struct internal_sun4_dynamic_link dyninfo; + /* Number of dynamic symbols. */ + bfd_size_type dynsym_count; + /* Read in nlists for dynamic symbols. */ + struct external_nlist *dynsym; + /* Read in dynamic string table. */ + char *dynstr; + /* Number of dynamic relocs. */ + bfd_size_type dynrel_count; + /* Read in dynamic relocs. This may be reloc_std_external or + reloc_ext_external. */ + PTR dynrel; +}; +/* Read in the basic dynamic information. This locates the __DYNAMIC + structure and uses it to find the dynamic_link structure. It + creates and saves a sunos_dynamic_info structure. If it can't find + __DYNAMIC, it sets the valid field of the sunos_dynamic_info + structure to false to avoid doing this work again. */ -boolean -sunos4_mkobject (abfd) +static boolean +sunos_read_dynamic_info (abfd) bfd *abfd; { - char *rawptr; - - bfd_error = system_call_error; - - /* Use an intermediate variable for clarity */ - rawptr = bfd_zalloc (abfd, sizeof (struct aoutdata) + sizeof (struct exec)); - - if (rawptr == NULL) { - bfd_error = no_memory; - return false; - } - - set_tdata (abfd, (struct aoutdata *) rawptr); - exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct aoutdata)); - - /* For simplicity's sake we just make all the sections right here. */ - - obj_textsec (abfd) = (asection *)NULL; - obj_datasec (abfd) = (asection *)NULL; - obj_bsssec (abfd) = (asection *)NULL; - bfd_make_section (abfd, ".text"); - bfd_make_section (abfd, ".data"); - bfd_make_section (abfd, ".bss"); + struct sunos_dynamic_info *info; + struct external_nlist dynsym; + char buf[sizeof "__DYNAMIC"]; + asection *dynsec; + file_ptr dynoff; + struct external_sun4_dynamic dyninfo; + unsigned long dynver; + struct external_sun4_dynamic_link linkinfo; + + if (obj_aout_dynamic_info (abfd) != (PTR) NULL) + return true; + + info = ((struct sunos_dynamic_info *) + bfd_zalloc (abfd, sizeof (struct sunos_dynamic_info))); + info->valid = false; + info->dynsym = NULL; + info->dynstr = NULL; + info->dynrel = NULL; + obj_aout_dynamic_info (abfd) = (PTR) info; + + /* We look for the __DYNAMIC symbol to locate the dynamic linking + information. It should be the first symbol if it is defined. If + we can't find it, don't sweat it. */ + if ((abfd->flags & DYNAMIC) == 0 + || bfd_get_symcount (abfd) <= 0 + || bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 + || (bfd_read ((PTR) &dynsym, 1, EXTERNAL_NLIST_SIZE, abfd) + != EXTERNAL_NLIST_SIZE) + || ((dynsym.e_type[0] & N_TYPE) != N_DATA + && (dynsym.e_type[0] & N_TYPE) != N_TEXT) + || bfd_seek (abfd, + obj_str_filepos (abfd) + GET_WORD (abfd, dynsym.e_strx), + SEEK_SET) != 0 + || bfd_read ((PTR) buf, 1, sizeof buf, abfd) != sizeof buf + || buf[sizeof buf - 1] != '\0' + || strcmp (buf, "__DYNAMIC") != 0) + return true; + + if ((dynsym.e_type[0] & N_TYPE) == N_DATA) + dynsec = obj_datasec (abfd); + else + dynsec = obj_textsec (abfd); + if (! bfd_get_section_contents (abfd, dynsec, (PTR) &dyninfo, + (GET_WORD (abfd, dynsym.e_value) + - bfd_get_section_vma (abfd, dynsec)), + sizeof dyninfo)) + return true; + + dynver = GET_WORD (abfd, dyninfo.ld_version); + if (dynver != 2 && dynver != 3) + return true; + + dynoff = GET_WORD (abfd, dyninfo.ld); + + /* dynoff is a virtual address. It is probably always in the .data + section, but this code should work even if it moves. */ + if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd))) + dynsec = obj_textsec (abfd); + else + dynsec = obj_datasec (abfd); + dynoff -= bfd_get_section_vma (abfd, dynsec); + if (dynoff < 0 || dynoff > bfd_section_size (abfd, dynsec)) + return true; + + /* This executable appears to be dynamically linked in a way that we + can understand. */ + if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, dynoff, + (bfd_size_type) sizeof linkinfo)) + return true; + + /* Swap in the dynamic link information. */ + info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded); + info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need); + info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules); + info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got); + info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt); + info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel); + info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash); + info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab); + info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash); + info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets); + info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols); + info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size); + info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text); + info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz); + + /* The only way to get the size of the symbol information appears to + be to determine the distance between it and the string table. */ + info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab) + / EXTERNAL_NLIST_SIZE); + BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE + == info->dyninfo.ld_symbols - info->dyninfo.ld_stab); + + /* Similarly, the relocs end at the hash table. */ + info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel) + / obj_reloc_entry_size (abfd)); + BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd) + == info->dyninfo.ld_hash - info->dyninfo.ld_rel); + + info->valid = true; return true; } -/* Keep track of machine architecture and machine type for a.out's. - Return the machine_type for a particular arch&machine, or M_UNKNOWN - if that exact arch&machine can't be represented in a.out format. - - If the architecture is understood, machine type 0 (default) should - always be understood. */ - -static enum machine_type -aout_machine_type (arch, machine) - enum bfd_architecture arch; - unsigned long machine; -{ - enum machine_type arch_flags; - - arch_flags = M_UNKNOWN; - - switch (arch) { - case bfd_arch_sparc: - if (machine == 0) arch_flags = M_SPARC; - break; - - case bfd_arch_m68k: - switch (machine) { - case 0: arch_flags = M_68010; break; - case 68000: arch_flags = M_UNKNOWN; break; - case 68010: arch_flags = M_68010; break; - case 68020: arch_flags = M_68020; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_i386: - if (machine == 0) arch_flags = M_386; - break; - - case bfd_arch_a29k: - if (machine == 0) arch_flags = M_29K; - break; - - default: - arch_flags = M_UNKNOWN; - break; - } - return arch_flags; -} - -/* Write an object file in SunOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ +/* Read in the dynamic symbols. */ -boolean -sunos4_write_object_contents (abfd) +static bfd_size_type +MY(read_dynamic_symbols) (abfd, syms, strs, strsize) bfd *abfd; + struct external_nlist **syms; + char **strs; + bfd_size_type *strsize; { - size_t data_pad = 0; - unsigned char exec_bytes[EXEC_BYTES_SIZE]; - struct exec *execp = exec_hdr (abfd); + struct sunos_dynamic_info *info; - - - execp->a_text = obj_textsec (abfd)->size; - - /* Magic number, maestro, please! */ - switch (bfd_get_architecture(abfd)) { - case bfd_arch_m68k: - switch (bfd_get_machine(abfd)) { - case 68010: - N_SET_MACHTYPE(*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE(*execp, M_68020); - break; + if (obj_aout_dynamic_info (abfd) == (PTR) NULL) + { + if (! sunos_read_dynamic_info (abfd)) + return (bfd_size_type) -1; } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE(*execp, M_29K); - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - } - choose_reloc_size(abfd); + info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); + if (! info->valid || info->dynsym_count == 0) + return 0; - N_SET_MAGIC (*execp, OMAGIC); - if (abfd->flags & D_PAGED) { - /* This is not strictly true, but will probably do for the default - case. FIXME. - */ + if (info->dynsym == (struct external_nlist *) NULL) + { + info->dynsym = ((struct external_nlist *) + bfd_alloc (abfd, + (info->dynsym_count + * EXTERNAL_NLIST_SIZE))); + info->dynstr = (char *) bfd_alloc (abfd, info->dyninfo.ld_symb_size); + if (bfd_seek (abfd, info->dyninfo.ld_stab, SEEK_SET) != 0 + || (bfd_read ((PTR) info->dynsym, info->dynsym_count, + EXTERNAL_NLIST_SIZE, abfd) + != info->dynsym_count * EXTERNAL_NLIST_SIZE) + || bfd_seek (abfd, info->dyninfo.ld_symbols, SEEK_SET) != 0 + || (bfd_read ((PTR) info->dynstr, 1, info->dyninfo.ld_symb_size, + abfd) + != info->dyninfo.ld_symb_size)) + return (bfd_size_type) -1; + } - execp->a_text = obj_textsec (abfd)->size + EXEC_BYTES_SIZE; - N_SET_MAGIC (*execp, ZMAGIC); - } else if (abfd->flags & WP_TEXT) { - N_SET_MAGIC (*execp, NMAGIC); - } - N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */ + *syms = info->dynsym; + *strs = info->dynstr; + *strsize = info->dyninfo.ld_symb_size; - if (abfd->flags & D_PAGED) +#ifdef CHECK_DYNAMIC_HASH + /* Check my understanding of the dynamic hash table by making sure + that each symbol can be located in the hash table. */ + { + bfd_size_type table_size; + bfd_byte *table; + bfd_size_type i; + + if (info->dyninfo.ld_buckets > info->dynsym_count) + abort (); + table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash; + table = (bfd_byte *) alloca (table_size); + if (bfd_seek (abfd, info->dyninfo.ld_hash, SEEK_SET) != 0 + || bfd_read ((PTR) table, 1, table_size, abfd) != table_size) + abort (); + for (i = 0; i < info->dynsym_count; i++) { - data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1) - & (- PAGE_SIZE)) - obj_datasec(abfd)->size; - - if (data_pad > obj_bsssec(abfd)->size) - execp->a_bss = 0; - else - execp->a_bss = obj_bsssec(abfd)->size - data_pad; - execp->a_data = obj_datasec(abfd)->size + data_pad; - + unsigned char *name; + unsigned long hash; + + name = ((unsigned char *) info->dynstr + + GET_WORD (abfd, info->dynsym[i].e_strx)); + hash = 0; + while (*name != '\0') + hash = (hash << 1) + *name++; + hash &= 0x7fffffff; + hash %= info->dyninfo.ld_buckets; + while (GET_WORD (abfd, table + 8 * hash) != i) + { + hash = GET_WORD (abfd, table + 8 * hash + 4); + if (hash == 0 || hash >= table_size / 8) + abort (); + } } - else { - execp->a_data = obj_datasec (abfd)->size; - execp->a_bss = obj_bsssec (abfd)->size; } +#endif /* CHECK_DYNAMIC_HASH */ - execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); - execp->a_entry = bfd_get_start_address (abfd); - - - - - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - - bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes); - - bfd_seek (abfd, 0L, false); - bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd); - - /* Now write out reloc info, followed by syms and strings */ - - if (bfd_get_symcount (abfd) != 0) - { - bfd_seek (abfd, - (long)(N_SYMOFF(*execp)), false); - - aout_write_syms (abfd); - - bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false); - - if (!aout_squirt_out_relocs (abfd, obj_textsec (abfd))) return false; - bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false); - - if (!aout_squirt_out_relocs (abfd, obj_datasec (abfd))) return false; - } - return true; + return info->dynsym_count; } - -/* core files */ - -#define CORE_MAGIC 0x080456 -#define CORE_NAMELEN 16 - -/* The core structure is taken from the Sun documentation. - Unfortunately, they don't document the FPA structure, or at least I - can't find it easily. Fortunately the core header contains its own - length. So this shouldn't cause problems, except for c_ucode, which - so far we don't use but is easy to find with a little arithmetic. */ - -/* But the reg structure can be gotten from the SPARC processor handbook. - This really should be in a GNU include file though so that gdb can use - the same info. */ -struct regs { - int r_psr; - int r_pc; - int r_npc; - int r_y; - int r_g1; - int r_g2; - int r_g3; - int r_g4; - int r_g5; - int r_g6; - int r_g7; - int r_o0; - int r_o1; - int r_o2; - int r_o3; - int r_o4; - int r_o5; - int r_o6; - int r_o7; -}; - -/* Taken from Sun documentation: */ - -/* FIXME: It's worse than we expect. This struct contains TWO substructs - neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't - even portably access the stuff in between! */ - -struct core { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ - struct regs c_regs; /* General purpose registers -- MACHDEP SIZE */ - struct exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ -}; -/* Supposedly the user stack grows downward from the bottom of kernel memory. - Presuming that this remains true, this definition will work. */ -#define USRSTACK (-(128*1024*1024)) - -PROTO (static void, swapcore, (bfd *abfd, struct core *core)); - -/* need this cast b/c ptr is really void * */ -#define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr) -#define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section) -#define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section) -#define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section) -#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section) - -/* These are stored in the bfd's tdata */ -struct suncordata { - struct core *hdr; /* core file header */ - asection *data_section; - asection *stack_section; - asection *reg_section; - asection *reg2_section; -}; +/* Read in the dynamic relocs for a section. */ -bfd_target * -sunos4_core_file_p (abfd) +static bfd_size_type +MY(read_dynamic_relocs) (abfd, relocs) bfd *abfd; + PTR *relocs; { - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - int core_size; - int core_mag; - struct core *core; - char *rawptr; - - bfd_error = system_call_error; - - if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_mag = bfd_h_getlong (abfd, longbuf); + struct sunos_dynamic_info *info; - if (core_mag != CORE_MAGIC) return 0; - - /* SunOS core headers can vary in length; second word is size; */ - if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_size = bfd_h_getlong (abfd, longbuf); - /* Sanity check */ - if (core_size > 20000) - return 0; - - if (bfd_seek (abfd, 0L, false) < 0) return 0; - - rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata)); - if (rawptr == NULL) { - bfd_error = no_memory; - return 0; - } - - core = (struct core *) (rawptr + sizeof (struct suncordata)); + if (obj_aout_dynamic_info (abfd) == (PTR) NULL) + { + if (! sunos_read_dynamic_info (abfd)) + return (bfd_size_type) -1; + } - if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) { - bfd_error = system_call_error; - bfd_release (abfd, rawptr); + info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); + if (! info->valid || info->dynrel_count == 0) return 0; - } - swapcore (abfd, core); - set_tdata (abfd, ((struct suncordata *) rawptr)); - core_hdr (abfd) = core; - - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) { -loser: - bfd_error = no_memory; - bfd_release (abfd, rawptr); - return 0; - } - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) { -loser1: - bfd_release (abfd, core_stacksec (abfd)); - goto loser; - } - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) { -loser2: - bfd_release (abfd, core_datasec (abfd)); - goto loser1; - } - core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_reg2sec (abfd) == NULL) { - bfd_release (abfd, core_regsec (abfd)); - goto loser2; - } - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD; - core_regsec (abfd)->flags = SEC_ALLOC; - core_reg2sec (abfd)->flags = SEC_ALLOC; - - core_stacksec (abfd)->size = core->c_ssize; - core_datasec (abfd)->size = core->c_dsize; - core_regsec (abfd)->size = (sizeof core->c_regs); - /* Float regs take up end of struct, except c_ucode. */ - core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) - - (file_ptr)(((struct core *)0)->fp_stuff); - - core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize); - core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr); - core_regsec (abfd)->vma = -1; - core_reg2sec (abfd)->vma = -1; - - core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; - core_datasec (abfd)->filepos = core->c_len; - /* In file header: */ - core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs); - core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff); - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - core_reg2sec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - - abfd->section_count = 4; - - return abfd->xvec; -} - -char * -sunos4_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->c_cmdname; -} - -int -sunos4_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->c_signo; -} - -boolean -sunos4_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - if (core_bfd->xvec != exec_bfd->xvec) { - bfd_error = system_call_error; - return false; - } + if (info->dynrel == (struct external_nlist *) NULL) + { + info->dynrel = (PTR) bfd_alloc (abfd, + (info->dynrel_count + * obj_reloc_entry_size (abfd))); + if (bfd_seek (abfd, info->dyninfo.ld_rel, SEEK_SET) != 0 + || (bfd_read ((PTR) info->dynrel, info->dynrel_count, + obj_reloc_entry_size (abfd), abfd) + != info->dynrel_count * obj_reloc_entry_size (abfd))) + return (bfd_size_type) -1; + } - return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd), - sizeof (struct exec)) == 0) ? true : false; -} + *relocs = info->dynrel; -/* byte-swap core structure */ -/* FIXME, this needs more work to swap IN a core struct from raw bytes */ -static void -swapcore (abfd, core) - bfd *abfd; - struct core *core; -{ - unsigned char exec_bytes[EXEC_BYTES_SIZE]; - - core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic); - core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len ); - /* Leave integer registers in target byte order. */ - bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE); - bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr); - core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo); - core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize); - core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize); - core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize); - /* Leave FP registers in target byte order. */ - /* Leave "c_ucode" unswapped for now, since we can't find it easily. */ + return info->dynrel_count; } - -/* We use BFD generic archive files. */ -#define aout_openr_next_archived_file bfd_generic_openr_next_archived_file -#define aout_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define aout_slurp_armap bfd_slurp_bsd_armap -#define aout_slurp_extended_name_table bfd_true -#define aout_write_armap bsd_write_armap -#define aout_truncate_arname bfd_bsd_truncate_arname - -/* We use our own core file format. */ -#define aout_core_file_failing_command sunos4_core_file_failing_command -#define aout_core_file_failing_signal sunos4_core_file_failing_signal -#define aout_core_file_matches_executable_p \ - sunos4_core_file_matches_executable_p - -/* We implement these routines ourselves, rather than using the generic - a.out versions. */ -#define aout_write_object_contents sunos4_write_object_contents - -bfd_target sunos_big_vec = -{ - "a.out-sunos-big", /* name */ - bfd_target_aout_flavour_enum, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */ - _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */ - - {_bfd_dummy_target, sunos4_object_p, - bfd_generic_archive_p, sunos4_core_file_p}, - {bfd_false, sunos4_mkobject, - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, sunos4_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - JUMP_TABLE(aout) -}; |