GAS: Consistently fix labels at the `.end' pseudo-op
Fix a functional regression with the `.end' pseudo-op, introduced with commitecb4347ade
("Last take: approval for MIPS_STABS_ELF killing"), <https://sourceware.org/ml/binutils/2002-06/msg00443.html>, and commitdcd410fe15
("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.
This commit is contained in:
parent
758d96d834
commit
5ff6a06c21
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue