* Reduce useless symbols for ELF in an attempt to make smaller
authorJeff Law <law@redhat.com>
Mon, 19 Dec 1994 21:23:20 +0000 (21:23 +0000)
committerJeff Law <law@redhat.com>
Mon, 19 Dec 1994 21:23:20 +0000 (21:23 +0000)
objects and speed up the linker.
* config/tc-hppa.c (struct call_info): Replace end_symbol field
with a size field.
(hppa_elf_mark_end_function): Delete unneeded function.
(pa_build_unwind_subspace): For the 2nd unwind relocation, use
the function symbol + function size instead of a special symbol
for the end of the function.
(process_exit): Compute the function size here.  Don't call
hppa_elf_mark_end_of_function anymore.
(pa_procend): Likewise.
(hppa_fix_adjustable): Only reject 32bit relocations for SOM.
(elf_hppa_final_processing): Simplify.

gas/ChangeLog
gas/config/tc-hppa.c

index 98fa1044b17a5da5bd40cd6a8773f7d04c660b12..eedb5bba39cb6335597dfb4b54c76f37d05dd48e 100644 (file)
@@ -1,3 +1,19 @@
+Mon Dec 19 14:15:07 1994  Jeff Law  (law@snake.cs.utah.edu)
+
+       * Reduce useless symbols for ELF in an attempt to make smaller
+       objects and speed up the linker.
+       * config/tc-hppa.c (struct call_info): Replace end_symbol field
+       with a size field.
+       (hppa_elf_mark_end_function): Delete unneeded function.
+       (pa_build_unwind_subspace): For the 2nd unwind relocation, use
+       the function symbol + function size instead of a special symbol
+       for the end of the function.
+       (process_exit): Compute the function size here.  Don't call 
+       hppa_elf_mark_end_of_function anymore.
+       (pa_procend): Likewise.
+       (hppa_fix_adjustable): Only reject 32bit relocations for SOM.
+       (elf_hppa_final_processing): Simplify.
+
 start-sanitize-arc
 Mon Dec 19 12:57:09 1994  Doug Evans  <dje@canuck.cygnus.com>
 
index c1ec189b140e7226cd3079ddf2cf93faa3e62059..4c5fd7335044041224f2b09372391d9f82dbfbc9 100644 (file)
@@ -145,8 +145,8 @@ struct call_info
     /* Name of this function.  */
     symbolS *start_symbol;
 
-    /* (temporary) symbol used to mark the end of this function.  */
-    symbolS *end_symbol;
+    /* Size of the function in bytes.  */
+    unsigned long function_size;
 
     /* Next entry in the chain.  */
     struct call_info *ci_next;
@@ -451,6 +451,7 @@ struct selector_entry
 
 /* Prototypes for functions local to tc-hppa.c.  */
 
+static void pa_check_current_space_and_subspace PARAMS ((void));
 static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
 static void pa_cons PARAMS ((int));
 static void pa_data PARAMS ((int));
@@ -539,7 +540,6 @@ static int log2 PARAMS ((int));
 static int pa_next_subseg PARAMS ((sd_chain_struct *));
 static unsigned int pa_stringer_aux PARAMS ((char *));
 static void pa_spaces_begin PARAMS ((void));
-static void hppa_elf_mark_end_of_function PARAMS ((void));
 
 /* File and gloally scoped variable declarations.  */
 
@@ -1058,6 +1058,31 @@ static struct default_space_dict pa_def_spaces[] =
 
 /* Actual functions to implement the PA specific code for the assembler.  */
 
+/* Called before writing the object file.  Make sure entry/exit and
+   proc/procend pairs match.  */
+
+void
+pa_check_eof ()
+{
+  if (within_entry_exit)
+    as_fatal ("Missing .exit\n");
+
+  if (within_procedure)
+    as_fatal ("Missing .procend\n");
+}
+
+/* Check to make sure we have a valid space and subspace.  */
+
+static void
+pa_check_current_space_and_subspace ()
+{
+  if (current_space == NULL)
+    as_fatal ("Not in a space.\n");
+
+  if (current_subspace == NULL)
+    as_fatal ("Not in a subspace.\n");
+}
+
 /* Returns a pointer to the label_symbol_struct for the current space.
    or NULL if no label_symbol_struct exists for the current space.  */
 
@@ -1367,6 +1392,9 @@ pa_ip (str)
   unsigned long opcode;
   struct pa_opcode *insn;
 
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   /* Skip to something interesting.  */
   for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
     ;
@@ -2568,15 +2596,7 @@ tc_gen_reloc (section, fixp)
 
       reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
       reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
