OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [block.c] - Blame information for rev 157

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Block-related functions for the GNU debugger, GDB.
2
 
3
   Copyright (C) 2003, 2007, 2008 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 "defs.h"
21
#include "block.h"
22
#include "symtab.h"
23
#include "symfile.h"
24
#include "gdb_obstack.h"
25
#include "cp-support.h"
26
#include "addrmap.h"
27
 
28
/* This is used by struct block to store namespace-related info for
29
   C++ files, namely using declarations and the current namespace in
30
   scope.  */
31
 
32
struct block_namespace_info
33
{
34
  const char *scope;
35
  struct using_direct *using;
36
};
37
 
38
static void block_initialize_namespace (struct block *block,
39
                                        struct obstack *obstack);
40
 
41
/* Return Nonzero if block a is lexically nested within block b,
42
   or if a and b have the same pc range.
43
   Return zero otherwise. */
44
 
45
int
46
contained_in (const struct block *a, const struct block *b)
47
{
48
  if (!a || !b)
49
    return 0;
50
  return BLOCK_START (a) >= BLOCK_START (b)
51
    && BLOCK_END (a) <= BLOCK_END (b);
52
}
53
 
54
 
55
/* Return the symbol for the function which contains a specified
56
   lexical block, described by a struct block BL.  */
57
 
58
struct symbol *
59
block_function (const struct block *bl)
60
{
61
  while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
62
    bl = BLOCK_SUPERBLOCK (bl);
63
 
64
  return BLOCK_FUNCTION (bl);
65
}
66
 
67
/* Return the blockvector immediately containing the innermost lexical
68
   block containing the specified pc value and section, or 0 if there
69
   is none.  PBLOCK is a pointer to the block.  If PBLOCK is NULL, we
70
   don't pass this information back to the caller.  */
71
 
72
struct blockvector *
73
blockvector_for_pc_sect (CORE_ADDR pc, struct bfd_section *section,
74
                         struct block **pblock, struct symtab *symtab)
75
{
76
  struct block *b;
77
  int bot, top, half;
78
  struct blockvector *bl;
79
 
80
  if (symtab == 0)               /* if no symtab specified by caller */
81
    {
82
      /* First search all symtabs for one whose file contains our pc */
83
      symtab = find_pc_sect_symtab (pc, section);
84
      if (symtab == 0)
85
        return 0;
86
    }
87
 
88
  bl = BLOCKVECTOR (symtab);
89
 
90
  /* Then search that symtab for the smallest block that wins.  */
91
 
92
  /* If we have an addrmap mapping code addresses to blocks, then use
93
     that.  */
94
  if (BLOCKVECTOR_MAP (bl))
95
    {
96
      b = addrmap_find (BLOCKVECTOR_MAP (bl), pc);
97
      if (b)
98
        {
99
          if (pblock)
100
            *pblock = b;
101
          return bl;
102
        }
103
      else
104
        return 0;
105
    }
106
 
107
 
108
  /* Otherwise, use binary search to find the last block that starts
109
     before PC.  */
110
  bot = 0;
111
  top = BLOCKVECTOR_NBLOCKS (bl);
112
 
113
  while (top - bot > 1)
114
    {
115
      half = (top - bot + 1) >> 1;
116
      b = BLOCKVECTOR_BLOCK (bl, bot + half);
117
      if (BLOCK_START (b) <= pc)
118
        bot += half;
119
      else
120
        top = bot + half;
121
    }
122
 
123
  /* Now search backward for a block that ends after PC.  */
124
 
125
  while (bot >= 0)
126
    {
127
      b = BLOCKVECTOR_BLOCK (bl, bot);
128
      if (BLOCK_END (b) > pc)
129
        {
130
          if (pblock)
131
            *pblock = b;
132
          return bl;
133
        }
134
      bot--;
135
    }
136
  return 0;
137
}
138
 
139
/* Return the blockvector immediately containing the innermost lexical block
140
   containing the specified pc value, or 0 if there is none.
141
   Backward compatibility, no section.  */
142
 
143
struct blockvector *
144
blockvector_for_pc (CORE_ADDR pc, struct block **pblock)
145
{
146
  return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
147
                                  pblock, NULL);
148
}
149
 
150
/* Return the innermost lexical block containing the specified pc value
151
   in the specified section, or 0 if there is none.  */
152
 
153
struct block *
154
block_for_pc_sect (CORE_ADDR pc, struct bfd_section *section)
155
{
156
  struct blockvector *bl;
157
  struct block *b;
158
 
159
  bl = blockvector_for_pc_sect (pc, section, &b, NULL);
160
  if (bl)
161
    return b;
162
  return 0;
163
}
164
 
165
/* Return the innermost lexical block containing the specified pc value,
166
   or 0 if there is none.  Backward compatibility, no section.  */
167
 
