* elflink.c (_bfd_elf_merge_symbol): Don't discard TLS symbols here.
[binutils-gdb.git] / bfd / elf.c
index c69129dae9d620ca777660da1ef96ea087b0042e..05d492db080f3a61ed015cae683e3e6532570a73 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,9 +1,6 @@
 /* ELF executable support for BFD.
 
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
-   2013
-   Free Software Foundation, Inc.
+   Copyright 1993-2013 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -246,7 +243,14 @@ bfd_elf_allocate_object (bfd *abfd,
     return FALSE;
 
   elf_object_id (abfd) = object_id;
-  elf_program_header_size (abfd) = (bfd_size_type) -1;
+  if (abfd->direction != read_direction)
+    {
+      struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
+      if (o == NULL)
+       return FALSE;
+      elf_tdata (abfd)->o = o;
+      elf_program_header_size (abfd) = (bfd_size_type) -1;
+    }
   return TRUE;
 }
 
@@ -263,7 +267,10 @@ bfd_boolean
 bfd_elf_mkcorefile (bfd *abfd)
 {
   /* I think this can be done just like an object file.  */
-  return abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd);
+  if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
+    return FALSE;
+  elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
+  return elf_tdata (abfd)->core != NULL;
 }
 
 static char *
@@ -2514,7 +2521,7 @@ _bfd_elf_single_rel_hdr (asection *sec)
    USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
    relocations.  */
 
-bfd_boolean
+static bfd_boolean
 _bfd_elf_init_reloc_shdr (bfd *abfd,
                          struct bfd_elf_section_reloc_data *reldata,
                          asection *asect,
@@ -5330,9 +5337,8 @@ _bfd_elf_write_object_contents (bfd *abfd)
     return FALSE;
 
   /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
-  if (t->build_id != NULL
-      && t->build_id->u.o.zero == 0)
-    return (*t->build_id->u.o.after_write_object_contents) (abfd);
+  if (t->o->build_id.after_write_object_contents != NULL)
+    return (*t->o->build_id.after_write_object_contents) (abfd);
 
   return TRUE;
 }
@@ -7871,7 +7877,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd)
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
     {
-      if (elf_shstrtab (abfd) != NULL)
+      if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
        _bfd_elf_strtab_free (elf_shstrtab (abfd));
       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
     }
@@ -7913,9 +7919,9 @@ elfcore_make_pid (bfd *abfd)
 {
   int pid;
 
-  pid = elf_tdata (abfd)->core_lwpid;
+  pid = elf_tdata (abfd)->core->lwpid;
   if (pid == 0)
-    pid = elf_tdata (abfd)->core_pid;
+    pid = elf_tdata (abfd)->core->pid;
 
   return pid;
 }
@@ -8005,10 +8011,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       /* Do not overwrite the core signal if it
         has already been set by another thread.  */
-      if (elf_tdata (abfd)->core_signal == 0)
-       elf_tdata (abfd)->core_signal = prstat.pr_cursig;
-      if (elf_tdata (abfd)->core_pid == 0)
-       elf_tdata (abfd)->core_pid = prstat.pr_pid;
+      if (elf_tdata (abfd)->core->signal == 0)
+       elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+      if (elf_tdata (abfd)->core->pid == 0)
+       elf_tdata (abfd)->core->pid = prstat.pr_pid;
 
       /* pr_who exists on:
         solaris 2.5+
@@ -8017,9 +8023,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
         linux 2.[01]
         */
 #if defined (HAVE_PRSTATUS_T_PR_WHO)
-      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
 #else
-      elf_tdata (abfd)->core_lwpid = prstat.pr_pid;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
 #endif
     }
 #if defined (HAVE_PRSTATUS32_T)
@@ -8034,10 +8040,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       /* Do not overwrite the core signal if it
         has already been set by another thread.  */