-      /* Ugh.  Yet another case where the generic ELF code's
-        handling of section vmas makes life a living hell.
-
-        The generic ELF code will subtract out section->vma from
-        the relocation offset before the relocs are written.  So
-        we have to add section->vma into the offset here so the
-        net sum is zero.  */
-      reloc->address = (fixp->fx_frag->fr_address + fixp->fx_where
-                       + section->vma);
+      reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
       reloc->addend = 0;       /* default */
 
       assert (reloc->howto && code == reloc->howto->type);
@@ -3856,6 +3876,9 @@ pa_parse_neg_add_cmpltr (s, isbranch)
 static void
 pa_align (bytes)
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   /* Let the generic gas code do most of the work.  */
   s_align_bytes (bytes);
 
@@ -3876,6 +3899,9 @@ pa_block (z)
   unsigned int temp_size;
   int i;
 
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   temp_size = get_absolute_expression ();
 
   /* Always fill with zeros, that's what the HP assembler does.  */
@@ -3906,6 +3932,9 @@ static void
 pa_call (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   pa_call_args (&last_call_desc);
   demand_empty_rest_of_line ();
 }
@@ -4025,7 +4054,8 @@ pa_build_unwind_subspace (call_info)
 
   /* Relocation info. for end offset of the function.  */
   fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
-               call_info->end_symbol, (offsetT) 0,
+               call_info->start_symbol,
+               call_info->function_size,
                (expressionS *) NULL, 0, R_PARISC_DIR32, e_fsel, 32, 0, NULL);
 
   /* Dump it. */
@@ -4054,6 +4084,9 @@ pa_callinfo (unused)
   char *name, c, *p;
   int temp;
 
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   /* .CALLINFO must appear within a procedure definition.  */
   if (!within_procedure)
     as_bad (".callinfo is not within a procedure definition");
@@ -4189,24 +4222,11 @@ static void
 pa_code (unused)
      int unused;
 {
-  sd_chain_struct *sdchain;
-
-  /* First time through it might be necessary to create the
-     $TEXT$ space.  */
-  if ((sdchain = is_defined_space ("$TEXT$")) == NULL)
-    {
-      sdchain = create_new_space (pa_def_spaces[0].name,
-                                 pa_def_spaces[0].spnum,
-                                 pa_def_spaces[0].loadable,
-                                 pa_def_spaces[0].defined,
-                                 pa_def_spaces[0].private,
-                                 pa_def_spaces[0].sort,
-                                 pa_def_spaces[0].segment, 0);
-    }
-
-  SPACE_DEFINED (sdchain) = 1;
-  subseg_set (text_section, SUBSEG_CODE);
-  demand_empty_rest_of_line ();
+  current_space = is_defined_space ("$TEXT$");
+  current_subspace
+    = pa_subsegment_to_subspace (current_space->sd_seg, 0);
+  s_text (0);
+  pa_undefine_label ();
 }
 
 /* This is different than the standard GAS s_comm(). On HP9000/800 machines,
@@ -4279,6 +4299,9 @@ static void
 pa_enter (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   abort ();
 }
 
@@ -4288,6 +4311,9 @@ static void
 pa_entry (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   if (!within_procedure)
     as_bad ("Misplaced .entry. Ignored.");
   else
@@ -4361,11 +4387,13 @@ process_exit ()
 
   where = frag_more (0);
 
+  last_call_info->function_size
+    = where - frag_now->fr_literal - S_GET_VALUE (last_call_info->start_symbol);
+
 #ifdef OBJ_ELF
   /* Mark the end of the function, stuff away the location of the frag
      for the end of the function, and finally call pa_build_unwind_subspace
      to add an entry in the unwind table.  */
-  hppa_elf_mark_end_of_function ();
   pa_build_unwind_subspace (last_call_info);
 #else
   /* SOM defers building of unwind descriptors until the link phase.
@@ -4390,6 +4418,9 @@ static void
 pa_exit (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   if (!within_procedure)
     as_bad (".EXIT must appear within a procedure");
   else
@@ -4678,6 +4709,9 @@ static void
 pa_leave (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   abort ();
 }
 
@@ -4687,6 +4721,9 @@ static void
 pa_origin (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   s_org (0);
   pa_undefine_label ();
 }
@@ -4734,6 +4771,10 @@ pa_proc (unused)
      int unused;
 {
   struct call_info *call_info;
+
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   if (within_procedure)
     as_fatal ("Nested procedures");
 
@@ -4798,6 +4839,9 @@ pa_procend (unused)
      int unused;
 {
 
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   /* If we are within a procedure definition, make sure we've
      defined a label for the procedure; handle case where the
      label was defined after the .PROC directive.
@@ -4845,12 +4889,8 @@ pa_procend (unused)
   if (within_entry_exit)
     as_bad ("Missing .EXIT for a .ENTRY");
 
-#ifdef OBJ_ELF
-  /* ELF needs to mark the end of each function so that it can compute
-     the size of the function (apparently its needed in the symbol table).  */
-  hppa_elf_mark_end_of_function ();
-#endif
-
+  last_call_info->function_size
+    = frag_more (0) - frag_now->fr_literal - S_GET_VALUE (last_call_info->start_symbol);
   within_procedure = FALSE;
   demand_empty_rest_of_line ();
   pa_undefine_label ();
