diff options
author | Christophe Lyon <christophe.lyon@linaro.org> | 2019-11-25 08:55:37 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@linaro.org> | 2020-03-13 14:44:45 +0000 |
commit | abf874aafe3d717573e4a48bf0e3c6334e666a55 (patch) | |
tree | 48877a5c76632d003c4a64bea1b3a9eea74d4f96 /bfd | |
parent | 74e10d1742f1b8312359c59a2af06c9e661252b3 (diff) | |
download | gdb-abf874aafe3d717573e4a48bf0e3c6334e666a55.zip gdb-abf874aafe3d717573e4a48bf0e3c6334e666a55.tar.gz gdb-abf874aafe3d717573e4a48bf0e3c6334e666a55.tar.bz2 |
Add support for non-contiguous memory regions
2020-01-06 Christophe Lyon <christophe.lyon@linaro.org>
bfd/
* bfd-in2.h: Regenerate.
* section.c (asection): Add already_assigned field.
(BFD_FAKE_SECTION): Add default initializer for it.
* ecoff.c (bfd_debug_section): Initialize already_assigned field.
* elf32-arm.c (arm_build_one_stub): Add support for
non_contiguous_regions.
* elf32-csky.c (csky_build_one_stub): Likewise.
* elf32-hppa.c (hppa_build_one_stub): Likewise.
* elf32-m68hc11.c (m68hc11_elf_build_one_stub): Likewise.
* elf32-m68hc12.c (m68hc12_elf_build_one_stub): Likewise.
* elf32-metag.c (metag_build_one_stub): Likewise.
* elf32-nios2.c (nios2_build_one_stub): Likewise.
* elf64-ppc.c (ppc_build_one_stub): Likewise.
(ppc_size_one_stub): Likewise.
* elfnn-aarch64.c (aarch64_build_one_stub): Likewise.
* elflink.c (elf_link_input_bfd): Likewise.
include/
* bfdlink.h (bfd_link_info): Add non_contiguous_regions and
non_contiguous_regions_warnings fields.
ld/
* ldlang.c (lang_add_section): Add support for
non_contiguous_regions.
(size_input_section): Likewise.
(lang_size_sections_1): Likewise.
(process_insert_statements): Likewise.
* ldlex.h (option_values): Add OPTION_NON_CONTIGUOUS_REGIONS and
OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS.
* lexsup.c (ld_options): Add entries for
--enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings.
(parse_args): Handle it.
* NEWS: Add --enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings.
* ld.texi: Add --enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings documentation.
* emultempl/armelf.em (elf32_arm_add_stub_section): Add
SEC_LINKER_CREATED flag.
* emultempl/xtensaelf.em (ld_build_required_section_dependence):
Emit an error when --enable-non-contiguous-regions is used.
* testsuite/ld-elf/non-contiguous.d: New.
* testsuite/ld-elf/non-contiguous.ld: New.
* testsuite/ld-elf/non-contiguous.s: New.
* testsuite/ld-arm/arm-elf.exp: Run the new tests.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.s: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm2.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm4.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm4.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm5.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm5.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm6.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm6.ld: New.
* testsuite/ld-powerpc/powerpc.exp: Run new tests.
* testsuite/ld-powerpc/non-contiguous-powerpc.d: New.
* testsuite/ld-powerpc/non-contiguous-powerpc.ld: New.
* testsuite/ld-powerpc/non-contiguous-powerpc.sd: New.
* testsuite/ld-powerpc/non-contiguous-powerpc64.d: New.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 19 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 9 | ||||
-rw-r--r-- | bfd/ecoff.c | 6 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 11 | ||||
-rw-r--r-- | bfd/elf32-csky.c | 11 | ||||
-rw-r--r-- | bfd/elf32-hppa.c | 31 | ||||
-rw-r--r-- | bfd/elf32-m68hc11.c | 11 | ||||
-rw-r--r-- | bfd/elf32-m68hc12.c | 11 | ||||
-rw-r--r-- | bfd/elf32-metag.c | 15 | ||||
-rw-r--r-- | bfd/elf32-nios2.c | 13 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 50 | ||||
-rw-r--r-- | bfd/elflink.c | 12 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 16 | ||||
-rw-r--r-- | bfd/section.c | 9 |
14 files changed, 218 insertions, 6 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8b09093..84bc1e1 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,22 @@ +2020-03-13 Christophe Lyon <christophe.lyon@linaro.org> + + * bfd-in2.h: Regenerate. + * section.c (asection): Add already_assigned field. + (BFD_FAKE_SECTION): Add default initializer for it. + * ecoff.c (bfd_debug_section): Initialize already_assigned field. + * elf32-arm.c (arm_build_one_stub): Add support for + non_contiguous_regions. + * elf32-csky.c (csky_build_one_stub): Likewise. + * elf32-hppa.c (hppa_build_one_stub): Likewise. + * elf32-m68hc11.c (m68hc11_elf_build_one_stub): Likewise. + * elf32-m68hc12.c (m68hc12_elf_build_one_stub): Likewise. + * elf32-metag.c (metag_build_one_stub): Likewise. + * elf32-nios2.c (nios2_build_one_stub): Likewise. + * elf64-ppc.c (ppc_build_one_stub): Likewise. + (ppc_size_one_stub): Likewise. + * elfnn-aarch64.c (aarch64_build_one_stub): Likewise. + * elflink.c (elf_link_input_bfd): Likewise. + 2020-03-13 H.J. Lu <hongjiu.lu@intel.com> PR ld/24920 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 3711460..9859e51 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1192,6 +1192,10 @@ typedef struct bfd_section struct bfd_section *s; const char *linked_to_symbol_name; } map_head, map_tail; + /* Points to the output section this section is already assigned to, if any. + This is used when support for non-contiguous memory regions is enabled. */ + struct bfd_section *already_assigned; + } asection; /* Relax table contains information about instructions which can @@ -1373,7 +1377,10 @@ discarded_section (const asection *sec) (struct bfd_symbol *) SYM, &SEC.symbol, \ \ /* map_head, map_tail */ \ - { NULL }, { NULL } \ + { NULL }, { NULL }, \ + \ + /* already_assigned */ \ + NULL \ } /* We use a macro to initialize the static asymbol structures because diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 84eab99..ce8eb89 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -78,8 +78,10 @@ static asection bfd_debug_section = NULL, /* symbol_ptr_ptr, */ NULL, - /* map_head, map_tail */ - { NULL }, { NULL } + /* map_head, map_tail, */ + { NULL }, { NULL }, + /* already_assigned */ + NULL, }; /* Create an ECOFF object. */ diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index c899aeb..e8b2ac4 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -5064,6 +5064,17 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry; info = (struct bfd_link_info *) in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + globals = elf32_arm_hash_table (info); if (globals == NULL) return FALSE; diff --git a/bfd/elf32-csky.c b/bfd/elf32-csky.c index 6cf63f5..8415f7c 100644 --- a/bfd/elf32-csky.c +++ b/bfd/elf32-csky.c @@ -3621,6 +3621,17 @@ csky_build_one_stub (struct bfd_hash_entry *gen_entry, stub_entry = (struct elf32_csky_stub_hash_entry *)gen_entry; info = (struct bfd_link_info *) in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + globals = csky_elf_hash_table (info); if (globals == NULL) return FALSE; diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index b1b0f82..9760b75 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -731,6 +731,17 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) switch (hsh->stub_type) { case hppa_stub_long_branch: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + hsh->target_section); + abort(); + } + /* Create the long branch. A long branch is formed with "ldil" loading the upper bits of the target address into a register, then branching with "be" which adds in the lower bits. @@ -751,6 +762,16 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) break; case hppa_stub_long_branch_shared: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign %pA to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + hsh->target_section); + abort(); + } /* Branches are relative. This is where we are going to. */ sym_value = (hsh->target_value + hsh->target_section->output_offset @@ -823,6 +844,16 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) break; case hppa_stub_export: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign %pA to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + hsh->target_section); + abort(); + } /* Branches are relative. This is where we are going to. */ sym_value = (hsh->target_value + hsh->target_section->output_offset diff --git a/bfd/elf32-m68hc11.c b/bfd/elf32-m68hc11.c index 8d4d227..3e12ae5 100644 --- a/bfd/elf32-m68hc11.c +++ b/bfd/elf32-m68hc11.c @@ -415,6 +415,17 @@ m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry; info = (struct bfd_link_info *) in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + htab = m68hc11_elf_hash_table (info); if (htab == NULL) return FALSE; diff --git a/bfd/elf32-m68hc12.c b/bfd/elf32-m68hc12.c index e41b4c7..a04efd8 100644 --- a/bfd/elf32-m68hc12.c +++ b/bfd/elf32-m68hc12.c @@ -535,6 +535,17 @@ m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry; info = (struct bfd_link_info *) in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + htab = m68hc11_elf_hash_table (info); stub_sec = stub_entry->stub_sec; diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 07e9856..3f30d6d 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -3459,7 +3459,7 @@ metag_type_of_stub (asection *input_sec, #define MOV_PC_A0_3 0xa3180ca0 static bfd_boolean -metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED) +metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) { struct elf_metag_stub_hash_entry *hsh; asection *stub_sec; @@ -3467,9 +3467,22 @@ metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U bfd_byte *loc; bfd_vma sym_value; int size; + struct bfd_link_info *info; /* Massage our args to the form they really have. */ hsh = (struct elf_metag_stub_hash_entry *) gen_entry; + info = (struct bfd_link_info *) in_arg; + + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + hsh->target_section); + abort(); + } stub_sec = hsh->stub_sec; diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c index 2fcfe6f..8c8bc0c 100644 --- a/bfd/elf32-nios2.c +++ b/bfd/elf32-nios2.c @@ -2490,7 +2490,20 @@ nios2_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U = (struct elf32_nios2_stub_hash_entry *) gen_entry; asection *stub_sec = hsh->stub_sec; bfd_vma sym_value; + struct bfd_link_info *info; + + info = (struct bfd_link_info *) in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + hsh->target_section); + abort(); + } /* Make a note of the offset within the stubs for this entry. */ hsh->stub_offset = stub_sec->size; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index c804ab3..83eaadf 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -11362,6 +11362,31 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) stub_entry = (struct ppc_stub_hash_entry *) gen_entry; info = in_arg; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section != NULL + && stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + + /* Same for the group. */ + if (stub_entry->group->stub_sec != NULL + && stub_entry->group->stub_sec->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign group %pA target %pA to an " + "output section. Retry without " + "--enable-non-contiguous-regions.\n"), + stub_entry->group->stub_sec, + stub_entry->target_section); + abort(); + } + htab = ppc_hash_table (info); if (htab == NULL) return FALSE; @@ -11887,6 +11912,31 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) if (htab == NULL) return FALSE; + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section != NULL + && stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign %pA to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + + /* Same for the group. */ + if (stub_entry->group->stub_sec != NULL + && stub_entry->group->stub_sec->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign group %pA target %pA to an " + "output section. Retry without " + "--enable-non-contiguous-regions.\n"), + stub_entry->group->stub_sec, + stub_entry->target_section); + abort(); + } + /* Make a note of the offset within the stubs for this entry. */ stub_entry->stub_offset = stub_entry->group->stub_sec->size; diff --git a/bfd/elflink.c b/bfd/elflink.c index 5852844..589550e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -10569,6 +10569,18 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) discarding, we don't need to keep it. */ if (isym->st_shndx != SHN_UNDEF && isym->st_shndx < SHN_LORESERVE + && isec->output_section == NULL + && flinfo->info->non_contiguous_regions + && flinfo->info->non_contiguous_regions_warnings) + { + _bfd_error_handler (_("warning: --enable-non-contiguous-regions " + "discards section `%s' from '%s'\n"), + isec->name, isec->owner->filename); + continue; + } + + if (isym->st_shndx != SHN_UNDEF + && isym->st_shndx < SHN_LORESERVE && bfd_section_removed_from_list (output_bfd, isec->output_section)) continue; diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index ba3ad45..b00b6c4 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -3278,7 +3278,7 @@ _bfd_aarch64_add_stub_entry_after (const char *stub_name, static bfd_boolean aarch64_build_one_stub (struct bfd_hash_entry *gen_entry, - void *in_arg ATTRIBUTE_UNUSED) + void *in_arg) { struct elf_aarch64_stub_hash_entry *stub_entry; asection *stub_sec; @@ -3291,10 +3291,24 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry, unsigned int template_size; const uint32_t *template; unsigned int i; + struct bfd_link_info *info; /* Massage our args to the form they really have. */ stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry; + info = (struct bfd_link_info *) in_arg; + + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (stub_entry->target_section->output_section == NULL + && info->non_contiguous_regions) + { + _bfd_error_handler (_("Could not assign '%pA' to an output section. " + "Retry without --enable-non-contiguous-regions.\n"), + stub_entry->target_section); + abort(); + } + stub_sec = stub_entry->stub_sec; /* Make a note of the offset within the stubs for this entry. */ diff --git a/bfd/section.c b/bfd/section.c index 7de0a2d..eef118f 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -551,6 +551,10 @@ CODE_FRAGMENT . struct bfd_section *s; . const char *linked_to_symbol_name; . } map_head, map_tail; +. {* Points to the output section this section is already assigned to, if any. +. This is used when support for non-contiguous memory regions is enabled. *} +. struct bfd_section *already_assigned; +. .} asection; . .{* Relax table contains information about instructions which can @@ -732,7 +736,10 @@ CODE_FRAGMENT . (struct bfd_symbol *) SYM, &SEC.symbol, \ . \ . {* map_head, map_tail *} \ -. { NULL }, { NULL } \ +. { NULL }, { NULL }, \ +. \ +. {* already_assigned *} \ +. NULL \ . } . .{* We use a macro to initialize the static asymbol structures because |