[binutils-gdb] gdb: add block ordering predicate for ordering blocks in blockvector
Jan Vrany
jv@sourceware.org
Thu Oct 23 11:03:15 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=45b3bfcc906830d4feed35dbd0e2203f1886ead7
commit 45b3bfcc906830d4feed35dbd0e2203f1886ead7
Author: Jan Vrany <jan.vrany@labware.com>
Date: Thu Oct 23 12:01:34 2025 +0100
gdb: add block ordering predicate for ordering blocks in blockvector
This commit adds blockvector::block_less_than() predicate that defines
required ordering of blocks within blockvector.
It orders blocks so that blocks with lower start address come before
blocks with higher start address. If two blocks start at the same
address, enclosing (larger) block should come before nested (smaller)
block.
This ordering is depended upon in find_block_in_blockvector(). Although
its comment did not say so, find_block_in_blockvector() is called from
blockvector_for_pc_sect() which is explicit about it. While at it, I
changed the comment of find_block_in_blockvector() to say so explicitly
too.
As Andrew pointed out, buildsym.c sorts block slightly differently,
taking only the start address into account. The comment there says
blocks with same start address should not be reordered as they are in
correct order already and that order is needed. It is unclear to me
if buildsym.c arranges blocks starting at the same address in required
order before sorting them or this happens "by chance". I did modify
buildsym_compunit::make_blockvector() to assert blocks are properly
ordered and running testsuite did not show any regressions.
Approved-By: Tom Tromey <tom@tromey.com>
Diff:
---
gdb/block.c | 27 ++++++++++++++++++++++++++-
gdb/block.h | 4 ++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/gdb/block.c b/gdb/block.c
index 55a1d767dd9..02e6d0e4be2 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -119,7 +119,8 @@ block::inlined_p () const
}
/* A helper function that checks whether PC is in the blockvector BL.
- It returns the containing block if there is one, or else NULL. */
+ 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)
@@ -811,9 +812,33 @@ make_blockranges (struct objfile *objfile,
/* See block.h. */
+bool
+blockvector::block_less_than (const struct block *b1, const struct block *b2)
+{
+ /* Blocks with lower start address must come before blocks with higher start
+ address. If two blocks start at the same address, enclosing block
+ should come before nested blocks. Function find_block_in_blockvector()
+ depends on this ordering, allowing it to use binary search to find
+ inner-most block for given address. */
+ CORE_ADDR start1 = b1->start ();
+ CORE_ADDR start2 = b2->start ();
+
+ if (start1 != start2)
+ return start1 < start2;
+
+ return (b1->end () > b2->end ());
+}
+
+/* See block.h. */
+
void
blockvector::append_block (struct block *block)
{
+ gdb_assert ((num_blocks () == GLOBAL_BLOCK && block->is_global_block ())
+ || (num_blocks () == STATIC_BLOCK && block->is_static_block ())
+ || (num_blocks () >= FIRST_LOCAL_BLOCK
+ && !block_less_than (block, m_blocks.back ())));
+
m_blocks.push_back (block);
}
diff --git a/gdb/block.h b/gdb/block.h
index 0d914d82d9e..61070619ca7 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -490,6 +490,10 @@ struct blockvector
void set_map (addrmap_fixed *map)
{ m_map = map; }
+ /* Block comparison function. Returns true if B1 must be ordered before
+ B2 in a blockvector, false otherwise. */
+ static bool block_less_than (const struct block *b1, const struct block *b2);
+
/* Append BLOCK at the end of blockvector. The caller has to make sure that
blocks are appended in correct order. */
void append_block (struct block *block);
More information about the Gdb-cvs
mailing list