* elf32-sh.c (sh_elf_create_dynamic_sections): Return if dynamic
[deliverable/binutils-gdb.git] / bfd / elf.c
index 0331f3d316c87907065dcea2ae43195941bf26d1..470f3c2f76e3220bff153ac9c7f9a6181237a704 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -271,7 +271,7 @@ bfd_elf_hash (namearg)
          h ^= g;
        }
     }
-  return h;
+  return h & 0xffffffff;
 }
 
 /* Read a specified number of bytes at a specified offset in an ELF
@@ -936,7 +936,7 @@ const char *const bfd_elf_section_type_names[] = {
   "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
 };
 
-/* ELF relocs are against symbols.  If we are producing relocateable
+/* ELF relocs are against symbols.  If we are producing relocatable
    output, and the reloc is against an external symbol, and nothing
    has given us any additional addend, the resulting reloc will also
    be against the same symbol.  In such a case, we don't want to
@@ -944,7 +944,7 @@ const char *const bfd_elf_section_type_names[] = {
    all be done at final link time.  Rather than put special case code
    into bfd_perform_relocation, all the reloc types use this howto
    function.  It just short circuits the reloc if producing
-   relocateable output against an external symbol.  */
+   relocatable output against an external symbol.  */
 
 bfd_reloc_status_type
 bfd_elf_generic_reloc (abfd,
@@ -1070,6 +1070,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
            case PT_PHDR: pt = "PHDR"; break;
            case PT_TLS: pt = "TLS"; break;
            case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
+           case PT_GNU_STACK: pt = "STACK"; break;
            default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
            }
          fprintf (f, "%8s off    0x", pt);
@@ -1616,7 +1617,7 @@ bfd_elf_get_needed_list (abfd, info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
-  if (info->hash->creator->flavour != bfd_target_elf_flavour)
+  if (! is_elf_hash_table (info))
     return NULL;
   return elf_hash_table (info)->needed;
 }
@@ -1629,7 +1630,7 @@ bfd_elf_get_runpath_list (abfd, info)
      bfd *abfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
-  if (info->hash->creator->flavour != bfd_target_elf_flavour)
+  if (! is_elf_hash_table (info))
     return NULL;
   return elf_hash_table (info)->runpath;
 }
@@ -1837,7 +1838,7 @@ bfd_section_from_shdr (abfd, shindex)
          SHF_ALLOC is set, and this is a shared object, then we also
          treat this section as a BFD section.  We can not base the
          decision purely on SHF_ALLOC, because that flag is sometimes
-         set in a relocateable object file, which would confuse the
+         set in a relocatable object file, which would confuse the
          linker.  */
       if ((hdr->sh_flags & SHF_ALLOC) != 0
          && (abfd->flags & DYNAMIC) != 0
@@ -2292,6 +2293,13 @@ bfd_section_from_phdr (abfd, hdr, index)
     case PT_PHDR:
       return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr");
 
+    case PT_GNU_EH_FRAME:
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
+                                             "eh_frame_hdr");
+
+    case PT_GNU_STACK:
+      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");
+
     default:
       /* Check for any processor-specific program segment types.
          If no handler for them, default to making "segment" sections.  */
@@ -2331,7 +2339,7 @@ _bfd_elf_init_reloc_shdr (abfd, rel_hdr, asect, use_rela_p)
   rel_hdr->sh_entsize = (use_rela_p
                         ? bed->s->sizeof_rela
                         : bed->s->sizeof_rel);
-  rel_hdr->sh_addralign = bed->s->file_align;
+  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
   rel_hdr->sh_flags = 0;
   rel_hdr->sh_addr = 0;
   rel_hdr->sh_size = 0;
@@ -2361,9 +2369,9 @@ elf_fake_sections (abfd, asect, failedptrarg)
 
   this_hdr = &elf_section_data (asect)->this_hdr;
 
-  this_hdr->sh_name = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-                                                          asect->name, FALSE);
-  if (this_hdr->sh_name == (unsigned long) -1)
+  this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+                                                         asect->name, FALSE);
+  if (this_hdr->sh_name == (unsigned int) -1)
     {
       *failedptr = TRUE;
       return;
@@ -3509,6 +3517,21 @@ map_sections_to_segments (abfd)
       pm = &m->next;
     }
 
