Chromium Code Reviews| Index: gold/symtab.cc |
| =================================================================== |
| old mode 100644 |
| new mode 100755 |
| --- a/gold/symtab.cc |
| +++ b/gold/symtab.cc |
| @@ -527,7 +527,8 @@ |
| : saw_undefined_(0), offset_(0), table_(count), namepool_(), |
| forwarders_(), commons_(), tls_commons_(), small_commons_(), |
| large_commons_(), forced_locals_(), warnings_(), |
| - version_script_(version_script), gc_(NULL), icf_(NULL) |
| + version_script_(version_script), gc_(NULL), icf_(NULL), |
| + global_got_index_((unsigned int)-1) |
| { |
| namepool_.reserve(count); |
| } |
| @@ -2353,6 +2354,11 @@ |
| ++this->saw_undefined_; |
| } |
| +bool got_offset_compare(Symbol *sym1, Symbol *sym2) |
|
robertm
2012/04/27 19:46:15
the convention seems to be to move "*" to the left
Aleksandar Simeonov
2012/05/08 15:21:42
Will be done.
|
| +{ |
| + return sym1->got_offset(0) < sym2->got_offset(0); |
| +} |
| + |
| // Set the dynamic symbol indexes. INDEX is the index of the first |
| // global dynamic symbol. Pointers to the symbols are stored into the |
| // vector SYMS. The names are added to DYNPOOL. This returns an |
| @@ -2364,6 +2370,9 @@ |
| Stringpool* dynpool, |
| Versions* versions) |
| { |
| + std::vector<Symbol *> externals; |
|
robertm
2012/04/27 19:46:15
are these change specific to MIPS - if yes explain
Aleksandar Simeonov
2012/05/08 15:21:42
The dynamic symbol table is divided into local and
|
| + int i; |
| + |
| for (Symbol_table_type::iterator p = this->table_.begin(); |
| p != this->table_.end(); |
| ++p) |
| @@ -2376,7 +2385,13 @@ |
| if (!sym->should_add_dynsym_entry(this)) |
| sym->set_dynsym_index(-1U); |
| - else if (!sym->has_dynsym_index()) |
| + else if((!sym->has_dynsym_index() && sym->has_got_offset(0)) |
|
robertm
2012/04/27 19:46:15
This condition is complex enough that it might be
|
| + && (!sym->final_value_is_known() |
| + || (parameters->options().output_is_position_independent()))) |
| + { |
| + externals.push_back(sym); |
| + } |
| + else if(!sym->has_dynsym_index()) |
| { |
| sym->set_dynsym_index(index); |
| ++index; |
| @@ -2395,10 +2410,49 @@ |
| } |
| } |
| - // Finish up the versions. In some cases this may add new dynamic |
| - // symbols. |
| + // At the end of dynamic symbol table place global symbols that has |
| + // .got entry. |
| + std::sort(externals.begin(), externals.end(), got_offset_compare); |
|
robertm
2012/04/27 19:46:15
mention all the extra work you do here in the func
Aleksandar Simeonov
2012/05/08 15:21:42
Will be done.
|
| + for(i = 0; (unsigned int)i < externals.size(); i++) |
| + { |
| + Symbol* sym = externals[i]; |
| + |
| + if(sym->has_dynsym_index()) |
| + continue; |
| + |
| + // Record any version information. |
| + if (sym->version() != NULL) |
| + versions->record_version(this, dynpool, sym); |
| + } |
| + |
| index = versions->finalize(this, index, syms); |
| + // Set index of the first external symbol that has .got entry. |
| + this->global_got_index_ = index; |
| + |
| + for(i = 0; (unsigned int)i < externals.size(); i++) |
| + { |
| + Symbol* sym = externals[i]; |
| + |
| + if(sym->has_dynsym_index()) |
| + continue; |
| + |
| + sym->set_dynsym_index(index); |
| + ++index; |
| + syms->push_back(sym); |
| + dynpool->add(sym->name(), false, NULL); |
| + |
| + // If the symbol is defined in a dynamic object and is |
| + // referenced in a regular object, then mark the dynamic |
| + // object as needed. This is used to implement --as-needed. |
| + if (sym->is_from_dynobj() && sym->in_reg()) |
| + sym->object()->set_is_needed(); |
| + } |
| + |
| + // If there are no global symbols with .got entry set value to -1. |
| + if(this->global_got_index_ == index) |
| + this->global_got_index_ = (unsigned int)-1; |
| + |
| return index; |
| } |
| @@ -3580,6 +3634,32 @@ |
| elfcpp::Elf_types<64>::Elf_Addr value); |
| #endif |
| +#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG) |
| +template |
| +void |
| +Sized_symbol<32>::init_output_data(const char* name, const char* version, |
| + Output_data* od, Value_type value, |
|
robertm
2012/04/27 19:46:15
indentation is off, also convention seems to be on
Aleksandar Simeonov
2012/05/08 15:21:42
It is not sure what is convention since before the
|
| + Size_type symsize, elfcpp::STT type, |
| + elfcpp::STB binding, |
| + elfcpp::STV visibility, |
| + unsigned char nonvis, |
| + bool offset_is_from_end, |
| + bool is_predefined); |
| +#endif |
| + |
| +#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG) |
| +template |
| +void |
| +Sized_symbol<64>::init_output_data(const char* name, const char* version, |
| + Output_data* od, Value_type value, |
|
robertm
2012/04/27 19:46:15
here too
Aleksandar Simeonov
2012/05/08 15:21:42
Same as above.
|
| + Size_type symsize, elfcpp::STT type, |
| + elfcpp::STB binding, |
| + elfcpp::STV visibility, |
| + unsigned char nonvis, |
| + bool offset_is_from_end, |
| + bool is_predefined); |
| +#endif |
| + |
| #ifdef HAVE_TARGET_32_LITTLE |
| template |
| void |