diff options
author | Cary Coutant <ccoutant@google.com> | 2008-03-25 18:37:16 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2008-03-25 18:37:16 +0000 |
commit | 0a65a3a7402d9b8523844366c638a0354f48dfa4 (patch) | |
tree | 38d2a9a2cbf1277091cd8de1f92c3e6871156407 /gold/output.cc | |
parent | 403fe1979f7a9e128d3904731e709fadbf60ea81 (diff) | |
download | gdb-0a65a3a7402d9b8523844366c638a0354f48dfa4.zip gdb-0a65a3a7402d9b8523844366c638a0354f48dfa4.tar.gz gdb-0a65a3a7402d9b8523844366c638a0354f48dfa4.tar.bz2 |
* i386.cc (Target_i386::Got_type): New enum declaration.
(Target_i386::Scan::local): Updated callers of Output_data_got
member functions.
(Target_i386::Scan::global): Likewise.
(Target_i386::Relocate::relocate): Likewise.
(Target_i386::Relocate::relocate_tls): Likewise.
* object.h (Got_offset_list): New class.
(Sized_relobj::local_has_got_offset): Added got_type parameter.
(Sized_relobj::local_got_offset): Likewise.
(Sized_relobj::set_local_got_offset): Likewise.
(Sized_relobj::local_has_tls_got_offset): Removed.
(Sized_relobj::local_tls_got_offset): Removed.
(Sized_relobj::set_local_tls_got_offset): Removed.
(Sized_relobj::Local_got_offsets): Changed to store a list of offsets.
* output.cc (Output_data_got::add_global): Added got_type parameter.
(Output_data_got::add_global_with_rel): Likewise.
(Output_data_got::add_global_with_rela): Likewise.
(Output_data_got::add_global_pair_with_rel): New function.
(Output_data_got::add_global_pair_with_rela): New function.
(Output_data_got::add_local): Added got_type parameter.
(Output_data_got::add_local_with_rel): Likewise.
(Output_data_got::add_local_with_rela): Likewise.
(Output_data_got::add_local_pair_with_rel): New function.
(Output_data_got::add_local_pair_with_rela): New function.
(Output_data_got::add_global_tls): Removed.
(Output_data_got::add_global_tls_with_rel): Removed.
(Output_data_got::add_global_tls_with_rela): Removed.
(Output_data_got::add_local_tls): Removed.
(Output_data_got::add_local_tls_with_rel): Removed.
(Output_data_got::add_local_tls_with_rela): Removed.
* output.h (Output_data_got::add_global): Added got_type parameter.
(Output_data_got::add_global_with_rel): Likewise.
(Output_data_got::add_global_with_rela): Likewise.
(Output_data_got::add_global_pair_with_rel): New function.
(Output_data_got::add_global_pair_with_rela): New function.
(Output_data_got::add_local): Added got_type parameter.
(Output_data_got::add_local_with_rel): Likewise.
(Output_data_got::add_local_with_rela): Likewise.
(Output_data_got::add_local_pair_with_rel): New function.
(Output_data_got::add_local_pair_with_rela): New function.
(Output_data_got::add_global_tls): Removed.
(Output_data_got::add_global_tls_with_rel): Removed.
(Output_data_got::add_global_tls_with_rela): Removed.
(Output_data_got::add_local_tls): Removed.
(Output_data_got::add_local_tls_with_rel): Removed.
(Output_data_got::add_local_tls_with_rela): Removed.
* resolve.cc (Symbol::override_base_with_special): Removed
reference to has_got_offset_ field.
* symtab.cc (Symbol::init_fields): Replaced initialization
of got_offset_ with got_offsets_. Removed initialization
of has_got_offset_
*symtab.h (Symbol::has_got_offset): Aded got_type parameter.
(Symbol::got_offset): Likewise.
(Symbol::set_got_offset): Likewise.
(Symbol::has_tls_got_offset): Removed.
(Symbol::tls_got_offset): Removed.
(Symbol::set_tls_got_offset): Removed.
(Symbol::got_offset_): Removed.
(Symbol::tls_mod_got_offset_): Removed.
(Symbol::tls_pair_got_offset_): Removed.
(Symbol::got_offsets_): New field.
(Symbol::has_got_offset): Removed.
(Symbol::has_tls_mod_got_offset): Removed.
(Symbol::has_tls_pair_got_offset): Removed.
* x86_64.cc (Target_x86_64::Got_type): New enum declaration.
(Target_x86_64::Scan::local): Updated callers of Output_data_got
member functions.
(Target_x86_64::Scan::global): Likewise.
(Target_x86_64::Relocate::relocate): Likewise.
(Target_x86_64::Relocate::relocate_tls): Likewise.
Diffstat (limited to 'gold/output.cc')
-rw-r--r-- | gold/output.cc | 265 |
1 files changed, 103 insertions, 162 deletions
diff --git a/gold/output.cc b/gold/output.cc index 85cc2b2..3a11aa4 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1059,14 +1059,16 @@ Output_data_got<size, big_endian>::Got_entry::write(unsigned char* pov) const template<int size, bool big_endian> bool -Output_data_got<size, big_endian>::add_global(Symbol* gsym) +Output_data_got<size, big_endian>::add_global( + Symbol* gsym, + unsigned int got_type) { - if (gsym->has_got_offset()) + if (gsym->has_got_offset(got_type)) return false; this->entries_.push_back(Got_entry(gsym)); this->set_got_size(); - gsym->set_got_offset(this->last_got_offset()); + gsym->set_got_offset(got_type, this->last_got_offset()); return true; } @@ -1076,16 +1078,17 @@ template<int size, bool big_endian> void Output_data_got<size, big_endian>::add_global_with_rel( Symbol* gsym, + unsigned int got_type, Rel_dyn* rel_dyn, unsigned int r_type) { - if (gsym->has_got_offset()) + if (gsym->has_got_offset(got_type)) return; this->entries_.push_back(Got_entry()); this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - gsym->set_got_offset(got_offset); + gsym->set_got_offset(got_type, got_offset); rel_dyn->add_global(gsym, r_type, this, got_offset); } @@ -1093,260 +1096,198 @@ template<int size, bool big_endian> void Output_data_got<size, big_endian>::add_global_with_rela( Symbol* gsym, + unsigned int got_type, Rela_dyn* rela_dyn, unsigned int r_type) { - if (gsym->has_got_offset()) + if (gsym->has_got_offset(got_type)) return; this->entries_.push_back(Got_entry()); this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - gsym->set_got_offset(got_offset); + gsym->set_got_offset(got_type, got_offset); rela_dyn->add_global(gsym, r_type, this, got_offset, 0); } -// Add an entry for a local symbol to the GOT. This returns true if -// this is a new GOT entry, false if the symbol already has a GOT -// entry. - -template<int size, bool big_endian> -bool -Output_data_got<size, big_endian>::add_local( - Sized_relobj<size, big_endian>* object, - unsigned int symndx) -{ - if (object->local_has_got_offset(symndx)) - return false; - - this->entries_.push_back(Got_entry(object, symndx)); - this->set_got_size(); - object->set_local_got_offset(symndx, this->last_got_offset()); - return true; -} - -// Add an entry for a local symbol to the GOT, and add a dynamic -// relocation of type R_TYPE for the GOT entry. +// Add a pair of entries for a global symbol to the GOT, and add +// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. +// If R_TYPE_2 == 0, add the second entry with no relocation. template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_with_rel( - Sized_relobj<size, big_endian>* object, - unsigned int symndx, +Output_data_got<size, big_endian>::add_global_pair_with_rel( + Symbol* gsym, + unsigned int got_type, Rel_dyn* rel_dyn, - unsigned int r_type) + unsigned int r_type_1, + unsigned int r_type_2) { - if (object->local_has_got_offset(symndx)) + if (gsym->has_got_offset(got_type)) return; this->entries_.push_back(Got_entry()); - this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - object->set_local_got_offset(symndx, got_offset); - rel_dyn->add_local(object, symndx, r_type, this, got_offset); + gsym->set_got_offset(got_type, got_offset); + rel_dyn->add_global(gsym, r_type_1, this, got_offset); + + this->entries_.push_back(Got_entry()); + if (r_type_2 != 0) + { + got_offset = this->last_got_offset(); + rel_dyn->add_global(gsym, r_type_2, this, got_offset); + } + + this->set_got_size(); } template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_with_rela( - Sized_relobj<size, big_endian>* object, - unsigned int symndx, +Output_data_got<size, big_endian>::add_global_pair_with_rela( + Symbol* gsym, + unsigned int got_type, Rela_dyn* rela_dyn, - unsigned int r_type) + unsigned int r_type_1, + unsigned int r_type_2) { - if (object->local_has_got_offset(symndx)) + if (gsym->has_got_offset(got_type)) return; this->entries_.push_back(Got_entry()); - this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - object->set_local_got_offset(symndx, got_offset); - rela_dyn->add_local(object, symndx, r_type, this, got_offset, 0); + gsym->set_got_offset(got_type, got_offset); + rela_dyn->add_global(gsym, r_type_1, this, got_offset, 0); + + this->entries_.push_back(Got_entry()); + if (r_type_2 != 0) + { + got_offset = this->last_got_offset(); + rela_dyn->add_global(gsym, r_type_2, this, got_offset, 0); + } + + this->set_got_size(); } -// Add an entry (or a pair of entries) for a global TLS symbol to the GOT. -// In a pair of entries, the first value in the pair will be used for the -// module index, and the second value will be used for the dtv-relative -// offset. This returns true if this is a new GOT entry, false if the symbol -// already has a GOT entry. +// Add an entry for a local symbol to the GOT. This returns true if +// this is a new GOT entry, false if the symbol already has a GOT +// entry. template<int size, bool big_endian> bool -Output_data_got<size, big_endian>::add_global_tls(Symbol* gsym, bool need_pair) +Output_data_got<size, big_endian>::add_local( + Sized_relobj<size, big_endian>* object, + unsigned int symndx, + unsigned int got_type) { - if (gsym->has_tls_got_offset(need_pair)) + if (object->local_has_got_offset(symndx, got_type)) return false; - this->entries_.push_back(Got_entry(gsym)); - gsym->set_tls_got_offset(this->last_got_offset(), need_pair); - if (need_pair) - this->entries_.push_back(Got_entry(gsym)); + this->entries_.push_back(Got_entry(object, symndx)); this->set_got_size(); + object->set_local_got_offset(symndx, got_type, this->last_got_offset()); return true; } -// Add an entry for a global TLS symbol to the GOT, and add a dynamic -// relocation of type R_TYPE. +// Add an entry for a local symbol to the GOT, and add a dynamic +// relocation of type R_TYPE for the GOT entry. template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_global_tls_with_rel( - Symbol* gsym, +Output_data_got<size, big_endian>::add_local_with_rel( + Sized_relobj<size, big_endian>* object, + unsigned int symndx, + unsigned int got_type, Rel_dyn* rel_dyn, unsigned int r_type) { - if (gsym->has_tls_got_offset(false)) + if (object->local_has_got_offset(symndx, got_type)) return; this->entries_.push_back(Got_entry()); this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - gsym->set_tls_got_offset(got_offset, false); - rel_dyn->add_global(gsym, r_type, this, got_offset); + object->set_local_got_offset(symndx, got_type, got_offset); + rel_dyn->add_local(object, symndx, r_type, this, got_offset); } template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_global_tls_with_rela( - Symbol* gsym, +Output_data_got<size, big_endian>::add_local_with_rela( + Sized_relobj<size, big_endian>* object, + unsigned int symndx, + unsigned int got_type, Rela_dyn* rela_dyn, unsigned int r_type) { - if (gsym->has_tls_got_offset(false)) + if (object->local_has_got_offset(symndx, got_type)) return; this->entries_.push_back(Got_entry()); this->set_got_size(); unsigned int got_offset = this->last_got_offset(); - gsym->set_tls_got_offset(got_offset, false); - rela_dyn->add_global(gsym, r_type, this, got_offset, 0); -} - -// Add a pair of entries for a global TLS symbol to the GOT, and add -// dynamic relocations of type MOD_R_TYPE and DTV_R_TYPE, respectively. -template<int size, bool big_endian> -void -Output_data_got<size, big_endian>::add_global_tls_with_rel( - Symbol* gsym, - Rel_dyn* rel_dyn, - unsigned int mod_r_type, - unsigned int dtv_r_type) -{ - if (gsym->has_tls_got_offset(true)) - return; - - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); - gsym->set_tls_got_offset(got_offset, true); - rel_dyn->add_global(gsym, mod_r_type, this, got_offset); - - this->entries_.push_back(Got_entry()); - this->set_got_size(); - got_offset = this->last_got_offset(); - rel_dyn->add_global(gsym, dtv_r_type, this, got_offset); -} - -template<int size, bool big_endian> -void -Output_data_got<size, big_endian>::add_global_tls_with_rela( - Symbol* gsym, - Rela_dyn* rela_dyn, - unsigned int mod_r_type, - unsigned int dtv_r_type) -{ - if (gsym->has_tls_got_offset(true)) - return; - - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); - gsym->set_tls_got_offset(got_offset, true); - rela_dyn->add_global(gsym, mod_r_type, this, got_offset, 0); - - this->entries_.push_back(Got_entry()); - this->set_got_size(); - got_offset = this->last_got_offset(); - rela_dyn->add_global(gsym, dtv_r_type, this, got_offset, 0); -} - -// Add an entry (or a pair of entries) for a local TLS symbol to the GOT. -// In a pair of entries, the first value in the pair will be used for the -// module index, and the second value will be used for the dtv-relative -// offset. This returns true if this is a new GOT entry, false if the symbol -// already has a GOT entry. - -template<int size, bool big_endian> -bool -Output_data_got<size, big_endian>::add_local_tls( - Sized_relobj<size, big_endian>* object, - unsigned int symndx, - bool need_pair) -{ - if (object->local_has_tls_got_offset(symndx, need_pair)) - return false; - - this->entries_.push_back(Got_entry(object, symndx)); - object->set_local_tls_got_offset(symndx, this->last_got_offset(), need_pair); - if (need_pair) - this->entries_.push_back(Got_entry(object, symndx)); - this->set_got_size(); - return true; + object->set_local_got_offset(symndx, got_type, got_offset); + rela_dyn->add_local(object, symndx, r_type, this, got_offset, 0); } -// Add an entry (or pair of entries) for a local TLS symbol to the GOT, -// and add a dynamic relocation of type R_TYPE for the first GOT entry. -// Because this is a local symbol, the first GOT entry can be relocated -// relative to a section symbol, and the second GOT entry will have an -// dtv-relative value that can be computed at link time. +// Add a pair of entries for a local symbol to the GOT, and add +// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. +// If R_TYPE_2 == 0, add the second entry with no relocation. template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_tls_with_rel( +Output_data_got<size, big_endian>::add_local_pair_with_rel( Sized_relobj<size, big_endian>* object, unsigned int symndx, unsigned int shndx, - bool need_pair, + unsigned int got_type, Rel_dyn* rel_dyn, - unsigned int r_type) + unsigned int r_type_1, + unsigned int r_type_2) { - if (object->local_has_tls_got_offset(symndx, need_pair)) + if (object->local_has_got_offset(symndx, got_type)) return; this->entries_.push_back(Got_entry()); unsigned int got_offset = this->last_got_offset(); - object->set_local_tls_got_offset(symndx, got_offset, need_pair); + object->set_local_got_offset(symndx, got_type, got_offset); section_offset_type off; Output_section* os = object->output_section(shndx, &off); - rel_dyn->add_output_section(os, r_type, this, got_offset); + rel_dyn->add_output_section(os, r_type_1, this, got_offset); - // The second entry of the pair will be statically initialized - // with the TLS offset of the symbol. - if (need_pair) - this->entries_.push_back(Got_entry(object, symndx)); + this->entries_.push_back(Got_entry(object, symndx)); + if (r_type_2 != 0) + { + got_offset = this->last_got_offset(); + rel_dyn->add_output_section(os, r_type_2, this, got_offset); + } this->set_got_size(); } template<int size, bool big_endian> void -Output_data_got<size, big_endian>::add_local_tls_with_rela( +Output_data_got<size, big_endian>::add_local_pair_with_rela( Sized_relobj<size, big_endian>* object, unsigned int symndx, unsigned int shndx, - bool need_pair, + unsigned int got_type, Rela_dyn* rela_dyn, - unsigned int r_type) + unsigned int r_type_1, + unsigned int r_type_2) { - if (object->local_has_tls_got_offset(symndx, need_pair)) + if (object->local_has_got_offset(symndx, got_type)) return; this->entries_.push_back(Got_entry()); unsigned int got_offset = this->last_got_offset(); - object->set_local_tls_got_offset(symndx, got_offset, need_pair); + object->set_local_got_offset(symndx, got_type, got_offset); section_offset_type off; Output_section* os = object->output_section(shndx, &off); - rela_dyn->add_output_section(os, r_type, this, got_offset, 0); + rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0); - // The second entry of the pair will be statically initialized - // with the TLS offset of the symbol. - if (need_pair) - this->entries_.push_back(Got_entry(object, symndx)); + this->entries_.push_back(Got_entry(object, symndx)); + if (r_type_2 != 0) + { + got_offset = this->last_got_offset(); + rela_dyn->add_output_section(os, r_type_2, this, got_offset, 0); + } this->set_got_size(); } |