* obj-elf.c (obj_elf_stab_generic, in disabled code): If
authorKen Raeburn <raeburn@cygnus>
Wed, 4 Aug 1993 23:10:43 +0000 (23:10 +0000)
committerKen Raeburn <raeburn@cygnus>
Wed, 4 Aug 1993 23:10:43 +0000 (23:10 +0000)
debug section is new, allocate an extra 12 bytes at its start.  If
".stabs" type is N_SO, fill in filename symbol field of that first
entry.  Return early if "goof", to simplify later code slightly.
(adjust_stab_sections): New function.
(elf_frob_file): Apply adjust_stab_sections to each section.

* obj-elf.c (obj_elf_section, obj_elf_previous): No longer static.
* obj-elf.h (obj_elf_section, obj_elf_previous): Declare.
* tc-sparc.c (md_pseudo_table): Call them for "pushsection"
and "popsection", and call cons for "uaword" and "uahalf".

* obj-elf.c (obj_elf_version): Use English in error messages.

* tc-sparc.c (md_apply_fix, case BFD_RELOC_64): New case,
parallel to BFD_RELOC_32.
(tc_gen_reloc): Accept BFD_RELOC_64.

gas/config/obj-elf.c
gas/config/tc-sparc.c

index 7d99c9a97a75d46609d892d9754425c8275728a3..714ca316d49cc8a087dc19520324d13c8a5837c4 100644 (file)
@@ -27,11 +27,9 @@ static void obj_elf_xstab PARAMS ((int what));
 static void obj_elf_line PARAMS ((void));
 void obj_elf_desc PARAMS ((void));
 void obj_elf_version PARAMS ((void));
-static void obj_elf_section PARAMS ((int));
 static void obj_elf_size PARAMS ((void));
 static void obj_elf_type PARAMS ((void));
 static void obj_elf_ident PARAMS ((void));
-static void obj_elf_previous PARAMS ((void));
 
 const pseudo_typeS obj_pseudo_table[] =
 {
@@ -83,7 +81,7 @@ elf_file_symbol (s)
 static segT previous_section;
 static int previous_subsection;
 
-static void
+void
 obj_elf_section (xxx)
      int xxx;
 {
@@ -116,7 +114,10 @@ obj_elf_section (xxx)
       input_line_pointer = p;
     }
   if (!strcmp (string, ".rodata"))
-      default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC;
+    default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC;
+  else if (!strcmp (string, ".init")
+          || !strcmp (string, ".fini"))
+    default_flags = SEC_ALLOC | SEC_READONLY | SEC_RELOC | SEC_CODE;
   SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     flags = default_flags;
@@ -179,7 +180,7 @@ obj_elf_section (xxx)
   subseg_set (sec, 0);
 }
 
-static void
+void
 obj_elf_previous ()
 {
   if (previous_section == 0)
@@ -253,7 +254,10 @@ obj_elf_frob_symbol (sym, punt)
      symbolS *sym;
      int *punt;
 {
+#if 0 /* ?? The return value is ignored.  Only the value of *punt is
+        relevant.  */
   return obj_elf_write_symbol_p (sym);
+#endif
 }
 
 static void
@@ -388,6 +392,7 @@ obj_elf_stab_generic (what, secname)
   int saved_type = 0;
   int length;
   int goof = 0;
+  int seg_is_new = 0;
   long longint;
   asection *saved_seg = now_seg;
   asection *seg;
@@ -396,9 +401,9 @@ obj_elf_stab_generic (what, secname)
 #if 1
   /* This function doesn't work yet.
 
-     Actually, this function is okay, but some finalizations are needed
-     before writing the object file; that's not done yet, and the Solaris
-     linker chokes without it.
+     Actually, this function is okay, but some finalizations are
+     needed before writing the object file; that's not done yet, and
+     the Solaris linker chokes without it.
 
      In any case, this should effectively disable it for now.  */
   if (what == 's')
@@ -414,6 +419,7 @@ obj_elf_stab_generic (what, secname)
       bfd_set_section_flags (stdoutput, seg,
                             SEC_READONLY | SEC_ALLOC | SEC_RELOC);
       subseg_set (saved_seg, subseg);
+      seg_is_new = 1;
     }
 
   /*
@@ -510,36 +516,55 @@ obj_elf_stab_generic (what, secname)
        }
     }
 
-  if (!goof)
+  if (goof)
     {
-      subseg_new ((char *) seg->name, subseg);
+      ignore_rest_of_line ();
+      return;
+    }
 
-      /* Emit the stab symbol. */
-      elf_stab_symbol (symbolP, what);
+  subseg_new ((char *) seg->name, subseg);
 
