* 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.
This commit is contained in:
Ian Lance Taylor 1994-01-21 06:29:21 +00:00
parent 5e6cd559cf
commit 0ee75d02e5
6 changed files with 579 additions and 667 deletions

View File

@ -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

View File

@ -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

View File

@ -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 (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;
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;
for (; counter < count; counter++, rptr++, cache_ptr++) {
NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
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;
}
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);
}
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);
}
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;

View File

@ -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

View File

@ -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 */
/* Static routines defined in this file. */
void (*bfd_error_trap)();
struct external_nlist;
static bfd_target *sunos4_callback ();
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 *));
/*SUPPRESS558*/
/*SUPPRESS529*/
#define MY_read_dynamic_symbols MY(read_dynamic_symbols)
#define MY_read_dynamic_relocs MY(read_dynamic_relocs)
bfd_target *
sunos4_object_p (abfd)
/* Include the usual a.out support. */
#include "aoutf1.h"
/* SunOS shared library support. We store a pointer to this structure
in obj_aout_dynamic_info (abfd). */
struct sunos_dynamic_info
{
/* 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. */
static boolean
sunos_read_dynamic_info (abfd)
bfd *abfd;
{
unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
unsigned long magic; /* Swapped magic number */
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;
bfd_error = system_call_error;
if (obj_aout_dynamic_info (abfd) != (PTR) NULL)
return true;
if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
sizeof (magicbuf))
return 0;
magic = bfd_h_getlong (abfd, magicbuf);
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;
if (N_BADMAG (*((struct exec *) &magic))) return 0;
/* 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;
return some_aout_object_p (abfd, sunos4_callback);
}
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;
/* 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;
}
}
dynver = GET_WORD (abfd, dyninfo.ld_version);
if (dynver != 2 && dynver != 3)
return true;
/* Set parameters about this a.out file that are machine-dependent.
This routine is called from some_aout_object_p just before it returns. */
dynoff = GET_WORD (abfd, dyninfo.ld);
static bfd_target *
sunos4_callback (abfd)
bfd *abfd;
{
struct exec *execp = exec_hdr (abfd);
/* 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;
/* 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);
/* 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;
/* The file offsets of the sections */
obj_textsec (abfd)->filepos = EXEC_BYTES_SIZE; /*N_TXTOFF(*execp);*/
obj_datasec (abfd)->filepos = N_DATOFF(*execp);
/* 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 file offsets of the relocation info */
obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
/* 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);
/* The file offsets of the string table and symbol table. */
obj_str_filepos (abfd) = N_STROFF (*execp);
obj_sym_filepos (abfd) = N_SYMOFF (*execp);
/* 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);
/* 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;
}
boolean
sunos4_mkobject (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");
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.
/* Read in the dynamic symbols. */
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. */
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;
}
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);
N_SET_MAGIC (*execp, OMAGIC);
if (abfd->flags & D_PAGED) {
/* This is not strictly true, but will probably do for the default
case. FIXME.
*/
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? */
if (abfd->flags & D_PAGED)
{
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;
}
else {
execp->a_data = obj_datasec (abfd)->size;
execp->a_bss = obj_bsssec (abfd)->size;
}
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)
if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
{
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;
if (! sunos_read_dynamic_info (abfd))
return (bfd_size_type) -1;
}
return true;
info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
if (! info->valid || info->dynsym_count == 0)
return 0;
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;
}
*syms = info->dynsym;
*strs = info->dynstr;
*strsize = info->dyninfo.ld_symb_size;
#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++)
{
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 ();
}
}
}
#endif /* CHECK_DYNAMIC_HASH */
return info->dynsym_count;
}
/* core files */
#define CORE_MAGIC 0x080456
#define CORE_NAMELEN 16
/* Read in the dynamic relocs for a section. */
/* 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;
};
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;
struct sunos_dynamic_info *info;
bfd_error = system_call_error;
if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
{
if (! sunos_read_dynamic_info (abfd))
return (bfd_size_type) -1;
}
if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
sizeof (longbuf))
return 0;
core_mag = bfd_h_getlong (abfd, longbuf);
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)
info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
if (! info->valid || info->dynrel_count == 0)
return 0;
if (bfd_seek (abfd, 0L, false) < 0) return 0;
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;
}
rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
if (rawptr == NULL) {
bfd_error = no_memory;
return 0;
}
*relocs = info->dynrel;
core = (struct core *) (rawptr + sizeof (struct suncordata));
if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
bfd_error = system_call_error;
bfd_release (abfd, rawptr);
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;
return info->dynrel_count;
}
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;
}
return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
sizeof (struct exec)) == 0) ? true : false;
}
/* 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. */
}
/* 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)
};

View File

@ -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' : ' ');
}