mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 07:53:51 +08:00
* 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:
153
bfd/linker.c
153
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)));
|
||||
|
Reference in New Issue
Block a user