Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf.c
index f6923b48a5b3954ff503e3c1539229e9d348003b..13d4272c93620442d15d24fd612af16179a32510 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,6 @@
 /* ELF executable support for BFD.
 
-   Copyright (C) 1993-2014 Free Software Foundation, Inc.
+   Copyright (C) 1993-2015 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2758,6 +2758,15 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   this_hdr->sh_offset = 0;
   this_hdr->sh_size = asect->size;
   this_hdr->sh_link = 0;
+  /* PR 17512: file: 0eb809fe, 8b0535ee.  */
+  if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
+    {
+      (*_bfd_error_handler)
+       (_("%B: error: Alignment power %d of section `%A' is too big"),
+        abfd, asect, asect->alignment_power);
+      arg->failed = TRUE;
+      return;
+    }
   this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
   /* The sh_entsize and sh_info fields may have been set already by
      copy_private_section_data.  */
@@ -4011,6 +4020,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       last_size = 0;
       phdr_index = 0;
       maxpagesize = bed->maxpagesize;
+      /* PR 17512: file: c8455299.
+        Avoid divide-by-zero errors later on.
+        FIXME: Should we abort if the maxpagesize is zero ?  */
+      if (maxpagesize == 0)
+       maxpagesize = 1;
       writable = FALSE;
       dynsec = bfd_get_section_by_name (abfd, ".dynamic");
       if (dynsec != NULL
@@ -5206,7 +5220,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
              && (p->p_type != PT_NOTE
                  || bfd_get_format (abfd) != bfd_core))
            {
-             BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+             if (m->includes_filehdr || m->includes_phdrs)
+               {
+                 /* PR 17512: file: 2195325e.  */ 
+                 (*_bfd_error_handler)
+                   (_("%B: warning: non-load segment includes file header and/or program header"),
+                    abfd);
+                 return FALSE;
+               }
 
              p->p_filesz = 0;
              p->p_offset = m->sections[0]->filepos;
@@ -5947,8 +5968,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
             something.  They are allowed by the ELF spec however, so only
             a warning is produced.  */
          if (segment->p_type == PT_LOAD)
-           (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
-                                    " detected, is this intentional ?\n"),
+           (*_bfd_error_handler) (_("\
+%B: warning: Empty loadable segment detected, is this intentional ?"),
                                   ibfd);
 
          map->count = 0;
@@ -6561,7 +6582,15 @@ rewrite:
           i++, segment++)
        if (segment->p_type == PT_LOAD
            && maxpagesize < segment->p_align)
-         maxpagesize = segment->p_align;
+         {
+           /* PR 17512: file: f17299af.  */
+           if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
+             (*_bfd_error_handler) (_("\
+%B: warning: segment alignment of 0x%llx is too large"),
+                                    ibfd, (long long) segment->p_align);
+           else
+             maxpagesize = segment->p_align;
+         }
 
       if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
        bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
@@ -7702,109 +7731,6 @@ _bfd_elf_set_arch_mach (bfd *abfd,
   return bfd_default_set_arch_mach (abfd, arch, machine);
 }
 
-/* Find the function to a particular section and offset,
-   for error reporting.  */
-
-static bfd_boolean
-elf_find_function (bfd *abfd,
-                  asymbol **symbols,
-                  asection *section,
-                  bfd_vma offset,
-                  const char **filename_ptr,
-                  const char **functionname_ptr)
-{
-  struct elf_find_function_cache
-  {
-    asection *last_section;
-    asymbol *func;
-    const char *filename;
-    bfd_size_type func_size;
-  } *cache;
-
-  if (symbols == NULL)
-    return FALSE;
-
-  cache = elf_tdata (abfd)->elf_find_function_cache;
-  if (cache == NULL)
-    {
-      cache = bfd_zalloc (abfd, sizeof (*cache));
-      elf_tdata (abfd)->elf_find_function_cache = cache;
-      if (cache == NULL)
-       return FALSE;
-    }
-  if (cache->last_section != section
-      || cache->func == NULL
-      || offset < cache->func->value
-      || offset >= cache->func->value + cache->func_size)
-    {
-      asymbol *file;
-      bfd_vma low_func;
-      asymbol **p;
-      /* ??? Given multiple file symbols, it is impossible to reliably
-        choose the right file name for global symbols.  File symbols are
-        local symbols, and thus all file symbols must sort before any
-        global symbols.  The ELF spec may be interpreted to say that a
-        file symbol must sort before other local symbols, but currently
-        ld -r doesn't do this.  So, for ld -r output, it is possible to
-        make a better choice of file name for local symbols by ignoring
-        file symbols appearing after a given local symbol.  */
-      enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
-      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
-      file = NULL;
-      low_func = 0;
-      state = nothing_seen;
-      cache->filename = NULL;
-      cache->func = NULL;
-      cache->func_size = 0;
-      cache->last_section = section;
-
-      for (p = symbols; *p != NULL; p++)
-       {
-         asymbol *sym = *p;
-         bfd_vma code_off;
-         bfd_size_type size;
-
-         if ((sym->flags & BSF_FILE) != 0)
-           {
-             file = sym;
-             if (state == symbol_seen)
-               state = file_after_symbol_seen;
-             continue;
-           }
-
-         size = bed->maybe_function_sym (sym, section, &code_off);
-         if (size != 0
-             && code_off <= offset
-             && (code_off > low_func
-                 || (code_off == low_func
-                     && size > cache->func_size)))
-           {
-             cache->func = sym;
-             cache->func_size = size;
-             cache->filename = NULL;
-             low_func = code_off;
-             if (file != NULL
-                 && ((sym->flags & BSF_LOCAL) != 0
-                     || state != file_after_symbol_seen))
-               cache->filename = bfd_asymbol_name (file);
-           }
-         if (state == nothing_seen)
-           state = symbol_seen;
-       }
-    }
-
-  if (cache->func == NULL)
-    return FALSE;
-
-  if (filename_ptr)
-    *filename_ptr = cache->filename;
-  if (functionname_ptr)
-    *functionname_ptr = bfd_asymbol_name (cache->func);
-
-  return TRUE;
-}
-
 /* Find the nearest line to a particular section and offset,
    for error reporting.  */
 
