diff --git a/gdb/linespec.c b/gdb/linespec.c
index 94400f3f336..1d8d2ca3273 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -4102,7 +4102,7 @@ decode_digits_list_mode (struct linespec_state *self,
val.symtab = elt;
val.pspace = SYMTAB_PSPACE (elt);
val.pc = 0;
- val.explicit_line = 1;
+ val.explicit_line = true;
add_sal_to_sals (self, &values, &val, NULL, 0);
}
@@ -4136,6 +4136,7 @@ decode_digits_ordinary (struct linespec_state *self,
sal.pspace = SYMTAB_PSPACE (elt);
sal.symtab = elt;
sal.line = line;
+ sal.explicit_line = true;
sal.pc = pc;
sals.push_back (std::move (sal));
}
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 4920d94a247..c10e6b3e358 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3693,6 +3693,15 @@ skip_prologue_sal (struct symtab_and_line *sal)
if (sal->explicit_pc)
return;
+ /* In assembly code, if the user asks for a specific line then we should
+ not adjust the SAL. The user already has instruction level
+ visibility in this case, so selecting a line other than one requested
+ is likely to be the wrong choice. */
+ if (sal->symtab != nullptr
+ && sal->explicit_line
+ && SYMTAB_LANGUAGE (sal->symtab) == language_asm)
+ return;
+
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (sal->pspace);
@@ -3812,12 +3821,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
sal->pc = pc;
sal->section = section;
-
- /* Unless the explicit_line flag was set, update the SAL line
- and symtab to correspond to the modified PC location. */
- if (sal->explicit_line)
- return;
-
sal->symtab = start_sal.symtab;
sal->line = start_sal.line;
sal->end = start_sal.end;
diff --git a/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.S b/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.S
new file mode 100644
index 00000000000..698c3e6d624
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.S
@@ -0,0 +1,35 @@
+/* Copyright 2019 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ This file is part of the gdb testsuite.
+
+ Test that a breakpoint place by line number in an assembler file
+ will stop at the specified line. Previously versions of GDB have
+ incorrectly invoked the prologue analysis logic and skipped
+ forward. */
+
+ .text
+ .global main
+main:
+ nop
+test:
+ /* The next two instructions are required to look like an
+ x86-64 prologue so that GDB's prologue scanner will spot
+ them and skip forward. */
+ push %rbp /* Break here. */
+ mov %rsp, %rbp
+ nop /* Incorrect. */
+ nop
+ nop
diff --git a/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.exp b/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.exp
new file mode 100644
index 00000000000..6218ce541bd
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-break-on-asm-line.exp
@@ -0,0 +1,35 @@
+# Copyright 2019 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+ return
+}
+
+standard_testfile .S
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ { debug }] } {
+ untested "could not compile"
+ return -1
+}
+
+if ![runto_main] {
+ untested "could not run to main"
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here"]
+gdb_continue_to_breakpoint "Break on specified line" \
+ ".*/\\* Break here\\. \\*/.*"