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/i386.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/i386.cc')
-rw-r--r-- | gold/i386.cc | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/gold/i386.cc b/gold/i386.cc index cc55249..f12b6cd 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -339,6 +339,15 @@ class Target_i386 : public Sized_target<32, false> // general Target structure. static const Target::Target_info i386_info; + // The types of GOT entries needed for this platform. + enum Got_type + { + GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol + GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset + GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair + GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair + }; + // The GOT section. Output_data_got<32, false>* got_; // The PLT section. @@ -933,7 +942,7 @@ Target_i386::Scan::local(const General_options&, // The symbol requires a GOT entry. Output_data_got<32, false>* got = target->got_section(symtab, layout); unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); - if (got->add_local(object, r_sym)) + if (got->add_local(object, r_sym, GOT_TYPE_STANDARD)) { // If we are generating a shared object, we need to add a // dynamic RELATIVE relocation for this symbol's GOT entry. @@ -941,10 +950,9 @@ Target_i386::Scan::local(const General_options&, { Reloc_section* rel_dyn = target->rel_dyn_section(layout); unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); - rel_dyn->add_local_relative(object, r_sym, - elfcpp::R_386_RELATIVE, - got, - object->local_got_offset(r_sym)); + rel_dyn->add_local_relative( + object, r_sym, elfcpp::R_386_RELATIVE, got, + object->local_got_offset(r_sym, GOT_TYPE_STANDARD)); } } } @@ -991,10 +999,11 @@ Target_i386::Scan::local(const General_options&, Output_data_got<32, false>* got = target->got_section(symtab, layout); unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); - got->add_local_tls_with_rel(object, r_sym, - lsym.get_st_shndx(), true, - target->rel_dyn_section(layout), - elfcpp::R_386_TLS_DTPMOD32); + got->add_local_pair_with_rel(object, r_sym, + lsym.get_st_shndx(), + GOT_TYPE_TLS_PAIR, + target->rel_dyn_section(layout), + elfcpp::R_386_TLS_DTPMOD32, 0); } else if (optimized_type != tls::TLSOPT_TO_LE) unsupported_reloc_local(object, r_type); @@ -1047,7 +1056,7 @@ Target_i386::Scan::local(const General_options&, unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32 ? elfcpp::R_386_TLS_TPOFF32 : elfcpp::R_386_TLS_TPOFF); - got->add_local_with_rel(object, r_sym, + got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET, target->rel_dyn_section(layout), dyn_r_type); } @@ -1210,7 +1219,7 @@ Target_i386::Scan::global(const General_options& options, // The symbol requires a GOT entry. Output_data_got<32, false>* got = target->got_section(symtab, layout); if (gsym->final_value_is_known()) - got->add_global(gsym); + got->add_global(gsym, GOT_TYPE_STANDARD); else { // If this symbol is not fully resolved, we need to add a @@ -1219,12 +1228,14 @@ Target_i386::Scan::global(const General_options& options, if (gsym->is_from_dynobj() || gsym->is_undefined() || gsym->is_preemptible()) - got->add_global_with_rel(gsym, rel_dyn, elfcpp::R_386_GLOB_DAT); + got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, + rel_dyn, elfcpp::R_386_GLOB_DAT); else { - if (got->add_global(gsym)) - rel_dyn->add_global_relative(gsym, elfcpp::R_386_RELATIVE, - got, gsym->got_offset()); + if (got->add_global(gsym, GOT_TYPE_STANDARD)) + rel_dyn->add_global_relative( + gsym, elfcpp::R_386_RELATIVE, got, + gsym->got_offset(GOT_TYPE_STANDARD)); } } } @@ -1291,7 +1302,7 @@ Target_i386::Scan::global(const General_options& options, // dtv-relative offset. Output_data_got<32, false>* got = target->got_section(symtab, layout); - got->add_global_tls_with_rel(gsym, + got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR, target->rel_dyn_section(layout), elfcpp::R_386_TLS_DTPMOD32, elfcpp::R_386_TLS_DTPOFF32); @@ -1301,7 +1312,8 @@ Target_i386::Scan::global(const General_options& options, // Create a GOT entry for the tp-relative offset. Output_data_got<32, false>* got = target->got_section(symtab, layout); - got->add_global_with_rel(gsym, target->rel_dyn_section(layout), + got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET, + target->rel_dyn_section(layout), elfcpp::R_386_TLS_TPOFF32); } else if (optimized_type != tls::TLSOPT_TO_LE) @@ -1353,7 +1365,7 @@ Target_i386::Scan::global(const General_options& options, unsigned int dyn_r_type = (r_type == elfcpp::R_386_TLS_IE_32 ? elfcpp::R_386_TLS_TPOFF32 : elfcpp::R_386_TLS_TPOFF); - got->add_global_with_rel(gsym, + got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET, target->rel_dyn_section(layout), dyn_r_type); } @@ -1576,14 +1588,16 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo, case elfcpp::R_386_GOT32: if (gsym != NULL) { - gold_assert(gsym->has_got_offset()); - got_offset = gsym->got_offset() - target->got_size(); + gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD)); + got_offset = (gsym->got_offset(GOT_TYPE_STANDARD) + - target->got_size()); } else { unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym)); - got_offset = object->local_got_offset(r_sym) - target->got_size(); + gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD)); + got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD) + - target->got_size()); } have_got_offset = true; break; @@ -1770,14 +1784,16 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, unsigned int got_offset; if (gsym != NULL) { - gold_assert(gsym->has_tls_got_offset(true)); - got_offset = gsym->tls_got_offset(true) - target->got_size(); + gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_PAIR)); + got_offset = (gsym->got_offset(GOT_TYPE_TLS_PAIR) + - target->got_size()); } else { unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_tls_got_offset(r_sym, true)); - got_offset = (object->local_tls_got_offset(r_sym, true) + gold_assert(object->local_has_got_offset(r_sym, + GOT_TYPE_TLS_PAIR)); + got_offset = (object->local_got_offset(r_sym, GOT_TYPE_TLS_PAIR) - target->got_size()); } if (optimized_type == tls::TLSOPT_TO_IE) @@ -1868,14 +1884,16 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, unsigned int got_offset; if (gsym != NULL) { - gold_assert(gsym->has_got_offset()); - got_offset = gsym->got_offset(); + gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_OFFSET)); + got_offset = gsym->got_offset(GOT_TYPE_TLS_OFFSET); } else { unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym)); - got_offset = object->local_got_offset(r_sym); + gold_assert(object->local_has_got_offset(r_sym, + GOT_TYPE_TLS_OFFSET)); + got_offset = object->local_got_offset(r_sym, + GOT_TYPE_TLS_OFFSET); } // For the R_386_TLS_IE relocation, we need to apply the // absolute address of the GOT entry. |