gold_assert(sym->version() != NULL);
Stringpool::Key version_key;
- const char* version = dynpool->add(sym->version(), &version_key);
+ const char* version = dynpool->add(sym->version(), false, &version_key);
if (!sym->is_from_dynobj())
{
Stringpool::Key name_key)
{
Stringpool::Key filename_key;
- filename = dynpool->add(filename, &filename_key);
+ filename = dynpool->add(filename, true, &filename_key);
Key k(name_key, filename_key);
Version_base* const vbnull = NULL;
// Canonicalize the section name.
Stringpool::Key name_key;
- name = this->namepool_.add(name, len, &name_key);
+ name = this->namepool_.add_prefix(name, len, &name_key);
// Find the output section. The output section is selected based on
// the section name, type, and flags.
{
Stringpool::Key hdr_name_key;
const char* hdr_name = this->namepool_.add(".eh_frame_hdr",
+ false,
&hdr_name_key);
Output_section* hdr_os =
this->get_output_section(hdr_name, hdr_name_key,
{
// Canonicalize the name.
Stringpool::Key name_key;
- name = this->namepool_.add(name, &name_key);
+ name = this->namepool_.add(name, true, &name_key);
Output_section* os = this->get_output_section(name, name_key, type, flags);
os->add_output_section_data(posd);
if (!input_objects->any_dynamic())
return;
- const char* dynamic_name = this->namepool_.add(".dynamic", NULL);
+ const char* dynamic_name = this->namepool_.add(".dynamic", false, NULL);
this->dynamic_section_ = this->make_output_section(dynamic_name,
elfcpp::SHT_DYNAMIC,
(elfcpp::SHF_ALLOC
memcpy(buffer + 3 * (size / 8), name, namesz);
memcpy(buffer + 3 * (size / 8) + aligned_namesz, desc.data(), descsz);
- const char* note_name = this->namepool_.add(".note", NULL);
+ const char* note_name = this->namepool_.add(".note", false, NULL);
Output_section* os = this->make_output_section(note_name,
elfcpp::SHT_NOTE,
0);
{
this->sympool_.set_string_offsets();
- const char* symtab_name = this->namepool_.add(".symtab", NULL);
+ const char* symtab_name = this->namepool_.add(".symtab", false, NULL);
Output_section* osymtab = this->make_output_section(symtab_name,
elfcpp::SHT_SYMTAB,
0);
align);
osymtab->add_output_section_data(pos);
- const char* strtab_name = this->namepool_.add(".strtab", NULL);
+ const char* strtab_name = this->namepool_.add(".strtab", false, NULL);
Output_section* ostrtab = this->make_output_section(strtab_name,
elfcpp::SHT_STRTAB,
0);
// FIXME: We don't need to create a .shstrtab section if we are
// stripping everything.
- const char* name = this->namepool_.add(".shstrtab", NULL);
+ const char* name = this->namepool_.add(".shstrtab", false, NULL);
this->namepool_.set_string_offsets();
// Create the dynamic symbol table section.
- const char* dynsym_name = this->namepool_.add(".dynsym", NULL);
+ const char* dynsym_name = this->namepool_.add(".dynsym", false, NULL);
Output_section* dynsym = this->make_output_section(dynsym_name,
elfcpp::SHT_DYNSYM,
elfcpp::SHF_ALLOC);
// Create the dynamic string table section.
- const char* dynstr_name = this->namepool_.add(".dynstr", NULL);
+ const char* dynstr_name = this->namepool_.add(".dynstr", false, NULL);
Output_section* dynstr = this->make_output_section(dynstr_name,
elfcpp::SHT_STRTAB,
elfcpp::SHF_ALLOC);
Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
&phash, &hashlen);
- const char* hash_name = this->namepool_.add(".hash", NULL);
+ const char* hash_name = this->namepool_.add(".hash", false, NULL);
Output_section* hashsec = this->make_output_section(hash_name,
elfcpp::SHT_HASH,
elfcpp::SHF_ALLOC);
const Output_section* dynstr
ACCEPT_SIZE_ENDIAN)
{
- const char* vname = this->namepool_.add(".gnu.version", NULL);
+ const char* vname = this->namepool_.add(".gnu.version", false, NULL);
Output_section* vsec = this->make_output_section(vname,
elfcpp::SHT_GNU_versym,
elfcpp::SHF_ALLOC);
if (versions->any_defs())
{
- const char* vdname = this->namepool_.add(".gnu.version_d", NULL);
+ const char* vdname = this->namepool_.add(".gnu.version_d", false, NULL);
Output_section *vdsec;
vdsec = this->make_output_section(vdname, elfcpp::SHT_GNU_verdef,
elfcpp::SHF_ALLOC);
if (versions->any_needs())
{
- const char* vnname = this->namepool_.add(".gnu.version_r", NULL);
+ const char* vnname = this->namepool_.add(".gnu.version_r", false, NULL);
Output_section* vnsec;
vnsec = this->make_output_section(vnname, elfcpp::SHT_GNU_verneed,
elfcpp::SHF_ALLOC);
Output_section_data* odata = new Output_data_const(interp, len, 1);
- const char* interp_name = this->namepool_.add(".interp", NULL);
+ const char* interp_name = this->namepool_.add(".interp", false, NULL);
Output_section* osec = this->make_output_section(interp_name,
elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC);
}
}
- const Char_type* str = this->stringpool_.add(p, NULL);
+ const Char_type* str = this->stringpool_.add(p, true, NULL);
this->merged_strings_.push_back(Merged_string(object, shndx, i, str));
}
const char* name = pnames + sym.get_st_name();
- pool->add(name, NULL);
+ pool->add(name, true, NULL);
lv.set_output_symtab_index(index);
++index;
++count;
// Add a new dynamic entry with a string.
void
add_string(elfcpp::DT tag, const char* str)
- { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, NULL))); }
+ { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, true, NULL))); }
void
add_string(elfcpp::DT tag, const std::string& str)
template<typename Stringpool_char>
Stringpool_template<Stringpool_char>::Stringpool_template()
: string_set_(), strings_(), strtab_size_(0), next_index_(1),
- zero_null_(true)
+ next_uncopied_key_(-1), zero_null_(true)
{
}
template<typename Stringpool_char>
const Stringpool_char*
-Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, Key* pkey)
+Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
+ Key* pkey)
{
// FIXME: This will look up the entry twice in the hash table. The
// problem is that we can't insert S before we canonicalize it. I
}
Key k;
- const Stringpool_char* ret = this->add_string(s, &k);
+ const Stringpool_char* ret;
+ if (copy)
+ ret = this->add_string(s, &k);
+ else
+ {
+ ret = s;
+ k = this->next_uncopied_key_;
+ --this->next_uncopied_key_;
+ }
const off_t ozero = 0;
std::pair<const Stringpool_char*, Val> element(ret,
template<typename Stringpool_char>
const Stringpool_char*
-Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, size_t len,
- Key* pkey)
+Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
+ size_t len,
+ Key* pkey)
{
// FIXME: This implementation should be rewritten when we rewrite
// the hash table to avoid copying.
std::basic_string<Stringpool_char> st(s, len);
- return this->add(st, pkey);
+ return this->add(st.c_str(), true, pkey);
}
template<typename Stringpool_char>
// string pointer so that repeated runs of the linker will generate
// precisely the same output.
-// When you add a string to a Stringpool, Stringpool will make a copy
-// of it. Thus there is no need to keep a copy elsewhere.
+// When you add a string to a Stringpool, Stringpool will optionally
+// make a copy of it. Thus there is no requirement to keep a copy
+// elsewhere.
// A Stringpool can be turned into a string table, a sequential series
// of null terminated strings. The first string may optionally be a
{ this->zero_null_ = false; }
// Add the string S to the pool. This returns a canonical permanent
- // pointer to the string in the pool. If PKEY is not NULL, this
- // sets *PKEY to the key for the string.
+ // pointer to the string in the pool. If COPY is true, the string
+ // is copied into permanent storage. If PKEY is not NULL, this sets
+ // *PKEY to the key for the string.
const Stringpool_char*
- add(const Stringpool_char* s, Key* pkey);
-
- // Add the string S to the pool.
- const Stringpool_char*
- add(const std::basic_string<Stringpool_char>& s, Key* pkey)
- { return this->add(s.c_str(), pkey); }
+ add(const Stringpool_char* s, bool copy, Key* pkey);
// Add the prefix of length LEN of string S to the pool.
const Stringpool_char*
- add(const Stringpool_char* s, size_t len, Key* pkey);
+ add_prefix(const Stringpool_char* s, size_t len, Key* pkey);
// If the string S is present in the pool, return the canonical
// string pointer. Otherwise, return NULL. If PKEY is not NULL,
off_t strtab_size_;
// Next Stringdata index.
unsigned int next_index_;
+ // Next key value for a string we don't copy.
+ int next_uncopied_key_;
// Whether to reserve offset 0 to hold the null string.
bool zero_null_;
};
if (ver == NULL)
{
Stringpool::Key name_key;
- name = this->namepool_.add(name, &name_key);
+ name = this->namepool_.add(name, true, &name_key);
res = this->add_from_object(relobj, name, name_key, NULL, 0,
false, *psym);
}
else
{
Stringpool::Key name_key;
- name = this->namepool_.add(name, ver - name, &name_key);
+ name = this->namepool_.add_prefix(name, ver - name, &name_key);
bool def = false;
++ver;
}
Stringpool::Key ver_key;
- ver = this->namepool_.add(ver, &ver_key);
+ ver = this->namepool_.add(ver, true, &ver_key);
res = this->add_from_object(relobj, name, name_key, ver, ver_key,
def, *psym);
if (versym == NULL)
{
Stringpool::Key name_key;
- name = this->namepool_.add(name, &name_key);
+ name = this->namepool_.add(name, true, &name_key);
this->add_from_object(dynobj, name, name_key, NULL, 0,
false, sym);
continue;
// At this point we are definitely going to add this symbol.
Stringpool::Key name_key;
- name = this->namepool_.add(name, &name_key);
+ name = this->namepool_.add(name, true, &name_key);
if (v == static_cast<unsigned int>(elfcpp::VER_NDX_LOCAL)
|| v == static_cast<unsigned int>(elfcpp::VER_NDX_GLOBAL))
}
Stringpool::Key version_key;
- version = this->namepool_.add(version, &version_key);
+ version = this->namepool_.add(version, true, &version_key);
// If this is an absolute symbol, and the version name and
// symbol name are the same, then this is the version definition
{
// Canonicalize NAME and VERSION.
Stringpool::Key name_key;
- *pname = this->namepool_.add(*pname, &name_key);
+ *pname = this->namepool_.add(*pname, true, &name_key);
Stringpool::Key version_key = 0;
if (*pversion != NULL)
- *pversion = this->namepool_.add(*pversion, &version_key);
+ *pversion = this->namepool_.add(*pversion, true, &version_key);
Symbol* const snull = NULL;
std::pair<typename Symbol_table_type::iterator, bool> ins =
sym->set_dynsym_index(index);
++index;
syms->push_back(sym);
- dynpool->add(sym->name(), NULL);
+ dynpool->add(sym->name(), false, NULL);
// Record any version information.
if (sym->version() != NULL)
else
{
sym->set_symtab_index(index);
- pool->add(sym->name(), NULL);
+ pool->add(sym->name(), false, NULL);
++index;
off += sym_size;
}
// Canonicalize a symbol name for use in the hash table.
const char*
canonicalize_name(const char* name)
- { return this->namepool_.add(name, NULL); }
+ { return this->namepool_.add(name, true, NULL); }
// Possibly issue a warning for a reference to SYM at LOCATION which
// is in OBJ.