Add global parameters.
[deliverable/binutils-gdb.git] / gold / target-reloc.h
index ebaa8276cf05e5d5737472fde449e8c34ad8be3a..1e9ecd03dcff062292f9be981cbae53a6b9ec530 100644 (file)
@@ -6,30 +6,11 @@
 #include "elfcpp.h"
 #include "object.h"
 #include "symtab.h"
+#include "reloc-types.h"
 
 namespace gold
 {
 
-// Pick the ELF relocation accessor class and the size based on
-// SH_TYPE, which is either SHT_REL or SHT_RELA.
-
-template<int sh_type, int size, bool big_endian>
-struct Reloc_types;
-
-template<int size, bool big_endian>
-struct Reloc_types<elfcpp::SHT_REL, size, big_endian>
-{
-  typedef typename elfcpp::Rel<size, big_endian> Reloc;
-  static const int reloc_size = elfcpp::Elf_sizes<size>::rel_size;
-};
-
-template<int size, bool big_endian>
-struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
-{
-  typedef typename elfcpp::Rela<size, big_endian> Reloc;
-  static const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
-};
-
 // This function implements the generic part of reloc scanning.  This
 // is an inline function which takes a class whose operator()
 // implements the machine specific part of scanning.  We do it this
@@ -44,7 +25,8 @@ scan_relocs(
     Symbol_table* symtab,
     Layout* layout,
     Target_type* target,
-    Sized_object<size, big_endian>* object,
+    Sized_relobj<size, big_endian>* object,
+    unsigned int data_shndx,
     const unsigned char* prelocs,
     size_t reloc_count,
     size_t local_count,
@@ -66,7 +48,7 @@ scan_relocs(
 
       if (r_sym < local_count)
        {
-         assert(plocal_syms != NULL);
+         gold_assert(plocal_syms != NULL);
          typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
                                                      + r_sym * sym_size);
          const unsigned int shndx = lsym.get_st_shndx();
@@ -92,24 +74,24 @@ scan_relocs(
              continue;
            }
 
-         scan.local(options, symtab, layout, target, object, reloc, r_type,
-                    lsym);
+         scan.local(options, symtab, layout, target, object, data_shndx,
+                    reloc, r_type, lsym);
        }
       else
        {
          Symbol* gsym = global_syms[r_sym - local_count];
-         assert(gsym != NULL);
+         gold_assert(gsym != NULL);
          if (gsym->is_forwarder())
            gsym = symtab->resolve_forwards(gsym);
 
-         scan.global(options, symtab, layout, target, object, reloc, r_type,
-                     gsym);
+         scan.global(options, symtab, layout, target, object, data_shndx,
+                     reloc, r_type, gsym);
        }
     }
 }
 
 // This function implements the generic part of relocation processing.
-// This is an inline function which take a class whose operator()
+// This is an inline function which take a class whose relocate()
 // implements the machine specific part of relocation.  We do it this
 // way to avoid making a function call for each relocation, and to
 // avoid repeating the generic relocation handling code for each
@@ -140,8 +122,9 @@ relocate_section(
   Relocate relocate;
 
   unsigned int local_count = relinfo->local_symbol_count;
-  typename elfcpp::Elf_types<size>::Elf_Addr *local_values = relinfo->values;
-  Symbol** global_syms = relinfo->symbols;
+  const typename Sized_relobj<size, big_endian>::Local_values* local_values =
+    relinfo->local_values;
+  const Symbol* const * global_syms = relinfo->symbols;
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
@@ -153,26 +136,32 @@ relocate_section(
       unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
       unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
 
-      Sized_symbol<size>* sym;
-      typename elfcpp::Elf_types<size>::Elf_Addr value;
+      const Sized_symbol<size>* sym;
 
+      Symbol_value<size> symval;
+      const Symbol_value<size> *psymval;
       if (r_sym < local_count)
        {
          sym = NULL;
-         value = local_values[r_sym];
+         psymval = &(*local_values)[r_sym];
        }
       else
        {
-         Symbol* gsym = global_syms[r_sym - local_count];
-         assert(gsym != NULL);
+         const Symbol* gsym = global_syms[r_sym - local_count];
+         gold_assert(gsym != NULL);
          if (gsym->is_forwarder())
            gsym = relinfo->symtab->resolve_forwards(gsym);
 
-         sym = static_cast<Sized_symbol<size>*>(gsym);
-         value = sym->value();
+         sym = static_cast<const Sized_symbol<size>*>(gsym);
+         if (sym->has_symtab_index())
+           symval.set_output_symtab_index(sym->symtab_index());
+         else
+           symval.set_no_output_symtab_entry();
+         symval.set_output_value(sym->value());
+         psymval = &symval;
        }
 
-      if (!relocate.relocate(relinfo, target, i, reloc, r_type, sym, value,
+      if (!relocate.relocate(relinfo, target, i, reloc, r_type, sym, psymval,
                             view + offset, view_address + offset, view_size))
        continue;
 
@@ -193,6 +182,9 @@ relocate_section(
                  sym->name());
          // gold_exit(false);
        }
+
+      if (sym != NULL && sym->has_warning())
+       relinfo->symtab->issue_warning(sym, relinfo->location(i, offset));
     }
 }
 
This page took 0.038617 seconds and 4 git commands to generate.