mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 02:24:46 +08:00
PowerPC PLT stub alignment fixes
Asking for ppc32 plt call stubs to be aligned at 32 byte boundaries didn't quite work. For ld.bfd they were spaced 32 bytes apart, but only started on a 16 byte boundary. ld.gold also didn't get it right. Finding that bug made me check over the ppc64 plt stub alignment, where I found that negative values for alignment (meaning align to minimize boundary crossing) were not accepted. Since no one has complained about that, I guess I could have removed the feature from ld.bfd documentation, but I've opted instead to correct the code. I've also added an optional alignment paramenter for ppc32 --plt-align, for some consistency with gold and ppc64 ld.bfd. bfd/ * elf32-ppc.c (ppc_elf_create_glink): Correct alignment of .glink. * elf64-ppc.c (ppc64_elf_size_stubs): Handle negative plt_stub_align. (ppc64_elf_build_stubs): Likewise. gold/ * powerpc.cc (param_plt_align): New function supplying default --plt-align values. Use it.. (Stub_table::plt_call_align): ..here, and.. (Output_data_glink::global_entry_align): ..here. (Stub_table::stub_align): Correct 32-bit minimum alignment. ld/ * emultempl/ppc32elf.em: Support optional --plt-align arg. * emultempl/ppc64elf.em: Support negative --plt-align arg.
This commit is contained in:
parent
7ab8203798
commit
691d2e9af2
@ -1,3 +1,9 @@
|
|||||||
|
2018-01-18 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf32-ppc.c (ppc_elf_create_glink): Correct alignment of .glink.
|
||||||
|
* elf64-ppc.c (ppc64_elf_size_stubs): Handle negative plt_stub_align.
|
||||||
|
(ppc64_elf_build_stubs): Likewise.
|
||||||
|
|
||||||
2018-01-17 Nick Clifton <nickc@redhat.com>
|
2018-01-17 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/ru.po: Updated Russian translation.
|
* po/ru.po: Updated Russian translation.
|
||||||
|
@ -3475,14 +3475,17 @@ ppc_elf_create_glink (bfd *abfd, struct bfd_link_info *info)
|
|||||||
struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
|
struct ppc_elf_link_hash_table *htab = ppc_elf_hash_table (info);
|
||||||
asection *s;
|
asection *s;
|
||||||
flagword flags;
|
flagword flags;
|
||||||
|
int p2align;
|
||||||
|
|
||||||
flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
|
flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
|
||||||
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
|
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
|
||||||
s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
|
s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
|
||||||
htab->glink = s;
|
htab->glink = s;
|
||||||
|
p2align = htab->params->ppc476_workaround ? 6 : 4;
|
||||||
|
if (p2align < htab->params->plt_stub_align)
|
||||||
|
p2align = htab->params->plt_stub_align;
|
||||||
if (s == NULL
|
if (s == NULL
|
||||||
|| !bfd_set_section_alignment (abfd, s,
|
|| !bfd_set_section_alignment (abfd, s, p2align))
|
||||||
htab->params->ppc476_workaround ? 6 : 4))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!info->no_ld_generated_unwind_info)
|
if (!info->no_ld_generated_unwind_info)
|
||||||
|
@ -12743,9 +12743,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
|
|||||||
if (htab->params->plt_stub_align != 0)
|
if (htab->params->plt_stub_align != 0)
|
||||||
for (group = htab->group; group != NULL; group = group->next)
|
for (group = htab->group; group != NULL; group = group->next)
|
||||||
if (group->stub_sec != NULL)
|
if (group->stub_sec != NULL)
|
||||||
group->stub_sec->size = ((group->stub_sec->size
|
{
|
||||||
+ (1 << htab->params->plt_stub_align) - 1)
|
int align = abs (htab->params->plt_stub_align);
|
||||||
& -(1 << htab->params->plt_stub_align));
|
group->stub_sec->size
|
||||||
|
= (group->stub_sec->size + (1 << align) - 1) & -(1 << align);
|
||||||
|
}
|
||||||
|
|
||||||
for (group = htab->group; group != NULL; group = group->next)
|
for (group = htab->group; group != NULL; group = group->next)
|
||||||
if (group->stub_sec != NULL
|
if (group->stub_sec != NULL
|
||||||
@ -13285,9 +13287,10 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
|
|||||||
if (htab->params->plt_stub_align != 0)
|
if (htab->params->plt_stub_align != 0)
|
||||||
for (group = htab->group; group != NULL; group = group->next)
|
for (group = htab->group; group != NULL; group = group->next)
|
||||||
if ((stub_sec = group->stub_sec) != NULL)
|
if ((stub_sec = group->stub_sec) != NULL)
|
||||||
stub_sec->size = ((stub_sec->size
|
{
|
||||||
+ (1 << htab->params->plt_stub_align) - 1)
|
int align = abs (htab->params->plt_stub_align);
|
||||||
& -(1 << htab->params->plt_stub_align));
|
stub_sec->size = (stub_sec->size + (1 << align) - 1) & -(1 << align);
|
||||||
|
}
|
||||||
|
|
||||||
for (group = htab->group; group != NULL; group = group->next)
|
for (group = htab->group; group != NULL; group = group->next)
|
||||||
if ((stub_sec = group->stub_sec) != NULL)
|
if ((stub_sec = group->stub_sec) != NULL)
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
2018-01-18 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* powerpc.cc (param_plt_align): New function supplying default
|
||||||
|
--plt-align values. Use it..
|
||||||
|
(Stub_table::plt_call_align): ..here, and..
|
||||||
|
(Output_data_glink::global_entry_align): ..here.
|
||||||
|
(Stub_table::stub_align): Correct 32-bit minimum alignment.
|
||||||
|
|
||||||
2018-01-17 Alan Modra <amodra@gmail.com>
|
2018-01-17 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* options.h (speculate_indirect_jumps): New option.
|
* options.h (speculate_indirect_jumps): New option.
|
||||||
|
@ -4186,6 +4186,15 @@ output_bctr(unsigned char* p)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<int size>
|
||||||
|
static inline unsigned int
|
||||||
|
param_plt_align()
|
||||||
|
{
|
||||||
|
if (!parameters->options().user_set_plt_align())
|
||||||
|
return size == 64 ? 32 : 8;
|
||||||
|
return 1 << parameters->options().plt_align();
|
||||||
|
}
|
||||||
|
|
||||||
// Stub_table holds information about plt and long branch stubs.
|
// Stub_table holds information about plt and long branch stubs.
|
||||||
// Stubs are built in an area following some input section determined
|
// Stubs are built in an area following some input section determined
|
||||||
// by group_sections(). This input section is converted to a relaxed
|
// by group_sections(). This input section is converted to a relaxed
|
||||||
@ -4412,9 +4421,7 @@ class Stub_table : public Output_relaxed_input_section
|
|||||||
unsigned int
|
unsigned int
|
||||||
stub_align() const
|
stub_align() const
|
||||||
{
|
{
|
||||||
unsigned int min_align = 4;
|
unsigned int min_align = size == 64 ? 32 : 16;
|
||||||
if (!parameters->options().user_set_plt_align())
|
|
||||||
return size == 64 ? 32 : min_align;
|
|
||||||
unsigned int user_align = 1 << parameters->options().plt_align();
|
unsigned int user_align = 1 << parameters->options().plt_align();
|
||||||
return std::max(user_align, min_align);
|
return std::max(user_align, min_align);
|
||||||
}
|
}
|
||||||
@ -4483,7 +4490,7 @@ class Stub_table : public Output_relaxed_input_section
|
|||||||
unsigned int
|
unsigned int
|
||||||
plt_call_align(unsigned int bytes) const
|
plt_call_align(unsigned int bytes) const
|
||||||
{
|
{
|
||||||
unsigned int align = this->stub_align();
|
unsigned int align = param_plt_align<size>();
|
||||||
return (bytes + align - 1) & -align;
|
return (bytes + align - 1) & -align;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4926,9 +4933,7 @@ class Output_data_glink : public Output_section_data
|
|||||||
unsigned int
|
unsigned int
|
||||||
global_entry_align(unsigned int off) const
|
global_entry_align(unsigned int off) const
|
||||||
{
|
{
|
||||||
unsigned int align = 1 << parameters->options().plt_align();
|
unsigned int align = param_plt_align<size>();
|
||||||
if (!parameters->options().user_set_plt_align())
|
|
||||||
align = size == 64 ? 32 : 4;
|
|
||||||
return (off + align - 1) & -align;
|
return (off + align - 1) & -align;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2018-01-18 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* emultempl/ppc32elf.em: Support optional --plt-align arg.
|
||||||
|
* emultempl/ppc64elf.em: Support negative --plt-align arg.
|
||||||
|
|
||||||
2018-01-17 Alan Modra <amodra@gmail.com>
|
2018-01-17 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* emultempl/ppc32elf.em (params): Init new field.
|
* emultempl/ppc32elf.em (params): Init new field.
|
||||||
|
@ -271,7 +271,7 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
|
|||||||
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
|
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
|
||||||
{ "speculate-indirect-jumps", no_argument, NULL, OPTION_SPECULATE_INDIRECT_JUMPS },
|
{ "speculate-indirect-jumps", no_argument, NULL, OPTION_SPECULATE_INDIRECT_JUMPS },
|
||||||
{ "no-speculate-indirect-jumps", no_argument, NULL, OPTION_NO_SPECULATE_INDIRECT_JUMPS },
|
{ "no-speculate-indirect-jumps", no_argument, NULL, OPTION_NO_SPECULATE_INDIRECT_JUMPS },
|
||||||
{ "plt-align", no_argument, NULL, OPTION_PLT_ALIGN },
|
{ "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
|
||||||
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
|
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
|
||||||
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
|
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
|
||||||
fi
|
fi
|
||||||
@ -369,7 +369,16 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTION_PLT_ALIGN:
|
case OPTION_PLT_ALIGN:
|
||||||
params.plt_stub_align = 5;
|
if (optarg != NULL)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
unsigned long val = strtoul (optarg, &end, 0);
|
||||||
|
if (*end || val > 5)
|
||||||
|
einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
|
||||||
|
params.plt_stub_align = val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
params.plt_stub_align = 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPTION_NO_PLT_ALIGN:
|
case OPTION_NO_PLT_ALIGN:
|
||||||
|
@ -872,8 +872,8 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
|
|||||||
if (optarg != NULL)
|
if (optarg != NULL)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
unsigned long val = strtoul (optarg, &end, 0);
|
long val = strtol (optarg, &end, 0);
|
||||||
if (*end || val > 8)
|
if (*end || (unsigned long) val + 8 > 16)
|
||||||
einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
|
einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
|
||||||
params.plt_stub_align = val;
|
params.plt_stub_align = val;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user