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]
Other format: [Raw text]

Re: PATCH: Add -munwind-check=[none|warning|error]


On Thu, Feb 10, 2005 at 06:30:17PM -0800, James E Wilson wrote:
> On Thu, 2005-02-10 at 09:29, H. J. Lu wrote:
> > Here is the updated patch to add -munwind-check=[none|warning|error].
> > I documented this new option.
> 
> My feeling on this issue in general that we should be emitting a
> diagnostic here always.  This new code is finding latent bugs in the
> unwind info.  This is a correctness issue.  If we let the latent bugs
> through, then they will only be found if an exception is generated and
> the stack unwound, at which point it is far too late to recover from the
> mistake.  This makes it very important for the assembler to give a
> diagnostic when we find a problem.  I can live with this being a warning
> for now, to avoid compatibility problems, but it really is important
> that people fix their code if they want it to work correctly.
> 

Here is the new patch. I removed the -munwind-check=none option. I also
included the patch for the .endp check. IAS does ignore the name
after .endp. But checking it is a good idea. People will get a
warning unless they fix the code.


H.J.
----
gas/

2005-02-11  H.J. Lu  <hongjiu.lu@intel.com>

	* NEWS: Mention "-munwind-check=[warning|error]".

	* config/tc-ia64.c (md): Add unwind_check.
	(unwind_diagnostic): New.
	(in_procedure): Call unwind_diagnostic when a directive isn't
	in procedure.
	(in_prologue): Call unwind_diagnostic when a directive isn't in
	prologue.
	(in_body): Call unwind_diagnostic when a directive isn't in
	body region.
	(dot_endp): Set md.unwind_check to error before calling
	in_procedure and restore it after. When the name is missing or
	couldn't be found, use the one from the last .proc if
	md.unwind_check isn't error. Warn if md.unwind_check is
	warning.
	(md_parse_option): Handle "-munwind-check=[warning|error]".
	(md_show_usage): Add "-munwind-check=[warning|error]".
	(ia64_init): Set md.unwind_check to warning.

	* doc/as.texinfo: Add "-munwind-check=[none|warning|error]".
	* doc/c-ia64.texi: Likewise.

gas/testcase

2005-02-11  H.J. Lu  <hongjiu.lu@intel.com>

	* gas/ia64/ia64.exp: Pass -munwind-check=error for unwind-err
	and proc.

--- gas/NEWS.check	2004-12-10 14:20:32.000000000 -0800
+++ gas/NEWS	2005-02-11 09:39:54.396270244 -0800
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* New command line option -munwind-check=[warning|error] for IA64
+  targets.
+
 * Port to MAXQ processor contributed by HCL Tech.
 
 * Added support for generating unwind tables for ARM ELF targets.
--- gas/config/tc-ia64.c.check	2005-02-11 09:20:08.000000000 -0800
+++ gas/config/tc-ia64.c	2005-02-11 10:40:59.035659535 -0800
@@ -231,6 +231,13 @@ static struct
       auto_align : 1,
       keep_pending_output : 1;
 
+    /* What to do when something is wrong with unwind directives.  */
+    enum
+      {
+	unwind_check_warning,
+	unwind_check_error
+      } unwind_check;
+
     /* Each bundle consists of up to three instructions.  We keep
        track of four most recent instructions so we can correctly set
        the end_of_insn_group for the last instruction in a bundle.  */
@@ -3048,14 +3055,25 @@ dot_special_section (which)
   set_section ((char *) special_section_name[which]);
 }
 
+static void
+unwind_diagnostic (const char * region, const char *directive)
+{
+  if (md.unwind_check == unwind_check_warning)
+    as_warn (".%s outside of %s", directive, region);
+  else
+    {
+      as_bad (".%s outside of %s", directive, region);
+      ignore_rest_of_line ();
+    }
+}
+
 static int
 in_procedure (const char *directive)
 {
   if (unwind.proc_start
       && (!unwind.saved_text_seg || strcmp (directive, "endp") == 0))
     return 1;
-  as_bad (".%s outside of procedure", directive);
-  ignore_rest_of_line ();
+  unwind_diagnostic ("procedure", directive);
   return 0;
 }
 
@@ -3064,10 +3082,10 @@ in_prologue (const char *directive)
 {
   if (in_procedure (directive))
     {
+      /* We are in a procedure. Check if we are in a prologue.  */
       if (unwind.prologue)
 	return 1;
-      as_bad (".%s outside of prologue", directive);
-      ignore_rest_of_line ();
+      unwind_diagnostic ("prologue", directive);
     }
   return 0;
 }
@@ -3077,10 +3095,10 @@ in_body (const char *directive)
 {
   if (in_procedure (directive))
     {
+      /* We are in a procedure. Check if we are in a body.  */
       if (unwind.body)
 	return 1;
-      as_bad (".%s outside of body region", directive);
-      ignore_rest_of_line ();
+      unwind_diagnostic ("body region", directive);
     }
   return 0;
 }
@@ -4292,11 +4310,14 @@ dot_endp (dummy)
   long where;
   segT saved_seg;
   subsegT saved_subseg;
-  char *name, *p, c;
+  char *name, *default_name, *p, c;
   symbolS *sym;
+  int unwind_check = md.unwind_check;
 
+  md.unwind_check = unwind_check_error;
   if (!in_procedure ("endp"))
     return;
