public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v3 6/8] Introduce find_pc_partial_entry_range and use it in infrun.c
Date: Mon, 20 Aug 2018 22:46:00 -0000	[thread overview]
Message-ID: <20180820154546.5a9f9c6f@pinnacle.lan> (raw)
In-Reply-To: <20180820152512.671a7dc7@pinnacle.lan>

An earlier version of this patch used the returned block in conjunction
with BLOCK_ENTRY_PC to set stop_func_start in fill_in_stop_func() in
infrun.c.  While I think this was the correct thing to do, changes
to find_inferior_partial_function could potentially end up with
stop_func_end < stop_func_start, which is definitely wrong.  For
this case, we want to set both stop_func_start and stop_func_end
to the start and end of the range containing the function's entry
pc.

I think that this functionality will be useful in many other places
too - it probably ought to be used in all of the various prologue
analyzers in GDB.

The change to infrun.c was simple: the call to find_pc_partial_function
was replaced with a call to find_pc_partial_entry_range.  The difference
between these two functions is that find_pc_partial_entry_function
will (potentially) return the start and end address corresponding to
the range in which PC is found, but find_pc_partial_entry_range
will (again, potentially) return the start and end address of the
range containing the entry pc.  find_pc_partial_function has the
property that *ADDRESS <= PC < *ENDADDR.  This condition does not
necessarily hold for the outputs of find_pc_partial_entry_range.

It should be noted that for functions which contain only a single
range, the outputs of find_pc_partial_{function,entry_range} are
identical.

I think it might happen that find_pc_partial_entry_range will come
to be used in place of many of the calls to find_pc_partial_function
within GDB.  Care must be taken in making this change, however, since
some of this code depends on the *ADDRESS <= PC < *ENDADDR property.

gdb/ChangeLog:
    
    	* infrun.c (fill_in_stop_func): Use find_pc_partial_entry_range
    	in place of find_pc_partial_function.
    	* blockframe.c (find_pc_partial_entry_range): New function.
    	* symtab.h (find_pc_partial_entry_range): Declare and document.
