This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Overlays and symbol lookup query


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,
                                            &current_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);
 }
 
 /* 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: overlay-test.tar.bz2
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]