aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-04-09 09:32:39 +0930
committerAlan Modra <amodra@gmail.com>2018-04-09 17:40:54 +0930
commit3e04d7655bf63f4e5a0d0354c21aa3fa2ece3681 (patch)
treec79cf2877a3db9fcf0c1aa2cd21bd963da6b7c96 /ld
parent23cedd1dc90d05c4b80d4a4b000ed5f37b9c3268 (diff)
downloadgdb-3e04d7655bf63f4e5a0d0354c21aa3fa2ece3681.zip
gdb-3e04d7655bf63f4e5a0d0354c21aa3fa2ece3681.tar.gz
gdb-3e04d7655bf63f4e5a0d0354c21aa3fa2ece3681.tar.bz2
Inline PLT call optimization
This patch adds the analysis part of PLT call optimization, enabling the code added with the previous patch that actually performs the optimization. Gold support is not available yet. bfd/ * elf64-ppc.c (struct _ppc64_elf_section_data): Add has_pltcall field. (struct ppc_link_hash_table): Add can_convert_all_inline_plt. (ppc64_elf_check_relocs): Set has_pltcall. (ppc64_elf_adjust_dynamic_symbol): Discard some PLT entries. (ppc64_elf_inline_plt): New function. (ppc64_elf_size_dynamic_sections): Discard some PLT entries for locals. * elf64-ppc.h (ppc64_elf_inline_plt): Declare. * elf32-ppc.c (has_pltcall): Define. (struct ppc_elf_link_hash_table): Add can_convert_all_inline_plt. (ppc_elf_check_relocs): Set has_pltcall. (ppc_elf_inline_plt): New function. (ppc_elf_adjust_dynamic_symbol): Discard some PLT entries. (ppc_elf_size_dynamic_sections): Likewise. * elf32-ppc.h (ppc_elf_inline_plt): Declare. ld/ * emultempl/ppc64elf.em (no_inline_plt): New var. (ppc_before_allocation): Call ppc64_elf_inline_plt. (enum ppc64_opt): Add OPTION_NO_INLINE_OPT. (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Handle --no-inline-optimize. * emultemps/ppc32elf.em (no_inline_opt): New var. (prelim_size_sections): New function, extracted from.. (ppc_before_allocation): ..here. Call ppc_elf_inline_plt. (enum ppc32_opt): Add OPTION_NO_INLINE_OPT. (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Handle --no-inline-optimize.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog14
-rw-r--r--ld/emultempl/ppc32elf.em42
-rw-r--r--ld/emultempl/ppc64elf.em21
3 files changed, 70 insertions, 7 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index df36735..209cad8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,19 @@
2018-04-09 Alan Modra <amodra@gmail.com>
+ * emultempl/ppc64elf.em (no_inline_plt): New var.
+ (ppc_before_allocation): Call ppc64_elf_inline_plt.
+ (enum ppc64_opt): Add OPTION_NO_INLINE_OPT.
+ (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS,
+ PARSE_AND_LIST_ARGS_CASES): Handle --no-inline-optimize.
+ * emultemps/ppc32elf.em (no_inline_opt): New var.
+ (prelim_size_sections): New function, extracted from..
+ (ppc_before_allocation): ..here. Call ppc_elf_inline_plt.
+ (enum ppc32_opt): Add OPTION_NO_INLINE_OPT.
+ (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS,
+ PARSE_AND_LIST_ARGS_CASES): Handle --no-inline-optimize.
+
+2018-04-09 Alan Modra <amodra@gmail.com>
+
* emulparams/elf32ppc.sh (OTHER_RELRO_SECTIONS_2): Add .branch_lt.
(OTHER_GOT_RELOC_SECTIONS): Add .rela.branch_lt.
* testsuite/ld-powerpc/elfv2so.d: Update for symbol/stub reordering.
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 05a2894..439f891 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -35,6 +35,9 @@ fragment <<EOF
/* Whether to run tls optimization. */
static int notlsopt = 0;
+/* Whether to convert inline PLT calls to direct. */
+static int no_inline_opt = 0;
+
/* Choose the correct place for .got. */
static int old_got = 0;
@@ -116,10 +119,32 @@ EOF
fi
fragment <<EOF
static void
+prelim_size_sections (void)
+{
+ if (expld.phase != lang_mark_phase_enum)
+ {
+ expld.phase = lang_mark_phase_enum;
+ expld.dataseg.phase = exp_seg_none;
+ one_lang_size_sections_pass (NULL, FALSE);
+ /* We must not cache anything from the preliminary sizing. */
+ lang_reset_memory_regions ();
+ }
+}
+
+static void
ppc_before_allocation (void)
{
if (is_ppc_elf (link_info.output_bfd))
{
+ if (!no_inline_opt
+ && !bfd_link_relocatable (&link_info))
+ {
+ prelim_size_sections ();
+
+ if (!ppc_elf_inline_plt (&link_info))
+ einfo (_("%X%P: inline PLT: %E\n"));
+ }
+
if (ppc_elf_tls_setup (link_info.output_bfd, &link_info)
&& !notlsopt)
{
@@ -147,13 +172,7 @@ ppc_before_allocation (void)
asection *o;
/* Run lang_size_sections (if not already done). */
- if (expld.phase != lang_mark_phase_enum)
- {
- expld.phase = lang_mark_phase_enum;
- expld.dataseg.phase = exp_seg_none;
- one_lang_size_sections_pass (NULL, FALSE);
- lang_reset_memory_regions ();
- }
+ prelim_size_sections ();
for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
{
@@ -250,6 +269,7 @@ enum ppc32_opt
OPTION_OLD_PLT,
OPTION_PLT_ALIGN,
OPTION_NO_PLT_ALIGN,
+ OPTION_NO_INLINE_OPT,
OPTION_OLD_GOT,
OPTION_STUBSYMS,
OPTION_NO_STUBSYMS,
@@ -271,6 +291,7 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
{ "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
+ { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
fi
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
@@ -308,6 +329,9 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
--no-plt-align Dont'\''t align individual PLT call stubs\n"
));
fprintf (file, _("\
+ --no-inline-optimize Don'\''t convert inline PLT to direct calls\n"
+ ));
+ fprintf (file, _("\
--sdata-got Force GOT location just before .sdata\n"
));'
fi
@@ -369,6 +393,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
params.plt_stub_align = 0;
break;
+ case OPTION_NO_INLINE_OPT:
+ no_inline_opt = 1;
+ break;
+
case OPTION_OLD_GOT:
old_got = 1;
break;
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 62c298c..60bc8bd 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -55,6 +55,9 @@ static int no_tls_opt = 0;
/* Whether to run opd optimization. */
static int no_opd_opt = 0;
+/* Whether to convert inline PLT calls to direct. */
+static int no_inline_opt = 0;
+
/* Whether to run toc optimization. */
static int no_toc_opt = 0;
@@ -282,6 +285,15 @@ ppc_before_allocation (void)
&& !ppc64_elf_edit_opd (&link_info))
einfo (_("%X%P: can not edit %s: %E\n"), "opd");
+ if (!no_inline_opt
+ && !bfd_link_relocatable (&link_info))
+ {
+ prelim_size_sections ();
+
+ if (!ppc64_elf_inline_plt (&link_info))
+ einfo (_("%X%P: inline PLT: %E\n"));
+ }
+
if (ppc64_elf_tls_setup (&link_info)
&& !no_tls_opt)
{
@@ -706,6 +718,7 @@ enum ppc64_opt
OPTION_TLS_GET_ADDR_OPT,
OPTION_NO_TLS_GET_ADDR_OPT,
OPTION_NO_OPD_OPT,
+ OPTION_NO_INLINE_OPT,
OPTION_NO_TOC_OPT,
OPTION_NO_MULTI_TOC,
OPTION_NO_TOC_SORT,
@@ -733,6 +746,7 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "tls-get-addr-optimize", no_argument, NULL, OPTION_TLS_GET_ADDR_OPT },
{ "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
{ "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
+ { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
{ "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
{ "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
{ "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
@@ -810,6 +824,9 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
--no-opd-optimize Don'\''t optimize the OPD section\n"
));
fprintf (file, _("\
+ --no-inline-optimize Don'\''t convert inline PLT to direct calls\n"
+ ));
+ fprintf (file, _("\
--no-toc-optimize Don'\''t optimize the TOC section\n"
));
fprintf (file, _("\
@@ -915,6 +932,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
no_opd_opt = 1;
break;
+ case OPTION_NO_INLINE_OPT:
+ no_inline_opt = 1;
+ break;
+
case OPTION_NO_TOC_OPT:
no_toc_opt = 1;
break;