+  if (elf_tdata (abfd)->stack_flags)
+    {
+      amt = sizeof (struct elf_segment_map);
+      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+      if (m == NULL)
+       goto error_return;
+      m->next = NULL;
+      m->p_type = PT_GNU_STACK;
+      m->p_flags = elf_tdata (abfd)->stack_flags;
+      m->p_flags_valid = 1;
+
+      *pm = m;
+      pm = &m->next;
+    }
+
   free (sections);
   sections = NULL;
 
@@ -3744,7 +3767,7 @@ assign_file_positions_for_segments (abfd)
          && (abfd->flags & D_PAGED) != 0)
        p->p_align = bed->maxpagesize;
       else if (m->count == 0)
-       p->p_align = bed->s->file_align;
+       p->p_align = 1 << bed->s->log_file_align;
       else
        p->p_align = 0;
 
@@ -4095,6 +4118,12 @@ get_program_header_size (abfd)
       ++segs;
     }
 
+  if (elf_tdata (abfd)->stack_flags)
+    {
+      /* We need a PT_GNU_STACK segment.  */
+      ++segs;
+    }
+
   for (s = abfd->sections; s != NULL; s = s->next)
     {
       if ((s->flags & SEC_LOAD) != 0
@@ -4241,7 +4270,7 @@ assign_file_positions_except_relocs (abfd)
     }
 
   /* Place the section headers.  */
-  off = align_file_position (off, bed->s->file_align);
+  off = align_file_position (off, 1 << bed->s->log_file_align);
   i_ehdrp->e_shoff = off;
   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
 
@@ -4778,7 +4807,7 @@ copy_private_bfd_data (ibfd, obfd)
           section = section->next)
        if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
          ++section_count;
+
       /* Allocate a segment map big enough to contain
         all of the sections we have selected.  */
       amt = sizeof (struct elf_segment_map);
@@ -5068,7 +5097,10 @@ copy_private_bfd_data (ibfd, obfd)
              amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
              map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
              if (map == NULL)
-               return FALSE;
+               {
+                 free (sections);
+                 return FALSE;
+               }
 
              /* Initialise the fields of the segment map.  Set the physical
                 physical address to the LMA of the first section that has
@@ -5295,7 +5327,7 @@ swap_out_syms (abfd, sttp, relocatable_p)
   symtab_hdr->sh_entsize = bed->s->sizeof_sym;
   symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
   symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
-  symtab_hdr->sh_addralign = bed->s->file_align;
+  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
 
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
   symstrtab_hdr->sh_type = SHT_STRTAB;
@@ -5303,7 +5335,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
   amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym;
   outbound_syms = bfd_alloc (abfd, amt);
   if (outbound_syms == NULL)
-    return FALSE;
+    {
+      _bfd_stringtab_free (stt);
+      return FALSE;
+    }
   symtab_hdr->contents = (PTR) outbound_syms;
 
   outbound_shndx = NULL;
@@ -5313,7 +5348,11 @@ swap_out_syms (abfd, sttp, relocatable_p)
       amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
       outbound_shndx = bfd_zalloc (abfd, amt);
       if (outbound_shndx == NULL)
-       return FALSE;
+       {
+         _bfd_stringtab_free (stt);
+         return FALSE;
+       }
+
       symtab_shndx_hdr->contents = outbound_shndx;
       symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
       symtab_shndx_hdr->sh_size = amt;
@@ -5357,7 +5396,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
                                                            syms[idx]->name,
                                                            TRUE, FALSE);
          if (sym.st_name == (unsigned long) -1)
-           return FALSE;
+           {
+             _bfd_stringtab_free (stt);
+             return FALSE;
+           }
        }
 
       type_ptr = elf_symbol_from (abfd, syms[idx]);
@@ -5445,10 +5487,11 @@ swap_out_syms (abfd, sttp, relocatable_p)
 Unable to find equivalent output section for symbol '%s' from section '%s'"),
                                          syms[idx]->name ? syms[idx]->name : "<Local sym>",
                                          sec->name);
-                     bfd_set_error (bfd_error_invalid_operation);      
+                     bfd_set_error (bfd_error_invalid_operation);
+                     _bfd_stringtab_free (stt);
                      return FALSE;
                    }
-  
+
                  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
                  BFD_ASSERT (shndx != -1);
                }
@@ -5906,7 +5949,7 @@ _bfd_elf_slurp_version_tables (abfd)
   return TRUE;
 
  error_return:
-  if (contents == NULL)
+  if (contents != NULL)
     free (contents);
   return FALSE;
 }
@@ -6866,6 +6909,20 @@ elfcore_grok_note (abfd, note)
 #else
       return TRUE;
 #endif
+
+    case NT_AUXV:
+      {
+       asection *sect = bfd_make_section (abfd, ".auxv");
+
+       if (sect == NULL)
+         return FALSE;
+       sect->_raw_size = note->descsz;
+       sect->filepos = note->descpos;
+       sect->flags = SEC_HAS_CONTENTS;
+       sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+       return TRUE;
+      }
     }
 }
 
@@ -6983,18 +7040,30 @@ elfcore_grok_nto_status (abfd, note, tid)
   char buf[100];
   char *name;
   asection *sect;
+  short sig;
+  unsigned flags;
 
   /* nto_procfs_status 'pid' field is at offset 0.  */
   elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
 
