diff options
-rw-r--r-- | gold/ChangeLog | 33 | ||||
-rw-r--r-- | gold/output.cc | 65 | ||||
-rw-r--r-- | gold/output.h | 4 | ||||
-rw-r--r-- | gold/script-sections.cc | 65 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 27 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 38 | ||||
-rw-r--r-- | gold/testsuite/script_test_15.c | 10 | ||||
-rwxr-xr-x | gold/testsuite/script_test_15a.sh | 41 | ||||
-rw-r--r-- | gold/testsuite/script_test_15a.t | 40 | ||||
-rwxr-xr-x | gold/testsuite/script_test_15b.sh | 42 | ||||
-rw-r--r-- | gold/testsuite/script_test_15b.t | 49 | ||||
-rwxr-xr-x | gold/testsuite/script_test_15c.sh | 42 | ||||
-rw-r--r-- | gold/testsuite/script_test_15c.t | 41 | ||||
-rw-r--r-- | gold/testsuite/script_test_2.cc | 18 |
14 files changed, 463 insertions, 52 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 7ff70b2..d129ddf 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,6 +1,37 @@ 2016-12-11 Cary Coutant <ccoutant@gmail.com> - * Makefile.in: Regenerate. + PR gold/16711 + * output.cc (Output_section::set_final_data_size): Calculate data size + based on relative offset rather than file offset. + (Output_segment::set_section_addresses): Track file offset separately + from address offset. + (Output_segment::set_section_list_addresses): Add pfoff parameter. + Track file offset separately. Don't move file offset for BSS + sections. + * output.h (Output_segment::set_section_list_addresses): Add pfoff + parameter. + * script-sections.cc (Orphan_section_placement): Add PLACE_LAST_ALLOC. + (Orphan_section_placement::Orphan_section_placement): Initialize it. + (Orphan_section_placement::output_section_init): Track last allocated + section. + (Orphan_section_placement::find_place): Place BSS after last allocated + section. + (Output_section_element_input::set_section_addresses): Always override + input section alignment when SUBALIGN is specified. + (Output_section_definition::set_section_addresses): Override alignment + of output section when SUBALIGN is specified. + + * testsuite/Makefile.am (script_test_15a, script_test_15b) + (script_test_15c): New test cases. + * testsuite/Makefile.in: Regenerate. + * testsuite/script_test_2.cc: Adjust expected layout. + * testsuite/script_test_15.c: New source file. + * testsuite/script_test_15a.sh: New shell script. + * testsuite/script_test_15a.t: New linker script. + * testsuite/script_test_15b.sh: New shell script. + * testsuite/script_test_15b.t: New linker script. + * testsuite/script_test_15c.sh: New shell script. + * testsuite/script_test_15c.t: New linker script. 2016-12-08 Alan Modra <amodra@gmail.com> diff --git a/gold/output.cc b/gold/output.cc index 8e043d7..cf934fb 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -3165,17 +3165,17 @@ Output_section::set_final_data_size() uint64_t address = this->address(); off_t startoff = this->offset(); - off_t off = startoff + this->first_input_offset_; + off_t off = this->first_input_offset_; for (Input_section_list::iterator p = this->input_sections_.begin(); p != this->input_sections_.end(); ++p) { off = align_address(off, p->addralign()); - p->set_address_and_file_offset(address + (off - startoff), off, + p->set_address_and_file_offset(address + off, startoff + off, startoff); off += p->data_size(); } - data_size = off - startoff; + data_size = off; } // For full incremental links, we want to allocate some patch space @@ -4398,12 +4398,14 @@ Output_segment::set_section_addresses(const Target* target, this->offset_ = orig_off; off_t off = 0; + off_t foff = *poff; uint64_t ret = 0; for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i) { if (i == static_cast<int>(ORDER_RELRO_LAST)) { *poff += last_relro_pad; + foff += last_relro_pad; addr += last_relro_pad; if (this->output_lists_[i].empty()) { @@ -4415,12 +4417,20 @@ Output_segment::set_section_addresses(const Target* target, } addr = this->set_section_list_addresses(layout, reset, &this->output_lists_[i], - addr, poff, pshndx, &in_tls); - if (i < static_cast<int>(ORDER_SMALL_BSS)) - { - this->filesz_ = *poff - orig_off; - off = *poff; - } + addr, poff, &foff, pshndx, + &in_tls); + + // FOFF tracks the last offset used for the file image, + // and *POFF tracks the last offset used for the memory image. + // When not using a linker script, bss sections should all + // be processed in the ORDER_SMALL_BSS and later buckets. + gold_assert(*poff == foff + || i == static_cast<int>(ORDER_TLS_BSS) + || i >= static_cast<int>(ORDER_SMALL_BSS) + || layout->script_options()->saw_sections_clause()); + + this->filesz_ = foff - orig_off; + off = foff; ret = addr; } @@ -4485,6 +4495,7 @@ uint64_t Output_segment::set_section_list_addresses(Layout* layout, bool reset, Output_data_list* pdl, uint64_t addr, off_t* poff, + off_t* pfoff, unsigned int* pshndx, bool* in_tls) { @@ -4494,10 +4505,14 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, off_t maxoff = startoff; off_t off = startoff; + off_t foff = *pfoff; for (Output_data_list::iterator p = pdl->begin(); p != pdl->end(); ++p) { + bool is_bss = (*p)->is_section_type(elfcpp::SHT_NOBITS); + bool is_tls = (*p)->is_section_flag_set(elfcpp::SHF_TLS); + if (reset) (*p)->reset_address_and_file_offset(); @@ -4507,7 +4522,7 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, { uint64_t align = (*p)->addralign(); - if ((*p)->is_section_flag_set(elfcpp::SHF_TLS)) + if (is_tls) { // Give the first TLS section the alignment of the // entire TLS segment. Otherwise the TLS segment as a @@ -4542,8 +4557,11 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, if (!parameters->incremental_update()) { + gold_assert(off == foff || is_bss); off = align_address(off, align); - (*p)->set_address_and_file_offset(addr + (off - startoff), off); + if (is_tls || !is_bss) + foff = off; + (*p)->set_address_and_file_offset(addr + (off - startoff), foff); } else { @@ -4551,6 +4569,7 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, (*p)->pre_finalize_data_size(); off_t current_size = (*p)->current_data_size(); off = layout->allocate(current_size, align, startoff); + foff = off; if (off == -1) { gold_assert((*p)->output_section() != NULL); @@ -4558,7 +4577,7 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, "relink with --incremental-full"), (*p)->output_section()->name()); } - (*p)->set_address_and_file_offset(addr + (off - startoff), off); + (*p)->set_address_and_file_offset(addr + (off - startoff), foff); if ((*p)->data_size() > current_size) { gold_assert((*p)->output_section() != NULL); @@ -4573,13 +4592,22 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, // For incremental updates, use the fixed offset for the // high-water mark computation. off = (*p)->offset(); + foff = off; } else { // The script may have inserted a skip forward, but it // better not have moved backward. if ((*p)->address() >= addr + (off - startoff)) - off += (*p)->address() - (addr + (off - startoff)); + { + if (!is_bss && off > foff) + gold_warning(_("script places BSS section in the middle " + "of a LOAD segment; space will be allocated " + "in the file")); + off += (*p)->address() - (addr + (off - startoff)); + if (is_tls || !is_bss) + foff = off; + } else { if (!layout->script_options()->saw_sections_clause()) @@ -4603,7 +4631,7 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, os->name(), previous_dot, dot); } } - (*p)->set_file_offset(off); + (*p)->set_file_offset(foff); (*p)->finalize_data_size(); } @@ -4618,10 +4646,14 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, // We want to ignore the size of a SHF_TLS SHT_NOBITS // section. Such a section does not affect the size of a // PT_LOAD segment. - if (!(*p)->is_section_flag_set(elfcpp::SHF_TLS) - || !(*p)->is_section_type(elfcpp::SHT_NOBITS)) + if (!is_tls || !is_bss) off += (*p)->data_size(); + // We don't allocate space in the file for SHT_NOBITS sections, + // unless a script has force-placed one in the middle of a segment. + if (!is_bss) + foff = off; + if (off > maxoff) maxoff = off; @@ -4633,6 +4665,7 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset, } *poff = maxoff; + *pfoff = foff; return addr + (maxoff - startoff); } diff --git a/gold/output.h b/gold/output.h index 62386a6..9083b5a 100644 --- a/gold/output.h +++ b/gold/output.h @@ -4851,8 +4851,8 @@ class Output_segment // Set the section addresses in an Output_data_list. uint64_t set_section_list_addresses(Layout*, bool reset, Output_data_list*, - uint64_t addr, off_t* poff, unsigned int* pshndx, - bool* in_tls); + uint64_t addr, off_t* poff, off_t* fpoff, + unsigned int* pshndx, bool* in_tls); // Return the number of Output_sections in an Output_data_list. unsigned int diff --git a/gold/script-sections.cc b/gold/script-sections.cc index f35ecc1..ae81f89 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -329,6 +329,7 @@ class Orphan_section_placement PLACE_TLS, PLACE_TLS_BSS, PLACE_BSS, + PLACE_LAST_ALLOC, PLACE_REL, PLACE_INTERP, PLACE_NONALLOC, @@ -368,6 +369,7 @@ Orphan_section_placement::Orphan_section_placement() this->initialize_place(PLACE_TLS, NULL); this->initialize_place(PLACE_TLS_BSS, NULL); this->initialize_place(PLACE_BSS, ".bss"); + this->initialize_place(PLACE_LAST_ALLOC, NULL); this->initialize_place(PLACE_REL, NULL); this->initialize_place(PLACE_INTERP, ".interp"); this->initialize_place(PLACE_NONALLOC, NULL); @@ -396,6 +398,15 @@ Orphan_section_placement::output_section_init(const std::string& name, bool first_init = this->first_init_; this->first_init_ = false; + // Remember the last allocated section. Any orphan bss sections + // will be placed after it. + if (os != NULL + && (os->flags() & elfcpp::SHF_ALLOC) != 0) + { + this->places_[PLACE_LAST_ALLOC].location = location; + this->places_[PLACE_LAST_ALLOC].have_location = true; + } + for (int i = 0; i < PLACE_MAX; ++i) { if (this->places_[i].name != NULL && this->places_[i].name == name) @@ -509,7 +520,7 @@ Orphan_section_placement::find_place(Output_section* os, follow = PLACE_TEXT; break; case PLACE_BSS: - follow = PLACE_DATA; + follow = PLACE_LAST_ALLOC; break; case PLACE_REL: follow = PLACE_TEXT; @@ -1751,16 +1762,16 @@ Output_section_element_input::set_section_addresses( p != matching_sections[i].end(); ++p) { - // Override the original address alignment if SUBALIGN is specified - // and is greater than the original alignment. We need to make a - // copy of the input section to modify the alignment. + // Override the original address alignment if SUBALIGN is specified. + // We need to make a copy of the input section to modify the + // alignment. Output_section::Input_section sis(p->input_section()); uint64_t this_subalign = sis.addralign(); if (!sis.is_input_section()) sis.output_section_data()->finalize_data_size(); uint64_t data_size = sis.data_size(); - if (this_subalign < subalign) + if (subalign > 0) { this_subalign = subalign; sis.set_addralign(subalign); @@ -2463,6 +2474,35 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, this->output_section_->set_addralign(align); } + uint64_t subalign; + if (this->subalign_ == NULL) + subalign = 0; + else + { + Output_section* subalign_section; + subalign = this->subalign_->eval_with_dot(symtab, layout, true, + *dot_value, NULL, + &subalign_section, NULL, + false); + if (subalign_section != NULL) + gold_warning(_("subalign of section %s is not absolute"), + this->name_.c_str()); + + // Reserve a value of 0 to mean there is no SUBALIGN property. + if (subalign == 0) + subalign = 1; + + // The external alignment of the output section must be at least + // as large as that of the input sections. If there is no + // explicit ALIGN property, we set the output section alignment + // to match the input section alignment. + if (align < subalign || this->align_ == NULL) + { + align = subalign; + this->output_section_->set_addralign(align); + } + } + address = align_address(address, align); uint64_t start_address = address; @@ -2547,21 +2587,6 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, this->evaluated_load_address_ = laddr; - uint64_t subalign; - if (this->subalign_ == NULL) - subalign = 0; - else - { - Output_section* subalign_section; - subalign = this->subalign_->eval_with_dot(symtab, layout, true, - *dot_value, NULL, - &subalign_section, NULL, - false); - if (subalign_section != NULL) - gold_warning(_("subalign of section %s is not absolute"), - this->name_.c_str()); - } - std::string fill; if (this->fill_ != NULL) { diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 17f45d6..6a0b19d 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -2009,6 +2009,33 @@ script_test_14: $(srcdir)/script_test_14.t script_test_14.o gcctestdir/ld script_test_14.stdout: script_test_14 $(TEST_OBJDUMP) -s script_test_14 > $@ +# Test BSS section placement at end of segment. +check_SCRIPTS += script_test_15a.sh +check_DATA += script_test_15a.stdout +MOSTLYCLEANFILES += script_test_15a +script_test_15a: $(srcdir)/script_test_15a.t script_test_15.o gcctestdir/ld + gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15a.t +script_test_15a.stdout: script_test_15a + $(TEST_READELF) -lSW script_test_15a > $@ + +# Test BSS section placement in middle of segment. +check_SCRIPTS += script_test_15b.sh +check_DATA += script_test_15b.stdout +MOSTLYCLEANFILES += script_test_15b +script_test_15b: $(srcdir)/script_test_15b.t script_test_15.o gcctestdir/ld + gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15b.t +script_test_15b.stdout: script_test_15b + $(TEST_READELF) -lSW script_test_15b > $@ + +# Test orphan BSS section placement. +check_SCRIPTS += script_test_15c.sh +check_DATA += script_test_15c.stdout +MOSTLYCLEANFILES += script_test_15c +script_test_15c: $(srcdir)/script_test_15c.t script_test_15.o gcctestdir/ld + gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15c.t +script_test_15c.stdout: script_test_15c + $(TEST_READELF) -lSW script_test_15c > $@ + # Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new, # and --dynamic-list-cpp-typeinfo diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 5fef3cf..a1d8b39 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -365,9 +365,11 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4 script_test_5 \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6 script_test_7 \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8 script_test_9 \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14 dynamic_list \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout libthin1.a \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin3.a libthinall.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14 script_test_15a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15b script_test_15c \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list dynamic_list.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin1.a libthin3.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthinall.a \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_2.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_4.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libthin2.a alt/libthin4.a @@ -391,6 +393,12 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ # Test for SORT_BY_INIT_PRIORITY. +# Test BSS section placement at end of segment. + +# Test BSS section placement in middle of segment. + +# Test orphan BSS section placement. + # Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new, # and --dynamic-list-cpp-typeinfo @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_42 = \ @@ -410,6 +418,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_9.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15a.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15b.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15c.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.sh # Create the data files that debug_msg.sh analyzes. @@ -459,6 +470,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_9.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15a.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15b.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_15c.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout @GCC_FALSE@initpri1_DEPENDENCIES = @NATIVE_LINKER_FALSE@initpri1_DEPENDENCIES = @@ -5101,6 +5115,12 @@ script_test_9.sh.log: script_test_9.sh @p='script_test_9.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) script_test_14.sh.log: script_test_14.sh @p='script_test_14.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +script_test_15a.sh.log: script_test_15a.sh + @p='script_test_15a.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +script_test_15b.sh.log: script_test_15b.sh + @p='script_test_15b.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +script_test_15c.sh.log: script_test_15c.sh + @p='script_test_15c.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) dynamic_list.sh.log: dynamic_list.sh @p='dynamic_list.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) plugin_test_1.sh.log: plugin_test_1.sh @@ -6642,6 +6662,18 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ script_test_14.o -T $(srcdir)/script_test_14.t @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_14.stdout: script_test_14 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -s script_test_14 > $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15a: $(srcdir)/script_test_15a.t script_test_15.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15a.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15a.stdout: script_test_15a +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -lSW script_test_15a > $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15b: $(srcdir)/script_test_15b.t script_test_15.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15b.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15b.stdout: script_test_15b +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -lSW script_test_15b > $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15c: $(srcdir)/script_test_15c.t script_test_15.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ script_test_15.o -T $(srcdir)/script_test_15c.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_15c.stdout: script_test_15c +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -lSW script_test_15c > $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list: basic_test.o gcctestdir/ld $(srcdir)/dynamic_list.t @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,--dynamic-list $(srcdir)/dynamic_list.t \ diff --git a/gold/testsuite/script_test_15.c b/gold/testsuite/script_test_15.c new file mode 100644 index 0000000..48cfde8 --- /dev/null +++ b/gold/testsuite/script_test_15.c @@ -0,0 +1,10 @@ +int data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; + +int extra[] __attribute__ ((section(".data.extra"))) = { 1, 2, 3, 4 }; + +int zeroes[1024] = {0}; + +int main(void) +{ + return 0; +} diff --git a/gold/testsuite/script_test_15a.sh b/gold/testsuite/script_test_15a.sh new file mode 100755 index 0000000..791350c --- /dev/null +++ b/gold/testsuite/script_test_15a.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# script_test_15a.sh -- test for .bss placement. + +# Copyright (C) 2016 Free Software Foundation, Inc. +# Written by Cary Coutant <ccoutant@gmail.com>. + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# Check that the .bss section is not allocated in the file image. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_15a.stdout "LOAD.*0x0000.. 0x0010.. RW" +check script_test_15a.stdout "01.*\\.data .*\\.data.extra .*\\.bss" diff --git a/gold/testsuite/script_test_15a.t b/gold/testsuite/script_test_15a.t new file mode 100644 index 0000000..5f14c8e --- /dev/null +++ b/gold/testsuite/script_test_15a.t @@ -0,0 +1,40 @@ +/* script_test_15a.t -- linker script test 15a for gold + + Copyright (C) 2016 Free Software Foundation, Inc. + Written by Cary Coutant <ccoutant@google.com>. + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* We won't try to run this program, just ensure that it links + as expected. */ + +SECTIONS +{ + /* With luck this will be enough to get the program working. */ + .interp : { *(.interp) } + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + /* Required by the ARM target. */ + .ARM.extab : { *(.ARM.extab*) } + .ARM.exidx : { *(.ARM.exidx*) } + . = ALIGN(0x10000); + .dynamic : { *(.dynamic) } + .data : { *(.data) } + .got : { *(.got .toc) } + .bss : { *(.bss) } +} diff --git a/gold/testsuite/script_test_15b.sh b/gold/testsuite/script_test_15b.sh new file mode 100755 index 0000000..3179758 --- /dev/null +++ b/gold/testsuite/script_test_15b.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# script_test_15b.sh -- test for .bss placement. + +# Copyright (C) 2016 Free Software Foundation, Inc. +# Written by Cary Coutant <ccoutant@gmail.com>. + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# Check that a .bss section placed in the middle of a segment +# is allocated in the file image. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_15b.stdout "LOAD.*0x0010.. 0x0010.. RW" +check script_test_15b.stdout "01.*\\.bss .*\\.data .*\\.data.extra" diff --git a/gold/testsuite/script_test_15b.t b/gold/testsuite/script_test_15b.t new file mode 100644 index 0000000..2a17a7f --- /dev/null +++ b/gold/testsuite/script_test_15b.t @@ -0,0 +1,49 @@ +/* script_test_15b.t -- linker script test 15b for gold + + Copyright (C) 2016 Free Software Foundation, Inc. + Written by Cary Coutant <ccoutant@google.com>. + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* Test that a .bss section explicitly placed in the middle of a + segment has allocated file space. */ + +/* We won't try to run this program, just ensure that it links + as expected. */ + +PHDRS +{ + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); +} + +SECTIONS +{ + /* With luck this will be enough to get the program working. */ + .interp : { *(.interp) } :text + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + /* Required by the ARM target. */ + .ARM.extab : { *(.ARM.extab*) } + .ARM.exidx : { *(.ARM.exidx*) } + . = ALIGN(0x10000); + .dynamic : { *(.dynamic) } + .bss : { *(.bss) } :data + .data : { *(.data) } + .got : { *(.got .toc) } +} diff --git a/gold/testsuite/script_test_15c.sh b/gold/testsuite/script_test_15c.sh new file mode 100755 index 0000000..27631fc --- /dev/null +++ b/gold/testsuite/script_test_15c.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# script_test_15c.sh -- test for .bss placement. + +# Copyright (C) 2016 Free Software Foundation, Inc. +# Written by Cary Coutant <ccoutant@gmail.com>. + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# Check that an orphan .bss section is placed at the end of a segment +# and is not allocated in the file image. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_15c.stdout "LOAD.*0x0000.. 0x0010.. RW" +check script_test_15c.stdout "01.*\\.data .*\\.data.extra .*\\.bss" diff --git a/gold/testsuite/script_test_15c.t b/gold/testsuite/script_test_15c.t new file mode 100644 index 0000000..667d727 --- /dev/null +++ b/gold/testsuite/script_test_15c.t @@ -0,0 +1,41 @@ +/* script_test_15c.t -- linker script test 15c for gold + + Copyright (C) 2016 Free Software Foundation, Inc. + Written by Cary Coutant <ccoutant@google.com>. + + This file is part of gold. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* Test that an orphan .bss section is placed at the end of the segment. */ + +/* We won't try to run this program, just ensure that it links + as expected. */ + +SECTIONS +{ + /* With luck this will be enough to get the program working. */ + .interp : { *(.interp) } + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + /* Required by the ARM target. */ + .ARM.extab : { *(.ARM.extab*) } + .ARM.exidx : { *(.ARM.exidx*) } + . = ALIGN(0x10000); + .dynamic : { *(.dynamic) } + .data : { *(.data) } + .got : { *(.got .toc) } +} diff --git a/gold/testsuite/script_test_2.cc b/gold/testsuite/script_test_2.cc index d1b7aa9..eb45b32 100644 --- a/gold/testsuite/script_test_2.cc +++ b/gold/testsuite/script_test_2.cc @@ -42,21 +42,19 @@ int main(int, char**) { assert(reinterpret_cast<uintptr_t>(start_test_area) == 0x20000001); - assert(reinterpret_cast<uintptr_t>(start_test_area_1) == 0x20000010); + assert(reinterpret_cast<uintptr_t>(start_test_area_1) == 0x20000020); - // We should see the string from script_test_2b.o next. The - // subalign should move it up to 0x20000020. - for (int i = 0; i < 16; ++i) - assert(start_test_area_1[i] == 0); - assert(strcmp(start_test_area_1 + 16, "test bb") == 0); + assert(strcmp(start_test_area_1, "test bb") == 0); // Next the string from script_test_2a.o, after the subalign. - for (int i = 16 + 7; i < 48; ++i) + for (int i = 7; i < 32; ++i) assert(start_test_area_1[i] == 0); - assert(strcmp(start_test_area_1 + 48, "test aa") == 0); + assert(strcmp(start_test_area_1 + 32, "test aa") == 0); - // Move four bytes forward to start_data. - assert(reinterpret_cast<uintptr_t>(start_test_area_1 + 48 + 8 + 4) + // Skip to start_data at relative offset 60. + for (int i = 32 + 7; i < 60; ++i) + assert(start_test_area_1[i] == 0); + assert(reinterpret_cast<uintptr_t>(start_test_area_1 + 60) == reinterpret_cast<uintptr_t>(start_data)); assert(memcmp(start_data, "\1\2\0\4\0\0\0\010\0\0\0\0\0\0\0", 15) == 0 || memcmp(start_data, "\1\0\2\0\0\0\4\0\0\0\0\0\0\0\010", 15) == 0); |