PR 9918
[deliverable/binutils-gdb.git] / gold / i386.cc
index 8889a6802b701733f8050473e6cbeae999109208..3beacaa28cae2ea1326ed94875a8e50eeffe75ef 100644 (file)
@@ -1,6 +1,6 @@
 // i386.cc -- i386 target support for gold.
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -62,6 +62,22 @@ class Target_i386 : public Sized_target<32, false>
       got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
   { }
 
+  // Process the relocations to determine unreferenced sections for 
+  // garbage collection.
+  void
+  gc_process_relocs(const General_options& options,
+                    Symbol_table* symtab,
+                    Layout* layout,
+                    Sized_relobj<32, false>* object,
+                    unsigned int data_shndx,
+                    unsigned int sh_type,
+                    const unsigned char* prelocs,
+                    size_t reloc_count,
+                    Output_section* output_section,
+                    bool needs_special_offset_handling,
+                    size_t local_symbol_count,
+                    const unsigned char* plocal_symbols);
+
   // Scan the relocations to look for symbol adjustments.
   void
   scan_relocs(const General_options& options,
@@ -135,7 +151,7 @@ class Target_i386 : public Sized_target<32, false>
 
   // Return whether SYM is defined by the ABI.
   bool
-  do_is_defined_by_abi(Symbol* sym) const
+  do_is_defined_by_abi(const Symbol* sym) const
   { return strcmp(sym->name(), "___tls_get_addr") == 0; }
 
   // Return the size of the GOT section.
@@ -198,13 +214,14 @@ class Target_i386 : public Sized_target<32, false>
     inline bool
     should_apply_static_reloc(const Sized_symbol<32>* gsym,
                               int ref_flags,
-                              bool is_32bit);
+                              bool is_32bit,
+                             Output_section* output_section);
 
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<32, false>*, Target_i386*, size_t relnum,
-            const elfcpp::Rel<32, false>&,
+    relocate(const Relocate_info<32, false>*, Target_i386*, Output_section*,
+            size_t relnum, const elfcpp::Rel<32, false>&,
             unsigned int r_type, const Sized_symbol<32>*,
             const Symbol_value<32>*,
             unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
@@ -323,7 +340,7 @@ class Target_i386 : public Sized_target<32, false>
   void
   make_plt_entry(Symbol_table*, Layout*, Symbol*);
 
-  // Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+  // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
   void
   define_tls_base_symbol(Symbol_table*, Layout*);
 
@@ -736,7 +753,7 @@ Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
   this->plt_->add_entry(gsym);
 }
 
-// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
 
 void
 Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
@@ -1456,6 +1473,38 @@ Target_i386::Scan::global(const General_options&,
     }
 }
 
+// Process relocations for gc.
+
+void
+Target_i386::gc_process_relocs(const General_options& options,
+                               Symbol_table* symtab,
+                               Layout* layout,
+                               Sized_relobj<32, false>* object,
+                               unsigned int data_shndx,
+                               unsigned int,
+                               const unsigned char* prelocs,
+                               size_t reloc_count,
+                               Output_section* output_section,
+                               bool needs_special_offset_handling,
+                               size_t local_symbol_count,
+                               const unsigned char* plocal_symbols)
+{
+  gold::gc_process_relocs<32, false, Target_i386, elfcpp::SHT_REL,
+                         Target_i386::Scan>(
+    options,
+    symtab,
+    layout,
+    this,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols);
+}
+
 // Scan relocations for a section.
 
 void
@@ -1547,8 +1596,15 @@ Target_i386::do_finalize_sections(Layout* layout)
 inline bool
 Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
                                                  int ref_flags,
-                                                 bool is_32bit)
+                                                 bool is_32bit,
+                                                Output_section* output_section)
 {
+  // If the output section is not allocated, then we didn't call
+  // scan_relocs, we didn't create a dynamic reloc, and we must apply
+  // the reloc here.
+  if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
+    return true;
+
   // For local symbols, we will have created a non-RELATIVE dynamic
   // relocation only if (a) the output is position independent,
   // (b) the relocation is absolute (not pc- or segment-relative), and
@@ -1574,6 +1630,7 @@ Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
 inline bool
 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
                                Target_i386* target,
+                               Output_section *output_section,
                                size_t relnum,
                                const elfcpp::Rel<32, false>& rel,
                                unsigned int r_type,
@@ -1585,7 +1642,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 {
   if (this->skip_call_tls_get_addr_)
     {
-      if (r_type != elfcpp::R_386_PLT32
+      if ((r_type != elfcpp::R_386_PLT32
+           && r_type != elfcpp::R_386_PC32)
          || gsym == NULL
          || strcmp(gsym->name(), "___tls_get_addr") != 0)
        gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
@@ -1648,7 +1706,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
       break;
 
     case elfcpp::R_386_32:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+                                   output_section))
         Relocate_functions<32, false>::rel32(view, object, psymval);
       break;
 
@@ -1657,13 +1716,14 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, true))
+        if (should_apply_static_reloc(gsym, ref_flags, true, output_section))
           Relocate_functions<32, false>::pcrel32(view, object, psymval, address);
       }
       break;
 
     case elfcpp::R_386_16:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+                                   output_section))
         Relocate_functions<32, false>::rel16(view, object, psymval);
       break;
 
@@ -1672,13 +1732,14 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, false))
+        if (should_apply_static_reloc(gsym, ref_flags, false, output_section))
           Relocate_functions<32, false>::pcrel16(view, object, psymval, address);
       }
       break;
 
     case elfcpp::R_386_8:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false))
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
+                                   output_section))
         Relocate_functions<32, false>::rel8(view, object, psymval);
       break;
 
@@ -1687,7 +1748,8 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
         int ref_flags = Symbol::NON_PIC_REF;
         if (gsym != NULL && gsym->type() == elfcpp::STT_FUNC)
           ref_flags |= Symbol::FUNCTION_CALL;
-        if (should_apply_static_reloc(gsym, ref_flags, false))
+        if (should_apply_static_reloc(gsym, ref_flags, false,
+                                     output_section))
           Relocate_functions<32, false>::pcrel8(view, object, psymval, address);
       }
       break;
This page took 0.026175 seconds and 4 git commands to generate.