]> Git Repo - binutils.git/blobdiff - bfd/elfcode.h
* coffcode.h (bfd_coff_backend_data): Added new arguments to
[binutils.git] / bfd / elfcode.h
index 978385fddc8d6af88157fbab459dd10cac1d23dc..88f4cc900880d8f6162d03b6b10edf5dfd4dfba3 100644 (file)
@@ -641,7 +641,8 @@ DEFUN (bfd_section_from_shdr, (abfd, shindex),
        bfd_section_from_shdr (abfd, hdr->sh_info);     /* target */
        bfd_section_from_shdr (abfd, hdr->sh_link);     /* symbol table */
        target_sect = section_from_elf_index (abfd, hdr->sh_info);
-       if (target_sect == NULL)
+       if (target_sect == NULL
+           || elf_section_data (target_sect) == NULL)
          return false;
 
        hdr2 = &elf_section_data (target_sect)->rel_hdr;
@@ -823,7 +824,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
   Elf_Internal_Shdr *i_shdrp;  /* Section header table, internal form */
   int shindex;
   char *shstrtab;              /* Internal copy of section header stringtab */
-  struct elf_backend_data *ebd;        /* Use to get ELF_ARCH stored in xvec */
+  struct elf_backend_data *ebd;
   struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
 
   /* Read in the ELF header in external format.  */
@@ -877,51 +878,65 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
   if (i_ehdrp->e_shoff == 0)
     goto got_wrong_format_error;
 
+  /* As a simple sanity check, verify that the what BFD thinks is the
+     size of each section header table entry actually matches the size
+     recorded in the file. */
+  if (i_ehdrp->e_shentsize != sizeof (x_shdr))
+    goto got_wrong_format_error;
+
+  ebd = get_elf_backend_data (abfd);
+
+  /* Check that the ELF e_machine field matches what this particular
+     BFD format expects.  */
+  if (ebd->elf_machine_code != i_ehdrp->e_machine)
+    {
+      bfd_target **target_ptr;
+
+      if (ebd->elf_machine_code != EM_NONE)
+       goto got_wrong_format_error;
+
+      /* This is the generic ELF target.  Let it match any ELF target
+        for which we do not have a specific backend.  */
+      for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
+       {
+         struct elf_backend_data *back;
+
+         if ((*target_ptr)->flavour != bfd_target_elf_flavour)
+           continue;
+         back = (struct elf_backend_data *) (*target_ptr)->backend_data;
+         if (back->elf_machine_code == i_ehdrp->e_machine)
+           {
+             /* target_ptr is an ELF backend which matches this
+                object file, so reject the generic ELF target.  */
+             goto got_wrong_format_error;
+           }
+       }
+    }
+
+
+  /* Set the flags and architecture before calling the backend so that
+     it can override them.  */
   if (i_ehdrp->e_type == ET_EXEC)
     abfd->flags |= EXEC_P;
   else if (i_ehdrp->e_type == ET_DYN)
     abfd->flags |= DYNAMIC;
 
-  /* Retrieve the architecture information from the xvec and verify
-     that it matches the machine info stored in the ELF header.
-     This allows us to resolve ambiguous formats that might not
-     otherwise be distinguishable. */
-
-  ebd = get_elf_backend_data (abfd);
-
-  /* Perhaps the elf architecture value should be another field in the
-     elf backend data?  If you change this to work that way, make sure
-     that you still get bfd_arch_unknown for unknown architecture types,
-     and that it still gets accepted by the `generic' elf target.  */
-  {
-    int i;
-    enum bfd_architecture arch = bfd_arch_unknown;
+  bfd_default_set_arch_mach (abfd, ebd->arch, 0);
 
-    for (i = 0; i < bfd_elf_arch_map_size; i++)
-      {
-       if (bfd_elf_arch_map[i].elf_arch == i_ehdrp->e_machine)
-         {
-           arch = bfd_elf_arch_map[i].bfd_arch;
-           break;
-         }
-      }
-    /* start-sanitize-v9 */
-    if (i_ehdrp->e_machine == EM_SPARC64)
-      arch = bfd_arch_sparc;
-    /* end-sanitize-v9 */
-    if (ebd->arch != arch)
-      goto got_wrong_format_error;
-    bfd_default_set_arch_mach (abfd, arch, 0);
-  }
+  /* Remember the entry point specified in the ELF file header. */
+  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
 
+  /* Let the backend double check the format and override global
+     information.  */
+  if (ebd->elf_backend_object_p)
+    {
+      if ((*ebd->elf_backend_object_p) (abfd) == false)
+       goto got_wrong_format_error;
+    }
+    
   /* Allocate space for a copy of the section header table in
      internal form, seek to the section header table in the file,
-     read it in, and convert it to internal form.  As a simple sanity
-     check, verify that the what BFD thinks is the size of each section
-     header table entry actually matches the size recorded in the file. */
-
-  if (i_ehdrp->e_shentsize != sizeof (x_shdr))
-    goto got_wrong_format_error;
+     read it in, and convert it to internal form.  */
   i_shdrp = (Elf_Internal_Shdr *)
     bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum);
   elf_elfsections (abfd) =
