]> Git Repo - binutils.git/blobdiff - bfd/elf.c
comment change
[binutils.git] / bfd / elf.c
index 424372ce2c52365a1d17f641f3c47bca2a25125e..e12a885c5ee8cbffddd9ad0f7984f1669fa66c54 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,5 +1,5 @@
 /* ELF executable support for BFD.
-   Copyright 1993 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -335,50 +335,152 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
 {
   FILE *f = (FILE *) farg;
   Elf_Internal_Phdr *p;
-  unsigned int i, c;
+  asection *s;
+  bfd_byte *dynbuf = NULL;
 
   p = elf_tdata (abfd)->phdr;
-  if (p == NULL)
-    return true;
+  if (p != NULL)
+    {
+      unsigned int i, c;
 
-  c = elf_elfheader (abfd)->e_phnum;
-  for (i = 0; i < c; i++, p++)
+      fprintf (f, "\nProgram Header:\n");
+      c = elf_elfheader (abfd)->e_phnum;
+      for (i = 0; i < c; i++, p++)
+       {
+         const char *s;
+         char buf[20];
+
+         switch (p->p_type)
+           {
+           case PT_NULL: s = "NULL"; break;
+           case PT_LOAD: s = "LOAD"; break;
+           case PT_DYNAMIC: s = "DYNAMIC"; break;
+           case PT_INTERP: s = "INTERP"; break;
+           case PT_NOTE: s = "NOTE"; break;
+           case PT_SHLIB: s = "SHLIB"; break;
+           case PT_PHDR: s = "PHDR"; break;
+           default: sprintf (buf, "0x%lx", p->p_type); s = buf; break;
+           }
+         fprintf (f, "%8s off    0x", s);
+         fprintf_vma (f, p->p_offset);
+         fprintf (f, " vaddr 0x");
+         fprintf_vma (f, p->p_vaddr);
+         fprintf (f, " paddr 0x");
+         fprintf_vma (f, p->p_paddr);
+         fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
+         fprintf (f, "         filesz 0x");
+         fprintf_vma (f, p->p_filesz);
+         fprintf (f, " memsz 0x");
+         fprintf_vma (f, p->p_memsz);
+         fprintf (f, " flags %c%c%c",
+                  (p->p_flags & PF_R) != 0 ? 'r' : '-',
+                  (p->p_flags & PF_W) != 0 ? 'w' : '-',
+                  (p->p_flags & PF_X) != 0 ? 'x' : '-');
+         if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0)
+           fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X));
+         fprintf (f, "\n");
+       }
+    }
+
+  s = bfd_get_section_by_name (abfd, ".dynamic");
+  if (s != NULL)
     {
-      const char *s;
-      char buf[20];
+      int elfsec;
+      unsigned long link;
+      bfd_byte *extdyn, *extdynend;
+      size_t extdynsize;
+      void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+
+      fprintf (f, "\nDynamic Section:\n");
 
-      switch (p->p_type)
+      dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size);
+      if (dynbuf == NULL)
+       goto error_return;
+      if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, (file_ptr) 0,
+                                     s->_raw_size))
+       goto error_return;
+
+      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+      if (elfsec == -1)
+       goto error_return;
+      link = elf_elfsections (abfd)[elfsec]->sh_link;
+
+      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
+      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
+
+      extdyn = dynbuf;
+      extdynend = extdyn + s->_raw_size;
+      for (; extdyn < extdynend; extdyn += extdynsize)
        {
-       case PT_NULL: s = "NULL"; break;
-       case PT_LOAD: s = "LOAD"; break;
-       case PT_DYNAMIC: s = "DYNAMIC"; break;
-       case PT_INTERP: s = "INTERP"; break;
-       case PT_NOTE: s = "NOTE"; break;
-       case PT_SHLIB: s = "SHLIB"; break;
-       case PT_PHDR: s = "PHDR"; break;
-       default: sprintf (buf, "0x%lx", p->p_type); s = buf; break;
+         Elf_Internal_Dyn dyn;
+         const char *name;
+         char ab[20];
+         boolean stringp;
+
+         (*swap_dyn_in) (abfd, (PTR) extdyn, &dyn);
+
+         if (dyn.d_tag == DT_NULL)
+           break;
+
+         stringp = false;
+         switch (dyn.d_tag)
+           {
+           default:
+             sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
+             name = ab;
+             break;
+
+           case DT_NEEDED: name = "NEEDED"; stringp = true; break;
+           case DT_PLTRELSZ: name = "PLTRELSZ"; break;
+           case DT_PLTGOT: name = "PLTGOT"; break;
+           case DT_HASH: name = "HASH"; break;
+           case DT_STRTAB: name = "STRTAB"; break;
+           case DT_SYMTAB: name = "SYMTAB"; break;
+           case DT_RELA: name = "RELA"; break;
+           case DT_RELASZ: name = "RELASZ"; break;
+           case DT_RELAENT: name = "RELAENT"; break;
+           case DT_STRSZ: name = "STRSZ"; break;
+           case DT_SYMENT: name = "SYMENT"; break;
+           case DT_INIT: name = "INIT"; break;
+           case DT_FINI: name = "FINI"; break;
+           case DT_SONAME: name = "SONAME"; stringp = true; break;
+           case DT_RPATH: name = "RPATH"; stringp = true; break;
+           case DT_SYMBOLIC: name = "SYMBOLIC"; break;
+           case DT_REL: name = "REL"; break;
+           case DT_RELSZ: name = "RELSZ"; break;
+           case DT_RELENT: name = "RELENT"; break;
+           case DT_PLTREL: name = "PLTREL"; break;
+           case DT_DEBUG: name = "DEBUG"; break;
+           case DT_TEXTREL: name = "TEXTREL"; break;
+           case DT_JMPREL: name = "JMPREL"; break;
+           }
+
+         fprintf (f, "  %-11s ", name);
+         if (! stringp)
+           fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
+         else
+           {
+             const char *string;
+
+             string = bfd_elf_string_from_elf_section (abfd, link,
+                                                       dyn.d_un.d_val);
+             if (string == NULL)
+               goto error_return;
+             fprintf (f, "%s", string);
+           }
+         fprintf (f, "\n");
        }
-      fprintf (f, "%8s off    0x", s);
-      fprintf_vma (f, p->p_offset);
-      fprintf (f, " vaddr 0x");
-      fprintf_vma (f, p->p_vaddr);
-      fprintf (f, " paddr 0x");
-      fprintf_vma (f, p->p_paddr);
-      fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
-      fprintf (f, "         filesz 0x");
-      fprintf_vma (f, p->p_filesz);
-      fprintf (f, " memsz 0x");
-      fprintf_vma (f, p->p_memsz);
-      fprintf (f, " flags %c%c%c",
-              (p->p_flags & PF_R) != 0 ? 'r' : '-',
-              (p->p_flags & PF_W) != 0 ? 'w' : '-',
-              (p->p_flags & PF_X) != 0 ? 'x' : '-');
-      if ((p->p_flags &~ (PF_R | PF_W | PF_X)) != 0)
-       fprintf (f, " %lx", p->p_flags &~ (PF_R | PF_W | PF_X));
-      fprintf (f, "\n");
+
+      free (dynbuf);
+      dynbuf = NULL;
     }
 
   return true;
+
+ error_return:
+  if (dynbuf != NULL)
+    free (dynbuf);
+  return false;
 }
 
 /* Display ELF-specific fields of a symbol.  */