@@ -7824,24 +7750,15 @@ _bfd_elf_find_nearest_line (bfd *abfd,
                                     filename_ptr, functionname_ptr,
                                     line_ptr, discriminator_ptr,
                                     dwarf_debug_sections, 0,
-                                    &elf_tdata (abfd)->dwarf2_find_line_info))
+                                    &elf_tdata (abfd)->dwarf2_find_line_info)
+      || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+                                       filename_ptr, functionname_ptr,
+                                       line_ptr))
     {
       if (!*functionname_ptr)
-       elf_find_function (abfd, symbols, section, offset,
-                          *filename_ptr ? NULL : filename_ptr,
-                          functionname_ptr);
-
-      return TRUE;
-    }
-
-  if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
-                                    filename_ptr, functionname_ptr, line_ptr))
-    {
-      if (!*functionname_ptr)
-       elf_find_function (abfd, symbols, section, offset,
-                          *filename_ptr ? NULL : filename_ptr,
-                          functionname_ptr);
-
+       _bfd_elf_find_function (abfd, symbols, section, offset,
+                               *filename_ptr ? NULL : filename_ptr,
+                               functionname_ptr);
       return TRUE;
     }
 
@@ -7856,8 +7773,8 @@ _bfd_elf_find_nearest_line (bfd *abfd,
   if (symbols == NULL)
     return FALSE;
 
-  if (! elf_find_function (abfd, symbols, section, offset,
-                          filename_ptr, functionname_ptr))
+  if (! _bfd_elf_find_function (abfd, symbols, section, offset,
+                               filename_ptr, functionname_ptr))
     return FALSE;
 
   *line_ptr = 0;
@@ -8357,6 +8274,18 @@ 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_s390_vxrs_low (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-low", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-high", note);
+}
+
 static bfd_boolean
 elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
 {
@@ -8821,6 +8750,20 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       else
         return TRUE;
 
+    case NT_S390_VXRS_LOW:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_s390_vxrs_low (abfd, note);
+      else
+       return TRUE;
+
+    case NT_S390_VXRS_HIGH:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_s390_vxrs_high (abfd, note);
+      else
+       return TRUE;
+
     case NT_ARM_VFP:
       if (note->namesz == 6
          && strcmp (note->namedata, "LINUX") == 0)
@@ -9686,6 +9629,31 @@ elfcore_write_s390_tdb (bfd *abfd,
                              note_name, NT_S390_TDB, s390_tdb, size);
 }
 
+char *
+elfcore_write_s390_vxrs_low (bfd *abfd,
+                            char *buf,
+                            int *bufsiz,
+                            const void *s390_vxrs_low,
+                            int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_S390_VXRS_LOW, s390_vxrs_low, size);
+}
+
+char *
+elfcore_write_s390_vxrs_high (bfd *abfd,
+                            char *buf,
+                            int *bufsiz,
+                            const void *s390_vxrs_high,
+                            int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_S390_VXRS_HIGH,
+                            s390_vxrs_high, size);
+}
+
 char *
 elfcore_write_arm_vfp (bfd *abfd,
                       char *buf,
@@ -9770,6 +9738,10 @@ elfcore_write_register_note (bfd *abfd,
     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-s390-vxrs-low") == 0)
+    return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-vxrs-high") == 0)
+    return elfcore_write_s390_vxrs_high (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)
@@ -9818,30 +9790,35 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
 
        case bfd_core:
          {
+#define GROKER_ELEMENT(S,F) {S, sizeof (S) - 1, F}
            struct
            {
              const char * string;
+             size_t len;
              bfd_boolean (* func)(bfd *, Elf_Internal_Note *);
            }
            grokers[] =
            {
-             { "", elfcore_grok_note },
-             { "NetBSD-CORE", elfcore_grok_netbsd_note },
-             { "OpenBSD", elfcore_grok_openbsd_note },
-             { "QNX", elfcore_grok_nto_note },
-             { "SPU/", elfcore_grok_spu_note }
+             GROKER_ELEMENT ("", elfcore_grok_note),
+             GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note),
+             GROKER_ELEMENT ( "OpenBSD", elfcore_grok_openbsd_note),
+             GROKER_ELEMENT ("QNX", elfcore_grok_nto_note),
+             GROKER_ELEMENT ("SPU/", elfcore_grok_spu_note)
            };
+#undef GROKER_ELEMENT
            int i;
 
            for (i = ARRAY_SIZE (grokers); i--;)
-             if (in.namesz >= sizeof grokers[i].string - 1
-                 && strncmp (in.namedata, grokers[i].string,
-                             sizeof (grokers[i].string) - 1) == 0)
-               {
-                 if (! grokers[i].func (abfd, & in))
-                   return FALSE;
-                 break;
-               }
+             {
+               if (in.namesz >= grokers[i].len
+                   && strncmp (in.namedata, grokers[i].string,
+                               grokers[i].len) == 0)
+                 {
+                   if (! grokers[i].func (abfd, & in))
+                     return FALSE;
+                   break;
+                 }
+             }
            break;
          }
 
This page took 0.029039 seconds and 4 git commands to generate.