summaryrefslogtreecommitdiff
path: root/gold/i386.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2008-03-25 18:37:16 +0000
committerCary Coutant <ccoutant@google.com>2008-03-25 18:37:16 +0000
commit0a65a3a7402d9b8523844366c638a0354f48dfa4 (patch)
tree38d2a9a2cbf1277091cd8de1f92c3e6871156407 /gold/i386.cc
parent403fe1979f7a9e128d3904731e709fadbf60ea81 (diff)
downloadbinutils-gdb-0a65a3a7402d9b8523844366c638a0354f48dfa4.tar.gz
* 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.cc78
1 files changed, 48 insertions, 30 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index cc55249e9c8..f12b6cdebf0 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.