testsuite, threads: fix LD_LIBRARY_PATH in 'tls-sepdebug.exp'
[binutils-gdb.git] / gdb / block.c
blob6f60877785499db98c6e964c3c8f56a32fb2182d
1 /* Block-related functions for the GNU debugger, GDB.
3 Copyright (C) 2003-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "block.h"
21 #include "symtab.h"
22 #include "symfile.h"
23 #include "gdbsupport/gdb_obstack.h"
24 #include "cp-support.h"
25 #include "addrmap.h"
26 #include "gdbtypes.h"
27 #include "objfiles.h"
28 #include "cli/cli-cmds.h"
29 #include "inferior.h"
31 /* This is used by struct block to store namespace-related info for
32 C++ files, namely using declarations and the current namespace in
33 scope. */
35 struct block_namespace_info : public allocate_on_obstack<block_namespace_info>
37 const char *scope = nullptr;
38 struct using_direct *using_decl = nullptr;
41 /* See block.h. */
43 struct objfile *
44 block::objfile () const
46 if (function () != nullptr)
47 return function ()->objfile ();
49 return this->global_block ()->compunit ()->objfile ();
52 /* See block. */
54 struct gdbarch *
55 block::gdbarch () const
57 if (function () != nullptr)
58 return function ()->arch ();
60 return objfile ()->arch ();
63 /* See block.h. */
65 bool
66 block::contains (const struct block *a, bool allow_nested) const
68 if (a == nullptr)
69 return false;
73 if (a == this)
74 return true;
75 /* If A is a function block, then A cannot be contained in B,
76 except if A was inlined. */
77 if (!allow_nested && a->function () != NULL && !a->inlined_p ())
78 return false;
79 a = a->superblock ();
81 while (a != NULL);
83 return false;
86 /* See block.h. */
88 struct symbol *
89 block::linkage_function () const
91 const block *bl = this;
93 while ((bl->function () == NULL || bl->inlined_p ())
94 && bl->superblock () != NULL)
95 bl = bl->superblock ();
97 return bl->function ();
100 /* See block.h. */
102 struct symbol *
103 block::containing_function () const
105 const block *bl = this;
107 while (bl->function () == NULL && bl->superblock () != NULL)
108 bl = bl->superblock ();
110 return bl->function ();
113 /* See block.h. */
115 bool
116 block::inlined_p () const
118 return function () != nullptr && function ()->is_inlined ();
121 /* A helper function that checks whether PC is in the blockvector BL.
122 It returns the containing block if there is one, or else NULL. */
124 static const struct block *
125 find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
127 const struct block *b;
128 int bot, top, half;
130 /* If we have an addrmap mapping code addresses to blocks, then use
131 that. */
132 if (bl->map ())
133 return (const struct block *) bl->map ()->find (pc);
135 /* Otherwise, use binary search to find the last block that starts
136 before PC.
137 Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1.
138 They both have the same START,END values.
139 Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the
140 fact that this choice was made was subtle, now we make it explicit. */
141 gdb_assert (bl->blocks ().size () >= 2);
142 bot = STATIC_BLOCK;
143 top = bl->blocks ().size ();
145 while (top - bot > 1)
147 half = (top - bot + 1) >> 1;
148 b = bl->block (bot + half);
149 if (b->start () <= pc)
150 bot += half;
151 else
152 top = bot + half;
155 /* Now search backward for a block that ends after PC. */
157 while (bot >= STATIC_BLOCK)
159 b = bl->block (bot);
160 if (!(b->start () <= pc))
161 return NULL;
162 if (b->end () > pc)
163 return b;
164 bot--;
167 return NULL;
170 /* Return the blockvector immediately containing the innermost lexical
171 block containing the specified pc value and section, or 0 if there
172 is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we
173 don't pass this information back to the caller. */
175 const struct blockvector *
176 blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
177 const struct block **pblock,
178 struct compunit_symtab *cust)
180 const struct blockvector *bl;
181 const struct block *b;
183 if (cust == NULL)
185 /* First search all symtabs for one whose file contains our pc */
186 cust = find_pc_sect_compunit_symtab (pc, section);
187 if (cust == NULL)
188 return 0;
191 bl = cust->blockvector ();
193 /* Then search that symtab for the smallest block that wins. */
194 b = find_block_in_blockvector (bl, pc);
195 if (b == NULL)
196 return NULL;
198 if (pblock)
199 *pblock = b;
200 return bl;
203 /* Return true if the blockvector BV contains PC, false otherwise. */
206 blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc)
208 return find_block_in_blockvector (bv, pc) != NULL;
211 /* Return call_site for specified PC in GDBARCH. PC must match exactly, it
212 must be the next instruction after call (or after tail call jump). Throw
213 NO_ENTRY_VALUE_ERROR otherwise. This function never returns NULL. */
215 struct call_site *
216 call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
218 struct compunit_symtab *cust;
219 call_site *cs = nullptr;
221 /* -1 as tail call PC can be already after the compilation unit range. */
222 cust = find_pc_compunit_symtab (pc - 1);
224 if (cust != nullptr)
225 cs = cust->find_call_site (pc);
227 if (cs == nullptr)
229 bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc);
231 /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
232 the call target. */
233 throw_error (NO_ENTRY_VALUE_ERROR,
234 _("DW_OP_entry_value resolving cannot find "
235 "DW_TAG_call_site %s in %s"),
236 paddress (gdbarch, pc),
237 (msym.minsym == NULL ? "???"
238 : msym.minsym->print_name ()));
241 return cs;
244 /* Return the blockvector immediately containing the innermost lexical block
245 containing the specified pc value, or 0 if there is none.
246 Backward compatibility, no section. */
248 const struct blockvector *
249 blockvector_for_pc (CORE_ADDR pc, const struct block **pblock)
251 return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
252 pblock, NULL);
255 /* Return the innermost lexical block containing the specified pc value
256 in the specified section, or 0 if there is none. */
258 const struct block *
259 block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
261 const struct blockvector *bl;
262 const struct block *b;
264 bl = blockvector_for_pc_sect (pc, section, &b, NULL);
265 if (bl)
266 return b;
267 return 0;
270 /* Return the innermost lexical block containing the specified pc value,
271 or 0 if there is none. Backward compatibility, no section. */
273 const struct block *
274 block_for_pc (CORE_ADDR pc)
276 return block_for_pc_sect (pc, find_pc_mapped_section (pc));
279 /* Now come some functions designed to deal with C++ namespace issues.
280 The accessors are safe to use even in the non-C++ case. */
282 /* See block.h. */
284 const char *
285 block::scope () const
287 for (const block *block = this;
288 block != nullptr;
289 block = block->superblock ())
291 if (block->m_namespace_info != nullptr
292 && block->m_namespace_info->scope != nullptr)
293 return block->m_namespace_info->scope;
296 return "";
299 /* See block.h. */
301 void
302 block::initialize_namespace (struct obstack *obstack)
304 if (m_namespace_info == nullptr)
305 m_namespace_info = new (obstack) struct block_namespace_info;
308 /* See block.h. */
310 void
311 block::set_scope (const char *scope, struct obstack *obstack)
313 if (scope == nullptr || scope[0] == '\0')
315 /* Don't bother. */
316 return;
319 initialize_namespace (obstack);
320 m_namespace_info->scope = scope;
323 /* See block.h. */
325 struct using_direct *
326 block::get_using () const
328 if (m_namespace_info == nullptr)
329 return nullptr;
330 else
331 return m_namespace_info->using_decl;
334 /* See block.h. */
336 void
337 block::set_using (struct using_direct *using_decl, struct obstack *obstack)
339 if (using_decl == nullptr)
341 /* Don't bother. */
342 return;
345 initialize_namespace (obstack);
346 m_namespace_info->using_decl = using_decl;
349 /* See block.h. */
351 const struct block *
352 block::static_block () const
354 if (superblock () == nullptr)
355 return nullptr;
357 const block *block = this;
358 while (block->superblock ()->superblock () != NULL)
359 block = block->superblock ();
361 return block;
364 /* See block.h. */
366 const struct global_block *
367 block::global_block () const
369 const block *block = this;
371 while (block->superblock () != NULL)
372 block = block->superblock ();
374 return block->as_global_block ();
377 /* See block.h. */
379 struct global_block *
380 block::as_global_block ()
382 gdb_assert (this->is_global_block ());
384 return static_cast<struct global_block *>(this);
387 /* See block.h. */
389 const struct global_block *
390 block::as_global_block () const
392 gdb_assert (this->is_global_block ());
394 return static_cast<const struct global_block *>(this);
397 /* See block.h. */
399 const struct block *
400 block::function_block () const
402 const block *block = this;
404 while (block != nullptr && block->function () == nullptr)
405 block = block->superblock ();
407 return block;
410 /* See block.h. */
412 struct dynamic_prop *
413 block::static_link () const
415 struct objfile *objfile = this->objfile ();
417 /* Only objfile-owned blocks that materialize top function scopes can have
418 static links. */
419 if (objfile == NULL || function () == NULL)
420 return NULL;
422 return (struct dynamic_prop *) objfile_lookup_static_link (objfile, this);
425 /* Initialize a block iterator, either to iterate over a single block,
426 or, for static and global blocks, all the included symtabs as
427 well. */
429 static void
430 initialize_block_iterator (const struct block *block,
431 struct block_iterator *iter,
432 const lookup_name_info *name)
434 enum block_enum which;
436 iter->idx = -1;
437 iter->name = name;
439 if (block->is_global_block ())
440 which = GLOBAL_BLOCK;
441 else if (block->is_static_block ())
442 which = STATIC_BLOCK;
443 else
445 iter->d.block = block;
447 /* A signal value meaning that we're iterating over a single
448 block. */
449 iter->which = FIRST_LOCAL_BLOCK;
450 return;
453 compunit_symtab *cu = block->global_block ()->compunit ();
455 /* If this is an included symtab, find the canonical includer and
456 use it instead. */
457 while (cu->user != NULL)
458 cu = cu->user;
460 /* Putting this check here simplifies the logic of the iterator
461 functions. If there are no included symtabs, we only need to
462 search a single block, so we might as well just do that
463 directly. */
464 if (cu->includes == NULL)
466 iter->d.block = block;
467 /* A signal value meaning that we're iterating over a single
468 block. */
469 iter->which = FIRST_LOCAL_BLOCK;
471 else
473 iter->d.compunit_symtab = cu;
474 iter->which = which;
478 /* A helper function that finds the current compunit over whose static
479 or global block we should iterate. */
481 static struct compunit_symtab *
482 find_iterator_compunit_symtab (struct block_iterator *iterator)
484 if (iterator->idx == -1)
485 return iterator->d.compunit_symtab;
486 return iterator->d.compunit_symtab->includes[iterator->idx];
489 /* Perform a single step for a plain block iterator, iterating across
490 symbol tables as needed. Returns the next symbol, or NULL when
491 iteration is complete. */
493 static struct symbol *
494 block_iterator_step (struct block_iterator *iterator, int first)
496 struct symbol *sym;
498 gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
500 while (1)
502 if (first)
504 struct compunit_symtab *cust
505 = find_iterator_compunit_symtab (iterator);
506 const struct block *block;
508 /* Iteration is complete. */
509 if (cust == NULL)
510 return NULL;
512 block = cust->blockvector ()->block (iterator->which);
513 sym = mdict_iterator_first (block->multidict (),
514 &iterator->mdict_iter);
516 else
517 sym = mdict_iterator_next (&iterator->mdict_iter);
519 if (sym != NULL)
520 return sym;
522 /* We have finished iterating the appropriate block of one
523 symtab. Now advance to the next symtab and begin iteration
524 there. */
525 ++iterator->idx;
526 first = 1;
530 /* Perform a single step for a "match" block iterator, iterating
531 across symbol tables as needed. Returns the next symbol, or NULL
532 when iteration is complete. */
534 static struct symbol *
535 block_iter_match_step (struct block_iterator *iterator,
536 int first)
538 struct symbol *sym;
540 gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
542 while (1)
544 if (first)
546 struct compunit_symtab *cust
547 = find_iterator_compunit_symtab (iterator);
548 const struct block *block;
550 /* Iteration is complete. */
551 if (cust == NULL)
552 return NULL;
554 block = cust->blockvector ()->block (iterator->which);
555 sym = mdict_iter_match_first (block->multidict (), *iterator->name,
556 &iterator->mdict_iter);
558 else
559 sym = mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);
561 if (sym != NULL)
562 return sym;
564 /* We have finished iterating the appropriate block of one
565 symtab. Now advance to the next symtab and begin iteration
566 there. */
567 ++iterator->idx;
568 first = 1;
572 /* See block.h. */
574 struct symbol *
575 block_iterator_first (const struct block *block,
576 struct block_iterator *iterator,
577 const lookup_name_info *name)
579 initialize_block_iterator (block, iterator, name);
581 if (name == nullptr)
583 if (iterator->which == FIRST_LOCAL_BLOCK)
584 return mdict_iterator_first (block->multidict (),
585 &iterator->mdict_iter);
587 return block_iterator_step (iterator, 1);
590 if (iterator->which == FIRST_LOCAL_BLOCK)
591 return mdict_iter_match_first (block->multidict (), *name,
592 &iterator->mdict_iter);
594 return block_iter_match_step (iterator, 1);
597 /* See block.h. */
599 struct symbol *
600 block_iterator_next (struct block_iterator *iterator)
602 if (iterator->name == nullptr)
604 if (iterator->which == FIRST_LOCAL_BLOCK)
605 return mdict_iterator_next (&iterator->mdict_iter);
607 return block_iterator_step (iterator, 0);
610 if (iterator->which == FIRST_LOCAL_BLOCK)
611 return mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);
613 return block_iter_match_step (iterator, 0);
616 /* See block.h. */
618 bool
619 best_symbol (struct symbol *a, const domain_search_flags domain)
621 if (a->aclass () == LOC_UNRESOLVED)
622 return false;
624 if ((domain & SEARCH_VAR_DOMAIN) != 0)
625 return a->domain () == VAR_DOMAIN;
627 return a->matches (domain);
630 /* See block.h. */
632 struct symbol *
633 better_symbol (struct symbol *a, struct symbol *b,
634 const domain_search_flags domain)
636 if (a == NULL)
637 return b;
638 if (b == NULL)
639 return a;
641 if (a->matches (domain) && !b->matches (domain))
642 return a;
644 if (b->matches (domain) && !a->matches (domain))
645 return b;
647 if (a->aclass () != LOC_UNRESOLVED && b->aclass () == LOC_UNRESOLVED)
648 return a;
650 if (b->aclass () != LOC_UNRESOLVED && a->aclass () == LOC_UNRESOLVED)
651 return b;
653 return a;
656 /* See block.h.
658 Note that if NAME is the demangled form of a C++ symbol, we will fail
659 to find a match during the binary search of the non-encoded names, but
660 for now we don't worry about the slight inefficiency of looking for
661 a match we'll never find, since it will go pretty quick. Once the
662 binary search terminates, we drop through and do a straight linear
663 search on the symbols. Each symbol which is marked as being a ObjC/C++
664 symbol (language_cplus or language_objc set) has both the encoded and
665 non-encoded names tested for a match. */
667 struct symbol *
668 block_lookup_symbol (const struct block *block, const lookup_name_info &name,
669 const domain_search_flags domain)
671 if (!block->function ())
673 struct symbol *other = NULL;
675 for (struct symbol *sym : block_iterator_range (block, &name))
677 /* See comment related to PR gcc/debug/91507 in
678 block_lookup_symbol_primary. */
679 if (best_symbol (sym, domain))
680 return sym;
681 /* This is a bit of a hack, but symbol_matches_domain might ignore
682 STRUCT vs VAR domain symbols. So if a matching symbol is found,
683 make sure there is no "better" matching symbol, i.e., one with
684 exactly the same domain. PR 16253. */
685 if (sym->matches (domain))
686 other = better_symbol (other, sym, domain);
688 return other;
690 else
692 /* Note that parameter symbols do not always show up last in the
693 list; this loop makes sure to take anything else other than
694 parameter symbols first; it only uses parameter symbols as a
695 last resort. Note that this only takes up extra computation
696 time on a match.
697 It's hard to define types in the parameter list (at least in
698 C/C++) so we don't do the same PR 16253 hack here that is done
699 for the !BLOCK_FUNCTION case. */
701 struct symbol *sym_found = NULL;
703 for (struct symbol *sym : block_iterator_range (block, &name))
705 if (sym->matches (domain))
707 sym_found = sym;
708 if (!sym->is_argument ())
710 break;
714 return (sym_found); /* Will be NULL if not found. */
718 /* See block.h. */
720 struct symbol *
721 block_lookup_symbol_primary (const struct block *block, const char *name,
722 const domain_search_flags domain)
724 struct symbol *sym, *other;
725 struct mdict_iterator mdict_iter;
727 lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
729 /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
730 gdb_assert (block->superblock () == NULL
731 || block->superblock ()->superblock () == NULL);
733 other = NULL;
734 for (sym = mdict_iter_match_first (block->multidict (), lookup_name,
735 &mdict_iter);
736 sym != NULL;
737 sym = mdict_iter_match_next (lookup_name, &mdict_iter))
739 /* With the fix for PR gcc/debug/91507, we get for:
741 extern char *zzz[];
742 char *zzz[ ] = {
743 "abc",
744 "cde"
747 DWARF which will result in two entries in the symbol table, a decl
748 with type char *[] and a def with type char *[2].
750 If we return the decl here, we don't get the value of zzz:
752 $ gdb a.spec.out -batch -ex "p zzz"
753 $1 = 0x601030 <zzz>
755 because we're returning the symbol without location information, and
756 because the fallback that uses the address from the minimal symbols
757 doesn't work either because the type of the decl does not specify a
758 size.
760 To fix this, we prefer def over decl in best_symbol and
761 better_symbol.
763 In absence of the gcc fix, both def and decl have type char *[], so
764 the only option to make this work is improve the fallback to use the
765 size of the minimal symbol. Filed as PR exp/24989. */
766 if (best_symbol (sym, domain))
767 return sym;
769 /* This is a bit of a hack, but 'matches' might ignore
770 STRUCT vs VAR domain symbols. So if a matching symbol is found,
771 make sure there is no "better" matching symbol, i.e., one with
772 exactly the same domain. PR 16253. */
773 if (sym->matches (domain))
774 other = better_symbol (other, sym, domain);
777 return other;
780 /* See block.h. */
782 struct symbol *
783 block_find_symbol (const struct block *block, const lookup_name_info &name,
784 const domain_search_flags domain, struct symbol **stub)
786 /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
787 gdb_assert (block->superblock () == NULL
788 || block->superblock ()->superblock () == NULL);
790 for (struct symbol *sym : block_iterator_range (block, &name))
792 if (!sym->matches (domain))
793 continue;
795 if (!TYPE_IS_OPAQUE (sym->type ()))
796 return sym;
798 if (stub != nullptr)
799 *stub = sym;
801 return nullptr;
804 /* See block.h. */
806 struct blockranges *
807 make_blockranges (struct objfile *objfile,
808 const std::vector<blockrange> &rangevec)
810 struct blockranges *blr;
811 size_t n = rangevec.size();
813 blr = (struct blockranges *)
814 obstack_alloc (&objfile->objfile_obstack,
815 sizeof (struct blockranges)
816 + (n - 1) * sizeof (struct blockrange));
818 blr->nranges = n;
819 for (int i = 0; i < n; i++)
820 blr->range[i] = rangevec[i];
821 return blr;
824 /* Implement 'maint info blocks' command. If passed an argument then
825 print a list of all blocks at the given address. With no arguments
826 then list all blocks at the current address of the current inferior. */
828 static void
829 maintenance_info_blocks (const char *arg, int from_tty)
831 CORE_ADDR address;
833 /* With no argument use the program counter of the current thread. If
834 there is an argument then use this as the address to examine. */
835 if (arg == nullptr)
837 if (inferior_ptid == null_ptid)
838 error (_("no inferior thread"));
840 struct regcache *regcache = get_thread_regcache (inferior_thread ());
841 address = regcache_read_pc (regcache);
843 else
844 address = parse_and_eval_address (arg);
846 /* Find the inner most block for ADDRESS. */
847 const struct block *cur_block = block_for_pc (address);
848 if (cur_block == nullptr)
850 gdb_printf (_("No blocks at %s\n"), core_addr_to_string_nz (address));
851 return;
854 gdb_printf (_("Blocks at %s:\n"), core_addr_to_string_nz (address));
856 const struct objfile *toplevel_objfile = cur_block->objfile ();
857 if (toplevel_objfile != nullptr)
858 gdb_printf (_(" from objfile: [(objfile *) %s] %s\n"),
859 host_address_to_string (toplevel_objfile),
860 objfile_name (toplevel_objfile));
862 gdb_printf ("\n");
864 /* List the blocks backwards; global block (widest scope) first, down to
865 the smallest scoped block last. To do this we need to build the list
866 of blocks starting from the inner block, then print that list
867 backwards. */
868 std::vector<const struct block *> blocks;
869 while (cur_block != nullptr)
871 blocks.emplace_back (cur_block);
872 cur_block = cur_block->superblock ();
875 for (auto it = blocks.rbegin (); it != blocks.rend (); ++it)
877 cur_block = *it;
879 gdb_assert (cur_block->objfile () == toplevel_objfile);
881 gdb_printf (_("[(block *) %s] %s..%s\n"),
882 host_address_to_string (cur_block),
883 core_addr_to_string_nz (cur_block->start ()),
884 core_addr_to_string_nz (cur_block->end ()));
885 gdb_printf (_(" entry pc: %s\n"),
886 core_addr_to_string_nz (cur_block->entry_pc ()));
888 if (cur_block->is_static_block ())
889 gdb_printf (_(" is static block\n"));
891 if (cur_block->is_global_block ())
892 gdb_printf (_(" is global block\n"));
894 if (cur_block->function () != nullptr)
896 if (cur_block->inlined_p ())
897 gdb_printf (_(" inline function: %s\n"),
898 cur_block->function ()->print_name ());
899 else
900 gdb_printf (_(" function: %s\n"),
901 cur_block->function ()->print_name ());
904 if (cur_block->scope () != nullptr
905 && *cur_block->scope () != '\0')
906 gdb_printf (_(" scope: %s\n"), cur_block->scope ());
908 if (int symbol_count = mdict_size (cur_block->multidict ());
909 symbol_count > 0)
910 gdb_printf (_(" symbol count: %d\n"), symbol_count);
912 if (cur_block->is_contiguous ())
913 gdb_printf (_(" is contiguous\n"));
914 else
916 gdb_printf (_(" address ranges:\n"));
917 for (const blockrange &rng : cur_block->ranges ())
918 gdb_printf (_(" %s..%s\n"),
919 core_addr_to_string_nz (rng.start ()),
920 core_addr_to_string_nz (rng.end ()));
927 void _initialize_block ();
928 void
929 _initialize_block ()
931 add_cmd ("blocks", class_maintenance, maintenance_info_blocks,
932 _("\
933 Display block information for current thread.\n\
935 Usage:\n\
937 maintenance info blocks [ADDRESS]\n\
939 With no ADDRESS show all blocks at the current address, starting with the\n\
940 global block and working down to the inner most block.\n\
942 When ADDRESS is given, list the blocks at ADDRESS."),
943 &maintenanceinfolist);