Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches@sourceware.org
Cc: Daniel Jacobowitz <drow@false.org>
Subject: Re: [patch] Parse DW_AT_ranges into PSYMTABS (for childless CU, 	for  vDSO32)
Date: Tue, 09 Oct 2007 18:59:00 -0000	[thread overview]
Message-ID: <20071009185434.GA27810@host0.dyn.jankratochvil.net> (raw)
In-Reply-To: <20071009181701.GA30757@caradoc.them.org>

[-- Attachment #1: Type: text/plain, Size: 1585 bytes --]

On Tue, 09 Oct 2007 20:17:01 +0200, Daniel Jacobowitz wrote:
> On Tue, Oct 09, 2007 at 08:02:46PM +0200, Jan Kratochvil wrote:
> > DW_TAG_compile_unit has no children and it has neither DW_AT_low_pc nor
> > DW_AT_high_pc but it has DW_AT_ranges instead.  So far DW_AT_ranges was not
> > parsed into PSYMTABS and so this file was ignored during the debug info search
> > later.  Reasons for the discontinuous vDSO32 layout/hack are in the Linux
> > kernel sources.
> 
> I'm curious, why is this?  I couldn't find them in my kernel tree.

linux-2.6.22/arch/x86_64/ia32/vsyscall.lds
  /* This is an 32bit object and we cannot easily get the offsets
     into the 64bit kernel. Just hardcode them here. This assumes
     that all the stubs don't need more than 0x100 bytes. */
  . = VSYSCALL_BASE + 0x500;


> > +# Avoid `-lm' from `lib/ada.exp' as it would fail with out `-nostdlib'.
> > +# Provide BOARD for SET_BOARD_INFO.
> > +set board [target_info name]
> > +set_board_info mathlib ""
> 
> Actually this is from DejaGNU.  And it's global state, so you have
> just made other tests behave differently depending on whether you run
> this one first or not.

Overlooked it, thanks.  Saved/restored it in the attached updated patch.
I understand it is very ugly hack, it would be probably more appropriate to fix
`lib/ada.exp' instead.


> I bet you don't need a custom linker script and -nostdlib to test
> this.  Gas must be generating the DW_AT_ranges itself regardless of
> whether there's a gap.

Which one, .space, .org +x? These all fill the space with flesh bytes.


Regards,
Jan

[-- Attachment #2: gdb-6.6-cu-ranges.patch --]
[-- Type: text/plain, Size: 13755 bytes --]

2007-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* dwarf2read.c (dwarf2_get_pc_bounds): Moved the `DW_AT_ranges' parsing
	code with its variables OBJFILE, CU_HEADER and OBFD into ...
	(dwarf2_ranges_read): ... a new function.
	(read_partial_die): Implemented the parsing of `DW_AT_ranges'.

2007-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.dwarf2/dw2-ranges.S, gdb.dwarf2/dw2-ranges.exp,
	gdb.dwarf2/dw2-ranges.lds: New files.

--- ./gdb/dwarf2read.c	26 Sep 2007 13:59:54 -0000	1.232
+++ ./gdb/dwarf2read.c	9 Oct 2007 15:03:09 -0000
@@ -3075,6 +3075,124 @@ read_lexical_block_scope (struct die_inf
   local_symbols = new->locals;
 }
 
+/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
+   Return 1 if the attributes are present and valid, otherwise, return 0.  */
+
+static int
+dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
+		    CORE_ADDR *high_return, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct comp_unit_head *cu_header = &cu->header;
+  bfd *obfd = objfile->obfd;
+  unsigned int addr_size = cu_header->addr_size;
+  CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+  /* Base address selection entry.  */
+  CORE_ADDR base;
+  int found_base;
+  unsigned int dummy;
+  gdb_byte *buffer;
+  CORE_ADDR marker;
+  int low_set;
+  CORE_ADDR low = 0;
+  CORE_ADDR high = 0;
+
+  found_base = cu_header->base_known;
+  base = cu_header->base_address;
+
+  if (offset >= dwarf2_per_objfile->ranges_size)
+    {
+      complaint (&symfile_complaints,
+		 _("Offset %d out of bounds for DW_AT_ranges attribute"),
+		 offset);
+      return 0;
+    }
+  buffer = dwarf2_per_objfile->ranges_buffer + offset;
+
+  /* Read in the largest possible address.  */
+  marker = read_address (obfd, buffer, cu, &dummy);
+  if ((marker & mask) == mask)
+    {
+      /* If we found the largest possible address, then
+	 read the base address.  */
+      base = read_address (obfd, buffer + addr_size, cu, &dummy);
+      buffer += 2 * addr_size;
+      offset += 2 * addr_size;
+      found_base = 1;
+    }
+
+  low_set = 0;
+
+  while (1)
+    {
+      CORE_ADDR range_beginning, range_end;
+
+      range_beginning = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      range_end = read_address (obfd, buffer, cu, &dummy);
+      buffer += addr_size;
+      offset += 2 * addr_size;
+
+      /* An end of list marker is a pair of zero addresses.  */
+      if (range_beginning == 0 && range_end == 0)
+	/* Found the end of list entry.  */
+	break;
+
+      /* Each base address selection entry is a pair of 2 values.
+	 The first is the largest possible address, the second is
+	 the base address.  Check for a base address here.  */
+      if ((range_beginning & mask) == mask)
+	{
+	  /* If we found the largest possible address, then
+	     read the base address.  */
+	  base = read_address (obfd, buffer + addr_size, cu, &dummy);
+	  found_base = 1;
+	  continue;
+	}
+
+      if (!found_base)
+	{
+	  /* We have no valid base address for the ranges
+	     data.  */
+	  complaint (&symfile_complaints,
+		     _("Invalid .debug_ranges data (no base address)"));
+	  return 0;
+	}
+
+      range_beginning += base;
+      range_end += base;
+
+      /* FIXME: This is recording everything as a low-high
+	 segment of consecutive addresses.  We should have a
+	 data structure for discontiguous block ranges
+	 instead.  */
+      if (! low_set)
+	{
+	  low = range_beginning;
+	  high = range_end;
+	  low_set = 1;
+	}
+      else
+	{
+	  if (range_beginning < low)
+	    low = range_beginning;
+	  if (range_end > high)
+	    high = range_end;
+	}
+    }
+
+  if (! low_set)
+    /* If the first entry is an end-of-list marker, the range
+       describes an empty scope, i.e. no instructions.  */
+    return 0;
+
+  if (low_return)
+    *low_return = low;
+  if (high_return)
+    *high_return = high;
+  return 1;
+}
+
 /* Get low and high pc attributes from a die.  Return 1 if the attributes
    are present and valid, otherwise, return 0.  Return -1 if the range is
    discontinuous, i.e. derived from DW_AT_ranges information.  */
@@ -3082,10 +3200,7 @@ static int
 dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 		      CORE_ADDR *highpc, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->objfile;
-  struct comp_unit_head *cu_header = &cu->header;
   struct attribute *attr;
-  bfd *obfd = objfile->obfd;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
   int ret = 0;
@@ -3109,108 +3224,11 @@ dwarf2_get_pc_bounds (struct die_info *d
       attr = dwarf2_attr (die, DW_AT_ranges, cu);
       if (attr != NULL)
 	{
-	  unsigned int addr_size = cu_header->addr_size;
-	  CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
 	  /* Value of the DW_AT_ranges attribute is the offset in the
 	     .debug_ranges section.  */
-	  unsigned int offset = DW_UNSND (attr);
-	  /* Base address selection entry.  */
-	  CORE_ADDR base;
-	  int found_base;
-	  unsigned int dummy;
-	  gdb_byte *buffer;
-	  CORE_ADDR marker;
-	  int low_set;
- 
-	  found_base = cu_header->base_known;
-	  base = cu_header->base_address;
-
-	  if (offset >= dwarf2_per_objfile->ranges_size)
-	    {
-	      complaint (&symfile_complaints,
-	                 _("Offset %d out of bounds for DW_AT_ranges attribute"),
-			 offset);
-	      return 0;
-	    }
-	  buffer = dwarf2_per_objfile->ranges_buffer + offset;
-
-	  /* Read in the largest possible address.  */
-	  marker = read_address (obfd, buffer, cu, &dummy);
-	  if ((marker & mask) == mask)
-	    {
-	      /* If we found the largest possible address, then
-		 read the base address.  */
-	      base = read_address (obfd, buffer + addr_size, cu, &dummy);
-	      buffer += 2 * addr_size;
-	      offset += 2 * addr_size;
-	      found_base = 1;
-	    }
-
-	  low_set = 0;
-
-	  while (1)
-	    {
-	      CORE_ADDR range_beginning, range_end;
-
-	      range_beginning = read_address (obfd, buffer, cu, &dummy);
-	      buffer += addr_size;
-	      range_end = read_address (obfd, buffer, cu, &dummy);
-	      buffer += addr_size;
-	      offset += 2 * addr_size;
-
-	      /* An end of list marker is a pair of zero addresses.  */
-	      if (range_beginning == 0 && range_end == 0)
-		/* Found the end of list entry.  */
-		break;
-
-	      /* Each base address selection entry is a pair of 2 values.
-		 The first is the largest possible address, the second is
-		 the base address.  Check for a base address here.  */
-	      if ((range_beginning & mask) == mask)
-		{
-		  /* If we found the largest possible address, then
-		     read the base address.  */
-		  base = read_address (obfd, buffer + addr_size, cu, &dummy);
-		  found_base = 1;
-		  continue;
-		}
-
-	      if (!found_base)
-		{
-		  /* We have no valid base address for the ranges
-		     data.  */
-		  complaint (&symfile_complaints,
-			     _("Invalid .debug_ranges data (no base address)"));
-		  return 0;
-		}
-
-	      range_beginning += base;
-	      range_end += base;
-
-	      /* FIXME: This is recording everything as a low-high
-		 segment of consecutive addresses.  We should have a
-		 data structure for discontiguous block ranges
-		 instead.  */
-	      if (! low_set)
-		{
-		  low = range_beginning;
-		  high = range_end;
-		  low_set = 1;
-		}
-	      else
-		{
-		  if (range_beginning < low)
-		    low = range_beginning;
-		  if (range_end > high)
-		    high = range_end;
-		}
-	    }
-
-	  if (! low_set)
-	    /* If the first entry is an end-of-list marker, the range
-	       describes an empty scope, i.e. no instructions.  */
+	  if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu))
 	    return 0;
-
+	  /* Found discontinuous range of addresses.  */
 	  ret = -1;
 	}
     }
@@ -5571,6 +5589,11 @@ read_partial_die (struct partial_die_inf
 	  has_high_pc_attr = 1;
 	  part_die->highpc = DW_ADDR (&attr);
 	  break;
+	case DW_AT_ranges:
+	  if (dwarf2_ranges_read (DW_UNSND (&attr), &part_die->lowpc,
+				  &part_die->highpc, cu))
+	    has_low_pc_attr = has_high_pc_attr = 1;
+	  break;
 	case DW_AT_location:
           /* Support the .debug_loc offsets */
           if (attr_form_is_block (&attr))
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.dwarf2/dw2-ranges.S	9 Oct 2007 15:03:10 -0000
@@ -0,0 +1,33 @@
+/*
+   Copyright 2007 Free Software Foundation, Inc.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+	.text
+
+	.section	.text._start, "ax", @progbits
+	.globl	_start
+	.func	_start
+_start:	call	func
+	.endfunc
+	.size	_start, . - _start
+
+	.section	.text.func, "ax", @progbits
+	.globl	func
+	.func	func
+func:	int3
+	nop
+	.endfunc
+	.size	func, . - func
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.dwarf2/dw2-ranges.exp	9 Oct 2007 15:03:10 -0000
@@ -0,0 +1,98 @@
+# Copyright 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test DW_TAG_compile_unit with no children and with neither DW_AT_low_pc nor
+# DW_AT_high_pc but with DW_AT_ranges instead.  We created the hole there for
+# DW_AT_ranges by the linker script.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    verbose "Skipping i386/amd64 DW_AT_ranges test."
+    return 0  
+}
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } then {
+    verbose "Skipping i386/amd64 DW_AT_ranges test."
+    return 0
+}
+
+set testfile "dw2-ranges"
+set srcfile ${testfile}.S
+set ldsfile ${testfile}.lds
+set binfile ${objdir}/${subdir}/${testfile}
+
+# Avoid `-lm' from `lib/ada.exp' as it would fail with our `-nostdlib'.
+# Provide BOARD for SET_BOARD_INFO.
+set board [target_info name]
+if [board_info $board exists mathlib] {
+    set mathlib_orig [board_info $board mathlib]
+} else {
+    unset -nocomplain mathlib_orig
+}
+set_board_info mathlib ""
+
+set compiled [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-Wl,--script=${srcdir}/${subdir}/${ldsfile} -nostdlib"]]
+
+# Restore the board info.
+if [info exists mathlib_orig] {
+    # SET_BOARD_INFO does not change an already set value.
+    set board_info($board,mathlib) $mathlib_orig
+} else {
+    # There is no deleting function for the board info.
+    unset board_info($board,mathlib)
+}
+
+if  { $compiled != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Former wrong output:
+# 	Program received signal SIGTRAP, Trace/breakpoint trap.
+# 	0x000000000000002b in func ()
+# 	(gdb) bt
+# 	#0  0x000000000000002b in func ()
+# 	#1  0x0000000000000029 in _start ()
+# 	(gdb) _
+# Correct output:
+# 	Program received signal SIGTRAP, Trace/breakpoint trap.
+# 	func () at dw2-ranges.S:14
+# 	14              nop
+# 	Current language:  auto; currently asm
+# 	(gdb) bt
+# 	#0  func () at dw2-ranges.S:14
+# 	#1  0x0000000000000029 in _start () at dw2-ranges.S:6
+# 	(gdb) _
+# The entry #1 is missing on i386.
+# 	"#0 +func \\(\\) at .*dw2-ranges.S:\[0-9\]+\r\n#1 .*in _start \\(\\) at .*dw2-ranges.S:\[0-9\]+"
+
+gdb_run_cmd
+set test "run"
+gdb_test_multiple "" "$test" {
+    -re "Program received signal SIGTRAP,.*$gdb_prompt $" {
+	pass $test
+    }
+}
+
+gdb_test "backtrace" "#0 +func \\(\\) at .*dw2-ranges.S:\[0-9\]+"
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.dwarf2/dw2-ranges.lds	9 Oct 2007 15:03:10 -0000
@@ -0,0 +1,25 @@
+/*
+   Copyright 2007 Free Software Foundation, Inc.
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+SECTIONS
+{
+	.text._start : { *(.text._start) }
+	/* Create the hole.  */
+	. = . + 1;
+	.text.func : { *(.text.func) }
+}
+ENTRY(_start)

  reply	other threads:[~2007-10-09 18:54 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-09 18:17 Jan Kratochvil
2007-10-09 18:22 ` Daniel Jacobowitz
2007-10-09 18:59   ` Jan Kratochvil [this message]
2007-10-09 19:13     ` Daniel Jacobowitz
2007-11-24 15:43       ` Jan Kratochvil
2007-11-25 14:48         ` Daniel Jacobowitz
2007-11-30  7:42         ` Vladimir Prus
2007-11-30 11:10           ` Jan Kratochvil
2007-11-30 14:56             ` Daniel Jacobowitz
2007-11-30 15:09               ` Jan Kratochvil
2007-12-01  0:55               ` Jim Blandy
2007-12-01 17:30                 ` Joel Brobecker
2007-12-09 20:40               ` [patch] Discontiguous PSYMTABs [Re: [patch] Parse DW_AT_ranges into PSYMTABS (for childless CU, for vDSO32)] Jan Kratochvil
2007-12-10  0:21                 ` [patch] Removal of the FIND_PC_SECT_PSYMTAB search [Re: [patch] Discontiguous PSYMTABs] Jan Kratochvil
2007-12-17  1:02                 ` [patch] Discontiguous PSYMTABs [Re: [patch] Parse DW_AT_ranges into PSYMTABS (for childless CU, for vDSO32)] Daniel Jacobowitz
2007-12-17  1:03                   ` Daniel Jacobowitz
2007-12-17  2:41                     ` [patch] Discontiguous PSYMTABs Jan Kratochvil
2007-12-17  3:41                       ` Daniel Jacobowitz
2008-04-23 22:15                     ` [patch] [0/2] " Jan Kratochvil
2008-04-23 22:18                     ` [patch] [1/2] Discontiguous PSYMTABs (partial DIEs base address) Jan Kratochvil
2008-05-01 19:43                       ` Daniel Jacobowitz
2008-04-23 22:24                     ` [patch] [2/2] Discontiguous PSYMTABs (psymtabs->symtabs by addrmap) Jan Kratochvil
2008-05-01 19:46                       ` Daniel Jacobowitz
2008-05-04 17:38                         ` Jan Kratochvil
2008-05-12 22:24                       ` Overlay support broken (Re: [patch] [2/2] Discontiguous PSYMTABs (psymtabs->symtabs by addrmap)) Ulrich Weigand
2008-05-12 22:37                         ` Michael Snyder
2008-05-13  1:39                           ` Daniel Jacobowitz
2008-05-13  3:17                             ` Jan Kratochvil
2008-05-13 15:37                             ` Doug Evans
2008-05-13 15:42                             ` Michael Snyder
2008-05-13 15:31                           ` Doug Evans
2008-05-12 23:52                         ` Jan Kratochvil
2008-05-13 18:45                           ` Ulrich Weigand
2008-05-13 19:08                             ` Pedro Alves
2008-05-13 19:01                               ` Pedro Alves
2008-05-13 19:11                               ` Michael Snyder
2008-05-15 16:39                             ` Jan Kratochvil
2008-05-15 18:16                               ` Ulrich Weigand
2008-05-15 18:44                                 ` Daniel Jacobowitz
2008-05-15 19:06                                   ` Ulrich Weigand
2008-05-16 18:32                                   ` Ulrich Weigand
2008-05-15 19:18                               ` Michael Snyder
2008-04-23 21:31                 ` [patch] Discontiguous PSYMTABs [Re: [patch] Parse DW_AT_ranges into PSYMTABS (for childless CU, for vDSO32)] Doug Evans
2008-04-23 21:31                   ` Jan Kratochvil

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=20071009185434.GA27810@host0.dyn.jankratochvil.net \
    --to=jan.kratochvil@redhat.com \
    --cc=drow@false.org \
    --cc=gdb-patches@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