168
struct block *
169
block_for_pc (CORE_ADDR pc)
170
{
171
  return block_for_pc_sect (pc, find_pc_mapped_section (pc));
172
}
173
 
174
/* Now come some functions designed to deal with C++ namespace issues.
175
   The accessors are safe to use even in the non-C++ case.  */
176
 
177
/* This returns the namespace that BLOCK is enclosed in, or "" if it
178
   isn't enclosed in a namespace at all.  This travels the chain of
179
   superblocks looking for a scope, if necessary.  */
180
 
181
const char *
182
block_scope (const struct block *block)
183
{
184
  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
185
    {
186
      if (BLOCK_NAMESPACE (block) != NULL
187
          && BLOCK_NAMESPACE (block)->scope != NULL)
188
        return BLOCK_NAMESPACE (block)->scope;
189
    }
190
 
191
  return "";
192
}
193
 
194
/* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
195
   OBSTACK.  (It won't make a copy of SCOPE, however, so that already
196
   has to be allocated correctly.)  */
197
 
198
void
199
block_set_scope (struct block *block, const char *scope,
200
                 struct obstack *obstack)
201
{
202
  block_initialize_namespace (block, obstack);
203
 
204
  BLOCK_NAMESPACE (block)->scope = scope;
205
}
206
 
207
/* This returns the first using directives associated to BLOCK, if
208
   any.  */
209
 
210
/* FIXME: carlton/2003-04-23: This uses the fact that we currently
211
   only have using directives in static blocks, because we only
212
   generate using directives from anonymous namespaces.  Eventually,
213
   when we support using directives everywhere, we'll want to replace
214
   this by some iterator functions.  */
215
 
216
struct using_direct *
217
block_using (const struct block *block)
218
{
219
  const struct block *static_block = block_static_block (block);
220
 
221
  if (static_block == NULL
222
      || BLOCK_NAMESPACE (static_block) == NULL)
223
    return NULL;
224
  else
225
    return BLOCK_NAMESPACE (static_block)->using;
226
}
227
 
228
/* Set BLOCK's using member to USING; if needed, allocate memory via
229
   OBSTACK.  (It won't make a copy of USING, however, so that already
230
   has to be allocated correctly.)  */
231
 
232
void
233
block_set_using (struct block *block,
234
                 struct using_direct *using,
235
                 struct obstack *obstack)
236
{
237
  block_initialize_namespace (block, obstack);
238
 
239
  BLOCK_NAMESPACE (block)->using = using;
240
}
241
 
242
/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
243
   ititialize its members to zero.  */
244
 
245
static void
246
block_initialize_namespace (struct block *block, struct obstack *obstack)
247
{
248
  if (BLOCK_NAMESPACE (block) == NULL)
249
    {
250
      BLOCK_NAMESPACE (block)
251
        = obstack_alloc (obstack, sizeof (struct block_namespace_info));
252
      BLOCK_NAMESPACE (block)->scope = NULL;
253
      BLOCK_NAMESPACE (block)->using = NULL;
254
    }
255
}
256
 
257
/* Return the static block associated to BLOCK.  Return NULL if block
258
   is NULL or if block is a global block.  */
259
 
260
const struct block *
261
block_static_block (const struct block *block)
262
{
263
  if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
264
    return NULL;
265
 
266
  while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
267
    block = BLOCK_SUPERBLOCK (block);
268
 
269
  return block;
270
}
271
 
272
/* Return the static block associated to BLOCK.  Return NULL if block
273
   is NULL.  */
274
 
275
const struct block *
276
block_global_block (const struct block *block)
277
{
278
  if (block == NULL)
279
    return NULL;
280
 
281
  while (BLOCK_SUPERBLOCK (block) != NULL)
282
    block = BLOCK_SUPERBLOCK (block);
283
 
284
  return block;
285
}
286
 
287
/* Allocate a block on OBSTACK, and initialize its elements to
288
   zero/NULL.  This is useful for creating "dummy" blocks that don't
289
   correspond to actual source files.
290
 
291
   Warning: it sets the block's BLOCK_DICT to NULL, which isn't a
292
   valid value.  If you really don't want the block to have a
293
   dictionary, then you should subsequently set its BLOCK_DICT to
294
   dict_create_linear (obstack, NULL).  */
295
 
296
struct block *
297
allocate_block (struct obstack *obstack)
298
{
299
  struct block *bl = obstack_alloc (obstack, sizeof (struct block));
300
 
301
  BLOCK_START (bl) = 0;
302
  BLOCK_END (bl) = 0;
303
  BLOCK_FUNCTION (bl) = NULL;
304
  BLOCK_SUPERBLOCK (bl) = NULL;
305
  BLOCK_DICT (bl) = NULL;
306
  BLOCK_NAMESPACE (bl) = NULL;
307
 
308
  return bl;
309
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.