Index: src/gas/config/obj-coff-seh.c =================================================================== --- src.orig/gas/config/obj-coff-seh.c 2010-09-15 09:03:08.000000000 +0200 +++ src/gas/config/obj-coff-seh.c 2010-09-15 09:52:38.203713600 +0200 @@ -158,6 +158,23 @@ 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, segT cseg) +{ + const char *cseg_name, *nseg_name; + if (cseg == now_seg) + return 1; + cseg_name = bfd_get_section_name (stdoutput, cseg); + nseg_name = bfd_get_section_name (stdoutput, now_seg); + if (!strcmp (cseg_name, nseg_name)) + return 1; + 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) { @@ -398,7 +415,7 @@ obj_coff_seh_endproc (int what ATTRIBUTE as_bad (_(".seh_endproc used without .seh_proc")); return; } - + seh_validate_seg (".seh_endproc", seh_ctx_cur->code_seg); do_seh_endproc (); } @@ -451,7 +468,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", seh_ctx_cur->code_seg)) return; demand_empty_rest_of_line (); @@ -556,7 +574,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", seh_ctx_cur->code_seg)) return; reg = seh_x64_read_reg (".seh_pushreg", 1); @@ -573,7 +592,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", seh_ctx_cur->code_seg)) return; demand_empty_rest_of_line (); @@ -589,7 +609,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, seh_ctx_cur->code_seg)) return; reg = seh_x64_read_reg (directive, what); @@ -634,7 +655,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", seh_ctx_cur->code_seg)) return; off = get_absolute_expression (); @@ -671,7 +693,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", seh_ctx_cur->code_seg)) 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 07:38:04.000000000 +0200 +++ src/gas/testsuite/gas/pe/pe.exp 2010-09-15 09:47:23.257699700 +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 09:51:02.917263500 +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 09:43:05.085933100 +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 +