From 5ed0fbad2b15c1a0419c4046fc11488811c68152 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 20 Oct 2020 10:44:37 +0100 Subject: [PATCH] Implement SHF_GNU_ABIND --- bfd/elf-bfd.h | 10 +- bfd/elf.c | 9 +- bfd/elflink.c | 133 ++++- binutils/readelf.c | 10 + gas/config/obj-elf.c | 47 +- gas/config/obj-elf.h | 1 + gas/testsuite/gas/elf/section10.d | 4 +- gas/testsuite/gas/elf/section10.s | 4 +- include/elf/common.h | 2 + include/elf/external.h | 14 + ld/configure.tgt | 1 - ld/ldelfgen.c | 568 ++++++++++++++++++++++ ld/ldlang.c | 8 +- ld/ldlang.h | 5 + ld/testsuite/ld-arm/abind-1.d | 49 ++ ld/testsuite/ld-arm/abind-1.s | 183 +++++++ ld/testsuite/ld-arm/arm-elf.exp | 2 + ld/testsuite/ld-elf/abind-1.s | 57 +++ ld/testsuite/ld-elf/abind-1a.d | 27 + ld/testsuite/ld-elf/abind-1a.ld | 28 ++ ld/testsuite/ld-elf/abind-1b.d | 27 + ld/testsuite/ld-elf/abind-1b.ld | 28 ++ ld/testsuite/ld-elf/abind-1c.d | 27 + ld/testsuite/ld-elf/abind-1c.ld | 28 ++ ld/testsuite/ld-elf/abind-1d.d | 27 + ld/testsuite/ld-elf/abind-1d.ld | 28 ++ ld/testsuite/ld-elf/abind-1e.d | 27 + ld/testsuite/ld-elf/abind-1e.ld | 27 + ld/testsuite/ld-elf/abind-1f.d | 27 + ld/testsuite/ld-elf/abind-1f.ld | 28 ++ ld/testsuite/ld-elf/abind-1g.d | 27 + ld/testsuite/ld-elf/abind-1g.ld | 27 + ld/testsuite/ld-elf/abind-1h.d | 27 + ld/testsuite/ld-elf/abind-1h.ld | 27 + ld/testsuite/ld-elf/abind-1i.d | 27 + ld/testsuite/ld-elf/abind-1i.ld | 22 + ld/testsuite/ld-elf/abind-2.s | 183 +++++++ ld/testsuite/ld-elf/abind-2a.d | 73 +++ ld/testsuite/ld-elf/abind-2a.ld | 28 ++ ld/testsuite/ld-elf/abind-2b.d | 73 +++ ld/testsuite/ld-elf/abind-2b.ld | 28 ++ ld/testsuite/ld-elf/abind-2c.d | 73 +++ ld/testsuite/ld-elf/abind-2c.ld | 27 + ld/testsuite/ld-elf/abind-2d.d | 73 +++ ld/testsuite/ld-elf/abind-2d.ld | 28 ++ ld/testsuite/ld-elf/abind-2e.d | 73 +++ ld/testsuite/ld-elf/abind-2e.ld | 27 + ld/testsuite/ld-elf/abind-2f.d | 73 +++ ld/testsuite/ld-elf/abind-2f.ld | 27 + ld/testsuite/ld-elf/abind-2g.d | 73 +++ ld/testsuite/ld-elf/abind-2g.ld | 22 + ld/testsuite/ld-msp430-elf/location-1.d | 23 + ld/testsuite/ld-msp430-elf/location-1.s | 98 ++++ ld/testsuite/ld-msp430-elf/location-2.d | 30 ++ ld/testsuite/ld-msp430-elf/location-2.s | 76 +++ ld/testsuite/ld-msp430-elf/location-3.d | 10 + ld/testsuite/ld-msp430-elf/location-3.s | 12 + ld/testsuite/ld-msp430-elf/msp430-elf.exp | 4 + ld/testsuite/ld-x86-64/abind-1.d | 54 ++ ld/testsuite/ld-x86-64/abind-1.s | 175 +++++++ ld/testsuite/ld-x86-64/x86-64.exp | 1 + 61 files changed, 2938 insertions(+), 19 deletions(-) create mode 100644 ld/testsuite/ld-arm/abind-1.d create mode 100644 ld/testsuite/ld-arm/abind-1.s create mode 100644 ld/testsuite/ld-elf/abind-1.s create mode 100644 ld/testsuite/ld-elf/abind-1a.d create mode 100644 ld/testsuite/ld-elf/abind-1a.ld create mode 100644 ld/testsuite/ld-elf/abind-1b.d create mode 100644 ld/testsuite/ld-elf/abind-1b.ld create mode 100644 ld/testsuite/ld-elf/abind-1c.d create mode 100644 ld/testsuite/ld-elf/abind-1c.ld create mode 100644 ld/testsuite/ld-elf/abind-1d.d create mode 100644 ld/testsuite/ld-elf/abind-1d.ld create mode 100644 ld/testsuite/ld-elf/abind-1e.d create mode 100644 ld/testsuite/ld-elf/abind-1e.ld create mode 100644 ld/testsuite/ld-elf/abind-1f.d create mode 100644 ld/testsuite/ld-elf/abind-1f.ld create mode 100644 ld/testsuite/ld-elf/abind-1g.d create mode 100644 ld/testsuite/ld-elf/abind-1g.ld create mode 100644 ld/testsuite/ld-elf/abind-1h.d create mode 100644 ld/testsuite/ld-elf/abind-1h.ld create mode 100644 ld/testsuite/ld-elf/abind-1i.d create mode 100644 ld/testsuite/ld-elf/abind-1i.ld create mode 100644 ld/testsuite/ld-elf/abind-2.s create mode 100644 ld/testsuite/ld-elf/abind-2a.d create mode 100644 ld/testsuite/ld-elf/abind-2a.ld create mode 100644 ld/testsuite/ld-elf/abind-2b.d create mode 100644 ld/testsuite/ld-elf/abind-2b.ld create mode 100644 ld/testsuite/ld-elf/abind-2c.d create mode 100644 ld/testsuite/ld-elf/abind-2c.ld create mode 100644 ld/testsuite/ld-elf/abind-2d.d create mode 100644 ld/testsuite/ld-elf/abind-2d.ld create mode 100644 ld/testsuite/ld-elf/abind-2e.d create mode 100644 ld/testsuite/ld-elf/abind-2e.ld create mode 100644 ld/testsuite/ld-elf/abind-2f.d create mode 100644 ld/testsuite/ld-elf/abind-2f.ld create mode 100644 ld/testsuite/ld-elf/abind-2g.d create mode 100644 ld/testsuite/ld-elf/abind-2g.ld create mode 100644 ld/testsuite/ld-msp430-elf/location-1.d create mode 100644 ld/testsuite/ld-msp430-elf/location-1.s create mode 100644 ld/testsuite/ld-msp430-elf/location-2.d create mode 100644 ld/testsuite/ld-msp430-elf/location-2.s create mode 100644 ld/testsuite/ld-msp430-elf/location-3.d create mode 100644 ld/testsuite/ld-msp430-elf/location-3.s create mode 100644 ld/testsuite/ld-x86-64/abind-1.d create mode 100644 ld/testsuite/ld-x86-64/abind-1.s diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index ffb75f7919..1dc08ba2ba 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1897,15 +1897,17 @@ struct output_elf_obj_tdata bfd_boolean flags_init; }; -/* Indicate if the bfd contains SHF_GNU_MBIND/SHF_GNU_RETAIN sections or - symbols that have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE - binding. Used to set the osabi field in the ELF header structure. */ +/* Indicate if the bfd contains SHF_GNU_MBIND, SHF_GNU_RETAIN or SHF_GNU_ABIND + sections or symbols that have the STT_GNU_IFUNC symbol type or + STB_GNU_UNIQUE binding. Used to set the osabi field in the ELF header + structure. */ enum elf_gnu_osabi { elf_gnu_osabi_mbind = 1 << 0, elf_gnu_osabi_ifunc = 1 << 1, elf_gnu_osabi_unique = 1 << 2, elf_gnu_osabi_retain = 1 << 3, + elf_gnu_osabi_abind = 1 << 4, }; typedef struct elf_section_list @@ -2035,7 +2037,7 @@ struct elf_obj_tdata ENUM_BITFIELD (dynamic_lib_link_class) dyn_lib_class : 4; /* Whether the bfd uses OS specific bits that require ELFOSABI_GNU. */ - ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 4; + ENUM_BITFIELD (elf_gnu_osabi) has_gnu_osabi : 5; /* Whether if the bfd contains the GNU_PROPERTY_NO_COPY_ON_PROTECTED property. */ diff --git a/bfd/elf.c b/bfd/elf.c index dc097e825a..5e30b1016a 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3284,8 +3284,13 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg) /* Don't clear sh_flags. Assembler may set additional bits. */ - if ((asect->flags & SEC_ALLOC) != 0 - || asect->user_set_vma) + if (!arg->link_info + && elf_section_flags (asect) & SHF_GNU_ABIND) + { + /* Don't clobber sh_addr already set for a GNU_ABIND section. */ + } + else if ((asect->flags & SEC_ALLOC) != 0 + || asect->user_set_vma) this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect); else this_hdr->sh_addr = 0; diff --git a/bfd/elflink.c b/bfd/elflink.c index 742254055c..d93e744cf1 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4044,6 +4044,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) size_t tabsize = 0; asection *s; bfd_boolean just_syms; + static bfd_boolean created_abind_init_sec = FALSE; htab = elf_hash_table (info); bed = get_elf_backend_data (abfd); @@ -4081,16 +4082,16 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) (_("alternate ELF machine code found (%d) in %pB, expecting %d"), ehdr->e_machine, abfd, bed->elf_machine_code); - /* As a GNU extension, any input sections which are named - .gnu.warning.SYMBOL are treated as warning symbols for the given - symbol. This differs from .gnu.warning sections, which generate - warnings when they are included in an output file. */ - /* PR 12761: Also generate this warning when building shared libraries. */ for (s = abfd->sections; s != NULL; s = s->next) { const char *name; name = bfd_section_name (s); + /* As a GNU extension, any input sections which are named + .gnu.warning.SYMBOL are treated as warning symbols for the given + symbol. This differs from .gnu.warning sections, which generate + warnings when they are included in an output file. */ + /* PR 12761: Also generate this warning when building shared libraries. */ if (CONST_STRNEQ (name, ".gnu.warning.")) { char *msg; @@ -4146,6 +4147,65 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) s->flags |= SEC_EXCLUDE; } } + else if (!bfd_link_relocatable (info) + && (elf_section_data (s)->this_hdr.sh_flags & SHF_GNU_ABIND)) + { + /* Orphan sections with the SHF_GNU_ABIND flag so they can be freely + moved around the statement list, by renaming them so they don't + match a linker script rule. */ + bfd_rename_section (s, concat (".gnu.abind", s->name, (const char *)NULL)); + + if (!created_abind_init_sec) + { + /* Create .gnu.abind_init_array and an undefined symbol for the + library function required to make use of it. */ + asection *s_init; + flagword flags = (SEC_HAS_CONTENTS | SEC_READONLY + | SEC_ALLOC | SEC_LOAD | SEC_KEEP); + + s_init = bfd_make_section_anyway_with_flags (abfd, ".gnu.abind_init_array", flags); + if (s_init == NULL) + { + _bfd_error_handler + (_("%pB: could not create .gnu.abind_init_array section\n"), abfd); + goto error_return; + } + + if (bed->s->arch_size == 64) + { + elf_section_data (s_init)->this_hdr.sh_entsize + = sizeof (Elf64_External_AbindInitArray_Entry); + bfd_set_section_alignment (s_init, 8); + } + else + { + elf_section_data (s_init)->this_hdr.sh_entsize + = sizeof (Elf32_External_AbindInitArray_Entry); + bfd_set_section_alignment (s_init, 4); + } + + /* Create an undefined symbol to ............. */ + struct bfd_link_hash_entry *h; + + h = bfd_link_hash_lookup (info->hash, "__run_gnu_abind_init_array", TRUE, FALSE, TRUE); + if (h == NULL) + { + _bfd_error_handler + (_("%pB: could not create __run_gnu_abind_init_array symbol\n"), abfd); + goto error_return; + } + if (h->type == bfd_link_hash_new) + { + h->type = bfd_link_hash_undefined; + h->u.undef.abfd = NULL; + h->non_ir_ref_regular = TRUE; + if (is_elf_hash_table (info->hash)) + ((struct elf_link_hash_entry *) h)->mark = 1; + bfd_link_add_undef (info->hash, h); + } + created_abind_init_sec = TRUE; + } + } } just_syms = ((s = abfd->sections) != NULL @@ -9801,6 +9861,66 @@ elf_link_output_symstrtab (struct elf_final_link_info *flinfo, return 1; } +static bfd_boolean +_elf_link_swap_out_abind_init_array (bfd *abfd) +{ + asection *init_sec, *s; + bfd_vma pos; + const struct elf_backend_data *bed; + int sizeof_addr; + + init_sec = bfd_get_section_by_name (abfd, ".gnu.abind_init_array"); + if (init_sec == NULL) + return TRUE; + + bed = get_elf_backend_data (abfd); + + if (bed->s->arch_size == 64) + { + elf_section_data (init_sec)->this_hdr.sh_entsize + = sizeof (Elf64_External_AbindInitArray_Entry); + sizeof_addr = 8; + } + else + { + elf_section_data (init_sec)->this_hdr.sh_entsize + = sizeof (Elf32_External_AbindInitArray_Entry); + sizeof_addr = 4; + } + + bfd_byte *data_contents = bfd_malloc (init_sec->size); + memset (data_contents, 0, init_sec->size); + pos = 0; + + for (s = abfd->sections; s != NULL; s = s->next) + { + if ((elf_section_flags (s) & SHF_GNU_ABIND) == 0 + /* .bss sections and those with LMA != VMA will require runtime + initialization using .gnu.abind_init_array. */ + || !(s->lma != s->vma + || (s->flags & (SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_CODE)) == 0)) + continue; + + if (pos >= init_sec->size) + { + _bfd_error_handler(_("%pB: .gnu.abind_init_array has incorrect size\n"), abfd); + return FALSE; + } + + /* FIXME Use a "swap_out" function to write out the entry. */ + /* When LMA == VMA, __run_gnu_abind_init_array knows the section is for + .bss and will instead zero-initialize for the given size. */ + memcpy (data_contents + pos, &s->vma, sizeof_addr); + pos += sizeof_addr; + memcpy (data_contents + pos, &s->lma, sizeof_addr); + pos += sizeof_addr; + memcpy (data_contents + pos, &s->size, sizeof_addr); + pos += sizeof_addr; + } + bfd_set_section_contents (abfd, init_sec, data_contents, 0, init_sec->size); + return TRUE; +} + /* Swap symbols out to the symbol table and flush the output symbols to the file. */ @@ -12823,6 +12943,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) goto return_local_hash_table; } + /* Swap out .gnu.abind_init_array. */ + _elf_link_swap_out_abind_init_array (abfd); + /* Now we know the size of the symtab section. */ if (bfd_get_symcount (abfd) > 0) { diff --git a/binutils/readelf.c b/binutils/readelf.c index e6ec99a2cc..f43687c1ed 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -5979,6 +5979,8 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags) /* 25 */ { STRING_COMMA_LEN ("VLE") }, /* GNU specific. */ /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") }, + /* GNU specific. */ + /* 27 */ { STRING_COMMA_LEN ("GNU_ABIND") }, }; if (do_section_details) @@ -6070,6 +6072,8 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags) case ELFOSABI_FREEBSD: if (flag == SHF_GNU_RETAIN) sindex = 26; + else if (flag == SHF_GNU_ABIND) + sindex = 27; /* Fall through */ case ELFOSABI_NONE: if (flag == SHF_GNU_MBIND) @@ -6148,6 +6152,12 @@ get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags) *p = 'R'; break; } + else if (flag == SHF_GNU_ABIND) + { + *p = 'a'; + break; + } + /* Fall through */ case ELFOSABI_NONE: if (flag == SHF_GNU_MBIND) diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 6586478975..2597b1018a 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -741,6 +741,7 @@ obj_elf_change_section (const char *name, elf_section_type (sec) = type; elf_section_flags (sec) = attr; elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info; + elf_section_data (sec)->this_hdr.sh_addr = match_p->sh_addr; /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ if (type == SHT_NOBITS) @@ -801,7 +802,14 @@ obj_elf_change_section (const char *name, | SEC_THREAD_LOCAL)) || ((elf_tdata (stdoutput)->has_gnu_osabi & elf_gnu_osabi_retain) && ((elf_section_flags (old_sec) ^ match_p->sh_flags) - & SHF_GNU_RETAIN))) + & SHF_GNU_RETAIN)) + /* Check GNU_ABIND state matches, and the address are the + same. */ + || ((elf_tdata (stdoutput)->has_gnu_osabi & elf_gnu_osabi_abind) + && (((elf_section_flags (old_sec) ^ match_p->sh_flags) + & SHF_GNU_ABIND) + || ((elf_section_data (old_sec)->this_hdr.sh_addr + != match_p->sh_addr))))) { if (ssect != NULL) as_warn (_("ignoring changed section attributes for %s"), name); @@ -867,6 +875,9 @@ obj_elf_parse_section_letters (char *str, size_t len, case 'R': *gnu_attr |= SHF_GNU_RETAIN; break; + case 'A': + *gnu_attr |= SHF_GNU_ABIND; + break; case '?': *is_clone = TRUE; break; @@ -1332,6 +1343,36 @@ obj_elf_section (int push) if ((gnu_attr & SHF_GNU_RETAIN) != 0) match.sh_flags |= SHF_GNU_RETAIN; + if ((gnu_attr & SHF_GNU_ABIND) != 0 && *input_line_pointer == ',') + { + char *save = input_line_pointer; + ++input_line_pointer; + SKIP_WHITESPACE (); + if (ISDIGIT (* input_line_pointer)) + { + char *t = input_line_pointer; + match.sh_addr = strtoul (input_line_pointer, + &input_line_pointer, 0); + if (match.sh_addr == (unsigned int) -1) + { + as_warn (_("invalid address for GNU_ABIND section: %s"), t); + match.sh_addr = 0; + } + } + else + { + as_warn (_("expected integer constant for GNU_ABIND section address")); + match.sh_addr = 0; + input_line_pointer = save; + } + } + else if ((attr & SHF_GNU_ABIND) != 0) + { + as_warn (_("address for SHF_GNU_ABIND not specified")); + attr &= ~SHF_GNU_ABIND; + } + + if (*input_line_pointer == ',') { char *save = input_line_pointer; @@ -1420,7 +1461,7 @@ obj_elf_section (int push) done: demand_empty_rest_of_line (); - if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0) + if ((gnu_attr & SHF_MASKOS) != 0) { struct elf_backend_data *bed; bfd_boolean mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0; @@ -1446,6 +1487,8 @@ obj_elf_section (int push) elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind; if ((gnu_attr & SHF_GNU_RETAIN) != 0) elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain; + if ((gnu_attr & SHF_GNU_ABIND) != 0) + elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_abind; attr |= gnu_attr; } diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 0a91ed462f..c5492cc8bc 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -108,6 +108,7 @@ struct elf_section_match const char * linked_to_symbol_name; unsigned int section_id; unsigned int sh_info; /* ELF section information. */ + bfd_vma sh_addr; /* ELF section address. */ bfd_vma sh_flags; /* ELF section flags. */ flagword flags; }; diff --git a/gas/testsuite/gas/elf/section10.d b/gas/testsuite/gas/elf/section10.d index 6aa7b088b1..8346d7b13c 100644 --- a/gas/testsuite/gas/elf/section10.d +++ b/gas/testsuite/gas/elf/section10.d @@ -18,7 +18,7 @@ #... [ ]*\[.*\][ ]+sec3 [ ]*PROGBITS.* -[ ]*\[.*fedff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\) +[ ]*\[.*fe9ff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*e900000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\) #... [ ]*\[.*\][ ]+sec4 [ ]*LOOS\+0x11[ ].* @@ -26,7 +26,7 @@ #... [ ]*\[.*\][ ]+sec5 [ ]*LOUSER\+0x9[ ].* -[ ]*\[.*fedf0000\]:.* EXCLUDE, OS \(.*ed00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\) +[ ]*\[.*fe9f0000\]:.* EXCLUDE, OS \(.*e900000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\) [ ]*\[.*\][ ]+.data.foo [ ]*LOUSER\+0x7f000000[ ].* [ ]*\[0+003\]: WRITE, ALLOC diff --git a/gas/testsuite/gas/elf/section10.s b/gas/testsuite/gas/elf/section10.s index d52b3458fb..1236045c3c 100644 --- a/gas/testsuite/gas/elf/section10.s +++ b/gas/testsuite/gas/elf/section10.s @@ -7,7 +7,7 @@ .word 2 # Make sure that specifying further arguments to .sections is still supported - .section sec3, "0xfedff000MS", %progbits, 32 + .section sec3, "0xfe9ff000MS", %progbits, 32 .word 3 # Make sure that extra flags can be set for well known sections as well. @@ -19,7 +19,7 @@ .word 5 # Test both together, with a quoted type value. - .section sec5, "0xfedf0000", "0x80000009" + .section sec5, "0xfe9f0000", "0x80000009" .word 6 # Test that declaring an extended version of a known special section works. diff --git a/include/elf/common.h b/include/elf/common.h index c01e562c78..babff115d9 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -555,6 +555,8 @@ #define SHF_MASKOS 0x0FF00000 /* New value, Oct 4, 1999 Draft */ #define SHF_GNU_BUILD_NOTE (1 << 20) /* Section contains GNU BUILD ATTRIBUTE notes. */ #define SHF_GNU_RETAIN (1 << 21) /* Section should not be garbage collected by the linker. */ +#define SHF_GNU_ABIND (1 << 22) /* Section should placed at a specific VMA. */ + #define SHF_MASKPROC 0xF0000000 /* Processor-specific semantics */ /* This used to be implemented as a processor specific section flag. diff --git a/include/elf/external.h b/include/elf/external.h index 230fdabd87..6f6e678dcd 100644 --- a/include/elf/external.h +++ b/include/elf/external.h @@ -311,6 +311,20 @@ typedef struct unsigned char a_val[8]; } Elf64_External_Auxv; +typedef struct +{ + unsigned char vma[4]; + unsigned char lma[4]; + unsigned char size[4]; +} Elf32_External_AbindInitArray_Entry; + +typedef struct +{ + unsigned char vma[8]; + unsigned char lma[8]; + unsigned char size[8]; +} Elf64_External_AbindInitArray_Entry; + /* Size of SHT_GROUP section entry. */ #define GRP_ENTRY_SIZE 4 diff --git a/ld/configure.tgt b/ld/configure.tgt index 70359301b5..9db64ed12d 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -584,7 +584,6 @@ moxie-*-*) targ_emul=elf32moxie ;; msp430-*-*) targ_emul=msp430elf targ_extra_emuls="msp430X" - targ_extra_ofiles=ldelfgen.o ;; mt-*elf) targ_emul=elf32mt targ_extra_ofiles=ldelfgen.o diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c index 3a5619435c..c1b9f8c1ab 100644 --- a/ld/ldelfgen.c +++ b/ld/ldelfgen.c @@ -30,11 +30,18 @@ #include "elf-bfd.h" #include "ldelfgen.h" +static bfd_boolean place_bound_sections (void); +static void dump_sections (lang_statement_list_type *root, lang_memory_region_type *r, int indent); + + void ldelf_map_segments (bfd_boolean need_layout) { int tries = 10; + if (!bfd_link_relocatable (&link_info)) + place_bound_sections (); + do { lang_relax_sections (need_layout); @@ -211,3 +218,564 @@ extern void ldelf_examine_strtab_for_ctf struct elf_strtab_hash *symstrtab ATTRIBUTE_UNUSED) {} #endif + + +/* Start SHF_GNU_ABIND handling. */ + +/* Insert __gnu_abind_init_array_{start,end} symbols at the start/end of + .gnu.abind_init_array. */ +static bfd_boolean +insert_abind_init_array_symbols (void) +{ + lang_statement_union_type * curr; + + lang_relax_sections (TRUE); + + for (curr = stat_ptr->head; curr != NULL; curr = curr->header.next) + { + switch (curr->header.type) + { + case lang_output_section_statement_enum: + if (curr->output_section_statement.bfd_section + && strcmp (curr->output_section_statement.bfd_section->name, + ".gnu.abind_init_array") == 0) + { + asection *os = curr->output_section_statement.bfd_section; + /* FIXME this gets orphaned at the end of the map file would be + good to attach it for aesthetics. */ + lang_add_assignment (exp_provide ("__gnu_abind_init_array_start", + exp_intop (os->vma), FALSE)); + lang_add_assignment (exp_provide ("__gnu_abind_init_array_end", + exp_intop (os->vma + os->size), + FALSE)); + return TRUE; + } + break; + default: + break; + } + } + return FALSE; +} + +/* Check a memory region exists at the address specified for the GNU_ABIND + section, and that we can place the section in that region. */ +static lang_memory_region_type * +get_region_for_abind (asection *sec, + bfd_boolean validate_flags ATTRIBUTE_UNUSED) +{ + bfd_vma addr = sec->vma; + lang_memory_region_type *r; + lang_memory_region_type *ret = NULL; + + for (r = get_memory_region_list (); r != NULL; r = r->next) + { + /* The default memory region spans the entire address space. Use it if + no other memory region contains the address. */ + if (strcmp ("*default*", r->name_list.name) == 0) + ret = r; + else if (addr >= r->origin && addr < (r->origin + r->length)) + { + /* FIXME/TODO Check the region we want to place the section in is + compatible with its type. */ +#if 0 + if (validate_flags + && (!verify_region_compatibility (r, stat_ptr, sec->flags))) + { + einfo (_("%P: warning: GNU_ABIND section '%s' is not compatible " + "with the memory region '%s' containing address 0x%v\n"), + sec->name, r->name_list.name, addr); + return NULL; + } +#endif + return r; + } + } + return ret; +} + + +/* Detach the output section S from the list that starts from ROOT. */ +static bfd_boolean +detach_output_sec (asection *s, lang_statement_list_type *root, + bfd_boolean dump) +{ + asection *os; + lang_statement_union_type * prev = NULL; + lang_statement_union_type * curr; + lang_output_section_statement_type * os_stat; + + for (curr = root->head; curr != NULL; curr = curr->header.next) + { + switch (curr->header.type) + { + case lang_output_section_statement_enum: + os_stat = &curr->output_section_statement; + if (!os_stat->bfd_section) + break; + + os = os_stat->bfd_section; + + if (os == s) + { + /* If this is the last statement, and we are detaching this + statement, we have to point the list tail to the previous + elements' next pointer. */ + if (curr->header.next == NULL) + root->tail = &prev->header.next; + + /* Adjust the next statement pointed to by the previous element. */ + if (prev == NULL) + root->head = curr->header.next; + else + prev->header.next = curr->header.next; + + /* This statement is no longer part of any list, so clear the next + element it points to. */ + curr->header.next = NULL; + + lang_relax_sections (TRUE); + return TRUE; + } + break; + + case lang_group_statement_enum: + if (detach_output_sec (s, &curr->group_statement.children, dump)) + return TRUE; + break; + + default: + break; + } + prev = curr; + } + return FALSE; +} + +static int +compare_abind_sec_vma (const void *a, const void *b) +{ + asection *asec = *(asection **) a, *bsec = *(asection **) b; + + if (asec->vma > bsec->vma) + return 1; + else if (asec->vma < bsec->vma) + return -1; + + return 0; +} + +/* Create a list of GNU_ABIND sections, sorted in ascending order of + their desired VMA. */ +static unsigned int +sort_abind_secs (asection ***sec_list_p) +{ + bfd *ibfd; + asection *sec; + asection **sec_list; + unsigned int sec_count = 0; + unsigned int list_size = 10; + + sec_list = (asection **) xmalloc (list_size * sizeof (asection *)); + *sec_list_p = sec_list; + + for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link.next) + for (sec = ibfd->sections; sec != NULL; sec = sec->next) + { + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour + || !(elf_section_flags (sec) & SHF_GNU_ABIND) + || (elf_section_flags (sec) & SEC_EXCLUDE) + || strcmp (sec->output_section->name, DISCARD_SECTION_NAME) == 0 + || sec->output_section == bfd_abs_section_ptr + || (link_info.gc_sections && !sec->gc_mark)) + continue; + + /* FIXME add an option to disable placement of lma != vma bound sections. */ + /*if (sec->output_section->lma != sec->output_section->vma)*/ + /*continue;*/ + + /* Before we go any further, validate the address of section. + We may not be able to place it there at all. */ + /*if (get_region_for_abind (sec, TRUE) == NULL)*/ + /*continue;*/ + + if (sec_count == list_size) + { + list_size *= 2; + sec_list = (asection **) + xrealloc (sec_list, list_size * sizeof (asection *)); + } + + sec_list[sec_count++] = sec; + + /* Sort the SHF_GNU_ABIND input sections by their specified VMA. */ + qsort (sec_list, sec_count, sizeof (asection *), &compare_abind_sec_vma); + } + return sec_count; +} + +/* Initialize a new lang_statement_union_type with the given output section + statement. */ +static lang_statement_union_type * +insert_os_stat (lang_output_section_statement_type *os_stat) +{ + lang_statement_union_type *new_stmt; + new_stmt = stat_alloc (sizeof (lang_output_section_statement_type)); + new_stmt->header.type = lang_output_section_statement_enum; + + new_stmt->output_section_statement = *os_stat; + new_stmt->output_section_statement.addr_tree = NULL; + new_stmt->header.next = NULL; + return new_stmt; +} + +/* Initialize an output section with a wild statement. */ +static void +insert_wild (lang_statement_list_type *list) +{ + lang_wild_statement_type *wild = NULL; + + wild = stat_alloc (sizeof (lang_wild_statement_type)); + wild->header.next = NULL; + wild->header.type = lang_wild_statement_enum; + + wild->filename = NULL; + wild->filenames_sorted = FALSE; + wild->section_flag_list = NULL; + wild->exclude_name_list = NULL; + wild->section_list = NULL; + wild->keep_sections = FALSE; + lang_list_init (&wild->children); + + *(list->tail) = (void *)wild; + list->tail = &wild->header.next; + + lang_relax_sections (TRUE); +} + +/* Return TRUE if this is the last output section statement in the entire statement list. */ +static bfd_boolean +is_last_real_os (lang_statement_union_type *os_stat) +{ + lang_statement_union_type *curr; + for (curr = os_stat->header.next; curr != NULL; curr = curr->header.next) + { + switch (curr->header.type) + { + case lang_output_section_statement_enum: + if (curr->output_section_statement.bfd_section + && (curr->output_section_statement.bfd_section->flags & SEC_ALLOC)) + return FALSE; + break; + default: + /* FIXME: Do we need to handle group statements? */ + break; + } + } + return TRUE; +} + + +/* Place SEC before the output section os_stat. If os_stat is NULL, there + should be free space at the desired address and we attach it to the + statement list as required. */ +static lang_output_section_statement_type * +move_abind_os (asection *sec, lang_statement_list_type *root) +{ + lang_statement_union_type * curr; + lang_statement_union_type * prev = NULL; + lang_statement_union_type * prev_os_stat = NULL; + lang_statement_union_type * insert_after = NULL; + bfd_vma addr = sec->vma; + lang_output_section_statement_type * os_stat; + asection *os; + const int dump = 0; + if (dump) + printf ("\nMoving %s\n", sec->name); + + /* We detached the output section statements for all GNU_ABIND sections + earlier. Find the statement for this output section, and reattach it. */ + os_stat = lang_output_section_find (sec->output_section->name); + os_stat->region = get_region_for_abind (sec, FALSE); + + /* Find the position in the statement list to insert this GNU_ABIND + section. */ + for (curr = root->head; curr != NULL; curr = curr->header.next) + { + switch (curr->header.type) + { + case lang_output_section_statement_enum: + if (curr->output_section_statement.bfd_section == NULL + || bfd_is_abs_section (curr->output_section_statement.bfd_section)) + { + /* Always keep a record of the last output section statement, so a + GNU_ABIND section can be attached after it. */ + prev_os_stat = prev = curr; + continue; + } + + os = curr->output_section_statement.bfd_section; + if (dump) + printf (" %s vma 0x%lx size 0x%lx\n", os->name, + os->vma, os->size); + + if (os->vma >= addr || (os->vma + os->size > addr)) + { + /* Between the end of the prev_os_stat and the end of this current + output section is the desired VMA for the GNU_ABIND section. + Insert the GNU_ABIND section after prev_os_stat. + If there is no prev_os_stat insert at the first suitable place in the overall + statement list, using insert_os_after to find that place. */ + if (prev_os_stat == NULL) + insert_after = *(insert_os_after ((lang_output_section_statement_type *)root->head)); + else + insert_after = prev_os_stat; + } + else if (curr->header.next == NULL || is_last_real_os (curr)) + { + /* Insert at the end of the statement list/after the last output + section. */ + insert_after = curr; + } + + if (insert_after != NULL) + { + lang_statement_union_type *new_stmt = insert_os_stat (os_stat); + new_stmt->output_section_statement.addr_tree = exp_intop (addr); + + if (dump) + { + if (insert_after->header.type == lang_output_section_statement_enum + && insert_after->output_section_statement.bfd_section) + printf (" INSERT %s HERE, after %s\n", sec->name, + insert_after->output_section_statement.bfd_section->name); + else + printf (" INSERT %s HERE, after unknown\n", sec->name); + } + + new_stmt->header.next = insert_after->header.next; + insert_after->header.next = new_stmt; + + if (insert_after->header.next == NULL) + root->tail = &new_stmt->header.next; + + return &new_stmt->output_section_statement; + } + prev_os_stat = curr; + break; + default: + if (dump) + printf (" statement type %d\n", curr->header.type); + break; + } + prev = curr; + } + return NULL; +} + +/* Place SHF_GNU_ABIND sections at their requested VMAs, if possible. */ +static bfd_boolean +place_bound_sections (void) +{ + bfd *ibfd; + asection *sec; + unsigned int num_abind; + lang_output_section_statement_type *os_stat; + unsigned int i; + asection **abind_secs; + + num_abind = sort_abind_secs (&abind_secs); + + if (num_abind == 0) + return TRUE; + + /* Detach the GNU_ABIND sections from the global statement list. This ensures that + regular sections are in accurate positions each time we go to look at + placing the GNU_ABIND section. + Create .abind_*_init_array entries if required. */ + for (i = 0; i < num_abind; i++) + { + static asection *init_sec = NULL; + struct elf_link_hash_entry *h; + + sec = abind_secs[i]->output_section; + + /* .bss sections and those with LMA != VMA will require runtime + initialization using .gnu.abind_init_array. */ + if ((sec->lma != sec->vma + || (sec->flags & (SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_CODE)) == 0)) + { + if (init_sec == NULL) + { + asection *s; + /* Find the input section version of .gnu.abind_init_array. + Changes to the size of the output section don't persist. */ + for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link.next) + for (s = ibfd->sections; s != NULL; s = s->next) + if (strcmp (s->name, ".gnu.abind_init_array") == 0) + init_sec = s; + + /* .gnu.abind_init_array should have been created in + elf_link_add_object_symbols. */ + if (init_sec == NULL) + { + einfo (_("%X%P: .gnu.abind_init_array has not been created\n")); + return FALSE; + } + } + + /* If the section will require a .gnu.abind_init_array entry, then additional + support from the run time library is required. + Verify that support is available by checking the + __run_gnu_abind_init_array has been resolved. */ + h = elf_link_hash_lookup (elf_hash_table (&link_info), + "__run_gnu_abind_init_array", + FALSE, FALSE, FALSE); + + if (h == NULL + || (h != NULL && (h->root.type != bfd_link_hash_defined))) + { + /* If we could restore the .gnu.abind section to its original name + and place it in its original output section, maybe this + error wouldn't have to be fatal. However, if the program requires + the section to be at a specific address, then it will not be + correct if we can't place the ABIND section. */ + einfo (_("%X%P: __run_gnu_abind_init_array symbol has not been resolved\n")); + + /* Report the remaining abind sections that can't be placed, then + quit. */ + for (; i < num_abind; i++) + { + if (!(sec->lma != sec->vma + || (sec->flags & (SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_CODE)) == 0)) + continue; + elf_section_flags (abind_secs[i]) &= ~SHF_GNU_ABIND; + elf_section_flags (abind_secs[i]->output_section) &= ~SHF_GNU_ABIND; + einfo (_("%X%P: SHF_GNU_ABIND section %s requires " + "initialization from __run_gnu_abind_init_array\n"), abind_secs[i]->name); + } + return FALSE; + } + bfd_set_section_size (init_sec, init_sec->size + + elf_section_data (init_sec)->this_hdr.sh_entsize); + } + + if (!detach_output_sec (abind_secs[i]->output_section, stat_ptr, FALSE)) + return FALSE; + } + + + for (i = 0; i < num_abind; i++) + { + lang_relax_sections (TRUE); + sec = abind_secs[i]; + os_stat = move_abind_os (sec, stat_ptr); + + if (os_stat == NULL) + { + einfo (_("%P: error: unable to place GNU_ABIND section %s\n"), sec->name); + continue; + } + + /* Refresh this bound section, which should only + ever contain a SHF_GNU_ABIND input section. */ + lang_list_init (&os_stat->children); + insert_wild (&os_stat->children); + /* We need to clear the output section before calling + lang_add_section. */ + sec->output_section = NULL; + lang_add_section (&os_stat->children.head->wild_statement.children, + sec, NULL, os_stat); + } + + if (!insert_abind_init_array_symbols ()) + { + einfo (_("%P: couldn't find .gnu.abind_init_array section to define " + "__gnu_abind_init_array_{start,end} symbols")); + return FALSE; + } + return TRUE; +} + +static void ATTRIBUTE_UNUSED +dump_sections (lang_statement_list_type *root, lang_memory_region_type *r, int indent) +{ + lang_statement_union_type * curr; + lang_output_section_statement_type * os_stat; + asection *s; + int i; + + for (curr = root->head; curr != NULL; curr = curr->header.next) + { + switch (curr->header.type) + { + case lang_input_section_enum: + s = curr->input_section.section; + + for (i = 0; i < indent; i++) + printf (" "); + if (s) + printf ("%s\n", s->name); + else + printf ("unknown input section\n"); + + break; + + case lang_output_section_statement_enum: + os_stat = &curr->output_section_statement; + for (i = 0; i < indent; i++) + printf (" "); + if (r != os_stat->region) + { + r = os_stat->region; + if (r) + printf ("\nNEW REGION %s\n---\n", r->name_list.name); + else + printf ("\nNEW UNKNOWN REGION\n---\n"); + } + s = curr->output_section_statement.bfd_section; + for (i = 0; i < indent; i++) + printf (" "); + if (s) + { + printf ("%s LMA: 0x%lx VMA: 0x%lx", s->name, s->lma, s->vma); + if (os_stat->lma_region) + printf (" LMA region = %s", os_stat->lma_region->name_list.name); + if (os_stat->region) + printf (" VMA region = %s", os_stat->region->name_list.name); + printf ("\n"); + } + else + printf ("unknown output section, curr region vma 0x%lx\n", os_stat->region->current); + + dump_sections (&curr->output_section_statement.children, curr->output_section_statement.region, indent + 1); + break; + + case lang_wild_statement_enum: + for (i = 0; i < indent; i++) + printf (" "); + printf ("wild statement\n"); + dump_sections (&curr->wild_statement.children, r, indent + 1); + break; + + case lang_group_statement_enum: + dump_sections (&curr->group_statement.children, r, indent + 1); + break; + + case lang_assignment_statement_enum: + if (1) + { + lang_assignment_statement_type *ass; + + ass = &curr->assignment_statement; + for (i = 0; i < indent; i++) + printf (" "); + printf ("assignment statement, dst = %s\n", ass->exp->assign.dst); + } + break; + + default: + break; + } + } +} diff --git a/ld/ldlang.c b/ld/ldlang.c index 4249b3a045..b8d260f780 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1345,6 +1345,12 @@ static lang_memory_region_type *lang_memory_region_list; static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list; +lang_memory_region_type * +get_memory_region_list () +{ + return lang_memory_region_list; +} + lang_memory_region_type * lang_memory_region_lookup (const char *const name, bfd_boolean create) { @@ -1798,7 +1804,7 @@ output_prev_sec_find (lang_output_section_statement_type *os) insert non-alloc note sections among assignments setting end of image symbols. */ -static lang_statement_union_type ** +lang_statement_union_type ** insert_os_after (lang_output_section_statement_type *after) { lang_statement_union_type **where; diff --git a/ld/ldlang.h b/ld/ldlang.h index 196debfa37..631e50d027 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -520,6 +520,8 @@ extern struct asneeded_minfo **asneeded_list_tail; extern void (*output_bfd_hash_table_free_fn) (struct bfd_link_hash_table *); +extern lang_memory_region_type * get_memory_region_list (void); + extern void lang_init (void); extern void lang_finish @@ -595,6 +597,9 @@ extern void ldlang_add_file extern lang_output_section_statement_type *lang_output_section_find_by_flags (const asection *, flagword, lang_output_section_statement_type **, lang_match_sec_type_func); + +extern lang_statement_union_type ** insert_os_after +(lang_output_section_statement_type *after); extern lang_output_section_statement_type *lang_insert_orphan (asection *, const char *, int, lang_output_section_statement_type *, struct orphan_save *, etree_type *, lang_statement_list_type *); diff --git a/ld/testsuite/ld-arm/abind-1.d b/ld/testsuite/ld-arm/abind-1.d new file mode 100644 index 0000000000..1b2ad44d56 --- /dev/null +++ b/ld/testsuite/ld-arm/abind-1.d @@ -0,0 +1,49 @@ +#name: SHF_GNU_ABIND 1 (using default linker script) +#source: abind-1.s +#ld: -e _start +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +00008000 t addr_0x8000_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +0000b002 r addr_0xb002 +#... +0000b100 t addr_0xb100 +#... +0000b200 r addr_0xb200_size_0x1000 +#... +0000c402 d addr_0xc402 +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0000e000 b addr_0xe000_size_0x1000 +#... +0000f000 b addr_0xf000 +#pass diff --git a/ld/testsuite/ld-arm/abind-1.s b/ld/testsuite/ld-arm/abind-1.s new file mode 100644 index 0000000000..68183a3bbb --- /dev/null +++ b/ld/testsuite/ld-arm/abind-1.s @@ -0,0 +1,183 @@ +/* abind-2*.ld linker scripts don't have rules for uniquely named sections. + This means they will be orphaned which will better test the intermixing of + .abind and regular sections, instead of just having one large indivisible + block for each output section. */ + +/* Arbitrary sized .data sections. */ + .section .data.size_0x1,"aw" + .type data_size_0x1, %object +data_size_0x1: + .zero 0x1 + + .section .data.size_0x10,"aw" + .type data_size_0x10, %object +data_size_0x10: + .zero 0x10 + + .section .data.size_0x80,"aw" + .type data_size_0x80, %object +data_size_0x80: + .zero 0x80 + + .section .data.size_0x100,"aw" + .type data_size_0x100, %object +data_size_0x100: + .zero 0x100 + + .section .data.size_0x800,"aw" + .type data_size_0x800, %object +data_size_0x800: + .zero 0x800 + + .section .data.size_0x1000,"aw" + .type data_size_0x1000, %object +data_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .bss sections. */ + + .section .bss.size_0x1,"aw",%nobits + .type bss_size_0x1, %object +bss_size_0x1: + .zero 0x1 + + .section .bss.size_0x10,"aw",%nobits + .type bss_size_0x10, %object +bss_size_0x10: + .zero 0x10 + + .section .bss.size_0x80,"aw",%nobits + .type bss_size_0x80, %object +bss_size_0x80: + .zero 0x80 + + .section .bss.size_0x100,"aw",%nobits + .type bss_size_0x100, %object +bss_size_0x100: + .zero 0x100 + + .section .bss.size_0x800,"aw",%nobits + .type bss_size_0x800, %object +bss_size_0x800: + .zero 0x800 + + .section .bss.size_0x1000,"aw",%nobits + .type bss_size_0x1000, %object +bss_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .text sections. */ + + .section .text.size_0x1,"ax",%progbits + .type text_size_0x1, %function +text_size_0x1: + .zero 0x1 + + .section .text.size_0x10,"ax",%progbits + .type text_size_0x10, %function +text_size_0x10: + .zero 0x10 + + .section .text.size_0x80,"ax",%progbits + .type text_size_0x80, %function +text_size_0x80: + .zero 0x80 + + .section .text.size_0x100,"ax",%progbits + .type text_size_0x100, %function +text_size_0x100: + .zero 0x100 + + .section .text.size_0x800,"ax",%progbits + .type text_size_0x800, %function +text_size_0x800: + .zero 0x800 + + .section .text.size_0x1000,"ax",%progbits + .type text_size_0x1000, %function +text_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .rodata sections. */ + + .section .rodata.size_0x1,"a" + .type rodata_size_0x1, %object +rodata_size_0x1: + .zero 0x1 + + .section .rodata.size_0x10,"a" + .type rodata_size_0x10, %object +rodata_size_0x10: + .zero 0x10 + + .section .rodata.size_0x80,"a" + .type rodata_size_0x80, %object +rodata_size_0x80: + .zero 0x80 + + .section .rodata.size_0x100,"a" + .type rodata_size_0x100, %object +rodata_size_0x100: + .zero 0x100 + + .section .rodata.size_0x800,"a" + .type rodata_size_0x800, %object +rodata_size_0x800: + .zero 0x800 + + .section .rodata.size_0x1000,"a" + .type rodata_size_0x1000, %object +rodata_size_0x1000: + .zero 0x1000 + +/* Start .gnu.abind sections. */ + +/* Fix a large section to the start of the region used for the LMA region of + the .data sections. This will expose any placement issues causing + overlapping LMAs. */ + .section .text.addr_0x8000,"axA",%progbits,0x8000 + .type addr_0x8000, %function +addr_0x8000_size_0x1000: + .zero 0x1000 + + .section .rodata.addr_0xb002,"aA",0xb002 + .type addr_0xb002, %object +addr_0xb002: + .byte 2 + + .section .text.addr_0xb100,"axA",%progbits,0xb100 + .type addr_0xb100, %function +addr_0xb100: + .zero 2 + + .section .rodata.addr_0xb200,"aA",0xb200 + .type addr_0xb200, %object +addr_0xb200_size_0x1000: + .zero 0x1000 + + .section .data.addr_0xc402,"awA",0xc402 + .type addr_0xc402, %object +addr_0xc402: + .zero 2 + + .section .bss.addr_0xe000,"awA",%nobits,0xe000 + .type addr_0xe000, %object +addr_0xe000_size_0x1000: + .zero 0x1000 + + .section .bss.addr_0xf000,"awA",%nobits,0x0f000 + .type addr_0xf000, %object +addr_0xf000: + .zero 1 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 + + .section .text.__run_gnu_abind_init_array,"ax",%progbits + .global __run_gnu_abind_init_array + .type __run_gnu_abind_init_array, %function +__run_gnu_abind_init_array: + .word 0 diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 0b47d636df..11b06b28a6 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -1269,6 +1269,8 @@ run_dump_test "non-contiguous-arm4" run_dump_test "non-contiguous-arm5" run_dump_test "non-contiguous-arm6" +run_dump_test "abind-1" + if { ![istarget "arm*-*-nacl*"] } { run_dump_test "thumb-plt" run_dump_test "thumb-plt-got" diff --git a/ld/testsuite/ld-elf/abind-1.s b/ld/testsuite/ld-elf/abind-1.s new file mode 100644 index 0000000000..aa3f1fcf82 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1.s @@ -0,0 +1,57 @@ +/* This should get placed before addr_0x8200, at 0x8000. */ + .section .data.size_0x100,"aw" + .type size_0x100, %object +size_0x100: + .zero 0x100 + +/* This should get placed after addr_0x8200. */ + .section .bss.size_0x150,"aw",%nobits + .type size_0x150, %object +size_0x150: + .zero 0x150 + + .section .data.addr_0x8200,"awA",0x8200 + .type addr_0x8200, %object +addr_0x8200: + .short 1 + + .section .bss.addr_0x9000,"awA",%nobits,0x9000 + .type addr_0x9000, %object +addr_0x9000: + .zero 1 + +/* This should be the last section in the region. */ + .section .bss.addr_0xa000,"awA",%nobits,0xa000 + .type addr_0xa000, %object +addr_0xa000: + .zero 1 + +/* Fix a large section to the start of the region used for the LMA region of + the .data sections. This will expose any placement issues causing + overlapping LMAs. */ + .section .text.addr_0x0,"axA",%progbits,0x0 + .type addr_0x0, %function +addr_0x0: + .zero 0x1000 + + .section .text.size_0x500,"ax",%progbits + .type size_0x500, %function +size_0x500: + .zero 0x1000 + + .section .rodata.addr_0x1002,"aA",0x1002 + .type addr_0x1002, %object +addr_0x1002: + .byte 2 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 + + .section .text.__run_gnu_abind_init_array,"ax",%progbits + .global __run_gnu_abind_init_array + .type __run_gnu_abind_init_array, %function +__run_gnu_abind_init_array: + .word 0 diff --git a/ld/testsuite/ld-elf/abind-1a.d b/ld/testsuite/ld-elf/abind-1a.d new file mode 100644 index 0000000000..1b758fef59 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1a.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1a +#source: abind-1.s +#ld: -e _start -T abind-1a.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +[0-9a-f]+ . size_0x150 +#... +0+8200 . addr_0x8200 +#... +[0-9a-f]+ . size_0x100 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1a.ld b/ld/testsuite/ld-elf/abind-1a.ld new file mode 100644 index 0000000000..dd3a18ef70 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1a.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x7fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x7fff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .text : + { + *(.text .text.*) + } > ROM + + .rodata : + { + *(.rodata .rodata.*) + } > ROM + + .data : + { + *(.data .data.*) + } > RAM AT> ROM +} diff --git a/ld/testsuite/ld-elf/abind-1b.d b/ld/testsuite/ld-elf/abind-1b.d new file mode 100644 index 0000000000..41c926529a --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1b.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1b +#source: abind-1.s +#ld: -e _start -T abind-1b.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +[0-9a-f]+ . size_0x100 +#... +0+8200 . addr_0x8200 +#... +[0-9a-f]+ . size_0x150 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1b.ld b/ld/testsuite/ld-elf/abind-1b.ld new file mode 100644 index 0000000000..99f9163b7f --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1b.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x6fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x6fff +} + +SECTIONS +{ + .data : + { + *(.data .data.*) + } > RAM AT> ROM + + .bss : + { + *(.bss .bss.*) + } > RAM + + .text : + { + *(.text .text.*) + } > ROM + + .rodata : + { + *(.rodata .rodata.*) + } > ROM +} diff --git a/ld/testsuite/ld-elf/abind-1c.d b/ld/testsuite/ld-elf/abind-1c.d new file mode 100644 index 0000000000..740e6b112d --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1c.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1c +#source: abind-1.s +#ld: -e _start -T abind-1c.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +[0-9a-f]+ . size_0x150 +#... +0+8200 . addr_0x8200 +#... +[0-9a-f]+ . size_0x100 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1c.ld b/ld/testsuite/ld-elf/abind-1c.ld new file mode 100644 index 0000000000..1587ef028e --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1c.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x6fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x6fff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .text : + { + *(.text .text.*) + } > ROM + + .data : + { + *(.data .data.*) + } > RAM AT> ROM + + .rodata : + { + *(.rodata .rodata.*) + } > ROM +} diff --git a/ld/testsuite/ld-elf/abind-1d.d b/ld/testsuite/ld-elf/abind-1d.d new file mode 100644 index 0000000000..9c2e64dc4c --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1d.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1d +#source: abind-1.s +#ld: -e _start -T abind-1d.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +[0-9a-f]+ . size_0x150 +#... +0+8200 . addr_0x8200 +#... +[0-9a-f]+ . size_0x100 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1d.ld b/ld/testsuite/ld-elf/abind-1d.ld new file mode 100644 index 0000000000..852e03e645 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1d.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x6fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x6fff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM AT> ROM + + .text : + { + *(.text .text.*) + } > ROM + + .rodata : + { + *(.rodata .rodata.*) + } > ROM +} diff --git a/ld/testsuite/ld-elf/abind-1e.d b/ld/testsuite/ld-elf/abind-1e.d new file mode 100644 index 0000000000..ac1a78654f --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1e.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1e (No LMA region) +#source: abind-1.s +#ld: -e _start -T abind-1e.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x150 +#... +[0-9a-f]+ . size_0x100 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +0+8200 . addr_0x8200 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1e.ld b/ld/testsuite/ld-elf/abind-1e.ld new file mode 100644 index 0000000000..58b3dc075a --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1e.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0xefff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM + + .text : + { + *(.text .text.*) + } > RAM + + .rodata : + { + *(.rodata .rodata.*) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-1f.d b/ld/testsuite/ld-elf/abind-1f.d new file mode 100644 index 0000000000..2981a4e6d1 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1f.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1f (Placement in other region) +#source: abind-1.s +#ld: -e _start -T abind-1f.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x150 +#... +[0-9a-f]+ . size_0x100 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +0+8200 . addr_0x8200 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1f.ld b/ld/testsuite/ld-elf/abind-1f.ld new file mode 100644 index 0000000000..7a655e0262 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1f.ld @@ -0,0 +1,28 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0x9fff + VECT : ORIGIN = 0xa000, LENGTH = 0x4 +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM + + .text : + { + *(.text .text.*) + } > RAM + + .rodata : + { + *(.rodata .rodata.*) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-1g.d b/ld/testsuite/ld-elf/abind-1g.d new file mode 100644 index 0000000000..90807c4951 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1g.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1g (Placement outside region) +#source: abind-1.s +#ld: -e _start -T abind-1g.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x150 +#... +[0-9a-f]+ . size_0x100 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +0+8200 . addr_0x8200 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1g.ld b/ld/testsuite/ld-elf/abind-1g.ld new file mode 100644 index 0000000000..8749d74626 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1g.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0x9fff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM + + .text : + { + *(.text .text.*) + } > RAM + + .rodata : + { + *(.rodata .rodata.*) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-1h.d b/ld/testsuite/ld-elf/abind-1h.d new file mode 100644 index 0000000000..a17f5d47a0 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1h.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1h (No flags set on region) +#source: abind-1.s +#ld: -e _start -T abind-1h.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x150 +#... +[0-9a-f]+ . size_0x100 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +0+8200 . addr_0x8200 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1h.ld b/ld/testsuite/ld-elf/abind-1h.ld new file mode 100644 index 0000000000..8092bb40d6 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1h.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM : ORIGIN = 0x0000, LENGTH = 0xafff +} + +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } > RAM + + .data : + { + *(.data .data.*) + } > RAM + + .text : + { + *(.text .text.*) + } > RAM + + .rodata : + { + *(.rodata .rodata.*) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-1i.d b/ld/testsuite/ld-elf/abind-1i.d new file mode 100644 index 0000000000..17696c3760 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1i.d @@ -0,0 +1,27 @@ +#name: SHF_GNU_ABIND 1i (No memory regions) +#source: abind-1.s +#ld: -e _start -T abind-1i.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 . addr_0x0 +#... +0+1002 . addr_0x1002 +#... +[0-9a-f]+ . size_0x150 +#... +[0-9a-f]+ . size_0x100 +#... +[0-9a-f]+ . size_0x500 +#... +[0-9a-f]+ . _start +#... +[0-9a-f]+ . __run_gnu_abind_init_array +#... +0+8200 . addr_0x8200 +#... +0+9000 . addr_0x9000 +#... +0+a000 . addr_0xa000 +#pass diff --git a/ld/testsuite/ld-elf/abind-1i.ld b/ld/testsuite/ld-elf/abind-1i.ld new file mode 100644 index 0000000000..9b763c7387 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-1i.ld @@ -0,0 +1,22 @@ +SECTIONS +{ + .bss : + { + *(.bss .bss.*) + } + + .data : + { + *(.data .data.*) + } + + .text : + { + *(.text .text.*) + } + + .rodata : + { + *(.rodata .rodata.*) + } +} diff --git a/ld/testsuite/ld-elf/abind-2.s b/ld/testsuite/ld-elf/abind-2.s new file mode 100644 index 0000000000..75777e4817 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2.s @@ -0,0 +1,183 @@ +/* abind-2*.ld linker scripts don't have rules for uniquely named sections. + This means they will be orphaned which will better test the intermixing of + .abind and regular sections, instead of just having one large indivisible + block for each output section. */ + +/* Arbitrary sized .data sections. */ + .section .data.size_0x1,"aw" + .type data_size_0x1, %object +data_size_0x1: + .zero 0x1 + + .section .data.size_0x10,"aw" + .type data_size_0x10, %object +data_size_0x10: + .zero 0x10 + + .section .data.size_0x80,"aw" + .type data_size_0x80, %object +data_size_0x80: + .zero 0x80 + + .section .data.size_0x100,"aw" + .type data_size_0x100, %object +data_size_0x100: + .zero 0x100 + + .section .data.size_0x800,"aw" + .type data_size_0x800, %object +data_size_0x800: + .zero 0x800 + + .section .data.size_0x1000,"aw" + .type data_size_0x1000, %object +data_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .bss sections. */ + + .section .bss.size_0x1,"aw",%nobits + .type bss_size_0x1, %object +bss_size_0x1: + .zero 0x1 + + .section .bss.size_0x10,"aw",%nobits + .type bss_size_0x10, %object +bss_size_0x10: + .zero 0x10 + + .section .bss.size_0x80,"aw",%nobits + .type bss_size_0x80, %object +bss_size_0x80: + .zero 0x80 + + .section .bss.size_0x100,"aw",%nobits + .type bss_size_0x100, %object +bss_size_0x100: + .zero 0x100 + + .section .bss.size_0x800,"aw",%nobits + .type bss_size_0x800, %object +bss_size_0x800: + .zero 0x800 + + .section .bss.size_0x1000,"aw",%nobits + .type bss_size_0x1000, %object +bss_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .text sections. */ + + .section .text.size_0x1,"ax",%progbits + .type text_size_0x1, %function +text_size_0x1: + .zero 0x1 + + .section .text.size_0x10,"ax",%progbits + .type text_size_0x10, %function +text_size_0x10: + .zero 0x10 + + .section .text.size_0x80,"ax",%progbits + .type text_size_0x80, %function +text_size_0x80: + .zero 0x80 + + .section .text.size_0x100,"ax",%progbits + .type text_size_0x100, %function +text_size_0x100: + .zero 0x100 + + .section .text.size_0x800,"ax",%progbits + .type text_size_0x800, %function +text_size_0x800: + .zero 0x800 + + .section .text.size_0x1000,"ax",%progbits + .type text_size_0x1000, %function +text_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .rodata sections. */ + + .section .rodata.size_0x1,"a" + .type rodata_size_0x1, %object +rodata_size_0x1: + .zero 0x1 + + .section .rodata.size_0x10,"a" + .type rodata_size_0x10, %object +rodata_size_0x10: + .zero 0x10 + + .section .rodata.size_0x80,"a" + .type rodata_size_0x80, %object +rodata_size_0x80: + .zero 0x80 + + .section .rodata.size_0x100,"a" + .type rodata_size_0x100, %object +rodata_size_0x100: + .zero 0x100 + + .section .rodata.size_0x800,"a" + .type rodata_size_0x800, %object +rodata_size_0x800: + .zero 0x800 + + .section .rodata.size_0x1000,"a" + .type rodata_size_0x1000, %object +rodata_size_0x1000: + .zero 0x1000 + +/* Start .gnu.abind sections. */ + +/* Fix a large section to the start of the region used for the LMA region of + the .data sections. This will expose any placement issues causing + overlapping LMAs. */ + .section .text.addr_0x0,"axA",%progbits,0x0 + .type addr_0x0, %function +addr_0x0_size_0x1000: + .zero 0x1000 + + .section .rodata.addr_0x1002,"aA",0x1002 + .type addr_0x1002, %object +addr_0x1002: + .byte 2 + + .section .text.addr_0x2000,"axA",%progbits,0x2000 + .type addr_0x2000, %function +addr_0x2000: + .zero 2 + + .section .rodata.addr_0x3002,"aA",0x3002 + .type addr_0x3002, %object +addr_0x3002_size_0x1000: + .zero 0x1000 + + .section .data.addr_0x8000,"awA",0x8000 + .type addr_0x8000, %object +addr_0x8000: + .zero 2 + + .section .bss.addr_0x9000,"awA",%nobits,0x9000 + .type addr_0x9000, %object +addr_0x9000_size_0x1000: + .zero 0x1000 + + .section .bss.addr_0xd000,"awA",%nobits,0xd000 + .type addr_0xd000, %object +addr_0xd000: + .zero 1 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 + + .section .text.__run_gnu_abind_init_array,"ax",%progbits + .global __run_gnu_abind_init_array + .type __run_gnu_abind_init_array, %function +__run_gnu_abind_init_array: + .word 0 diff --git a/ld/testsuite/ld-elf/abind-2a.d b/ld/testsuite/ld-elf/abind-2a.d new file mode 100644 index 0000000000..ec247ac951 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2a.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2a +#source: abind-2.s +#ld: -e _start -T abind-2a.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . text_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+8000 d addr_0x8000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2a.ld b/ld/testsuite/ld-elf/abind-2a.ld new file mode 100644 index 0000000000..517366f395 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2a.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x7fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x7fff +} + +SECTIONS +{ + .text : + { + *(.text) + } > ROM + + .rodata : + { + *(.rodata) + } > ROM + + .data : + { + *(.data) + } > RAM AT> ROM + + .bss : + { + *(.bss) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-2b.d b/ld/testsuite/ld-elf/abind-2b.d new file mode 100644 index 0000000000..66057ab3bd --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2b.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2b +#source: abind-2.s +#ld: -e _start -T abind-2b.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . text_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+8000 d addr_0x8000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2b.ld b/ld/testsuite/ld-elf/abind-2b.ld new file mode 100644 index 0000000000..e180fabedb --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2b.ld @@ -0,0 +1,28 @@ +MEMORY +{ + ROM (rx) : ORIGIN = 0x0000, LENGTH = 0x7fff + RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x7fff +} + +SECTIONS +{ + .text : + { + *(.text) + } > ROM + + .rodata : + { + *(.rodata) + } > ROM + + .bss : + { + *(.bss) + } > RAM + + .data : + { + *(.data) + } > RAM AT> ROM +} diff --git a/ld/testsuite/ld-elf/abind-2c.d b/ld/testsuite/ld-elf/abind-2c.d new file mode 100644 index 0000000000..74f62a36f1 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2c.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2c +#source: abind-2.s +#ld: -e _start -T abind-2c.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +0+8000 d addr_0x8000 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2c.ld b/ld/testsuite/ld-elf/abind-2c.ld new file mode 100644 index 0000000000..3c553f4b31 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2c.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0xefff +} + +SECTIONS +{ + .bss : + { + *(.bss) + } > RAM + + .data : + { + *(.data) + } > RAM + + .text : + { + *(.text) + } > RAM + + .rodata : + { + *(.rodata) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-2d.d b/ld/testsuite/ld-elf/abind-2d.d new file mode 100644 index 0000000000..1fb480843f --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2d.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2d +#source: abind-2.s +#ld: -e _start -T abind-2d.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +0+8000 d addr_0x8000 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2d.ld b/ld/testsuite/ld-elf/abind-2d.ld new file mode 100644 index 0000000000..00b375bfbe --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2d.ld @@ -0,0 +1,28 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0xcfff + VECT : ORIGIN = 0xd000, LENGTH = 0x4 +} + +SECTIONS +{ + .bss : + { + *(.bss) + } > RAM + + .data : + { + *(.data) + } > RAM + + .text : + { + *(.text) + } > RAM + + .rodata : + { + *(.rodata) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-2e.d b/ld/testsuite/ld-elf/abind-2e.d new file mode 100644 index 0000000000..ff15f34de8 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2e.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2e +#source: abind-2.s +#ld: -e _start -T abind-2e.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +0+8000 d addr_0x8000 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2e.ld b/ld/testsuite/ld-elf/abind-2e.ld new file mode 100644 index 0000000000..b1bb54b3a4 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2e.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0xcfff +} + +SECTIONS +{ + .bss : + { + *(.bss) + } > RAM + + .data : + { + *(.data) + } > RAM + + .text : + { + *(.text) + } > RAM + + .rodata : + { + *(.rodata) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-2f.d b/ld/testsuite/ld-elf/abind-2f.d new file mode 100644 index 0000000000..8a59b5da79 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2f.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2f +#source: abind-2.s +#ld: -e _start -T abind-2f.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +0+8000 d addr_0x8000 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2f.ld b/ld/testsuite/ld-elf/abind-2f.ld new file mode 100644 index 0000000000..4867878538 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2f.ld @@ -0,0 +1,27 @@ +MEMORY +{ + RAM : ORIGIN = 0x0000, LENGTH = 0xdfff +} + +SECTIONS +{ + .bss : + { + *(.bss) + } > RAM + + .data : + { + *(.data) + } > RAM + + .text : + { + *(.text) + } > RAM + + .rodata : + { + *(.rodata) + } > RAM +} diff --git a/ld/testsuite/ld-elf/abind-2g.d b/ld/testsuite/ld-elf/abind-2g.d new file mode 100644 index 0000000000..7084f5fcee --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2g.d @@ -0,0 +1,73 @@ +#name: SHF_GNU_ABIND 2g +#source: abind-2.s +#ld: -e _start -T abind-2g.ld +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+0000 t addr_0x0_size_0x1000 +#... +[0-9a-f]+ . bss_size_0x1 +#... +0+1002 r addr_0x1002 +#... +[0-9a-f]+ . bss_size_0x10 +#... +[0-9a-f]+ . bss_size_0x80 +#... +[0-9a-f]+ . bss_size_0x100 +#... +[0-9a-f]+ . bss_size_0x800 +#... +0+2000 t addr_0x2000 +#... +[0-9a-f]+ . bss_size_0x1000 +#... +0+3002 r addr_0x3002_size_0x1000 +#... +[0-9a-f]+ . data_size_0x1 +#... +[0-9a-f]+ . data_size_0x10 +#... +[0-9a-f]+ . data_size_0x80 +#... +[0-9a-f]+ . data_size_0x100 +#... +[0-9a-f]+ . data_size_0x800 +#... +[0-9a-f]+ . data_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +#... +[0-9a-f]+ . text_size_0x10 +#... +[0-9a-f]+ . text_size_0x80 +#... +[0-9a-f]+ . text_size_0x100 +#... +[0-9a-f]+ . text_size_0x800 +#... +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +#... +[0-9a-f]+ T __run_gnu_abind_init_array +#... +[0-9a-f]+ . rodata_size_0x1 +#... +[0-9a-f]+ . rodata_size_0x10 +#... +[0-9a-f]+ . rodata_size_0x80 +#... +[0-9a-f]+ . rodata_size_0x100 +#... +[0-9a-f]+ . rodata_size_0x800 +#... +0+8000 d addr_0x8000 +#... +0+9000 b addr_0x9000_size_0x1000 +#... +[0-9a-f]+ . rodata_size_0x1000 +#... +0+d000 b addr_0xd000 +#pass diff --git a/ld/testsuite/ld-elf/abind-2g.ld b/ld/testsuite/ld-elf/abind-2g.ld new file mode 100644 index 0000000000..2a9be2b5c8 --- /dev/null +++ b/ld/testsuite/ld-elf/abind-2g.ld @@ -0,0 +1,22 @@ +SECTIONS +{ + .bss : + { + *(.bss) + } + + .data : + { + *(.data) + } + + .text : + { + *(.text) + } + + .rodata : + { + *(.rodata) + } +} diff --git a/ld/testsuite/ld-msp430-elf/location-1.d b/ld/testsuite/ld-msp430-elf/location-1.d new file mode 100644 index 0000000000..9a23431033 --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-1.d @@ -0,0 +1,23 @@ +# Test that text, rodata, data and bss locsyms get placed at the correct +# addresses. +# The variable "either" should be placed in between the .data sections. +# +#name: SMK_LOCATION data meta-information +#ld: -e _start +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +00000510 . loc510_data +00000520 . loc520_data +000005f1 . loc5f1_data +#... +[0-9a-f]+ . either +#... +00000790 . loc790_data +00000808 . loc808_data +00000850 . loc850_bss +#... +00009000 . loc9000_text +0000910a . loc910a_rodata +#pass diff --git a/ld/testsuite/ld-msp430-elf/location-1.s b/ld/testsuite/ld-msp430-elf/location-1.s new file mode 100644 index 0000000000..83d179d281 --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-1.s @@ -0,0 +1,98 @@ + .global arr_1 + .section .data.arr_1,"aw" + .type arr_1, %object +arr_1: + .zero 80 + + .global arr_2 + .section .data.arr_2,"aw" + .type arr_2, %object +arr_2: + .zero 80 + + .global arr_3 + .section .data.arr_3,"aw" + .type arr_3, %object +arr_3: + .zero 80 + + .global arr_4 + .section .data.arr_4,"aw" + .type arr_4, %object +arr_4: + .zero 80 + +/* + .global const_arr_1 + .section .rodata.const_arr_1,"a" + .type const_arr_1, %object +const_arr_1: + .zero 80 + */ + + + .global loc808_data + .section .data.loc808_data,"awA",0x808 + .type loc808_data, %object +loc808_data: + .short 2056 + + .global loc510_data + .section .data.loc510_data,"awA",0x510 + .type loc510_data, %object +loc510_data: + .byte 81 + + .global loc520_data + .section .data.loc520_data,"awA",0x520 + .type loc520_data, %object +loc520_data: + .byte 82 + + .global loc790_data + .section .data.loc790_data,"awA",0x790 + .type loc790_data, %object +loc790_data: + .byte 114 + + .global loc5f1_data + .section .data.loc5f1_data,"awA",0x5f1 + .type loc5f1_data, %object +loc5f1_data: + .byte 95 + + .section .text.loc9000_text,"axA",%progbits,0x9000 + .global loc9000_text + .type loc9000_text, %function +loc9000_text: + .word 0 + + .global loc910a_rodata + .section .rodata.loc910a_rodata,"aA",0x910a + .type loc910a_rodata, %object +loc910a_rodata: + .byte 2 + + .global loc850_bss + .section .bss.loc850_bss,"awA",%nobits,0x850 + .type loc850_bss, %object +loc850_bss: + .zero 1 + + .global normal_bss + .section .bss.normal_bss,"aw",%nobits + .type normal_bss, %object +normal_bss: + .zero 1 + + .global either + .section .either.data,"aw" + .type either, %object +either: + .byte 1 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 diff --git a/ld/testsuite/ld-msp430-elf/location-2.d b/ld/testsuite/ld-msp430-elf/location-2.d new file mode 100644 index 0000000000..87f3d4555e --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-2.d @@ -0,0 +1,30 @@ +# Test that relaxation of branch instructions to jumps does not interfere +# with accurrate placement of sections. +# Before location placement, the BR instructions are all close enough to their +# destination such that they can be relaxed to JMP. However, after placement +# of the sections, some of the JMP will now be out of range, so check that they +# get relaxed back to a BR (tested by the fact there are no relocation +# overflows), and that the functions still get placed at the +# correct address. +#name: SMK_LOCATION meta-information placement after relaxation +#ld: -e _start +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+8000 . fn_8000 +#... +0+8200 . fn_8200 +#... +0+8500 . fn_dst +#... +0+8600 . fn_8600 +#... +0+8700 . fn_8700 +#... +0+8a00 . fn_8a00 +#... +0+9000 . fn_9000 +#... +0+910a . loc910a_rodata +#pass diff --git a/ld/testsuite/ld-msp430-elf/location-2.s b/ld/testsuite/ld-msp430-elf/location-2.s new file mode 100644 index 0000000000..0c278a1f78 --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-2.s @@ -0,0 +1,76 @@ + .global loc910a_rodata + .section .rodata.loc910a_rodata,"a" + .type loc910a_rodata, @object +loc910a_rodata: + .byte 2 + .location 0x910a + + .section .text.fn_8700,"ax",@progbits + .global fn_8700 + .type fn_8700, @function +fn_8700: + br #fn_dst + br #fn_9000 + NOP + RET + .section .text.fn_8a00,"ax",@progbits + .global fn_8a00 + .type fn_8a00, @function +fn_8a00: + br #fn_dst + br #fn_9000 + NOP + RET + .section .text.fn_8600,"ax",@progbits + .global fn_8600 + .type fn_8600, @function +fn_8600: + br #fn_dst + br #fn_9000 + NOP + RET + .section .text.fn_8000,"ax",@progbits + .global fn_8000 + .type fn_8000, @function +fn_8000: + br #fn_dst + br #fn_9000 + NOP + RET + .section .text.fn_8200,"ax",@progbits + .global fn_8200 + .type fn_8200, @function +fn_8200: + br #fn_dst + br #fn_9000 + NOP + RET + .section .text.fn_9000,"ax",@progbits + .global fn_9000 + .type fn_9000, @function +fn_9000: + br #fn_dst + NOP + RET + .section .text.fn_dst,"ax",@progbits + .global fn_dst + .type fn_dst, @function +fn_dst: + add r12, r12 + NOP + RET + .location 0x8000, .text.fn_8000 + .location 0x8500, .text.fn_dst + .location 0x8200, .text.fn_8200 + .location 0x9000, .text.fn_9000 + .location 0x8600, .text.fn_8600 + .location 0x8700, .text.fn_8700 + .location 0x8a00, .text.fn_8a00 + .section .text._start,"ax",@progbits + .global _start + .type _start, @function +_start: + CALL #fn_8000 + MOV.B #0, R12 + .refsym __crt0_call_exit + RET diff --git a/ld/testsuite/ld-msp430-elf/location-3.d b/ld/testsuite/ld-msp430-elf/location-3.d new file mode 100644 index 0000000000..0a2becf6fc --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-3.d @@ -0,0 +1,10 @@ +# Test that a text locsym in a random section still gets placed. +# +#name: Orphaned location section +#ld: -e _start +#notarget: ![supports_gnu_osabi] +#nm : -n + +#... +00009100 . loc9100_text +#pass diff --git a/ld/testsuite/ld-msp430-elf/location-3.s b/ld/testsuite/ld-msp430-elf/location-3.s new file mode 100644 index 0000000000..2a2e970933 --- /dev/null +++ b/ld/testsuite/ld-msp430-elf/location-3.s @@ -0,0 +1,12 @@ + .section .faketext,"ax",%progbits + .global loc9100_text + .type loc9100_text, %function +loc9100_text: + .word 0 + .location 0x9100 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 diff --git a/ld/testsuite/ld-msp430-elf/msp430-elf.exp b/ld/testsuite/ld-msp430-elf/msp430-elf.exp index 875b413c14..22d476a4a5 100644 --- a/ld/testsuite/ld-msp430-elf/msp430-elf.exp +++ b/ld/testsuite/ld-msp430-elf/msp430-elf.exp @@ -190,6 +190,10 @@ run_ld_link_tests $msp430eithershuffletests run_ld_link_tests $msp430warntests run_dump_test valid-map +run_dump_test location-1 +run_dump_test location-2 +run_dump_test location-3 + run_ld_link_tests {{ "Check no reloc overflow with #lo and data in the upper region" "-m msp430X" "" "" {reloc-lo-430x.s} {} "reloc-lo-430x"}} run_ld_link_tests {{ "Check .upper prefixed input sections can be placed" diff --git a/ld/testsuite/ld-x86-64/abind-1.d b/ld/testsuite/ld-x86-64/abind-1.d new file mode 100644 index 0000000000..33e91e7c51 --- /dev/null +++ b/ld/testsuite/ld-x86-64/abind-1.d @@ -0,0 +1,54 @@ +#name: SHF_GNU_ABIND 1 (using default linker script) +#source: abind-1.s +#ld: -e _start +#notarget: ![supports_gnu_osabi] +#nm: -n + +#... +0+400000 t addr_0x400000_size_0x1000 +#... +[0-9a-f]+ . text_size_0x1 +[0-9a-f]+ . text_size_0x10 +[0-9a-f]+ . text_size_0x80 +[0-9a-f]+ . text_size_0x100 +[0-9a-f]+ . text_size_0x800 +[0-9a-f]+ . text_size_0x1000 +#... +[0-9a-f]+ T _start +[0-9a-f]+ T __run_gnu_abind_init_array +#... +0+404002 r addr_0x404002 +0+406100 t addr_0x406100 +#... +[0-9a-f]+ . rodata_size_0x1 +[0-9a-f]+ . rodata_size_0x10 +[0-9a-f]+ . rodata_size_0x80 +[0-9a-f]+ . rodata_size_0x100 +[0-9a-f]+ . rodata_size_0x800 +[0-9a-f]+ . rodata_size_0x1000 +#... +0+40b200 r addr_0x40b200_size_0x1000 +#... +0+40c402 d addr_0x40c402 +#... +[0-9a-f]+ . data_size_0x1 +[0-9a-f]+ . data_size_0x10 +[0-9a-f]+ . data_size_0x80 +[0-9a-f]+ . data_size_0x100 +[0-9a-f]+ . data_size_0x800 +[0-9a-f]+ . data_size_0x1000 +#... +0+40e000 b addr_0x40e000_size_0x1000 +#... +0+40f000 b addr_0x40f000 +#... +[0-9a-f]+ . __bss_start +[0-9a-f]+ . _edata +#... +[0-9a-f]+ . bss_size_0x1 +[0-9a-f]+ . bss_size_0x10 +[0-9a-f]+ . bss_size_0x80 +[0-9a-f]+ . bss_size_0x100 +[0-9a-f]+ . bss_size_0x800 +[0-9a-f]+ . bss_size_0x1000 +#pass diff --git a/ld/testsuite/ld-x86-64/abind-1.s b/ld/testsuite/ld-x86-64/abind-1.s new file mode 100644 index 0000000000..c7068c7581 --- /dev/null +++ b/ld/testsuite/ld-x86-64/abind-1.s @@ -0,0 +1,175 @@ +/* Arbitrary sized .data sections. */ + .section .data.size_0x1,"aw" + .type data_size_0x1, %object +data_size_0x1: + .zero 0x1 + + .section .data.size_0x10,"aw" + .type data_size_0x10, %object +data_size_0x10: + .zero 0x10 + + .section .data.size_0x80,"aw" + .type data_size_0x80, %object +data_size_0x80: + .zero 0x80 + + .section .data.size_0x100,"aw" + .type data_size_0x100, %object +data_size_0x100: + .zero 0x100 + + .section .data.size_0x800,"aw" + .type data_size_0x800, %object +data_size_0x800: + .zero 0x800 + + .section .data.size_0x1000,"aw" + .type data_size_0x1000, %object +data_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .bss sections. */ + + .section .bss.size_0x1,"aw",%nobits + .type bss_size_0x1, %object +bss_size_0x1: + .zero 0x1 + + .section .bss.size_0x10,"aw",%nobits + .type bss_size_0x10, %object +bss_size_0x10: + .zero 0x10 + + .section .bss.size_0x80,"aw",%nobits + .type bss_size_0x80, %object +bss_size_0x80: + .zero 0x80 + + .section .bss.size_0x100,"aw",%nobits + .type bss_size_0x100, %object +bss_size_0x100: + .zero 0x100 + + .section .bss.size_0x800,"aw",%nobits + .type bss_size_0x800, %object +bss_size_0x800: + .zero 0x800 + + .section .bss.size_0x1000,"aw",%nobits + .type bss_size_0x1000, %object +bss_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .text sections. */ + + .section .text.size_0x1,"ax",%progbits + .type text_size_0x1, %function +text_size_0x1: + .zero 0x1 + + .section .text.size_0x10,"ax",%progbits + .type text_size_0x10, %function +text_size_0x10: + .zero 0x10 + + .section .text.size_0x80,"ax",%progbits + .type text_size_0x80, %function +text_size_0x80: + .zero 0x80 + + .section .text.size_0x100,"ax",%progbits + .type text_size_0x100, %function +text_size_0x100: + .zero 0x100 + + .section .text.size_0x800,"ax",%progbits + .type text_size_0x800, %function +text_size_0x800: + .zero 0x800 + + .section .text.size_0x1000,"ax",%progbits + .type text_size_0x1000, %function +text_size_0x1000: + .zero 0x1000 + +/* Arbitrary sized .rodata sections. */ + + .section .rodata.size_0x1,"a" + .type rodata_size_0x1, %object +rodata_size_0x1: + .zero 0x1 + + .section .rodata.size_0x10,"a" + .type rodata_size_0x10, %object +rodata_size_0x10: + .zero 0x10 + + .section .rodata.size_0x80,"a" + .type rodata_size_0x80, %object +rodata_size_0x80: + .zero 0x80 + + .section .rodata.size_0x100,"a" + .type rodata_size_0x100, %object +rodata_size_0x100: + .zero 0x100 + + .section .rodata.size_0x800,"a" + .type rodata_size_0x800, %object +rodata_size_0x800: + .zero 0x800 + + .section .rodata.size_0x1000,"a" + .type rodata_size_0x1000, %object +rodata_size_0x1000: + .zero 0x1000 + +/* Start .gnu.abind sections. */ + + .section .text.addr_0x400000,"axA",%progbits,0x400000 + .type addr_0x400000, %function +addr_0x400000_size_0x1000: + .zero 0x1000 + + .section .rodata.addr_0x404002,"aA",0x404002 + .type addr_0x404002, %object +addr_0x404002: + .byte 2 + + .section .text.addr_0x406100,"axA",%progbits,0x406100 + .type addr_0x406100, %function +addr_0x406100: + .zero 2 + + .section .rodata.addr_0x40b200,"aA",0x40b200 + .type addr_0x40b200, %object +addr_0x40b200_size_0x1000: + .zero 0x1000 + + .section .data.addr_0x40c402,"awA",0x40c402 + .type addr_0x40c402, %object +addr_0x40c402: + .zero 2 + + .section .bss.addr_0x40e000,"awA",%nobits,0x40e000 + .type addr_0x40e000, %object +addr_0x40e000_size_0x1000: + .zero 0x1000 + + .section .bss.addr_0x40f000,"awA",%nobits,0x40f000 + .type addr_0x40f000, %object +addr_0x40f000: + .zero 1 + + .section .text._start,"ax",%progbits + .global _start + .type _start, %function +_start: + .word 0 + + .section .text.__run_gnu_abind_init_array,"ax",%progbits + .global __run_gnu_abind_init_array + .type __run_gnu_abind_init_array, %function +__run_gnu_abind_init_array: + .word 0 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 59cad54a79..5f61135ccb 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -245,6 +245,7 @@ if { ![ld_link $ld tmpdir/$test "-m$emul tmpdir/${test}a.o tmpdir/${test}b.o"] } } } +run_dump_test "abind-1" run_dump_test "abs" run_dump_test "abs-k1om" run_dump_test "abs-l1om" -- 2.28.0