This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Set STT_FUNC symbol sizes in .endp directive on IA-64


Hi!

Although I cannot see clear word on it in IA-64 Assembly Reference Guide,
.size is never used there for functions, so I guess .endp should set at
least default symbol sizes.
The following patch implements this, but sizes from .endp have lower
priority than explicit .size wherever it appears (if you think .endp should
have the same priority, it is a one-line change).

2001-08-23  Jakub Jelinek  <jakub@redhat.com>

	* config/tc-ia64.c (dot_endp): Set function symbol sizes.
	* config/obj-elf.c (obj_elf_size): When size is constant, free
	and clear symbol_get_obj(sym)->size if any.

--- gas/config/tc-ia64.c.jj	Mon Aug 13 13:05:37 2001
+++ gas/config/tc-ia64.c	Thu Aug 23 13:01:57 2001
@@ -3841,6 +3841,8 @@ dot_endp (dummy)
   segT saved_seg;
   subsegT saved_subseg;
   const char *sec_name, *text_name;
+  char *name, *p, c;
+  symbolS *sym;
 
   if (unwind.saved_text_seg)
     {
@@ -3897,9 +3899,6 @@ dot_endp (dummy)
   if (strcmp (text_name, ".text") == 0)
     text_name = "";
 
-  expression (&e);
-  demand_empty_rest_of_line ();
-
   insn_group_break (1, 0, 0);
 
   /* If there wasn't a .handlerdata, we haven't generated an image yet.  */
@@ -3955,6 +3954,50 @@ dot_endp (dummy)
 
     }
   subseg_set (saved_seg, saved_subseg);
+
+  /* Parse names of main and alternate entry points and set symbol sizes.  */
+  while (1)
+    {
+      SKIP_WHITESPACE ();
+      name = input_line_pointer;
+      c = get_symbol_end ();
+      p = input_line_pointer;
+      sym = symbol_find (name);
+      if (sym && unwind.proc_start
+	  && (symbol_get_bfdsym (sym)->flags & BSF_FUNCTION)
+	  && S_GET_SIZE (sym) == 0 && symbol_get_obj (sym)->size == NULL)
+	{
+	  fragS *fr = symbol_get_frag (unwind.proc_start);
+	  fragS *frag = symbol_get_frag (sym);
+
+	  /* Check whether the function label is at or beyond last
+	     .proc directive.  */
+	  while (fr && fr != frag)
+	    fr = fr->fr_next;
+	  if (fr)
+	    {
+	      if (frag == frag_now && SEG_NORMAL (now_seg))
+		S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym));
+	      else
+		{
+		  symbol_get_obj (sym)->size =
+		    (expressionS *) xmalloc (sizeof (expressionS));
+		  symbol_get_obj (sym)->size->X_op = O_subtract;
+		  symbol_get_obj (sym)->size->X_add_symbol
+		    = symbol_new (FAKE_LABEL_NAME, now_seg,
+				  frag_now_fix (), frag_now);
+		  symbol_get_obj (sym)->size->X_op_symbol = sym;
+		  symbol_get_obj (sym)->size->X_add_number = 0;
+		}
+	    }
+	}
+      *p = c;
+      SKIP_WHITESPACE ();
+      if (*input_line_pointer != ',')
+	break;
+      ++input_line_pointer;
+    }
+  demand_empty_rest_of_line ();
   unwind.proc_start = unwind.proc_end = unwind.info = 0;
 }
 
--- gas/config/obj-elf.c.jj	Mon Aug 13 13:05:36 2001
+++ gas/config/obj-elf.c	Thu Aug 23 13:06:46 2001
@@ -1453,7 +1453,14 @@ obj_elf_size (ignore)
   sym = symbol_find_or_make (name);
   *p = c;
   if (exp.X_op == O_constant)
-    S_SET_SIZE (sym, exp.X_add_number);
+    {
+      S_SET_SIZE (sym, exp.X_add_number);
+      if (symbol_get_obj (sym)->size)
+	{
+	  xfree (symbol_get_obj (sym)->size);
+	  symbol_get_obj (sym)->size = NULL;
+	}
+    }
   else
     {
       symbol_get_obj (sym)->size =

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]