From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v4 6/8] Introduce find_function_entry_range_from_pc and use it in infrun.c
Date: Wed, 22 Aug 2018 17:18:00 -0000 [thread overview]
Message-ID: <20180822101805.19fc734e@pinnacle.lan> (raw)
In-Reply-To: <20180822095721.3e298051@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_function_entry_range_from_pc. 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_function_entry_range_from_pc 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_function_entry_range_from_pc.
It should be noted that for functions which contain only a single
range, the outputs of find_pc_partial_function and
find_function_entry_range_from_pc are identical.
I think it might happen that find_function_entry_range_from_pc 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.
Finally, a note regarding the name: I had initially chosen a different
name with a find_pc_partial_ prefix, but Simon suggested the current
name citing the goal of eventually making naming consistent using
the form find_X_from_Y. In this case X is "function_entry_range" and
Y is "pc". Both the name and rationale made sense to me, so that's
how it came to be.
gdb/ChangeLog:
* infrun.c (fill_in_stop_func): Use find_function_entry_range_from_pc
in place of find_pc_partial_function.
* blockframe.c (find_function_entry_range_from_pc): New function.
* symtab.h (find_function_entry_range_from_pc): Declare and document.
---
gdb/blockframe.c | 37 +++++++++++++++++++++++++++++++++++++
gdb/infrun.c | 7 ++++---
gdb/symtab.h | 21 ++++++++++++++++++++-
3 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 6ea0965..f6dd861 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -377,6 +377,43 @@ find_pc_partial_function (CORE_ADDR pc, const char **name, CORE_ADDR *address,
/* See symtab.h. */
+bool
+find_function_entry_range_from_pc (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_function_entry_range_from_pc"));
+ }
+
+ 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..7731ccd 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4287,9 +4287,10 @@ fill_in_stop_func (struct gdbarch *gdbarch,
{
/* 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_function_entry_range_from_pc (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..eb14f34 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1725,12 +1725,31 @@ 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_function_entry_range_from_pc. */
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_function_entry_range_from_pc (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. */
next prev parent reply other threads:[~2018-08-22 17:18 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-22 16:57 [PATCH v4 0/8] Non-contiguous address range support Kevin Buettner
2018-08-22 17:07 ` [PATCH v4 1/8] Add block range data structure for blocks with non-contiguous address ranges Kevin Buettner
2018-08-22 17:09 ` [PATCH v4 2/8] Record explicit block ranges from dwarf2read.c Kevin Buettner
2018-08-22 17:11 ` [PATCH v4 3/8] Add support for non-contiguous blocks to find_pc_partial_function Kevin Buettner
2018-08-22 17:14 ` [PATCH v4 4/8] Disassemble blocks with non-contiguous ranges Kevin Buettner
2018-08-22 17:16 ` [PATCH v4 5/8] Use BLOCK_ENTRY_PC in place of most uses of BLOCK_START Kevin Buettner
2018-08-22 17:18 ` Kevin Buettner [this message]
2018-08-22 17:19 ` [PATCH v4 7/8] Relocate block range start and end addresses Kevin Buettner
2018-08-22 17:20 ` [PATCH v4 8/8] Test case for functions with non-contiguous ranges Kevin Buettner
2018-08-22 18:22 ` [PATCH v4 0/8] Non-contiguous address range support Simon Marchi
2018-08-23 16:16 ` Pedro Alves
2018-08-23 23:31 ` Kevin Buettner
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=20180822101805.19fc734e@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).