* elf.c (_bfd_elf_make_section_from_shdr): New function, based on
authorIan Lance Taylor <ian@airs.com>
Fri, 20 May 1994 16:04:59 +0000 (16:04 +0000)
committerIan Lance Taylor <ian@airs.com>
Fri, 20 May 1994 16:04:59 +0000 (16:04 +0000)
code repeated three times in bfd_section_from_shdr in elfcode.h.
* libelf.h (_bfd_elf_make_section_from_shdr): Declare.
* elfcode.h (bfd_section_from_shdr): Use new function
_bfd_elf_make_section_from_shdr to create BFD sections.  If a
reloc section does not use the main symbol table, or it is part of
the process image, treat it as a normal section, not relocs.
* elf32-mips.c (mips_elf_section_from_shdr): Use new function
_bfd_elf_make_section_from_shdr.

bfd/ChangeLog
bfd/elf.c
bfd/elf32-mips.c
bfd/elfcode.h
bfd/libelf.h

index a542d71..aaecc9c 100644 (file)
@@ -1,3 +1,15 @@
+Fri May 20 11:57:05 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       * elf.c (_bfd_elf_make_section_from_shdr): New function, based on
+       code repeated three times in bfd_section_from_shdr in elfcode.h.
+       * libelf.h (_bfd_elf_make_section_from_shdr): Declare.
+       * elfcode.h (bfd_section_from_shdr): Use new function
+       _bfd_elf_make_section_from_shdr to create BFD sections.  If a
+       reloc section does not use the main symbol table, or it is part of
+       the process image, treat it as a normal section, not relocs.
+       * elf32-mips.c (mips_elf_section_from_shdr): Use new function
+       _bfd_elf_make_section_from_shdr.
+
 Thu May 19 11:37:11 1994  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
 
        * elf32-target.h, elf64-target.h: Change ar_max_namelen value from
index a3ec151..b5c23db 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -154,6 +154,68 @@ elf_string_from_elf_section (abfd, shindex, strindex)
   return ((char *) hdr->rawdata) + strindex;
 }
 
+/* Make a BFD section from an ELF section.  We store a pointer to the
+   BFD section in the rawdata field of the header.  */
+
+boolean
+_bfd_elf_make_section_from_shdr (abfd, hdr, name)
+     bfd *abfd;
+     Elf_Internal_Shdr *hdr;
+     const char *name;
+{
+  asection *newsect;
+  flagword flags;
+
+  if (hdr->rawdata != NULL)
+    {
+      BFD_ASSERT (strcmp (name, ((asection *) hdr->rawdata)->name) == 0);
+      return true;
+    }
+
+  newsect = bfd_make_section_anyway (abfd, name);
+  if (newsect == NULL)
+    return false;
+
+  newsect->filepos = hdr->sh_offset;
+
+  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
+      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
+      || ! bfd_set_section_alignment (abfd, newsect,
+                                     bfd_log2 (hdr->sh_addralign)))
+    return false;
+
+  flags = SEC_NO_FLAGS;
+  if (hdr->sh_type != SHT_NOBITS)
+    flags |= SEC_HAS_CONTENTS;
+  if ((hdr->sh_flags & SHF_ALLOC) != 0)
+    {
+      flags |= SEC_ALLOC;
+      if (hdr->sh_type != SHT_NOBITS)
+       flags |= SEC_LOAD;
+    }
+  if ((hdr->sh_flags & SHF_WRITE) == 0)
+    flags |= SEC_READONLY;
+  if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
+    flags |= SEC_CODE;
+  else if ((flags & SEC_ALLOC) != 0)
+    flags |= SEC_DATA;
+
+  /* The debugging sections appear to be recognized only by name, not
+     any sort of flag.  */
+  if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
+      || strncmp (name, ".line", sizeof ".line" - 1) == 0
+      || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
+    flags |= SEC_DEBUGGING;
+
+  if (! bfd_set_section_flags (abfd, newsect, flags))
+    return false;
+
+  hdr->rawdata = (PTR) newsect;
+  elf_section_data (newsect)->this_hdr = *hdr;
+
+  return true;
+}
+
 /*
 INTERNAL_FUNCTION
        bfd_elf_find_section
index 7f4930d..1794210 100644 (file)
@@ -795,6 +795,8 @@ mips_elf_section_from_shdr (abfd, hdr, name)
      Elf32_Internal_Shdr *hdr;
      char *name;
 {
+  asection *newsect;
+
   /* There ought to be a place to keep ELF backend specific flags, but
      at the moment there isn't one.  We just keep track of the
      sections by their name, instead.  Fortunately, the ABI gives
@@ -835,60 +837,33 @@ mips_elf_section_from_shdr (abfd, hdr, name)
       return false;
     }
 
-  if (hdr->rawdata == NULL)
-    {
-      asection *newsect;
-
-      newsect = bfd_make_section (abfd, name);
-      if (newsect != NULL)
-       {
-         newsect->filepos = hdr->sh_offset;
-         newsect->flags |= SEC_HAS_CONTENTS;
-         newsect->vma = hdr->sh_addr;
-         newsect->_raw_size = hdr->sh_size;
-         newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-
-         if (hdr->sh_flags & SHF_ALLOC)
-           {
-             newsect->flags |= SEC_ALLOC;
-             newsect->flags |= SEC_LOAD;
-           }
-
-         if (!(hdr->sh_flags & SHF_WRITE))
-           newsect->flags |= SEC_READONLY;
-
-         if (hdr->sh_flags & SHF_EXECINSTR)
-           newsect->flags |= SEC_CODE;
-         else if (newsect->flags & SEC_ALLOC)
-           newsect->flags |= SEC_DATA;
-
-         if (hdr->sh_type == SHT_MIPS_DEBUG)
-           newsect->flags |= SEC_DEBUGGING;
+  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+    return false;
+  newsect = (asection *) hdr->rawdata;
 
-         hdr->rawdata = (void *) newsect;
+  if (hdr->sh_type == SHT_MIPS_DEBUG)
+    {
+      if (! bfd_set_section_flags (abfd, newsect,
+                                  (bfd_get_section_flags (abfd, newsect)
+                                   | SEC_DEBUGGING)))
+       return false;
+    }
 
-         /* FIXME: We should record the sh_info field for a .gptab
-            section.  */
+  /* FIXME: We should record sh_info for a .gptab section.  */
 
