* elfcode.h (bfd_add_to_strtab): Now static.
authorKen Raeburn <raeburn@cygnus>
Mon, 21 Jun 1993 00:53:45 +0000 (00:53 +0000)
committerKen Raeburn <raeburn@cygnus>
Mon, 21 Jun 1993 00:53:45 +0000 (00:53 +0000)
(sym_is_global): New function.
(bfd_section_from_shdr): Makr stirng tables other than for section and symbol
names as normal sections having contents.
(fix_up_strtabs): New function; fixes up ELF header fields for stab sections
with string tables associated.
(elf_write_object_contents): Map fix_up_strtabs over all BFD sections.
Reordered condition tests for symbol flags; default to local-object value
instead of global-object.

* elfcode.h (new_section_hook): Define here.

bfd/elfcode.h

index 533ad3c..3aeffe4 100644 (file)
@@ -99,6 +99,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define elf_no_info_to_howto_rel       NAME(bfd_elf,no_info_to_howto_rel)
 #define elf_get_sect_thunk             NAME(bfd_elf,get_sect_thunk)
 #define elf_hash                       NAME(bfd_elf,hash)
+#define elf_new_section_hook           NAME(bfd_elf,new_section_hook)
 
 
 #ifdef HAVE_PROCFS             /* Some core file support requires host /proc files */