-      if (what == 's' || what == 'n')
-       {
-         cons (4);
-         input_line_pointer--;
-       }
-      else
-       {
-         char *p = frag_more (4);
-         md_number_to_chars (p, 0, 0);
-       }
-      subseg_new ((char *) saved_seg->name, subseg);
+  if (seg_is_new)
+    /* allocate and discard -- filled in later */
+    (void) frag_more (12);
 
-      if ((what == 's' || what == 'n')
-         && symbolP->sy_value.X_op == O_constant)
-       {
-         /* symbol is not needed in the regular symbol table */
-         symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
-       }
+  /* Emit the stab symbol. */
+  elf_stab_symbol (symbolP, what);
 
+  if (what == 's' || what == 'n')
+    {
+      cons (4);
+      input_line_pointer--;
+    }
+  else
+    {
+      char *p = frag_more (4);
+      md_number_to_chars (p, 0, 0);
     }
 
-#ifndef NO_LISTING
-  if (listing && !goof)
+  subseg_new ((char *) saved_seg->name, subseg);
+
+  if ((what == 's' || what == 'n')
+      && symbolP->sy_value.X_op == O_constant)
+    {
+      /* symbol is not needed in the regular symbol table */
+      symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
+    }
+
+  if (what == 's' && S_GET_TYPE (symbolP) == N_SO)
+    {
+      fragS *fragp = seg_info (seg)->frchainP->frch_root;
+      while (fragp
+            && fragp->fr_address + fragp->fr_fix < 12)
+       fragp = fragp->fr_next;
+      assert (fragp != 0);
+      assert (fragp->fr_type == rs_fill);
+      assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
+      md_number_to_chars (fragp->fr_literal, (valueT) symbolP->sy_name_offset,
+                         4);
+    }
+
+  if (listing)
     switch (S_GET_TYPE (symbolP))
       {
       case N_SLINE:
@@ -550,12 +575,8 @@ obj_elf_stab_generic (what, secname)
        listing_source_file (string);
        break;
       }
-#endif
 
-  if (goof)
-    ignore_rest_of_line ();
-  else
-    demand_empty_rest_of_line ();
+  demand_empty_rest_of_line ();
 }
 
 static void
@@ -683,8 +704,8 @@ obj_elf_version ()
       subseg_new ((char *) note_secp->name, 0);
       len = strlen (name);
 
-      i_note.namesz = ((len + 1) + 3) & ~3;    /* round this to word boundary  */
-      i_note.descsz = 0;       /* no description       */
+      i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
+      i_note.descsz = 0;       /* no description */
       i_note.type = NT_VERSION;
       p = frag_more (sizeof (e_note.namesz));
       md_number_to_chars (p, (valueT) i_note.namesz, 4);
@@ -706,7 +727,7 @@ obj_elf_version ()
     }
   else
     {
-      as_bad ("Expected \"-ed string");
+      as_bad ("Expected quoted string");
     }
   demand_empty_rest_of_line ();
 }
@@ -826,15 +847,59 @@ obj_elf_ident ()
   subseg_set (old_section, old_subsection);
 }
 
