From: "Andrew Burgess" <aburgess@broadcom.com>
To: "gdb@sourceware.org" <gdb@sourceware.org>
Subject: Overlays and symbol lookup query
Date: Tue, 07 Dec 2010 15:15:00 -0000 [thread overview]
Message-ID: <4CFE4F8B.8060202@broadcom.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 9302 bytes --]
Hi,
I ran into an issue relating to overlays and would be grateful for any
advice on the best way to fix the problem.
There's a demo attached, untar, then make && make test, but the
interesting bit is the linker script:
SECTIONS
{
.text : { test.o(.text) }
OVERLAY :
{
.overlay_a { file_a.o(.text) }
.overlay_b { file_b.o(.text) }
}
}
file_a contains func_a, and file_b contains func_b.
I then start up gdb on the executable and do:
(gdb) info line func_a
Line 2 of "file_a.c" starts at address 0xc <func_a> and ends at 0xf
<func_a+3>.
(gdb) info line func_b
Line 2 of "file_a.c" starts at address 0xc <func_a> and ends at 0xf
<func_a+3>.
So gdb is clearly confused by my overlays as it thinks both symbols are
in file_a.
I know that debugging with overlays is special, but it feels like gdb
should give me a sensible answer in this case - don't know if you'll
agree with this though?
The problem is caused in find_function_start_sal(symtab.c), up to that
point we have a symbol for which we're getting the information, from the
symbol we have a symtab. We then discard the symbol/symtab and call
find_pc_sect_line which is forced to lookup the symtab based on the
address, it seems reasonable that this gives me the wrong answer as it
doesn't know which overlay is mapped in at that point.
The patch below is a _rough_ cut at solving this issue by extending
find_pc_sect_line to take a symtab* and only look one up by address if
the passed in symtab* is NULL, the rest of the changes are to fix call
sites.
This doesn't completely fix the "info line" case, the printing of the
start/end addresses is still wrong, but right now I'm just after any
feedback on the current set of changes, or if anyone thinks there's a
better way to fix this problem.
Thanks,
Andrew
diff -ur clean/src/gdb/block.c working/src/gdb/block.c
--- clean/src/gdb/block.c 2010-01-01 07:31:30.000000000 +0000
+++ working/src/gdb/block.c 2010-12-07 13:53:10.799284000 +0000
@@ -174,12 +174,12 @@
in the specified section, or 0 if there is none. */
struct block *
-block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
+block_for_pc_sect (CORE_ADDR pc, struct symtab *symtab, struct
obj_section *section)
{
struct blockvector *bl;
struct block *b;
- bl = blockvector_for_pc_sect (pc, section, &b, NULL);
+ bl = blockvector_for_pc_sect (pc, section, &b, symtab);
if (bl)
return b;
return 0;
@@ -191,7 +191,7 @@
struct block *
block_for_pc (CORE_ADDR pc)
{
- return block_for_pc_sect (pc, find_pc_mapped_section (pc));
+ return block_for_pc_sect (pc, NULL, find_pc_mapped_section (pc));
}
/* Now come some functions designed to deal with C++ namespace issues.
diff -ur clean/src/gdb/block.h working/src/gdb/block.h
--- clean/src/gdb/block.h 2010-01-01 07:31:30.000000000 +0000
+++ working/src/gdb/block.h 2010-12-07 13:53:10.811286000 +0000
@@ -147,7 +147,7 @@
extern struct block *block_for_pc (CORE_ADDR);
-extern struct block *block_for_pc_sect (CORE_ADDR, struct obj_section *);
+extern struct block * block_for_pc_sect (CORE_ADDR, struct symtab *,
struct obj_section *);
extern const char *block_scope (const struct block *block);
diff -ur clean/src/gdb/blockframe.c working/src/gdb/blockframe.c
--- clean/src/gdb/blockframe.c 2010-05-13 23:44:02.000000000 +0100
+++ working/src/gdb/blockframe.c 2010-12-07 13:53:51.042763000 +0000
@@ -136,7 +136,7 @@
struct symbol *
find_pc_sect_function (CORE_ADDR pc, struct obj_section *section)
{
- struct block *b = block_for_pc_sect (pc, section);
+ struct block *b = block_for_pc_sect (pc, NULL, section);
if (b == 0)
return 0;
diff -ur clean/src/gdb/linespec.c working/src/gdb/linespec.c
--- clean/src/gdb/linespec.c 2010-07-13 21:07:44.000000000 +0100
+++ working/src/gdb/linespec.c 2010-12-07 14:47:45.783167000 +0000
@@ -1990,6 +1990,7 @@
values.sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
+ (struct symtab*) 0,
(struct obj_section *) 0, 0);
values.sals[0].section = SYMBOL_OBJ_SECTION (msymbol);
@@ -1999,7 +2000,7 @@
values.sals[0].pc,
¤t_target);
if (pc != values.sals[0].pc)
- values.sals[0] = find_pc_sect_line (pc, NULL, 0);
+ values.sals[0] = find_pc_sect_line (pc, NULL, NULL, 0);
if (funfirstline)
skip_prologue_sal (&values.sals[0]);
diff -ur clean/src/gdb/printcmd.c working/src/gdb/printcmd.c
--- clean/src/gdb/printcmd.c 2010-10-15 19:54:12.000000000 +0100
+++ working/src/gdb/printcmd.c 2010-12-07 13:53:10.969287000 +0000
@@ -717,7 +717,7 @@
{
struct symtab_and_line sal;
- sal = find_pc_sect_line (addr, section, 0);
+ sal = find_pc_sect_line (addr, (struct symtab*)NULL, section, 0);
if (sal.symtab)
{
diff -ur clean/src/gdb/symtab.c working/src/gdb/symtab.c
--- clean/src/gdb/symtab.c 2010-10-17 19:49:46.000000000 +0100
+++ working/src/gdb/symtab.c 2010-12-07 14:02:52.237975000 +0000
@@ -1890,7 +1890,7 @@
/* If it's worth the effort, we could be using a binary search. */
struct symtab_and_line
-find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int
notcurrent)
+find_pc_sect_line (CORE_ADDR pc, struct symtab *symtab, struct
obj_section *section, int notcurrent)
{
struct symtab *s;
struct linetable *l;
@@ -2011,8 +2011,11 @@
return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
}
+ if ( symtab == NULL )
+ s = find_pc_sect_symtab (pc, section);
+ else
+ s = symtab;
- s = find_pc_sect_symtab (pc, section);
if (!s)
{
/* if no symbol information, return previous pc */
@@ -2134,7 +2137,7 @@
section = find_pc_overlay (pc);
if (pc_in_unmapped_range (pc, section))
pc = overlay_mapped_address (pc, section);
- return find_pc_sect_line (pc, section, notcurrent);
+ return find_pc_sect_line (pc, NULL, section, notcurrent);
}
\f
/* Find line number LINE in any symtab whose name is the same as
@@ -2289,7 +2292,7 @@
This also insures that we never give a range like "starts at 0x134
and ends at 0x12c". */
- found_sal = find_pc_sect_line (startaddr, sal.section, 0);
+ found_sal = find_pc_sect_line (startaddr, sal.symtab, sal.section, 0);
if (found_sal.line != sal.line)
{
/* The specified line (sal) has zero bytes. */
@@ -2416,6 +2419,7 @@
fixup_symbol_section (sym, NULL);
sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+ SYMBOL_SYMTAB (sym),
SYMBOL_OBJ_SECTION (sym), 0);
/* We always should have a line for the function start address.
@@ -2502,7 +2506,7 @@
pc = overlay_mapped_address (pc, section);
/* Calculate line number. */
- start_sal = find_pc_sect_line (pc, section, 0);
+ start_sal = find_pc_sect_line (pc, NULL, section, 0);
/* Check if gdbarch_skip_prologue left us in mid-line, and the next
line is still part of the same function. */
@@ -2515,7 +2519,7 @@
/* First pc of next line */
pc = start_sal.end;
/* Recalculate the line number (might not be N+1). */
- start_sal = find_pc_sect_line (pc, section, 0);
+ start_sal = find_pc_sect_line (pc, NULL, section, 0);
}
/* On targets with executable formats that don't have a concept of
@@ -2527,7 +2531,7 @@
{
pc = gdbarch_skip_main_prologue (gdbarch, pc);
/* Recalculate the line number (might not be N+1). */
- start_sal = find_pc_sect_line (pc, section, 0);
+ start_sal = find_pc_sect_line (pc, NULL, section, 0);
}
/* If we still don't have a valid source line, try to find the first
@@ -2542,7 +2546,7 @@
{
pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
/* Recalculate the line number. */
- start_sal = find_pc_sect_line (pc, section, 0);
+ start_sal = find_pc_sect_line (pc, NULL, section, 0);
}
do_cleanups (old_chain);
@@ -2566,7 +2570,7 @@
/* Check if we are now inside an inlined function. If we can,
use the call site of the function instead. */
- b = block_for_pc_sect (sal->pc, sal->section);
+ b = block_for_pc_sect (sal->pc, sal->symtab, sal->section);
function_block = NULL;
while (b != NULL)
{
@@ -4643,7 +4647,7 @@
set_current_program_space (ret.sals[i].pspace);
filter[i] = 1;
- blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
+ blocks[i] = block_for_pc_sect (ret.sals[i].pc,
ret.sals[i].symtab, ret.sals[i].section);
}
do_cleanups (old_chain);
diff -ur clean/src/gdb/symtab.h working/src/gdb/symtab.h
--- clean/src/gdb/symtab.h 2010-10-17 19:49:47.000000000 +0100
+++ working/src/gdb/symtab.h 2010-12-07 13:53:11.099286000 +0000
@@ -1106,6 +1106,7 @@
/* Same function, but specify a section as well as an address */
extern struct symtab_and_line find_pc_sect_line (CORE_ADDR,
+ struct symtab *,
struct obj_section *, int);
/* Given a symtab and line number, return the pc there. */
[-- Attachment #2: overlay-test.tar.bz2 --]
[-- Type: application/octet-stream, Size: 1239 bytes --]
next reply other threads:[~2010-12-07 15:15 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-07 15:15 Andrew Burgess [this message]
2010-12-08 21:59 ` Petr Hluzín
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CFE4F8B.8060202@broadcom.com \
--to=aburgess@broadcom.com \
--cc=gdb@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox