Made tests to XFAIL for arc*-*-elf*.
[deliverable/binutils-gdb.git] / bfd / elf64-s390.c
index 3887e8d016902fde9594676a75b347528879ef20..fc7a337331ed3d1eede1f200db7b4a74db0f1851 100644 (file)
@@ -25,6 +25,7 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/s390.h"
+#include <stdarg.h>
 
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
    from smaller values.  Start with zero, widen, *then* decrement.  */
@@ -337,10 +338,10 @@ elf_s390_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
        && strcasecmp (elf_howto_table[i].name, r_name) == 0)
       return &elf_howto_table[i];
 
-    if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
-      return &elf64_s390_vtinherit_howto;
-    if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
-      return &elf64_s390_vtentry_howto;
+  if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
+    return &elf64_s390_vtinherit_howto;
+  if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
+    return &elf64_s390_vtentry_howto;
 
   return NULL;
 }
@@ -492,8 +493,8 @@ elf_s390_is_local_label_name (bfd *abfd, const char *name)
 
    The GOT holds the address in the PLT to be executed.
    The loader then gets:
-   24(15) =  Pointer to the structure describing the object.
-   28(15) =  Offset in symbol table
+   48(15) =  Pointer to the structure describing the object.
+   56(15) =  Offset in symbol table
    The loader  must  then find the module where the function is
    and insert the address in the GOT.
 
@@ -664,9 +665,9 @@ struct elf_s390_link_hash_table
 
 /* Get the s390 ELF linker hash table from a link_info structure.  */
 
-#define elf_s390_hash_table(p) \
-  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
-  == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL)
+#define elf_s390_hash_table(p)                                         \
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash))      \
+   == S390_ELF_DATA ? ((struct elf_s390_link_hash_table *) ((p)->hash)) : NULL)
 
 #define ELF64 1
 #include "elf-s390-common.c"
@@ -2479,7 +2480,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                    PLT_ENTRY_SIZE;
 
                  /* Offset in GOT is PLT index plus GOT headers(3)
-                    times 4, addr & GOT addr.  */
+                    times 8, addr & GOT addr.  */
                  relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
                  if (r_type == R_390_GOTPLTENT)
                    relocation += htab->elf.sgot->output_section->vma;
@@ -3357,14 +3358,9 @@ elf_s390_relocate_section (bfd *output_bfd,
            }
 
          if (r == bfd_reloc_overflow)
-           {
-
-             if (! ((*info->callbacks->reloc_overflow)
-                    (info, (h ? &h->root : NULL), name, howto->name,
-                     (bfd_vma) 0, input_bfd, input_section,
-                     rel->r_offset)))
-               return FALSE;
-           }
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
          else
            {
              (*_bfd_error_handler)
@@ -3608,7 +3604,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
            }
        }
       else if (bfd_link_pic (info)
-         && SYMBOL_REFERENCES_LOCAL (info, h))
+              && SYMBOL_REFERENCES_LOCAL (info, h))
        {
          /* If this is a static link, or it is a -Bsymbolic link and
             the symbol is defined locally or was forced to be local
@@ -3627,7 +3623,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
       else
        {
          BFD_ASSERT((h->got.offset & 1) == 0);
-do_glob_dat:
+       do_glob_dat:
          bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgot->contents + h->got.offset);
          rela.r_info = ELF64_R_INFO (h->dynindx, R_390_GLOB_DAT);
          rela.r_addend = 0;
@@ -3749,16 +3745,17 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
              continue;
 
            case DT_PLTGOT:
-             dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
+             s = htab->elf.sgotplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_JMPREL:
-             dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
+             s = htab->elf.srelplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_PLTRELSZ:
-             s = htab->elf.srelplt->output_section;
-             dyn.d_un.d_val = s->size;
+             dyn.d_un.d_val = htab->elf.srelplt->size + htab->elf.irelplt->size;
              break;
 
            case DT_RELASZ:
@@ -3769,8 +3766,7 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
                 linker script arranges for .rela.plt to follow all
                 other relocation sections, we don't have to worry
                 about changing the DT_RELA entry.  */
-             s = htab->elf.srelplt->output_section;
-             dyn.d_un.d_val -= s->size;
+             dyn.d_un.d_val -= htab->elf.srelplt->size + htab->elf.irelplt->size;
              break;
            }
 
@@ -3785,9 +3781,10 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
                  PLT_FIRST_ENTRY_SIZE);
          /* Fixup relative address to start of GOT */
          bfd_put_32 (output_bfd,
-                     (htab->elf.sgotplt->output_section->vma +
-                      htab->elf.sgotplt->output_offset
-                      - htab->elf.splt->output_section->vma - 6)/2,
+                     (htab->elf.sgotplt->output_section->vma
+                      + htab->elf.sgotplt->output_offset
+                      - htab->elf.splt->output_section->vma
+                      - htab->elf.splt->output_offset - 6)/2,
                      htab->elf.splt->contents + 8);
        }
       if (elf_section_data (htab->elf.splt->output_section) != NULL)
@@ -3807,7 +3804,7 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
          /* One entry for shared object struct ptr.  */
          bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 8);
          /* One entry for _dl_runtime_resolve.  */
-         bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 12);
+         bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + 16);
        }
 
       elf_section_data (htab->elf.sgot->output_section)
@@ -3847,7 +3844,120 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
 
   return TRUE;
 }
+\f
+/* Support for core dump NOTE sections.  */
+
+static bfd_boolean
+elf_s390_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+  int offset;
+  size_t size;
+
+  switch (note->descsz)
+    {
+    default:
+      return FALSE;
+
+    case 336:                  /* sizeof(struct elf_prstatus) on s390x */
+      /* pr_cursig */
+      elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
+
+      /* pr_pid */
+      elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
+
+      /* pr_reg */
+      offset = 112;
+      size = 216;
+      break;
+    }
+
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         size, note->descpos + offset);
+}
 
+static bfd_boolean
+elf_s390_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->descsz)
+    {
+    default:
+      return FALSE;
+
+    case 136:                  /* sizeof(struct elf_prpsinfo) on s390x */
+      elf_tdata (abfd)->core->pid
+       = bfd_get_32 (abfd, note->descdata + 24);
+      elf_tdata (abfd)->core->program
+       = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
+      elf_tdata (abfd)->core->command
+       = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core->command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return TRUE;
+}
+
+static char *
+elf_s390_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+                         int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+      {
+       char data[136] = { 0 };
+       const char *fname, *psargs;
+
+       va_start (ap, note_type);
+       fname = va_arg (ap, const char *);
+       psargs = va_arg (ap, const char *);
+       va_end (ap);
+
+       strncpy (data + 40, fname, 16);
+       strncpy (data + 56, psargs, 80);
+       return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+                                  &data, sizeof (data));
+      }
+
+    case NT_PRSTATUS:
+      {
+       char data[336] = { 0 };
+       long pid;
+       int cursig;
+       const void *gregs;
+
+       va_start (ap, note_type);
+       pid = va_arg (ap, long);
+       cursig = va_arg (ap, int);
+       gregs = va_arg (ap, const void *);
+       va_end (ap);
+
+       bfd_put_16 (abfd, cursig, data + 12);
+       bfd_put_32 (abfd, pid, data + 32);
+       memcpy (data + 112, gregs, 216);
+       return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+                                  &data, sizeof (data));
+      }
+    }
+  /* NOTREACHED */
+}
+\f
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
@@ -3946,6 +4056,9 @@ const struct elf_size_info s390_elf64_size_info =
 #define elf_backend_relocate_section         elf_s390_relocate_section
 #define elf_backend_size_dynamic_sections     elf_s390_size_dynamic_sections
 #define elf_backend_init_index_section       _bfd_elf_init_1_index_section
+#define elf_backend_grok_prstatus            elf_s390_grok_prstatus
+#define elf_backend_grok_psinfo                      elf_s390_grok_psinfo
+#define elf_backend_write_core_note          elf_s390_write_core_note
 #define elf_backend_plt_sym_val                      elf_s390_plt_sym_val
 #define elf_backend_add_symbol_hook           elf_s390_add_symbol_hook
 #define elf_backend_sort_relocs_p             elf_s390_elf_sort_relocs_p
@@ -3953,19 +4066,4 @@ const struct elf_size_info s390_elf64_size_info =
 #define bfd_elf64_mkobject             elf_s390_mkobject
 #define elf_backend_object_p           elf_s390_object_p
 
-/* Enable ELF64 archive functions.  */
-#define bfd_elf64_archive_functions
-extern bfd_boolean bfd_elf64_archive_slurp_armap (bfd *);
-extern bfd_boolean bfd_elf64_archive_write_armap (bfd *, unsigned int, struct orl *, unsigned int, int);
-
-#define bfd_elf64_archive_slurp_extended_name_table    _bfd_archive_coff_slurp_extended_name_table
-#define bfd_elf64_archive_construct_extended_name_table _bfd_archive_coff_construct_extended_name_table
-#define bfd_elf64_archive_truncate_arname              _bfd_archive_coff_truncate_arname
-#define bfd_elf64_archive_read_ar_hdr                  _bfd_archive_coff_read_ar_hdr
-#define bfd_elf64_archive_write_ar_hdr                 _bfd_archive_coff_write_ar_hdr
-#define bfd_elf64_archive_openr_next_archived_file     _bfd_archive_coff_openr_next_archived_file
-#define bfd_elf64_archive_get_elt_at_index             _bfd_archive_coff_get_elt_at_index
-#define bfd_elf64_archive_generic_stat_arch_elt        _bfd_archive_coff_generic_stat_arch_elt
-#define bfd_elf64_archive_update_armap_timestamp       _bfd_archive_coff_update_armap_timestamp
-
 #include "elf64-target.h"
This page took 0.02698 seconds and 4 git commands to generate.