(arm_add_to_rel): Fix R_ARM_THM_PC22 relocations.
This commit is contained in:
parent
5cc18311d9
commit
9a5aca8c9c
|
@ -1,3 +1,8 @@
|
||||||
|
2000-09-29 Momchil Velikov <velco@fadata.bg>
|
||||||
|
|
||||||
|
* elf32-arm.h (arm_add_to_rel): Correctly adjust the addend for
|
||||||
|
R_ARM_THM_PC22 relocations.
|
||||||
|
|
||||||
2000-09-29 NIIBE Yutaka <gniibe@chroot.org>
|
2000-09-29 NIIBE Yutaka <gniibe@chroot.org>
|
||||||
|
|
||||||
* elflink.h (elf_link_add_object_symbols): Don't bfd_release runpath.
|
* elflink.h (elf_link_add_object_symbols): Don't bfd_release runpath.
|
||||||
|
|
155
bfd/elf32-arm.h
155
bfd/elf32-arm.h
|
@ -544,7 +544,7 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
|
||||||
|| !bfd_set_section_flags (abfd, sec, flags)
|
|| !bfd_set_section_flags (abfd, sec, flags)
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|| !bfd_set_section_alignment (abfd, sec, 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Set the gc mark to prevent the section from being removed by garbage
|
/* Set the gc mark to prevent the section from being removed by garbage
|
||||||
collection, despite the fact that no relocs refer to this section. */
|
collection, despite the fact that no relocs refer to this section. */
|
||||||
sec->gc_mark = 1;
|
sec->gc_mark = 1;
|
||||||
|
@ -562,7 +562,7 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
|
||||||
|| !bfd_set_section_flags (abfd, sec, flags)
|
|| !bfd_set_section_flags (abfd, sec, flags)
|
||||||
|| !bfd_set_section_alignment (abfd, sec, 2))
|
|| !bfd_set_section_alignment (abfd, sec, 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
sec->gc_mark = 1;
|
sec->gc_mark = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,7 +724,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
if (free_relocs != NULL)
|
if (free_relocs != NULL)
|
||||||
free (free_relocs);
|
free (free_relocs);
|
||||||
|
@ -732,7 +732,7 @@ error_return:
|
||||||
free (free_contents);
|
free (free_contents);
|
||||||
if (free_extsyms != NULL)
|
if (free_extsyms != NULL)
|
||||||
free (free_extsyms);
|
free (free_extsyms);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +979,7 @@ elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
|
||||||
+ input_section->output_section->vma
|
+ input_section->output_section->vma
|
||||||
+ offset + addend)
|
+ offset + addend)
|
||||||
- 8;
|
- 8;
|
||||||
|
|
||||||
tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
|
tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
|
||||||
|
|
||||||
bfd_put_32 (output_bfd, tmp, hit_data
|
bfd_put_32 (output_bfd, tmp, hit_data
|
||||||
|
@ -1154,13 +1154,13 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
sreloc->contents)
|
sreloc->contents)
|
||||||
+ sreloc->reloc_count));
|
+ sreloc->reloc_count));
|
||||||
++sreloc->reloc_count;
|
++sreloc->reloc_count;
|
||||||
|
|
||||||
/* If this reloc is against an external symbol, we do not want to
|
/* If this reloc is against an external symbol, we do not want to
|
||||||
fiddle with the addend. Otherwise, we need to include the symbol
|
fiddle with the addend. Otherwise, we need to include the symbol
|
||||||
value so that it becomes an addend for the dynamic reloc. */
|
value so that it becomes an addend for the dynamic reloc. */
|
||||||
if (! relocate)
|
if (! relocate)
|
||||||
return bfd_reloc_ok;
|
return bfd_reloc_ok;
|
||||||
|
|
||||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||||
contents, rel->r_offset, value,
|
contents, rel->r_offset, value,
|
||||||
(bfd_vma) 0);
|
(bfd_vma) 0);
|
||||||
|
@ -1252,11 +1252,11 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
|
|
||||||
signed_addend = value;
|
signed_addend = value;
|
||||||
signed_addend >>= howto->rightshift;
|
signed_addend >>= howto->rightshift;
|
||||||
|
|
||||||
/* It is not an error for an undefined weak reference to be
|
/* It is not an error for an undefined weak reference to be
|
||||||
out of range. Any program that branches to such a symbol
|
out of range. Any program that branches to such a symbol
|
||||||
is going to crash anyway, so there is no point worrying
|
is going to crash anyway, so there is no point worrying
|
||||||
about getting the destination exactly right. */
|
about getting the destination exactly right. */
|
||||||
if (! h || h->root.type != bfd_link_hash_undefweak)
|
if (! h || h->root.type != bfd_link_hash_undefweak)
|
||||||
{
|
{
|
||||||
/* Perform a signed range check. */
|
/* Perform a signed range check. */
|
||||||
|
@ -1264,7 +1264,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
|| signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
|
|| signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
|
||||||
return bfd_reloc_overflow;
|
return bfd_reloc_overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef OLD_ARM_ABI
|
#ifndef OLD_ARM_ABI
|
||||||
/* If necessary set the H bit in the BLX instruction. */
|
/* If necessary set the H bit in the BLX instruction. */
|
||||||
if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
|
if (r_type == R_ARM_XPC25 && ((value & 2) == 2))
|
||||||
|
@ -1401,11 +1401,11 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
relocation -= (input_section->output_section->vma
|
relocation -= (input_section->output_section->vma
|
||||||
+ input_section->output_offset
|
+ input_section->output_offset
|
||||||
+ rel->r_offset);
|
+ rel->r_offset);
|
||||||
|
|
||||||
if (! globals->no_pipeline_knowledge)
|
if (! globals->no_pipeline_knowledge)
|
||||||
{
|
{
|
||||||
Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form. */
|
Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form. */
|
||||||
|
|
||||||
i_ehdrp = elf_elfheader (input_bfd);
|
i_ehdrp = elf_elfheader (input_bfd);
|
||||||
|
|
||||||
/* Previous versions of this code also used to add in the pipline
|
/* Previous versions of this code also used to add in the pipline
|
||||||
|
@ -1467,7 +1467,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
BFD_ASSERT (sgot != NULL);
|
BFD_ASSERT (sgot != NULL);
|
||||||
if (sgot == NULL)
|
if (sgot == NULL)
|
||||||
return bfd_reloc_notsupported;
|
return bfd_reloc_notsupported;
|
||||||
|
|
||||||
/* Note that sgot->output_offset is not involved in this
|
/* Note that sgot->output_offset is not involved in this
|
||||||
calculation. We always want the start of .got. If we
|
calculation. We always want the start of .got. If we
|
||||||
define _GLOBAL_OFFSET_TABLE in a different way, as is
|
define _GLOBAL_OFFSET_TABLE in a different way, as is
|
||||||
|
@ -1569,7 +1569,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
|
||||||
|
|
||||||
value = sgot->output_offset + off;
|
value = sgot->output_offset + off;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||||
contents, rel->r_offset, value,
|
contents, rel->r_offset, value,
|
||||||
(bfd_vma) 0);
|
(bfd_vma) 0);
|
||||||
|
@ -1642,44 +1642,67 @@ arm_add_to_rel (abfd, address, howto, increment)
|
||||||
reloc_howto_type * howto;
|
reloc_howto_type * howto;
|
||||||
bfd_signed_vma increment;
|
bfd_signed_vma increment;
|
||||||
{
|
{
|
||||||
bfd_vma contents;
|
|
||||||
bfd_signed_vma addend;
|
bfd_signed_vma addend;
|
||||||
|
|
||||||
contents = bfd_get_32 (abfd, address);
|
if (howto->type == R_ARM_THM_PC22)
|
||||||
|
|
||||||
/* Get the (signed) value from the instruction. */
|
|
||||||
addend = contents & howto->src_mask;
|
|
||||||
if (addend & ((howto->src_mask + 1) >> 1))
|
|
||||||
{
|
{
|
||||||
bfd_signed_vma mask;
|
int upper_insn, lower_insn;
|
||||||
|
int upper, lower;
|
||||||
mask = -1;
|
|
||||||
mask &= ~ howto->src_mask;
|
|
||||||
addend |= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add in the increment, (which is a byte value). */
|
upper_insn = bfd_get_16 (abfd, address);
|
||||||
switch (howto->type)
|
lower_insn = bfd_get_16 (abfd, address + 2);
|
||||||
{
|
upper = upper_insn & 0x7ff;
|
||||||
case R_ARM_THM_PC22:
|
lower = lower_insn & 0x7ff;
|
||||||
default:
|
|
||||||
|
addend = (upper << 12) | (lower << 1);
|
||||||
addend += increment;
|
addend += increment;
|
||||||
break;
|
addend >>= 1;
|
||||||
|
|
||||||
case R_ARM_PC24:
|
|
||||||
addend <<= howto->size;
|
|
||||||
addend += increment;
|
|
||||||
|
|
||||||
/* Should we check for overflow here ? */
|
|
||||||
|
|
||||||
/* Drop any undesired bits. */
|
upper_insn = (upper_insn & 0xf800) | ((addend >> 11) & 0x7ff);
|
||||||
addend >>= howto->rightshift;
|
lower_insn = (lower_insn & 0xf800) | (addend & 0x7ff);
|
||||||
break;
|
|
||||||
|
bfd_put_16 (abfd, upper_insn, address);
|
||||||
|
bfd_put_16 (abfd, lower_insn, address + 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bfd_vma contents;
|
||||||
|
|
||||||
|
contents = bfd_get_32 (abfd, address);
|
||||||
|
|
||||||
|
/* Get the (signed) value from the instruction. */
|
||||||
|
addend = contents & howto->src_mask;
|
||||||
|
if (addend & ((howto->src_mask + 1) >> 1))
|
||||||
|
{
|
||||||
|
bfd_signed_vma mask;
|
||||||
|
|
||||||
|
mask = -1;
|
||||||
|
mask &= ~ howto->src_mask;
|
||||||
|
addend |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add in the increment, (which is a byte value). */
|
||||||
|
switch (howto->type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
addend += increment;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_ARM_PC24:
|
||||||
|
addend <<= howto->size;
|
||||||
|
addend += increment;
|
||||||
|
|
||||||
|
/* Should we check for overflow here ? */
|
||||||
|
|
||||||
|
/* Drop any undesired bits. */
|
||||||
|
addend >>= howto->rightshift;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
|
||||||
|
|
||||||
|
bfd_put_32 (abfd, contents, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
|
|
||||||
|
|
||||||
bfd_put_32 (abfd, contents, address);
|
|
||||||
}
|
}
|
||||||
#endif /* USE_REL */
|
#endif /* USE_REL */
|
||||||
|
|
||||||
|
@ -2144,42 +2167,42 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
|
||||||
the EABI version is not set. */
|
the EABI version is not set. */
|
||||||
if (flags & EF_INTERWORK)
|
if (flags & EF_INTERWORK)
|
||||||
fprintf (file, _(" [interworking enabled]"));
|
fprintf (file, _(" [interworking enabled]"));
|
||||||
|
|
||||||
if (flags & EF_APCS_26)
|
if (flags & EF_APCS_26)
|
||||||
fprintf (file, _(" [APCS-26]"));
|
fprintf (file, _(" [APCS-26]"));
|
||||||
else
|
else
|
||||||
fprintf (file, _(" [APCS-32]"));
|
fprintf (file, _(" [APCS-32]"));
|
||||||
|
|
||||||
if (flags & EF_APCS_FLOAT)
|
if (flags & EF_APCS_FLOAT)
|
||||||
fprintf (file, _(" [floats passed in float registers]"));
|
fprintf (file, _(" [floats passed in float registers]"));
|
||||||
|
|
||||||
if (flags & EF_PIC)
|
if (flags & EF_PIC)
|
||||||
fprintf (file, _(" [position independent]"));
|
fprintf (file, _(" [position independent]"));
|
||||||
|
|
||||||
if (flags & EF_NEW_ABI)
|
if (flags & EF_NEW_ABI)
|
||||||
fprintf (file, _(" [new ABI]"));
|
fprintf (file, _(" [new ABI]"));
|
||||||
|
|
||||||
if (flags & EF_OLD_ABI)
|
if (flags & EF_OLD_ABI)
|
||||||
fprintf (file, _(" [old ABI]"));
|
fprintf (file, _(" [old ABI]"));
|
||||||
|
|
||||||
if (flags & EF_SOFT_FLOAT)
|
if (flags & EF_SOFT_FLOAT)
|
||||||
fprintf (file, _(" [software FP]"));
|
fprintf (file, _(" [software FP]"));
|
||||||
|
|
||||||
flags &= ~(EF_INTERWORK | EF_APCS_26 | EF_APCS_FLOAT | EF_PIC
|
flags &= ~(EF_INTERWORK | EF_APCS_26 | EF_APCS_FLOAT | EF_PIC
|
||||||
| EF_NEW_ABI | EF_OLD_ABI | EF_SOFT_FLOAT);
|
| EF_NEW_ABI | EF_OLD_ABI | EF_SOFT_FLOAT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EF_ARM_EABI_VER1:
|
case EF_ARM_EABI_VER1:
|
||||||
fprintf (file, _(" [Version1 EABI]"));
|
fprintf (file, _(" [Version1 EABI]"));
|
||||||
|
|
||||||
if (flags & EF_ARM_SYMSARESORTED)
|
if (flags & EF_ARM_SYMSARESORTED)
|
||||||
fprintf (file, _(" [sorted symbol table]"));
|
fprintf (file, _(" [sorted symbol table]"));
|
||||||
else
|
else
|
||||||
fprintf (file, _(" [unsorted symbol table]"));
|
fprintf (file, _(" [unsorted symbol table]"));
|
||||||
|
|
||||||
flags &= ~ EF_ARM_SYMSARESORTED;
|
flags &= ~ EF_ARM_SYMSARESORTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf (file, _(" <EABI version unrecognised>"));
|
fprintf (file, _(" <EABI version unrecognised>"));
|
||||||
break;
|
break;
|
||||||
|
@ -2197,7 +2220,7 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
fprintf (file, _("<Unrecognised flag bits set>"));
|
fprintf (file, _("<Unrecognised flag bits set>"));
|
||||||
|
|
||||||
fputc ('\n', file);
|
fputc ('\n', file);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2221,7 +2244,7 @@ elf32_arm_get_symbol_type (elf_sym, type)
|
||||||
if (type != STT_OBJECT)
|
if (type != STT_OBJECT)
|
||||||
return ELF_ST_TYPE (elf_sym->st_info);
|
return ELF_ST_TYPE (elf_sym->st_info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2303,12 +2326,12 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
bfd * dynobj;
|
bfd * dynobj;
|
||||||
asection * sgot, *srelgot, *sreloc;
|
asection * sgot, *srelgot, *sreloc;
|
||||||
bfd_vma * local_got_offsets;
|
bfd_vma * local_got_offsets;
|
||||||
|
|
||||||
if (info->relocateable)
|
if (info->relocateable)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
sgot = srelgot = sreloc = NULL;
|
sgot = srelgot = sreloc = NULL;
|
||||||
|
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
dynobj = elf_hash_table (info)->dynobj;
|
||||||
local_got_offsets = elf_local_got_offsets (abfd);
|
local_got_offsets = elf_local_got_offsets (abfd);
|
||||||
|
|
||||||
|
@ -2325,13 +2348,13 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
{
|
{
|
||||||
struct elf_link_hash_entry *h;
|
struct elf_link_hash_entry *h;
|
||||||
unsigned long r_symndx;
|
unsigned long r_symndx;
|
||||||
|
|
||||||
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)
|
||||||
h = NULL;
|
h = NULL;
|
||||||
else
|
else
|
||||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||||
|
|
||||||
/* Some relocs require a global offset table. */
|
/* Some relocs require a global offset table. */
|
||||||
if (dynobj == NULL)
|
if (dynobj == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2365,7 +2388,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
&& (h != NULL || info->shared))
|
&& (h != NULL || info->shared))
|
||||||
{
|
{
|
||||||
srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
|
srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
|
||||||
|
|
||||||
/* If no got relocation section, make one and initialize. */
|
/* If no got relocation section, make one and initialize. */
|
||||||
if (srelgot == NULL)
|
if (srelgot == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2550,7 +2573,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
|
||||||
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
|
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* This relocation describes which C++ vtable entries are actually
|
/* This relocation describes which C++ vtable entries are actually
|
||||||
used. Record for later use during GC. */
|
used. Record for later use during GC. */
|
||||||
case R_ARM_GNU_VTENTRY:
|
case R_ARM_GNU_VTENTRY:
|
||||||
|
@ -2930,7 +2953,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
|
||||||
outname = bfd_get_section_name (output_bfd,
|
outname = bfd_get_section_name (output_bfd,
|
||||||
s->output_section);
|
s->output_section);
|
||||||
target = bfd_get_section_by_name (output_bfd, outname + 4);
|
target = bfd_get_section_by_name (output_bfd, outname + 4);
|
||||||
|
|
||||||
if (target != NULL
|
if (target != NULL
|
||||||
&& (target->flags & SEC_READONLY) != 0
|
&& (target->flags & SEC_READONLY) != 0
|
||||||
&& (target->flags & SEC_ALLOC) != 0)
|
&& (target->flags & SEC_ALLOC) != 0)
|
||||||
|
|
Loading…
Reference in New Issue