* 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.
This commit is contained in:
Jeff Law
1996-03-29 06:56:02 +00:00
parent 3197da91f9
commit 39f2796643
5 changed files with 583 additions and 44 deletions

View File

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