aboutsummaryrefslogtreecommitdiff
path: root/gdb/block.h
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2024-10-10 11:37:34 +0100
committerAndrew Burgess <aburgess@redhat.com>2024-10-27 20:18:49 +0000
commitf8258cdaf95a80de8375ae54fa968c452733043f (patch)
treea67cfc08760355347ed416c6411185e3f1bfef3e /gdb/block.h
parenta723c56efb07c4f8b3f6a3ed4b878a2f8f5572cc (diff)
downloadbinutils-users/aburgess/try-gdb-block-entry-pc.zip
binutils-users/aburgess/try-gdb-block-entry-pc.tar.gz
binutils-users/aburgess/try-gdb-block-entry-pc.tar.bz2
gdb: fix handling of DW_AT_entry_pc of inlined subroutinesusers/aburgess/try-gdb-block-entry-pc
The entry PC for a DIE, e.g. an inline function, might not be the base address of the DIE. Currently though, in block::entry_pc(), GDB always returns the base address (low-pc or the first address of the first range) as the entry PC. This commit extends the block class to carry the entry PC as a separate member variable. Then the DWARF reader is extended to read and set the entry PC for the block. Now in block::entry_pc(), if the entry PC has been set to a specific value, this is the value returned. I have not removed the old code in block::entry_pc(). If the specific entry PC value was not set then we still fall back on the old approach of just returning the base address. Doing this feels more useful than just claiming there is no entry PC. This should also mean that we shouldn't see any change in behaviour for compilers that don't emit the DW_AT_entry_pc, or for debug readers (e.g. stabs) that don't set the entry PC value within a block. The DWARF-5 spec for reading the entry PC is a super-set of the spec as found in DWARF-4. For example, if there is no DW_AT_entry_pc then DWARF-4 says to use DW_AT_low_pc while DWARF-5 says to use the base address, which is DW_AT_low_pc or the first address in the first range specified by DW_AT_ranges if there is no DW_AT_low_pc. I have taken the approach of just implementing the DWARF-5 spec for everyone. There doesn't seem to be any benefit to deliberately ignoring a ranges based entry PC value for DWARF-4. If some naughty compiler has emitted that, then lets use it. Similarly, DWARF-4 says that DW_AT_entry_pc is an address. DWARF-5 allows an address or a constant, where the constant is an offset from the base address. I allow both approaches for all DWARF versions. There doesn't seem to be any downsides to this approach. The inline-entry.exp test was originally contributed by Bernd here: https://inbox.sourceware.org/gdb-patches/AS1PR01MB94659E4D9B3F4A6006CC605FE4922@AS1PR01MB9465.eurprd01.prod.exchangelabs.com though I have made some edits, making more use of lib/gdb.exp functions, making the gdb_test output patterns a little tighter, and updating the test to run with Clang. I also moved the test to gdb.opt/ as that seemed like a better home for it. Co-Authored-By: Bernd Edlinger <bernd.edlinger@hotmail.de>
Diffstat (limited to 'gdb/block.h')
-rw-r--r--gdb/block.h44
1 files changed, 32 insertions, 12 deletions
diff --git a/gdb/block.h b/gdb/block.h
index c3babad..3bd2c51 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -179,27 +179,35 @@ struct block : public allocate_on_obstack<block>
/* Return the "entry PC" of this block.
- The entry PC is the lowest (start) address for the block when all addresses
- within the block are contiguous. If non-contiguous, then use the start
- address for the first range in the block.
-
- At the moment, this almost matches what DWARF specifies as the entry
- pc. (The missing bit is support for DW_AT_entry_pc which should be
- preferred over range data and the low_pc.)
+ If the entry PC has been set to a specific value then this is
+ returned. Otherwise, the entry PC is the lowest (start) address for
+ the block when all addresses within the block are contiguous. If
+ non-contiguous, then use the start address for the first range in the
+ block.
- Once support for DW_AT_entry_pc is added, I expect that an entry_pc
- field will be added to one of these data structures. Once that's done,
- the entry_pc field can be set from the dwarf reader (and other readers
- too). ENTRY_PC can then be redefined to be less DWARF-centric. */
+ This almost matches what DWARF specifies as the entry pc, except that
+ the final case, using the first address of the first range, is a GDB
+ extension. However, the DWARF reader sets the specific entry PC
+ wherever possible, so this non-standard fallback case is only used as
+ a last resort. */
CORE_ADDR entry_pc () const
{
- if (this->is_contiguous ())
+ if (m_entry_pc != 0)
+ return m_entry_pc;
+ else if (this->is_contiguous ())
return this->start ();
else
return this->ranges ()[0].start ();
}
+ /* Set this block's entry PC. */
+
+ void set_entry_pc (CORE_ADDR addr)
+ {
+ m_entry_pc = addr;
+ }
+
/* Return the objfile of this block. */
struct objfile *objfile () const;
@@ -344,6 +352,18 @@ private:
startaddr and endaddr above. */
struct blockranges *m_ranges = nullptr;
+
+ /* The entry address for this block. The value 0 is special and
+ indicates that the entry address has not been set.
+
+ Using 0 as a special value is not ideal, targets for which 0 is a
+ valid code address might run into problems if they want to use 0 as a
+ block's entry address, but the alternative is to carry a flag
+ indicating if m_entry_pc is valid or not, but that would make 'struct
+ block' even bigger, and we want to keep 'struct block' as small as
+ possible (we might have a lot of blocks). */
+
+ CORE_ADDR m_entry_pc = 0;
};
/* The global block is singled out so that we can provide a back-link