Index: src/gas/config/obj-coff-seh.c =================================================================== --- src.orig/gas/config/obj-coff-seh.c 2010-09-15 19:30:14.369128900 +0200 +++ src/gas/config/obj-coff-seh.c 2010-09-15 19:41:50.472943700 +0200 @@ -157,6 +157,21 @@ seh_hash_find_or_make (segT cseg, const return item; } +/* Check if current segment has same name. */ +static int +seh_validate_seg (const char *directive) +{ + const char *cseg_name, *nseg_name; + if (seh_ctx_cur->code_seg == now_seg) + return 1; + cseg_name = bfd_get_section_name (stdoutput, seh_ctx_cur->code_seg); + nseg_name = bfd_get_section_name (stdoutput, now_seg); + as_bad (_("%s used in segment '%s' instead of expected '%s'"), + directive, nseg_name, cseg_name); + ignore_rest_of_line (); + return 0; +} + static void switch_xdata (int subseg, segT code_seg) { @@ -397,7 +412,7 @@ obj_coff_seh_endproc (int what ATTRIBUTE as_bad (_(".seh_endproc used without .seh_proc")); return; } - + seh_validate_seg (".seh_endproc"); do_seh_endproc (); } @@ -450,7 +465,8 @@ obj_coff_seh_proc (int what ATTRIBUTE_UN static void obj_coff_seh_endprologue (int what ATTRIBUTE_UNUSED) { - if (!verify_context (".seh_endprologue")) + if (!verify_context (".seh_endprologue") + || !seh_validate_seg (".seh_endprologue")) return; demand_empty_rest_of_line (); @@ -555,7 +571,8 @@ obj_coff_seh_pushreg (int what ATTRIBUTE { int reg; - if (!verify_context_and_target (".seh_pushreg", seh_kind_x64)) + if (!verify_context_and_target (".seh_pushreg", seh_kind_x64) + || !seh_validate_seg (".seh_pushreg")) return; reg = seh_x64_read_reg (".seh_pushreg", 1); @@ -572,7 +589,8 @@ obj_coff_seh_pushreg (int what ATTRIBUTE static void obj_coff_seh_pushframe (int what ATTRIBUTE_UNUSED) { - if (!verify_context_and_target (".seh_pushframe", seh_kind_x64)) + if (!verify_context_and_target (".seh_pushframe", seh_kind_x64) + || !seh_validate_seg (".seh_pushframe")) return; demand_empty_rest_of_line (); @@ -588,7 +606,8 @@ obj_coff_seh_save (int what) int code, reg, scale; offsetT off; - if (!verify_context_and_target (directive, seh_kind_x64)) + if (!verify_context_and_target (directive, seh_kind_x64) + || !seh_validate_seg (directive)) return; reg = seh_x64_read_reg (directive, what); @@ -633,7 +652,8 @@ obj_coff_seh_stackalloc (int what ATTRIB offsetT off; int code, info; - if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64)) + if (!verify_context_and_target (".seh_stackalloc", seh_kind_x64) + || !seh_validate_seg (".seh_stackalloc")) return; off = get_absolute_expression (); @@ -670,7 +690,8 @@ obj_coff_seh_setframe (int what ATTRIBUT offsetT off; int reg; - if (!verify_context_and_target (".seh_setframe", seh_kind_x64)) + if (!verify_context_and_target (".seh_setframe", seh_kind_x64) + || !seh_validate_seg (".seh_setframe")) return; reg = seh_x64_read_reg (".seh_setframe", 0); Index: src/gas/testsuite/gas/pe/pe.exp =================================================================== --- src.orig/gas/testsuite/gas/pe/pe.exp 2010-09-15 19:30:14.387129900 +0200 +++ src/gas/testsuite/gas/pe/pe.exp 2010-09-15 19:30:30.033024800 +0200 @@ -40,7 +40,7 @@ run_dump_test "section-align-3" # These tests are only for x86_64 targets if ([istarget "x86_64-*-mingw*"]) then { - + run_list_test "seh-x64-err-1" "" run_dump_test "peseh-x64" run_dump_test "peseh-x64-2" run_dump_test "peseh-x64-3" Index: src/gas/testsuite/gas/pe/seh-x64-err-1.l =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gas/testsuite/gas/pe/seh-x64-err-1.l 2010-09-15 19:30:30.039025100 +0200 @@ -0,0 +1,24 @@ +.*: Assembler messages: +.*:5: Error: .seh_endproc used without .seh_proc +.*:6: Error: .seh_stackalloc used outside of .seh_proc block +.*:7: Error: .seh_setframe used outside of .seh_proc block +.*:8: Error: .seh_endprologue used outside of .seh_proc block +.*:9: Error: .seh_pushreg used outside of .seh_proc block +.*:10: Error: .seh_savereg used outside of .seh_proc block +.*:11: Error: .seh_savexmm used outside of .seh_proc block +.*:12: Error: .seh_handler used outside of .seh_proc block +.*:13: Error: .seh_handler used outside of .seh_proc block +.*:14: Error: .seh_handler used outside of .seh_proc block +.*:15: Error: .seh_handler used outside of .seh_proc block +.*:16: Error: .seh_handlerdata used outside of .seh_proc block +.*:19: Error: .seh_proc requires function label name +.*:23: Warning: .seh_eh ignored for this target +.*:24: Warning: .seh_32 ignored for this target +.*:25: Warning: .seh_no32 ignored for this target +.*:33: Error: .seh_stackalloc used in segment '.data' instead of expected '.text' +.*:34: Error: .seh_setframe used in segment '.data' instead of expected '.text' +.*:35: Error: .seh_endprologue used in segment '.data' instead of expected '.text' +.*:36: Error: .seh_pushreg used in segment '.data' instead of expected '.text' +.*:37: Error: .seh_savereg used in segment '.data' instead of expected '.text' +.*:38: Error: .seh_savexmm used in segment '.data' instead of expected '.text' +.*:39: Error: .seh_endproc used in segment '.data' instead of expected '.text' Index: src/gas/testsuite/gas/pe/seh-x64-err-1.s =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gas/testsuite/gas/pe/seh-x64-err-1.s 2010-09-15 19:30:30.042025300 +0200 @@ -0,0 +1,40 @@ + .file "t1.c" + .text +#seh pseudos out of seh_proc block + + .seh_endproc + .seh_stackalloc 8 + .seh_setframe %rbp, 0 + .seh_endprologue + .seh_pushreg %rbp + .seh_savereg %rbp + .seh_savexmm %xmm1 + .seh_handler dummy_handler + .seh_handler dummy_handler, @unwind + .seh_handler dummy_handler, @except + .seh_handler dummy_handler, @unwind,@except + .seh_handlerdata + .long 0 + .text + .seh_proc + + .seh_proc test_foreign_directives +test_foreign_directives: + .seh_eh + .seh_32 + .seh_no32 + .long 0 + .seh_endproc + +# test for wrong segment pseudos. + .seh_proc test_wrong_segment +test_wrong_segment: + .data + .seh_stackalloc 8 + .seh_setframe %rbp, 0 + .seh_endprologue + .seh_pushreg %rbp + .seh_savereg %rbp + .seh_savexmm %xmm1 + .seh_endproc +