@@ -576,6 +678,7 @@ bfd_section_from_shdr (abfd, shindex)
     case SHT_DYNAMIC:  /* Dynamic linking information.  */
     case SHT_NOBITS:   /* .bss section.  */
     case SHT_HASH:     /* .hash section.  */
+    case SHT_NOTE:     /* .note section.  */
       return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
 
     case SHT_SYMTAB:           /* A symbol table */
@@ -752,9 +855,6 @@ bfd_section_from_shdr (abfd, shindex)
       }
       break;
 
-    case SHT_NOTE:
-      break;
-
     case SHT_SHLIB:
       return true;
 
@@ -1158,12 +1258,9 @@ assign_section_numbers (abfd)
              char *alc;
 
              len = strlen (sec->name);
-             alc = (char *) malloc (len - 2);
+             alc = (char *) bfd_malloc (len - 2);
              if (alc == NULL)
-               {
-                 bfd_set_error (bfd_error_no_memory);
-                 return false;
-               }
+               return false;
              strncpy (alc, sec->name, len - 3);
              alc[len - 3] = '\0';
              s = bfd_get_section_by_name (abfd, alc);
@@ -1548,13 +1645,10 @@ map_sections_to_segments (abfd)
 
   /* Select the allocated sections, and sort them.  */
 
