mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 10:03:47 +08:00
2013-04-29 Alexander Ivchenko <alexander.ivchenko@intel.com>
gold/ * output.cc (Output_section::add_merge_input_section): Allow to merge sections if the alignment is more than character size. * merge.h (Output_merge_string::Output_merge_string): Remove assert. * merge.cc (Output_merge_string<Char_type>::do_add_input_section): Count only not-null strings. Check the alignment of strings. * stringpool.h (Stringpool_template<Stringpool_char>::Stringpool_template): Add alignment as the argument. (Stringpool_template<Stringpool_char>::addralign_): New class member. * stringpool.cc (Stringpool_template<Stringpool_char>::new_key_offset): Align non-zero length strings according to the addralign_. (Stringpool_template<Stringpool_char>::set_string_offsets): Updating offsets according to the given alignment. * testsuite/Makefile.am (text_section_grouping): Test if string literals are getting merged. * testsuite/Makefile.in: Regenerate. * testsuite/merge_string_literals_1.c: New file. * testsuite/merge_string_literals_2.c: Ditto. * testsuite/merge_string_literals.sh: Ditto.
This commit is contained in:
parent
5dad867cca
commit
e31908b642
@ -1,3 +1,26 @@
|
||||
2013-04-29 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||
|
||||
* output.cc (Output_section::add_merge_input_section): Allow
|
||||
to merge sections if the alignment is more than character size.
|
||||
* merge.h (Output_merge_string::Output_merge_string): Remove
|
||||
assert.
|
||||
* merge.cc (Output_merge_string<Char_type>::do_add_input_section): Count
|
||||
only not-null strings. Check the alignment of strings.
|
||||
* stringpool.h
|
||||
(Stringpool_template<Stringpool_char>::Stringpool_template): Add
|
||||
alignment as the argument.
|
||||
(Stringpool_template<Stringpool_char>::addralign_): New class member.
|
||||
* stringpool.cc (Stringpool_template<Stringpool_char>::new_key_offset):
|
||||
Align non-zero length strings according to the addralign_.
|
||||
(Stringpool_template<Stringpool_char>::set_string_offsets):
|
||||
Updating offsets according to the given alignment.
|
||||
* testsuite/Makefile.am (text_section_grouping): Test if string
|
||||
literals are getting merged.
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
* testsuite/merge_string_literals_1.c: New file.
|
||||
* testsuite/merge_string_literals_2.c: Ditto.
|
||||
* testsuite/merge_string_literals.sh: Ditto.
|
||||
|
||||
2013-04-26 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* target-reloc.h (relocate_section): If the reloc offset is out of
|
||||
|
@ -540,25 +540,43 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
|
||||
this->merged_strings_lists_.push_back(merged_strings_list);
|
||||
Merged_strings& merged_strings = merged_strings_list->merged_strings;
|
||||
|
||||
// Count the number of strings in the section and size the list.
|
||||
// Count the number of non-null strings in the section and size the list.
|
||||
size_t count = 0;
|
||||
for (const Char_type* pt = p; pt < pend0; pt += string_length(pt) + 1)
|
||||
++count;
|
||||
for (const Char_type* pt = p, len = string_length(pt);
|
||||
pt < pend0;
|
||||
pt += len + 1)
|
||||
if (len != 0)
|
||||
++count;
|
||||
if (pend0 < pend)
|
||||
++count;
|
||||
merged_strings.reserve(count + 1);
|
||||
|
||||
// The index I is in bytes, not characters.
|
||||
section_size_type i = 0;
|
||||
|
||||
// We assume here that the beginning of the section is correctly
|
||||
// aligned, so each string within the section must retain the same
|
||||
// modulo.
|
||||
uintptr_t init_align_modulo = (reinterpret_cast<uintptr_t>(pdata)
|
||||
& (this->addralign() - 1));
|
||||
bool has_misaligned_strings = false;
|
||||
|
||||
while (p < pend0)
|
||||
{
|
||||
size_t len = string_length(p);
|
||||
|
||||
Stringpool::Key key;
|
||||
this->stringpool_.add_with_length(p, len, true, &key);
|
||||
if (len != 0)
|
||||
{
|
||||
// Within merge input section each string must be aligned.
|
||||
if ((reinterpret_cast<uintptr_t>(p) & (this->addralign() - 1))
|
||||
!= init_align_modulo)
|
||||
has_misaligned_strings = true;
|
||||
|
||||
merged_strings.push_back(Merged_string(i, key));
|
||||
Stringpool::Key key;
|
||||
this->stringpool_.add_with_length(p, len, true, &key);
|
||||
|
||||
merged_strings.push_back(Merged_string(i, key));
|
||||
}
|
||||
p += len + 1;
|
||||
i += (len + 1) * sizeof(Char_type);
|
||||
}
|
||||
@ -581,6 +599,12 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
|
||||
this->input_count_ += count;
|
||||
this->input_size_ += len;
|
||||
|
||||
if (has_misaligned_strings)
|
||||
gold_warning(_("%s: section %s contains incorrectly aligned strings;"
|
||||
" the alignment of those strings won't be preserved"),
|
||||
object->name().c_str(),
|
||||
object->section_name(shndx).c_str());
|
||||
|
||||
// For script processing, we keep the input sections.
|
||||
if (this->keeps_input_sections())
|
||||
record_input_section(object, shndx);
|
||||
|
@ -461,10 +461,9 @@ class Output_merge_string : public Output_merge_base
|
||||
{
|
||||
public:
|
||||
Output_merge_string(uint64_t addralign)
|
||||
: Output_merge_base(sizeof(Char_type), addralign), stringpool_(),
|
||||
: Output_merge_base(sizeof(Char_type), addralign), stringpool_(addralign),
|
||||
merged_strings_lists_(), input_count_(0), input_size_(0)
|
||||
{
|
||||
gold_assert(addralign <= sizeof(Char_type));
|
||||
this->stringpool_.set_no_zero_null();
|
||||
}
|
||||
|
||||
|
@ -2635,11 +2635,6 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
|
||||
{
|
||||
bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
|
||||
|
||||
// We only merge strings if the alignment is not more than the
|
||||
// character size. This could be handled, but it's unusual.
|
||||
if (is_string && addralign > entsize)
|
||||
return false;
|
||||
|
||||
// We cannot restore merged input section states.
|
||||
gold_assert(this->checkpoint_ == NULL);
|
||||
|
||||
|
@ -34,9 +34,10 @@ namespace gold
|
||||
{
|
||||
|
||||
template<typename Stringpool_char>
|
||||
Stringpool_template<Stringpool_char>::Stringpool_template()
|
||||
Stringpool_template<Stringpool_char>::Stringpool_template(uint64_t addralign)
|
||||
: string_set_(), key_to_offset_(), strings_(), strtab_size_(0),
|
||||
zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char))
|
||||
zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)),
|
||||
addralign_(addralign)
|
||||
{
|
||||
if (parameters->options_valid() && parameters->options().optimize() >= 2)
|
||||
this->optimize_ = true;
|
||||
@ -221,8 +222,10 @@ Stringpool_template<Stringpool_char>::new_key_offset(size_t length)
|
||||
offset = 0;
|
||||
else
|
||||
{
|
||||
offset = this->offset_;
|
||||
this->offset_ += (length + 1) * sizeof(Stringpool_char);
|
||||
// Align non-zero length strings.
|
||||
if (length != 0)
|
||||
offset = align_address(this->offset_, this->addralign_);
|
||||
this->offset_ = offset + (length + 1) * sizeof(Stringpool_char);
|
||||
}
|
||||
this->key_to_offset_.push_back(offset);
|
||||
}
|
||||
@ -421,8 +424,8 @@ Stringpool_template<Stringpool_char>::set_string_offsets()
|
||||
* charsize));
|
||||
else
|
||||
{
|
||||
this_offset = offset;
|
||||
offset += ((*curr)->first.length + 1) * charsize;
|
||||
this_offset = align_address(offset, this->addralign_);
|
||||
offset = this_offset + ((*curr)->first.length + 1) * charsize;
|
||||
}
|
||||
this->key_to_offset_[(*curr)->second - 1] = this_offset;
|
||||
last_offset = this_offset;
|
||||
|
@ -180,7 +180,7 @@ class Stringpool_template
|
||||
typedef size_t Key;
|
||||
|
||||
// Create a Stringpool.
|
||||
Stringpool_template();
|
||||
Stringpool_template(uint64_t addralign = 1);
|
||||
|
||||
~Stringpool_template();
|
||||
|
||||
@ -409,6 +409,8 @@ class Stringpool_template
|
||||
bool optimize_;
|
||||
// offset of the next string.
|
||||
section_offset_type offset_;
|
||||
// The alignment of strings in the stringpool.
|
||||
uint64_t addralign_;
|
||||
};
|
||||
|
||||
// The most common type of Stringpool.
|
||||
|
@ -329,6 +329,18 @@ icf_sht_rel_addend_test: icf_sht_rel_addend_test_1.o icf_sht_rel_addend_test_2.o
|
||||
icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
|
||||
$(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
|
||||
|
||||
check_SCRIPTS += merge_string_literals.sh
|
||||
check_DATA += merge_string_literals.stdout
|
||||
MOSTLYCLEANFILES += merge_string_literals
|
||||
merge_string_literals_1.o: merge_string_literals_1.c
|
||||
$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
|
||||
merge_string_literals_2.o: merge_string_literals_2.c
|
||||
$(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
|
||||
merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
|
||||
merge_string_literals.stdout: merge_string_literals
|
||||
$(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
|
||||
|
||||
check_PROGRAMS += basic_test
|
||||
check_PROGRAMS += basic_pic_test
|
||||
basic_test.o: basic_test.cc
|
||||
|
@ -85,6 +85,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh undef_symbol.sh \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.sh ver_test_2.sh \
|
||||
@ -119,6 +120,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_4 = incremental_test \
|
||||
@ -140,6 +142,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ merge_string_literals \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/weak_undef_lib.so
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_5 = icf_virtual_function_folding_test \
|
||||
@ -3755,6 +3758,8 @@ icf_string_merge_test.sh.log: icf_string_merge_test.sh
|
||||
@p='icf_string_merge_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
icf_sht_rel_addend_test.sh.log: icf_sht_rel_addend_test.sh
|
||||
@p='icf_sht_rel_addend_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
merge_string_literals.sh.log: merge_string_literals.sh
|
||||
@p='merge_string_literals.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
two_file_shared.sh.log: two_file_shared.sh
|
||||
@p='two_file_shared.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||
weak_plt.sh.log: weak_plt.sh
|
||||
@ -4440,6 +4445,14 @@ uninstall-am:
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf=all icf_sht_rel_addend_test_1.o icf_sht_rel_addend_test_2.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_sht_rel_addend_test.stdout: icf_sht_rel_addend_test
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) icf_sht_rel_addend_test > icf_sht_rel_addend_test.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_1.o: merge_string_literals_1.c
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals_2.o: merge_string_literals_2.c
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O2 -c -fPIC -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals: merge_string_literals_1.o merge_string_literals_2.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ merge_string_literals_1.o merge_string_literals_2.o -O2 -shared -nostdlib
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@merge_string_literals.stdout: merge_string_literals
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -s -j.rodata merge_string_literals > merge_string_literals.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test.o: basic_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test: basic_test.o gcctestdir/ld
|
||||
|
41
gold/testsuite/merge_string_literals.sh
Executable file
41
gold/testsuite/merge_string_literals.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
# merge_string_literals.sh -- test
|
||||
|
||||
# Copyright 2013 Free Software Foundation, Inc.
|
||||
# Written by Alexander Ivchenko <alexander.ivchenko@intel.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.
|
||||
|
||||
# The goal of this program is to check whether string literals from different
|
||||
# object files are merged together
|
||||
|
||||
set -e
|
||||
|
||||
check()
|
||||
{
|
||||
number_of_occurrence=`grep $2 ./$1 -o| wc -l`
|
||||
if [ $number_of_occurrence != $3 ]
|
||||
then
|
||||
echo "String literals were not merged"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# If string literals were merged, then "abcd" appears two times
|
||||
check merge_string_literals.stdout "abcd" 2
|
31
gold/testsuite/merge_string_literals_1.c
Normal file
31
gold/testsuite/merge_string_literals_1.c
Normal file
@ -0,0 +1,31 @@
|
||||
// merge_string_literals_1.c -- a test case for gold
|
||||
|
||||
// Copyright 2013 Free Software Foundation, Inc.
|
||||
// Written by Alexander Ivchenko <alexander.ivchenko@intel.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.
|
||||
|
||||
// The goal of this program is to check whether string literals from different
|
||||
// object files are merged together
|
||||
|
||||
const char* bar1() {
|
||||
return "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
}
|
||||
const char* bar1_short() {
|
||||
return "abcdef";
|
||||
}
|
31
gold/testsuite/merge_string_literals_2.c
Normal file
31
gold/testsuite/merge_string_literals_2.c
Normal file
@ -0,0 +1,31 @@
|
||||
// merge_string_literals_2.c -- a test case for gold
|
||||
|
||||
// Copyright 2013 Free Software Foundation, Inc.
|
||||
// Written by Alexander Ivchenko <alexander.ivchenko@intel.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.
|
||||
|
||||
// The goal of this program is to check whether string literals from different
|
||||
// object files are merged together
|
||||
|
||||
const char* bar2() {
|
||||
return "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
}
|
||||
const char* bar2_short() {
|
||||
return "abcdef";
|
||||
}
|
Loading…
Reference in New Issue
Block a user