@@ -5159,6 +5199,9 @@ pa_subspace (unused)
   ssd_chain_struct *ssd;
   asection *section;
 
+  if (current_space == NULL)
+    as_fatal ("Must be in a space before changing or declaring subspaces.\n");
+
   if (within_procedure)
     {
       as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
@@ -5861,6 +5904,10 @@ pa_stringer_aux (s)
      char *s;
 {
   unsigned int c = *s & CHAR_MASK;
+
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   switch (c)
     {
     case '\"':
@@ -6009,6 +6056,9 @@ static void
 pa_fill (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   s_fill (0);
   pa_undefine_label ();
 }
@@ -6019,6 +6069,9 @@ static void
 pa_lcomm (needs_align)
      int needs_align;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   s_lcomm (needs_align);
   pa_undefine_label ();
 }
@@ -6029,6 +6082,9 @@ static void
 pa_lsym (unused)
      int unused;
 {
+  /* We must have a valid space and subspace.  */
+  pa_check_current_space_and_subspace ();
+
   s_lsym (0);
   pa_undefine_label ();
 }
@@ -6082,9 +6138,11 @@ hppa_fix_adjustable (fixp)
 
   hppa_fix = (struct hppa_fix_struct *) fixp->tc_fix_data;
 
-  /* Reject reductions of symbols in 32bit plabel relocs.  */
+#ifdef OBJ_SOM
+  /* Reject reductions of symbols in 32bit relocs.  */
   if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
     return 0;
+#endif
 
   /* Reject reductions of symbols in DLT relative relocs.  */
   if (hppa_fix->fx_r_field == e_tsel
@@ -6139,66 +6197,8 @@ hppa_force_relocation (fixp)
 
 /* Now for some ELF specific code.  FIXME.  */
 #ifdef OBJ_ELF
-/* Mark the end of a function so that it's possible to compute
-   the size of the function in hppa_elf_final_processing.  */
-
-static void
-hppa_elf_mark_end_of_function ()
-{
-  /* ELF does not have EXIT relocations.  All we do is create a
-     temporary symbol marking the end of the function.  */
-  char *name = (char *)
-    xmalloc (strlen ("L$\001end_") +
-            strlen (S_GET_NAME (last_call_info->start_symbol)) + 1);
-
-  if (name)
-    {
-      symbolS *symbolP;
-
-      strcpy (name, "L$\001end_");
-      strcat (name, S_GET_NAME (last_call_info->start_symbol));
-
-      /* If we have a .exit followed by a .procend, then the
-        symbol will have already been defined.  */
-      symbolP = symbol_find (name);
-      if (symbolP)
-       {
-         /* The symbol has already been defined!  This can
-            happen if we have a .exit followed by a .procend.
-
-            This is *not* an error.  All we want to do is free
-            the memory we just allocated for the name and continue.  */
-         xfree (name);
-       }
-      else
-       {
-         /* symbol value should be the offset of the
-            last instruction of the function */
-         symbolP = symbol_new (name, now_seg,
-                               (valueT) (obstack_next_free (&frags)
-                                         - frag_now->fr_literal - 4),
-                               frag_now);
-
-         assert (symbolP);
-         symbolP->bsym->flags = BSF_LOCAL;
-         symbol_table_insert (symbolP);
-       }
-
-      if (symbolP)
-       last_call_info->end_symbol = symbolP;
-      else
-       as_bad ("Symbol '%s' could not be created.", name);
-
-    }
-  else
-    as_bad ("No memory for symbol name.");
-
-}
-
 /* For ELF, this function serves one purpose:  to setup the st_size
-   field of STT_FUNC symbols.  To do this, we need to scan the
-   call_info structure list, determining st_size in by taking the
-   difference in the address of the beginning/end marker symbols.  */
+   field of STT_FUNC symbols.  */
 
 void
 elf_hppa_final_processing ()
@@ -6211,9 +6211,7 @@ elf_hppa_final_processing ()
     {
       elf_symbol_type *esym
       = (elf_symbol_type *) call_info_pointer->start_symbol->bsym;
-      esym->internal_elf_sym.st_size =
-       S_GET_VALUE (call_info_pointer->end_symbol)
-       - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
+      esym->internal_elf_sym.st_size = call_info_pointer->function_size;
     }
 }
 #endif