From 85024cd8bcb93f4112470ecdbd6c10fc2aea724f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 16 Jun 2014 11:04:04 +0930 Subject: [PATCH] Run write_object_file after errors 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. --- gas/ChangeLog | 14 +++++ gas/as.c | 59 ++++++++++++++------- gas/config/obj-elf.c | 12 +++-- gas/testsuite/ChangeLog | 16 ++++++ gas/testsuite/gas/elf/bad-group.err | 3 +- gas/testsuite/gas/elf/bad-group.s | 2 +- gas/testsuite/gas/elf/bad-size.err | 3 +- gas/testsuite/gas/i386/mpx-inval-1.l | 9 ++-- gas/testsuite/gas/i386/reloc32.l | 1 + gas/testsuite/gas/i386/x86-64-mpx-inval-1.l | 9 ++-- gas/testsuite/gas/i386/x86-64-mpx-inval-2.l | 3 +- gas/testsuite/gas/macros/dot.l | 4 +- gas/testsuite/gas/macros/dot.s | 4 +- gas/testsuite/gas/symver/symver6.l | 1 + gas/write.c | 27 ++-------- gas/write.h | 1 - 16 files changed, 102 insertions(+), 66 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 8f1aec1849..e62969cd8c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2014-06-16 Alan Modra + + * 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 * config/tc-dlx.c (machine_ip): Move initialisation of the_insn diff --git a/gas/as.c b/gas/as.c index 752af644a8..32459a875e 100644 --- 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]; - /* 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 (); + write_object_file (); - if (keep_it) - 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); + + 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 (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. */ diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index e406f7b61e..e59f27b51e 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -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); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index efc129b8d8..c146d66982 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2014-06-16 Alan Modra + + * 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 * gas/vax/elf-rel.d: Update. diff --git a/gas/testsuite/gas/elf/bad-group.err b/gas/testsuite/gas/elf/bad-group.err index 4b650d42fe..db5db2fc0f 100644 --- a/gas/testsuite/gas/elf/bad-group.err +++ b/gas/testsuite/gas/elf/bad-group.err @@ -1,2 +1,3 @@ .*bad-group\.s: Assembler messages: -.*bad-group\.s:.* Error: .* +.*bad-group\.s:10: Error: .* +#pass diff --git a/gas/testsuite/gas/elf/bad-group.s b/gas/testsuite/gas/elf/bad-group.s index dc927c62d0..7a7368fa8f 100644 --- a/gas/testsuite/gas/elf/bad-group.s +++ b/gas/testsuite/gas/elf/bad-group.s @@ -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: diff --git a/gas/testsuite/gas/elf/bad-size.err b/gas/testsuite/gas/elf/bad-size.err index caa6bae80c..513d250c2c 100644 --- a/gas/testsuite/gas/elf/bad-size.err +++ b/gas/testsuite/gas/elf/bad-size.err @@ -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 diff --git a/gas/testsuite/gas/i386/mpx-inval-1.l b/gas/testsuite/gas/i386/mpx-inval-1.l index 121aad6c9a..b356080cd5 100644 --- a/gas/testsuite/gas/i386/mpx-inval-1.l +++ b/gas/testsuite/gas/i386/mpx-inval-1.l @@ -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 diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/reloc32.l index 74e80df610..9299445851 100644 --- a/gas/testsuite/gas/i386/reloc32.l +++ b/gas/testsuite/gas/i386/reloc32.l @@ -65,3 +65,4 @@ .*:159: Error: .* .*:160: Error: .* .*:161: Error: .* +#pass diff --git a/gas/testsuite/gas/i386/x86-64-mpx-inval-1.l b/gas/testsuite/gas/i386/x86-64-mpx-inval-1.l index 16b3aff95a..361de10cea 100644 --- a/gas/testsuite/gas/i386/x86-64-mpx-inval-1.l +++ b/gas/testsuite/gas/i386/x86-64-mpx-inval-1.l @@ -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 diff --git a/gas/testsuite/gas/i386/x86-64-mpx-inval-2.l b/gas/testsuite/gas/i386/x86-64-mpx-inval-2.l index c7be066ffe..d9a1b6e747 100644 --- a/gas/testsuite/gas/i386/x86-64-mpx-inval-2.l +++ b/gas/testsuite/gas/i386/x86-64-mpx-inval-2.l @@ -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 diff --git a/gas/testsuite/gas/macros/dot.l b/gas/testsuite/gas/macros/dot.l index 5c616b072c..07334cece2 100644 --- a/gas/testsuite/gas/macros/dot.l +++ b/gas/testsuite/gas/macros/dot.l @@ -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[ ]* diff --git a/gas/testsuite/gas/macros/dot.s b/gas/testsuite/gas/macros/dot.s index e9c326d5c0..6916400c9c 100644 --- a/gas/testsuite/gas/macros/dot.s +++ b/gas/testsuite/gas/macros/dot.s @@ -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 diff --git a/gas/testsuite/gas/symver/symver6.l b/gas/testsuite/gas/symver/symver6.l index 69468b4939..c2d12ae060 100644 --- a/gas/testsuite/gas/symver/symver6.l +++ b/gas/testsuite/gas/symver/symver6.l @@ -1,2 +1,3 @@ .*: Assembler messages: .*:7: Error: multiple versions \[`foo@version1'|`foo@@version1'\] for symbol `foo' +#pass diff --git a/gas/write.c b/gas/write.c index 4ab275d89d..d1918e6575 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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 diff --git a/gas/write.h b/gas/write.h index c9b3da09fa..038900541c 100644 --- a/gas/write.h +++ b/gas/write.h @@ -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);