aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-ppc.c7
-rw-r--r--bfd/elf64-ppc.c15
-rw-r--r--gold/ChangeLog8
-rw-r--r--gold/powerpc.cc19
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/emultempl/ppc32elf.em13
-rw-r--r--ld/emultempl/ppc64elf.em4
8 files changed, 58 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f1c5c41..3c8fcf3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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>
* po/ru.po: Updated Russian translation.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 73701d4..32104a1 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -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);
asection *s;
flagword flags;
+ int p2align;
flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
s = bfd_make_section_anyway_with_flags (abfd, ".glink", flags);
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
- || !bfd_set_section_alignment (abfd, s,
- htab->params->ppc476_workaround ? 6 : 4))
+ || !bfd_set_section_alignment (abfd, s, p2align))
return FALSE;
if (!info->no_ld_generated_unwind_info)
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 65cf7fe..b2d288b 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -12743,9 +12743,11 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
if (htab->params->plt_stub_align != 0)
for (group = htab->group; group != NULL; group = group->next)
if (group->stub_sec != NULL)
- group->stub_sec->size = ((group->stub_sec->size
- + (1 << htab->params->plt_stub_align) - 1)
- & -(1 << htab->params->plt_stub_align));
+ {
+ int align = abs (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)
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)
for (group = htab->group; group != NULL; group = group->next)
if ((stub_sec = group->stub_sec) != NULL)
- stub_sec->size = ((stub_sec->size
- + (1 << htab->params->plt_stub_align) - 1)
- & -(1 << htab->params->plt_stub_align));
+ {
+ int align = abs (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)
if ((stub_sec = group->stub_sec) != NULL)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index ec56a89..b833a7b 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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>
* options.h (speculate_indirect_jumps): New option.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 6b65792..3c38a06 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -4186,6 +4186,15 @@ output_bctr(unsigned char* 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.
// Stubs are built in an area following some input section determined
// 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
stub_align() const
{
- unsigned int min_align = 4;
- if (!parameters->options().user_set_plt_align())
- return size == 64 ? 32 : min_align;
+ unsigned int min_align = size == 64 ? 32 : 16;
unsigned int user_align = 1 << parameters->options().plt_align();
return std::max(user_align, min_align);
}
@@ -4483,7 +4490,7 @@ class Stub_table : public Output_relaxed_input_section
unsigned int
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;
}
@@ -4926,9 +4933,7 @@ class Output_data_glink : public Output_section_data
unsigned int
global_entry_align(unsigned int off) const
{
- unsigned int align = 1 << parameters->options().plt_align();
- if (!parameters->options().user_set_plt_align())
- align = size == 64 ? 32 : 4;
+ unsigned int align = param_plt_align<size>();
return (off + align - 1) & -align;
}
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 9ee555b..3801705 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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>
* emultempl/ppc32elf.em (params): Init new field.
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 4e71a78..3007fb2 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -271,7 +271,7 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
{ "speculate-indirect-jumps", no_argument, NULL, OPTION_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 },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
fi
@@ -369,7 +369,16 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
break;
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;
case OPTION_NO_PLT_ALIGN:
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index c7c27b0..0baa424 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -872,8 +872,8 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
if (optarg != NULL)
{
char *end;
- unsigned long val = strtoul (optarg, &end, 0);
- if (*end || val > 8)
+ long val = strtol (optarg, &end, 0);
+ if (*end || (unsigned long) val + 8 > 16)
einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
params.plt_stub_align = val;
}