* merge.h (Output_merge_string::Merged_string): Remove object, shndx,
[binutils-gdb.git] / gold / target-reloc.h
index 06597e2124fcab4154a1be8ea35dbf67a682fdd5..23866e373d5690f8f77dc08f167f5376a331df67 100644 (file)
@@ -83,7 +83,8 @@ scan_relocs(
          shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
          if (is_ordinary
              && shndx != elfcpp::SHN_UNDEF
-             && !object->is_section_included(shndx))
+             && !object->is_section_included(shndx)
+              && !symtab->is_section_folded(object, shndx))
            {
              // RELOC is a relocation against a local symbol in a
              // section we are discarding.  We can ignore this
@@ -102,7 +103,6 @@ scan_relocs(
 
              continue;
            }
-
          scan.local(symtab, layout, target, object, data_shndx,
                     output_section, reloc, r_type, lsym);
        }
@@ -144,6 +144,31 @@ get_comdat_behavior(const char* name)
   return CB_WARNING;
 }
 
+// Give an error for a symbol with non-default visibility which is not
+// defined locally.
+
+inline void
+visibility_error(const Symbol* sym)
+{
+  const char* v;
+  switch (sym->visibility())
+    {
+    case elfcpp::STV_INTERNAL:
+      v = _("internal");
+      break;
+    case elfcpp::STV_HIDDEN:
+      v = _("hidden");
+      break;
+    case elfcpp::STV_PROTECTED:
+      v = _("protected");
+      break;
+    default:
+      gold_unreachable();
+    }
+  gold_error(_("%s symbol '%s' is not defined locally"),
+            v, sym->name());
+}
+
 // This function implements the generic part of relocation processing.
 // The template parameter Relocate must be a class type which provides
 // a single function, relocate(), which implements the machine
@@ -254,7 +279,7 @@ relocate_section(
            }
 
          sym = static_cast<const Sized_symbol<size>*>(gsym);
-         if (sym->has_symtab_index())
+         if (sym->has_symtab_index() && sym->symtab_index() != -1U)
            symval.set_output_symtab_index(sym->symtab_index());
          else
            symval.set_no_output_symtab_entry();
@@ -316,13 +341,17 @@ relocate_section(
        }
 
       if (sym != NULL
-         && sym->is_undefined()
+         && (sym->is_undefined() || sym->is_placeholder())
          && sym->binding() != elfcpp::STB_WEAK
          && !is_defined_in_discarded_section
           && !target->is_defined_by_abi(sym)
          && (!parameters->options().shared()       // -shared
               || parameters->options().defs()))     // -z defs
        gold_undefined_symbol_at_location(sym, relinfo, i, offset);
+      else if (sym != NULL
+              && sym->visibility() != elfcpp::STV_DEFAULT
+              && (sym->is_undefined() || sym->is_from_dynobj()))
+       visibility_error(sym);
 
       if (sym != NULL && sym->has_warning())
        relinfo->symtab->issue_warning(sym, relinfo, i, offset);
@@ -462,6 +491,9 @@ scan_relocatable_relocs(
                  if (strategy != Relocatable_relocs::RELOC_DISCARD)
                     object->output_section(shndx)->set_needs_symtab_index();
                }
+
+             if (strategy == Relocatable_relocs::RELOC_COPY)
+               object->set_must_have_output_symtab_entry(r_sym);
            }
        }
 
@@ -483,7 +515,7 @@ relocate_for_relocatable(
     const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
-    section_size_type,
+    section_size_type view_size,
     unsigned char* reloc_view,
     section_size_type reloc_view_size)
 {
@@ -505,6 +537,19 @@ relocate_for_relocatable(
       if (strategy == Relocatable_relocs::RELOC_DISCARD)
        continue;
 
+      if (strategy == Relocatable_relocs::RELOC_SPECIAL)
+       {
+         // Target wants to handle this relocation.
+         Sized_target<size, big_endian>* target =
+           parameters->sized_target<size, big_endian>();
+         target->relocate_special_relocatable(relinfo, sh_type, prelocs,
+                                              i, output_section,
+                                              offset_in_output_section,
+                                              view, view_address,
+                                              view_size, pwrite);
+         pwrite += reloc_size;
+         continue;
+       }
       Reltype reloc(prelocs);
       Reltype_write reloc_write(pwrite);