-      if (elf_tdata (abfd)->core_signal == 0)
-       elf_tdata (abfd)->core_signal = prstat.pr_cursig;
-      if (elf_tdata (abfd)->core_pid == 0)
-       elf_tdata (abfd)->core_pid = prstat.pr_pid;
+      if (elf_tdata (abfd)->core->signal == 0)
+       elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+      if (elf_tdata (abfd)->core->pid == 0)
+       elf_tdata (abfd)->core->pid = prstat.pr_pid;
 
       /* pr_who exists on:
         solaris 2.5+
@@ -8046,9 +8052,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
         linux 2.[01]
         */
 #if defined (HAVE_PRSTATUS32_T_PR_WHO)
-      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
 #else
-      elf_tdata (abfd)->core_lwpid = prstat.pr_pid;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
 #endif
     }
 #endif /* HAVE_PRSTATUS32_T */
@@ -8165,6 +8171,12 @@ elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
 }
 
+static bfd_boolean
+elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
+}
+
 static bfd_boolean
 elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
 {
@@ -8240,13 +8252,13 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
 #if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
-      elf_tdata (abfd)->core_pid = psinfo.pr_pid;
+      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
 #endif
-      elf_tdata (abfd)->core_program
+      elf_tdata (abfd)->core->program
        = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
                                sizeof (psinfo.pr_fname));
 
-      elf_tdata (abfd)->core_command
+      elf_tdata (abfd)->core->command
        = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
                                sizeof (psinfo.pr_psargs));
     }
@@ -8259,13 +8271,13 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
 #if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
-      elf_tdata (abfd)->core_pid = psinfo.pr_pid;
+      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
 #endif
-      elf_tdata (abfd)->core_program
+      elf_tdata (abfd)->core->program
        = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
                                sizeof (psinfo.pr_fname));
 
-      elf_tdata (abfd)->core_command
+      elf_tdata (abfd)->core->command
        = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
                                sizeof (psinfo.pr_psargs));
     }
@@ -8283,7 +8295,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
      implementations, so strip it off if it exists.  */
 
   {
-    char *command = elf_tdata (abfd)->core_command;
+    char *command = elf_tdata (abfd)->core->command;
     int n = strlen (command);
 
     if (0 < n && command[n - 1] == ' ')
@@ -8308,7 +8320,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&pstat, note->descdata, sizeof (pstat));
 
-      elf_tdata (abfd)->core_pid = pstat.pr_pid;
+      elf_tdata (abfd)->core->pid = pstat.pr_pid;
     }
 #if defined (HAVE_PSTATUS32_T)
   else if (note->descsz == sizeof (pstatus32_t))
@@ -8318,7 +8330,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&pstat, note->descdata, sizeof (pstat));
 
-      elf_tdata (abfd)->core_pid = pstat.pr_pid;
+      elf_tdata (abfd)->core->pid = pstat.pr_pid;
     }
 #endif
   /* Could grab some more details from the "representative"
@@ -8348,11 +8360,11 @@ elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
 
   memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
 
-  elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
+  elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
   /* Do not overwrite the core signal if it has already been set by
      another thread.  */
-  if (elf_tdata (abfd)->core_signal == 0)
-    elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
+  if (elf_tdata (abfd)->core->signal == 0)
+    elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
 
   /* Make a ".reg/999" section.  */
 
@@ -8435,11 +8447,11 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
   switch (type)
     {
     case 1 /* NOTE_INFO_PROCESS */:
-      /* FIXME: need to add ->core_command.  */
+      /* FIXME: need to add ->core->command.  */
       /* process_info.pid */
-      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 8);
+      elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8);
       /* process_info.signal */
-      elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 12);
+      elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12);
       break;
 
     case 2 /* NOTE_INFO_THREAD */:
@@ -8622,6 +8634,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       else
         return TRUE;
 
+    case NT_S390_TDB:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_tdb (abfd, note);
+      else
+        return TRUE;
+
     case NT_ARM_VFP:
       if (note->namesz == 6
          && strcmp (note->namedata, "LINUX") == 0)
@@ -8694,12 +8713,12 @@ elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
     return FALSE;
 
   t = elf_tdata (abfd);