@@ -936,6 +951,11 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
        goto got_system_call_error;
       elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
       elf_elfsections(abfd)[shindex] = i_shdrp + shindex;
+
+      /* If this is a .dynamic section, mark the object file as being
+        dynamically linked.  */
+      if (i_shdrp[shindex].sh_type == SHT_DYNAMIC)
+       abfd->flags |= DYNAMIC;
     }
   if (i_ehdrp->e_shstrndx)
     {
@@ -986,10 +1006,6 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
       bfd_section_from_shdr (abfd, shindex);
     }
 
-  /* Remember the entry point specified in the ELF file header. */
-
-  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
-
   return (abfd->xvec);
 
   /* If we are going to use goto's to avoid duplicating error setting
@@ -1071,7 +1087,11 @@ DEFUN (elf_make_sections, (abfd, asect, obj),
       rela_hdr->sh_flags = 0;
       rela_hdr->sh_addr = 0;
       rela_hdr->sh_offset = 0;
-      rela_hdr->sh_addralign = 0;
+
+      /* FIXME: Systems I've checked use an alignment of 4, but it is
+        possible that some systems use a different alignment.  */
+      rela_hdr->sh_addralign = 4;
+
       rela_hdr->size = 0;
     }
   if (asect->flags & SEC_ALLOC)
@@ -1108,7 +1128,7 @@ write_relocs (abfd, sec, xxx)
   int idx;
   int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
   asymbol *last_sym = 0;
-  int last_sym_idx;
+  int last_sym_idx = 9999999;  /* should always be written before use */
 
   if ((sec->flags & SEC_RELOC) == 0)
     return;
@@ -1239,7 +1259,8 @@ DEFUN (elf_fake_sections, (abfd, asect, obj),
     this_hdr->sh_type = SHT_PROGBITS;
   else if ((asect->flags & SEC_ALLOC) && ((asect->flags & SEC_LOAD) == 0))
     {
-      BFD_ASSERT (!strcmp (asect->name, ".bss"));
+      BFD_ASSERT (strcmp (asect->name, ".bss") == 0
+                 || strcmp (asect->name, ".sbss") == 0);
       this_hdr->sh_type = SHT_NOBITS;
     }
   /* FIXME I am not sure how to detect a .note section from the flags
@@ -1291,7 +1312,11 @@ DEFUN (elf_fake_sections, (abfd, asect, obj),
        rela_hdr->sh_addr = 0;
        rela_hdr->sh_size = 0;
        rela_hdr->sh_offset = 0;
-       rela_hdr->sh_addralign = 0;
+
+       /* FIXME: Systems I've checked use an alignment of 4, but some
+          systems may use a different alignment.  */
+       rela_hdr->sh_addralign = 4;
+
        rela_hdr->size = 0;
       }
   }
