This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: Add -munwind-check=[none|warning|error]
On Fri, Feb 11, 2005 at 10:45:11AM -0800, H. J. Lu wrote:
> 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.
>
>
Here is a small update. I modified the comments for ia64_init. I am
working on a patch which needs to set a new default option in md.
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 10:51:56.872522083 -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:54:33.968190713 -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,10 +7189,9 @@ 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
- default endianness. */
+/* Set the default options in md. Cannot do this in md_begin because
+ that is called after md_parse_option which is where we set the
+ options in md based on command line options. */
void
ia64_init (argc, argv)
@@ -7137,6 +7199,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 10:51:56.883520660 -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 10:51:56.883520660 -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:51:56.884520530 -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"
}