+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc_stub_type): Add ppc_stub_global_entry.
+ (struct ppc_link_hash_table): Increase size of stub_count array.
+ (build_global_entry_stubs): Emit symbol on global entry stub.
+ (ppc64_elf_build_stubs): NULL check htab->brlt. Add global entry
+ stub stats.
+
2014-07-01 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (abiversion, set_abiversion): Move earlier.
ppc_stub_plt_branch,
ppc_stub_plt_branch_r2off,
ppc_stub_plt_call,
- ppc_stub_plt_call_r2save
+ ppc_stub_plt_call_r2save,
+ ppc_stub_global_entry
};
struct ppc_stub_hash_entry {
bfd_size_type got_reli_size;
/* Statistics. */
- unsigned long stub_count[ppc_stub_plt_call_r2save];
+ unsigned long stub_count[ppc_stub_global_entry];
/* Number of stubs against global syms. */
unsigned long stub_globals;
htab->stub_error = TRUE;
}
+ htab->stub_count[ppc_stub_global_entry - 1] += 1;
+ if (htab->params->emit_stub_syms)
+ {
+ size_t len = strlen (h->root.root.string);
+ char *name = bfd_malloc (sizeof "12345678.global_entry." + len);
+
+ if (name == NULL)
+ return FALSE;
+
+ sprintf (name, "%08x.global_entry.%s", s->id, h->root.root.string);
+ h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
+ if (h == NULL)
+ return FALSE;
+ if (h->root.type == bfd_link_hash_new)
+ {
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = s;
+ h->root.u.def.value = p - s->contents;
+ h->ref_regular = 1;
+ h->def_regular = 1;
+ h->ref_regular_nonweak = 1;
+ h->forced_local = 1;
+ h->non_elf = 0;
+ }
+ }
+
if (PPC_HA (off) != 0)
{
bfd_put_32 (s->owner, ADDIS_R12_R12 | PPC_HA (off), p);
elf_link_hash_traverse (&htab->elf, build_global_entry_stubs, info);
}
- if (htab->brlt->size != 0)
+ if (htab->brlt != NULL && htab->brlt->size != 0)
{
htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
htab->brlt->size);
" long branch %lu\n"
" long toc adj %lu\n"
" plt call %lu\n"
- " plt call toc %lu"),
+ " plt call toc %lu\n"
+ " global entry %lu"),
stub_sec_count,
stub_sec_count == 1 ? "" : "s",
htab->stub_count[ppc_stub_long_branch - 1],
htab->stub_count[ppc_stub_plt_branch - 1],
htab->stub_count[ppc_stub_plt_branch_r2off - 1],
htab->stub_count[ppc_stub_plt_call - 1],
- htab->stub_count[ppc_stub_plt_call_r2save - 1]);
+ htab->stub_count[ppc_stub_plt_call_r2save - 1],
+ htab->stub_count[ppc_stub_global_entry - 1]);
}
return TRUE;
}
+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * emultempl/ppc64elf.em (stub_added): Delete.
+ (gld${EMULATION_NAME}_finish): Call ppc64_elf_build_stubs even when
+ none of the usual stubs have been added. Only change entry_section
+ for ELFv1.
+
2014-07-01 Alan Modra <amodra@gmail.com>
* sysdep.h: Don't include limits.h and sys/param.h. Don't
#include "elf-bfd.h"
#include "elf64-ppc.h"
#include "ldlex.h"
+#include "elf/ppc64.h"
static asection *ppc_add_stub_section (const char *, asection *);
static void ppc_layout_sections_again (void);
/* Fake input file for stubs. */
static lang_input_statement_type *stub_file;
-static int stub_added = 0;
/* Whether we need to call ppc_layout_sections_again. */
static int need_laying_out = 0;
if (info.add.head == NULL)
goto err_ret;
- stub_added = 1;
if (hook_in_stub (&info, &os->children.head))
return stub_sec;
static void
gld${EMULATION_NAME}_finish (void)
{
+ char *msg = NULL;
+ char *line, *endline;
+
/* e_entry on PowerPC64 points to the function descriptor for
_start. If _start is missing, default to the first function
descriptor in the .opd section. */
- entry_section = ".opd";
-
- if (stub_added)
+ if ((elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
+ entry_section = ".opd";
+
+ if (params.emit_stub_syms < 0)
+ params.emit_stub_syms = 1;
+ if (stub_file != NULL
+ && !link_info.relocatable
+ && !ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
+ einfo ("%X%P: can not build stubs: %E\n");
+
+ fflush (stdout);
+ for (line = msg; line != NULL; line = endline)
{
- char *msg = NULL;
- char *line, *endline;
-
- if (params.emit_stub_syms < 0)
- params.emit_stub_syms = 1;
- if (!ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
- einfo ("%X%P: can not build stubs: %E\n");
-
- fflush (stdout);
- for (line = msg; line != NULL; line = endline)
- {
- endline = strchr (line, '\n');
- if (endline != NULL)
- *endline++ = '\0';
- fprintf (stderr, "%s: %s\n", program_name, line);
- }
- fflush (stderr);
- if (msg != NULL)
- free (msg);
+ endline = strchr (line, '\n');
+ if (endline != NULL)
+ *endline++ = '\0';
+ fprintf (stderr, "%s: %s\n", program_name, line);
}
+ fflush (stderr);
+ if (msg != NULL)
+ free (msg);
ppc64_elf_restore_symbols (&link_info);
finish_default ();