summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/bfd
diff options
context:
space:
mode:
authorMarcus Shawcroft <marcus.shawcroft@gmail.com>2015-03-22 08:31:18 +0000
committerAndrew Hsieh <andrewhsieh@google.com>2015-03-30 21:39:13 -0700
commit15c4812b1a1343236166916189c7159be84a5327 (patch)
tree2fcba7dbe8fa8956580002afab868c7b8c869c0b /binutils-2.25/bfd
parent53079dc96023ca7367d09acc8fdc5044d4ffdfb6 (diff)
downloadtoolchain_binutils-15c4812b1a1343236166916189c7159be84a5327.zip
toolchain_binutils-15c4812b1a1343236166916189c7159be84a5327.tar.gz
toolchain_binutils-15c4812b1a1343236166916189c7159be84a5327.tar.bz2
[AArch64] Implement branch over stub section.
Ensure that injection of a stub section does not break a link where there is an xpectation that flow of control can pass from one input section to another simply by linking the input sections in series. The solution here is to allow stub sections to be inserted after any input section (existing behaviour), but inject an additional branch at the start of each stub section such that control flow falling into the stub section will branch over the stub section. Change-Id: I8ccadcfb2f43e6409cb5a649087a47c0c8826b15
Diffstat (limited to 'binutils-2.25/bfd')
-rw-r--r--binutils-2.25/bfd/elfnn-aarch64.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/binutils-2.25/bfd/elfnn-aarch64.c b/binutils-2.25/bfd/elfnn-aarch64.c
index c5bee70..27601fc 100644
--- a/binutils-2.25/bfd/elfnn-aarch64.c
+++ b/binutils-2.25/bfd/elfnn-aarch64.c
@@ -3090,8 +3090,17 @@ _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table *htab)
}
bfd_hash_traverse (&htab->stub_hash_table, aarch64_size_one_stub, htab);
-}
+ for (section = htab->stub_bfd->sections;
+ section != NULL; section = section->next)
+ {
+ if (!strstr (section->name, STUB_SUFFIX))
+ continue;
+
+ if (section->size)
+ section->size += 4;
+ }
+}
/* Determine and set the size of the stub section for a final link.
@@ -3455,6 +3464,9 @@ elfNN_aarch64_build_stubs (struct bfd_link_info *info)
if (stub_sec->contents == NULL && size != 0)
return FALSE;
stub_sec->size = 0;
+
+ bfd_putl32 (0x14000000 | (size >> 2), stub_sec->contents);
+ stub_sec->size += 4;
}
/* Build the stubs as directed by the stub hash table. */
@@ -6343,6 +6355,10 @@ elfNN_aarch64_output_arch_local_syms (bfd *output_bfd,
osi.sec_shndx = _bfd_elf_section_from_bfd_section
(output_bfd, osi.sec->output_section);
+ /* The first instruction in a stub is always a branch. */
+ if (!elfNN_aarch64_output_map_sym (&osi, AARCH64_MAP_INSN, 0))
+ return FALSE;
+
bfd_hash_traverse (&htab->stub_hash_table, aarch64_map_one_stub,
&osi);
}