2008-03-07 Paul Brook <paul@codesourcery.com>
bfd/ * elf32-arm.c (elf32_arm_howto_table_1): Fix bitmasks for MOVW and MOVT relocations. (elf32_arm_final_link_relocate): Fix off by one MOVW/MOVT sign extension. (elf32_arm_relocate_section): Handle MOVW and MOVT relocations. Improve safety check for other weird relocations. (elf32_arm_check_relocs): Only set h->needs_plt for branch/call relocations. gas/ * config/tc-arm.c (md_apply_fix): Use correct offset range. ld/testsuite/ * ld-arm/arm-elf.exp (armelftests): Add movw-merge and arm-app-movw. * ld-arm/arm-app-movw.s: New test. * ld-arm/arm-app.r: Update expected output. * ld-arm/movw-merge.d: New test. * ld-arm/movw-merge.s: New test.
This commit is contained in:
parent
460b285508
commit
39623e120c
10 changed files with 168 additions and 41 deletions
|
@ -1,3 +1,14 @@
|
|||
2008-03-07 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_howto_table_1): Fix bitmasks for MOVW and
|
||||
MOVT relocations.
|
||||
(elf32_arm_final_link_relocate): Fix off by one MOVW/MOVT sign
|
||||
extension.
|
||||
(elf32_arm_relocate_section): Handle MOVW and MOVT
|
||||
relocations. Improve safety check for other weird relocations.
|
||||
(elf32_arm_check_relocs): Only set h->needs_plt for branch/call
|
||||
relocations.
|
||||
|
||||
2008-03-03 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* xtensa-isa.c (xtensa_isa_num_pipe_stages): Make max_stage static and
|
||||
|
|
132
bfd/elf32-arm.c
132
bfd/elf32-arm.c
|
@ -696,8 +696,8 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
|
|||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_MOVW_ABS_NC", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x0000ffff, /* src_mask */
|
||||
0x0000ffff, /* dst_mask */
|
||||
0x000f0fff, /* src_mask */
|
||||
0x000f0fff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_MOVT_ABS, /* type */
|
||||
|
@ -710,8 +710,8 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
|
|||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_MOVT_ABS", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x0000ffff, /* src_mask */
|
||||
0x0000ffff, /* dst_mask */
|
||||
0x000f0fff, /* src_mask */
|
||||
0x000f0fff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_MOVW_PREL_NC, /* type */
|
||||
|
@ -724,8 +724,8 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
|
|||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_MOVW_PREL_NC", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x0000ffff, /* src_mask */
|
||||
0x0000ffff, /* dst_mask */
|
||||
0x000f0fff, /* src_mask */
|
||||
0x000f0fff, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_MOVT_PREL, /* type */
|
||||
|
@ -738,8 +738,8 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
|
|||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_MOVT_PREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x0000ffff, /* src_mask */
|
||||
0x0000ffff, /* dst_mask */
|
||||
0x000f0fff, /* src_mask */
|
||||
0x000f0fff, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_THM_MOVW_ABS_NC, /* type */
|
||||
|
@ -5916,7 +5916,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
|||
if (globals->use_rel)
|
||||
{
|
||||
addend = ((insn >> 4) & 0xf000) | (insn & 0xfff);
|
||||
signed_addend = (addend ^ 0x10000) - 0x10000;
|
||||
signed_addend = (addend ^ 0x8000) - 0x8000;
|
||||
}
|
||||
|
||||
value += signed_addend;
|
||||
|
@ -5966,7 +5966,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
|||
| ((insn >> 15) & 0x0800)
|
||||
| ((insn >> 4) & 0x0700)
|
||||
| (insn & 0x00ff);
|
||||
signed_addend = (addend ^ 0x10000) - 0x10000;
|
||||
signed_addend = (addend ^ 0x8000) - 0x8000;
|
||||
}
|
||||
|
||||
value += signed_addend;
|
||||
|
@ -6548,34 +6548,85 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
|||
asection *msec;
|
||||
bfd_vma addend, value;
|
||||
|
||||
if (howto->rightshift)
|
||||
switch (r_type)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
|
||||
input_bfd, input_section,
|
||||
(long) rel->r_offset, howto->name);
|
||||
return FALSE;
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
addend = ((value & 0xf0000) >> 4) | (value & 0xfff);
|
||||
addend = (addend ^ 0x8000) - 0x8000;
|
||||
break;
|
||||
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
value = bfd_get_16 (input_bfd, contents + rel->r_offset)
|
||||
<< 16;
|
||||
value |= bfd_get_16 (input_bfd,
|
||||
contents + rel->r_offset + 2);
|
||||
addend = ((value & 0xf7000) >> 4) | (value & 0xff)
|
||||
| ((value & 0x04000000) >> 15);
|
||||
addend = (addend ^ 0x8000) - 0x8000;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (howto->rightshift
|
||||
|| (howto->src_mask & (howto->src_mask + 1)))
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
|
||||
input_bfd, input_section,
|
||||
(long) rel->r_offset, howto->name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
|
||||
/* Get the (signed) value from the instruction. */
|
||||
addend = value & howto->src_mask;
|
||||
if (addend & ((howto->src_mask + 1) >> 1))
|
||||
{
|
||||
bfd_signed_vma mask;
|
||||
|
||||
mask = -1;
|
||||
mask &= ~ howto->src_mask;
|
||||
addend |= mask;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
value = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
|
||||
/* Get the (signed) value from the instruction. */
|
||||
addend = value & howto->src_mask;
|
||||
if (addend & ((howto->src_mask + 1) >> 1))
|
||||
{
|
||||
bfd_signed_vma mask;
|
||||
|
||||
mask = -1;
|
||||
mask &= ~ howto->src_mask;
|
||||
addend |= mask;
|
||||
}
|
||||
msec = sec;
|
||||
addend =
|
||||
_bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
|
||||
- relocation;
|
||||
addend += msec->output_section->vma + msec->output_offset;
|
||||
value = (value & ~ howto->dst_mask) | (addend & howto->dst_mask);
|
||||
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
|
||||
|
||||
/* Cases here must match those in the preceeding
|
||||
switch statement. */
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
value = (value & 0xfff0f000) | ((addend & 0xf000) << 4)
|
||||
| (addend & 0xfff);
|
||||
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
|
||||
break;
|
||||
|
||||
case R_ARM_THM_MOVW_ABS_NC:
|
||||
case R_ARM_THM_MOVT_ABS:
|
||||
value = (value & 0xfbf08f00) | ((addend & 0xf700) << 4)
|
||||
| (addend & 0xff) | ((addend & 0x0800) << 15);
|
||||
bfd_put_16 (input_bfd, value >> 16,
|
||||
contents + rel->r_offset);
|
||||
bfd_put_16 (input_bfd, value,
|
||||
contents + rel->r_offset + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
value = (value & ~ howto->dst_mask)
|
||||
| (addend & howto->dst_mask);
|
||||
bfd_put_32 (input_bfd, value, contents + rel->r_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -7663,6 +7714,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
asection *sreloc;
|
||||
bfd_vma *local_got_offsets;
|
||||
struct elf32_arm_link_hash_table *htab;
|
||||
bfd_boolean needs_plt;
|
||||
|
||||
if (info->relocatable)
|
||||
return TRUE;
|
||||
|
@ -7804,10 +7856,6 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
break;
|
||||
/* Fall through */
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_ABS32_NOI:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_REL32_NOI:
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_PLT32:
|
||||
case R_ARM_CALL:
|
||||
|
@ -7816,6 +7864,13 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
case R_ARM_THM_CALL:
|
||||
case R_ARM_THM_JUMP24:
|
||||
case R_ARM_THM_JUMP19:
|
||||
needs_plt = 1;
|
||||
goto normal_reloc;
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_ABS32_NOI:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_REL32_NOI:
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
case R_ARM_MOVW_PREL_NC:
|
||||
|
@ -7824,6 +7879,9 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
case R_ARM_THM_MOVT_ABS:
|
||||
case R_ARM_THM_MOVW_PREL_NC:
|
||||
case R_ARM_THM_MOVT_PREL:
|
||||
needs_plt = 0;
|
||||
normal_reloc:
|
||||
|
||||
/* Should the interworking branches be listed here? */
|
||||
if (h != NULL)
|
||||
{
|
||||
|
@ -7840,11 +7898,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||
refers to is in a different object. We can't tell for
|
||||
sure yet, because something later might force the
|
||||
symbol local. */
|
||||
if (r_type != R_ARM_ABS32
|
||||
&& r_type != R_ARM_REL32
|
||||
&& r_type != R_ARM_ABS32_NOI
|
||||
&& r_type != R_ARM_REL32_NOI
|
||||
&& r_type != R_ARM_ABS12)
|
||||
if (needs_plt)
|
||||
h->needs_plt = 1;
|
||||
|
||||
/* If we create a PLT entry, this relocation will reference
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2008-03-07 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/tc-arm.c (md_apply_fix): Use correct offset range.
|
||||
|
||||
2008-03-07 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/tc-ppc.c (ppc_setup_opcodes): Tidy. Add code to test
|
||||
|
|
|
@ -18804,7 +18804,7 @@ md_apply_fix (fixS * fixP,
|
|||
/* REL format relocations are limited to a 16-bit addend. */
|
||||
if (!fixP->fx_done)
|
||||
{
|
||||
if (value < -0x1000 || value > 0xffff)
|
||||
if (value < -0x8000 || value > 0x7fff)
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("offset out of range"));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2008-03-07 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* ld-arm/arm-elf.exp (armelftests): Add movw-merge and arm-app-movw.
|
||||
* ld-arm/arm-app-movw.s: New test.
|
||||
* ld-arm/arm-app.r: Update expected output.
|
||||
* ld-arm/movw-merge.d: New test.
|
||||
* ld-arm/movw-merge.s: New test.
|
||||
|
||||
2008-03-01 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-powerpc/relbrlt.d: Update. Also check .branch_lt section.
|
||||
|
|
11
ld/testsuite/ld-arm/arm-app-movw.s
Normal file
11
ld/testsuite/ld-arm/arm-app-movw.s
Normal file
|
@ -0,0 +1,11 @@
|
|||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
movw r0, #:lower16:data_obj
|
||||
movt r0, #:upper16:data_obj
|
||||
movw r0, #:lower16:lib_func1
|
||||
movt r0, #:upper16:lib_func1
|
||||
|
||||
.globl app_func2
|
||||
app_func2:
|
||||
bx lr
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
tmpdir/arm-app: file format elf32-(little|big)arm
|
||||
tmpdir/arm-app.*: file format elf32-(little|big)arm
|
||||
|
||||
DYNAMIC RELOCATION RECORDS
|
||||
OFFSET TYPE VALUE
|
||||
|
|
|
@ -176,6 +176,12 @@ set armelftests {
|
|||
{"ARMv4 interworking" "-static -T arm.ld --fix-v4bx-interworking" "--fix-v4bx -meabi=4" {armv4-bx.s}
|
||||
{{objdump -d armv4-bx.d}}
|
||||
"armv4-bx"}
|
||||
{"MOVW/MOVT and merged sections" "-T arm.ld" "" {movw-merge.s}
|
||||
{{objdump -dw movw-merge.d}}
|
||||
"movw-merge"}
|
||||
{"MOVW/MOVT against shared libraries" "tmpdir/arm-lib.so" "" {arm-app-movw.s}
|
||||
{{objdump -Rw arm-app.r}}
|
||||
"arm-app-movw"}
|
||||
}
|
||||
|
||||
run_ld_link_tests $armelftests
|
||||
|
|
13
ld/testsuite/ld-arm/movw-merge.d
Normal file
13
ld/testsuite/ld-arm/movw-merge.d
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
.*: file format.*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
00008000 <[^>]*>:
|
||||
8000: e3080013 movw r0, #32787 ; 0x8013
|
||||
8004: e3400000 movt r0, #0 ; 0x0
|
||||
|
||||
00008008 <[^>]*>:
|
||||
8008: f248 0013 movw r0, #32787 ; 0x8013
|
||||
800c: f2c0 0000 movt r0, #0 ; 0x0
|
||||
|
20
ld/testsuite/ld-arm/movw-merge.s
Normal file
20
ld/testsuite/ld-arm/movw-merge.s
Normal file
|
@ -0,0 +1,20 @@
|
|||
.arch armv7-a
|
||||
.syntax unified
|
||||
.text
|
||||
.global _start
|
||||
.type _start, %function
|
||||
_start:
|
||||
movw r0, #:lower16:.LC0
|
||||
movt r0, #:upper16:.LC0
|
||||
.thumb
|
||||
.global tfunc
|
||||
.type tfunc, %function
|
||||
tfunc:
|
||||
movw r0, #:lower16:.LC0
|
||||
movt r0, #:upper16:.LC0
|
||||
|
||||
.section .rodata.str1.4,"aMS",%progbits,1
|
||||
.align 2
|
||||
.ascii "pad"
|
||||
.LC0:
|
||||
.ascii "inner: cont \000"
|
Loading…
Reference in a new issue