---
 gdb/blockframe.c | 37 +++++++++++++++++++++++++++++++++++++
 gdb/infrun.c     |  7 ++++---
 gdb/symtab.h     | 20 +++++++++++++++++++-
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 95eed75..2d09740 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -358,6 +358,43 @@ find_pc_partial_function (CORE_ADDR pc, const char **name, CORE_ADDR *address,
 
 /* See symtab.h.  */
 
+bool
+find_pc_partial_entry_range (CORE_ADDR pc, const char **name,
+                             CORE_ADDR *address, CORE_ADDR *endaddr)
+{
+  const struct block *block;
+  bool status = find_pc_partial_function (pc, name, address, endaddr, &block);
+
+  if (status && block != nullptr && !BLOCK_CONTIGUOUS_P (block))
+    {
+      CORE_ADDR entry_pc = BLOCK_ENTRY_PC (block);
+
+      for (int i = 0; i < BLOCK_NRANGES (block); i++)
+        {
+	  if (BLOCK_RANGE_START (block, i) <= entry_pc
+	      && entry_pc < BLOCK_RANGE_END (block, i))
+	    {
+	      if (address != nullptr)
+	        *address = BLOCK_RANGE_START (block, i);
+
+	      if (endaddr != nullptr)
+	        *endaddr = BLOCK_RANGE_END (block, i);
+
+	      return status;
+	    }
+	}
+
+      /* It's an internal error if we exit the above loop without finding
+         the range.  */
+      internal_error (__FILE__, __LINE__,
+                      _("Entry block not found in find_pc_partial_entry_range"));
+    }
+
+  return status;
+}
+
+/* See symtab.h.  */
+
 struct type *
 find_function_type (CORE_ADDR pc)
 {
diff --git a/gdb/infrun.c b/gdb/infrun.c
index b25d745..fb72880 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4285,11 +4285,12 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 {
   if (!ecs->stop_func_filled_in)
     {
+
       /* Don't care about return value; stop_func_start and stop_func_name
 	 will both be 0 if it doesn't work.  */
-      find_pc_partial_function (ecs->event_thread->suspend.stop_pc,
-				&ecs->stop_func_name,
-				&ecs->stop_func_start, &ecs->stop_func_end);
+      find_pc_partial_entry_range (ecs->event_thread->suspend.stop_pc,
+				   &ecs->stop_func_name,
+				   &ecs->stop_func_start, &ecs->stop_func_end);
       ecs->stop_func_start
 	+= gdbarch_deprecated_function_start_offset (gdbarch);
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 746b5e6..fc47a3a 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1725,12 +1725,30 @@ extern struct symbol *find_symbol_at_address (CORE_ADDR);
    This might suggest that *ADDRESS and *ENDADDR ought to be set to the
    limits of the entry pc range, but that will cause the 
    *ADDRESS <= PC < *ENDADDR condition to be violated; many of the
-   callers of find_pc_partial_function expect this condition to hold.  */
+   callers of find_pc_partial_function expect this condition to hold. 
+
+   Callers which require the start and/or end addresses for the range
+   containing the entry pc should instead call
+   find_pc_partial_entry_range.  */
 
 extern int find_pc_partial_function (CORE_ADDR pc, const char **name,
 				     CORE_ADDR *address, CORE_ADDR *endaddr,
 				     const struct block **block = nullptr);
 
+/* Like find_pc_partial_function, above, but *ADDRESS and *ENDADDR are
+   set to start and end addresses of the range containing the entry pc.
+
+   Note that it is not necessarily the case that (for non-NULL ADDRESS
+   and ENDADDR arguments) the *ADDRESS <= PC < *ENDADDR condition will
+   hold.
+
+   See comment for find_pc_partial_function, above, for further
+   explanation.  */
+
+extern bool find_pc_partial_entry_range (CORE_ADDR pc, const char **name,
+				         CORE_ADDR *address,
+					 CORE_ADDR *endaddr);
+
 /* Return the type of a function with its first instruction exactly at
    the PC address.  Return NULL otherwise.  */
 

  parent reply	other threads:[~2018-08-20 22:46 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-20 22:25 [PATCH v3 0/8] Non-contiguous address range support Kevin Buettner
2018-08-20 22:34 ` [PATCH v3 1/8] Add block range data structure for blocks with non-contiguous address ranges Kevin Buettner
2018-08-20 22:37 ` [PATCH v3 2/8] Record explicit block ranges from dwarf2read.c Kevin Buettner
2018-08-20 22:39 ` [PATCH v3 3/8] Add support for non-contiguous blocks to find_pc_partial_function Kevin Buettner
2018-08-21 16:12   ` Simon Marchi
2018-08-20 22:41 ` [PATCH v3 4/8] Disassemble blocks with non-contiguous ranges Kevin Buettner
2018-08-20 22:43 ` [PATCH v3 5/8] Use BLOCK_ENTRY_PC in place of most uses of BLOCK_START Kevin Buettner
2018-08-20 22:46 ` Kevin Buettner [this message]
2018-08-21 16:19   ` [PATCH v3 6/8] Introduce find_pc_partial_entry_range and use it in infrun.c Simon Marchi
2018-08-21 17:50     ` Kevin Buettner
2018-08-21 18:23       ` Simon Marchi
2018-08-21 18:47         ` Kevin Buettner
2018-08-20 22:47 ` [PATCH v3 7/8] Relocate block range start and end addresses Kevin Buettner
2018-08-20 22:48 ` [PATCH v3 8/8] Test case for functions with non-contiguous ranges Kevin Buettner
2018-08-21 16:28   ` Simon Marchi
2018-08-21 16:29 ` [PATCH v3 0/8] Non-contiguous address range support Simon Marchi

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=20180820154546.5a9f9c6f@pinnacle.lan \
    --to=kevinb@redhat.com \
    --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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).