This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] GAS: Consistently fix labels at the `.end' pseudo-op


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5ff6a06c215a5288787decfb933591afb5aa434d

commit 5ff6a06c215a5288787decfb933591afb5aa434d
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Fri Feb 17 20:30:55 2017 +0000

    GAS: Consistently fix labels at the `.end' pseudo-op
    
    Fix a functional regression with the `.end' pseudo-op, introduced with
    commit ecb4347adecd ("Last take: approval for MIPS_STABS_ELF killing"),
    <https://sourceware.org/ml/binutils/2002-06/msg00443.html>, and commit
    dcd410fe1544 ("GNU as 2.14 on IRIX 6: crashes with shared libs"),
    <https://sourceware.org/ml/binutils/2003-07/msg00415.html>, which caused
    symbol values for labels placed between the end of a function's contents
    and its terminating `.end' followed by one of the alignment pseudo-ops
    to be different depending on whether either `-mdebug', or `-mno-pdr', or
    neither of the command-line options is in effect, be it implied or
    specified.
    
    Given debug-label-end.s as follows and the `mips-linux' target we have:
    
    $ cat debug-label-end.s
    	.text
    
    	.globl	foo
    	.globl	bar
    	.align	4, 0
    	.ent	foo
    foo:
    	nop
    	.aent	bar
    bar:
    	.insn
    	.end	foo
    	.align	4, 0
    	.space	16
    
    	.globl	baz
    	.ent	baz
    baz:
    	nop
    	.end	baz
    	.align	4, 0
    	.space	16
    $ as -o debug-label-end.o debug-label-end.s
    $ readelf -s debug-label-end.o | grep bar
         9: 00000004     0 FUNC    GLOBAL DEFAULT    1 bar
    $ as -mdebug -o debug-label-end.o debug-label-end.s
    $ readelf -s debug-label-end.o | grep bar
         9: 00000010     0 FUNC    GLOBAL DEFAULT    1 bar
    $ as -mno-pdr -o debug-label-end.o debug-label-end.s
    $ readelf -s debug-label-end.o | grep bar
         8: 00000010     0 FUNC    GLOBAL DEFAULT    1 bar
    $
    
    The reason is the call to `md_flush_pending_output', which in the case
    of `mips*-*-*' targets expands to `mips_emit_delays', which in turn
    calls `mips_no_prev_insn', which calls `mips_clear_insn_labels', which
    clears the list of outstanding labels.  That list is in turn consulted
    in `mips_align', called in the interpretation of alignment directives,
    and the labels adjusted to the current location.
    
    A call to `md_flush_pending_output' is only made from `s_mips_end' and
    then only if `-mpdr' is in effect, which is the default for `*-*-linux*'
    and some other `mips*-*-*' targets.  A call to `md_flush_pending_output'
    is never made from `ecoff_directive_end', which is used in place of
    `s_mips_end' when `-mdebug' is in effect.  Consequently if `-mno-pdr' or
    `-mdebug' is in effect the list of outstanding labels makes it through
    to any alignment directive that follows and the labels are differently
    interpreted depending on the command-lines options used.  And we want
    code produced to be always the same.
    
    Call `md_flush_pending_output' unconditionally then in `s_mips_end' and
    add such a call from `ecoff_directive_end' as well, as long as the macro
    is defined.  While `ecoff_directive_end' is shared among targets, the
    only one other than `mips*-*-*' actually using it is `alpha*-*-*' and it
    does not define `md_flush_pending_output'.  So the semantics isn't going
    to change for it and neither it has to have its `s_alpha_end' updated
    or have code in `ecoff_directive_end' conditionalized.
    
    	gas/
    	* ecoff.c (ecoff_directive_end) [md_flush_pending_output]: Call
    	`md_flush_pending_output'.
    	* config/tc-mips.c (s_mips_end) [md_flush_pending_output]: Call
    	`md_flush_pending_output' unconditionally.
    	* testsuite/gas/mips/debug-label-end-1.d: New test.
    	* testsuite/gas/mips/debug-label-end-2.d: New test.
    	* testsuite/gas/mips/debug-label-end-3.d: New test.
    	* testsuite/gas/mips/debug-label-end.s: New test source.
    	* testsuite/gas/mips/mips.exp: Run the new tests.

Diff:
---
 gas/ChangeLog                              | 12 ++++++++++++
 gas/config/tc-mips.c                       |  8 ++++----
 gas/ecoff.c                                |  4 ++++
 gas/testsuite/gas/mips/debug-label-end-1.d | 21 +++++++++++++++++++++
 gas/testsuite/gas/mips/debug-label-end-2.d | 17 +++++++++++++++++
 gas/testsuite/gas/mips/debug-label-end-3.d | 17 +++++++++++++++++
 gas/testsuite/gas/mips/debug-label-end.s   | 22 ++++++++++++++++++++++
 gas/testsuite/gas/mips/mips.exp            |  4 ++++
 8 files changed, 101 insertions(+), 4 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 738083e..2b11805 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2017-02-22  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* ecoff.c (ecoff_directive_end) [md_flush_pending_output]: Call
+	`md_flush_pending_output'.
+	* config/tc-mips.c (s_mips_end) [md_flush_pending_output]: Call
+	`md_flush_pending_output' unconditionally.
+	* testsuite/gas/mips/debug-label-end-1.d: New test.
+	* testsuite/gas/mips/debug-label-end-2.d: New test.
+	* testsuite/gas/mips/debug-label-end-3.d: New test.
+	* testsuite/gas/mips/debug-label-end.s: New test source.
+	* testsuite/gas/mips/mips.exp: Run the new tests.
+
 2017-02-22  Hans-Peter Nilsson  <hp@axis.com>
 
 	* testsuite/gas/all/err-sizeof.s: Include cris*-*-* in the list of
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index d151b01..54b94be 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -19080,6 +19080,10 @@ s_mips_end (int x ATTRIBUTE_UNUSED)
       cur_proc_ptr->func_end_sym = exp->X_add_symbol;
     }
 
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
   /* Generate a .pdr section.  */
   if (!ECOFF_DEBUGGING && mips_flag_pdr)
     {
@@ -19088,10 +19092,6 @@ s_mips_end (int x ATTRIBUTE_UNUSED)
       expressionS exp;
       char *fragp;
 
-#ifdef md_flush_pending_output
-      md_flush_pending_output ();
-#endif
-
       gas_assert (pdr_seg);
       subseg_set (pdr_seg, 0);
 
diff --git a/gas/ecoff.c b/gas/ecoff.c
index 5c37312..608d72b 100644
--- a/gas/ecoff.c
+++ b/gas/ecoff.c
@@ -3025,6 +3025,10 @@ ecoff_directive_end (int ignore ATTRIBUTE_UNUSED)
 					 frag_now),
 			     (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
 
+#ifdef md_flush_pending_output
+  md_flush_pending_output ();
+#endif
+
   cur_proc_ptr = (proc_t *) NULL;
 
   (void) restore_line_pointer (name_end);
diff --git a/gas/testsuite/gas/mips/debug-label-end-1.d b/gas/testsuite/gas/mips/debug-label-end-1.d
new file mode 100644
index 0000000..c158326
--- /dev/null
+++ b/gas/testsuite/gas/mips/debug-label-end-1.d
@@ -0,0 +1,21 @@
+#readelf: -s
+#name: MIPS ECOFF/PDR debug interaction with labels at .end 1
+#as: -32 -no-mdebug -mpdr
+#source: debug-label-end.s
+
+# Verify that .end finalizes any labels outstanding
+# where PDR debug generation is enabled, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000004     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
+# vs:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000010     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
+#...
+ *[0-9]+: +0+000000 +4 +FUNC +GLOBAL +DEFAULT +[0-9]+ foo
+ *[0-9]+: +0+000004 +0 +FUNC +GLOBAL +DEFAULT +[0-9]+ bar
+ *[0-9]+: +0+000020 +4 +FUNC +GLOBAL +DEFAULT +[0-9]+ baz
+#pass
diff --git a/gas/testsuite/gas/mips/debug-label-end-2.d b/gas/testsuite/gas/mips/debug-label-end-2.d
new file mode 100644
index 0000000..ad36caf
--- /dev/null
+++ b/gas/testsuite/gas/mips/debug-label-end-2.d
@@ -0,0 +1,17 @@
+#readelf: -s
+#name: MIPS ECOFF/PDR debug interaction with labels at .end 2
+#as: -32 -mdebug -mno-pdr
+#source: debug-label-end.s
+#dump: debug-label-end-1.d
+
+# Verify that .end finalizes any labels outstanding
+# where ECOFF debug generation is enabled, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000004     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
+# vs:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000010     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
diff --git a/gas/testsuite/gas/mips/debug-label-end-3.d b/gas/testsuite/gas/mips/debug-label-end-3.d
new file mode 100644
index 0000000..184583e
--- /dev/null
+++ b/gas/testsuite/gas/mips/debug-label-end-3.d
@@ -0,0 +1,17 @@
+#readelf: -s
+#name: MIPS ECOFF/PDR debug interaction with labels at .end 3
+#as: -32 -no-mdebug -mno-pdr
+#source: debug-label-end.s
+#dump: debug-label-end-1.d
+
+# Verify that .end finalizes any labels outstanding
+# where both ECOFF and PDR generation is disabled, e.g.:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000004     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
+# vs:
+#    Num:    Value  Size Type    Bind   Vis      Ndx Name
+#      7: 00000000     4 FUNC    GLOBAL DEFAULT    1 foo
+#      8: 00000010     0 FUNC    GLOBAL DEFAULT    1 bar
+#      9: 00000020     4 FUNC    GLOBAL DEFAULT    1 baz
diff --git a/gas/testsuite/gas/mips/debug-label-end.s b/gas/testsuite/gas/mips/debug-label-end.s
new file mode 100644
index 0000000..caf4dd1
--- /dev/null
+++ b/gas/testsuite/gas/mips/debug-label-end.s
@@ -0,0 +1,22 @@
+	.text
+
+	.globl	foo
+	.globl	bar
+	.align	4, 0
+	.ent	foo
+foo:
+	nop
+	.aent	bar
+bar:
+	.insn
+	.end	foo
+	.align	4, 0
+	.space	16
+
+	.globl	baz
+	.ent	baz
+baz:
+	nop
+	.end	baz
+	.align	4, 0
+	.space	16
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 8a9f9f1..bef7106 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1794,6 +1794,10 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test_arches "isa-override-1" "" [mips_arch_list_matching mips1]
     run_list_test_arches "isa-override-2" "-32" [mips_arch_list_matching mips1]
 
+    run_dump_test "debug-label-end-1"
+    run_dump_test "debug-label-end-2"
+    run_dump_test "debug-label-end-3"
+
     run_dump_test_arches "r6"		[mips_arch_list_matching mips32r6]
     if $has_newabi {
 	run_dump_test_arches "r6-n32"	[mips_arch_list_matching mips64r6]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]