-  t->build_id = bfd_alloc (abfd, sizeof (t->build_id->u.i) - 1 + note->descsz);
+  t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
   if (t->build_id == NULL)
     return FALSE;
 
-  t->build_id->u.i.size = note->descsz;
-  memcpy (t->build_id->u.i.data, note->descdata, note->descsz);
+  t->build_id->size = note->descsz;
+  memcpy (t->build_id->data, note->descdata, note->descsz);
 
   return TRUE;
 }
@@ -8764,15 +8783,15 @@ static bfd_boolean
 elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   /* Signal number at offset 0x08. */
-  elf_tdata (abfd)->core_signal
+  elf_tdata (abfd)->core->signal
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
 
   /* Process ID at offset 0x50. */
-  elf_tdata (abfd)->core_pid
+  elf_tdata (abfd)->core->pid
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
 
   /* Command name at 0x7c (max 32 bytes, including nul). */
-  elf_tdata (abfd)->core_command
+  elf_tdata (abfd)->core->command
     = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
 
   return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
@@ -8785,7 +8804,7 @@ elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
   int lwp;
 
   if (elfcore_netbsd_get_lwpid (note, &lwp))
-    elf_tdata (abfd)->core_lwpid = lwp;
+    elf_tdata (abfd)->core->lwpid = lwp;
 
   if (note->type == NT_NETBSDCORE_PROCINFO)
     {
@@ -8848,15 +8867,15 @@ static bfd_boolean
 elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   /* Signal number at offset 0x08. */
-  elf_tdata (abfd)->core_signal
+  elf_tdata (abfd)->core->signal
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
 
   /* Process ID at offset 0x20. */
-  elf_tdata (abfd)->core_pid
+  elf_tdata (abfd)->core->pid
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
 
   /* Command name at 0x48 (max 32 bytes, including nul). */
-  elf_tdata (abfd)->core_command
+  elf_tdata (abfd)->core->command
     = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
 
   return TRUE;
@@ -8919,7 +8938,7 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
   unsigned flags;
 
   /* nto_procfs_status 'pid' field is at offset 0.  */
-  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
+  elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
 
   /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
   *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
@@ -8930,15 +8949,15 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
   /* nto_procfs_status 'what' field is at offset 14.  */
   if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
     {
-      elf_tdata (abfd)->core_signal = sig;
-      elf_tdata (abfd)->core_lwpid = *tid;
+      elf_tdata (abfd)->core->signal = sig;
+      elf_tdata (abfd)->core->lwpid = *tid;
     }
 
   /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
      do not come from signals so we make sure we set the current
      thread just in case.  */
   if (flags & 0x00000080)
-    elf_tdata (abfd)->core_lwpid = *tid;
+    elf_tdata (abfd)->core->lwpid = *tid;
 
   /* Make a ".qnx_core_status/%d" section.  */
   sprintf (buf, ".qnx_core_status/%ld", *tid);
@@ -8986,7 +9005,7 @@ elfcore_grok_nto_regs (bfd *abfd,
   sect->alignment_power = 2;
 
   /* This is the current thread.  */
-  if (elf_tdata (abfd)->core_lwpid == tid)
+  if (elf_tdata (abfd)->core->lwpid == tid)
     return elfcore_maybe_make_sect (abfd, base, sect);
 
   return TRUE;
@@ -9475,6 +9494,18 @@ elfcore_write_s390_system_call (bfd *abfd,
                             s390_system_call, size);
 }
 
+char *
+elfcore_write_s390_tdb (bfd *abfd,
+                       char *buf,
+                       int *bufsiz,
+                       const void *s390_tdb,
+                       int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_TDB, s390_tdb, size);
+}
+
 char *
 elfcore_write_arm_vfp (bfd *abfd,
                       char *buf,
@@ -9557,6 +9588,8 @@ elfcore_write_register_note (bfd *abfd,
     return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-s390-system-call") == 0)
     return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-tdb") == 0)
+    return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-arm-vfp") == 0)
     return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-aarch-tls") == 0)