+  md.unwind_check = unwind_check;
 
   if (unwind.saved_text_seg)
     {
@@ -4368,6 +4389,11 @@ dot_endp (dummy)
 
   subseg_set (saved_seg, saved_subseg);
 
+  if (unwind.proc_start)
+    default_name = (char *) S_GET_NAME (unwind.proc_start);
+  else
+    default_name = NULL;
+
   /* Parse names of main and alternate entry points and set symbol sizes.  */
   while (1)
     {
@@ -4376,10 +4402,35 @@ dot_endp (dummy)
       c = get_symbol_end ();
       p = input_line_pointer;
       if (!*name)
-	as_bad ("Empty argument of .endp");
-      else
+	{
+	  if (md.unwind_check == unwind_check_warning)
+	    {
+	      if (default_name)
+		{
+		  as_warn ("Empty argument of .endp. Use the default name `%s'",
+			   default_name);
+		  name = default_name;
+		}
+	      else
+		as_warn ("Empty argument of .endp");
+	    }
+	  else
+	    as_bad ("Empty argument of .endp");
+	}
+      if (*name)
 	{
 	  sym = symbol_find (name);
+	  if (!sym
+	      && md.unwind_check == unwind_check_warning
+	      && default_name
+	      && default_name != name)
+	    {
+	      /* We have a bad name. Try the default one if needed.  */
+	      as_warn ("`%s' was not defined within procedure. Use the default name `%s'",
+		       name, default_name);
+	      name = default_name;
+	      sym = symbol_find (name);
+	    }
 	  if (!sym || !S_IS_DEFINED (sym))
 	    as_bad ("`%s' was not defined within procedure", name);
 	  else if (unwind.proc_start
@@ -6689,6 +6740,16 @@ md_parse_option (c, arg)
 	  md.flags |= EF_IA_64_BE;
 	  default_big_endian = 1;
 	}
+      else if (strncmp (arg, "unwind-check=", 13) == 0)
+	{
+	  arg += 13;
+	  if (strcmp (arg, "warning") == 0)
+	    md.unwind_check = unwind_check_warning;
+	  else if (strcmp (arg, "error") == 0)
+	    md.unwind_check = unwind_check_error;
+	  else
+	    return 0;
+	}
       else
 	return 0;
       break;
@@ -6792,6 +6853,8 @@ IA-64 options:\n\
 			  EF_IA_64_NOFUNCDESC_CONS_GP)\n\
   -milp32|-milp64|-mlp64|-mp64	select data model (default -mlp64)\n\
   -mle | -mbe		  select little- or big-endian byte order (default -mle)\n\
+  -munwind-check=[warning|error]\n\
+			  unwind directive check (default -munwind-check=warning)\n\
   -x | -xexplicit	  turn on dependency violation checking (default)\n\
   -xauto		  automagically remove dependency violations\n\
   -xdebug		  debug dependency violation checker\n"),
@@ -7126,9 +7189,10 @@ md_begin ()
   md.entry_labels = NULL;
 }
 
-/* Set the elf type to 64 bit ABI by default.  Cannot do this in md_begin
-   because that is called after md_parse_option which is where we do the
-   dynamic changing of md.flags based on -mlp64 or -milp32.  Also, set the
+/* Set the elf type to 64 bit ABI and unwind directive checking to
+   warning by default.  Cannot do this in md_begin because that is
+   called after md_parse_option which is where we do the dynamic
+   changing of md.flags based on -mlp64 or -milp32.  Also, set the
    default endianness.  */
 
 void
@@ -7137,6 +7201,8 @@ ia64_init (argc, argv)
      char **argv ATTRIBUTE_UNUSED;
 {
   md.flags = MD_FLAGS_DEFAULT;
+  /* FIXME: We should change it to unwind_check_error someday.  */
+  md.unwind_check = unwind_check_warning;
 }
 
 /* Return a string for the target object file format.  */
--- gas/doc/as.texinfo.check	2005-02-11 09:20:16.000000000 -0800
+++ gas/doc/as.texinfo	2005-02-11 09:40:10.764149990 -0800
@@ -315,6 +315,7 @@ gcc(1), ld(1), and the Info entries for 
    [@b{-mconstant-gp}|@b{-mauto-pic}]
    [@b{-milp32}|@b{-milp64}|@b{-mlp64}|@b{-mp64}]
    [@b{-mle}|@b{mbe}]
+   [@b{-munwind-check=warning}|@b{-munwind-check=error}]
    [@b{-x}|@b{-xexplicit}] [@b{-xauto}] [@b{-xdebug}]
 @end ifset
 @ifset IP2K
--- gas/doc/c-ia64.texi.check	2005-02-11 09:20:16.000000000 -0800
+++ gas/doc/c-ia64.texi	2005-02-11 09:41:16.774599159 -0800
@@ -65,6 +65,14 @@ These options select the byte order.  Th
 byte order (default) and @code{-mbe} selects big-endian byte order.  Note that
 IA-64 machine code always uses little-endian byte order.
 
+@item -munwind-check=warning
+@item -munwind-check=error
+These options control what the assembler will do when performing
+consistency checks on unwind directives.  @code{-munwind-check=warning}
+will make the assembler issue a warning when an unwind directive check
+fails.  This is the default.  @code{-munwind-check=error} will make the
+assembler issue an error when an unwind directive check fails.
+
 @item -x
 @item -xexplicit
 These options turn on dependency violation checking.  This checking is turned on by
--- gas/testsuite/gas/ia64/ia64.exp.check	2005-02-03 12:00:27.000000000 -0800
+++ gas/testsuite/gas/ia64/ia64.exp	2005-02-11 10:02:18.138205233 -0800
@@ -67,7 +67,7 @@ if [istarget "ia64-*"] then {
     run_dump_test "bundling"
     run_list_test "label" ""
     run_list_test "last" ""
-    run_list_test "proc" ""
+    run_list_test "proc" "-munwind-check=error"
     run_list_test "slot2" ""
-    run_list_test "unwind-err" ""
+    run_list_test "unwind-err" "-munwind-check=error"
 }


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