@@ -1313,9 +1338,15 @@ DEFUN (elf_fake_sections, (abfd, asect, obj),
    all local symbols to be at the head of the list.  */
 
 static INLINE int
-sym_is_global (sym)
+sym_is_global (abfd, sym)
+     bfd *abfd;
      asymbol *sym;
 {
+  /* If the backend has a special mapping, use it.  */
+  if (get_elf_backend_data (abfd)->elf_backend_sym_is_global)
+    return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global)
+           (abfd, sym));
+
   if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
     {
       if (sym->flags & BSF_LOCAL)
@@ -1419,7 +1450,7 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
   /* Identify and classify all of the symbols.  */
   for (idx = 0; idx < symcount; idx++)
     {
-      if (!sym_is_global (syms[idx]))
+      if (!sym_is_global (abfd, syms[idx]))
        num_locals++;
       else
        num_globals++;
@@ -1430,7 +1461,7 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
   for (idx = 0; idx < symcount; idx++)
     {
       syms[idx]->udata = (PTR) &sym_extra[idx];
-      if (!sym_is_global (syms[idx]))
+      if (!sym_is_global (abfd, syms[idx]))
        sym_extra[idx].elf_sym_num = 1 + num_locals2++;
       else
        sym_extra[idx].elf_sym_num = 1 + num_locals + num_globals2++;
@@ -1619,7 +1650,7 @@ map_program_segments (abfd)
 
   done = (char *) alloca (i_ehdrp->e_shnum);
   memset (done, 0, i_ehdrp->e_shnum);
-  for (i = 0; i < i_ehdrp->e_shnum; i++)
+  for (i = 1; i < i_ehdrp->e_shnum; i++)
     {
       i_shdrp = i_shdrpp[i];
       /* If it's going to be mapped in, it's been assigned a position.  */
@@ -1681,12 +1712,10 @@ map_program_segments (abfd)
       if (i_shdrp->sh_type == SHT_PROGBITS)
        file_size = i_shdrp->sh_size;
 
-      for (i = 0; i < i_ehdrp->e_shnum; i++)
+      for (i = 1; i < i_ehdrp->e_shnum; i++)
        {
          file_ptr f1;
 
-         if (file_size != mem_size)
-           break;
          if (done[i])
            continue;
          i_shdrp = i_shdrpp[i];
@@ -1696,6 +1725,8 @@ map_program_segments (abfd)
            {
              if (i_shdrp->sh_offset - f1 != i_shdrp->sh_addr - high)
                continue;
+             if (file_size != mem_size)
+               break;
            }
          else /* sh_type == NOBITS */
            {
@@ -1786,12 +1817,14 @@ assign_file_positions_except_relocs (abfd)
      The order, for now: <ehdr> <shdr> <sec1> <sec2> <sec3> ... <rel1> ...
      or:                 <ehdr> <phdr> <sec1> <sec2> ... <shdr> <rel1> ... */
 
+  struct elf_obj_tdata *t = elf_tdata (abfd);
   file_ptr off;
   int i;
   Elf_Internal_Shdr **i_shdrpp = elf_elfsections (abfd);
   Elf_Internal_Shdr *i_shdrp;
   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
   int exec_p = (abfd->flags & EXEC_P) != 0;
+  bfd_vma maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
 
   /* Everything starts after the ELF file header.  */
   off = i_ehdrp->e_ehsize;
@@ -1802,11 +1835,17 @@ assign_file_positions_except_relocs (abfd)
       off = align_file_position (off);
       i_ehdrp->e_shoff = off;
       off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
-
       off = assign_file_positions_for_symtab_and_strtabs (abfd, off);
     }
-  for (i = 0; i < i_ehdrp->e_shnum; i++)
+  for (i = 1; i < i_ehdrp->e_shnum; i++)
     {
+      /* The symtab and strtab sections are placed by
+        assign_file_positions_for_symtab_and_strtabs.  */
+      if (i == t->symtab_section
+         || i == t->strtab_section
+         || i == t->shstrtab_section)
+       continue;
+
       i_shdrp = i_shdrpp[i];
       if (i_shdrp->sh_type == SHT_REL || i_shdrp->sh_type == SHT_RELA)
        {
@@ -1815,7 +1854,6 @@ assign_file_positions_except_relocs (abfd)
        }
       if (exec_p)
        {
-         bfd_vma maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
          if (maxpagesize == 0)
            maxpagesize = 1;    /* make the arithmetic work */
          /* This isn't necessarily going to give the best packing, if the
@@ -1828,29 +1866,32 @@ assign_file_positions_except_relocs (abfd)
            }
          /* Blindly assume that the segments are ordered optimally.  With
             the default LD script, they will be.  */
-         {
-           /* need big unsigned type */
-           bfd_vma addtl_off;
-           addtl_off = i_shdrp->sh_addr - off;
-           addtl_off = addtl_off % maxpagesize;
-           if (addtl_off)
-             {
-               off += addtl_off;
-             }
-         }
-         if (i_shdrp->sh_type == SHT_NOBITS)
+         if (i_shdrp->sh_type != SHT_NOBITS)
            {
-             file_ptr off2;
-             i_shdrp->sh_offset = off;
-             if (off % maxpagesize != 0)
-               off2 = maxpagesize - (off % maxpagesize);
-             if (off2 > i_shdrp->sh_size)
-               off2 = i_shdrp->sh_size;
-             off += off2;
+             /* need big unsigned type */
+             bfd_vma addtl_off;
+             addtl_off = i_shdrp->sh_addr - off;
+             addtl_off = addtl_off % maxpagesize;
+             if (addtl_off)
+               {
+                 off += addtl_off;
+               }
            }
        }
       off = assign_file_position_for_section (i_shdrp, off);
 
+      if (exec_p
+         && i_shdrp->sh_type == SHT_NOBITS
+         && (i == i_ehdrp->e_shnum
+             || i_shdrpp[i + 1]->sh_type != SHT_NOBITS))
+       {
+         /* Skip to the next page to ensure that when the file is
+            loaded the bss section is loaded with zeroes.  I don't
+            know if this is required on all platforms, but it
+            shouldn't really hurt.  */
+         off = BFD_ALIGN (off, maxpagesize);
+       }
+
       if (exec_p
          && get_elf_backend_data(abfd)->maxpagesize > 1
          && i_shdrp->sh_type == SHT_PROGBITS
@@ -1871,7 +1912,7 @@ assign_file_positions_except_relocs (abfd)
 
       off = assign_file_positions_for_symtab_and_strtabs (abfd, off);
 
-      for (i = 0; i < i_ehdrp->e_shnum; i++)
+      for (i = 1; i < i_ehdrp->e_shnum; i++)
        {
          i_shdrp = i_shdrpp[i];
          if (i_shdrp->sh_offset + 1 == 0
@@ -2012,6 +2053,11 @@ swap_out_syms (abfd)
     symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
     symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
 
+    /* FIXME: Systems I've checked use 4 byte alignment for .symtab,
+       but it is possible that there are systems which use a different
+       alignment.  */
+    symtab_hdr->sh_addralign = 4;
+
     /* see assert in elf_fake_sections that supports this: */
     symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
     symstrtab_hdr->sh_type = SHT_STRTAB;
@@ -2049,7 +2095,8 @@ swap_out_syms (abfd)
            sym.st_size = value;
            /* Should retrieve this from somewhere... */
            sym.st_value = 16;
-           sym.st_shndx = SHN_COMMON;
+           sym.st_shndx = elf_section_from_bfd_section (abfd,
+                                                        syms[idx]->section);
          }
        else
          {
@@ -2084,7 +2131,7 @@ swap_out_syms (abfd)
          }
 
        if (bfd_is_com_section (syms[idx]->section))
-         sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE);
+         sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
        else if (syms[idx]->section == &bfd_und_section)
          sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE);
        else if (syms[idx]->flags & BSF_SECTION_SYM)
@@ -2126,7 +2173,7 @@ swap_out_syms (abfd)
     symstrtab_hdr->sh_entsize = 0;
     symstrtab_hdr->sh_link = 0;
     symstrtab_hdr->sh_info = 0;
-    symstrtab_hdr->sh_addralign = 0;
+    symstrtab_hdr->sh_addralign = 1;
     symstrtab_hdr->size = 0;
   }
 
@@ -2141,7 +2188,7 @@ swap_out_syms (abfd)
     this_hdr->sh_flags = 0;
     this_hdr->sh_addr = 0;
     this_hdr->sh_entsize = 0;
-    this_hdr->sh_addralign = 0;
+    this_hdr->sh_addralign = 1;
     this_hdr->size = 0;
   }
 }
@@ -2202,7 +2249,7 @@ assign_file_positions_for_relocs (abfd)
   int i;
   Elf_Internal_Shdr **shdrpp = elf_elfsections (abfd);
   Elf_Internal_Shdr *shdrp;
-  for (i = 0; i < elf_elfheader(abfd)->e_shnum; i++)
+  for (i = 1; i < elf_elfheader(abfd)->e_shnum; i++)
     {
       shdrp = shdrpp[i];
       if (shdrp->sh_type != SHT_REL && shdrp->sh_type != SHT_RELA)
@@ -2216,10 +2263,20 @@ assign_file_positions_for_relocs (abfd)
 boolean
 DEFUN (NAME(bfd_elf,write_object_contents), (abfd), bfd * abfd)
 {
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
   Elf_Internal_Ehdr *i_ehdrp;
   Elf_Internal_Shdr **i_shdrp;
   int count;
 
+  /* We don't know how to write dynamic objects.  Specifically, we
+     don't know how to construct the program header.  */
+  if ((abfd->flags & DYNAMIC) != 0)
+    {
+      fprintf (stderr, "Writing ELF dynamic objects is not supported\n");
+      bfd_error = wrong_format;
+      return false;
+    }
+
   if (abfd->output_has_begun == false)
     {
       prep_headers (abfd);
@@ -2234,10 +2291,8 @@ DEFUN (NAME(bfd_elf,write_object_contents), (abfd), bfd * abfd)
   assign_file_positions_for_relocs (abfd);
 
   /* After writing the headers, we need to write the sections too... */
-  for (count = 0; count < i_ehdrp->e_shnum; count++)
+  for (count = 1; count < i_ehdrp->e_shnum; count++)
     {
-      struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
       if (bed->elf_backend_section_processing)
        (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
       if (i_shdrp[count]->contents)
@@ -2247,6 +2302,10 @@ DEFUN (NAME(bfd_elf,write_object_contents), (abfd), bfd * abfd)
                     abfd);
        }
     }
+
+  if (bed->elf_backend_final_write_processing)
+    (*bed->elf_backend_final_write_processing) (abfd);
+
   return write_shdrs_and_ehdr (abfd);
 }
 
@@ -2429,10 +2488,6 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs),
      to be prepared to read both (and merge them) or ensure that we
      only read the full symbol table.  Currently we only get called to
      read the full symbol table.  -fnf */
-  if (bfd_get_outsymbols (abfd) != NULL)
-    {
-      return true;
-    }
 
   /* Read each raw ELF symbol, converting from external ELF form to
      internal ELF form, and then using the information to create a
@@ -2564,6 +2619,7 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs),
       *symptrs = 0;            /* Final null pointer */
     }
 
+  free ((PTR) x_symp);
   return true;
 }
 
This page took 0.039685 seconds and 4 git commands to generate.