diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-06-02 22:07:27 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-06-02 22:07:27 +0000 |
commit | e85e8bfe62883193337669c948d125fb13f235ed (patch) | |
tree | d8cb15cc280c6ec134ff98ac03e01165f44d4cf2 /bfd/aoutx.h | |
parent | ed601bea1c9dd09ba488acdbb2431d112580dd2d (diff) | |
download | gdb-e85e8bfe62883193337669c948d125fb13f235ed.zip gdb-e85e8bfe62883193337669c948d125fb13f235ed.tar.gz gdb-e85e8bfe62883193337669c948d125fb13f235ed.tar.bz2 |
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.
Diffstat (limited to 'bfd/aoutx.h')
-rw-r--r-- | bfd/aoutx.h | 186 |
1 files changed, 123 insertions, 63 deletions
diff --git a/bfd/aoutx.h b/bfd/aoutx.h index c65924d..3600829 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -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); |