[1/3] Check function is GC'ed

Message ID 1408609338-17561-1-git-send-email-yao@codesourcery.com
State New, archived
Headers

Commit Message

Yao Qi Aug. 21, 2014, 8:22 a.m. UTC
  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 'textlow' field of partial symtabl to check
whether 'textlow' is zero.  If it isn't, address zero really means the
function is GC'ed.  This patch fixes the fail above.  Note that this
patch only fixes the problem on the path that partial symtab is used.
On other paths partial symtab isn't used (start gdb with --readnow for
example), I don't find a good way to fix it.

It is regression tested on x86_64-linux, arm-none-eabi,
arm-none-linux-gnueabi.  OK to apply?

gdb:

2014-08-20  Yao Qi  <yao@codesourcery.com>

	* dwarf2read.c (dwarf_decode_lines_1): Skip the line table if
	PST->textlow is greater than zero.
---
 gdb/dwarf2read.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
  

Comments

Doug Evans Aug. 22, 2014, 5:40 p.m. UTC | #1
Yao Qi writes:
 > 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 'textlow' field of partial symtabl to check
 > whether 'textlow' is zero.  If it isn't, address zero really means the
 > function is GC'ed.  This patch fixes the fail above.  Note that this
 > patch only fixes the problem on the path that partial symtab is used.
 > On other paths partial symtab isn't used (start gdb with --readnow for
 > example), I don't find a good way to fix it.
 > 
 > It is regression tested on x86_64-linux, arm-none-eabi,
 > arm-none-linux-gnueabi.  OK to apply?
 > 
 > gdb:
 > 
 > 2014-08-20  Yao Qi  <yao@codesourcery.com>
 > 
 > 	* dwarf2read.c (dwarf_decode_lines_1): Skip the line table if
 > 	PST->textlow is greater than zero.
 > ---
 >  gdb/dwarf2read.c | 9 ++++++++-
 >  1 file changed, 8 insertions(+), 1 deletion(-)
 > 
 > diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
 > index b4d53c8..cf2ce76 100644
 > --- a/gdb/dwarf2read.c
 > +++ b/gdb/dwarf2read.c
 > @@ -17229,6 +17229,8 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
 >        /* Decode the table.  */
 >        while (!end_sequence)
 >  	{
 > +	  struct partial_symtab *pst = NULL;
 > +
 >  	  op_code = read_1_byte (abfd, line_ptr);
 >  	  line_ptr += 1;
 >  	  if (line_ptr > line_end)
 > @@ -17291,7 +17293,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 (!decode_for_pst_p && !dwarf2_per_objfile->using_index)
 > +		    pst = cu->per_cu->v.psymtab;
 > +
 > +		  if (address == 0
 > +		      && (!dwarf2_per_objfile->has_section_at_zero
 > +			  || (pst != NULL && pst->textlow > address)))
 >  		    {
 >  		      /* This line table is for a function which has been
 >  			 GCd by the linker.  Ignore it.  PR gdb/12528 */

Hi.

I'd like to solve this for both partial syms and .gdb_index.

We want to, essentially, discard the entry if address is outside the
range of the cu (the range needn't be contiguous, but for the task
at hand I don't think it matters).  I haven't dug into this too deeply,
but if we have lowpc (which for example is that read_file_scope has
before it calls handle_DW_AT_stmt_list (which calls dwarf_decode_lines),
can we use that in the test?  Can we arrange for all callers of
dwarf_decode_lines_1 pass lowpc down to it? [Or both lowpc,highpc
for a more complete test, but for the task at hand we've only been
checking, effectively, lowpc all along so I don't mind leaving it at that
for now.]
  

Patch

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index b4d53c8..cf2ce76 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17229,6 +17229,8 @@  dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
       /* Decode the table.  */
       while (!end_sequence)
 	{
+	  struct partial_symtab *pst = NULL;
+
 	  op_code = read_1_byte (abfd, line_ptr);
 	  line_ptr += 1;
 	  if (line_ptr > line_end)
@@ -17291,7 +17293,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 (!decode_for_pst_p && !dwarf2_per_objfile->using_index)
+		    pst = cu->per_cu->v.psymtab;
+
+		  if (address == 0
+		      && (!dwarf2_per_objfile->has_section_at_zero
+			  || (pst != NULL && pst->textlow > address)))
 		    {
 		      /* This line table is for a function which has been
 			 GCd by the linker.  Ignore it.  PR gdb/12528 */