1 /* Block-related functions for the GNU debugger, GDB.
2
3 Copyright (C) 2003-2024 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
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
29 /* This is used by struct block to store namespace-related info for
30 C++ files, namely using declarations and the current namespace in
31 scope. */
32
33 struct block_namespace_info : public allocate_on_obstack<block_namespace_info>
34 {
35 const char *scope = nullptr;
36 struct using_direct *using_decl = nullptr;
37 };
38
39 /* See block.h. */
40
41 struct objfile *
objfile()42 block::objfile () const
43 {
44 const struct global_block *global_block;
45
46 if (function () != nullptr)
47 return function ()->objfile ();
48
49 global_block = (struct global_block *) this->global_block ();
50 return global_block->compunit_symtab->objfile ();
51 }
52
53 /* See block. */
54
55 struct gdbarch *
gdbarch()56 block::gdbarch () const
57 {
58 if (function () != nullptr)
59 return function ()->arch ();
60
61 return objfile ()->arch ();
62 }
63
64 /* See block.h. */
65
66 bool
contains(const struct block * a,bool allow_nested)67 block::contains (const struct block *a, bool allow_nested) const
68 {
69 if (a == nullptr)
70 return false;
71
72 do
73 {
74 if (a == this)
75 return true;
76 /* If A is a function block, then A cannot be contained in B,
77 except if A was inlined. */
78 if (!allow_nested && a->function () != NULL && !a->inlined_p ())
79 return false;
80 a = a->superblock ();
81 }
82 while (a != NULL);
83
84 return false;
85 }
86
87 /* See block.h. */
88
89 struct symbol *
linkage_function()90 block::linkage_function () const
91 {
92 const block *bl = this;
93
94 while ((bl->function () == NULL || bl->inlined_p ())
95 && bl->superblock () != NULL)
96 bl = bl->superblock ();
97
98 return bl->function ();
99 }
100
101 /* See block.h. */
102
103 struct symbol *
containing_function()104 block::containing_function () const
105 {
106 const block *bl = this;
107
108 while (bl->function () == NULL && bl->superblock () != NULL)
109 bl = bl->superblock ();
110
111 return bl->function ();
112 }
113
114 /* See block.h. */
115
116 bool
inlined_p()117 block::inlined_p () const
118 {
119 return function () != nullptr && function ()->is_inlined ();
120 }
121
122 /* A helper function that checks whether PC is in the blockvector BL.
123 It returns the containing block if there is one, or else NULL. */
124
125 static const struct block *
find_block_in_blockvector(const struct blockvector * bl,CORE_ADDR pc)126 find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
127 {
128 const struct block *b;
129 int bot, top, half;
130
131 /* If we have an addrmap mapping code addresses to blocks, then use
132 that. */
133 if (bl->map ())
134 return (const struct block *) bl->map ()->find (pc);
135
136 /* Otherwise, use binary search to find the last block that starts
137 before PC.
138 Note: GLOBAL_BLOCK is block 0, STATIC_BLOCK is block 1.
139 They both have the same START,END values.
140 Historically this code would choose STATIC_BLOCK over GLOBAL_BLOCK but the
141 fact that this choice was made was subtle, now we make it explicit. */
142 gdb_assert (bl->blocks ().size () >= 2);
143 bot = STATIC_BLOCK;
144 top = bl->blocks ().size ();
145
146 while (top - bot > 1)
147 {
148 half = (top - bot + 1) >> 1;
149 b = bl->block (bot + half);
150 if (b->start () <= pc)
151 bot += half;
152 else
153 top = bot + half;
154 }
155
156 /* Now search backward for a block that ends after PC. */
157
158 while (bot >= STATIC_BLOCK)
159 {
160 b = bl->block (bot);
161 if (!(b->start () <= pc))
162 return NULL;
163 if (b->end () > pc)
164 return b;
165 bot--;
166 }
167
168 return NULL;
169 }
170
171 /* Return the blockvector immediately containing the innermost lexical
172 block containing the specified pc value and section, or 0 if there
173 is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we
174 don't pass this information back to the caller. */
175
176 const struct blockvector *
blockvector_for_pc_sect(CORE_ADDR pc,struct obj_section * section,const struct block ** pblock,struct compunit_symtab * cust)177 blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
178 const struct block **pblock,
179 struct compunit_symtab *cust)
180 {
181 const struct blockvector *bl;
182 const struct block *b;
183
184 if (cust == NULL)
185 {
186 /* First search all symtabs for one whose file contains our pc */
187 cust = find_pc_sect_compunit_symtab (pc, section);
188 if (cust == NULL)
189 return 0;
190 }
191
192 bl = cust->blockvector ();
193
194 /* Then search that symtab for the smallest block that wins. */
195 b = find_block_in_blockvector (bl, pc);
196 if (b == NULL)
197 return NULL;
198
199 if (pblock)
200 *pblock = b;
201 return bl;
202 }
203
204 /* Return true if the blockvector BV contains PC, false otherwise. */
205
206 int
blockvector_contains_pc(const struct blockvector * bv,CORE_ADDR pc)207 blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc)
208 {
209 return find_block_in_blockvector (bv, pc) != NULL;
210 }
211
212 /* Return call_site for specified PC in GDBARCH. PC must match exactly, it
213 must be the next instruction after call (or after tail call jump). Throw
214 NO_ENTRY_VALUE_ERROR otherwise. This function never returns NULL. */
215
216 struct call_site *
call_site_for_pc(struct gdbarch * gdbarch,CORE_ADDR pc)217 call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
218 {
219 struct compunit_symtab *cust;
220 call_site *cs = nullptr;
221
222 /* -1 as tail call PC can be already after the compilation unit range. */
223 cust = find_pc_compunit_symtab (pc - 1);
224
225 if (cust != nullptr)
226 cs = cust->find_call_site (pc);
227
228 if (cs == nullptr)
229 {
230 struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc);
231
232 /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
233 the call target. */
234 throw_error (NO_ENTRY_VALUE_ERROR,
235 _("DW_OP_entry_value resolving cannot find "
236 "DW_TAG_call_site %s in %s"),
237 paddress (gdbarch, pc),
238 (msym.minsym == NULL ? "???"
239 : msym.minsym->print_name ()));
240 }
241
242 return cs;
243 }
244
245 /* Return the blockvector immediately containing the innermost lexical block
246 containing the specified pc value, or 0 if there is none.
247 Backward compatibility, no section. */
248
249 const struct blockvector *
blockvector_for_pc(CORE_ADDR pc,const struct block ** pblock)250 blockvector_for_pc (CORE_ADDR pc, const struct block **pblock)
251 {
252 return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
253 pblock, NULL);
254 }
255
256 /* Return the innermost lexical block containing the specified pc value
257 in the specified section, or 0 if there is none. */
258
259 const struct block *
block_for_pc_sect(CORE_ADDR pc,struct obj_section * section)260 block_for_pc_sect (CORE_ADDR pc, struct obj_section *section)
261 {
262 const struct blockvector *bl;
263 const struct block *b;
264
265 bl = blockvector_for_pc_sect (pc, section, &b, NULL);
266 if (bl)
267 return b;
268 return 0;
269 }
270
271 /* Return the innermost lexical block containing the specified pc value,
272 or 0 if there is none. Backward compatibility, no section. */
273
274 const struct block *
block_for_pc(CORE_ADDR pc)275 block_for_pc (CORE_ADDR pc)
276 {
277 return block_for_pc_sect (pc, find_pc_mapped_section (pc));
278 }
279
280 /* Now come some functions designed to deal with C++ namespace issues.
281 The accessors are safe to use even in the non-C++ case. */
282
283 /* See block.h. */
284
285 const char *
scope()286 block::scope () const
287 {
288 for (const block *block = this;
289 block != nullptr;
290 block = block->superblock ())
291 {
292 if (block->m_namespace_info != nullptr
293 && block->m_namespace_info->scope != nullptr)
294 return block->m_namespace_info->scope;
295 }
296
297 return "";
298 }
299
300 /* See block.h. */
301
302 void
initialize_namespace(struct obstack * obstack)303 block::initialize_namespace (struct obstack *obstack)
304 {
305 if (m_namespace_info == nullptr)
306 m_namespace_info = new (obstack) struct block_namespace_info;
307 }
308
309 /* See block.h. */
310
311 void
set_scope(const char * scope,struct obstack * obstack)312 block::set_scope (const char *scope, struct obstack *obstack)
313 {
314 if (scope == nullptr || scope[0] == '\0')
315 {
316 /* Don't bother. */
317 return;
318 }
319
320 initialize_namespace (obstack);
321 m_namespace_info->scope = scope;
322 }
323
324 /* See block.h. */
325
326 struct using_direct *
get_using()327 block::get_using () const
328 {
329 if (m_namespace_info == nullptr)
330 return nullptr;
331 else
332 return m_namespace_info->using_decl;
333 }
334
335 /* See block.h. */
336
337 void
set_using(struct using_direct * using_decl,struct obstack * obstack)338 block::set_using (struct using_direct *using_decl, struct obstack *obstack)
339 {
340 if (using_decl == nullptr)
341 {
342 /* Don't bother. */
343 return;
344 }
345
346 initialize_namespace (obstack);
347 m_namespace_info->using_decl = using_decl;
348 }
349
350 /* See block.h. */
351
352 const struct block *
static_block()353 block::static_block () const
354 {
355 if (superblock () == nullptr)
356 return nullptr;
357
358 const block *block = this;
359 while (block->superblock ()->superblock () != NULL)
360 block = block->superblock ();
361
362 return block;
363 }
364
365 /* See block.h. */
366
367 const struct block *
global_block()368 block::global_block () const
369 {
370 const block *block = this;
371
372 while (block->superblock () != NULL)
373 block = block->superblock ();
374
375 return block;
376 }
377
378 /* See block.h. */
379
380 const struct block *
function_block()381 block::function_block () const
382 {
383 const block *block = this;
384
385 while (block != nullptr && block->function () == nullptr)
386 block = block->superblock ();
387
388 return block;
389 }
390
391 /* See block.h. */
392
393 void
set_compunit_symtab(struct compunit_symtab * cu)394 block::set_compunit_symtab (struct compunit_symtab *cu)
395 {
396 struct global_block *gb;
397
398 gdb_assert (superblock () == NULL);
399 gb = (struct global_block *) this;
400 gdb_assert (gb->compunit_symtab == NULL);
401 gb->compunit_symtab = cu;
402 }
403
404 /* See block.h. */
405
406 struct dynamic_prop *
static_link()407 block::static_link () const
408 {
409 struct objfile *objfile = this->objfile ();
410
411 /* Only objfile-owned blocks that materialize top function scopes can have
412 static links. */
413 if (objfile == NULL || function () == NULL)
414 return NULL;
415
416 return (struct dynamic_prop *) objfile_lookup_static_link (objfile, this);
417 }
418
419 /* Return the compunit of the global block. */
420
421 static struct compunit_symtab *
get_block_compunit_symtab(const struct block * block)422 get_block_compunit_symtab (const struct block *block)
423 {
424 struct global_block *gb;
425
426 gdb_assert (block->superblock () == NULL);
427 gb = (struct global_block *) block;
428 gdb_assert (gb->compunit_symtab != NULL);
429 return gb->compunit_symtab;
430 }
431
432
433
434 /* Initialize a block iterator, either to iterate over a single block,
435 or, for static and global blocks, all the included symtabs as
436 well. */
437
438 static void
439 initialize_block_iterator (const struct block *block,
440 struct block_iterator *iter,
441 const lookup_name_info *name = nullptr)
442 {
443 enum block_enum which;
444 struct compunit_symtab *cu;
445
446 iter->idx = -1;
447 iter->name = name;
448
449 if (block->superblock () == NULL)
450 {
451 which = GLOBAL_BLOCK;
452 cu = get_block_compunit_symtab (block);
453 }
454 else if (block->superblock ()->superblock () == NULL)
455 {
456 which = STATIC_BLOCK;
457 cu = get_block_compunit_symtab (block->superblock ());
458 }
459 else
460 {
461 iter->d.block = block;
462 /* A signal value meaning that we're iterating over a single
463 block. */
464 iter->which = FIRST_LOCAL_BLOCK;
465 return;
466 }
467
468 /* If this is an included symtab, find the canonical includer and
469 use it instead. */
470 while (cu->user != NULL)
471 cu = cu->user;
472
473 /* Putting this check here simplifies the logic of the iterator
474 functions. If there are no included symtabs, we only need to
475 search a single block, so we might as well just do that
476 directly. */
477 if (cu->includes == NULL)
478 {
479 iter->d.block = block;
480 /* A signal value meaning that we're iterating over a single
481 block. */
482 iter->which = FIRST_LOCAL_BLOCK;
483 }
484 else
485 {
486 iter->d.compunit_symtab = cu;
487 iter->which = which;
488 }
489 }
490
491 /* A helper function that finds the current compunit over whose static
492 or global block we should iterate. */
493
494 static struct compunit_symtab *
find_iterator_compunit_symtab(struct block_iterator * iterator)495 find_iterator_compunit_symtab (struct block_iterator *iterator)
496 {
497 if (iterator->idx == -1)
498 return iterator->d.compunit_symtab;
499 return iterator->d.compunit_symtab->includes[iterator->idx];
500 }
501
502 /* Perform a single step for a plain block iterator, iterating across
503 symbol tables as needed. Returns the next symbol, or NULL when
504 iteration is complete. */
505
506 static struct symbol *
block_iterator_step(struct block_iterator * iterator,int first)507 block_iterator_step (struct block_iterator *iterator, int first)
508 {
509 struct symbol *sym;
510
511 gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
512
513 while (1)
514 {
515 if (first)
516 {
517 struct compunit_symtab *cust
518 = find_iterator_compunit_symtab (iterator);
519 const struct block *block;
520
521 /* Iteration is complete. */
522 if (cust == NULL)
523 return NULL;
524
525 block = cust->blockvector ()->block (iterator->which);
526 sym = mdict_iterator_first (block->multidict (),
527 &iterator->mdict_iter);
528 }
529 else
530 sym = mdict_iterator_next (&iterator->mdict_iter);
531
532 if (sym != NULL)
533 return sym;
534
535 /* We have finished iterating the appropriate block of one
536 symtab. Now advance to the next symtab and begin iteration
537 there. */
538 ++iterator->idx;
539 first = 1;
540 }
541 }
542
543 /* Perform a single step for a "match" block iterator, iterating
544 across symbol tables as needed. Returns the next symbol, or NULL
545 when iteration is complete. */
546
547 static struct symbol *
block_iter_match_step(struct block_iterator * iterator,int first)548 block_iter_match_step (struct block_iterator *iterator,
549 int first)
550 {
551 struct symbol *sym;
552
553 gdb_assert (iterator->which != FIRST_LOCAL_BLOCK);
554
555 while (1)
556 {
557 if (first)
558 {
559 struct compunit_symtab *cust
560 = find_iterator_compunit_symtab (iterator);
561 const struct block *block;
562
563 /* Iteration is complete. */
564 if (cust == NULL)
565 return NULL;
566
567 block = cust->blockvector ()->block (iterator->which);
568 sym = mdict_iter_match_first (block->multidict (), *iterator->name,
569 &iterator->mdict_iter);
570 }
571 else
572 sym = mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);
573
574 if (sym != NULL)
575 return sym;
576
577 /* We have finished iterating the appropriate block of one
578 symtab. Now advance to the next symtab and begin iteration
579 there. */
580 ++iterator->idx;
581 first = 1;
582 }
583 }
584
585 /* See block.h. */
586
587 struct symbol *
block_iterator_first(const struct block * block,struct block_iterator * iterator,const lookup_name_info * name)588 block_iterator_first (const struct block *block,
589 struct block_iterator *iterator,
590 const lookup_name_info *name)
591 {
592 initialize_block_iterator (block, iterator, name);
593
594 if (name == nullptr)
595 {
596 if (iterator->which == FIRST_LOCAL_BLOCK)
597 return mdict_iterator_first (block->multidict (),
598 &iterator->mdict_iter);
599
600 return block_iterator_step (iterator, 1);
601 }
602
603 if (iterator->which == FIRST_LOCAL_BLOCK)
604 return mdict_iter_match_first (block->multidict (), *name,
605 &iterator->mdict_iter);
606
607 return block_iter_match_step (iterator, 1);
608 }
609
610 /* See block.h. */
611
612 struct symbol *
block_iterator_next(struct block_iterator * iterator)613 block_iterator_next (struct block_iterator *iterator)
614 {
615 if (iterator->name == nullptr)
616 {
617 if (iterator->which == FIRST_LOCAL_BLOCK)
618 return mdict_iterator_next (&iterator->mdict_iter);
619
620 return block_iterator_step (iterator, 0);
621 }
622
623 if (iterator->which == FIRST_LOCAL_BLOCK)
624 return mdict_iter_match_next (*iterator->name, &iterator->mdict_iter);
625
626 return block_iter_match_step (iterator, 0);
627 }
628
629 /* See block.h. */
630
631 bool
best_symbol(struct symbol * a,const domain_search_flags domain)632 best_symbol (struct symbol *a, const domain_search_flags domain)
633 {
634 if (a->aclass () == LOC_UNRESOLVED)
635 return false;
636
637 if ((domain & SEARCH_VAR_DOMAIN) != 0)
638 return a->domain () == VAR_DOMAIN;
639
640 return a->matches (domain);
641 }
642
643 /* See block.h. */
644
645 struct symbol *
better_symbol(struct symbol * a,struct symbol * b,const domain_search_flags domain)646 better_symbol (struct symbol *a, struct symbol *b,
647 const domain_search_flags domain)
648 {
649 if (a == NULL)
650 return b;
651 if (b == NULL)
652 return a;
653
654 if (a->matches (domain) && !b->matches (domain))
655 return a;
656
657 if (b->matches (domain) && !a->matches (domain))
658 return b;
659
660 if (a->aclass () != LOC_UNRESOLVED && b->aclass () == LOC_UNRESOLVED)
661 return a;
662
663 if (b->aclass () != LOC_UNRESOLVED && a->aclass () == LOC_UNRESOLVED)
664 return b;
665
666 return a;
667 }
668
669 /* See block.h.
670
671 Note that if NAME is the demangled form of a C++ symbol, we will fail
672 to find a match during the binary search of the non-encoded names, but
673 for now we don't worry about the slight inefficiency of looking for
674 a match we'll never find, since it will go pretty quick. Once the
675 binary search terminates, we drop through and do a straight linear
676 search on the symbols. Each symbol which is marked as being a ObjC/C++
677 symbol (language_cplus or language_objc set) has both the encoded and
678 non-encoded names tested for a match. */
679
680 struct symbol *
block_lookup_symbol(const struct block * block,const lookup_name_info & name,const domain_search_flags domain)681 block_lookup_symbol (const struct block *block, const lookup_name_info &name,
682 const domain_search_flags domain)
683 {
684 if (!block->function ())
685 {
686 struct symbol *other = NULL;
687
688 for (struct symbol *sym : block_iterator_range (block, &name))
689 {
690 /* See comment related to PR gcc/debug/91507 in
691 block_lookup_symbol_primary. */
692 if (best_symbol (sym, domain))
693 return sym;
694 /* This is a bit of a hack, but symbol_matches_domain might ignore
695 STRUCT vs VAR domain symbols. So if a matching symbol is found,
696 make sure there is no "better" matching symbol, i.e., one with
697 exactly the same domain. PR 16253. */
698 if (sym->matches (domain))
699 other = better_symbol (other, sym, domain);
700 }
701 return other;
702 }
703 else
704 {
705 /* Note that parameter symbols do not always show up last in the
706 list; this loop makes sure to take anything else other than
707 parameter symbols first; it only uses parameter symbols as a
708 last resort. Note that this only takes up extra computation
709 time on a match.
710 It's hard to define types in the parameter list (at least in
711 C/C++) so we don't do the same PR 16253 hack here that is done
712 for the !BLOCK_FUNCTION case. */
713
714 struct symbol *sym_found = NULL;
715
716 for (struct symbol *sym : block_iterator_range (block, &name))
717 {
718 if (sym->matches (domain))
719 {
720 sym_found = sym;
721 if (!sym->is_argument ())
722 {
723 break;
724 }
725 }
726 }
727 return (sym_found); /* Will be NULL if not found. */
728 }
729 }
730
731 /* See block.h. */
732
733 struct symbol *
block_lookup_symbol_primary(const struct block * block,const char * name,const domain_search_flags domain)734 block_lookup_symbol_primary (const struct block *block, const char *name,
735 const domain_search_flags domain)
736 {
737 struct symbol *sym, *other;
738 struct mdict_iterator mdict_iter;
739
740 lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
741
742 /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
743 gdb_assert (block->superblock () == NULL
744 || block->superblock ()->superblock () == NULL);
745
746 other = NULL;
747 for (sym = mdict_iter_match_first (block->multidict (), lookup_name,
748 &mdict_iter);
749 sym != NULL;
750 sym = mdict_iter_match_next (lookup_name, &mdict_iter))
751 {
752 /* With the fix for PR gcc/debug/91507, we get for:
753 ...
754 extern char *zzz[];
755 char *zzz[ ] = {
756 "abc",
757 "cde"
758 };
759 ...
760 DWARF which will result in two entries in the symbol table, a decl
761 with type char *[] and a def with type char *[2].
762
763 If we return the decl here, we don't get the value of zzz:
764 ...
765 $ gdb a.spec.out -batch -ex "p zzz"
766 $1 = 0x601030 <zzz>
767 ...
768 because we're returning the symbol without location information, and
769 because the fallback that uses the address from the minimal symbols
770 doesn't work either because the type of the decl does not specify a
771 size.
772
773 To fix this, we prefer def over decl in best_symbol and
774 better_symbol.
775
776 In absence of the gcc fix, both def and decl have type char *[], so
777 the only option to make this work is improve the fallback to use the
778 size of the minimal symbol. Filed as PR exp/24989. */
779 if (best_symbol (sym, domain))
780 return sym;
781
782 /* This is a bit of a hack, but 'matches' might ignore
783 STRUCT vs VAR domain symbols. So if a matching symbol is found,
784 make sure there is no "better" matching symbol, i.e., one with
785 exactly the same domain. PR 16253. */
786 if (sym->matches (domain))
787 other = better_symbol (other, sym, domain);
788 }
789
790 return other;
791 }
792
793 /* See block.h. */
794
795 struct symbol *
block_find_symbol(const struct block * block,const lookup_name_info & name,const domain_search_flags domain,struct symbol ** stub)796 block_find_symbol (const struct block *block, const lookup_name_info &name,
797 const domain_search_flags domain, struct symbol **stub)
798 {
799 /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
800 gdb_assert (block->superblock () == NULL
801 || block->superblock ()->superblock () == NULL);
802
803 for (struct symbol *sym : block_iterator_range (block, &name))
804 {
805 if (!sym->matches (domain))
806 continue;
807
808 if (!TYPE_IS_OPAQUE (sym->type ()))
809 return sym;
810
811 if (stub != nullptr)
812 *stub = sym;
813 }
814 return nullptr;
815 }
816
817 /* See block.h. */
818
819 struct blockranges *
make_blockranges(struct objfile * objfile,const std::vector<blockrange> & rangevec)820 make_blockranges (struct objfile *objfile,
821 const std::vector<blockrange> &rangevec)
822 {
823 struct blockranges *blr;
824 size_t n = rangevec.size();
825
826 blr = (struct blockranges *)
827 obstack_alloc (&objfile->objfile_obstack,
828 sizeof (struct blockranges)
829 + (n - 1) * sizeof (struct blockrange));
830
831 blr->nranges = n;
832 for (int i = 0; i < n; i++)
833 blr->range[i] = rangevec[i];
834 return blr;
835 }
836
837