* elf32-sh.c (sh_elf_create_dynamic_sections): Return if dynamic
[deliverable/binutils-gdb.git] / bfd / elf.c
index 72fe61c4a3c629b9f1b887569dc75fb8a5d821f0..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
@@ -2296,6 +2297,9 @@ bfd_section_from_phdr (abfd, hdr, index)
       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.  */
@@ -2335,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;
@@ -2365,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;
@@ -3513,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;
 
@@ -3748,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;
 
@@ -4099,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
@@ -4245,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;
 
@@ -5302,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;
@@ -6884,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;
+      }
     }
 }
 
@@ -7001,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);
@@ -7061,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
@@ -7125,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;
@@ -7535,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.027932 seconds and 4 git commands to generate.