aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2016-05-23 09:41:36 +0100
committerThomas Preud'homme <thomas.preudhomme@arm.com>2016-05-23 09:41:36 +0100
commitd7c5bd02f73408553992db3650b95b14e73820d4 (patch)
tree0c3582c859dbae479b446a2e8f4df320beaf9dfc /bfd
parentdaa4adae63f91377fe9b3e8d7421a0ceb4a51e26 (diff)
downloadgdb-d7c5bd02f73408553992db3650b95b14e73820d4.zip
gdb-d7c5bd02f73408553992db3650b95b14e73820d4.tar.gz
gdb-d7c5bd02f73408553992db3650b95b14e73820d4.tar.bz2
Support for dedicated ARM stub section with padding
2016-05-23 Thomas Preud'homme <thomas.preudhomme@arm.com> bfd/ * elf32-arm.c (arm_dedicated_stub_section_padding): New function. (elf32_arm_size_stubs): Declare stub_type in a more outer scope and account for padding for stub section requiring one. (elf32_arm_build_stubs): Add comment to stress the importance of zeroing veneer section content.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/elf32-arm.c37
2 files changed, 43 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5a99dcf..8d8c24c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,13 @@
2016-05-23 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * elf32-arm.c (arm_dedicated_stub_section_padding): New function.
+ (elf32_arm_size_stubs): Declare stub_type in a more outer scope and
+ account for padding for stub section requiring one.
+ (elf32_arm_build_stubs): Add comment to stress the importance of
+ zeroing veneer section content.
+
+2016-05-23 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* bfd-in.h (bfd_elf32_arm_keep_private_stub_output_sections): Declare
bfd hook.
* bfd-in2.h: Regenerate.
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e5c69f5..6375ae4 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -4435,6 +4435,18 @@ arm_stub_sym_claimed (enum elf32_arm_stub_type stub_type)
return FALSE;
}
+/* Returns the padding needed for the dedicated section used stubs of type
+ STUB_TYPE. */
+
+static int
+arm_dedicated_stub_section_padding (enum elf32_arm_stub_type stub_type)
+{
+ if (stub_type >= max_stub_type)
+ abort (); /* Should be unreachable. */
+
+ return 0;
+}
+
static bfd_boolean
arm_build_one_stub (struct bfd_hash_entry *gen_entry,
void * in_arg)
@@ -5411,6 +5423,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
bfd *input_bfd;
unsigned int bfd_indx;
asection *stub_sec;
+ enum elf32_arm_stub_type stub_type;
bfd_boolean stub_changed = FALSE;
unsigned prev_num_a8_fixes = num_a8_fixes;
@@ -5466,7 +5479,6 @@ elf32_arm_size_stubs (bfd *output_bfd,
for (; irela < irelaend; irela++)
{
unsigned int r_type, r_indx;
- enum elf32_arm_stub_type stub_type;
asection *sym_sec;
bfd_vma sym_value;
bfd_vma destination;
@@ -5780,7 +5792,27 @@ elf32_arm_size_stubs (bfd *output_bfd,
stub_sec->size = 0;
}
+ /* Compute stub section size, considering padding. */
bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab);
+ for (stub_type = arm_stub_none + 1; stub_type < max_stub_type;
+ stub_type++)
+ {
+ int size, padding;
+ asection **stub_sec_p;
+
+ padding = arm_dedicated_stub_section_padding (stub_type);
+ stub_sec_p = arm_dedicated_stub_input_section_ptr (htab, stub_type);
+ /* Skip if no stub input section or no stub section padding
+ required. */
+ if ((stub_sec_p != NULL && *stub_sec_p == NULL) || padding == 0)
+ continue;
+ /* Stub section padding required but no dedicated section. */
+ BFD_ASSERT (stub_sec_p);
+
+ size = (*stub_sec_p)->size;
+ size = (size + padding - 1) & ~(padding - 1);
+ (*stub_sec_p)->size = size;
+ }
/* Add Cortex-A8 erratum veneers to stub section sizes too. */
if (htab->fix_cortex_a8)
@@ -5885,7 +5917,8 @@ elf32_arm_build_stubs (struct bfd_link_info *info)
if (!strstr (stub_sec->name, STUB_SUFFIX))
continue;
- /* Allocate memory to hold the linker stubs. */
+ /* Allocate memory to hold the linker stubs. Zeroing the stub sections
+ must at least be done for stub section requiring padding. */
size = stub_sec->size;
stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
if (stub_sec->contents == NULL && size != 0)