-  sections = (asection **) malloc (bfd_count_sections (abfd)
-                                  * sizeof (asection *));
+  sections = (asection **) bfd_malloc (bfd_count_sections (abfd)
+                                      * sizeof (asection *));
   if (sections == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   i = 0;
   for (s = abfd->sections; s != NULL; s = s->next)
@@ -1752,6 +1846,12 @@ assign_file_positions_for_segments (abfd)
        return false;
     }
 
+  if (bed->elf_backend_modify_segment_map)
+    {
+      if (! (*bed->elf_backend_modify_segment_map) (abfd))
+       return false;
+    }
+
   count = 0;
   for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
     ++count;
@@ -1763,11 +1863,6 @@ assign_file_positions_for_segments (abfd)
   if (count == 0)
     return true;
 
-  /* Let the backend count up any program headers it might need.  */
-  if (bed->elf_backend_create_program_headers)
-    count = ((*bed->elf_backend_create_program_headers)
-            (abfd, (Elf_Internal_Phdr *) NULL, count));
-
   /* If we already counted the number of program segments, make sure
      that we allocated enough space.  This happens when SIZEOF_HEADERS
      is used in a linker script.  */
@@ -1803,12 +1898,22 @@ assign_file_positions_for_segments (abfd)
       unsigned int i;
       asection **secpp;
 
+      /* If elf_segment_map is not from map_sections_to_segments, the
+         sections may not be correctly ordered.  */
+      if (m->count > 0)
+       qsort (m->sections, (size_t) m->count, sizeof (asection *),
+              elf_sort_sections);
+
       p->p_type = m->p_type;
 
       if (m->p_flags_valid)
        p->p_flags = m->p_flags;
+      else
+       p->p_flags = 0;
 
-      if (p->p_type == PT_LOAD && m->count > 0)
+      if (p->p_type == PT_LOAD
+         && m->count > 0
+         && (m->sections[0]->flags & SEC_LOAD) != 0)
        off += (m->sections[0]->vma - off) % bed->maxpagesize;
 
       if (m->count == 0)
