Check function is GC'ed

I see the following fail on arm-none-eabi target,

(gdb) b 24^M
Breakpoint 1 at 0x4: file
../../../../git/gdb/testsuite/gdb.base/break-on-linker-gcd-function.cc,
line 24.^M
(gdb) FAIL: gdb.base/break-on-linker-gcd-function.exp: b 24

Currently, we are using flag has_section_at_zero to determine whether
address zero in debug info means the corresponding code has been
GC'ed, like this:

	case DW_LNE_set_address:
	  address = read_address (abfd, line_ptr, cu, &bytes_read);

	  if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
	    {
	      /* This line table is for a function which has been
		 GCd by the linker.  Ignore it.  PR gdb/12528 */

However, this is incorrect on some bare metal targets, as .text
section is located at 0x0, so dwarf2_per_objfile->has_section_at_zero
is true.  If a function is GC'ed by linker, the address is zero.  GDB
thinks address zero is a function's address rather than this function
is GC'ed.

In this patch, we choose 'lowpc' got in read_file_scope to check
whether 'lowpc' is greater than zero.  If it isn't, address zero really
means the function is GC'ed.  In this patch, we pass 'lowpc' in
read_file_scope through handle_DW_AT_stmt_list and dwarf_decode_lines,
and to dwarf_decode_lines_1 finally.

This patch fixes the fail above. This patch also covers the path that
partial symbol isn't used, which is tested by starting gdb with
--readnow option.

It is regression tested on x86-linux with
target_board=dwarf4-gdb-index, and arm-none-eabi.  OK to apply?

gdb:

2014-09-19  Yao Qi  <yao@codesourcery.com>

	* dwarf2read.c (dwarf_decode_lines): Update declaration.
	(handle_DW_AT_stmt_list): Add argument 'lowpc'.  Update
	comments.  Callers update.
	(dwarf_decode_lines): Likewise.
	(dwarf_decode_lines_1): Add argument 'lowpc'.  Update
	comments.  Skip the line table if  'lowpc' is greater than
	'address'.  Don't check
	dwarf2_per_objfile->has_section_at_zero.

gdb/testsuite:

2014-09-19  Yao Qi  <yao@codesourcery.com>

	* gdb.base/break-on-linker-gcd-function.exp: Move test into new
	proc set_breakpoint_on_gcd_function.  Invoke
	set_breakpoint_on_gcd_function.  Restart GDB with --readnow and
	invoke set_breakpoint_on_gcd_function again.
This commit is contained in:
Yao Qi 2014-08-04 14:57:22 +08:00
parent 8e635c209b
commit c3b7b696c2
4 changed files with 59 additions and 16 deletions

View file

@ -1,3 +1,14 @@
2014-09-19 Yao Qi <yao@codesourcery.com>
* dwarf2read.c (dwarf_decode_lines): Update declaration.
(handle_DW_AT_stmt_list): Add argument 'lowpc'. Update
comments. Callers update.
(dwarf_decode_lines): Likewise.
(dwarf_decode_lines_1): Add argument 'lowpc'. Update
comments. Skip the line table if 'lowpc' is greater than
'address'. Don't check
dwarf2_per_objfile->has_section_at_zero.
2014-09-18 Doug Evans <dje@google.com>
* NEWS: Mention new "producer" attribute of gdb.Symtab.

View file

@ -1512,7 +1512,8 @@ static struct line_header *dwarf_decode_line_header (unsigned int offset,
struct dwarf2_cu *cu);
static void dwarf_decode_lines (struct line_header *, const char *,
struct dwarf2_cu *, struct partial_symtab *);
struct dwarf2_cu *, struct partial_symtab *,
CORE_ADDR);
static void dwarf2_start_subfile (const char *, const char *, const char *);
@ -4448,7 +4449,7 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
return; /* No linetable, so no includes. */
/* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
dwarf_decode_lines (lh, pst->dirname, cu, pst);
dwarf_decode_lines (lh, pst->dirname, cu, pst, pst->textlow);
free_line_header (lh);
}
@ -8967,11 +8968,12 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
/* Handle DW_AT_stmt_list for a compilation unit.
DIE is the DW_TAG_compile_unit die for CU.
COMP_DIR is the compilation directory. */
COMP_DIR is the compilation directory. LOWPC is passed to
dwarf_decode_lines. See dwarf_decode_lines comments about it. */
static void
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
const char *comp_dir) /* ARI: editCase function */
const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
{
struct attribute *attr;
@ -8988,7 +8990,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
{
cu->line_header = line_header;
make_cleanup (free_cu_line_header, cu);
dwarf_decode_lines (line_header, comp_dir, cu, NULL);
dwarf_decode_lines (line_header, comp_dir, cu, NULL, lowpc);
}
}
}
@ -9039,7 +9041,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Decode line number information if present. We do this before
processing child DIEs, so that the line header table is available
for DW_AT_decl_file. */
handle_DW_AT_stmt_list (die, cu, comp_dir);
handle_DW_AT_stmt_list (die, cu, comp_dir, lowpc);
/* Process all dies in compilation unit. */
if (die->child != NULL)
@ -17252,7 +17254,8 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
static void
dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
struct dwarf2_cu *cu, const int decode_for_pst_p)
struct dwarf2_cu *cu, const int decode_for_pst_p,
CORE_ADDR lowpc)
{
const gdb_byte *line_ptr, *extended_end;
const gdb_byte *line_end;
@ -17375,7 +17378,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
case DW_LNE_set_address:
address = read_address (abfd, line_ptr, cu, &bytes_read);
if (address == 0 && !dwarf2_per_objfile->has_section_at_zero)
/* If address < lowpc then it's not a usable value, it's
outside the pc range of the CU. However, we restrict
the test to only address values of zero to preserve
GDB's previous behaviour which is to handle the specific
case of a function being GC'd by the linker. */
if (address == 0 && address < lowpc)
{
/* This line table is for a function which has been
GCd by the linker. Ignore it. PR gdb/12528 */
@ -17595,17 +17603,20 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
as the corresponding symtab. Since COMP_DIR is not used in the name of the
symtab we don't use it in the name of the psymtabs we create.
E.g. expand_line_sal requires this when finding psymtabs to expand.
A good testcase for this is mb-inline.exp. */
A good testcase for this is mb-inline.exp.
LOWPC is the lowest address in CU (or 0 if not known). */
static void
dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
struct dwarf2_cu *cu, struct partial_symtab *pst)
struct dwarf2_cu *cu, struct partial_symtab *pst,
CORE_ADDR lowpc)
{
struct objfile *objfile = cu->objfile;
const int decode_for_pst_p = (pst != NULL);
struct subfile *first_subfile = current_subfile;
dwarf_decode_lines_1 (lh, comp_dir, cu, decode_for_pst_p);
dwarf_decode_lines_1 (lh, comp_dir, cu, decode_for_pst_p, lowpc);
if (decode_for_pst_p)
{

View file

@ -1,3 +1,10 @@
2014-09-19 Yao Qi <yao@codesourcery.com>
* gdb.base/break-on-linker-gcd-function.exp: Move test into new
proc set_breakpoint_on_gcd_function. Invoke
set_breakpoint_on_gcd_function. Restart GDB with --readnow and
invoke set_breakpoint_on_gcd_function again.
2014-09-18 Doug Evans <dje@google.com>
* gdb.dwarf2/symtab-producer.exp: New file.

View file

@ -41,9 +41,23 @@ if {[build_executable_from_specs $testfile.exp $testfile \
clean_restart $testfile
# Single hex digit
set xd {[0-9a-f]}
proc set_breakpoint_on_gcd_function {} {
# Single hex digit
set xd {[0-9a-f]}
# This accepts e.g. "Breakpoint 1 at 0x40968a" (fixed GDB)
# but rejects e.g. "Breakpoint 1 at 0x4" (broken GDB).
gdb_test "b [gdb_get_line_number "gdb break here"]" "Breakpoint \[0-9\] at 0x${xd}${xd}+: .*"
# This accepts e.g. "Breakpoint 1 at 0x40968a" (fixed GDB)
# but rejects e.g. "Breakpoint 1 at 0x4" (broken GDB).
gdb_test "b [gdb_get_line_number "gdb break here"]" \
"Breakpoint \[0-9\] at 0x${xd}${xd}+: .*"
}
set_breakpoint_on_gcd_function
set saved_gdbflags $GDBFLAGS
set GDBFLAGS "$GDBFLAGS --readnow"
clean_restart ${testfile}
set GDBFLAGS $saved_gdbflags
with_test_prefix "readnow" {
set_breakpoint_on_gcd_function
}