oops - fix date ion ChangeLog entry
[deliverable/binutils-gdb.git] / bfd / elf32-m68k.c
index 709057b15315e138d7dd18c5f544d6b907a53eaa..d53cfdf45a35255c06cc7e4168ab6f644ade97ed 100644 (file)
@@ -224,9 +224,9 @@ static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
 /* Procedure linkage table entries for the cpu32 */
 static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
 {
-  0x20, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a0 */
+  0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
   0, 0, 0, 0,             /* replaced with offset to .got + 4.  */
-  0x4e, 0xd0,             /* jmp %a0@ */
+  0x4e, 0xd1,             /* jmp %a1@ */
   0, 0, 0, 0,             /* replace with offset to .got +8. */
   0, 0, 0, 0,             /* pad out to 24 bytes.  */
   0, 0, 0, 0,             /* pad out to 24 bytes.  */
@@ -235,9 +235,9 @@ static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
 
 static const bfd_byte elf_cpu32_plt_entry[PLT_CPU32_ENTRY_SIZE] =
 {
-  0x20, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a0 */
+  0x22, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a1 */
   0, 0, 0, 0,              /* replaced with offset to symbol's .got entry.  */
-  0x4e, 0xd0,              /* jmp %a0@ */
+  0x4e, 0xd1,              /* jmp %a1@ */
   0x2f, 0x3c,              /* move.l #offset,-(%sp) */
   0, 0, 0, 0,              /* replaced with offset into relocation table.  */
   0x60, 0xff,              /* bra.l .plt */
@@ -855,11 +855,11 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
   dynobj = elf_hash_table (info)->dynobj;
-  if (dynobj)
-    {
-      sgot = bfd_get_section_by_name (dynobj, ".got");
-      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
-    }
+  if (dynobj == NULL)
+    return true;
+
+  sgot = bfd_get_section_by_name (dynobj, ".got");
+  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
@@ -887,7 +887,7 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
                    }
                }
            }
-         else
+         else if (local_got_refcounts != NULL)
            {
              if (local_got_refcounts[r_symndx] > 0)
                {
@@ -1262,12 +1262,17 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
+        Unused entries should be reclaimed before the section's contents
+        are written out, but at the moment this does not happen.  Thus in
+        order to prevent writing out garbage, we initialise the section's
+        contents to zero.  */
+      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
       if (s->contents == NULL && s->_raw_size != 0)
        return false;
     }
@@ -1307,6 +1312,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
        {
          if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
            return false;
+         info->flags |= DF_TEXTREL;
        }
     }
 
@@ -1479,13 +1485,17 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
-         else if (info->shared && !info->symbolic && !info->no_undefined)
+         else if (info->shared && !info->symbolic
+                  && !info->no_undefined
+                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
            relocation = 0;
          else
            {
              if (!(info->callbacks->undefined_symbol
                    (info, h->root.root.string, input_bfd,
-                    input_section, rel->r_offset)))
+                    input_section, rel->r_offset,
+                    (!info->shared || info->no_undefined
+                     || ELF_ST_VISIBILITY (h->other)))))
                return false;
              relocation = 0;
            }
@@ -2169,6 +2179,144 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
   return true;
 }
 
+/* Given a .data section and a .emreloc in-memory section, store
+   relocation information into the .emreloc section which can be
+   used at runtime to relocate the section.  This is called by the
+   linker when the --embedded-relocs switch is used.  This is called
+   after the add_symbols entry point has been called for all the
+   objects, and before the final_link entry point is called.  */
+
+boolean
+bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     asection *datasec;
+     asection *relsec;
+     char **errmsg;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf32_External_Sym *extsyms;
+  Elf32_External_Sym *free_extsyms = NULL;
+  Elf_Internal_Rela *internal_relocs;
+  Elf_Internal_Rela *free_relocs = NULL;
+  Elf_Internal_Rela *irel, *irelend;
+  bfd_byte *p;
+
+  BFD_ASSERT (! info->relocateable);
+
+  *errmsg = NULL;
+
+  if (datasec->reloc_count == 0)
+    return true;
+
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  /* Read this BFD's symbols if we haven't done so already, or get the cached
+     copy if it exists.  */
+  if (symtab_hdr->contents != NULL)
+    extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+  else
+    {
+      /* Go get them off disk.  */
+      if (info->keep_memory)
+       extsyms = ((Elf32_External_Sym *)
+                  bfd_alloc (abfd, symtab_hdr->sh_size));
+      else
+       extsyms = ((Elf32_External_Sym *)
+                  bfd_malloc (symtab_hdr->sh_size));
+      if (extsyms == NULL)
+       goto error_return;
+      if (! info->keep_memory)
+       free_extsyms = extsyms;
+      if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+         || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+             != symtab_hdr->sh_size))
+       goto error_return;
+      if (info->keep_memory)
+       symtab_hdr->contents = extsyms;
+    }
+
+  /* Get a copy of the native relocations.  */
+  internal_relocs = (_bfd_elf32_link_read_relocs
+                    (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                     info->keep_memory));
+  if (internal_relocs == NULL)
+    goto error_return;
+  if (! info->keep_memory)
+    free_relocs = internal_relocs;
+
+  relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12);
+  if (relsec->contents == NULL)
+    goto error_return;
+
+  p = relsec->contents;
+
+  irelend = internal_relocs + datasec->reloc_count;
+  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
+    {
+      asection *targetsec;
+
+      /* We are going to write a four byte longword into the runtime
+       reloc section.  The longword will be the address in the data
+       section which must be relocated.  It is followed by the name
+       of the target section NUL-padded or truncated to 8
+       characters.  */
+
+      /* We can only relocate absolute longword relocs at run time.  */
+      if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
+       {
+         *errmsg = _("unsupported reloc type");
+         bfd_set_error (bfd_error_bad_value);
+         goto error_return;
+       }
+
+      /* Get the target section referred to by the reloc.  */
+      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+       {
+         Elf_Internal_Sym isym;
+
+         /* A local symbol.  */
+         bfd_elf32_swap_symbol_in (abfd,
+                                   extsyms + ELF32_R_SYM (irel->r_info),
+                                   &isym);
+
+         targetsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+       }
+      else
+       {
+         unsigned long indx;
+         struct elf_link_hash_entry *h;
+
+         /* An external symbol.  */
+         indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+         h = elf_sym_hashes (abfd)[indx];
+         BFD_ASSERT (h != NULL);
+         if (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+           targetsec = h->root.u.def.section;
+         else
+           targetsec = NULL;
+       }
+
+      bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+      memset (p + 4, 0, 8);
+      if (targetsec != NULL)
+       strncpy (p + 4, targetsec->output_section->name, 8);
+    }
+  
+  if (free_extsyms != NULL)
+    free (free_extsyms);
+  if (free_relocs != NULL)
+    free (free_relocs);
+  return true;
+
+error_return:
+  if (free_extsyms != NULL)
+    free (free_extsyms);
+  if (free_relocs != NULL)
+    free (free_relocs);
+  return false;
+}
+
 #define TARGET_BIG_SYM                 bfd_elf32_m68k_vec
 #define TARGET_BIG_NAME                        "elf32-m68k"
 #define ELF_MACHINE_CODE               EM_68K
This page took 0.028618 seconds and 4 git commands to generate.