aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/layout.cc2
-rw-r--r--gold/merge.cc12
-rw-r--r--gold/stringpool.cc50
-rw-r--r--gold/stringpool.h14
-rw-r--r--gold/symtab.cc3
5 files changed, 51 insertions, 30 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index 45980d5..231e2c9 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -269,7 +269,7 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
// Canonicalize the section name.
Stringpool::Key name_key;
- name = this->namepool_.add_prefix(name, len, &name_key);
+ name = this->namepool_.add_with_length(name, len, true, &name_key);
// Find the output section. The output section is selected based on
// the section name, type, and flags.
diff --git a/gold/merge.cc b/gold/merge.cc
index 65acf82..2c76759 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -520,7 +520,8 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
}
}
- const Char_type* str = this->stringpool_.add_prefix(p, pl - p, NULL);
+ const Char_type* str = this->stringpool_.add_with_length(p, pl - p, true,
+ NULL);
section_size_type bytelen_with_null = ((pl - p) + 1) * sizeof(Char_type);
this->merged_strings_.push_back(Merged_string(object, shndx, i, str,
@@ -549,8 +550,13 @@ Output_merge_string<Char_type>::finalize_merged_data()
this->merged_strings_.begin();
p != this->merged_strings_.end();
++p)
- this->add_mapping(p->object, p->shndx, p->offset, p->length,
- this->stringpool_.get_offset(p->string));
+ {
+ size_t charlen_without_null = (p->length / sizeof(Char_type)) - 1;
+ section_offset_type offset =
+ this->stringpool_.get_offset_with_length(p->string,
+ charlen_without_null);
+ this->add_mapping(p->object, p->shndx, p->offset, p->length, offset);
+ }
// Save some memory.
this->merged_strings_.clear();
diff --git a/gold/stringpool.cc b/gold/stringpool.cc
index 3d8bfe6..9ba505a 100644
--- a/gold/stringpool.cc
+++ b/gold/stringpool.cc
@@ -136,8 +136,9 @@ Stringpool_template<Stringpool_char>::Stringpool_eq::operator()(
{
return (h1.hash_code == h2.hash_code
&& h1.length == h2.length
- && memcmp(h1.string, h2.string,
- h1.length * sizeof(Stringpool_char)) == 0);
+ && (h1.string == h2.string
+ || memcmp(h1.string, h2.string,
+ h1.length * sizeof(Stringpool_char)) == 0));
}
// Hash function. The length is in characters, not bytes.
@@ -257,6 +258,16 @@ const Stringpool_char*
Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
Key* pkey)
{
+ return this->add_with_length(s, string_length(s), copy, pkey);
+}
+
+template<typename Stringpool_char>
+const Stringpool_char*
+Stringpool_template<Stringpool_char>::add_with_length(const Stringpool_char* s,
+ size_t length,
+ bool copy,
+ Key* pkey)
+{
typedef std::pair<typename String_set_type::iterator, bool> Insert_type;
if (!copy)
@@ -266,7 +277,7 @@ Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
const Key k = this->next_uncopied_key_;
const section_offset_type ozero = 0;
- std::pair<Hashkey, Hashval> element(Hashkey(s),
+ std::pair<Hashkey, Hashval> element(Hashkey(s, length),
std::make_pair(k, ozero));
Insert_type ins = this->string_set_.insert(element);
@@ -289,24 +300,12 @@ Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
return p->first.string;
}
- return this->add_prefix(s, string_length(s), pkey);
-}
-
-// Add a prefix of a string to a string pool.
-
-template<typename Stringpool_char>
-const Stringpool_char*
-Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
- size_t len,
- Key* pkey)
-{
- // When adding an entry, this will look it up twice in the hash
+ // When we have to copy the string, we look it up twice in the hash
// table. The problem is that we can't insert S before we
// canonicalize it by copying it into the canonical list. The hash
- // code will only be computed once, so this isn't all that
- // expensive.
+ // code will only be computed once.
- Hashkey hk(s, len);
+ Hashkey hk(s, length);
typename String_set_type::const_iterator p = this->string_set_.find(hk);
if (p != this->string_set_.end())
{
@@ -316,14 +315,13 @@ Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
}
Key k;
- hk.string = this->add_string(s, len, &k);
+ hk.string = this->add_string(s, length, &k);
// The contents of the string stay the same, so we don't need to
// adjust hk.hash_code or hk.length.
const section_offset_type ozero = 0;
std::pair<Hashkey, Hashval> element(hk, std::make_pair(k, ozero));
- typedef std::pair<typename String_set_type::iterator, bool> Insert_type;
Insert_type ins = this->string_set_.insert(element);
gold_assert(ins.second);
@@ -483,8 +481,18 @@ section_offset_type
Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s)
const
{
+ return this->get_offset_with_length(s, string_length(s));
+}
+
+template<typename Stringpool_char>
+section_offset_type
+Stringpool_template<Stringpool_char>::get_offset_with_length(
+ const Stringpool_char* s,
+ size_t length) const
+{
gold_assert(this->strtab_size_ != 0);
- typename String_set_type::const_iterator p = this->string_set_.find(s);
+ Hashkey hk(s, length);
+ typename String_set_type::const_iterator p = this->string_set_.find(hk);
if (p != this->string_set_.end())
return p->second.second;
gold_unreachable();
diff --git a/gold/stringpool.h b/gold/stringpool.h
index 0da7921..773bfc1 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -108,9 +108,10 @@ class Stringpool_template
const Stringpool_char*
add(const Stringpool_char* s, bool copy, Key* pkey);
- // Add the prefix of length LEN of string S to the pool.
+ // Add string S of length LEN characters to the pool. If COPY is
+ // true, S need not be null terminated.
const Stringpool_char*
- add_prefix(const Stringpool_char* s, size_t len, Key* pkey);
+ add_with_length(const Stringpool_char* s, size_t len, bool copy, Key* pkey);
// If the string S is present in the pool, return the canonical
// string pointer. Otherwise, return NULL. If PKEY is not NULL,
@@ -133,7 +134,12 @@ class Stringpool_template
// Get the offset of the string S in the string table.
section_offset_type
get_offset(const std::basic_string<Stringpool_char>& s) const
- { return this->get_offset(s.c_str()); }
+ { return this->get_offset_with_length(s.c_str(), s.size()); }
+
+ // Get the offset of string S, with length LENGTH characters, in the
+ // string table.
+ section_offset_type
+ get_offset_with_length(const Stringpool_char* s, size_t length) const;
// Get the size of the string table. This returns the number of
// bytes, not in units of Stringpool_char.
@@ -218,7 +224,7 @@ class Stringpool_template
// Note that these constructors are relatively expensive, because
// they compute the hash code.
- Hashkey(const Stringpool_char* s)
+ explicit Hashkey(const Stringpool_char* s)
: string(s), length(string_length(s)), hash_code(string_hash(s, length))
{ }
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 2cab980..afe47da 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -630,7 +630,8 @@ Symbol_table::add_from_relobj(
else
{
Stringpool::Key name_key;
- name = this->namepool_.add_prefix(name, ver - name, &name_key);
+ name = this->namepool_.add_with_length(name, ver - name, true,
+ &name_key);
bool def = false;
++ver;