Add linker support for SunOS shared libraries.

* sunos.c: Include bfdlink.h.  Add many new functions and
	definitions for SunOS shared library support.
	* bfd-in.h (bfd_sunos_record_link_assignment): Declare.
	(bfd_sunos_size_dynamic_sections): Declare.
	* bfd-in2.h: Rebuilt.
	* aoutx.h (struct aout_link_hash_entry): Move to libaout.h.
	(struct aout_link_hash_table): Likewise.
	(aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
	(aout_hash_table): Likewise.
	(NAME(aout,link_hash_newfunc)): Rename from aout_link_hash_newfunc
	and make externally visible.
	(NAME(aout,link_hash_table_init)): New function.
	(NAME(aout,link_hash_table_create)): Call
	NAME(aout,link_hash_table_init), not _bfd_link_hash_table_init.
	(aout_link_add_symbols): Don't fail if no symbols.  If it exists,
	call add_dynamic_symbols backend entry point for dynamic objects.
	Use add_one_symbol backend entry point if it exists.
	(NAME(aout,final_link)): Call finish_dynamic_link backend entry
	point, if it exists.
	(aout_link_input_bfd): For a dynamic object, call
	link_dynamic_object backend entry point, if it exists.
	(aout_link_write_other_symbol): Call write_dynamic_symbol backend
	entry point, if it exists.
	(aout_link_input_section): Don't read the relocs if they have
	already been read.
	(aout_link_input_section_std): When doing a final link, for a
	reloc against an external symbol, call check_dynamic_reloc backend
	entry point, if it exists.
	(aout_link_input_section_ext): Likewise.
	* libaout.h: Protect against multiple inclusion.  Include
	bfdlink.h.
	(struct aout_link_hash_entry): Move in from aoutx.h.
	(struct aout_link_hash_table): Likewise.
	(aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
	(aout_hash_table): Likewise.
	(struct aout_backend_data): Add fields add_dynamic_symbols,
	add_one_symbol, link_dynamic_object, write_dynamic_symbol,
	check_dynamic_reloc, and finish_dynamic_link.
	(struct aout_section_data_struct): Define new structure.
	(aout_section_data): Define new accessor macro.
	(NAME(aout,link_hash_newfunc)): Declare.
	(NAME(aout,link_hash_table_init)): Declare.
	* aoutf1.h (sunos4_aout_backend): Initialize new aout_backend_data
	fields.
	* aout-target.h (MY(backend_data)): Likewise.
	* i386aout.c (MY(backend_data)): Likewise.
	* i386mach3.c (MY(backend_data)): Likewise.
	* mipsbsd.c (MY(backend_data)): Likewise.
	* sparclynx.c (sparclynx_aout_backend): Likewise.
This commit is contained in:
Ian Lance Taylor 1994-06-02 22:07:27 +00:00
parent ed601bea1c
commit e85e8bfe62
4 changed files with 2104 additions and 110 deletions

View File

@ -1,3 +1,62 @@
Thu Jun 2 17:39:22 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
Add linker support for SunOS shared libraries.
* sunos.c: Include bfdlink.h. Add many new functions and
definitions for SunOS shared library support.
* bfd-in.h (bfd_sunos_record_link_assignment): Declare.
(bfd_sunos_size_dynamic_sections): Declare.
* bfd-in2.h: Rebuilt.
* aoutx.h (struct aout_link_hash_entry): Move to libaout.h.
(struct aout_link_hash_table): Likewise.
(aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
(aout_hash_table): Likewise.
(NAME(aout,link_hash_newfunc)): Rename from aout_link_hash_newfunc
and make externally visible.
(NAME(aout,link_hash_table_init)): New function.
(NAME(aout,link_hash_table_create)): Call
NAME(aout,link_hash_table_init), not _bfd_link_hash_table_init.
(aout_link_add_symbols): Don't fail if no symbols. If it exists,
call add_dynamic_symbols backend entry point for dynamic objects.
Use add_one_symbol backend entry point if it exists.
(NAME(aout,final_link)): Call finish_dynamic_link backend entry
point, if it exists.
(aout_link_input_bfd): For a dynamic object, call
link_dynamic_object backend entry point, if it exists.
(aout_link_write_other_symbol): Call write_dynamic_symbol backend
entry point, if it exists.
(aout_link_input_section): Don't read the relocs if they have
already been read.
(aout_link_input_section_std): When doing a final link, for a
reloc against an external symbol, call check_dynamic_reloc backend
entry point, if it exists.
(aout_link_input_section_ext): Likewise.
* libaout.h: Protect against multiple inclusion. Include
bfdlink.h.
(struct aout_link_hash_entry): Move in from aoutx.h.
(struct aout_link_hash_table): Likewise.
(aout_link_hash_lookup, aout_link_hash_traverse): Likewise.
(aout_hash_table): Likewise.
(struct aout_backend_data): Add fields add_dynamic_symbols,
add_one_symbol, link_dynamic_object, write_dynamic_symbol,
check_dynamic_reloc, and finish_dynamic_link.
(struct aout_section_data_struct): Define new structure.
(aout_section_data): Define new accessor macro.
(NAME(aout,link_hash_newfunc)): Declare.
(NAME(aout,link_hash_table_init)): Declare.
* aoutf1.h (sunos4_aout_backend): Initialize new aout_backend_data
fields.
* aout-target.h (MY(backend_data)): Likewise.
* i386aout.c (MY(backend_data)): Likewise.
* i386mach3.c (MY(backend_data)): Likewise.
* mipsbsd.c (MY(backend_data)): Likewise.
* sparclynx.c (sparclynx_aout_backend): Likewise.
* aoutx.h (NAME(aout,slurp_symbol_table)): Don't zero out cached
until we know it is non-NULL.
(aout_link_write_symbols): Don't skip a warning symbol even if it
has already been written out. If skipping an indirect symbol,
skip the next symbol as well.
Wed Jun 1 14:37:50 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* hosts/sun3.h: Don't declare qsort, malloc or realloc.

View File

@ -1578,13 +1578,12 @@ NAME(aout,slurp_symbol_table) (abfd)
cached_size = (obj_aout_external_sym_count (abfd)
* sizeof (aout_symbol_type));
cached = (aout_symbol_type *) malloc (cached_size);
memset (cached, 0, cached_size);
if (cached == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
memset (cached, 0, cached_size);
/* Convert from external symbol information to internal. */
if (! (NAME(aout,translate_symbol_table)
@ -2819,26 +2818,6 @@ NAME(aout,bfd_free_cached_info) (abfd)
/* a.out link code. */
/* a.out linker hash table entries. */
struct aout_link_hash_entry
{
struct bfd_link_hash_entry root;
/* Symbol index in output file. */
int indx;
};
/* a.out linker hash table. */
struct aout_link_hash_table
{
struct bfd_link_hash_table root;
};
static struct bfd_hash_entry *aout_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *entry,
struct bfd_hash_table *table,
const char *string));
static boolean aout_link_add_object_symbols
PARAMS ((bfd *, struct bfd_link_info *));
static boolean aout_link_check_archive_element
@ -2851,8 +2830,8 @@ static boolean aout_link_add_symbols
/* Routine to create an entry in an a.out link hash table. */
static struct bfd_hash_entry *
aout_link_hash_newfunc (entry, table, string)
struct bfd_hash_entry *
NAME(aout,link_hash_newfunc) (entry, table, string)
struct bfd_hash_entry *entry;
struct bfd_hash_table *table;
const char *string;
@ -2881,6 +2860,19 @@ aout_link_hash_newfunc (entry, table, string)
return (struct bfd_hash_entry *) ret;
}
/* Initialize an a.out link hash table. */
boolean
NAME(aout,link_hash_table_init) (table, abfd, newfunc)
struct aout_link_hash_table *table;
bfd *abfd;
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *));
{
return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
}
/* Create an a.out link hash table. */
struct bfd_link_hash_table *
@ -2896,8 +2888,8 @@ NAME(aout,link_hash_table_create) (abfd)
bfd_set_error (bfd_error_no_memory);
return (struct bfd_link_hash_table *) NULL;
}
if (! _bfd_link_hash_table_init (&ret->root, abfd,
aout_link_hash_newfunc))
if (! NAME(aout,link_hash_table_init) (ret, abfd,
NAME(aout,link_hash_newfunc)))
{
free (ret);
return (struct bfd_link_hash_table *) NULL;
@ -2905,25 +2897,6 @@ NAME(aout,link_hash_table_create) (abfd)
return &ret->root;
}
/* Look up an entry in an a.out link hash table. */
#define aout_link_hash_lookup(table, string, create, copy, follow) \
((struct aout_link_hash_entry *) \
bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
/* Traverse an a.out link hash table. */
#define aout_link_hash_traverse(table, func, info) \
(bfd_link_hash_traverse \
(&(table)->root, \
(boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
(info)))
/* Get the a.out link hash table from the info structure. This is
just a cast. */
#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
/* Given an a.out BFD, add symbols to the global hash table as
appropriate. */
@ -3148,6 +3121,11 @@ aout_link_add_symbols (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
const char *, flagword, asection *,
bfd_vma, const char *, boolean,
boolean,
struct bfd_link_hash_entry **));
bfd_size_type sym_count;
char *strings;
boolean copy;
@ -3170,13 +3148,24 @@ aout_link_add_symbols (abfd, info)
bfd_alloc (abfd,
((size_t) sym_count
* sizeof (struct aout_link_hash_entry *))));
if (!sym_hash)
if (sym_hash == NULL && sym_count != 0)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
obj_aout_sym_hashes (abfd) = sym_hash;
if ((abfd->flags & DYNAMIC) != 0
&& aout_backend_info (abfd)->add_dynamic_symbols != NULL)
{
if (! (*aout_backend_info (abfd)->add_dynamic_symbols) (abfd, info))
return false;
}
add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
if (add_one_symbol == NULL)
add_one_symbol = _bfd_generic_link_add_one_symbol;
p = obj_aout_external_syms (abfd);
pend = p + sym_count;
for (; p < pend; p++, sym_hash++)
@ -3291,7 +3280,7 @@ aout_link_add_symbols (abfd, info)
break;
}
if (! (_bfd_generic_link_add_one_symbol
if (! ((*add_one_symbol)
(info, abfd, name, flags, section, value, string, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
return false;
@ -3522,6 +3511,13 @@ NAME(aout,final_link) (abfd, info, callback)
}
}
/* Finish up any dynamic linking we may be doing. */
if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
{
if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
return false;
}
/* Update the header information. */
abfd->symcount = obj_aout_external_sym_count (abfd);
exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
@ -3549,6 +3545,14 @@ aout_link_input_bfd (finfo, input_bfd)
BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
/* If this is a dynamic object, it may need special handling. */
if ((input_bfd->flags & DYNAMIC) != 0
&& aout_backend_info (input_bfd)->link_dynamic_object != NULL)
{
return ((*aout_backend_info (input_bfd)->link_dynamic_object)
(finfo->info, input_bfd));
}
/* Get the symbols. We probably have them already, unless
finfo->info->keep_memory is false. */
if (! aout_get_external_symbols (input_bfd))
@ -3721,8 +3725,11 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
/* If the symbol has already been written out, skip it. */
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type != bfd_link_hash_warning
&& h->root.written)
{
if ((type & N_TYPE) == N_INDR)
skip_indirect = true;
*symbol_map = h->indx;
continue;
}
@ -3946,6 +3953,18 @@ aout_link_write_other_symbol (h, data)
bfd_vma val;
struct external_nlist outsym;
output_bfd = finfo->output_bfd;
if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
{
if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
(output_bfd, finfo->info, h)))
{
/* FIXME: No way to handle errors. */
abort ();
}
}
if (h->root.written)
return true;
@ -3957,8 +3976,6 @@ aout_link_write_other_symbol (h, data)
false, false) == NULL))
return true;
output_bfd = finfo->output_bfd;
switch (h->root.type)
{
default:
@ -4038,7 +4055,8 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
{
bfd_size_type input_size;
bfd_byte *contents = NULL;
PTR relocs = NULL;
PTR relocs;
PTR free_relocs = NULL;
/* Get the section contents. */
input_size = bfd_section_size (input_bfd, input_section);
@ -4052,16 +4070,22 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
(file_ptr) 0, input_size))
goto error_return;
/* Read in the relocs. */
relocs = (PTR) malloc (rel_size);
if (relocs == NULL && rel_size != 0)
/* Read in the relocs if we haven't already done it. */
if (aout_section_data (input_section) != NULL
&& aout_section_data (input_section)->relocs != NULL)
relocs = aout_section_data (input_section)->relocs;
else
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
relocs = free_relocs = (PTR) malloc (rel_size);
if (relocs == NULL && rel_size != 0)
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
}
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
|| bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
goto error_return;
}
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
|| bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
goto error_return;
/* Relocate the section contents. */
if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
@ -4107,14 +4131,14 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
<= obj_datasec (finfo->output_bfd)->rel_filepos)));
}
if (relocs != NULL)
free (relocs);
if (free_relocs != NULL)
free (free_relocs);
if (contents != NULL)
free (contents);
return true;
error_return:
if (relocs != NULL)
free (relocs);
if (free_relocs != NULL)
free (free_relocs);
if (contents != NULL)
free (contents);
return false;
@ -4156,6 +4180,10 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
bfd_byte *contents;
int *symbol_map;
{
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
bfd *, asection *,
struct aout_link_hash_entry *,
PTR, boolean *));
bfd *output_bfd;
boolean relocateable;
struct external_nlist *syms;
@ -4166,6 +4194,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
struct reloc_std_external *rel_end;
output_bfd = finfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
@ -4343,6 +4372,19 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
struct aout_link_hash_entry *h;
h = sym_hashes[r_index];
if (check_dynamic_reloc != NULL)
{
boolean skip;
if (! ((*check_dynamic_reloc)
(finfo->info, input_bfd, input_section, h,
(PTR) rel, &skip)))
return false;
if (skip)
continue;
}
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
{
@ -4427,6 +4469,10 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
bfd_byte *contents;
int *symbol_map;
{
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
bfd *, asection *,
struct aout_link_hash_entry *,
PTR, boolean *));
bfd *output_bfd;
boolean relocateable;
struct external_nlist *syms;
@ -4437,6 +4483,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
struct reloc_ext_external *rel_end;
output_bfd = finfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
@ -4619,6 +4666,19 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
struct aout_link_hash_entry *h;
h = sym_hashes[r_index];
if (check_dynamic_reloc != NULL)
{
boolean skip;
if (! ((*check_dynamic_reloc)
(finfo->info, input_bfd, input_section, h,
(PTR) rel, &skip)))
return false;
if (skip)
continue;
}
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
{
@ -4838,7 +4898,7 @@ aout_link_reloc_link_order (finfo, o, p)
boolean ok;
size = bfd_get_reloc_size (howto);
buf = (bfd_byte*) bfd_zmalloc (size);
buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == (bfd_byte *) NULL)
{
bfd_set_error (bfd_error_no_memory);

View File

@ -18,10 +18,15 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef LIBAOUT_H
#define LIBAOUT_H
/* We try to encapsulate the differences in the various a.out file
variants in a few routines, and otherwise share large masses of code.
This means we only have to fix bugs in one place, most of the time. */
#include "bfdlink.h"
/* Parameterize the a.out code based on whether it is being built
for a 32-bit architecture or a 64-bit architecture. */
#if ARCH_SIZE==64
@ -50,7 +55,42 @@ struct external_exec;
struct external_nlist;
struct reloc_ext_external;
struct reloc_std_external;
/* a.out backend linker hash table entries. */
struct aout_link_hash_entry
{
struct bfd_link_hash_entry root;
/* Symbol index in output file. */
int indx;
};
/* a.out backend linker hash table. */
struct aout_link_hash_table
{
struct bfd_link_hash_table root;
};
/* Look up an entry in an a.out link hash table. */
#define aout_link_hash_lookup(table, string, create, copy, follow) \
((struct aout_link_hash_entry *) \
bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
/* Traverse an a.out link hash table. */
#define aout_link_hash_traverse(table, func, info) \
(bfd_link_hash_traverse \
(&(table)->root, \
(boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
(info)))
/* Get the a.out link hash table from the info structure. This is
just a cast. */
#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
/* Back-end information for various a.out targets. */
struct aout_backend_data
{
@ -63,6 +103,9 @@ struct aout_backend_data
If not, the text section starts on the next page. */
unsigned char text_includes_header;
/* The value to pass to N_SET_FLAGS. */
unsigned char exec_hdr_flags;
/* If the text section VMA isn't specified, and we need an absolute
address, use this as the default. If we're producing a relocatable
file, zero is always used. */
@ -79,6 +122,39 @@ struct aout_backend_data
to the size of the text section in the file for alignment purposes but
does *not* get counted in the length of the text section. */
unsigned char exec_header_not_counted;
/* Callback from the add symbols phase of the linker code to handle
a dynamic object. */
boolean (*add_dynamic_symbols) PARAMS ((bfd *, struct bfd_link_info *));
/* Callback from the add symbols phase of the linker code to handle
adding a single symbol to the global linker hash table. */
boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
const char *, flagword, asection *,
bfd_vma, const char *, boolean,
boolean,
struct bfd_link_hash_entry **));
/* Called to handle linking a dynamic object. */
boolean (*link_dynamic_object) PARAMS ((struct bfd_link_info *, bfd *));
/* Called for each global symbol being written out by the linker.
This should write out the dynamic symbol information. */
boolean (*write_dynamic_symbol) PARAMS ((bfd *, struct bfd_link_info *,
struct aout_link_hash_entry *));
/* This callback is called by the linker for each reloc against an
external symbol. RELOC is a pointer to the unswapped reloc. If
*SKIP is set to true, the reloc will be skipped. */
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *info,
bfd *input_bfd,
asection *input_section,
struct aout_link_hash_entry *h,
PTR reloc, boolean *skip));
/* Called at the end of a link to finish up any dynamic linking
information. */
boolean (*finish_dynamic_link) PARAMS ((bfd *, struct bfd_link_info *));
};
#define aout_backend_info(abfd) \
((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
@ -269,11 +345,26 @@ struct aout_data_struct {
macro is only ever applied to an asymbol */
#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd))
/* Information we keep for each a.out section. This is currently only
used by the a.out backend linker. */
struct aout_section_data_struct
{
/* The unswapped relocation entries for this section. */
PTR relocs;
};
#define aout_section_data(s) \
((struct aout_section_data_struct *) (s)->used_by_bfd)
/* Prototype declarations for functions defined in aoutx.h */
boolean
NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section));
boolean
NAME(aout,make_sections) PARAMS ((bfd *));
bfd_target *
NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd,
struct internal_exec *execp,
@ -374,6 +465,17 @@ void
NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
struct internal_exec *execp, struct external_exec *raw_bytes));
struct bfd_hash_entry *
NAME(aout,link_hash_newfunc)
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
boolean
NAME(aout,link_hash_table_init)
PARAMS ((struct aout_link_hash_table *, bfd *,
struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *)));
struct bfd_link_hash_table *
NAME(aout,link_hash_table_create) PARAMS ((bfd *));
@ -453,3 +555,5 @@ aout_stab_name PARAMS ((int code));
} \
}
#endif
#endif /* ! defined (LIBAOUT_H) */

File diff suppressed because it is too large Load Diff