From 0ee75d02e516e8ee40f45733855771936ed30490 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 21 Jan 1994 06:29:21 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 33 ++ bfd/aoutf1.h | 80 ++++- bfd/aoutx.h | 289 +++++++++++++----- bfd/bfd-in2.h | 3 + bfd/sunos.c | 816 +++++++++++++++----------------------------------- bfd/syms.c | 15 +- 6 files changed, 574 insertions(+), 662 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5b47c973703..f7eb6671ffa 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,36 @@ +Fri Jan 21 01:11:55 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) + + * 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. + Thu Jan 20 20:57:27 1994 Ken Raeburn (raeburn@cujo.cygnus.com) * hosts/alphaosf.h (uint64e_type, uint64_type, int64_type): Delete diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h index 2f4b7286ddb..b5dcecfddaf 100644 --- a/bfd/aoutf1.h +++ b/bfd/aoutf1.h @@ -195,7 +195,70 @@ DEFUN(NAME(aout,sunos4_write_object_contents), */ N_SET_FLAGS (*execp, 1); #endif - + + N_SET_DYNAMIC(*execp, bfd_get_file_flags(abfd) & DYNAMIC); + + /* At least for SunOS, the dynamic symbols and relocs are embedded + in the .text section, and we do not want to write them out with + the symbol table. FIXME: This may be right if there is any other + form of a.out shared libraries. */ + if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0 + && bfd_get_outsymbols (abfd) != (asymbol **) NULL) + { + bfd_size_type i; + asymbol **sym_ptr_ptr; + bfd_size_type count; + arelent **rel_ptr_ptr; + + sym_ptr_ptr = bfd_get_outsymbols (abfd); + count = bfd_get_symcount (abfd); + for (i = 0; i < count; i++, sym_ptr_ptr++) + { + if (((*sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0) + { + /* This assumes that all dynamic symbols follow all + non-dynamic symbols, which is what slurp_symbol_table + does. */ + *sym_ptr_ptr = NULL; + bfd_get_symcount (abfd) = i; + break; + } + } + + if (obj_textsec (abfd)->reloc_count > 0) + { + rel_ptr_ptr = obj_textsec (abfd)->orelocation; + count = obj_textsec (abfd)->reloc_count; + for (i = 0; i < count; i++, rel_ptr_ptr++) + { + if (((*(*rel_ptr_ptr)->sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0) + { + /* This assumes that all relocs against dynamic + symbols follow all relocs against other symbols, + which is what slurp_reloc_table does. */ + *rel_ptr_ptr = NULL; + obj_textsec (abfd)->reloc_count = i; + break; + } + } + } + + if (obj_datasec (abfd)->reloc_count > 0) + { + rel_ptr_ptr = obj_datasec (abfd)->orelocation; + count = obj_datasec (abfd)->reloc_count; + for (i = 0; i < count; i++, rel_ptr_ptr++) + { + if (((*(*rel_ptr_ptr)->sym_ptr_ptr)->flags & BSF_DYNAMIC) != 0) + { + *rel_ptr_ptr = NULL; + obj_datasec (abfd)->reloc_count = i; + break; + } + } + } + } + WRITE_HEADERS(abfd, execp); return true; @@ -586,8 +649,21 @@ DEFUN (sunos4_set_sizes, (abfd), } } +#ifndef MY_read_dynamic_symbols +#define MY_read_dynamic_symbols 0 +#endif +#ifndef MY_read_dynamic_relocs +#define MY_read_dynamic_relocs 0 +#endif + static CONST struct aout_backend_data sunos4_aout_backend = { - 0, 1, 0, sunos4_set_sizes, 0, + 0, /* zmagic files are not contiguous */ + 1, /* text includes header */ + 0, /* default text vma */ + sunos4_set_sizes, + 0, /* header is counted in zmagic text */ + MY_read_dynamic_symbols, + MY_read_dynamic_relocs }; #define MY_core_file_failing_command sunos4_core_file_failing_command diff --git a/bfd/aoutx.h b/bfd/aoutx.h index b8040cbc06d..03665907a42 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -134,6 +134,12 @@ DESCRIPTION #include "aout/stab_gnu.h" #include "aout/ar.h" +static boolean translate_symbol_table PARAMS ((bfd *, aout_symbol_type *, + struct external_nlist *, + bfd_size_type, char *, + bfd_size_type, + boolean dynamic)); + /* SUBSECTION Relocations @@ -430,12 +436,17 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p), obj_datasec (abfd)->_raw_size = execp->a_data; obj_bsssec (abfd)->_raw_size = execp->a_bss; - obj_textsec (abfd)->flags = (execp->a_trsize != 0 ? - (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) : - (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); - obj_datasec (abfd)->flags = (execp->a_drsize != 0 ? - (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) : - (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); + /* If this object is dynamically linked, we assume that both + sections have relocs. This does no real harm, even though it may + not be true. */ + obj_textsec (abfd)->flags = + (execp->a_trsize != 0 || (abfd->flags & DYNAMIC) != 0 + ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) + : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); + obj_datasec (abfd)->flags = + (execp->a_drsize != 0 || (abfd->flags & DYNAMIC) != 0 + ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) + : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); obj_bsssec (abfd)->flags = SEC_ALLOC; #ifdef THIS_IS_ONLY_DOCUMENTATION @@ -1273,7 +1284,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd), { cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT; } - else + else if (! sym_is_undefined (cache_ptr)) { cache_ptr->symbol.flags = BSF_LOCAL; } @@ -1366,9 +1377,6 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd), /* Native-level interface to symbols. */ -/* We read the symbols into a buffer, which is discarded when this -function exits. We read the strings into a buffer large enough to -hold them all plus all the cached symbol entries. */ asymbol * DEFUN(NAME(aout,make_empty_symbol),(abfd), @@ -1381,6 +1389,51 @@ DEFUN(NAME(aout,make_empty_symbol),(abfd), return &new->symbol; } +/* Translate a set of internal symbols into external symbols. */ + +static boolean +translate_symbol_table (abfd, in, ext, count, str, strsize, dynamic) + bfd *abfd; + aout_symbol_type *in; + struct external_nlist *ext; + bfd_size_type count; + char *str; + bfd_size_type strsize; + boolean dynamic; +{ + struct external_nlist *ext_end; + + ext_end = ext + count; + for (; ext < ext_end; ext++, in++) + { + bfd_vma x; + + x = GET_WORD (abfd, ext->e_strx); + in->symbol.the_bfd = abfd; + if (x < strsize) + in->symbol.name = str + x; + else + return false; + + in->symbol.value = GET_SWORD (abfd, ext->e_value); + in->desc = bfd_h_get_16 (abfd, ext->e_desc); + in->other = bfd_h_get_8 (abfd, ext->e_other); + in->type = bfd_h_get_8 (abfd, ext->e_type); + in->symbol.udata = 0; + + translate_from_native_sym_flags (ext, in, abfd); + + if (dynamic) + in->symbol.flags |= BSF_DYNAMIC; + } + + return true; +} + +/* We read the symbols into a buffer, which is discarded when this + function exits. We read the strings into a buffer large enough to + hold them all plus all the cached symbol entries. */ + boolean DEFUN(NAME(aout,slurp_symbol_table),(abfd), bfd *abfd) @@ -1391,6 +1444,10 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd), struct external_nlist *syms; char *strings; aout_symbol_type *cached; + bfd_size_type dynsym_count = 0; + struct external_nlist *dynsyms = NULL; + char *dynstrs = NULL; + bfd_size_type dynstr_size; /* If there's no work to be done, don't do any */ if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true; @@ -1406,12 +1463,24 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd), return false; string_size = GET_WORD (abfd, string_chars); - strings =(char *) bfd_alloc(abfd, string_size + 1); - cached = (aout_symbol_type *) - bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type))); + /* If this is a dynamic object, see if we can get the dynamic symbol + table. */ + if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0 + && aout_backend_info (abfd)->read_dynamic_symbols) + { + dynsym_count = ((*aout_backend_info (abfd)->read_dynamic_symbols) + (abfd, &dynsyms, &dynstrs, &dynstr_size)); + if (dynsym_count == (bfd_size_type) -1) + return false; + } - /* malloc this, so we can free it if simply. The symbol caching - might want to allocate onto the bfd's obstack */ + strings = (char *) bfd_alloc (abfd, string_size + 1); + cached = ((aout_symbol_type *) + bfd_zalloc (abfd, + ((bfd_get_symcount (abfd) + dynsym_count) + * sizeof (aout_symbol_type)))); + + /* Don't allocate on the obstack, so we can free it easily. */ syms = (struct external_nlist *) bfd_xmalloc(symbol_size); bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET); if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) @@ -1434,32 +1503,18 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd), strings[string_size] = 0; /* Just in case. */ /* OK, now walk the new symtable, cacheing symbol properties */ - { - register struct external_nlist *sym_pointer; - register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd); - register aout_symbol_type *cache_ptr = cached; + if (! translate_symbol_table (abfd, cached, syms, bfd_get_symcount (abfd), + strings, string_size, false)) + goto bailout; + if (dynsym_count > 0) + { + if (! translate_symbol_table (abfd, cached + bfd_get_symcount (abfd), + dynsyms, dynsym_count, dynstrs, + dynstr_size, true)) + goto bailout; - /* Run through table and copy values */ - for (sym_pointer = syms, cache_ptr = cached; - sym_pointer < sym_end; sym_pointer ++, cache_ptr++) - { - long x = GET_WORD(abfd, sym_pointer->e_strx); - cache_ptr->symbol.the_bfd = abfd; - if (x == 0) - cache_ptr->symbol.name = ""; - else if (x >= 0 && x < string_size) - cache_ptr->symbol.name = x + strings; - else - goto bailout; - - cache_ptr->symbol.value = GET_SWORD(abfd, sym_pointer->e_value); - cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc); - cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other); - cache_ptr->type = bfd_h_get_8(abfd, sym_pointer->e_type); - cache_ptr->symbol.udata = 0; - translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd); - } - } + bfd_get_symcount (abfd) += dynsym_count; + } obj_aout_symbols (abfd) = cached; free((PTR)syms); @@ -2233,71 +2288,129 @@ DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols), unsigned int count; bfd_size_type reloc_size; PTR relocs; + bfd_size_type dynrel_count = 0; + PTR dynrels = NULL; arelent *reloc_cache; size_t each_size; + unsigned int counter = 0; + arelent *cache_ptr; if (asect->relocation) return true; if (asect->flags & SEC_CONSTRUCTOR) return true; - if (asect == obj_datasec (abfd)) { + if (asect == obj_datasec (abfd)) reloc_size = exec_hdr(abfd)->a_drsize; - } else if (asect == obj_textsec (abfd)) { + else if (asect == obj_textsec (abfd)) reloc_size = exec_hdr(abfd)->a_trsize; - } else { - bfd_error = invalid_operation; - return false; - } + else + { + bfd_error = invalid_operation; + return false; + } + + if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0 + && aout_backend_info (abfd)->read_dynamic_relocs) + { + dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs) + (abfd, &dynrels)); + if (dynrel_count == (bfd_size_type) -1) + return false; + } bfd_seek (abfd, asect->rel_filepos, SEEK_SET); each_size = obj_reloc_entry_size (abfd); count = reloc_size / each_size; - - reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof - (arelent))); - if (!reloc_cache) { -nomem: - bfd_error = no_memory; - return false; - } + reloc_cache = ((arelent *) + bfd_zalloc (abfd, + (size_t) ((count + dynrel_count) + * sizeof (arelent)))); + if (!reloc_cache) + { + nomem: + bfd_error = no_memory; + return false; + } relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs) { - bfd_release (abfd, reloc_cache); - goto nomem; - } + if (!relocs) + { + bfd_release (abfd, reloc_cache); + goto nomem; + } - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) { - bfd_release (abfd, relocs); - bfd_release (abfd, reloc_cache); - bfd_error = system_call_error; - return false; - } + if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) + { + bfd_release (abfd, relocs); + bfd_release (abfd, reloc_cache); + bfd_error = system_call_error; + return false; + } - if (each_size == RELOC_EXT_SIZE) { - register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; + cache_ptr = reloc_cache; + if (each_size == RELOC_EXT_SIZE) + { + register struct reloc_ext_external *rptr = + (struct reloc_ext_external *) relocs; - for (; counter < count; counter++, rptr++, cache_ptr++) { - NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols); + for (; counter < count; counter++, rptr++, cache_ptr++) + NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols); } - } else { - register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; + else + { + register struct reloc_std_external *rptr + = (struct reloc_std_external *) relocs; - for (; counter < count; counter++, rptr++, cache_ptr++) { - NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols); + for (; counter < count; counter++, rptr++, cache_ptr++) + NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols); } - } + if (dynrel_count > 0) + { + asymbol **dynsyms; + + /* The dynamic symbols are at the end of the symbol table. */ + for (dynsyms = symbols; + *dynsyms != NULL && ((*dynsyms)->flags & BSF_DYNAMIC) == 0; + ++dynsyms) + ; + + /* Swap in the dynamic relocs. These relocs may be for either + section, so we must discard ones we don't want. */ + counter = 0; + if (each_size == RELOC_EXT_SIZE) + { + register struct reloc_ext_external *rptr + = (struct reloc_ext_external *) dynrels; + + for (; counter < dynrel_count; counter++, rptr++, cache_ptr++) + { + NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, dynsyms); + cache_ptr->address -= bfd_get_section_vma (abfd, asect); + if (cache_ptr->address >= bfd_section_size (abfd, asect)) + --cache_ptr; + } + } + else + { + register struct reloc_std_external *rptr + = (struct reloc_std_external *) dynrels; + + for (; counter < dynrel_count; counter++, rptr++, cache_ptr++) + { + NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, dynsyms); + cache_ptr->address -= bfd_get_section_vma (abfd, asect); + if (cache_ptr->address >= bfd_section_size (abfd, asect)) + --cache_ptr; + } + } + } bfd_release (abfd,relocs); asect->relocation = reloc_cache; - asect->reloc_count = count; + asect->reloc_count = cache_ptr - reloc_cache; return true; } @@ -2393,6 +2506,8 @@ DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect), bfd *abfd AND sec_ptr asect) { + bfd_size_type dynrel_count = 0; + if (bfd_get_format (abfd) != bfd_object) { bfd_error = invalid_operation; return 0; @@ -2401,16 +2516,26 @@ DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect), return (sizeof (arelent *) * (asect->reloc_count+1)); } + if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0 + && aout_backend_info (abfd)->read_dynamic_relocs) + { + PTR dynrels; + + dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs) + (abfd, &dynrels)); + if (dynrel_count == (bfd_size_type) -1) + return 0; + } if (asect == obj_datasec (abfd)) return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd)) - +1)); + ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd)) + + dynrel_count + 1)); if (asect == obj_textsec (abfd)) return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd)) - +1)); + ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd)) + + dynrel_count + 1)); bfd_error = invalid_operation; return 0; diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 06de0c6dd58..2e91a1d8db1 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1637,6 +1637,9 @@ typedef struct symbol_cache_entry for ELF STT_FILE symbols. */ #define BSF_FILE 0x4000 + /* Symbol is from dynamic linking information. */ +#define BSF_DYNAMIC 0x8000 + flagword flags; /* A pointer to the section to which this symbol is diff --git a/bfd/sunos.c b/bfd/sunos.c index a451a48914e..7f62a33ad86 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 -#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) -}; diff --git a/bfd/syms.c b/bfd/syms.c index 021332f5061..cb799c65014 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -249,6 +249,9 @@ CODE_FRAGMENT . for ELF STT_FILE symbols. *} .#define BSF_FILE 0x4000 . +. {* Symbol is from dynamic linking information. *} +.#define BSF_DYNAMIC 0x8000 +. . flagword flags; . . {* A pointer to the section to which this symbol is @@ -352,10 +355,11 @@ DESCRIPTION stream @var{file}. */ void -DEFUN(bfd_print_symbol_vandf,(file, symbol), -FILE *file AND +DEFUN(bfd_print_symbol_vandf,(arg, symbol), +PTR arg AND asymbol *symbol) { + FILE *file = (FILE *) arg; flagword type = symbol->flags; if (symbol->section != (asection *)NULL) { @@ -365,6 +369,9 @@ asymbol *symbol) { fprintf_vma(file, symbol->value); } + + /* This presumes that a symbol can not be both BSF_DEBUGGING and + BSF_DYNAMIC. */ fprintf(file," %c%c%c%c%c%c%c", (type & BSF_LOCAL) ? 'l':' ', (type & BSF_GLOBAL) ? 'g' : ' ', @@ -372,8 +379,8 @@ asymbol *symbol) (type & BSF_CONSTRUCTOR) ? 'C' : ' ', (type & BSF_WARNING) ? 'W' : ' ', (type & BSF_INDIRECT) ? 'I' : ' ', - (type & BSF_DEBUGGING) ? 'd' :' '); - + (type & BSF_DEBUGGING) ? 'd' + : (type & BSF_DYNAMIC) ? 'D' : ' '); } -- 2.30.2