From 34248c3af73049fe1f8b7a4b9eb7ae09f42eed95 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Sat, 15 Nov 2014 10:08:34 -0800 Subject: [PATCH] PR symtab/17559 Basically the problem is that "symtab" is ambiguous. Is it the primary symtab (where we canonically think of blockvectors as being stored) or is it for a specific file (where each file's line table is stored) ? gdb_disassembly wants the symtab that contains the line table but is instead getting the primary symtab. gdb/ChangeLog: PR symtab/17559 * symtab.c (find_pc_line_symtab): New function. * symtab.h (find_pc_line_symtab): Declare. * disasm.c (gdb_disassembly): Call find_pc_line_symtab instead of find_pc_symtab. * tui/tui-disasm.c (tui_set_disassem_content): Ditto. * tui/tui-hooks.c (tui_selected_frame_level_changed_hook): Ditto. * tui/tui-source.c (tui_vertical_source_scroll): Ditto. * tui/tui-win.c (make_visible_with_new_height): Ditto. * tui/tui-winsource.c (tui_horizontal_source_scroll): Ditto. (tui_display_main): Call find_pc_line_symtab instead of find_pc_line. gdb/testsuite/ChangeLog: PR symtab/17559 * gdb.base/line-symtabs.exp: New file. * gdb.base/line-symtabs.c: New file. * gdb.base/line-symtabs.h: New file. --- gdb/ChangeLog | 14 +++++++++++ gdb/disasm.c | 5 ++-- gdb/symtab.c | 13 ++++++++++ gdb/symtab.h | 4 +++ gdb/testsuite/ChangeLog | 7 ++++++ gdb/testsuite/gdb.base/line-symtabs.c | 25 +++++++++++++++++++ gdb/testsuite/gdb.base/line-symtabs.exp | 33 +++++++++++++++++++++++++ gdb/testsuite/gdb.base/line-symtabs.h | 24 ++++++++++++++++++ gdb/tui/tui-disasm.c | 2 +- gdb/tui/tui-hooks.c | 2 +- gdb/tui/tui-source.c | 2 +- gdb/tui/tui-win.c | 2 +- gdb/tui/tui-winsource.c | 10 ++++---- 13 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 gdb/testsuite/gdb.base/line-symtabs.c create mode 100644 gdb/testsuite/gdb.base/line-symtabs.exp create mode 100644 gdb/testsuite/gdb.base/line-symtabs.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6198d5433c..6bd84c0467 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2014-11-15 Doug Evans + + PR symtab/17559 + * symtab.c (find_pc_line_symtab): New function. + * symtab.h (find_pc_line_symtab): Declare. + * disasm.c (gdb_disassembly): Call find_pc_line_symtab instead of + find_pc_symtab. + * tui/tui-disasm.c (tui_set_disassem_content): Ditto. + * tui/tui-hooks.c (tui_selected_frame_level_changed_hook): Ditto. + * tui/tui-source.c (tui_vertical_source_scroll): Ditto. + * tui/tui-win.c (make_visible_with_new_height): Ditto. + * tui/tui-winsource.c (tui_horizontal_source_scroll): Ditto. + (tui_display_main): Call find_pc_line_symtab instead of find_pc_line. + 2014-11-15 Doug Evans * symtab.c (expand_symtab_containing_pc): Renamed from diff --git a/gdb/disasm.c b/gdb/disasm.c index 6ff3793f2e..365aa94f09 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -410,13 +410,12 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout, struct ui_file *stb = mem_fileopen (); struct cleanup *cleanups = make_cleanup_ui_file_delete (stb); struct disassemble_info di = gdb_disassemble_info (gdbarch, stb); - /* To collect the instruction outputted from opcodes. */ - struct symtab *symtab = NULL; + struct symtab *symtab; struct linetable_entry *le = NULL; int nlines = -1; /* Assume symtab is valid for whole PC range. */ - symtab = find_pc_symtab (low); + symtab = find_pc_line_symtab (low); if (symtab != NULL && symtab->linetable != NULL) { diff --git a/gdb/symtab.c b/gdb/symtab.c index 4672ac31ea..d2146bb2a9 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -2431,6 +2431,19 @@ find_pc_line (CORE_ADDR pc, int notcurrent) pc = overlay_mapped_address (pc, section); return find_pc_sect_line (pc, section, notcurrent); } + +/* See symtab.h. */ + +struct symtab * +find_pc_line_symtab (CORE_ADDR pc) +{ + struct symtab_and_line sal; + + /* This always passes zero for NOTCURRENT to find_pc_line. + There are currently no callers that ever pass non-zero. */ + sal = find_pc_line (pc, 0); + return sal.symtab; +} /* Find line number LINE in any symtab whose name is the same as SYMTAB. diff --git a/gdb/symtab.h b/gdb/symtab.h index d69fbcfc32..257d3be217 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1271,6 +1271,10 @@ extern struct symtab_and_line find_pc_line (CORE_ADDR, int); extern struct symtab_and_line find_pc_sect_line (CORE_ADDR, struct obj_section *, int); +/* Wrapper around find_pc_line to just return the symtab. */ + +extern struct symtab *find_pc_line_symtab (CORE_ADDR); + /* Given a symtab and line number, return the pc there. */ extern int find_line_pc (struct symtab *, int, CORE_ADDR *); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ce9c8192c0..65687c011b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-11-15 Doug Evans + + PR symtab/17559 + * gdb.base/line-symtabs.exp: New file. + * gdb.base/line-symtabs.c: New file. + * gdb.base/line-symtabs.h: New file. + 2014-11-14 Yao Qi * gdb.dwarf2/dw2-ifort-parameter.c: Remove inline asm. diff --git a/gdb/testsuite/gdb.base/line-symtabs.c b/gdb/testsuite/gdb.base/line-symtabs.c new file mode 100644 index 0000000000..d21c711833 --- /dev/null +++ b/gdb/testsuite/gdb.base/line-symtabs.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 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 . */ + +#include "line-symtabs.h" + +int +main () +{ + header_function (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/line-symtabs.exp b/gdb/testsuite/gdb.base/line-symtabs.exp new file mode 100644 index 0000000000..9bcbb92383 --- /dev/null +++ b/gdb/testsuite/gdb.base/line-symtabs.exp @@ -0,0 +1,33 @@ +# Test handling of line symbol tables (non-primary symtabs). +# Copyright 2014 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 . + +standard_testfile .c line-symtabs.h + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return -1 +} + +if ![runto_main] { + fail "Can't run to main" + return -1 +} + +# PR 17559: gdb_disassembly was using the wrong symtab lookup function. +# It was expecting the symtab of the source file containing $pc, +# instead it was getting the primary symtab of that compilation unit. +gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here} $srcfile2]" +gdb_continue_to_breakpoint "continue to breakpoint in header" +gdb_test "disas /m" "break here.*End of assembler dump\\." diff --git a/gdb/testsuite/gdb.base/line-symtabs.h b/gdb/testsuite/gdb.base/line-symtabs.h new file mode 100644 index 0000000000..7e190606ca --- /dev/null +++ b/gdb/testsuite/gdb.base/line-symtabs.h @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 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 . */ + +int x; + +void +header_function (void) +{ + x = 42; /* break here */ +} diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c index 1c89a14cfd..88b14de31f 100644 --- a/gdb/tui/tui-disasm.c +++ b/gdb/tui/tui-disasm.c @@ -275,7 +275,7 @@ tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc) void tui_show_disassem (struct gdbarch *gdbarch, CORE_ADDR start_addr) { - struct symtab *s = find_pc_symtab (start_addr); + struct symtab *s = find_pc_line_symtab (start_addr); struct tui_win_info *win_with_focus = tui_win_with_focus (); struct tui_line_or_address val; diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c index 7db392a427..4c6e450460 100644 --- a/gdb/tui/tui-hooks.c +++ b/gdb/tui/tui-hooks.c @@ -202,7 +202,7 @@ tui_selected_frame_level_changed_hook (int level) { struct symtab *s; - s = find_pc_symtab (pc); + s = find_pc_line_symtab (pc); /* elz: This if here fixes the problem with the pc not being displayed in the tui asm layout, with no debug symbols. The value of s would be 0 here, and select_source_symtab would diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c index 7aceaa8e98..9842bb37e3 100644 --- a/gdb/tui/tui-source.c +++ b/gdb/tui/tui-source.c @@ -357,7 +357,7 @@ tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction, struct symtab_and_line cursal = get_current_source_symtab_and_line (); if (cursal.symtab == (struct symtab *) NULL) - s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL))); + s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL))); else s = cursal.symtab; diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c index 9c7a23f8b4..d17a1e4741 100644 --- a/gdb/tui/tui-win.c +++ b/gdb/tui/tui-win.c @@ -1386,7 +1386,7 @@ make_visible_with_new_height (struct tui_win_info *win_info) struct frame_info *frame = deprecated_safe_get_selected_frame (); struct gdbarch *gdbarch = get_frame_arch (frame); - s = find_pc_symtab (get_frame_pc (frame)); + s = find_pc_line_symtab (get_frame_pc (frame)); if (win_info->generic.type == SRC_WIN) { line.loa = LOA_LINE; diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c index 171b1712be..48a95e4edc 100644 --- a/gdb/tui/tui-winsource.c +++ b/gdb/tui/tui-winsource.c @@ -51,12 +51,12 @@ tui_display_main (void) tui_get_begin_asm_address (&gdbarch, &addr); if (addr != (CORE_ADDR) 0) { - struct symtab_and_line sal; + struct symtab *s; tui_update_source_windows_with_addr (gdbarch, addr); - sal = find_pc_line (addr, 0); - if (sal.symtab) - tui_update_locator_fullname (symtab_to_fullname (sal.symtab)); + s = find_pc_line_symtab (addr); + if (s != NULL) + tui_update_locator_fullname (symtab_to_fullname (s)); else tui_update_locator_fullname ("??"); } @@ -331,7 +331,7 @@ tui_horizontal_source_scroll (struct tui_win_info *win_info, = get_current_source_symtab_and_line (); if (cursal.symtab == NULL) - s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL))); + s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL))); else s = cursal.symtab; } -- 2.34.1