-  /* nto_procfs_status 'tid' field is at offset 4.  */
-  elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+  /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
+  *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+
+  /* nto_procfs_status 'flags' field is at offset 8.  */
+  flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
 
   /* nto_procfs_status 'what' field is at offset 14.  */
-  elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, (bfd_byte *) ddata + 14);
+  if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
+    {
+      elf_tdata (abfd)->core_signal = sig;
+      elf_tdata (abfd)->core_lwpid = *tid;
+    }
 
-  /* Pass tid back.  */
-  *tid = elf_tdata (abfd)->core_lwpid;
+  /* _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;
 
   /* Make a ".qnx_core_status/%d" section.  */
   sprintf (buf, ".qnx_core_status/%d", *tid);
@@ -7043,7 +7112,11 @@ elfcore_grok_nto_gregs (abfd, note, tid)
   sect->flags           = SEC_HAS_CONTENTS;
   sect->alignment_power = 2;
 
-  return elfcore_maybe_make_sect (abfd, ".reg", sect);
+  /* This is the current thread.  */
+  if (elf_tdata (abfd)->core_lwpid == tid)
+    return elfcore_maybe_make_sect (abfd, ".reg", sect);
+
+  return TRUE;
 }
 
 #define BFD_QNT_CORE_INFO      7
@@ -7057,7 +7130,7 @@ elfcore_grok_nto_note (abfd, note)
      Elf_Internal_Note *note;
 {
   /* Every GREG section has a STATUS section before it.  Store the
-     tid from the previous call to pass down to the next gregs 
+     tid from the previous call to pass down to the next gregs
      function.  */
   static pid_t tid = 1;
 
@@ -7107,7 +7180,7 @@ elfcore_write_note (abfd, buf, bufsiz, name, type, input, size)
 
       namesz = strlen (name) + 1;
       bed = get_elf_backend_data (abfd);
-      pad = -namesz & (bed->s->file_align - 1);
+      pad = -namesz & ((1 << bed->s->log_file_align) - 1);
     }
 
   newspace = sizeof (Elf_External_Note) - 1 + namesz + pad + size;
@@ -7517,3 +7590,27 @@ _bfd_elf_section_offset (abfd, info, sec, offset)
       return offset;
     }
 }
+\f
+/* Create a new BFD as if by bfd_openr.  Rather than opening a file,
+   reconstruct an ELF file by reading the segments out of remote memory
+   based on the ELF file header at EHDR_VMA and the ELF program headers it
+   points to.  If not null, *LOADBASEP is filled in with the difference
+   between the VMAs from which the segments were read, and the VMAs the
+   file headers (and hence BFD's idea of each section's VMA) put them at.
+
+   The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+   remote memory at target address VMA into the local buffer at MYADDR; it
+   should return zero on success or an `errno' code on failure.  TEMPL must
+   be a BFD for an ELF target with the word size and byte order found in
+   the remote memory.  */
+
+bfd *
+bfd_elf_bfd_from_remote_memory (templ, ehdr_vma, loadbasep, target_read_memory)
+     bfd *templ;
+     bfd_vma ehdr_vma;
+     bfd_vma *loadbasep;
+     int (*target_read_memory) PARAMS ((bfd_vma vma, char *myaddr, int len));
+{
+  return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
+    (templ, ehdr_vma, loadbasep, target_read_memory);
+}
This page took 0.029296 seconds and 4 git commands to generate.