gdb: change find_block_in_blockvector to be a method

This changes find_block_in_blockvector() to be a method lookup()
of struct blockvector.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
Jan Vrany
2025-11-04 11:18:12 +00:00
parent cf312b990e
commit f29e763e90
2 changed files with 57 additions and 55 deletions

View File

@@ -118,56 +118,6 @@ block::inlined_p () const
return function () != nullptr && function ()->is_inlined (); return function () != nullptr && function ()->is_inlined ();
} }
/* A helper function that checks whether PC is in the blockvector BL.
It returns the innermost lexical block containing the specified pc
if there is one, or else NULL. */
static const struct block *
find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
{
const struct block *b;
int bot, top, half;
/* If we have an addrmap mapping code addresses to blocks, then use
that. */
if (bl->map ())
return (const struct block *) bl->map ()->find (pc);
/* Otherwise, use binary search to find the last block that starts
before PC.
Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1.
They both have the same START,END values.
Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the
fact that this choice was made was subtle, now we make it explicit. */
gdb_assert (bl->blocks ().size () >= 2);
bot = STATIC_BLOCK;
top = bl->blocks ().size ();
while (top - bot > 1)
{
half = (top - bot + 1) >> 1;
b = bl->block (bot + half);
if (b->start () <= pc)
bot += half;
else
top = bot + half;
}
/* Now search backward for a block that ends after PC. */
while (bot >= STATIC_BLOCK)
{
b = bl->block (bot);
if (!(b->start () <= pc))
return NULL;
if (b->end () > pc)
return b;
bot--;
}
return NULL;
}
/* Return the blockvector immediately containing the innermost lexical /* Return the blockvector immediately containing the innermost lexical
block containing the specified pc value and section, or 0 if there block containing the specified pc value and section, or 0 if there
is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we
@@ -192,7 +142,7 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
bl = cust->blockvector (); bl = cust->blockvector ();
/* Then search that symtab for the smallest block that wins. */ /* Then search that symtab for the smallest block that wins. */
b = find_block_in_blockvector (bl, pc); b = bl->lookup (pc);
if (b == NULL) if (b == NULL)
return NULL; return NULL;
@@ -206,7 +156,7 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
int int
blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc) blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc)
{ {
return find_block_in_blockvector (bv, pc) != NULL; return bv->lookup (pc) != nullptr;
} }
/* Return call_site for specified PC in GDBARCH. PC must match exactly, it /* Return call_site for specified PC in GDBARCH. PC must match exactly, it
@@ -816,9 +766,9 @@ bool
blockvector::block_less_than (const struct block *b1, const struct block *b2) blockvector::block_less_than (const struct block *b1, const struct block *b2)
{ {
/* Blocks with lower start address must come before blocks with higher start /* Blocks with lower start address must come before blocks with higher start
address. If two blocks start at the same address, enclosing block address. If two blocks start at the same address, enclosing block
should come before nested blocks. Function find_block_in_blockvector() should come before nested blocks. Method blockvector::lookup()
depends on this ordering, allowing it to use binary search to find depends on this ordering, allowing it to use binary search to find
inner-most block for given address. */ inner-most block for given address. */
CORE_ADDR start1 = b1->start (); CORE_ADDR start1 = b1->start ();
CORE_ADDR start2 = b2->start (); CORE_ADDR start2 = b2->start ();
@@ -842,6 +792,54 @@ blockvector::append_block (struct block *block)
m_blocks.push_back (block); m_blocks.push_back (block);
} }
/* See block.h. */
const struct block *
blockvector::lookup (CORE_ADDR addr) const
{
const struct block *b;
int bot, top, half;
/* If we have an addrmap mapping code addresses to blocks, then use
that. */
if (map ())
return (const struct block *) map ()->find (addr);
/* Otherwise, use binary search to find the last block that starts
before PC.
Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1.
They both have the same START,END values.
Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the
fact that this choice was made was subtle, now we make it explicit. */
gdb_assert (blocks ().size () >= 2);
bot = STATIC_BLOCK;
top = blocks ().size ();
while (top - bot > 1)
{
half = (top - bot + 1) >> 1;
b = block (bot + half);
if (b->start () <= addr)
bot += half;
else
top = bot + half;
}
/* Now search backward for a block that ends after PC. */
while (bot >= STATIC_BLOCK)
{
b = block (bot);
if (!(b->start () <= addr))
return NULL;
if (b->end () > addr)
return b;
bot--;
}
return NULL;
}
blockvector::~blockvector () blockvector::~blockvector ()
{ {
for (struct block *bl : m_blocks) for (struct block *bl : m_blocks)

View File

@@ -502,6 +502,10 @@ struct blockvector
blocks are appended in correct order. */ blocks are appended in correct order. */
void append_block (struct block *block); void append_block (struct block *block);
/* Lookup the innermost lexical block containing ADDR. Returns the block
if there is one, NULL otherwise. */
const struct block *lookup (CORE_ADDR addr) const;
private: private:
/* An address map mapping addresses to blocks in this blockvector. /* An address map mapping addresses to blocks in this blockvector.
This pointer is zero if the blocks' start and end addresses are This pointer is zero if the blocks' start and end addresses are