mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 14:39:09 +08:00
Find the first .init and .fini sections correctly.
Clobber millicode syms via a hash traversal here. elf_adjust_dynamic_symbol really ought to let us look at all dynamic symbols, but it doesn't.
This commit is contained in:
@ -1,3 +1,15 @@
|
|||||||
|
2000-09-15 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* elf32-hppa.c (hppa_add_stub): Dont set first_init_sec and
|
||||||
|
first_fini_sec here.
|
||||||
|
(elf32_hppa_size_stubs): Instead correctly find the first .init
|
||||||
|
and .fini section here.
|
||||||
|
|
||||||
|
2000-09-15 David Huggins-Daines <dhd@linuxcare.com>
|
||||||
|
|
||||||
|
* elf32-hppa.c (clobber_millicode_symbols): New function.
|
||||||
|
(elf32_hppa_size_dynamic_sections): Call it.
|
||||||
|
|
||||||
2000-09-14 Alan Modra <alan@linuxcare.com.au>
|
2000-09-14 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
* elf32-hppa.c (elf32_hppa_link_hash_entry): Make pic_call
|
* elf32-hppa.c (elf32_hppa_link_hash_entry): Make pic_call
|
||||||
|
135
bfd/elf32-hppa.c
135
bfd/elf32-hppa.c
@ -345,6 +345,9 @@ static boolean hppa_discard_copies
|
|||||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static boolean clobber_millicode_symbols
|
||||||
|
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
|
||||||
|
|
||||||
static boolean elf32_hppa_size_dynamic_sections
|
static boolean elf32_hppa_size_dynamic_sections
|
||||||
PARAMS ((bfd *, struct bfd_link_info *));
|
PARAMS ((bfd *, struct bfd_link_info *));
|
||||||
|
|
||||||
@ -621,27 +624,11 @@ hppa_add_stub (stub_name, section, sec_count, info)
|
|||||||
stub_sec = hplink->stub_section_created[sec_count];
|
stub_sec = hplink->stub_section_created[sec_count];
|
||||||
if (stub_sec == NULL)
|
if (stub_sec == NULL)
|
||||||
{
|
{
|
||||||
int special_sec = 0;
|
|
||||||
|
|
||||||
/* We only want one stub for .init and .fini because glibc
|
|
||||||
splits the _init and _fini functions into two parts. We
|
|
||||||
don't want to put a stub in the middle of a function.
|
|
||||||
It would be better to merge all the stub sections for an
|
|
||||||
output section if the output section + stubs is small enough.
|
|
||||||
This would fix the .init and .fini case and also allow stubs
|
|
||||||
to be merged. It's more linker work though. */
|
|
||||||
if (strncmp (section->name, ".init", 5) == 0)
|
if (strncmp (section->name, ".init", 5) == 0)
|
||||||
{
|
stub_sec = hplink->stub_section_created[hplink->first_init_sec - 1];
|
||||||
if (hplink->first_init_sec != 0)
|
|
||||||
stub_sec = hplink->stub_section_created[hplink->first_init_sec-1];
|
|
||||||
special_sec = 1;
|
|
||||||
}
|
|
||||||
else if (strncmp (section->name, ".fini", 5) == 0)
|
else if (strncmp (section->name, ".fini", 5) == 0)
|
||||||
{
|
stub_sec = hplink->stub_section_created[hplink->first_fini_sec - 1];
|
||||||
if (hplink->first_fini_sec != 0)
|
|
||||||
stub_sec = hplink->stub_section_created[hplink->first_fini_sec-1];
|
|
||||||
special_sec = 2;
|
|
||||||
}
|
|
||||||
if (stub_sec == NULL)
|
if (stub_sec == NULL)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -657,14 +644,6 @@ hppa_add_stub (stub_name, section, sec_count, info)
|
|||||||
stub_sec = (*hplink->add_stub_section) (s_name, section);
|
stub_sec = (*hplink->add_stub_section) (s_name, section);
|
||||||
if (stub_sec == NULL)
|
if (stub_sec == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (special_sec != 0)
|
|
||||||
{
|
|
||||||
if (special_sec == 1)
|
|
||||||
hplink->first_init_sec = sec_count + 1;
|
|
||||||
else
|
|
||||||
hplink->first_fini_sec = sec_count + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hplink->stub_section_created[sec_count] = stub_sec;
|
hplink->stub_section_created[sec_count] = stub_sec;
|
||||||
}
|
}
|
||||||
@ -2127,6 +2106,27 @@ hppa_discard_copies (h, inf)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is called via elf_link_hash_traverse to force
|
||||||
|
millicode symbols local so they do not end up as globals in the
|
||||||
|
dynamic symbol table. We ought to be able to do this in
|
||||||
|
adjust_dynamic_symbol, but our adjust_dynamic_symbol is not called
|
||||||
|
for all dynamic symbols. Arguably, this is a bug in
|
||||||
|
elf_adjust_dynamic_symbol. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
clobber_millicode_symbols (h, info)
|
||||||
|
struct elf_link_hash_entry *h;
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
{
|
||||||
|
if (h->type == STT_PARISC_MILLI)
|
||||||
|
{
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
|
||||||
|
elf32_hppa_hide_symbol(info, h);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the sizes of the dynamic sections. */
|
/* Set the sizes of the dynamic sections. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
@ -2158,6 +2158,11 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
|||||||
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
|
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Force millicode symbols local. */
|
||||||
|
elf_link_hash_traverse (&hplink->root,
|
||||||
|
clobber_millicode_symbols,
|
||||||
|
info);
|
||||||
|
|
||||||
/* DT_INIT and DT_FINI need a .plt entry. Make sure they have
|
/* DT_INIT and DT_FINI need a .plt entry. Make sure they have
|
||||||
one. */
|
one. */
|
||||||
funcname = info->init_function;
|
funcname = info->init_function;
|
||||||
@ -2511,6 +2516,50 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
|
|||||||
/* Now we can free the external symbols. */
|
/* Now we can free the external symbols. */
|
||||||
free (ext_syms);
|
free (ext_syms);
|
||||||
|
|
||||||
|
/* Go looking for .init and .fini sections. We only want one
|
||||||
|
stub section for each of .init* and .fini* because glibc
|
||||||
|
splits the _init and _fini functions into multiple parts, and
|
||||||
|
putting a stub in the middle of a function is not a good idea.
|
||||||
|
It would be better to merge all the stub sections for an
|
||||||
|
output section if the output section + stubs is small enough.
|
||||||
|
This would fix the .init and .fini case and also allow stubs
|
||||||
|
to be merged. It's more linker work though. */
|
||||||
|
for (section = input_bfd->sections;
|
||||||
|
section != NULL;
|
||||||
|
section = section->next, sec_count++)
|
||||||
|
{
|
||||||
|
if (hplink->first_init_sec == 0)
|
||||||
|
{
|
||||||
|
if (strncmp (section->name, ".init", 5) == 0)
|
||||||
|
hplink->first_init_sec = sec_count + 1;
|
||||||
|
}
|
||||||
|
if (hplink->first_fini_sec == 0)
|
||||||
|
{
|
||||||
|
if (strncmp (section->name, ".fini", 5) == 0)
|
||||||
|
hplink->first_fini_sec = sec_count + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ! LONG_BRANCH_PIC_IN_SHLIB
|
||||||
|
/* If this is a shared link, find all the stub reloc
|
||||||
|
sections. */
|
||||||
|
if (info->shared)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
asection *reloc_sec;
|
||||||
|
|
||||||
|
name = bfd_malloc (strlen (section->name)
|
||||||
|
+ sizeof STUB_SUFFIX
|
||||||
|
+ 5);
|
||||||
|
if (name == NULL)
|
||||||
|
return false;
|
||||||
|
sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX);
|
||||||
|
reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name);
|
||||||
|
hplink->reloc_section_created[sec_count] = reloc_sec;
|
||||||
|
free (name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (info->shared && hplink->multi_subspace)
|
if (info->shared && hplink->multi_subspace)
|
||||||
{
|
{
|
||||||
unsigned int symndx;
|
unsigned int symndx;
|
||||||
@ -2558,7 +2607,8 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
|
|||||||
{
|
{
|
||||||
stub_entry = hppa_add_stub (stub_name,
|
stub_entry = hppa_add_stub (stub_name,
|
||||||
sec,
|
sec,
|
||||||
sec_count + sec->index,
|
(sec_count + sec->index
|
||||||
|
- input_bfd->section_count),
|
||||||
info);
|
info);
|
||||||
if (!stub_entry)
|
if (!stub_entry)
|
||||||
goto error_ret_free_local;
|
goto error_ret_free_local;
|
||||||
@ -2578,30 +2628,6 @@ elf32_hppa_size_stubs (stub_bfd, multi_subspace, info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if LONG_BRANCH_PIC_IN_SHLIB
|
|
||||||
sec_count += input_bfd->section_count;
|
|
||||||
#else
|
|
||||||
if (! info->shared)
|
|
||||||
sec_count += input_bfd->section_count;
|
|
||||||
else
|
|
||||||
for (section = input_bfd->sections;
|
|
||||||
section != NULL;
|
|
||||||
section = section->next, sec_count++)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
asection *reloc_sec;
|
|
||||||
|
|
||||||
name = bfd_malloc (strlen (section->name)
|
|
||||||
+ sizeof STUB_SUFFIX
|
|
||||||
+ 5);
|
|
||||||
if (name == NULL)
|
|
||||||
return false;
|
|
||||||
sprintf (name, ".rela%s%s", section->name, STUB_SUFFIX);
|
|
||||||
reloc_sec = bfd_get_section_by_name (hplink->root.dynobj, name);
|
|
||||||
hplink->reloc_section_created[sec_count] = reloc_sec;
|
|
||||||
free (name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -3735,11 +3761,6 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
|||||||
hplink = hppa_link_hash_table (info);
|
hplink = hppa_link_hash_table (info);
|
||||||
dynobj = hplink->root.dynobj;
|
dynobj = hplink->root.dynobj;
|
||||||
|
|
||||||
/* Millicode symbols should not be put in the dynamic
|
|
||||||
symbol table under any circumstances. */
|
|
||||||
if (ELF_ST_TYPE (sym->st_info) == STT_PARISC_MILLI)
|
|
||||||
h->dynindx = -1;
|
|
||||||
|
|
||||||
if (h->plt.offset != (bfd_vma) -1)
|
if (h->plt.offset != (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
bfd_vma value;
|
bfd_vma value;
|
||||||
|
Reference in New Issue
Block a user