@@ -571,6 +572,16 @@ DEFUN (bfd_section_from_shdr, (abfd, shindex),
       return true;
 
     case SHT_STRTAB:           /* A string table */
+      if (!strcmp (name, ".strtab") || !strcmp (name, ".shstrtab"))
+       return true;
+
+      if (!hdr->rawdata)
+       {
+         newsect = bfd_make_section (abfd, name);
+         if (newsect)
+           newsect->flags = SEC_HAS_CONTENTS;
+       }
+
       return true;
 
     case SHT_REL:
@@ -653,6 +664,15 @@ DEFUN (bfd_section_from_shdr, (abfd, shindex),
   return true;
 }
 
+boolean
+DEFUN (elf_new_section_hook, (abfd, sec),
+       bfd *abfd
+       AND asection *sec)
+{
+  sec->symbol->name = "";
+  return true;
+}
+
 static struct strtab *
 DEFUN (bfd_new_strtab, (abfd),
        bfd * abfd)
@@ -669,7 +689,7 @@ DEFUN (bfd_new_strtab, (abfd),
   return ss;
 }
 
-int
+static int
 DEFUN (bfd_add_to_strtab, (abfd, ss, str),
        bfd * abfd AND
        struct strtab *ss AND
@@ -728,8 +748,6 @@ DEFUN (bfd_shdr_from_section, (abfd, hdr, shstrtab, indx),
   asection *sect;
   int ndx;
 
-  /* figure out out to write the section name from the bfd section name. MWE */
-
   sect = abfd->sections;
   for (ndx = indx; --ndx;)
     {
@@ -1588,125 +1606,170 @@ DEFUN (elf_make_sections, (abfd, asect, obj),
   int this_section;
   int idx;
 
-  /* check if we're making a PROGBITS section... */
-  /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */
-  /* this was too strict... what *do* we want to check here? */
-  if (1)
-    {
-      Elf_Internal_Shdr *this_hdr;
-      this_section = elf_section_from_bfd_section (abfd, asect);
-      this_hdr = &thunk->i_shdrp[this_section];
+  Elf_Internal_Shdr *this_hdr;
+  this_section = elf_section_from_bfd_section (abfd, asect);
+  this_hdr = &thunk->i_shdrp[this_section];
 
-      this_hdr->sh_addr = asect->vma;
-      this_hdr->sh_size = asect->_raw_size;
-      /* contents already set by elf_set_section_contents */
+  this_hdr->sh_addr = asect->vma;
+  this_hdr->sh_size = asect->_raw_size;
+  /* contents already set by elf_set_section_contents */
 
-      if (asect->flags & SEC_RELOC)
-       {
-         /* emit a reloc section, and thus strtab and symtab... */
-         Elf_Internal_Shdr *rela_hdr;
-         Elf_Internal_Shdr *symtab_hdr;
-         Elf_External_Rela *outbound_relocas;
-         Elf_External_Rel *outbound_relocs;
-         int rela_section;
-         int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
+  if (asect->flags & SEC_RELOC)
+    {
+      /* emit a reloc section, and thus strtab and symtab... */
+      Elf_Internal_Shdr *rela_hdr;
+      Elf_Internal_Shdr *symtab_hdr;
+      Elf_External_Rela *outbound_relocas;
+      Elf_External_Rel *outbound_relocs;
+      int rela_section;
+      int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
 
-         symtab_hdr = &thunk->i_shdrp[thunk->symtab_section];
+      symtab_hdr = &thunk->i_shdrp[thunk->symtab_section];
 
-         if (thunk->symtab_section == this_section + 1)
-           rela_section = thunk->symtab_section + 2;   /* symtab + symstrtab */
-         else
-           rela_section = this_section + 1;
-         rela_hdr = &thunk->i_shdrp[rela_section];
-         rela_hdr->sh_link = thunk->symtab_section;
-         rela_hdr->sh_info = this_section;
+      if (thunk->symtab_section == this_section + 1)
+       rela_section = thunk->symtab_section + 2; /* symtab + symstrtab */
+      else
+       rela_section = this_section + 1;
+      rela_hdr = &thunk->i_shdrp[rela_section];
+      rela_hdr->sh_link = thunk->symtab_section;
+      rela_hdr->sh_info = this_section;
 
-         /* orelocation has the data, reloc_count has the count... */
-         if (use_rela_p)
+      /* orelocation has the data, reloc_count has the count... */
+      if (use_rela_p)
+       {
+         rela_hdr->sh_type = SHT_RELA;
+         rela_hdr->sh_entsize = sizeof (Elf_External_Rela);
+         rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count;
+         outbound_relocas = (Elf_External_Rela *) bfd_alloc (abfd, rela_hdr->sh_size);
+       
+         for (idx = 0; idx < asect->reloc_count; idx++)
            {
-             rela_hdr->sh_type = SHT_RELA;
-             rela_hdr->sh_entsize = sizeof (Elf_External_Rela);
-             rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count;
-             outbound_relocas = (Elf_External_Rela *) bfd_alloc (abfd, rela_hdr->sh_size);
-
-             for (idx = 0; idx < asect->reloc_count; idx++)
-               {
-                 Elf_Internal_Rela dst_rela;
-                 Elf_External_Rela *src_rela;
-                 arelent *ptr;
-
-                 ptr = asect->orelocation[idx];
-                 src_rela = outbound_relocas + idx;
-                 if (!(abfd->flags & EXEC_P))
-                   dst_rela.r_offset = ptr->address - asect->vma;
-                 else
-                   dst_rela.r_offset = ptr->address;
-
-                 dst_rela.r_info
-                   = ELF32_R_INFO (elf_symbol_from_bfd_symbol (abfd, ptr->sym_ptr_ptr),
-                                   ptr->howto->type);
-
-                 dst_rela.r_addend = ptr->addend;
-                 elf_swap_reloca_out (abfd, &dst_rela, src_rela);
-               }
-
-             rela_hdr->contents = (void *) outbound_relocas;
+             Elf_Internal_Rela dst_rela;
+             Elf_External_Rela *src_rela;
+             arelent *ptr;
+       
+             ptr = asect->orelocation[idx];
+             src_rela = outbound_relocas + idx;
+             if (!(abfd->flags & EXEC_P))
+               dst_rela.r_offset = ptr->address - asect->vma;
+             else
+               dst_rela.r_offset = ptr->address;
+       
+             dst_rela.r_info
+               = ELF32_R_INFO (elf_symbol_from_bfd_symbol (abfd, ptr->sym_ptr_ptr),
+                               ptr->howto->type);
+       
+             dst_rela.r_addend = ptr->addend;
+             elf_swap_reloca_out (abfd, &dst_rela, src_rela);
            }
-         else
-           /* REL relocations */
+
+         rela_hdr->contents = (void *) outbound_relocas;
+       }
+      else
+       /* REL relocations */
+       {
+         rela_hdr->sh_type = SHT_REL;
+         rela_hdr->sh_entsize = sizeof (Elf_External_Rel);
+         rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count;
+         outbound_relocs = (Elf_External_Rel *)
+           bfd_alloc (abfd, rela_hdr->sh_size);
+       
+         for (idx = 0; idx < asect->reloc_count; idx++)
            {
-             rela_hdr->sh_type = SHT_REL;
-             rela_hdr->sh_entsize = sizeof (Elf_External_Rel);
-             rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count;
-             outbound_relocs = (Elf_External_Rel *)
-               bfd_alloc (abfd, rela_hdr->sh_size);
+             Elf_Internal_Rel dst_rel;
+             Elf_External_Rel *src_rel;
+             arelent *ptr;
+       
+             ptr = asect->orelocation[idx];
+             src_rel = outbound_relocs + idx;
+             if (!(abfd->flags & EXEC_P))
+               dst_rel.r_offset = ptr->address - asect->vma;
+             else
+               dst_rel.r_offset = ptr->address;
+       
+             dst_rel.r_info
+               = ELF32_R_INFO (elf_symbol_from_bfd_symbol (abfd, ptr->sym_ptr_ptr),
+                               ptr->howto->type);
+       
+             elf_swap_reloc_out (abfd, &dst_rel, src_rel);
+       
+             /* Update the addend -- FIXME add 64 bit support.  */
+#ifdef DEBUG
+             fprintf (stderr, "Updating addend: 0x%.8lx = %d, this_section = %d\n",
+                      (long) ((unsigned char *) (elf_elfsections (abfd)[this_section].contents)
+                              + dst_rel.r_offset), ptr->addend, this_section);
+#endif
+       
+             bfd_put_32 (abfd, ptr->addend,
+                         (unsigned char *) (elf_elfsections (abfd)[this_section].contents)
+                         + dst_rel.r_offset);
+           }
+         rela_hdr->contents = (void *) outbound_relocs;
+       }
+    }
+  if (asect->flags & SEC_ALLOC)
+    {
+      this_hdr->sh_flags |= SHF_ALLOC;
+      if (asect->flags & SEC_LOAD)
+       {
+         /* @@ Do something with sh_type? */
+       }
+    }
+  if (!(asect->flags & SEC_READONLY))
+    this_hdr->sh_flags |= SHF_WRITE;
 
-             for (idx = 0; idx < asect->reloc_count; idx++)
-               {
-                 Elf_Internal_Rel dst_rel;
-                 Elf_External_Rel *src_rel;
-                 arelent *ptr;
+  if (asect->flags & SEC_CODE)
+    this_hdr->sh_flags |= SHF_EXECINSTR;
+}
 
-                 ptr = asect->orelocation[idx];
-                 src_rel = outbound_relocs + idx;
-                 if (!(abfd->flags & EXEC_P))
-                   dst_rel.r_offset = ptr->address - asect->vma;
-                 else
-                   dst_rel.r_offset = ptr->address;
+static void
+fix_up_strtabs (abfd, asect, obj)
+     bfd *abfd;
+     asection *asect;
+     PTR obj;
+{
+  int this_section = elf_section_from_bfd_section (abfd, asect);
+  elf_sect_thunk *thunk = (elf_sect_thunk *) obj;
+  Elf_Internal_Shdr *this_hdr = &thunk->i_shdrp[this_section];
 
-                 dst_rel.r_info
-                   = ELF32_R_INFO (elf_symbol_from_bfd_symbol (abfd, ptr->sym_ptr_ptr),
-                                   ptr->howto->type);
+  /* @@ Check flags!  */
+  if (!strncmp (asect->name, ".stab", 5)
+      && strcmp ("str", asect->name + strlen (asect->name) - 3))
+    {
+      asection *s;
+      char strtab[100];                /* @@ fixed size buffer -- eliminate */
+      int stridx;
 
-                 elf_swap_reloc_out (abfd, &dst_rel, src_rel);
+      strcpy (strtab, asect->name);
+      strcat (strtab, "str");
 
-                 /* Update the addend -- FIXME add 64 bit support.  */
-#ifdef DEBUG
-                 fprintf (stderr, "Updating addend: 0x%.8lx = %d, this_section = %d\n",
-                          (long) ((unsigned char *) (elf_elfsections (abfd)[this_section].contents)
-                           + dst_rel.r_offset), ptr->addend, this_section);
-#endif
+      s = bfd_get_section_by_name (abfd, strtab);
+      fprintf (stderr, "`%s' -> 0x%x\n", strtab, s);
+      if (s)
+       {
+         Elf_Internal_Shdr *s2 = thunk->i_shdrp;
 
-                 bfd_put_32 (abfd, ptr->addend,
-                             (unsigned char *) (elf_elfsections (abfd)[this_section].contents)
-                             + dst_rel.r_offset);
-               }
-             rela_hdr->contents = (void *) outbound_relocs;
+         for (stridx = 0; /* ?? */; s2++, stridx++)
+           {
+             if (!strcmp (strtab, s2->sh_name + elf_shstrtab (abfd)->tab))
+               break;
            }
        }
-      if (asect->flags & SEC_ALLOC)
+      else
        {
-         this_hdr->sh_flags |= SHF_ALLOC;
-         if (asect->flags & SEC_LOAD)
+         asection *s2 = abfd->sections;
+         stridx = 0;
+         fprintf (stderr, " not in:");
+         while (s2)
            {
-             /* @@ Do something with sh_type? */
+             fprintf (stderr, " %s", s2->name);
+             s2 = s2->next;
            }
+         fprintf (stderr, "\n");
        }
-      if (!(asect->flags & SEC_READONLY))
-       this_hdr->sh_flags |= SHF_WRITE;
-
-      if (asect->flags & SEC_CODE)
-       this_hdr->sh_flags |= SHF_EXECINSTR;
+      this_hdr->sh_link = stridx;
+      /* @@ Assuming 32 bits!  */
+      this_hdr->sh_entsize = 0xc;
     }
 }
 
@@ -1853,6 +1916,25 @@ DEFUN (bfd_elf_locate_sh, (abfd, strtab, shdrp, name),
 /* Map symbol from it's internal number to the external number, moving
    all local symbols to be at the head of the list.  */
 
+static INLINE int
+sym_is_global (sym)
+     asymbol *sym;
+{
+  if (sym->flags & BSF_GLOBAL)
+    {
+      if (sym->flags & BSF_LOCAL)
+       abort ();
+      return 1;
+    }
+  if (sym->section == &bfd_und_section)
+    return 1;
+  if (bfd_is_com_section (sym->section))
+    return 1;
+  if (sym->flags & (BSF_LOCAL | BSF_SECTION_SYM | BSF_FILE))
+    return 0;
+  return 0;
+}
+
 static boolean
 DEFUN (elf_map_symbols, (abfd), bfd * abfd)
 {
@@ -1915,8 +1997,7 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
   /* Identify and classify all of the symbols.  */
   for (idx = 0; idx < symcount; idx++)
     {
-      flags = syms[idx]->flags;
-      if (flags & (BSF_LOCAL | BSF_SECTION_SYM | BSF_FILE))
+      if (!sym_is_global (syms[idx]))
        num_locals++;
       else
        num_globals++;
@@ -1926,8 +2007,7 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
      dummy symbol.  */
   for (idx = 0; idx < symcount; idx++)
     {
-      flags = syms[idx]->flags;
-      if (flags & (BSF_LOCAL | BSF_SECTION_SYM | BSF_FILE))
+      if (!sym_is_global (syms[idx]))
        symtab_map[idx] = 1 + num_locals2++;
       else
        symtab_map[idx] = 1 + num_locals + num_globals2++;
@@ -2309,6 +2389,7 @@ DEFUN (elf_write_object_contents, (abfd), bfd * abfd)
   est.symtab_section = elf_onesymtab (abfd);   /* filled in by elf_fake */
 
   bfd_map_over_sections (abfd, elf_make_sections, &est);
+  bfd_map_over_sections (abfd, fix_up_strtabs, &est);
 
   /* Dump out the symtabs. */
   {
@@ -2360,35 +2441,32 @@ DEFUN (elf_write_object_contents, (abfd), bfd * abfd)
 
        sym.st_size = (Elf32_Word) (elf_symbol_from (abfd, syms[idx]))->internal_elf_sym.st_size;
 
-       if (syms[idx]->flags & BSF_WEAK)
+       if (syms[idx]->section == &bfd_und_section
+           || bfd_is_com_section (syms[idx]->section))
+         sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE);
+       else if (syms[idx]->flags & BSF_WEAK)
          sym.st_info = ELF_ST_INFO (STB_WEAK, STT_OBJECT);
-       else if (syms[idx]->flags & BSF_LOCAL)
-         {
-           if (syms[idx]->flags & BSF_FUNCTION)
-             sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
-           else
-             sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT);
-         }
-       else if (syms[idx]->flags & BSF_GLOBAL)
+       else if (syms[idx]->flags & BSF_SECTION_SYM)
+         sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
+       else if (syms[idx]->flags & BSF_FILE)
+         sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+       else if (syms[idx]->flags & (BSF_GLOBAL | BSF_EXPORT))
          {
            if (syms[idx]->flags & BSF_FUNCTION)
              sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
            else
              sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
          }
-       else if (syms[idx]->flags & BSF_EXPORT)
+       else if (syms[idx]->flags & BSF_LOCAL)
          {
            if (syms[idx]->flags & BSF_FUNCTION)
-             sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
+             sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
            else
-             sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
+             sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT);
          }
-       else if (syms[idx]->flags & BSF_SECTION_SYM)
-         sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-       else if (syms[idx]->flags & BSF_FILE)
-         sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
        else
-         sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
+         /* Default to local if flag isn't set at all.  */
+         sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT);
 
        sym.st_other = 0;
        if (syms[idx]->section)