summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Shinwell <shinwell@codesourcery.com>2006-08-30 17:39:17 +0000
committerMark Shinwell <shinwell@codesourcery.com>2006-08-30 17:39:17 +0000
commit81ecfae8c39bf0d348aefafff51395a26fb49fc5 (patch)
treeb43ebca2ffea8419c047c4b7a0978a2acd1fb3fc
parent082397387ad1b0faf7099e9d05db6d3b61b54007 (diff)
downloadgdb-81ecfae8c39bf0d348aefafff51395a26fb49fc5.tar.gz
bfd/
* elf32-arm.c (elf32_arm_final_link_relocate): Add support for R_ARM_MOVW_BREL_NC, R_ARM_MOVW_BREL, R_ARM_MOVT_BREL, R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVW_BREL and R_ARM_THM_MOVT_BREL relocations.
-rw-r--r--ChangeLog.csl8
-rw-r--r--bfd/elf32-arm.c39
2 files changed, 41 insertions, 6 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl
index 095990713eb..613242f3990 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,3 +1,11 @@
+2006-08-30 Mark Shinwell <shinwell@codesourcery.com>
+
+ bfd/
+ * elf32-arm.c (elf32_arm_final_link_relocate): Add support for
+ R_ARM_MOVW_BREL_NC, R_ARM_MOVW_BREL, R_ARM_MOVT_BREL,
+ R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVW_BREL and
+ R_ARM_THM_MOVT_BREL relocations.
+
2006-08-29 Nathan Sidwell <nathan@codesourcery.com>
* ldlang.c (walk_wild): Allow * to glob '/' in wildcarded match.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 9ae60fd88a1..5d45b6d3c83 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -4732,6 +4732,13 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case R_ARM_MOVT_ABS:
case R_ARM_MOVW_PREL_NC:
case R_ARM_MOVT_PREL:
+ /* Until we properly support segment-base-relative addressing then
+ we assume the segment base to be zero, as for the group relocations.
+ Thus R_ARM_MOVW_BREL_NC has the same semantics as R_ARM_MOVW_ABS_NC
+ and R_ARM_MOVT_BREL has the same semantics as R_ARM_MOVT_ABS. */
+ case R_ARM_MOVW_BREL_NC:
+ case R_ARM_MOVW_BREL:
+ case R_ARM_MOVT_BREL:
{
bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
@@ -4740,15 +4747,21 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
signed_addend = (addend ^ 0x10000) - 0x10000;
}
+
value += signed_addend;
- if (sym_flags == STT_ARM_TFUNC)
- value |= 1;
if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL)
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
- if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL)
+ if (r_type == R_ARM_MOVW_BREL && value >= 0x10000)
+ return bfd_reloc_overflow;
+
+ if (sym_flags == STT_ARM_TFUNC)
+ value |= 1;
+
+ if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL
+ || r_type == R_ARM_MOVT_BREL)
value >>= 16;
insn &= 0xfff0f000;
@@ -4762,6 +4775,14 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
case R_ARM_THM_MOVT_ABS:
case R_ARM_THM_MOVW_PREL_NC:
case R_ARM_THM_MOVT_PREL:
+ /* Until we properly support segment-base-relative addressing then
+ we assume the segment base to be zero, as for the above relocations.
+ Thus R_ARM_THM_MOVW_BREL_NC has the same semantics as
+ R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_BREL has the same semantics
+ as R_ARM_THM_MOVT_ABS. */
+ case R_ARM_THM_MOVW_BREL_NC:
+ case R_ARM_THM_MOVW_BREL:
+ case R_ARM_THM_MOVT_BREL:
{
bfd_vma insn;
@@ -4776,15 +4797,21 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
| (insn & 0x00ff);
signed_addend = (addend ^ 0x10000) - 0x10000;
}
+
value += signed_addend;
- if (sym_flags == STT_ARM_TFUNC)
- value |= 1;
if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL)
value -= (input_section->output_section->vma
+ input_section->output_offset + rel->r_offset);
- if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL)
+ if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000)
+ return bfd_reloc_overflow;
+
+ if (sym_flags == STT_ARM_TFUNC)
+ value |= 1;
+
+ if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL
+ || r_type == R_ARM_THM_MOVT_BREL)
value >>= 16;
insn &= 0xfbf08f00;