aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gutson <dgutson@codesourcery.com>2009-08-21 23:38:07 +0000
committerDaniel Gutson <dgutson@codesourcery.com>2009-08-21 23:38:07 +0000
commitcd1dac3d4a9145d560bf6f726a227119a087be23 (patch)
tree547659bc2cb709dfe7d02210dfbbf995009462be
parent62af60e2daf96e527c442d06661cbbde253c777b (diff)
downloadgdb-cd1dac3d4a9145d560bf6f726a227119a087be23.zip
gdb-cd1dac3d4a9145d560bf6f726a227119a087be23.tar.gz
gdb-cd1dac3d4a9145d560bf6f726a227119a087be23.tar.bz2
2S09-08-21 Daniel Gutson <dgutson@codesourcery.com>
ld/ * ld-arm/callweak.d: Opcodes updated. * ld-arm/callweak.s: Architecture specified. * ld-arm/callweak-2.d: New test case. * ld-arm/callweak-2.s: New file. bfd/ * elf32-arm.c (arch_has_thumb2_nop): New function. (arch_has_arm_nop): New function. (elf32_arm_final_link_relocate): NOP opcodes changed. SVS: ----------------------------------------------------------------------
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-arm.c50
-rw-r--r--ld/testsuite/ChangeLog7
-rw-r--r--ld/testsuite/ld-arm/callweak-2.d15
-rw-r--r--ld/testsuite/ld-arm/callweak-2.s17
-rw-r--r--ld/testsuite/ld-arm/callweak.d4
-rw-r--r--ld/testsuite/ld-arm/callweak.s1
7 files changed, 91 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f9c4c6d..47f793f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2009-08-21 Daniel Gutson <dgutson@codesourcery.com>
+
+ * elf32-arm.c (arch_has_thumb2_nop): New function.
+ (arch_has_arm_nop): New function.
+ (elf32_arm_final_link_relocate): NOP opcodes changed.
+
2009-08-16 Doug Evans <dje@google.com>
* opncls.c (bfd_close): Until BFD_IN_MEMORY has an iovec,
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 49c80ad..5a0d9c3 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2987,6 +2987,26 @@ using_thumb2 (struct elf32_arm_link_hash_table *globals)
return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
}
+/* Determine what kind of NOPs are available. */
+
+static bfd_boolean
+arch_has_arm_nop (struct elf32_arm_link_hash_table *globals)
+{
+ const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ return arch == TAG_CPU_ARCH_V6T2
+ || arch == TAG_CPU_ARCH_V6K
+ || arch == TAG_CPU_ARCH_V7;
+}
+
+static bfd_boolean
+arch_has_thumb2_nop (struct elf32_arm_link_hash_table *globals)
+{
+ const int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+ Tag_CPU_arch);
+ return arch == TAG_CPU_ARCH_V6T2 || arch == TAG_CPU_ARCH_V7;
+}
+
static bfd_boolean
arm_stub_is_thumb (enum elf32_arm_stub_type stub_type)
{
@@ -7073,13 +7093,19 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
/* A branch to an undefined weak symbol is turned into a jump to
the next instruction unless a PLT entry will be created.
- Do the same for local undefined symbols. */
+ Do the same for local undefined symbols.
+ The jump to the next instruction is optimized as a NOP depending
+ on the architecture. */
if (h ? (h->root.type == bfd_link_hash_undefweak
&& !(splt != NULL && h->plt.offset != (bfd_vma) -1))
: bfd_is_und_section (sym_sec))
{
- value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000)
- | 0x0affffff;
+ value = (bfd_get_32 (input_bfd, hit_data) & 0xf0000000);
+
+ if (arch_has_arm_nop (globals))
+ value |= 0x0320f000;
+ else
+ value |= 0x01a00000; /* Using pre-UAL nop: mov r0, r0. */
}
else
{
@@ -7324,15 +7350,25 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
bfd_vma check;
bfd_signed_vma signed_check;
int bitsize;
- int thumb2 = using_thumb2 (globals);
+ const int thumb2 = using_thumb2 (globals);
/* A branch to an undefined weak symbol is turned into a jump to
- the next instruction unless a PLT entry will be created. */
+ the next instruction unless a PLT entry will be created.
+ The jump to the next instruction is optimized as a NOP.W for
+ Thumb-2 enabled architectures. */
if (h && h->root.type == bfd_link_hash_undefweak
&& !(splt != NULL && h->plt.offset != (bfd_vma) -1))
{
- bfd_put_16 (input_bfd, 0xe000, hit_data);
- bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+ if (arch_has_thumb2_nop (globals))
+ {
+ bfd_put_16 (input_bfd, 0xf3af, hit_data);
+ bfd_put_16 (input_bfd, 0x8000, hit_data + 2);
+ }
+ else
+ {
+ bfd_put_16 (input_bfd, 0xe000, hit_data);
+ bfd_put_16 (input_bfd, 0xbf00, hit_data + 2);
+ }
return bfd_reloc_ok;
}
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 6f9bc27..040ce8f 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2009-08-21 Daniel Gutson <dgutson@codesourcery.com>
+
+ * ld-arm/callweak.d: Opcodes updated.
+ * ld-arm/callweak.s: Architecture specified.
+ * ld-arm/callweak-2.d: New test case.
+ * ld-arm/callweak-2.s: New file.
+
2009-08-17 Nick Clifton <nickc@redhat.com>
* ld-elf/linkonce1.d: Accept "UNUSED" as part of the name of an
diff --git a/ld/testsuite/ld-arm/callweak-2.d b/ld/testsuite/ld-arm/callweak-2.d
new file mode 100644
index 0000000..d401479
--- /dev/null
+++ b/ld/testsuite/ld-arm/callweak-2.d
@@ -0,0 +1,15 @@
+
+.*: file format.*
+
+Disassembly of section .far:
+
+12340000 <[^>]*>:
+12340000: e320f000 nop \{0\}
+12340004: 0320f000 nopeq \{0\}
+
+12340008 <[^>]*>:
+12340008: f3af 8000 nop.w
+1234000c: 2000 movs r0, #0
+1234000e: f3af 8000 nop.w
+12340012: 4770 bx lr
+
diff --git a/ld/testsuite/ld-arm/callweak-2.s b/ld/testsuite/ld-arm/callweak-2.s
new file mode 100644
index 0000000..af4f026
--- /dev/null
+++ b/ld/testsuite/ld-arm/callweak-2.s
@@ -0,0 +1,17 @@
+ .syntax unified
+ .arch armv6t2
+ .weak bar
+ .section .far, "ax", %progbits
+ .global _start
+ .type _start, %function
+_start:
+ bl bar
+ bleq bar
+ .thumb
+ .type foo, %function
+ .thumb_func
+foo:
+ bl bar
+ movs r0, #0
+ bl bar
+ bx lr
diff --git a/ld/testsuite/ld-arm/callweak.d b/ld/testsuite/ld-arm/callweak.d
index 3dffcc4..89cb4a5 100644
--- a/ld/testsuite/ld-arm/callweak.d
+++ b/ld/testsuite/ld-arm/callweak.d
@@ -4,8 +4,8 @@
Disassembly of section .far:
12340000 <[^>]*>:
-12340000: eaffffff b 12340004 <[^>]*>
-12340004: 0affffff beq 12340008 <[^>]*>
+12340000: e1a00000 nop ; \(mov r0, r0\)
+12340004: 01a00000 moveq r0, r0
12340008 <[^>]*>:
12340008: e000 b.n 1234000c <[^>]*>
diff --git a/ld/testsuite/ld-arm/callweak.s b/ld/testsuite/ld-arm/callweak.s
index 6850da3..b9bcd1b 100644
--- a/ld/testsuite/ld-arm/callweak.s
+++ b/ld/testsuite/ld-arm/callweak.s
@@ -1,4 +1,5 @@
.syntax unified
+ .arch armv6
.weak bar
.section .far, "ax", %progbits
.global _start