diff options
author | Cary Coutant <ccoutant@google.com> | 2013-04-29 17:15:09 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2013-04-29 17:15:09 +0000 |
commit | e31908b642bf3602c06fe64ab574a865307e45b0 (patch) | |
tree | 10a5d3ebaad183647e9da9ef874b2fc7fed3aa9a /gold/merge.cc | |
parent | 5dad867ccace0a74c90b729372c9c01392756875 (diff) | |
download | gdb-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.cc | 36 |
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); |