* elf32-arm.h (struct elf32_arm_relocs_copied): Remove pc_count.
(elf32_arm_copy_indirect_symbol): Don't copy pc_count. (elf32_arm_final_link_relocate): Handle PLT32 and PC24 relocs identically. Do not emit PC24 relocations for shared libraries. (elf32_arm_gc_sweep_hook): Handle PLT32 and PC24 relocs identically. Don't adjust pc_count. (elf32_arm_check_relocs): Handle PLT32 and PC24 relocs identically. Set ELF_LINK_HASH_NEEDS_PLT for both. Don't adjust pc_count; don't adjust count for branch relocations. (allocate_dynrelocs): Correct typo in call to WILL_CALL_FINISH_DYNAMIC_SYMBOL. Never allocate space for PC24 or PLT32 relocs when linking.
This commit is contained in:
parent
c787b88946
commit
7359ea6525
|
@ -1,3 +1,18 @@
|
||||||
|
2004-01-09 Daniel Jacobowitz <drow@mvista.com>
|
||||||
|
|
||||||
|
* elf32-arm.h (struct elf32_arm_relocs_copied): Remove pc_count.
|
||||||
|
(elf32_arm_copy_indirect_symbol): Don't copy pc_count.
|
||||||
|
(elf32_arm_final_link_relocate): Handle PLT32 and PC24 relocs
|
||||||
|
identically. Do not emit PC24 relocations for shared libraries.
|
||||||
|
(elf32_arm_gc_sweep_hook): Handle PLT32 and PC24 relocs
|
||||||
|
identically. Don't adjust pc_count.
|
||||||
|
(elf32_arm_check_relocs): Handle PLT32 and PC24 relocs identically.
|
||||||
|
Set ELF_LINK_HASH_NEEDS_PLT for both. Don't adjust pc_count; don't
|
||||||
|
adjust count for branch relocations.
|
||||||
|
(allocate_dynrelocs): Correct typo in call to
|
||||||
|
WILL_CALL_FINISH_DYNAMIC_SYMBOL. Never allocate space for
|
||||||
|
PC24 or PLT32 relocs when linking.
|
||||||
|
|
||||||
2004-01-09 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
|
2004-01-09 Dmitry Semyonov <Dmitry.Semyonov@oktet.ru>
|
||||||
|
|
||||||
* coff-arm.c (aoutarm_std_reloc_howto): [ARM_WINCE] Synchronize ARM_26D
|
* coff-arm.c (aoutarm_std_reloc_howto): [ARM_WINCE] Synchronize ARM_26D
|
||||||
|
|
144
bfd/elf32-arm.h
144
bfd/elf32-arm.h
|
@ -205,8 +205,6 @@ struct elf32_arm_relocs_copied
|
||||||
asection * section;
|
asection * section;
|
||||||
/* Number of relocs copied in this section. */
|
/* Number of relocs copied in this section. */
|
||||||
bfd_size_type count;
|
bfd_size_type count;
|
||||||
/* Number of relocs copied in this section. */
|
|
||||||
bfd_size_type pc_count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Arm ELF linker hash entry. */
|
/* Arm ELF linker hash entry. */
|
||||||
|
@ -383,7 +381,6 @@ elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
|
||||||
for (q = edir->relocs_copied; q != NULL; q = q->next)
|
for (q = edir->relocs_copied; q != NULL; q = q->next)
|
||||||
if (q->section == p->section)
|
if (q->section == p->section)
|
||||||
{
|
{
|
||||||
q->pc_count += p->pc_count;
|
|
||||||
q->count += p->count;
|
q->count += p->count;
|
||||||
*pp = p->next;
|
*pp = p->next;
|
||||||
break;
|
break;
|
||||||
|
@ -1307,21 +1304,41 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
#ifndef OLD_ARM_ABI
|
#ifndef OLD_ARM_ABI
|
||||||
case R_ARM_XPC25:
|
case R_ARM_XPC25:
|
||||||
#endif
|
#endif
|
||||||
|
case R_ARM_PLT32:
|
||||||
/* r_symndx will be zero only for relocs against symbols
|
/* r_symndx will be zero only for relocs against symbols
|
||||||
from removed linkonce sections, or sections discarded by
|
from removed linkonce sections, or sections discarded by
|
||||||
a linker script. */
|
a linker script. */
|
||||||
if (r_symndx == 0)
|
if (r_symndx == 0)
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
|
/* Handle relocations which should use the PLT entry. ABS32/REL32
|
||||||
|
will use the symbol's value, which may point to a PLT entry, but we
|
||||||
|
don't need to handle that here. If we created a PLT entry, all
|
||||||
|
branches in this object should go to it. */
|
||||||
|
if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
|
||||||
|
&& h != NULL
|
||||||
|
&& h->plt.offset != (bfd_vma) -1)
|
||||||
|
{
|
||||||
|
BFD_ASSERT (splt != NULL);
|
||||||
|
BFD_ASSERT (!SYMBOL_CALLS_LOCAL (info, h));
|
||||||
|
|
||||||
|
value = (splt->output_section->vma
|
||||||
|
+ splt->output_offset
|
||||||
|
+ h->plt.offset);
|
||||||
|
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||||
|
contents, rel->r_offset, value,
|
||||||
|
(bfd_vma) 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* When generating a shared object, these relocations are copied
|
/* When generating a shared object, these relocations are copied
|
||||||
into the output file to be resolved at run time. */
|
into the output file to be resolved at run time. */
|
||||||
if ((info->shared
|
if (info->shared
|
||||||
&& (input_section->flags & SEC_ALLOC)
|
&& (input_section->flags & SEC_ALLOC)
|
||||||
&& (h == NULL
|
&& (h == NULL
|
||||||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||||
|| h->root.type != bfd_link_hash_undefweak)
|
|| h->root.type != bfd_link_hash_undefweak)
|
||||||
&& (r_type != R_ARM_PC24
|
&& r_type != R_ARM_PC24
|
||||||
|| !SYMBOL_CALLS_LOCAL (info, h))))
|
&& r_type != R_ARM_PLT32)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela outrel;
|
Elf_Internal_Rela outrel;
|
||||||
bfd_byte *loc;
|
bfd_byte *loc;
|
||||||
|
@ -1364,8 +1381,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
memset (&outrel, 0, sizeof outrel);
|
memset (&outrel, 0, sizeof outrel);
|
||||||
else if (h != NULL
|
else if (h != NULL
|
||||||
&& h->dynindx != -1
|
&& h->dynindx != -1
|
||||||
&& (r_type == R_ARM_PC24
|
&& (!info->shared
|
||||||
|| !info->shared
|
|
||||||
|| !info->symbolic
|
|| !info->symbolic
|
||||||
|| (h->elf_link_hash_flags
|
|| (h->elf_link_hash_flags
|
||||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||||
|
@ -1397,6 +1413,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
case R_ARM_XPC25: /* Arm BLX instruction. */
|
case R_ARM_XPC25: /* Arm BLX instruction. */
|
||||||
#endif
|
#endif
|
||||||
case R_ARM_PC24: /* Arm B/BL instruction */
|
case R_ARM_PC24: /* Arm B/BL instruction */
|
||||||
|
case R_ARM_PLT32:
|
||||||
#ifndef OLD_ARM_ABI
|
#ifndef OLD_ARM_ABI
|
||||||
if (r_type == R_ARM_XPC25)
|
if (r_type == R_ARM_XPC25)
|
||||||
{
|
{
|
||||||
|
@ -1869,37 +1886,6 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
contents, rel->r_offset, value,
|
contents, rel->r_offset, value,
|
||||||
(bfd_vma) 0);
|
(bfd_vma) 0);
|
||||||
|
|
||||||
case R_ARM_PLT32:
|
|
||||||
/* Relocation is to the entry for this symbol in the
|
|
||||||
procedure linkage table. */
|
|
||||||
|
|
||||||
/* Resolve a PLT32 reloc against a local symbol directly,
|
|
||||||
without using the procedure linkage table. */
|
|
||||||
if (h == NULL)
|
|
||||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
|
||||||
contents, rel->r_offset, value,
|
|
||||||
(bfd_vma) 0);
|
|
||||||
|
|
||||||
if (h->plt.offset == (bfd_vma) -1
|
|
||||||
|| globals->splt == NULL)
|
|
||||||
/* We didn't make a PLT entry for this symbol. This
|
|
||||||
happens when statically linking PIC code, or when
|
|
||||||
using -Bsymbolic. */
|
|
||||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
|
||||||
contents, rel->r_offset, value,
|
|
||||||
(bfd_vma) 0);
|
|
||||||
|
|
||||||
BFD_ASSERT(splt != NULL);
|
|
||||||
if (splt == NULL)
|
|
||||||
return bfd_reloc_notsupported;
|
|
||||||
|
|
||||||
value = (splt->output_section->vma
|
|
||||||
+ splt->output_offset
|
|
||||||
+ h->plt.offset);
|
|
||||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
|
||||||
contents, rel->r_offset, value,
|
|
||||||
(bfd_vma) 0);
|
|
||||||
|
|
||||||
case R_ARM_SBREL32:
|
case R_ARM_SBREL32:
|
||||||
return bfd_reloc_notsupported;
|
return bfd_reloc_notsupported;
|
||||||
|
|
||||||
|
@ -2808,6 +2794,7 @@ elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
case R_ARM_REL32:
|
case R_ARM_REL32:
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
|
case R_ARM_PLT32:
|
||||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||||
if (r_symndx >= symtab_hdr->sh_info)
|
if (r_symndx >= symtab_hdr->sh_info)
|
||||||
{
|
{
|
||||||
|
@ -2817,31 +2804,24 @@ elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
|
||||||
|
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
|
|
||||||
if (!info->shared && h->plt.refcount > 0)
|
if (h->plt.refcount > 0)
|
||||||
h->plt.refcount -= 1;
|
h->plt.refcount -= 1;
|
||||||
|
|
||||||
|
if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
|
||||||
|
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
|
||||||
|
{
|
||||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||||
|
|
||||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL; pp = &p->next)
|
for (pp = &eh->relocs_copied; (p = *pp) != NULL;
|
||||||
|
pp = &p->next)
|
||||||
if (p->section == sec)
|
if (p->section == sec)
|
||||||
{
|
{
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)
|
|
||||||
p->pc_count -= 1;
|
|
||||||
p->count -= 1;
|
p->count -= 1;
|
||||||
if (p->count == 0)
|
if (p->count == 0)
|
||||||
*pp = p->next;
|
*pp = p->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case R_ARM_PLT32:
|
|
||||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
|
||||||
if (r_symndx >= symtab_hdr->sh_info)
|
|
||||||
{
|
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
|
||||||
if (h->plt.refcount > 0)
|
|
||||||
h->plt.refcount -= 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2902,23 +2882,6 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
|
|
||||||
switch (ELF32_R_TYPE (rel->r_info))
|
switch (ELF32_R_TYPE (rel->r_info))
|
||||||
{
|
{
|
||||||
case R_ARM_PLT32:
|
|
||||||
/* This symbol requires a procedure linkage table entry. We
|
|
||||||
actually build the entry in adjust_dynamic_symbol,
|
|
||||||
because this might be a case of linking PIC code which is
|
|
||||||
never referenced by a dynamic object, in which case we
|
|
||||||
don't need to generate a procedure linkage table entry
|
|
||||||
after all. */
|
|
||||||
|
|
||||||
/* If this is a local symbol, we resolve it directly without
|
|
||||||
creating a procedure linkage table entry. */
|
|
||||||
if (h == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
|
|
||||||
h->plt.refcount++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_ARM_GOT32:
|
case R_ARM_GOT32:
|
||||||
/* This symbol requires a global offset table entry. */
|
/* This symbol requires a global offset table entry. */
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
|
@ -2961,7 +2924,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
case R_ARM_REL32:
|
case R_ARM_REL32:
|
||||||
case R_ARM_PC24:
|
case R_ARM_PC24:
|
||||||
if (h != NULL && !info->shared)
|
case R_ARM_PLT32:
|
||||||
|
if (h != NULL)
|
||||||
{
|
{
|
||||||
/* If this reloc is in a read-only section, we might
|
/* If this reloc is in a read-only section, we might
|
||||||
need a copy reloc. We can't check reliably at this
|
need a copy reloc. We can't check reliably at this
|
||||||
|
@ -2969,10 +2933,15 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
sections have not yet been mapped to output sections.
|
sections have not yet been mapped to output sections.
|
||||||
Tentatively set the flag for now, and correct in
|
Tentatively set the flag for now, and correct in
|
||||||
adjust_dynamic_symbol. */
|
adjust_dynamic_symbol. */
|
||||||
|
if (!info->shared)
|
||||||
h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
|
h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
|
||||||
|
|
||||||
/* We may need a .plt entry if the function this reloc
|
/* We may need a .plt entry if the function this reloc
|
||||||
refers to is in a shared lib. */
|
refers to is in a different object. */
|
||||||
|
if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24
|
||||||
|
|| ELF32_R_TYPE (rel->r_info) == R_ARM_PLT32)
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
|
||||||
|
|
||||||
h->plt.refcount += 1;
|
h->plt.refcount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2990,7 +2959,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
relocs_copied field of the hash table entry. */
|
relocs_copied field of the hash table entry. */
|
||||||
if (info->shared
|
if (info->shared
|
||||||
&& (sec->flags & SEC_ALLOC) != 0
|
&& (sec->flags & SEC_ALLOC) != 0
|
||||||
&& (ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
|
&& ((ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
|
||||||
|
&& ELF32_R_TYPE (rel->r_info) != R_ARM_PLT32)
|
||||||
|| (h != NULL
|
|| (h != NULL
|
||||||
&& (! info->symbolic
|
&& (! info->symbolic
|
||||||
|| (h->elf_link_hash_flags
|
|| (h->elf_link_hash_flags
|
||||||
|
@ -3068,12 +3038,11 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
*head = p;
|
*head = p;
|
||||||
p->section = sec;
|
p->section = sec;
|
||||||
p->count = 0;
|
p->count = 0;
|
||||||
p->pc_count = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
|
||||||
|
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
|
||||||
p->count += 1;
|
p->count += 1;
|
||||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24)
|
|
||||||
p->pc_count += 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3348,7 +3317,7 @@ allocate_dynrelocs (h, inf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->shared
|
if (info->shared
|
||||||
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
|
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
|
||||||
{
|
{
|
||||||
asection *s = htab->splt;
|
asection *s = htab->splt;
|
||||||
|
|
||||||
|
@ -3432,28 +3401,7 @@ allocate_dynrelocs (h, inf)
|
||||||
|
|
||||||
if (info->shared)
|
if (info->shared)
|
||||||
{
|
{
|
||||||
/* The only reloc that uses pc_count is R_ARM_PC24, which will
|
/* Discard relocs on undefined weak syms with non-default
|
||||||
appear on a call or on something like ".long foo - .". We
|
|
||||||
want calls to protected symbols to resolve directly to the
|
|
||||||
function rather than going via the plt. If people want
|
|
||||||
function pointer comparisons to work as expected then they
|
|
||||||
should avoid writing assembly like ".long foo - .". */
|
|
||||||
if (SYMBOL_CALLS_LOCAL (info, h))
|
|
||||||
{
|
|
||||||
struct elf32_arm_relocs_copied **pp;
|
|
||||||
|
|
||||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL; )
|
|
||||||
{
|
|
||||||
p->count -= p->pc_count;
|
|
||||||
p->pc_count = 0;
|
|
||||||
if (p->count == 0)
|
|
||||||
*pp = p->next;
|
|
||||||
else
|
|
||||||
pp = &p->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Also discard relocs on undefined weak syms with non-default
|
|
||||||
visibility. */
|
visibility. */
|
||||||
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
|
||||||
&& h->root.type == bfd_link_hash_undefweak)
|
&& h->root.type == bfd_link_hash_undefweak)
|
||||||
|
|
Loading…
Reference in New Issue