aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2020-09-07 14:25:25 +0200
committerMark Wielaard <mark@klomp.org>2020-09-11 19:18:44 +0200
commitedc7a80a9c04667dfa74f90f74bd39827bc372b7 (patch)
tree7b3047fb76bf8068810aaed3ee31e2f30bb5d0a4
parent548f5275787a2328b5c1ea041e13a53e67d4accb (diff)
downloadgdb-edc7a80a9c04667dfa74f90f74bd39827bc372b7.zip
gdb-edc7a80a9c04667dfa74f90f74bd39827bc372b7.tar.gz
gdb-edc7a80a9c04667dfa74f90f74bd39827bc372b7.tar.bz2
gas: Don't error when .debug_line already exists, unless .loc was used
When -g was used to generate DWARF gas would error out when a .debug_line already exists. But when a .debug_info section already exists it would simply skip generating one without warning or error. Do the same for .debug_line. It is only an error when the user explicitly uses .loc directives and also generates the .debug_line table itself. The tests are unfortunately arch specific because the line table is only generated when actual instructions have been emitted. Use i386 because that is probably the most used architecture. Before this patch the new dwarf-line-2 testcase would fail, with this patch it succeeds (and doesn't try to add its own line table). gas/ChangeLog: * as.texi (-g): Explicitly mention when .debug_info and .debug_line are generated for the DWARF format. (Loc): Add that it is an error to both use a .loc directive and generate a .debug_line yourself. * dwarf2dbg.c (dwarf2_any_loc_directive_seen): New static variable. (dwarf2_directive_loc): Set dwarf2_any_loc_directive_seen to TRUE. (dwarf2_finish): Check dwarf2_any_loc_directive_seen before emitting an error. Only create .debug_line if it is empty (or doesn't exist). * testsuite/gas/i386/i386.exp: Add dwarf2-line-{1,2,3,4} when testing an elf target. * testsuite/gas/i386/dwarf2-line-{1,2,3,4}.{s,d,l}: New test files.
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/doc/as.texi7
-rw-r--r--gas/dwarf2dbg.c29
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-1.d45
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-1.s28
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-2.d48
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-2.s91
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-3.d3
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-3.l2
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-3.s32
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-4.d46
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-4.s29
-rw-r--r--gas/testsuite/gas/i386/i386.exp5
13 files changed, 369 insertions, 10 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a45e12e..1d13940 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,17 @@
+2020-09-07 Mark Wielaard <mark@klomp.org>
+
+ * as.texi (-g): Explicitly mention when .debug_info and .debug_line
+ are generated for the DWARF format.
+ (Loc): Add that it is an error to both use a .loc directive and
+ generate a .debug_line yourself.
+ * dwarf2dbg.c (dwarf2_any_loc_directive_seen): New static variable.
+ (dwarf2_directive_loc): Set dwarf2_any_loc_directive_seen to TRUE.
+ (dwarf2_finish): Check dwarf2_any_loc_directive_seen before emitting
+ an error. Only create .debug_line if it is empty (or doesn't exist).
+ * testsuite/gas/i386/i386.exp: Add dwarf2-line-{1,2,3,4} when testing
+ an elf target.
+ * testsuite/gas/i386/dwarf2-line-{1,2,3,4}.{s,d,l}: New test files.
+
2020-09-10 Cooper Qu <cooper.qu@linux.alibaba.com>
* config/tc-csky.c (md_begin): Enable extend lrw by default for
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 112eaf8..f2a0314 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -745,7 +745,9 @@ compiler output).
@itemx --gen-debug
Generate debugging information for each assembler source line using whichever
debug format is preferred by the target. This currently means either STABS,
-ECOFF or DWARF2.
+ECOFF or DWARF2. When the debug format is DWARF then a @code{.debug_info} and
+@code{.debug_line} section is only emitted when the assembly file doesn't
+generate one itself.
@item --gstabs
Generate stabs debugging information for each assembler line. This
@@ -5857,7 +5859,8 @@ the @code{.loc} directive will add a row to the @code{.debug_line} line
number matrix corresponding to the immediately following assembly
instruction. The @var{fileno}, @var{lineno}, and optional @var{column}
arguments will be applied to the @code{.debug_line} state machine before
-the row is added.
+the row is added. It is an error for the input assembly file to generate
+a non-empty @code{.debug_line} and also use @code{loc} directives.
The @var{options} are a sequence of the following tokens in any order:
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index e0ea399..1c21d58 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -226,9 +226,15 @@ static unsigned int dirs_in_use = 0;
static unsigned int dirs_allocated = 0;
/* TRUE when we've seen a .loc directive recently. Used to avoid
- doing work when there's nothing to do. */
+ doing work when there's nothing to do. Will be reset by
+ dwarf2_consume_line_info. */
bfd_boolean dwarf2_loc_directive_seen;
+/* TRUE when we've seen any .loc directive at any time during parsing.
+ Indicates the user wants us to generate a .debug_line section.
+ Used in dwarf2_finish as sanity check. */
+static bfd_boolean dwarf2_any_loc_directive_seen;
+
/* TRUE when we're supposed to set the basic block mark whenever a
label is seen. */
bfd_boolean dwarf2_loc_mark_labels;
@@ -1290,7 +1296,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
}
demand_empty_rest_of_line ();
- dwarf2_loc_directive_seen = TRUE;
+ dwarf2_any_loc_directive_seen = dwarf2_loc_directive_seen = TRUE;
debug_type = DEBUG_NONE;
/* If we were given a view id, emit the row right away. */
@@ -2737,7 +2743,7 @@ dwarf2_init (void)
/* Finish the dwarf2 debug sections. We emit .debug.line if there
- were any .file/.loc directives, or --gdwarf2 was given, or if the
+ were any .file/.loc directives, or --gdwarf2 was given, and if the
file has a non-empty .debug_info section and an empty .debug_line
section. If we emit .debug_line, and the .debug_info section is
empty, we also emit .debug_info, .debug_aranges and .debug_abbrev.
@@ -2761,8 +2767,10 @@ dwarf2_finish (void)
empty_debug_line = line_seg == NULL || !seg_not_empty_p (line_seg);
/* We can't construct a new debug_line section if we already have one.
- Give an error. */
- if (all_segs && !empty_debug_line)
+ Give an error if we have seen any .loc, otherwise trust the user
+ knows what they are doing and want to generate the .debug_line
+ (and all other debug sections) themselves. */
+ if (all_segs && !empty_debug_line && dwarf2_any_loc_directive_seen)
as_fatal ("duplicate .debug_line sections");
if ((!all_segs && emit_other_sections)
@@ -2776,8 +2784,12 @@ dwarf2_finish (void)
sizeof_address = DWARF2_ADDR_SIZE (stdoutput);
/* Create and switch to the line number section. */
- line_seg = subseg_new (".debug_line", 0);
- bfd_set_section_flags (line_seg, SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS);
+ if (empty_debug_line)
+ {
+ line_seg = subseg_new (".debug_line", 0);
+ bfd_set_section_flags (line_seg,
+ SEC_READONLY | SEC_DEBUGGING | SEC_OCTETS);
+ }
/* For each subsection, chain the debug entries together. */
for (s = all_segs; s; s = s->next)
@@ -2803,7 +2815,8 @@ dwarf2_finish (void)
}
}
- out_debug_line (line_seg);
+ if (empty_debug_line)
+ out_debug_line (line_seg);
/* If this is assembler generated line info, and there is no
debug_info already, we need .debug_info, .debug_abbrev and
diff --git a/gas/testsuite/gas/i386/dwarf2-line-1.d b/gas/testsuite/gas/i386/dwarf2-line-1.d
new file mode 100644
index 0000000..196f099
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-1.d
@@ -0,0 +1,45 @@
+#as: -gdwarf-2
+#readelf: -wl
+#name: DWARF .debug_line 1
+
+Raw dump of debug contents of section \.z?debug_line:
+
+ Offset: 0x0
+ Length: .*
+ DWARF Version: 3
+ Prologue Length: .*
+ Minimum Instruction Length: 1
+ Initial value of 'is_stmt': 1
+ Line Base: -5
+ Line Range: 14
+ Opcode Base: 13
+
+ Opcodes:
+ Opcode 1 has 0 args
+ Opcode 2 has 1 arg
+ Opcode 3 has 1 arg
+ Opcode 4 has 1 arg
+ Opcode 5 has 1 arg
+ Opcode 6 has 0 args
+ Opcode 7 has 0 args
+ Opcode 8 has 0 args
+ Opcode 9 has 1 arg
+ Opcode 10 has 0 args
+ Opcode 11 has 0 args
+ Opcode 12 has 1 arg
+
+ The Directory Table \(offset 0x.*\):
+ .*
+
+ The File Name Table \(offset 0x.*\):
+ Entry Dir Time Size Name
+ 1 1 0 0 dwarf2-line-1.s
+
+ Line Number Statements:
+ \[0x.*\] Extended opcode 2: set Address to 0x0
+ \[0x.*\] Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
+ \[0x.*\] Special opcode 20: advance Address by 1 to 0x1 and Line by 1 to 10
+ \[0x.*\] Advance PC by 1 to 0x2
+ \[0x.*\] Extended opcode 1: End of Sequence
+
+
diff --git a/gas/testsuite/gas/i386/dwarf2-line-1.s b/gas/testsuite/gas/i386/dwarf2-line-1.s
new file mode 100644
index 0000000..a2cb22e
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-1.s
@@ -0,0 +1,28 @@
+ .file "dwarf2-test.c"
+ .text
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ .cfi_startproc
+ nop
+ ret
+ .cfi_endproc
+ .size main, .-main
+ .text
+
+ .section .debug_info,"",%progbits
+ .long 0x0
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+
+# No .debug_line ok even if there is a .debug_info section
diff --git a/gas/testsuite/gas/i386/dwarf2-line-2.d b/gas/testsuite/gas/i386/dwarf2-line-2.d
new file mode 100644
index 0000000..2553fea
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-2.d
@@ -0,0 +1,48 @@
+#as: -gdwarf-2
+#readelf: -wl
+#name: DWARF .debug_line 2
+
+Raw dump of debug contents of section .z?debug_line:
+
+ Offset: 0x0
+ Length: 62
+ DWARF Version: .
+ Prologue Length: 35
+ Minimum Instruction Length: 1
+ Initial value of 'is_stmt': 1
+ Line Base: 1
+ Line Range: 1
+ Opcode Base: 16
+
+ Opcodes:
+ Opcode 1 has 0 args
+ Opcode 2 has 1 arg
+ Opcode 3 has 1 arg
+ Opcode 4 has 1 arg
+ Opcode 5 has 1 arg
+ Opcode 6 has 0 args
+ Opcode 7 has 0 args
+ Opcode 8 has 0 args
+ Opcode 9 has 1 arg
+ Opcode 10 has 0 args
+ Opcode 11 has 0 args
+ Opcode 12 has 1 arg
+ Opcode 13 has 0 args
+ Opcode 14 has 0 args
+ Opcode 15 has 0 args
+
+ The Directory Table is empty.
+
+ The File Name Table \(offset 0x.*\):
+ Entry Dir Time Size Name
+ 1 0 0 0 file1.txt
+
+ Line Number Statements:
+ \[0x.*\] Extended opcode 2: set Address to 0x0
+ \[0x.*\] Advance Line by 3 to 4
+ \[0x.*\] Copy
+ \[0x.*\] Copy \(view 1\)
+ \[0x.*\] Extended opcode 2: set Address to 0x0
+ \[0x.*\] Extended opcode 1: End of Sequence
+
+
diff --git a/gas/testsuite/gas/i386/dwarf2-line-2.s b/gas/testsuite/gas/i386/dwarf2-line-2.s
new file mode 100644
index 0000000..d43acda
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-2.s
@@ -0,0 +1,91 @@
+ .file "dwarf2-test.c"
+ .text
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ .cfi_startproc
+ nop
+ ret
+ .cfi_endproc
+ .size main, .-main
+ .text
+
+ .section .debug_info,"",%progbits
+ .long 0x0
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+
+# A non-empty .debug_line section is ok when not using .loc directives
+ .section .debug_line
+.Lline1_begin:
+ .4byte .Lline1_end - .Lline1_start /* Initial length */
+.Lline1_start:
+ .2byte 2 /* Version */
+ .4byte .Lline1_lines - .Lline1_hdr /* header_length */
+.Lline1_hdr:
+ .byte 1 /* Minimum insn length */
+ .byte 1 /* default_is_stmt */
+ .byte 1 /* line_base */
+ .byte 1 /* line_range */
+ .byte 0x10 /* opcode_base */
+
+ /* Standard lengths */
+ .byte 0
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 0
+ .byte 0
+
+ /* Include directories */
+ .byte 0
+
+ /* File names */
+ .ascii "file1.txt\0"
+ .uleb128 0
+ .uleb128 0
+ .uleb128 0
+
+ .byte 0
+
+.Lline1_lines:
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lbegin_func_cu1
+
+ .byte 3 /* DW_LNS_advance_line */
+ .sleb128 3 /* ... to 4 */
+
+ .byte 1 /* DW_LNS_copy */
+
+ .byte 1 /* DW_LNS_copy (second time as an end-of-prologue marker) */
+
+ .byte 0 /* DW_LNE_set_address */
+ .uleb128 5
+ .byte 2
+ .4byte .Lend_func_cu1
+
+ .byte 0 /* DW_LNE_end_of_sequence */
+ .uleb128 1
+ .byte 1
+
diff --git a/gas/testsuite/gas/i386/dwarf2-line-3.d b/gas/testsuite/gas/i386/dwarf2-line-3.d
new file mode 100644
index 0000000..42c94c5
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-3.d
@@ -0,0 +1,3 @@
+#as: -gdwarf-2
+#name: DWARF .debug_line 3
+#error_output: dwarf2-line-3.l
diff --git a/gas/testsuite/gas/i386/dwarf2-line-3.l b/gas/testsuite/gas/i386/dwarf2-line-3.l
new file mode 100644
index 0000000..c26e1fa
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-3.l
@@ -0,0 +1,2 @@
+[^:]*: Assembler messages:
+[^:]*: Fatal error: duplicate .debug_line sections
diff --git a/gas/testsuite/gas/i386/dwarf2-line-3.s b/gas/testsuite/gas/i386/dwarf2-line-3.s
new file mode 100644
index 0000000..2085ef9
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-3.s
@@ -0,0 +1,32 @@
+ .file "dwarf2-test.c"
+ .text
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ .cfi_startproc
+ nop
+ .loc 1 1
+ ret
+ .cfi_endproc
+ .size main, .-main
+ .text
+
+ .section .debug_info,"",%progbits
+ .long 0x0
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+
+# A non-empty .debug_line section is NOT ok when using .loc directives
+ .section .debug_line,"",@progbits
+.Ldebug_line0:
+ .byte 0x1
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.d b/gas/testsuite/gas/i386/dwarf2-line-4.d
new file mode 100644
index 0000000..c0c85f4
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.d
@@ -0,0 +1,46 @@
+#as: -gdwarf-2
+#readelf: -wl
+#name: DWARF .debug_line 4
+
+Raw dump of debug contents of section \.z?debug_line:
+
+ Offset: 0x0
+ Length: .*
+ DWARF Version: 3
+ Prologue Length: .*
+ Minimum Instruction Length: 1
+ Initial value of 'is_stmt': 1
+ Line Base: -5
+ Line Range: 14
+ Opcode Base: 13
+
+ Opcodes:
+ Opcode 1 has 0 args
+ Opcode 2 has 1 arg
+ Opcode 3 has 1 arg
+ Opcode 4 has 1 arg
+ Opcode 5 has 1 arg
+ Opcode 6 has 0 args
+ Opcode 7 has 0 args
+ Opcode 8 has 0 args
+ Opcode 9 has 1 arg
+ Opcode 10 has 0 args
+ Opcode 11 has 0 args
+ Opcode 12 has 1 arg
+
+ The Directory Table \(offset 0x.*\):
+ .*
+
+ The File Name Table \(offset 0x.*\):
+ Entry Dir Time Size Name
+ 1 1 0 0 dwarf2-line-4.s
+
+ Line Number Statements:
+ \[0x.*\] Extended opcode 2: set Address to 0x0
+ \[0x.*\] Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
+ \[0x.*\] Advance Line by -8 to 1
+ \[0x.*\] Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 1
+ \[0x.*\] Advance PC by 1 to 0x2
+ \[0x.*\] Extended opcode 1: End of Sequence
+
+
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.s b/gas/testsuite/gas/i386/dwarf2-line-4.s
new file mode 100644
index 0000000..89bb62d
--- /dev/null
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.s
@@ -0,0 +1,29 @@
+ .file "dwarf2-test.c"
+ .text
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+ .cfi_startproc
+ nop
+ .loc 1 1
+ ret
+ .cfi_endproc
+ .size main, .-main
+ .text
+
+ .section .debug_info,"",%progbits
+ .long 0x0
+ .value 0x2
+ .long .Ldebug_abbrev0
+ .byte 0x8
+ .uleb128 0x1
+
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+ .uleb128 0x0 # (abbrev code)
+
+# No .debug_line ok even if there is a .debug_info section and using .locs
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 0a863ff..0efcc8c 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -599,6 +599,11 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]]
run_dump_test "localpic"
run_dump_test "debug1"
+ run_dump_test "dwarf2-line-1"
+ run_dump_test "dwarf2-line-2"
+ run_dump_test "dwarf2-line-3"
+ run_dump_test "dwarf2-line-4"
+
run_dump_test "dw2-compress-2"
run_dump_test "dw2-compressed-2"