* gold.cc (gold_exit): Call plugin cleanup handlers on exit.
[binutils-gdb.git] / gold / target-reloc.h
index 6683ddd05fd9294cda2e6be50a00f5a9cb84804c..b9ecf9fd6dab2907089ae614152d94b9afc0cc55 100644 (file)
@@ -283,6 +283,7 @@ relocate_section(
       if (sym != NULL
          && sym->is_undefined()
          && sym->binding() != elfcpp::STB_WEAK
+          && !target->is_defined_by_abi(sym)
          && (!parameters->options().shared()       // -shared
               || parameters->options().defs()))     // -z defs
        gold_undefined_symbol(sym, relinfo, i, offset);
@@ -307,8 +308,14 @@ class Default_scan_relocatable_relocs
   // Return the strategy to use for a local symbol which is not a
   // section symbol, given the relocation type.
   inline Relocatable_relocs::Reloc_strategy
-  local_non_section_strategy(unsigned int, Relobj*)
-  { return Relocatable_relocs::RELOC_COPY; }
+  local_non_section_strategy(unsigned int r_type, Relobj*, unsigned int r_sym)
+  {
+    // We assume that relocation type 0 is NONE.  Targets which are
+    // different must override.
+    if (r_type == 0 && r_sym == 0)
+      return Relocatable_relocs::RELOC_DISCARD;
+    return Relocatable_relocs::RELOC_COPY;
+  }
 
   // Return the strategy to use for a local symbol which is a section
   // symbol, given the relocation type.
@@ -412,7 +419,8 @@ scan_relocatable_relocs(
                  strategy = Relocatable_relocs::RELOC_DISCARD;
                }
              else if (lsym.get_st_type() != elfcpp::STT_SECTION)
-               strategy = scan.local_non_section_strategy(r_type, object);
+               strategy = scan.local_non_section_strategy(r_type, object,
+                                                          r_sym);
              else
                {
                  strategy = scan.local_section_strategy(r_type, object);
@@ -449,6 +457,7 @@ relocate_for_relocatable(
   typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write
     Reltype_write;
   const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
+  const Address invalid_address = static_cast<Address>(0) - 1;
 
   Sized_relobj<size, big_endian>* const object = relinfo->object;
   const unsigned int local_count = object->local_symbol_count();
@@ -523,7 +532,7 @@ relocate_for_relocatable(
 
       Address offset = reloc.get_r_offset();
       Address new_offset;
-      if (offset_in_output_section != -1U)
+      if (offset_in_output_section != invalid_address)
        new_offset = offset + offset_in_output_section;
       else
        {
@@ -542,7 +551,7 @@ relocate_for_relocatable(
       if (!parameters->options().relocatable())
        {
          new_offset += view_address;
-         if (offset_in_output_section != -1U)
+         if (offset_in_output_section != invalid_address)
            new_offset -= offset_in_output_section;
        }