Add symbols for global entry stub, and report stats
The undefined function symbols (with non-zero value) on global entry stubs are discarded by objdump when disassembling, so give objdump another symbol to mark the stubs. Also fixes a couple of bugs: - entry_section was set to .opd for ELFv2, which meant a hard error rather than a warning when _start wasn't defined. - global entry stubs were not built if they were the only type of stub in an executable. bfd/ * 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. ld/ * 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.
This commit is contained in:
parent
2dc0e7b400
commit
7341d5e22f
|
@ -1,3 +1,11 @@
|
|||
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.
|
||||
|
|
|
@ -3785,7 +3785,8 @@ enum ppc_stub_type {
|
|||
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 {
|
||||
|
@ -3959,7 +3960,7 @@ struct ppc_link_hash_table
|
|||
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;
|
||||
|
@ -12491,6 +12492,32 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf)
|
|||
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);
|
||||
|
@ -12669,7 +12696,7 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
|
|||
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);
|
||||
|
@ -12843,7 +12870,8 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
|
|||
" 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],
|
||||
|
@ -12851,7 +12879,8 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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
|
||||
|
|
|
@ -29,6 +29,7 @@ fragment <<EOF
|
|||
#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);
|
||||
|
@ -42,7 +43,6 @@ static struct ppc64_elf_params params = { NULL,
|
|||
|
||||
/* 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;
|
||||
|
@ -390,7 +390,6 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
|
|||
if (info.add.head == NULL)
|
||||
goto err_ret;
|
||||
|
||||
stub_added = 1;
|
||||
if (hook_in_stub (&info, &os->children.head))
|
||||
return stub_sec;
|
||||
|
||||
|
@ -518,33 +517,33 @@ gld${EMULATION_NAME}_after_allocation (void)
|
|||
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 ((elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
|
||||
entry_section = ".opd";
|
||||
|
||||
if (stub_added)
|
||||
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 ();
|
||||
|
|
Loading…
Reference in New Issue