}
else
{
- prpsinfo_t data;
+ prpsinfo64_t data;
memset (&data, 0, sizeof (data));
strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
}
else
{
- prstatus_t prstat;
+ prstatus64_t prstat;
memset (&prstat, 0, sizeof (prstat));
prstat.pr_pid = pid;
prstat.pr_cursig = cursig;
break;
}
- /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
- it here if it is defined in a non-shared object. */
- if (h->type == STT_GNU_IFUNC
- && h->def_regular)
- {
- /* It is referenced by a non-shared object. */
- h->ref_regular = 1;
- h->needs_plt = 1;
-
- /* STT_GNU_IFUNC symbol must go through PLT. */
- h->plt.refcount += 1;
-
- /* STT_GNU_IFUNC needs dynamic sections. */
- if (htab->elf.dynobj == NULL)
- htab->elf.dynobj = abfd;
-
- switch (r_type)
- {
- default:
- if (h->root.root.string)
- name = h->root.root.string;
- else
- name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
- NULL);
- (*_bfd_error_handler)
- (_("%B: relocation %s against STT_GNU_IFUNC "
- "symbol `%s' isn't handled by %s"), abfd,
- x86_64_elf_howto_table[r_type].name,
- name, __FUNCTION__);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
-
- case R_X86_64_32:
- if (ABI_64_P (abfd))
- goto not_pointer;
- case R_X86_64_64:
- h->non_got_ref = 1;
- h->pointer_equality_needed = 1;
- if (info->shared)
- {
- /* We must copy these reloc types into the output
- file. Create a reloc section in dynobj and
- make room for this reloc. */
- sreloc = _bfd_elf_create_ifunc_dyn_reloc
- (abfd, info, sec, sreloc,
- &((struct elf_x86_64_link_hash_entry *) h)->dyn_relocs);
- if (sreloc == NULL)
- return FALSE;
- }
- break;
-
- case R_X86_64_32S:
- case R_X86_64_PC32:
- case R_X86_64_PC64:
-not_pointer:
- h->non_got_ref = 1;
- if (r_type != R_X86_64_PC32
- && r_type != R_X86_64_PC64)
- h->pointer_equality_needed = 1;
- break;
-
- case R_X86_64_PLT32:
- break;
-
- case R_X86_64_GOTPCREL:
- case R_X86_64_GOTPCREL64:
- h->got.refcount += 1;
- if (htab->elf.sgot == NULL
- && !_bfd_elf_create_got_section (htab->elf.dynobj,
- info))
- return FALSE;
- break;
- }
-
- continue;
- }
+ /* It is referenced by a non-shared object. */
+ h->ref_regular = 1;
}
if (! elf_x86_64_tls_transition (info, abfd, sec, NULL,
{
struct elf_x86_64_link_hash_table *htab;
asection *s;
+ struct elf_x86_64_link_hash_entry *eh;
+ struct elf_dyn_relocs *p;
/* STT_GNU_IFUNC symbol must go through PLT. */
if (h->type == STT_GNU_IFUNC)
{
+ /* All local STT_GNU_IFUNC references must be treate as local
+ calls via local PLT. */
+ if (h->ref_regular
+ && SYMBOL_CALLS_LOCAL (info, h))
+ {
+ bfd_size_type pc_count = 0, count = 0;
+ struct elf_dyn_relocs **pp;
+
+ eh = (struct elf_x86_64_link_hash_entry *) h;
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ pc_count += p->pc_count;
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ count += p->count;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+
+ if (pc_count || count)
+ {
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ h->non_got_ref = 1;
+ }
+ }
+
if (h->plt.refcount <= 0)
{
h->plt.offset = (bfd_vma) -1;
if (ELIMINATE_COPY_RELOCS)
{
- struct elf_x86_64_link_hash_entry * eh;
- struct elf_dyn_relocs *p;
-
eh = (struct elf_x86_64_link_hash_entry *) h;
for (p = eh->dyn_relocs; p != NULL; p = p->next)
{