aboutsummaryrefslogtreecommitdiff
path: root/gdb/block.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/block.h')
-rw-r--r--gdb/block.h130
1 files changed, 96 insertions, 34 deletions
diff --git a/gdb/block.h b/gdb/block.h
index ae676c4..76fa203 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -1,6 +1,6 @@
/* Code dealing with blocks for GDB.
- Copyright (C) 2003-2024 Free Software Foundation, Inc.
+ Copyright (C) 2003-2025 Free Software Foundation, Inc.
This file is part of GDB.
@@ -17,11 +17,12 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#ifndef BLOCK_H
-#define BLOCK_H
+#ifndef GDB_BLOCK_H
+#define GDB_BLOCK_H
#include "dictionary.h"
#include "gdbsupport/array-view.h"
+#include "gdbsupport/next-iterator.h"
/* Opaque declarations. */
@@ -177,27 +178,31 @@ struct block : public allocate_on_obstack<block>
bool is_contiguous () const
{ return this->ranges ().size () <= 1; }
- /* Return the "entry PC" of this 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.
+ If the entry PC has been set to a specific value then this is
+ returned. Otherwise, the default_entry_pc() address is returned. */
- 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.)
+ CORE_ADDR entry_pc () const
+ {
+ return default_entry_pc () + m_entry_pc_offset;
+ }
- 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. */
+ /* Set this block's entry-pc to ADDR, which must lie between start() and
+ end(). The entry-pc is stored as the signed offset from the
+ default_entry_pc() address.
- CORE_ADDR entry_pc () const
+ Note that block sub-ranges can be out of order, as such the offset of
+ the entry-pc might be negative. */
+
+ void set_entry_pc (CORE_ADDR addr)
{
- if (this->is_contiguous ())
- return this->start ();
- else
- return this->ranges ()[0].start ();
+ CORE_ADDR start = default_entry_pc ();
+
+ gdb_assert (addr >= this->start () && addr < this->end ());
+ gdb_assert (start >= this->start () && start < this->end ());
+
+ m_entry_pc_offset = addr - start;
}
/* Return the objfile of this block. */
@@ -227,7 +232,7 @@ struct block : public allocate_on_obstack<block>
/* This returns the using directives list associated with this
block, if any. */
- struct using_direct *get_using () const;
+ next_range<using_direct> get_using () const;
/* Set this block's using member to USING; if needed, allocate
memory via OBSTACK. (It won't make a copy of USING, however, so
@@ -264,25 +269,26 @@ struct block : public allocate_on_obstack<block>
return sup->is_global_block ();
}
- /* Return the static block associated with block. */
+ /* Return the global block associated with block. */
- const struct block *global_block () const;
+ const struct global_block *global_block () const;
/* Return true if this block is a global block. */
bool is_global_block () const
{ return superblock () == nullptr; }
+ /* Return this block as a global_block. This block must be a global
+ block. */
+ struct global_block *as_global_block ();
+ const struct global_block *as_global_block () const;
+
/* Return the function block for this block. Returns nullptr if
there is no enclosing function, i.e., if this block is a static
or global block. */
const struct block *function_block () const;
- /* Set the compunit of this block, which must be a global block. */
-
- void set_compunit_symtab (struct compunit_symtab *);
-
/* Return a property to evaluate the static link associated to this
block.
@@ -307,6 +313,26 @@ struct block : public allocate_on_obstack<block>
private:
+ /* Return the default entry-pc of this block. The default is the address
+ we use if the debug information hasn't specifically set a different
+ entry-pc value. This is the lowest 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.
+
+ 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 default_entry_pc () const
+ {
+ if (this->is_contiguous ())
+ return this->start ();
+ else
+ return this->ranges ()[0].start ();
+ }
+
/* If the namespace_info is NULL, allocate it via OBSTACK and
initialize its members to zero. */
void initialize_namespace (struct obstack *obstack);
@@ -343,16 +369,49 @@ private:
startaddr and endaddr above. */
struct blockranges *m_ranges = nullptr;
+
+ /* The offset of the actual entry-pc value from the default entry-pc
+ value. If space was no object then we'd store an actual address along
+ with a flag to indicate if the address has been set or not. But we'd
+ like to keep the size of block low, so we'd like to use a single
+ member variable.
+
+ We would also like to avoid using 0 as a special address; some targets
+ do allow for accesses to address 0.
+
+ So instead we store the offset of the defined entry-pc from the
+ default entry-pc. See default_entry_pc() for the definition of the
+ default entry-pc. See entry_pc() for how this offset is used. */
+
+ LONGEST m_entry_pc_offset = 0;
};
/* The global block is singled out so that we can provide a back-link
- to the compunit symtab. */
+ to the compunit. */
struct global_block : public block
{
- /* This holds a pointer to the compunit symtab holding this block. */
+ /* Set the compunit of this global block.
+
+ The compunit must not have been set previously. */
+ void set_compunit (compunit_symtab *cu)
+ {
+ gdb_assert (m_compunit == nullptr);
+ m_compunit = cu;
+ }
+
+ /* Return the compunit of this global block.
- struct compunit_symtab *compunit_symtab = nullptr;
+ The compunit must have been set previously. */
+ compunit_symtab *compunit () const
+ {
+ gdb_assert (m_compunit != nullptr);
+ return m_compunit;
+ }
+
+private:
+ /* This holds a pointer to the compunit holding this block. */
+ compunit_symtab *m_compunit = nullptr;
};
struct blockvector
@@ -394,12 +453,15 @@ struct blockvector
{ return m_num_blocks; }
/* Return the global block of this blockvector. */
- struct block *global_block ()
- { return this->block (GLOBAL_BLOCK); }
+ struct global_block *global_block ()
+ { return static_cast<struct global_block *> (this->block (GLOBAL_BLOCK)); }
/* Const version of the above. */
- const struct block *global_block () const
- { return this->block (GLOBAL_BLOCK); }
+ const struct global_block *global_block () const
+ {
+ return static_cast<const struct global_block *>
+ (this->block (GLOBAL_BLOCK));
+ }
/* Return the static block of this blockvector. */
struct block *static_block ()
@@ -592,4 +654,4 @@ extern struct symbol *block_find_symbol (const struct block *block,
struct blockranges *make_blockranges (struct objfile *objfile,
const std::vector<blockrange> &rangevec);
-#endif /* BLOCK_H */
+#endif /* GDB_BLOCK_H */