-         /* For a .reginfo section, set the gp value in the tdata
-            information from the contents of this section.  We need
-            the gp value while processing relocs, so we just get it
-            now.  */
-         if (hdr->sh_type == SHT_MIPS_REGINFO)
-           {
-             Elf32_External_RegInfo ext;
-             Elf32_RegInfo s;
+  /* For a .reginfo section, set the gp value in the tdata information
+     from the contents of this section.  We need the gp value while
+     processing relocs, so we just get it now.  */
+  if (hdr->sh_type == SHT_MIPS_REGINFO)
+    {
+      Elf32_External_RegInfo ext;
+      Elf32_RegInfo s;
 
-             if (bfd_get_section_contents (abfd, newsect, (PTR) &ext,
-                                           (file_ptr) 0,
-                                           sizeof ext) == false)
-               return false;
-             bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
-             elf_gp (abfd) = s.ri_gp_value;
-           }
-       }
-      else
-       hdr->rawdata = (void *) bfd_get_section_by_name (abfd, name);
+      if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,
+                                     (file_ptr) 0, sizeof ext))
+       return false;
+      bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
+      elf_gp (abfd) = s.ri_gp_value;
     }
 
   return true;
@@ -1201,20 +1176,15 @@ mips_elf_final_link (abfd, info)
                                   _bfd_generic_link_write_global_symbol,
                                   (PTR) &wginfo);
 