+static void
+adjust_stab_sections (abfd, sec, xxx)
+     bfd *abfd;
+     asection *sec;
+     PTR xxx;
+{
+  char *name;
+  asection *strsec;
+  fragS *fragp;
+  int strsz, nsyms;
+
+  if (strncmp (".stab", sec->name, 5))
+    return;
+  if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
+    return;
+
+  name = (char *) alloca (strlen (sec->name) + 4);
+  strcpy (name, sec->name);
+  strcat (name, "str");
+  strsec = bfd_get_section_by_name (abfd, name);
+  if (strsec)
+    strsz = bfd_section_size (abfd, strsec);
+  else
+    strsz = 0;
+  nsyms = bfd_section_size (abfd, sec) / 12 - 1;
+
+  fragp = seg_info (sec)->frchainP->frch_root;
+  while (fragp
+        && fragp->fr_address + fragp->fr_fix < 12)
+    fragp = fragp->fr_next;
+  assert (fragp != 0);
+  assert (fragp->fr_type == rs_fill);
+  assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
+
+  bfd_h_put_16 (abfd, nsyms, fragp->fr_literal + 6);
+  bfd_h_put_32 (abfd, strsz, fragp->fr_literal + 8);
+}
+
 void 
 elf_frob_file ()
 {
+  bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
+
 #ifdef elf_tc_symbol
-  int i;
+  {
+    int i;
 
-  for (i = 0; i < stdoutput->symcount; i++)
-    elf_tc_symbol (stdoutput, (elf_symbol_type *) (stdoutput->outsymbols[i]), i + 1);
+    for (i = 0; i < stdoutput->symcount; i++)
+      elf_tc_symbol (stdoutput, (elf_symbol_type *) (stdoutput->outsymbols[i]),
+                    i + 1);
+  }
 #endif
+
 #ifdef elf_tc_final_processing
   elf_tc_final_processing_hook ();
 #endif
index 075308f1364ec62acb6ccf8c642e9828c85ee979..33f933324990ba6558e8f54fbf35a4fac2185da1 100644 (file)
@@ -80,9 +80,6 @@ const pseudo_typeS md_pseudo_table[] =
   {"common", s_common, 0},
   {"global", s_globl, 0},
   {"half", cons, 2},
-#ifdef OBJ_ELF
-  {"local", s_local, 0},
-#endif
   {"optim", s_ignore, 0},
   {"proc", s_proc, 0},
   {"reserve", s_reserve, 0},
@@ -94,6 +91,14 @@ const pseudo_typeS md_pseudo_table[] =
   {"xword", s_xword, 0},
 #endif
 /* end-sanitize-v9 */
+#ifdef OBJ_ELF
+  {"local", s_local, 0},
+  /* these are specific to sparc/svr4 */
+  {"pushsection", obj_elf_section, 0},
+  {"popsection", obj_elf_previous, 0},
+  {"uaword", cons, 4},
+  {"uahalf", cons, 2},
+#endif
   {NULL, 0, 0},
 };
 
@@ -1967,6 +1972,17 @@ md_apply_fix (fixP, value)
 
       /* start-sanitize-v9 */
 #ifndef NO_V9
+    case BFD_RELOC_64:
+      buf[0] = 0;
+      buf[1] = 0;
+      buf[2] = 0;
+      buf[3] = 0;
+      buf[4] = 0;
+      buf[5] = 0;
+      buf[6] = 0;
+      buf[7] = 0;
+      break;
+
     case BFD_RELOC_SPARC_11:
       if (((val > 0) && (val & ~0x7ff))
          || ((val < 0) && (~(val - 1) & ~0x7ff)))
@@ -2160,6 +2176,7 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_SPARC_BASE13:
     case BFD_RELOC_SPARC_WDISP22:
       /* start-sanitize-v9 */
+    case BFD_RELOC_64:
     case BFD_RELOC_SPARC_10:
     case BFD_RELOC_SPARC_11:
     case BFD_RELOC_SPARC_HH22:
@@ -2453,8 +2470,11 @@ md_section_align (segment, size)
      segT segment;
      valueT size;
 {
+#ifdef OBJ_AOUT
   /* Round all sects to multiple of 8 */
-  return (size + 7) & ~7;
+  size = (size + 7) & ~7;
+#endif
+  return size;
 }
 
 /* Exactly what point is a PC-relative offset relative TO?