aboutsummaryrefslogtreecommitdiff
path: root/gold/merge.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2013-04-29 17:15:09 +0000
committerCary Coutant <ccoutant@google.com>2013-04-29 17:15:09 +0000
commite31908b642bf3602c06fe64ab574a865307e45b0 (patch)
tree10a5d3ebaad183647e9da9ef874b2fc7fed3aa9a /gold/merge.cc
parent5dad867ccace0a74c90b729372c9c01392756875 (diff)
downloadgdb-e31908b642bf3602c06fe64ab574a865307e45b0.zip
gdb-e31908b642bf3602c06fe64ab574a865307e45b0.tar.gz
gdb-e31908b642bf3602c06fe64ab574a865307e45b0.tar.bz2
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.
Diffstat (limited to 'gold/merge.cc')
-rw-r--r--gold/merge.cc36
1 files changed, 30 insertions, 6 deletions
diff --git a/gold/merge.cc b/gold/merge.cc
index dde43e9..6480bd9 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -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);