From: Jan Vrany Date: Fri, 28 Nov 2025 13:47:02 +0000 (+0000) Subject: gdb: add unittests for blockvector lookup functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6287318dfd4e29da533d31945cf2ba188a6daf17;p=thirdparty%2Fbinutils-gdb.git gdb: add unittests for blockvector lookup functions This commit adds new unittest - blockvector-lookup - that tests blockvector::lookup () and blockvector::contains (). Approved-By: Simon Marchi --- diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 538d10a824d..ed29f1703cd 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -451,6 +451,7 @@ SUBDIR_PYTHON_LDFLAGS = SUBDIR_PYTHON_CFLAGS = SELFTESTS_SRCS = \ + block-selftests.c \ disasm-selftests.c \ gdbarch-selftests.c \ selftest-arch.c \ diff --git a/gdb/block-selftests.c b/gdb/block-selftests.c new file mode 100644 index 00000000000..f5883f18660 --- /dev/null +++ b/gdb/block-selftests.c @@ -0,0 +1,128 @@ +/* Self tests for blockvectors + + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "gdbsupport/selftest.h" +#include "block.h" +#include "addrmap.h" + + +namespace selftests { + +/* Create and add new block to given blockvector. */ +static struct block * +make_block (struct blockvector &bv, struct obstack &ob, CORE_ADDR start, + CORE_ADDR end, struct block *superblock = nullptr) +{ + auto b = new (&ob) struct block; + b->set_start (start); + b->set_end (end); + b->set_superblock (superblock); + b->set_multidict (mdict_create_linear_expandable (language_unknown)); + + bv.append_block (b); + + return b; +} + +/* A helper to create and set address map given a blockvector. */ +static void +make_map (struct blockvector &bv, struct obstack &ob) +{ + struct addrmap_mutable map; + + for (int i = bv.num_blocks () - 1; i > STATIC_BLOCK; i--) + { + auto b = bv.block (i); + map.set_empty (b->start (), b->end () - 1, b); + } + + bv.set_map (new (&ob) addrmap_fixed (&ob, &map)); +} + +/* Create and return blockvector with following blocks: + + B0 0x1000 - 0x4000 (global block) + B1 0x1000 - 0x4000 (static block) + B2 0x1000 - 0x2000 + (hole) + B3 0x3000 - 0x4000 + + If USE_MAP is true, then also set blockvector's address map. +*/ +static blockvector_up +make_blockvector (struct obstack &ob, bool use_map) +{ + auto bv = std::make_unique (0); + + auto global_block = make_block (*bv.get (), ob, 0x1000, 0x4000); + auto static_block = make_block (*bv.get (), ob, 0x1000, 0x4000, + global_block); + make_block (*bv.get (), ob, 0x1000, 0x2000, static_block); + make_block (*bv.get (), ob, 0x3000, 0x4000, static_block); + + if (use_map) + make_map (*bv.get (), ob); + + return bv; +} + +static void +test_blockvector_lookup_contains () +{ + for (bool with_map : { false, true }) + { + /* Test blockvector without an address map. */ + auto_obstack ob; + blockvector_up bv = make_blockvector (ob, with_map); + + /* Test address outside global block's range. */ + SELF_CHECK (bv->lookup (0x0500) == nullptr); + SELF_CHECK (bv->contains (0x0500) == false); + + /* Test address falling into a block. */ + SELF_CHECK (bv->lookup (0x1500) == bv->block (2)); + SELF_CHECK (bv->contains (0x1500) == true); + + /* Test address falling into a "hole". If BV has an address map, + lookup () returns nullptr. If not, lookup () return static block. + contains() returns false in both cases. */ + if (with_map) + SELF_CHECK (bv->lookup (0x2500) == nullptr); + else + SELF_CHECK (bv->lookup (0x2500) == bv->block (STATIC_BLOCK)); + SELF_CHECK (bv->contains (0x2500) == false); + + /* Test address falling into a block above the "hole". */ + SELF_CHECK (bv->lookup (0x3500) == bv->block (3)); + SELF_CHECK (bv->contains (0x3500) == true); + + /* Test address outside global block's range. */ + SELF_CHECK (bv->lookup (0x4000) == nullptr); + SELF_CHECK (bv->contains (0x4000) == false); + } +} + +} /* namespace selftests */ + + +INIT_GDB_FILE (block_selftest) +{ + selftests::register_test ("blockvector-lookup-contains", + selftests::test_blockvector_lookup_contains); +}