diff options
author | Jeff Law <law@redhat.com> | 1996-03-29 06:56:02 +0000 |
---|---|---|
committer | Jeff Law <law@redhat.com> | 1996-03-29 06:56:02 +0000 |
commit | 39f27966436499da318f99c3ad922a2ba2d9208b (patch) | |
tree | 62ed70815ab57538301fa7613b4adf03655ae7e7 /bfd/linker.c | |
parent | 3197da91f90da028652216b219de00c81eeb0914 (diff) | |
download | gdb-39f27966436499da318f99c3ad922a2ba2d9208b.zip gdb-39f27966436499da318f99c3ad922a2ba2d9208b.tar.gz gdb-39f27966436499da318f99c3ad922a2ba2d9208b.tar.bz2 |
* libbfd-in.h (generic_link_hash_newfunc): Add declaration.
* libbfd.h: Rebuilt.
* linker.c (generic_link_hash_newfunc): No longer static.
* coffcode.h (coff_bfd_link_hash_create): Allow specific targets
to override.
* coff-h8300.c: Add two derived hash tables and their associated
funtions and #defines for use by the h8300 linker.
(h8300_reloc16_extra_cases, case R_MEM_INDIRECT): Create entries in
the function vector as needed. Place the address of the function
vector entry in the location specified by the R_MEM_INDIRECT reloc.
Rewrite the vectors section contents as necessary.
(h8300_bfd_link_add_symbols): New function for the h8300 linker.
(coff_bfd_link_add_symbols): Define to use h8300 specific version.
(coff_bfd_link_hash_table_create): Likewise.
Linker changes for function vectors. HMSE.
Diffstat (limited to 'bfd/linker.c')
-rw-r--r-- | bfd/linker.c | 153 |
1 files changed, 112 insertions, 41 deletions
diff --git a/bfd/linker.c b/bfd/linker.c index d8d9f6b..c359c92 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -406,9 +406,6 @@ SUBSUBSECTION file at the end of <<NAME(aout,final_link)>>. */ -static struct bfd_hash_entry *generic_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); static boolean generic_link_read_symbols PARAMS ((bfd *)); static boolean generic_link_add_symbols @@ -516,6 +513,88 @@ bfd_link_hash_lookup (table, string, create, copy, follow) return ret; } +/* Look up a symbol in the main linker hash table if the symbol might + be wrapped. This should only be used for references to an + undefined symbol, not for definitions of a symbol. */ + +struct bfd_link_hash_entry * +bfd_wrapped_link_hash_lookup (abfd, info, string, create, copy, follow) + bfd *abfd; + struct bfd_link_info *info; + const char *string; + boolean create; + boolean copy; + boolean follow; +{ + if (info->wrap_hash != NULL) + { + const char *l; + + l = string; + if (*l == bfd_get_symbol_leading_char (abfd)) + ++l; + +#undef WRAP +#define WRAP "__wrap_" + + if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL) + { + char *n; + struct bfd_link_hash_entry *h; + + /* This symbol is being wrapped. We want to replace all + references to SYM with references to __wrap_SYM. */ + + n = (char *) bfd_malloc (strlen (l) + sizeof WRAP + 1); + if (n == NULL) + return NULL; + + /* Note that symbol_leading_char may be '\0'. */ + n[0] = bfd_get_symbol_leading_char (abfd); + n[1] = '\0'; + strcat (n, WRAP); + strcat (n, l); + h = bfd_link_hash_lookup (info->hash, n, create, true, follow); + free (n); + return h; + } + +#undef WRAP + +#undef REAL +#define REAL "__real_" + + if (*l == '_' + && strncmp (l, REAL, sizeof REAL - 1) == 0 + && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, + false, false) != NULL) + { + char *n; + struct bfd_link_hash_entry *h; + + /* This is a reference to __real_SYM, where SYM is being + wrapped. We want to replace all references to __real_SYM + with references to SYM. */ + + n = (char *) bfd_malloc (strlen (l + sizeof REAL - 1) + 2); + if (n == NULL) + return NULL; + + /* Note that symbol_leading_char may be '\0'. */ + n[0] = bfd_get_symbol_leading_char (abfd); + n[1] = '\0'; + strcat (n, l + sizeof REAL - 1); + h = bfd_link_hash_lookup (info->hash, n, create, true, follow); + free (n); + return h; + } + +#undef REAL + } + + return bfd_link_hash_lookup (info->hash, string, create, copy, follow); +} + /* Traverse a generic link hash table. The only reason this is not a macro is to do better type checking. This code presumes that an argument passed as a struct bfd_hash_entry * may be caught as a @@ -551,7 +630,7 @@ bfd_link_add_undef (table, h) /* Routine to create an entry in an generic link hash table. */ -static struct bfd_hash_entry * +struct bfd_hash_entry * generic_link_hash_newfunc (entry, table, string) struct bfd_hash_entry *entry; struct bfd_hash_table *table; @@ -1427,13 +1506,13 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, row = DEF_ROW; if (hashp != NULL && *hashp != NULL) - { - h = *hashp; - BFD_ASSERT (strcmp (h->root.string, name) == 0); - } + h = *hashp; else { - h = bfd_link_hash_lookup (info->hash, name, true, copy, false); + if (row == UNDEF_ROW || row == UNDEFW_ROW) + h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false); + else + h = bfd_link_hash_lookup (info->hash, name, true, copy, false); if (h == NULL) { if (hashp != NULL) @@ -1716,8 +1795,8 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, /* STRING is the name of the symbol we want to indirect to. */ - inh = bfd_link_hash_lookup (info->hash, string, true, copy, - false); + inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true, + copy, false); if (inh == (struct bfd_link_hash_entry *) NULL) return false; if (inh->type == bfd_link_hash_new) @@ -1901,12 +1980,9 @@ _bfd_generic_final_link (abfd, info) input_section); if (relsize < 0) return false; - relocs = (arelent **) malloc ((size_t) relsize); + relocs = (arelent **) bfd_malloc ((size_t) relsize); if (!relocs && relsize != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; symbols = _bfd_generic_link_get_symbols (input_bfd); reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, @@ -1983,16 +2059,10 @@ generic_add_output_symbol (output_bfd, psymalloc, sym) *psymalloc = 124; else *psymalloc *= 2; - if (output_bfd->outsymbols == (asymbol **) NULL) - newsyms = (asymbol **) malloc (*psymalloc * sizeof (asymbol *)); - else - newsyms = (asymbol **) realloc (output_bfd->outsymbols, - *psymalloc * sizeof (asymbol *)); + newsyms = (asymbol **) bfd_realloc (output_bfd->outsymbols, + *psymalloc * sizeof (asymbol *)); if (newsyms == (asymbol **) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; output_bfd->outsymbols = newsyms; } @@ -2082,6 +2152,11 @@ _bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc) the relocs in the output format being used. */ h = NULL; } + else if (bfd_is_und_section (bfd_get_section (sym))) + h = ((struct generic_link_hash_entry *) + bfd_wrapped_link_hash_lookup (output_bfd, info, + bfd_asymbol_name (sym), + false, false, true)); else h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), bfd_asymbol_name (sym), @@ -2311,10 +2386,7 @@ _bfd_generic_link_write_global_symbol (h, data) return true; if (h->sym != (asymbol *) NULL) - { - sym = h->sym; - BFD_ASSERT (strcmp (bfd_asymbol_name (sym), h->root.root.string) == 0); - } + sym = h->sym; else { sym = bfd_make_empty_symbol (wginfo->output_bfd); @@ -2373,9 +2445,10 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order) { struct generic_link_hash_entry *h; - h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), + h = ((struct generic_link_hash_entry *) + bfd_wrapped_link_hash_lookup (abfd, info, link_order->u.reloc.p->u.name, - false, false, true); + false, false, true)); if (h == (struct generic_link_hash_entry *) NULL || ! h->written) { @@ -2520,12 +2593,9 @@ default_fill_link_order (abfd, info, sec, link_order) BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); size = (size_t) link_order->size; - space = (char *) malloc (size); + space = (char *) bfd_malloc (size); if (space == NULL && size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; fill = link_order->u.fill.value; for (i = 0; i < size; i += 2) @@ -2618,6 +2688,10 @@ default_indirect_link_order (output_bfd, info, output_section, link_order, generic_link_add_symbol_list. */ if (sym->udata.p != NULL) h = (struct bfd_link_hash_entry *) sym->udata.p; + else if (bfd_is_und_section (bfd_get_section (sym))) + h = bfd_wrapped_link_hash_lookup (output_bfd, info, + bfd_asymbol_name (sym), + false, false, true); else h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (sym), @@ -2630,12 +2704,9 @@ default_indirect_link_order (output_bfd, info, output_section, link_order, /* Get and relocate the section contents. */ contents = ((bfd_byte *) - malloc ((size_t) bfd_section_size (input_bfd, input_section))); + bfd_malloc (bfd_section_size (input_bfd, input_section))); if (contents == NULL && bfd_section_size (input_bfd, input_section) != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } + goto error_return; new_contents = (bfd_get_relocated_section_contents (output_bfd, info, link_order, contents, info->relocateable, _bfd_generic_link_get_symbols (input_bfd))); |