mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-15 05:01:13 +08:00
__tls_get_addr_opt stubs and tocsave optimization
This patch fixes a bug in the handling of the __tls_get_addr_opt stub. Calls via this stub don't have a toc restoring instruction following the "bl", and the stub itself doesn't have an initial toc save instruction. Thus it is incorrect to skip over the first instruction when a __tls_get_addr call is marked with a tocsave reloc. * elf64-ppc.c (ppc64_elf_relocate_section): Don't skip first instruction of __tls_get_addr_opt stub. (plt_stub_size): Omit ALWAYS_EMIT_R2SAVE condition when dealing with __tls_get_addr_opt stub. (build_tls_get_addr_stub, ppc_size_one_stub): Likewise.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2018-08-07 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_relocate_section): Don't skip first
|
||||||
|
instruction of __tls_get_addr_opt stub.
|
||||||
|
(plt_stub_size): Omit ALWAYS_EMIT_R2SAVE condition when
|
||||||
|
dealing with __tls_get_addr_opt stub.
|
||||||
|
(build_tls_get_addr_stub, ppc_size_one_stub): Likewise.
|
||||||
|
|
||||||
2018-08-06 Claudiu Zissulescu <claziss@synopsys.com>
|
2018-08-06 Claudiu Zissulescu <claziss@synopsys.com>
|
||||||
|
|
||||||
* elf32-arc.c (arc_elf_merge_private_bfd_data): Complain about
|
* elf32-arc.c (arc_elf_merge_private_bfd_data): Complain about
|
||||||
|
@ -11027,8 +11027,7 @@ plt_stub_size (struct ppc_link_hash_table *htab,
|
|||||||
&& htab->params->tls_get_addr_opt)
|
&& htab->params->tls_get_addr_opt)
|
||||||
{
|
{
|
||||||
size += 7 * 4;
|
size += 7 * 4;
|
||||||
if (ALWAYS_EMIT_R2SAVE
|
if (stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
||||||
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
|
||||||
size += 6 * 4;
|
size += 6 * 4;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
@ -11273,8 +11272,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab,
|
|||||||
bfd_put_32 (obfd, MR_R3_R0, p), p += 4;
|
bfd_put_32 (obfd, MR_R3_R0, p), p += 4;
|
||||||
if (r != NULL)
|
if (r != NULL)
|
||||||
r[0].r_offset += 7 * 4;
|
r[0].r_offset += 7 * 4;
|
||||||
if (!ALWAYS_EMIT_R2SAVE
|
if (stub_entry->stub_type != ppc_stub_plt_call_r2save)
|
||||||
&& stub_entry->stub_type != ppc_stub_plt_call_r2save)
|
|
||||||
return build_plt_stub (htab, stub_entry, p, offset, r);
|
return build_plt_stub (htab, stub_entry, p, offset, r);
|
||||||
|
|
||||||
bfd_put_32 (obfd, MFLR_R11, p), p += 4;
|
bfd_put_32 (obfd, MFLR_R11, p), p += 4;
|
||||||
@ -11928,8 +11926,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
&& (stub_entry->h == htab->tls_get_addr_fd
|
&& (stub_entry->h == htab->tls_get_addr_fd
|
||||||
|| stub_entry->h == htab->tls_get_addr)
|
|| stub_entry->h == htab->tls_get_addr)
|
||||||
&& htab->params->tls_get_addr_opt
|
&& htab->params->tls_get_addr_opt
|
||||||
&& (ALWAYS_EMIT_R2SAVE
|
&& stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
||||||
|| stub_entry->stub_type == ppc_stub_plt_call_r2save))
|
|
||||||
stub_entry->group->tls_get_addr_opt_bctrl
|
stub_entry->group->tls_get_addr_opt_bctrl
|
||||||
= stub_entry->stub_offset + size - 5 * 4;
|
= stub_entry->stub_offset + size - 5 * 4;
|
||||||
|
|
||||||
@ -15336,6 +15333,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
&& ALWAYS_EMIT_R2SAVE)
|
&& ALWAYS_EMIT_R2SAVE)
|
||||||
|| stub_entry->stub_type == ppc_stub_plt_call_r2save
|
|| stub_entry->stub_type == ppc_stub_plt_call_r2save
|
||||||
|| stub_entry->stub_type == ppc_stub_plt_call_both)
|
|| stub_entry->stub_type == ppc_stub_plt_call_both)
|
||||||
|
&& !(h != NULL
|
||||||
|
&& (h == htab->tls_get_addr_fd
|
||||||
|
|| h == htab->tls_get_addr)
|
||||||
|
&& htab->params->tls_get_addr_opt)
|
||||||
&& rel + 1 < relend
|
&& rel + 1 < relend
|
||||||
&& rel[1].r_offset == rel->r_offset + 4
|
&& rel[1].r_offset == rel->r_offset + 4
|
||||||
&& ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOCSAVE)
|
&& ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOCSAVE)
|
||||||
|
Reference in New Issue
Block a user