Better handking for unresolved symbols
[deliverable/binutils-gdb.git] / bfd / elf-bfd.h
index 93f265fa1475349b83409e059ea0ee8cd0ddfcbd..abbe377e491dd6bd8d8f9aa9e04902e1c300933d 100644 (file)
@@ -1682,4 +1682,60 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory
 extern bfd_boolean _sh_elf_set_mach_from_flags
   (bfd *);
 
+/* This macro is to avoid lots of duplicated code in the body
+   of xxx_relocate_section() in the various elfxx-xxxx.c files.  */
+#define RELOC_FOR_GLOBAL_SYMBOL(h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned)  \
+  do                                                                                                                   \
+    {                                                                                                                  \
+      /* It seems this can happen with erroneous or unsupported                                                                \
+        input (mixing a.out and elf in an archive, for example.)  */                                                   \
+      if (sym_hashes == NULL)                                                                                          \
+       return FALSE;                                                                                                   \
+                                                                                                                       \
+      h = sym_hashes[r_symndx - symtab_hdr->sh_info];                                                                  \
+                                                                                                                       \
+      while (h->root.type == bfd_link_hash_indirect                                                                    \
+            || h->root.type == bfd_link_hash_warning)                                                                  \
+       h = (struct elf_link_hash_entry *) h->root.u.i.link;                                                            \
+                                                                                                                       \
+      warned = FALSE;                                                                                                  \
+      unresolved_reloc = FALSE;                                                                                                \
+      relocation = 0;                                                                                                  \
+      if (h->root.type == bfd_link_hash_defined                                                                                \
+         || h->root.type == bfd_link_hash_defweak)                                                                     \
+       {                                                                                                               \
+         sec = h->root.u.def.section;                                                                                  \
+         if (sec == NULL                                                                                               \
+             || sec->output_section == NULL)                                                                           \
+           /* Set a flag that will be cleared later if we find a                                                       \
+              relocation value for this symbol.  output_section                                                        \
+              is typically NULL for symbols satisfied by a shared                                                      \
+              library.  */                                                                                             \
+           unresolved_reloc = TRUE;                                                                                    \
+         else                                                                                                          \
+           relocation = (h->root.u.def.value                                                                           \
+                         + sec->output_section->vma                                                                    \
+                         + sec->output_offset);                                                                        \
+       }                                                                                                               \
+      else if (h->root.type == bfd_link_hash_undefweak)                                                                        \
+       ;                                                                                                               \
+      else if (!info->executable                                                                                       \
+              && info->unresolved_syms_in_objects == RM_IGNORE                                                         \
+              && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)                                                          \
+       ;                                                                                                               \
+      else                                                                                                             \
+       {                                                                                                               \
+         if (! info->callbacks->undefined_symbol                                                                       \
+             (info, h->root.root.string, input_bfd,                                                                    \
+              input_section, rel->r_offset,                                                                            \
+              ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)                             \
+               || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)                             \
+               || ELF_ST_VISIBILITY (h->other))                                                                        \
+              ))                                                                                                       \
+           return FALSE;                                                                                               \
+         warned = TRUE;                                                                                                \
+       }                                                                                                               \
+    }                                                                                                                  \
+  while (0)
+
 #endif /* _LIBELF_H_ */
This page took 0.02569 seconds and 4 git commands to generate.