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:
parent
8e635c209b
commit
c3b7b696c2
4 changed files with 59 additions and 16 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue