From 6bde4c52fb2d49572d365612f222a42b4d316f09 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 10 May 2016 15:45:01 +0100 Subject: [PATCH] Allow stubs without associated input section in ARM backend 2016-05-10 Thomas Preud'homme bfd/ * bfd-in.h (elf32_arm_size_stubs): Add an output section parameter. * bfd-in2.h: Regenerated. * elf32-arm.c (struct elf32_arm_link_hash_table): Add an output section parameter to add_stub_section callback. (elf32_arm_create_or_find_stub_sec): Get output section from link_sec and pass it down to add_stub_section. (elf32_arm_add_stub): Set section to stub_sec if NULL before using it for error message. (elf32_arm_size_stubs): Add output section parameter to add_stub_section function pointer parameter. ld/ * emultempl/armelf.em (elf32_arm_add_stub_section): Add output_section parameter and rename input_section parameter to after_input_section. Append input stub section to the output section if after_input_section is NULL. --- bfd/ChangeLog | 13 +++++++++++++ bfd/bfd-in.h | 3 ++- bfd/bfd-in2.h | 3 ++- bfd/elf32-arm.c | 10 ++++++++-- ld/ChangeLog | 7 +++++++ ld/emultempl/armelf.em | 28 ++++++++++++++++++++++------ 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7e89254380..5acc4d0b5a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2016-05-10 Thomas Preud'homme + + * bfd-in.h (elf32_arm_size_stubs): Add an output section parameter. + * bfd-in2.h: Regenerated. + * elf32-arm.c (struct elf32_arm_link_hash_table): Add an output section + parameter to add_stub_section callback. + (elf32_arm_create_or_find_stub_sec): Get output section from link_sec + and pass it down to add_stub_section. + (elf32_arm_add_stub): Set section to stub_sec if NULL before using it + for error message. + (elf32_arm_size_stubs): Add output section parameter to + add_stub_section function pointer parameter. + 2016-05-10 Thomas Preud'homme * elf32-arm.c (elf32_arm_create_stub): New function. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 46414056d6..a3a28e52e7 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -934,7 +934,8 @@ extern void elf32_arm_next_input_section (struct bfd_link_info *, struct bfd_section *); extern bfd_boolean elf32_arm_size_stubs (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma, - struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int), + struct bfd_section * (*) (const char *, struct bfd_section *, + struct bfd_section *, unsigned int), void (*) (void)); extern bfd_boolean elf32_arm_build_stubs (struct bfd_link_info *); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index f68c10766a..dbb00e8697 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -941,7 +941,8 @@ extern void elf32_arm_next_input_section (struct bfd_link_info *, struct bfd_section *); extern bfd_boolean elf32_arm_size_stubs (bfd *, bfd *, struct bfd_link_info *, bfd_signed_vma, - struct bfd_section * (*) (const char *, struct bfd_section *, unsigned int), + struct bfd_section * (*) (const char *, struct bfd_section *, + struct bfd_section *, unsigned int), void (*) (void)); extern bfd_boolean elf32_arm_build_stubs (struct bfd_link_info *); diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 9adc43e69c..e1ee67315f 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3163,7 +3163,8 @@ struct elf32_arm_link_hash_table bfd *stub_bfd; /* Linker call-backs. */ - asection * (*add_stub_section) (const char *, asection *, unsigned int); + asection * (*add_stub_section) (const char *, asection *, asection *, + unsigned int); void (*layout_sections_again) (void); /* Array to keep track of which stub sections have been created, and @@ -4144,6 +4145,7 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, { asection *link_sec; asection *stub_sec; + asection *out_sec; link_sec = htab->stub_group[section->id].link_sec; BFD_ASSERT (link_sec != NULL); @@ -4166,7 +4168,8 @@ elf32_arm_create_or_find_stub_sec (asection **link_sec_p, asection *section, memcpy (s_name, link_sec->name, namelen); memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX)); - stub_sec = (*htab->add_stub_section) (s_name, link_sec, + out_sec = link_sec->output_section; + stub_sec = (*htab->add_stub_section) (s_name, out_sec, link_sec, htab->nacl_p ? 4 : 3); if (stub_sec == NULL) return NULL; @@ -4202,6 +4205,8 @@ elf32_arm_add_stub (const char *stub_name, TRUE, FALSE); if (stub_entry == NULL) { + if (section == NULL) + section = stub_sec; (*_bfd_error_handler) (_("%s: cannot create stub entry %s"), section->owner, stub_name); @@ -5216,6 +5221,7 @@ elf32_arm_size_stubs (bfd *output_bfd, struct bfd_link_info *info, bfd_signed_vma group_size, asection * (*add_stub_section) (const char *, asection *, + asection *, unsigned int), void (*layout_sections_again) (void)) { diff --git a/ld/ChangeLog b/ld/ChangeLog index 752f766e3b..e7a4316855 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2016-05-10 Thomas Preud'homme + + * emultempl/armelf.em (elf32_arm_add_stub_section): Add output_section + parameter and rename input_section parameter to after_input_section. + Append input stub section to the output section if after_input_section + is NULL. + 2016-05-10 Thomas Preud'homme * testsuite/ld-arm/arm-elf.exp (EABI attribute merging 10 (DSP)): New diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index 2e43172084..bfb7ee498a 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -203,12 +203,12 @@ hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp) static asection * elf32_arm_add_stub_section (const char * stub_sec_name, - asection * input_section, + asection * output_section, + asection * after_input_section, unsigned int alignment_power) { asection *stub_sec; flagword flags; - asection *output_section; lang_output_section_statement_type *os; struct hook_stub_info info; @@ -221,18 +221,34 @@ elf32_arm_add_stub_section (const char * stub_sec_name, bfd_set_section_alignment (stub_file->the_bfd, stub_sec, alignment_power); - output_section = input_section->output_section; os = lang_output_section_get (output_section); - info.input_section = input_section; + info.input_section = after_input_section; lang_list_init (&info.add); lang_add_section (&info.add, stub_sec, NULL, os); if (info.add.head == NULL) goto err_ret; - if (hook_in_stub (&info, &os->children.head)) - return stub_sec; + if (after_input_section == NULL) + { + lang_statement_union_type **lp = &os->children.head; + lang_statement_union_type *l, *lprev = NULL; + + for (; (l = *lp) != NULL; lp = &l->header.next, lprev = l); + + if (lprev) + lprev->header.next = info.add.head; + else + os->children.head = info.add.head; + + return stub_sec; + } + else + { + if (hook_in_stub (&info, &os->children.head)) + return stub_sec; + } err_ret: einfo ("%X%P: can not make stub section: %E\n");