aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/elfnn-aarch64.c25
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp3
-rw-r--r--ld/testsuite/ld-aarch64/farcall-b-none-function.d21
-rw-r--r--ld/testsuite/ld-aarch64/farcall-b-section.d34
-rw-r--r--ld/testsuite/ld-aarch64/farcall-b-section.s20
-rw-r--r--ld/testsuite/ld-aarch64/farcall-bl-none-function.d21
-rw-r--r--ld/testsuite/ld-aarch64/farcall-bl-section.d34
-rw-r--r--ld/testsuite/ld-aarch64/farcall-bl-section.s20
-rw-r--r--ld/testsuite/ld-aarch64/farcall-section.d5
-rw-r--r--ld/testsuite/ld-aarch64/farcall-section.s19
12 files changed, 187 insertions, 33 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index dcf21ce..c4fd0bb 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2016-01-21 Jiong Wang <jiong.wang@arm.com>
+
+ * elfnn-aarch64.c (aarch64_type_of_stub): Allow insert long branch
+ veneer for sym_sec != input_sec.
+ (elfNN_aarch64_size_stub): Support STT_SECTION symbol.
+ (elfNN_aarch64_final_link_relocate): Take rela addend into account when
+ calculation destination.
+
2016-01-21 Alan Modra <amodra@gmail.com>
* elf-linux-core.h (swap_linux_prpsinfo32_out): New function.
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 70251f1..292470df 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2655,7 +2655,7 @@ aarch64_type_of_stub (struct bfd_link_info *info,
bfd_boolean via_plt_p;
if (st_type != STT_FUNC
- && (sym_sec != bfd_abs_section_ptr))
+ && (sym_sec == input_sec))
return stub_type;
globals = elf_aarch64_hash_table (info);
@@ -4174,7 +4174,7 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
goto error_ret_free_internal;
}
- stub_entry->target_value = sym_value;
+ stub_entry->target_value = sym_value + irela->r_addend;
stub_entry->target_section = sym_sec;
stub_entry->stub_type = stub_type;
stub_entry->h = hash;
@@ -5280,15 +5280,28 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
/* Check if a stub has to be inserted because the destination
is too far away. */
struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
- if (! aarch64_valid_branch_p (value, place))
+
+ /* If the branch destination is directed to plt stub, "value" will be
+ the final destination, otherwise we should plus signed_addend, it may
+ contain non-zero value, for example call to local function symbol
+ which are turned into "sec_sym + sec_off", and sec_off is kept in
+ signed_addend. */
+ if (! aarch64_valid_branch_p (via_plt_p ? value : value + signed_addend,
+ place))
/* The target is out of reach, so redirect the branch to
the local stub for this function. */
stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
rel, globals);
if (stub_entry != NULL)
- value = (stub_entry->stub_offset
- + stub_entry->stub_sec->output_offset
- + stub_entry->stub_sec->output_section->vma);
+ {
+ value = (stub_entry->stub_offset
+ + stub_entry->stub_sec->output_offset
+ + stub_entry->stub_sec->output_section->vma);
+
+ /* We have redirected the destination to stub entry address,
+ so ignore any addend record in the original rela entry. */
+ signed_addend = 0;
+ }
}
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
signed_addend, weak_undef_p);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index fc01ed6..a6494b8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2016-01-20 Jiong Wang <jiong.wang@arm.com>
+
+ * testsuite/ld-aarch64/farcall-section.d: Delete.
+ * testsuite/ld-aarch64/farcall-section.s: Delete.
+ * testsuite/ld-aarch64/farcall-b-section.d: New expectation file.
+ * testsuite/ld-aarch64/farcall-bl-section.d: Likewise.
+ * testsuite/ld-aarch64/farcall-b-section.s: New testcase.
+ * testsuite/ld-aarch64/farcall-bl-section.s: Likewise.
+ * testsuite/ld-aarch64/aarch64-elf.exp: Likewise.
+
2016-01-20 Nick Clifton <nickc@redhat.com>
PR 19457
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index c5c9ad0..939539e 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -170,7 +170,6 @@ run_dump_test "pcrel_pic_defined_local"
run_dump_test "limit-b"
run_dump_test "limit-bl"
-run_dump_test "farcall-section"
run_dump_test "farcall-back"
run_dump_test "farcall-b-defsym"
run_dump_test "farcall-bl-defsym"
@@ -181,6 +180,8 @@ run_dump_test "farcall-bl"
run_dump_test "farcall-b"
run_dump_test "farcall-b-none-function"
run_dump_test "farcall-bl-none-function"
+run_dump_test "farcall-b-section"
+run_dump_test "farcall-bl-section"
run_dump_test "tls-relax-all"
run_dump_test "tls-relax-gd-le"
diff --git a/ld/testsuite/ld-aarch64/farcall-b-none-function.d b/ld/testsuite/ld-aarch64/farcall-b-none-function.d
index 34a6568..ba2981f 100644
--- a/ld/testsuite/ld-aarch64/farcall-b-none-function.d
+++ b/ld/testsuite/ld-aarch64/farcall-b-none-function.d
@@ -2,4 +2,23 @@
#source: farcall-b-none-function.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_JUMP26 against symbol `bar'.*
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 14000003 b 100c <__bar_veneer>
+ 1004: d65f03c0 ret
+ 1008: 14000007 b 1024 <__bar_veneer\+0x18>
+
+.* <__bar_veneer>:
+ 100c: 90040010 adrp x16, 8001000 <bar>
+ 1010: 91000210 add x16, x16, #0x0
+ 1014: d61f0200 br x16
+ ...
+
+Disassembly of section .foo:
+
+.* <bar>:
+ 8001000: d65f03c0 ret
diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.d b/ld/testsuite/ld-aarch64/farcall-b-section.d
new file mode 100644
index 0000000..4745c0f
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-section.d
@@ -0,0 +1,34 @@
+#name: aarch64-farcall-b-section
+#source: farcall-b-section.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x8001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 14000008 b 1020 <___veneer>
+ 1004: 14000003 b 1010 <___veneer>
+ 1008: d65f03c0 ret
+ 100c: 1400000d b 1040 <___veneer\+0x20>
+
+.* <___veneer>:
+ 1010: 90040010 adrp x16, 8001000 <bar>
+ 1014: 91001210 add x16, x16, #0x4
+ 1018: d61f0200 br x16
+ 101c: 00000000 .inst 0x00000000 ; undefined
+
+.* <___veneer>:
+ 1020: 90040010 adrp x16, 8001000 <bar>
+ 1024: 91000210 add x16, x16, #0x0
+ 1028: d61f0200 br x16
+ ...
+
+Disassembly of section .foo:
+
+.* <bar>:
+ 8001000: d65f03c0 ret
+
+.* <bar2>:
+ 8001004: d65f03c0 ret
diff --git a/ld/testsuite/ld-aarch64/farcall-b-section.s b/ld/testsuite/ld-aarch64/farcall-b-section.s
new file mode 100644
index 0000000..1a135ef
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-b-section.s
@@ -0,0 +1,20 @@
+.global _start
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ b bar
+ b bar2
+ ret
+
+# We will place the section .foo at 0x8001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ .type bar2, @function
+bar2:
+ ret
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-none-function.d b/ld/testsuite/ld-aarch64/farcall-bl-none-function.d
index 6ce9ca4..b6a4dda 100644
--- a/ld/testsuite/ld-aarch64/farcall-bl-none-function.d
+++ b/ld/testsuite/ld-aarch64/farcall-bl-none-function.d
@@ -2,4 +2,23 @@
#source: farcall-bl-none-function.s
#as:
#ld: -Ttext 0x1000 --section-start .foo=0x8001000
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_CALL26 against symbol `bar'.*
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 94000003 bl 100c <__bar_veneer>
+ 1004: d65f03c0 ret
+ 1008: 14000007 b 1024 <__bar_veneer\+0x18>
+
+.* <__bar_veneer>:
+ 100c: 90040010 adrp x16, 8001000 <bar>
+ 1010: 91000210 add x16, x16, #0x0
+ 1014: d61f0200 br x16
+ ...
+
+Disassembly of section .foo:
+
+.* <bar>:
+ 8001000: d65f03c0 ret
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.d b/ld/testsuite/ld-aarch64/farcall-bl-section.d
new file mode 100644
index 0000000..2bd4f85
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-bl-section.d
@@ -0,0 +1,34 @@
+#name: aarch64-farcall-bl-section
+#source: farcall-bl-section.s
+#as:
+#ld: -Ttext 0x1000 --section-start .foo=0x8001000
+#objdump: -dr
+#...
+
+Disassembly of section .text:
+
+.* <_start>:
+ 1000: 94000008 bl 1020 <___veneer>
+ 1004: 94000003 bl 1010 <___veneer>
+ 1008: d65f03c0 ret
+ 100c: 1400000d b 1040 <___veneer\+0x20>
+
+.* <___veneer>:
+ 1010: 90040010 adrp x16, 8001000 <bar>
+ 1014: 91001210 add x16, x16, #0x4
+ 1018: d61f0200 br x16
+ 101c: 00000000 .inst 0x00000000 ; undefined
+
+.* <___veneer>:
+ 1020: 90040010 adrp x16, 8001000 <bar>
+ 1024: 91000210 add x16, x16, #0x0
+ 1028: d61f0200 br x16
+ ...
+
+Disassembly of section .foo:
+
+.* <bar>:
+ 8001000: d65f03c0 ret
+
+.* <bar2>:
+ 8001004: d65f03c0 ret
diff --git a/ld/testsuite/ld-aarch64/farcall-bl-section.s b/ld/testsuite/ld-aarch64/farcall-bl-section.s
new file mode 100644
index 0000000..4469d4d
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/farcall-bl-section.s
@@ -0,0 +1,20 @@
+ .global _start
+
+# We will place the section .text at 0x1000.
+
+ .text
+
+_start:
+ bl bar
+ bl bar2
+ ret
+
+# We will place the section .foo at 0x8001000.
+
+ .section .foo, "xa"
+ .type bar, @function
+bar:
+ ret
+ .type bar2, @function
+bar2:
+ ret
diff --git a/ld/testsuite/ld-aarch64/farcall-section.d b/ld/testsuite/ld-aarch64/farcall-section.d
deleted file mode 100644
index 85775e1..0000000
--- a/ld/testsuite/ld-aarch64/farcall-section.d
+++ /dev/null
@@ -1,5 +0,0 @@
-#name: Aarch64 farcall to symbol of type STT_SECTION
-#source: farcall-section.s
-#as:
-#ld: -Ttext 0x1000 --section-start .foo=0x8001014
-#error: .*\(.text\+0x0\): relocation truncated to fit: R_AARCH64_CALL26 against `.foo'
diff --git a/ld/testsuite/ld-aarch64/farcall-section.s b/ld/testsuite/ld-aarch64/farcall-section.s
deleted file mode 100644
index 86a070c..0000000
--- a/ld/testsuite/ld-aarch64/farcall-section.s
+++ /dev/null
@@ -1,19 +0,0 @@
-# Test to ensure that an Aarch64 call exceeding 128MB generates an error
-# if the destination is of type STT_SECTION (eg non-global symbol)
-
- .global _start
-
-# We will place the section .text at 0x1000.
-
- .text
-
-_start:
- bl bar
-
-# We will place the section .foo at 0x8001020.
-
- .section .foo, "xa"
-
-bar:
- ret
-