|
|
4910d4 |
--- binutils-2.25.orig/bfd/elfnn-aarch64.c 2015-09-14 12:05:10.010398108 +0100
|
|
|
4910d4 |
+++ binutils-2.25/bfd/elfnn-aarch64.c 2015-09-14 12:12:40.730934194 +0100
|
|
|
4910d4 |
@@ -2199,9 +2199,11 @@ aarch64_type_of_stub (struct bfd_link_in
|
|
|
4910d4 |
globals = elf_aarch64_hash_table (info);
|
|
|
4910d4 |
via_plt_p = (globals->root.splt != NULL && hash != NULL
|
|
|
4910d4 |
&& hash->root.plt.offset != (bfd_vma) - 1);
|
|
|
4910d4 |
-
|
|
|
4910d4 |
+ /* Make sure call to plt stub can fit into the branch range. */
|
|
|
4910d4 |
if (via_plt_p)
|
|
|
4910d4 |
- return stub_type;
|
|
|
4910d4 |
+ destination = (globals->root.splt->output_section->vma
|
|
|
4910d4 |
+ + globals->root.splt->output_offset
|
|
|
4910d4 |
+ + hash->root.plt.offset);
|
|
|
4910d4 |
|
|
|
4910d4 |
/* Determine where the call point is. */
|
|
|
4910d4 |
location = (input_sec->output_offset
|
|
|
4910d4 |
--- binutils-2.25.1.orig/bfd/elfnn-aarch64.c 2016-02-09 13:09:06.048284671 +0000
|
|
|
4910d4 |
+++ binutils-2.25.1/bfd/elfnn-aarch64.c 2016-02-09 13:11:13.397971718 +0000
|
|
|
4910d4 |
@@ -4394,38 +4394,25 @@ elfNN_aarch64_final_link_relocate (reloc
|
|
|
4910d4 |
/* If the call goes through a PLT entry, make sure to
|
|
|
4910d4 |
check distance to the right destination address. */
|
|
|
4910d4 |
if (via_plt_p)
|
|
|
4910d4 |
- {
|
|
|
4910d4 |
- value = (splt->output_section->vma
|
|
|
4910d4 |
- + splt->output_offset + h->plt.offset);
|
|
|
4910d4 |
- *unresolved_reloc_p = FALSE;
|
|
|
4910d4 |
- }
|
|
|
4910d4 |
+ value = (splt->output_section->vma
|
|
|
4910d4 |
+ + splt->output_offset + h->plt.offset);
|
|
|
4910d4 |
|
|
|
4910d4 |
- /* If the target symbol is global and marked as a function the
|
|
|
4910d4 |
- relocation applies a function call or a tail call. In this
|
|
|
4910d4 |
- situation we can veneer out of range branches. The veneers
|
|
|
4910d4 |
- use IP0 and IP1 hence cannot be used arbitrary out of range
|
|
|
4910d4 |
- branches that occur within the body of a function. */
|
|
|
4910d4 |
- if (h && h->type == STT_FUNC)
|
|
|
4910d4 |
- {
|
|
|
4910d4 |
- /* Check if a stub has to be inserted because the destination
|
|
|
4910d4 |
- is too far away. */
|
|
|
4910d4 |
- if (! aarch64_valid_branch_p (value, place))
|
|
|
4910d4 |
- {
|
|
|
4910d4 |
- /* The target is out of reach, so redirect the branch to
|
|
|
4910d4 |
- the local stub for this function. */
|
|
|
4910d4 |
- struct elf_aarch64_stub_hash_entry *stub_entry;
|
|
|
4910d4 |
- stub_entry = elfNN_aarch64_get_stub_entry (input_section,
|
|
|
4910d4 |
- sym_sec, h,
|
|
|
4910d4 |
- rel, globals);
|
|
|
4910d4 |
- if (stub_entry != NULL)
|
|
|
4910d4 |
- value = (stub_entry->stub_offset
|
|
|
4910d4 |
- + stub_entry->stub_sec->output_offset
|
|
|
4910d4 |
- + stub_entry->stub_sec->output_section->vma);
|
|
|
4910d4 |
- }
|
|
|
4910d4 |
- }
|
|
|
4910d4 |
+ /* Check if a stub has to be inserted because the destination
|
|
|
4910d4 |
+ is too far away. */
|
|
|
4910d4 |
+ struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
|
|
|
4910d4 |
+ if (! aarch64_valid_branch_p (value, place))
|
|
|
4910d4 |
+ /* The target is out of reach, so redirect the branch to
|
|
|
4910d4 |
+ the local stub for this function. */
|
|
|
4910d4 |
+ stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
|
|
|
4910d4 |
+ rel, globals);
|
|
|
4910d4 |
+ if (stub_entry != NULL)
|
|
|
4910d4 |
+ value = (stub_entry->stub_offset
|
|
|
4910d4 |
+ + stub_entry->stub_sec->output_offset
|
|
|
4910d4 |
+ + stub_entry->stub_sec->output_section->vma);
|
|
|
4910d4 |
}
|
|
|
4910d4 |
value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
|
|
|
4910d4 |
signed_addend, weak_undef_p);
|
|
|
4910d4 |
+ *unresolved_reloc_p = FALSE;
|
|
|
4910d4 |
break;
|
|
|
4910d4 |
|
|
|
4910d4 |
case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
|
|
|
4910d4 |
--- binutils-2.25.1.orig/bfd/elfnn-aarch64.c 2016-06-13 14:44:40.637034867 +0100
|
|
|
4910d4 |
+++ binutils-2.25.1/bfd/elfnn-aarch64.c 2016-06-13 14:50:42.798414611 +0100
|
|
|
4910d4 |
@@ -2190,6 +2190,7 @@ static enum elf_aarch64_stub_type
|
|
|
4910d4 |
aarch64_type_of_stub (struct bfd_link_info *info,
|
|
|
4910d4 |
asection *input_sec,
|
|
|
4910d4 |
const Elf_Internal_Rela *rel,
|
|
|
4910d4 |
+ asection *sym_sec,
|
|
|
4910d4 |
unsigned char st_type,
|
|
|
4910d4 |
struct elf_aarch64_link_hash_entry *hash,
|
|
|
4910d4 |
bfd_vma destination)
|
|
|
4910d4 |
@@ -2201,7 +2202,8 @@ aarch64_type_of_stub (struct bfd_link_in
|
|
|
4910d4 |
enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
|
|
|
4910d4 |
bfd_boolean via_plt_p;
|
|
|
4910d4 |
|
|
|
4910d4 |
- if (st_type != STT_FUNC)
|
|
|
4910d4 |
+ if (st_type != STT_FUNC
|
|
|
4910d4 |
+ && (sym_sec != bfd_abs_section_ptr))
|
|
|
4910d4 |
return stub_type;
|
|
|
4910d4 |
|
|
|
4910d4 |
globals = elf_aarch64_hash_table (info);
|
|
|
4910d4 |
@@ -3373,7 +3375,7 @@ elfNN_aarch64_size_stubs (bfd *output_bf
|
|
|
4910d4 |
|
|
|
4910d4 |
/* Determine what (if any) linker stub is needed. */
|
|
|
4910d4 |
stub_type = aarch64_type_of_stub
|
|
|
4910d4 |
- (info, section, irela, st_type, hash, destination);
|
|
|
4910d4 |
+ (info, section, irela, sym_sec, st_type, hash, destination);
|
|
|
4910d4 |
if (stub_type == aarch64_stub_none)
|
|
|
4910d4 |
continue;
|
|
|
4910d4 |
|