aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-09-12 16:38:04 +0000
committerIan Lance Taylor <iant@google.com>2007-09-12 16:38:04 +0000
commit8462ae85e4fa45aa0efb8b560e02ab21ecf90fd1 (patch)
tree48c0f1be2bcd5f3b45ac80e494ac457a5893c4a8 /gold
parent40b53987702c22f0ce9d5363fc493919517fa70a (diff)
downloadfsf-binutils-gdb-8462ae85e4fa45aa0efb8b560e02ab21ecf90fd1.zip
fsf-binutils-gdb-8462ae85e4fa45aa0efb8b560e02ab21ecf90fd1.tar.gz
fsf-binutils-gdb-8462ae85e4fa45aa0efb8b560e02ab21ecf90fd1.tar.bz2
Generate a GLOB_DAT reloc for a GOT32 reloc against a symbol defined
in a dynamic object.
Diffstat (limited to 'gold')
-rw-r--r--gold/i386.cc33
1 files changed, 19 insertions, 14 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index 448453a..6c1b987 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -666,7 +666,7 @@ Target_i386::optimize_tls_reloc(const General_options* options,
if (is_final)
return elfcpp::R_386_TLS_LE_32;
return r_type;
-
+
case elfcpp::R_386_TLS_LE:
case elfcpp::R_386_TLS_LE_32:
// When we already have Local-Exec, there is nothing further we
@@ -804,7 +804,7 @@ Target_i386::Scan::global(const General_options& options,
{
case elfcpp::R_386_NONE:
case elfcpp::R_386_GNU_VTINHERIT:
- case elfcpp::R_386_GNU_VTENTRY:
+ case elfcpp::R_386_GNU_VTENTRY:
break;
case elfcpp::R_386_32:
@@ -834,14 +834,22 @@ Target_i386::Scan::global(const General_options& options,
break;
case elfcpp::R_386_GOT32:
- // The symbol requires a GOT entry.
- if (target->got_section(&options, symtab, layout)->add_global(gsym))
- {
- // If this symbol is not fully resolved, we need to add a
- // dynamic relocation for it.
- if (!gsym->final_value_is_known(&options))
- gold_unreachable();
- }
+ {
+ // The symbol requires a GOT entry.
+ Output_data_got<32, false>* got = target->got_section(&options, symtab,
+ layout);
+ if (got->add_global(gsym))
+ {
+ // If this symbol is not fully resolved, we need to add a
+ // dynamic relocation for it.
+ if (!gsym->final_value_is_known(&options))
+ {
+ Reloc_section* rel_dyn = target->rel_dyn_section(layout);
+ rel_dyn->add_global(gsym, elfcpp::R_386_GLOB_DAT, got,
+ gsym->got_offset());
+ }
+ }
+ }
break;
case elfcpp::R_386_PLT32:
@@ -1051,11 +1059,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
// Pick the value to use for symbols defined in shared objects.
Symbol_value<32> symval;
- if (gsym != NULL && gsym->is_from_dynobj())
+ if (gsym != NULL && gsym->is_from_dynobj() && gsym->has_plt_offset())
{
- if (!gsym->has_plt_offset())
- gold_unreachable();
-
symval.set_output_value(target->plt_section()->address()
+ gsym->plt_offset());
psymval = &symval;