@@ -1836,6 +1941,8 @@ assign_file_positions_for_segments (abfd)
 
       if (m->includes_filehdr)
        {
+         if (! m->p_flags_valid)
+           p->p_flags |= PF_R;
          p->p_offset = 0;
          p->p_filesz = bed->s->sizeof_ehdr;
          p->p_memsz = bed->s->sizeof_ehdr;
@@ -1855,6 +1962,8 @@ assign_file_positions_for_segments (abfd)
 
       if (m->includes_phdrs)
        {
+         if (! m->p_flags_valid)
+           p->p_flags |= PF_R;
          if (m->includes_filehdr)
            {
              if (p->p_type == PT_LOAD)
@@ -1897,8 +2006,6 @@ assign_file_positions_for_segments (abfd)
            }
        }
 
-      if (! m->p_flags_valid)
-       p->p_flags = PF_R;
       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
        {
          asection *sec;
@@ -1914,15 +2021,18 @@ assign_file_positions_for_segments (abfd)
 
              /* The section VMA must equal the file position modulo
                  the page size.  */
-             adjust = (sec->vma - off) % bed->maxpagesize;
-             if (adjust != 0)
+             if ((flags & SEC_LOAD) != 0)
                {
-                 if (i == 0)
-                   abort ();
-                 p->p_memsz += adjust;
-                 if ((flags & SEC_LOAD) != 0)
-                   p->p_filesz += adjust;
-                 off += adjust;
+                 adjust = (sec->vma - off) % bed->maxpagesize;
+                 if (adjust != 0)
+                   {
+                     if (i == 0)
+                       abort ();
+                     p->p_memsz += adjust;
+                     if ((flags & SEC_LOAD) != 0)
+                       p->p_filesz += adjust;
+                     off += adjust;
+                   }
                }
 
              sec->filepos = off;
@@ -1942,6 +2052,7 @@ assign_file_positions_for_segments (abfd)
 
          if (! m->p_flags_valid)
            {
+             p->p_flags |= PF_R;
              if ((flags & SEC_CODE) != 0)
                p->p_flags |= PF_X;
              if ((flags & SEC_READONLY) == 0)
@@ -1978,11 +2089,6 @@ assign_file_positions_for_segments (abfd)
        }
     }
 
-  /* Let the backend set up any program headers it might need.  */
-  if (bed->elf_backend_create_program_headers)
-    count = ((*bed->elf_backend_create_program_headers)
-            (abfd, phdrs, count));
-
   /* Clear out any program headers we allocated but did not use.  */
   for (; count < alloc; count++, p++)
     {
@@ -2025,6 +2131,17 @@ get_program_header_size (abfd)
   if (elf_tdata (abfd)->program_header_size != 0)
     return elf_tdata (abfd)->program_header_size;
 
+  if (elf_tdata (abfd)->segment_map != NULL)
+    {
+      struct elf_segment_map *m;
+
+      segs = 0;
+      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+       ++segs;
+      elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
+      return elf_tdata (abfd)->program_header_size;
+    }
+
   /* Assume we will need exactly two PT_LOAD segments: one for text
      and one for data.  */
   segs = 2;
@@ -2046,9 +2163,15 @@ get_program_header_size (abfd)
     }
 
   /* Let the backend count up any program headers it might need.  */
-  if (bed->elf_backend_create_program_headers)
-    segs = ((*bed->elf_backend_create_program_headers)
-           (abfd, (Elf_Internal_Phdr *) NULL, segs));
+  if (bed->elf_backend_additional_program_headers)
+    {
+      int a;
+
+      a = (*bed->elf_backend_additional_program_headers) (abfd);
+      if (a == -1)
+       abort ();
+      segs += a;
+    }
 
   elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
   return elf_tdata (abfd)->program_header_size;
@@ -2186,7 +2309,7 @@ prep_headers (abfd)
 
   i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
   i_ehdrp->e_ident[EI_DATA] =
-    abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB;
+    bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
   i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
 
   for (count = EI_PAD; count < EI_NIDENT; count++)
@@ -2501,6 +2624,7 @@ copy_private_bfd_data (ibfd, obfd)
                 && (bfd_vma) s->filepos >= p->p_offset
                 && ((bfd_vma) s->filepos + s->_raw_size
                     <= p->p_offset + p->p_filesz)))
+           && (s->flags & SEC_ALLOC) != 0
            && s->output_section != NULL)
          ++csecs;
 
@@ -2538,6 +2662,7 @@ copy_private_bfd_data (ibfd, obfd)
                   && (bfd_vma) s->filepos >= p->p_offset
                   && ((bfd_vma) s->filepos + s->_raw_size
                       <= p->p_offset + p->p_filesz)))
+             && (s->flags & SEC_ALLOC) != 0
              && s->output_section != NULL)
            {
              m->sections[isec] = s->output_section;
@@ -2545,9 +2670,6 @@ copy_private_bfd_data (ibfd, obfd)
            }
        }
       BFD_ASSERT (isec == csecs);
-      if (csecs > 0)
-       qsort (m->sections, (size_t) csecs, sizeof (asection *),
-              elf_sort_sections);
       m->count = csecs;
 
       *pm = m;
This page took 0.035141 seconds and 4 git commands to generate.