Run write_object_file after errors
authorAlan Modra <amodra@gmail.com>
Mon, 16 Jun 2014 01:34:04 +0000 (11:04 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 16 Jun 2014 03:04:45 +0000 (12:34 +0930)
This is to fix unitialised memory access when printing listings.
Many targets don't initialise parts of insn frags or data frags that
have fixups, relying on md_apply_fix to finalise the frag.  Which is
fine normally, but means we need to run write_object_file after
errors, for listings.  Otherwise MALLOC_PERTURB_=1 causes errors like:
x86_64-linux  +FAIL: i386 mpx-inval-1
x86_64-linux  +FAIL: i386 inval-equ-1
x86_64-linux  +FAIL: i386 x86-64-mpx-inval-1

Running write_object_file after errors requires some tweaking to the
testsuite, since we then get extra errors reported from md_apply_fix.

gas/
* write.h (subsegs_finish): Delete declaration.
* write.c (subsegs_finish): Make static.
(write_object_file): Call subsegs_finish from here.  Don't print
warning and error count here..
* as.c (main): ..do so here instead.  Remove dead code for "no
object file generated".  Split out count strings to better support
internationalisation.  Don't call subsegs_finish. Tidy setting of
"keep_it".  Run write_object_file even after errors.
(keep_it): Make static.
* config/obj-elf.c (elf_frob_symbol): Remove assert.
(elf_frob_file_before_adjust): Likewise.
gas/testsuite/
* gas/elf/bad-group.s: Use %function.
* gas/elf/bad-group.err: Expect correct line number.  Allow
other errors.
* gas/elf/bad-size.err: Allow other errors.  Match expected
error somewhat more rigorously.
* gas/i386/reloc32.l: Allow other errors.
* gas/i386/mpx-inval-1.l: Match applied relocs.
* gas/i386/x86-64-mpx-inval-1.l: Likewise, and nop padding.
* gas/i386/x86-64-mpx-inval-2.l: Match nop padding, and allow
other errors.
* gas/macros/dot.s: Use .balign.
* gas/macros/dot.l: Update alignment output.
* gas/symver/symver6.l: Allow other errors.

16 files changed:
gas/ChangeLog
gas/as.c
gas/config/obj-elf.c
gas/testsuite/ChangeLog
gas/testsuite/gas/elf/bad-group.err
gas/testsuite/gas/elf/bad-group.s
gas/testsuite/gas/elf/bad-size.err
gas/testsuite/gas/i386/mpx-inval-1.l
gas/testsuite/gas/i386/reloc32.l
gas/testsuite/gas/i386/x86-64-mpx-inval-1.l
gas/testsuite/gas/i386/x86-64-mpx-inval-2.l
gas/testsuite/gas/macros/dot.l
gas/testsuite/gas/macros/dot.s
gas/testsuite/gas/symver/symver6.l
gas/write.c
gas/write.h

index 8f1aec1..e62969c 100644 (file)
@@ -1,5 +1,19 @@
 2014-06-16  Alan Modra  <amodra@gmail.com>
 
+       * write.h (subsegs_finish): Delete declaration.
+       * write.c (subsegs_finish): Make static.
+       (write_object_file): Call subsegs_finish from here.  Don't print
+       warning and error count here..
+       * as.c (main): ..do so here instead.  Remove dead code for "no
+       object file generated".  Split out count strings to better support
+       internationalisation.  Don't call subsegs_finish. Tidy setting of
+       "keep_it".  Run write_object_file even after errors.
+       (keep_it): Make static.
+       * config/obj-elf.c (elf_frob_symbol): Remove assert.
+       (elf_frob_file_before_adjust): Likewise.
+
+2014-06-16  Alan Modra  <amodra@gmail.com>
+
        * config/tc-dlx.c (machine_ip): Move initialisation of the_insn
        earlier.
 
index 752af64..32459a8 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -97,7 +97,7 @@ int debug_memory = 0;
 int verbose = 0;
 
 /* Keep the output file.  */
-int keep_it = 0;
+static int keep_it = 0;
 
 segT reg_section;
 segT expr_section;
@@ -1283,20 +1283,45 @@ main (int argc, char ** argv)
      directives from the user or by the backend, emit it now.  */
   cfi_finish ();
 
-  if (seen_at_least_1_file ()
-      && (flag_always_generate_output || had_errors () == 0))
-    keep_it = 1;
-  else
-    keep_it = 0;
+  keep_it = 0;
+  if (seen_at_least_1_file ())
+    {
+      int n_warns, n_errs;
+      char warn_msg[50];
+      char err_msg[50];
+
+      write_object_file ();
+
+      n_warns = had_warnings ();
+      n_errs = had_errors ();
+
+      if (n_warns == 1)
+       sprintf (warn_msg, _("%d warning"), n_warns);
+      else
+       sprintf (warn_msg, _("%d warnings"), n_warns);
+      if (n_errs == 1)
+       sprintf (err_msg, _("%d error"), n_errs);
+      else
+       sprintf (err_msg, _("%d errors"), n_errs);
 
-  /* This used to be done at the start of write_object_file in
-     write.c, but that caused problems when doing listings when
-     keep_it was zero.  This could probably be moved above md_end, but
-     I didn't want to risk the change.  */
-  subsegs_finish ();
+      if (flag_fatal_warnings && n_warns != 0)
+       {
+         if (n_errs == 0)
+           as_bad (_("%s, treating warnings as errors"), warn_msg);
+         n_errs += n_warns;
+       }
 
-  if (keep_it)
-    write_object_file ();
+      if (n_errs == 0)
+       keep_it = 1;
+      else if (flag_always_generate_output)
+       {
+         /* The -Z flag indicates that an object file should be generated,
+            regardless of warnings and errors.  */
+         keep_it = 1;
+         fprintf (stderr, _("%s, %s, generating bad object file\n"),
+                  err_msg, warn_msg);
+       }
+    }
 
   fflush (stderr);
 
@@ -1304,19 +1329,13 @@ main (int argc, char ** argv)
   listing_print (listing_filename, argv_orig);
 #endif
 
-  if (flag_fatal_warnings && had_warnings () > 0 && had_errors () == 0)
-    as_bad (_("%d warnings, treating warnings as errors"), had_warnings ());
-
-  if (had_errors () > 0 && ! flag_always_generate_output)
-    keep_it = 0;
-
   input_scrub_end ();
 
   END_PROGRESS (myname);
 
   /* Use xexit instead of return, because under VMS environments they
      may not place the same interpretation on the value given.  */
-  if (had_errors () > 0)
+  if (had_errors () != 0)
     xexit (EXIT_FAILURE);
 
   /* Only generate dependency file if assembler was successful.  */
index e406f7b..e59f27b 100644 (file)
@@ -2120,7 +2120,9 @@ elf_frob_symbol (symbolS *symp, int *puntp)
       char *p;
 
       p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
-      know (p != NULL);
+      if (p == NULL)
+       /* We will have already reported an error about a missing version.  */
+       *puntp = TRUE;
 
       /* This symbol was given a new name with the .symver directive.
 
@@ -2133,14 +2135,15 @@ elf_frob_symbol (symbolS *symp, int *puntp)
         symbol.  However, it's not clear whether it is the best
         approach.  */
 
-      if (! S_IS_DEFINED (symp))
+      else if (! S_IS_DEFINED (symp))
        {
          /* Verify that the name isn't using the @@ syntax--this is
             reserved for definitions of the default version to link
             against.  */
          if (p[1] == ELF_VER_CHR)
            {
-             as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
+             as_bad (_("invalid attempt to declare external version name"
+                       " as default in symbol `%s'"),
                      sy_obj->versioned_name);
              *puntp = TRUE;
            }
@@ -2403,8 +2406,7 @@ elf_frob_file_before_adjust (void)
 
                p = strchr (symbol_get_obj (symp)->versioned_name,
                            ELF_VER_CHR);
-               know (p != NULL);
-               if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
+               if (p != NULL && p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
                  {
                    size_t l = strlen (&p[3]) + 1;
                    memmove (&p[1], &p[3], l);
index efc129b..c146d66 100644 (file)
@@ -1,5 +1,21 @@
 2014-06-16  Alan Modra  <amodra@gmail.com>
 
+       * gas/elf/bad-group.s: Use %function.
+       * gas/elf/bad-group.err: Expect correct line number.  Allow
+       other errors.
+       * gas/elf/bad-size.err: Allow other errors.  Match expected
+       error somewhat more rigorously.
+       * gas/i386/reloc32.l: Allow other errors.
+       * gas/i386/mpx-inval-1.l: Match applied relocs.
+       * gas/i386/x86-64-mpx-inval-1.l: Likewise, and nop padding.
+       * gas/i386/x86-64-mpx-inval-2.l: Match nop padding, and allow
+       other errors.
+       * gas/macros/dot.s: Use .balign.
+       * gas/macros/dot.l: Update alignment output.
+       * gas/symver/symver6.l: Allow other errors.
+
+2014-06-16  Alan Modra  <amodra@gmail.com>
+
        * gas/vax/elf-rel.d: Update.
 
 2014-06-16  Alan Modra  <amodra@gmail.com>
index 4b650d4..db5db2f 100644 (file)
@@ -1,2 +1,3 @@
 .*bad-group\.s: Assembler messages:
-.*bad-group\.s:.* Error: .*
+.*bad-group\.s:10: Error: .*
+#pass
index dc927c6..7a7368f 100644 (file)
@@ -1,7 +1,7 @@
        .section        .text.startup,"ax",%progbits
        .globl main
 main:
-       .type   main, @function
+       .type   main, %function
 .LFB0:
        .section        .text.unlikely,"ax",%progbits
 .L5:
index caa6bae..513d250 100644 (file)
@@ -1,2 +1,3 @@
 .*bad-size\.s: Assembler messages:
-.*bad-size\.s:.* Error: .*
+#...
+.*bad-size\.s:.* Error: \.size expression .* does not evaluate to a constant
index 121aad6..b356080 100644 (file)
@@ -33,9 +33,9 @@ GAS LISTING .*
 .*  Error: expecting valid branch instruction after `bnd'
 .*  Warning: skipping prefixes on this instruction
 [      ]*9[    ]+003412
-[      ]*10[   ]+\?\?\?\? F2E200               bnd loop foo
+[      ]*10[   ]+\?\?\?\? F2E2E9               bnd loop foo
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*11[   ]+\?\?\?\? 67F2E300             bnd jcxz foo
+[      ]*11[   ]+\?\?\?\? 67F2E3E5             bnd jcxz foo
 .*  Error: expecting valid branch instruction after `bnd'
 [      ]*12[   ]+
 [      ]*13[   ]+\.intel_syntax noprefix
@@ -49,7 +49,8 @@ GAS LISTING .*
 [      ]*17[   ]+\?\?\?\? EA000000             bnd ljmp 0x1234,xxx
 .*  Error: expecting valid branch instruction after `bnd'
 [      ]*17[   ]+003412
-[      ]*18[   ]+\?\?\?\? F2E200               bnd loop foo
+[      ]*18[   ]+\?\?\?\? F2E2CE               bnd loop foo
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*19[   ]+\?\?\?\? 67F2E300             bnd jcxz foo
+[      ]*19[   ]+\?\?\?\? 67F2E3CA             bnd jcxz foo
 .*  Error: expecting valid branch instruction after `bnd'
+#pass
index 74e80df..9299445 100644 (file)
@@ -65,3 +65,4 @@
 .*:159: Error: .*
 .*:160: Error: .*
 .*:161: Error: .*
+#pass
index 16b3aff..361de10 100644 (file)
@@ -17,9 +17,9 @@ GAS LISTING .*
 .*  Error: expecting valid branch instruction after `bnd'
 [      ]*5[    ]+\?\?\?\? 6766F2AB             bnd stosw \(%edi\)              \# Bad
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*6[    ]+\?\?\?\? F2E200               bnd loop foo
+[      ]*6[    ]+\?\?\?\? F2E2(00|0A)                  bnd loop foo
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*7[    ]+\?\?\?\? F2E300               bnd jrcxz foo
+[      ]*7[    ]+\?\?\?\? F2E3(00|0D)                  bnd jrcxz foo
 .*  Error: expecting valid branch instruction after `bnd'
 [      ]*8[    ]+
 [      ]*9[    ]+\.intel_syntax noprefix
@@ -27,7 +27,8 @@ GAS LISTING .*
 .*  Error: expecting valid branch instruction after `bnd'
 [      ]*11[   ]+\?\?\?\? 6766F2AB             bnd stos WORD PTR \[edi]                \# Bad
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*12[   ]+\?\?\?\? F2E200               bnd loop foo
+[      ]*12[   ]+\?\?\?\? F2E2(00|18)                  bnd loop foo
 .*  Error: expecting valid branch instruction after `bnd'
-[      ]*13[   ]+\?\?\?\? F2E300               bnd jrcxz foo
+[      ]*13[   ]+\?\?\?\? F2E3(00|1B)(  |90)           bnd jrcxz foo
 .*  Error: expecting valid branch instruction after `bnd'
+#pass
index c7be066..d9a1b6e 100644 (file)
@@ -170,4 +170,5 @@ GAS LISTING .*
 [      ]*65[   ]+\?\?\?\? 670F1A14             bndldx bnd2, \[1\*ebx\+3\]
 .*  Error: 32-bit address isn't allowed in 64-bit MPX instructions\.
 [      ]*65[   ]+1D030000 
-[      ]*65[   ]+00
+[      ]*65[   ]+00(|909090 )
+#pass
index 5c616b0..07334ce 100644 (file)
@@ -6,11 +6,11 @@
 [      ]*[1-9][0-9]*[  ]+m 4, 2
 [      ]*[1-9][0-9]*[  ]+>  \.data
 [      ]*[1-9][0-9]*[  ]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
-[      ]*[1-9][0-9]*[  ]+>>  \.align 4
+[      ]*[1-9][0-9]*[  ]+>>  \.balign 4
 [      ]*[1-9][0-9]*[  ]+\?+[  ]+06 ?06[       ]+>>  \.byte 4\+2,4\+2
 [      ]*[1-9][0-9]*[  ]+\?+[  ]+00 ?00[       ]+>  \.skip 2
 [      ]*[1-9][0-9]*[  ]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
-[      ]*[1-9][0-9]*[  ]+>>  \.align 8
+[      ]*[1-9][0-9]*[  ]+\?+[  ]+00 ?00 ?00 ?00[       ]+>>  \.balign 8
 [      ]*[1-9][0-9]*[  ]+\?+[  ]+02 ?02[       ]+>>  \.byte 4-2,4-2
 [      ]*[1-9][0-9]*[  ]+\?+[  ]+00 ?00 ?00 ?00[       ]+>  \.skip 4\*2
 [      ]*[1-9][0-9]*[  ]+00 ?00 ?00 ?00[       ]*
index e9c326d..6916400 100644 (file)
@@ -1,12 +1,12 @@
  .altmacro
 
  .macro x.y.z val
-  .align 4
+  .balign 4
   .byte val,val
  .endm
 
  .macro .xyz val
-  .align 8
+  .balign 8
   .byte val,val
  .endm
 
index 69468b4..c2d12ae 100644 (file)
@@ -1,2 +1,3 @@
 .*: Assembler messages:
 .*:7: Error: multiple versions \[`foo@version1'|`foo@@version1'\] for symbol `foo'
+#pass
index 4ab275d..d1918e6 100644 (file)
@@ -1692,7 +1692,7 @@ set_symtab (void)
 #endif
 #endif
 
-void
+static void
 subsegs_finish (void)
 {
   struct frchain *frchainP;
@@ -1761,33 +1761,12 @@ write_object_file (void)
   fragS *fragP;                        /* Track along all frags.  */
 #endif
 
+  subsegs_finish ();
+
 #ifdef md_pre_output_hook
   md_pre_output_hook;
 #endif
 
-  /* Do we really want to write it?  */
-  {
-    int n_warns, n_errs;
-    n_warns = had_warnings ();
-    n_errs = had_errors ();
-    /* The -Z flag indicates that an object file should be generated,
-       regardless of warnings and errors.  */
-    if (flag_always_generate_output)
-      {
-       if (n_warns || n_errs)
-         as_warn (_("%d error%s, %d warning%s, generating bad object file"),
-                  n_errs, n_errs == 1 ? "" : "s",
-                  n_warns, n_warns == 1 ? "" : "s");
-      }
-    else
-      {
-       if (n_errs)
-         as_fatal (_("%d error%s, %d warning%s, no object file generated"),
-                   n_errs, n_errs == 1 ? "" : "s",
-                   n_warns, n_warns == 1 ? "" : "s");
-      }
-  }
-
 #ifdef md_pre_relax_hook
   md_pre_relax_hook;
 #endif
index c9b3da0..0389005 100644 (file)
@@ -169,7 +169,6 @@ extern struct reloc_list* reloc_list;
 extern void append (char **charPP, char *fromP, unsigned long length);
 extern void record_alignment (segT seg, int align);
 extern int get_recorded_alignment (segT seg);
-extern void subsegs_finish (void);
 extern void write_object_file (void);
 extern long relax_frag (segT, fragS *, long);
 extern int relax_segment (struct frag *, segT, int);