-  /* Remove empty sections.  Also drop the .options section, since it
-     has special semantics which I haven't bothered to figure out.
-     Also drop the .gptab sections, which also require special
-     handling which is not currently done.  Removing the .gptab
-     sections is required for Irix 5 compatibility; I don't know about
-     the other sections.  */
+  /* Drop the .options section, since it has special semantics which I
+     haven't bothered to figure out.  Also drop the .gptab sections,
+     which also require special handling which is not currently done.
+     Removing the .gptab sections is required for Irix 5
+     compatibility; I don't know about .options.  */
   secpp = &abfd->sections;
   while (*secpp != NULL)
     {
-      if (((*secpp)->_raw_size == 0
-          && strcmp ((*secpp)->name, ".data") != 0
-          && strcmp ((*secpp)->name, ".text") != 0
-          && strcmp ((*secpp)->name, ".bss") != 0)
-         || strcmp ((*secpp)->name, ".options") == 0
+      if (strcmp ((*secpp)->name, ".options") == 0
          || strncmp ((*secpp)->name, ".gptab", 6) == 0)
        {
          *secpp = (*secpp)->next;
@@ -1694,6 +1664,7 @@ static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap =
 #define ELF_ARCH                       bfd_arch_mips
 #define ELF_MACHINE_CODE               EM_MIPS
 #define ELF_MAXPAGESIZE                        0x10000
+#define elf_backend_collect            true
 #define elf_info_to_howto              0
 #define elf_info_to_howto_rel          mips_info_to_howto_rel
 #define elf_backend_sym_is_global      mips_elf_sym_is_global
index bdedb48..db0316a 100644 (file)
@@ -496,7 +496,6 @@ bfd_add_2_to_strtab (abfd, ss, str, str2)
   return ss->length - ln;
 }
 \f
-
 /* ELF .o/exec file reading */
 
 /* Create a new bfd section from an ELF section header. */
@@ -508,84 +507,20 @@ bfd_section_from_shdr (abfd, shindex)
 {
   Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
   Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
-  asection *newsect;
   char *name;
 
   name = elf_string_from_elf_strtab (abfd, hdr->sh_name);
 
   switch (hdr->sh_type)
     {
-
     case SHT_NULL:
-      /* inactive section. Throw it away. */
+      /* Inactive section. Throw it away.  */
       return true;
 
-    case SHT_PROGBITS:
-    case SHT_DYNAMIC:
-      /* Bits that get saved. This one is real. */
-      if (hdr->rawdata == NULL)
-       {
-         newsect = bfd_make_section_anyway (abfd, name);
-         if (newsect == NULL)
-           return false;
-
-         newsect->filepos = hdr->sh_offset;
-         newsect->flags |= SEC_HAS_CONTENTS;
-         newsect->vma = hdr->sh_addr;
-         newsect->_raw_size = hdr->sh_size;
-         newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-
-         if (hdr->sh_flags & SHF_ALLOC)
-           {
-             newsect->flags |= SEC_ALLOC;
-             newsect->flags |= SEC_LOAD;
-           }
-
-         if (!(hdr->sh_flags & SHF_WRITE))
-           newsect->flags |= SEC_READONLY;
-
-         if (hdr->sh_flags & SHF_EXECINSTR)
-           newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
-         else if (newsect->flags & SEC_ALLOC)
-           newsect->flags |= SEC_DATA;
-
-         /* The debugging sections appear to recognized only by name,
-            not any sort of flag.  */
-         if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
-             || strncmp (name, ".line", sizeof ".line" - 1) == 0
-             || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
-           newsect->flags |= SEC_DEBUGGING;
-
-         hdr->rawdata = (PTR) newsect;
-       }
-      return true;
-
-    case SHT_NOBITS:
-      /* Bits that get saved. This one is real. */
-      if (hdr->rawdata == NULL)
-       {
-         newsect = bfd_make_section_anyway (abfd, name);
-         if (newsect == NULL)
-           return false;
-
-         newsect->vma = hdr->sh_addr;
-         newsect->_raw_size = hdr->sh_size;
-         newsect->filepos = hdr->sh_offset;    /* fake */
-         newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-         if (hdr->sh_flags & SHF_ALLOC)
-           newsect->flags |= SEC_ALLOC;
-
-         if (!(hdr->sh_flags & SHF_WRITE))
-           newsect->flags |= SEC_READONLY;
-
-         /* FIXME: This section is empty.  Does it really make sense
-            to set SEC_CODE for it?  */
-         if (hdr->sh_flags & SHF_EXECINSTR)
-           newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
-
-         hdr->rawdata = (PTR) newsect;
-       }
-      return true;
+    case SHT_PROGBITS: /* Normal section with contents.  */
+    case SHT_DYNAMIC:  /* Dynamic linking information.  */
+    case SHT_NOBITS:   /* .bss section.  */
+      return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
 
     case SHT_SYMTAB:           /* A symbol table */
       if (elf_onesymtab (abfd) == shindex)
@@ -612,7 +547,7 @@ bfd_section_from_shdr (abfd, shindex)
       return true;
 
     case SHT_STRTAB:           /* A string table */
-      if (hdr->rawdata)
+      if (hdr->rawdata != NULL)
        return true;
       if (ehdr->e_shstrndx == shindex)
        {
@@ -658,48 +593,29 @@ bfd_section_from_shdr (abfd, shindex)
          }
       }
 
-      newsect = bfd_make_section_anyway (abfd, name);
-      if (newsect == NULL)
-       return false;
-
-      newsect->flags = SEC_HAS_CONTENTS;
-      hdr->rawdata = (PTR) newsect;
-      newsect->_raw_size = hdr->sh_size;
-      newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-      newsect->vma = hdr->sh_addr;
-      newsect->filepos = hdr->sh_offset;
-
-      if (hdr->sh_flags & SHF_ALLOC)
-       newsect->flags |= SEC_ALLOC | SEC_LOAD;
-      if (!(hdr->sh_flags & SHF_WRITE))
-       newsect->flags |= SEC_READONLY;
-      if (hdr->sh_flags & SHF_EXECINSTR)
-       newsect->flags |= SEC_CODE;
-      else if (newsect->flags & SEC_ALLOC)
-       newsect->flags |= SEC_DATA;
-
-      /* Check for debugging string tables.  */
-      if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
-         || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
-       newsect->flags |= SEC_DEBUGGING;
-
-      return true;
+      return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
 
     case SHT_REL:
     case SHT_RELA:
-      /* *These* do a lot of work -- but build no sections!
-        The spec says there can be multiple strtabs, but only one symtab,
-        but there can be lots of REL* sections. */
-      /* FIXME:  The above statement is wrong!  There are typically at least
-        two symbol tables in a dynamically linked executable, ".dynsym"
-        which is the dynamic linkage symbol table and ".symtab", which is
-        the "traditional" symbol table.  -fnf */
-
+      /* *These* do a lot of work -- but build no sections!  */
       {
        asection *target_sect;
        Elf_Internal_Shdr *hdr2;
        int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
 
+       /* Get the symbol table.  */
+       if (! bfd_section_from_shdr (abfd, hdr->sh_link))
+         return false;
+
+       /* If this reloc section does not use the main symbol table,
+          or if it is in the process image, we don't treat it as a
+          reloc section.  BFD can't adequately represent such a
+          section, so at least for now, we don't try.  We just
+          present it as a normal section.  */
+       if ((hdr->sh_flags & SHF_ALLOC) != 0
+           || hdr->sh_link != elf_onesymtab (abfd))
+         return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
        /* Don't allow REL relocations on a machine that uses RELA and
           vice versa.  */
        /* @@ Actually, the generic ABI does suggest that both might be
@@ -708,15 +624,13 @@ bfd_section_from_shdr (abfd, shindex)
           each of those architectures.  It's conceivable that, e.g., a
           bunch of absolute 32-bit relocs might be more compact in REL
           form even on a RELA machine...  */
-       BFD_ASSERT (!(use_rela_p && (hdr->sh_type == SHT_REL)));
-       BFD_ASSERT (!(!use_rela_p && (hdr->sh_type == SHT_RELA)));
-       BFD_ASSERT (hdr->sh_entsize ==
-                   (use_rela_p
-                    ? sizeof (Elf_External_Rela)
-                    : sizeof (Elf_External_Rel)));
-
-       if (! bfd_section_from_shdr (abfd, hdr->sh_info)     /* target */
-           || ! bfd_section_from_shdr (abfd, hdr->sh_link)) /* symbol table */
+       BFD_ASSERT (use_rela_p
+                   ? (hdr->sh_type == SHT_RELA
+                      && hdr->sh_entsize == sizeof (Elf_External_Rela))
+                   : (hdr->sh_type == SHT_REL
+                      && hdr->sh_entsize == sizeof (Elf_External_Rel)));
+
+       if (! bfd_section_from_shdr (abfd, hdr->sh_info))
          return false;
        target_sect = section_from_elf_index (abfd, hdr->sh_info);
        if (target_sect == NULL
@@ -728,7 +642,7 @@ bfd_section_from_shdr (abfd, shindex)
        elf_elfsections (abfd)[shindex] = hdr2;
        target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize;
        target_sect->flags |= SEC_RELOC;
-       target_sect->relocation = 0;
+       target_sect->relocation = NULL;
        target_sect->rel_filepos = hdr->sh_offset;
        abfd->flags |= HAS_RELOC;
        return true;
index 5d53f88..25d56b0 100644 (file)
@@ -453,7 +453,8 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
                                                            char **));
 extern boolean bfd_elf_mkobject PARAMS ((bfd *));
 extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
-
+extern boolean _bfd_elf_make_section_from_shdr
+  PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name));
 extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
   PARAMS ((bfd *));