Jakub Jelinek <jj@ultra.linux.cz>
[deliverable/binutils-gdb.git] / bfd / elf32-fr30.c
index 2ee500d9c92ca29b4191f17b2a91e1e7e6ae3737..7c8725f556228e514860d44e37307e952e1c3000 100644 (file)
@@ -330,7 +330,7 @@ fr30_elf_i32_reloc (abfd, reloc_entry, symbol, data,
 
 struct fr30_reloc_map
 {
-  unsigned int bfd_reloc_val;
+  bfd_reloc_code_real_type bfd_reloc_val;
   unsigned int fr30_reloc_val;
 };
 
@@ -731,6 +731,64 @@ fr30_elf_gc_sweep_hook (abfd, info, sec, relocs)
 {
   return true;
 }
+
+/* Look through the relocs for a section during the first phase.
+   Since we don't do .gots or .plts, we just need to consider the
+   virtual table relocs for gc.  */
+static boolean
+fr30_elf_check_relocs (abfd, info, sec, relocs)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     asection *sec;
+     const Elf_Internal_Rela *relocs;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  const Elf_Internal_Rela *rel;
+  const Elf_Internal_Rela *rel_end;
+  if (info->relocateable)
+    return true;
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
+  if (!elf_bad_symtab (abfd))
+    sym_hashes_end -= symtab_hdr->sh_info;
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      struct elf_link_hash_entry *h;
+      unsigned long r_symndx;
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+        h = NULL;
+      else
+        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+      switch (ELF32_R_TYPE (rel->r_info))
+        {
+        /* This relocation describes the C++ object vtable hierarchy.
+           Reconstruct it for later use during GC.  */
+        case R_FR30_GNU_VTINHERIT:
+          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+            return false;
+          break;
+        /* This relocation describes which C++ vtable entries are actually
+           used.  Record for later use during GC.  */
+        case R_FR30_GNU_VTENTRY:
+          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+            return false;
+          break;
+        }
+    }
+  return true;
+}
 \f
 #define ELF_ARCH               bfd_arch_fr30
 #define ELF_MACHINE_CODE       EM_CYGNUS_FR30
@@ -744,6 +802,7 @@ fr30_elf_gc_sweep_hook (abfd, info, sec, relocs)
 #define elf_backend_relocate_section           fr30_elf_relocate_section
 #define elf_backend_gc_mark_hook               fr30_elf_gc_mark_hook
 #define elf_backend_gc_sweep_hook              fr30_elf_gc_sweep_hook
+#define elf_backend_check_relocs                fr30_elf_check_relocs
 
 #define elf_backend_can_gc_sections            1
 
This page took 0.023763 seconds and 4 git commands to generate.