~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to pstack/rddbg.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* rddbg.c -- Read debugging information into a generic form.
 
2
   Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc.
 
3
   Written by Ian Lance Taylor <ian@cygnus.com>.
 
4
 
 
5
   This file is part of GNU Binutils.
 
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 2 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, write to the Free Software
 
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
20
   02111-1307, USA.  */
 
21
 
 
22
/* This file reads debugging information into a generic form.  This
 
23
   file knows how to dig the debugging information out of an object
 
24
   file.  */
 
25
 
 
26
#include <bfd.h>
 
27
#include "bucomm.h"
 
28
#include <libiberty.h>
 
29
#include "debug.h"
 
30
#include "budbg.h"
 
31
 
 
32
static boolean read_section_stabs_debugging_info
 
33
  PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
 
34
static boolean read_symbol_stabs_debugging_info
 
35
  PARAMS ((bfd *, asymbol **, long, PTR, boolean *));
 
36
static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *));
 
37
static void save_stab PARAMS ((int, int, bfd_vma, const char *));
 
38
static void stab_context PARAMS ((void));
 
39
static void free_saved_stabs PARAMS ((void));
 
40
 
 
41
/* Read debugging information from a BFD.  Returns a generic debugging
 
42
   pointer.  */
 
43
 
 
44
PTR
 
45
read_debugging_info (abfd, syms, symcount)
 
46
     bfd *abfd;
 
47
     asymbol **syms;
 
48
     long symcount;
 
49
{
 
50
  PTR dhandle;
 
51
  boolean found;
 
52
 
 
53
  dhandle = debug_init ();
 
54
  if (dhandle == NULL)
 
55
    return NULL;
 
56
 
 
57
  if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle,
 
58
                                           &found))
 
59
    return NULL;
 
60
 
 
61
  if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
 
62
    {
 
63
      if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle,
 
64
                                              &found))
 
65
        return NULL;
 
66
    }
 
67
 
 
68
  if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour)
 
69
    {
 
70
      if (! read_ieee_debugging_info (abfd, dhandle, &found))
 
71
        return NULL;
 
72
    }
 
73
 
 
74
  /* Try reading the COFF symbols if we didn't find any stabs in COFF
 
75
     sections.  */
 
76
  if (! found
 
77
      && bfd_get_flavour (abfd) == bfd_target_coff_flavour
 
78
      && symcount > 0)
 
79
    {
 
80
#if 0
 
81
/*
 
82
 * JZ: Do we need coff?
 
83
 */
 
84
      if (! parse_coff (abfd, syms, symcount, dhandle))
 
85
#else
 
86
      fprintf (stderr, "%s: COFF support temporarily disabled\n",
 
87
               bfd_get_filename (abfd));
 
88
      return NULL;
 
89
#endif
 
90
        return NULL;
 
91
      found = true;
 
92
    }
 
93
 
 
94
  if (! found)
 
95
    {
 
96
      fprintf (stderr, "%s: no recognized debugging information\n",
 
97
               bfd_get_filename (abfd));
 
98
      return NULL;
 
99
    }
 
100
 
 
101
  return dhandle;
 
102
}
 
103
 
 
104
/* Read stabs in sections debugging information from a BFD.  */
 
105
 
 
106
static boolean
 
107
read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
 
108
     bfd *abfd;
 
109
     asymbol **syms;
 
110
     long symcount;
 
111
     PTR dhandle;
 
112
     boolean *pfound;
 
113
{
 
114
  static struct
 
115
    {
 
116
      const char *secname;
 
117
      const char *strsecname;
 
118
    } names[] = { { ".stab", ".stabstr" } };
 
119
  unsigned int i;
 
120
  PTR shandle;
 
121
 
 
122
  *pfound = false;
 
123
  shandle = NULL;
 
124
 
 
125
  for (i = 0; i < sizeof names / sizeof names[0]; i++)
 
126
    {
 
127
      asection *sec, *strsec;
 
128
 
 
129
      sec = bfd_get_section_by_name (abfd, names[i].secname);
 
130
      strsec = bfd_get_section_by_name (abfd, names[i].strsecname);
 
131
      if (sec != NULL && strsec != NULL)
 
132
        {
 
133
          bfd_size_type stabsize, strsize;
 
134
          bfd_byte *stabs, *strings;
 
135
          bfd_byte *stab;
 
136
          bfd_size_type stroff, next_stroff;
 
137
 
 
138
          stabsize = bfd_section_size (abfd, sec);
 
139
          stabs = (bfd_byte *) xmalloc (stabsize);
 
140
          if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize))
 
141
            {
 
142
              fprintf (stderr, "%s: %s: %s\n",
 
143
                       bfd_get_filename (abfd), names[i].secname,
 
144
                       bfd_errmsg (bfd_get_error ()));
 
145
              return false;
 
146
            }
 
147
 
 
148
          strsize = bfd_section_size (abfd, strsec);
 
149
          strings = (bfd_byte *) xmalloc (strsize);
 
150
          if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
 
151
            {
 
152
              fprintf (stderr, "%s: %s: %s\n",
 
153
                       bfd_get_filename (abfd), names[i].strsecname,
 
154
                       bfd_errmsg (bfd_get_error ()));
 
155
              return false;
 
156
            }
 
157
 
 
158
          if (shandle == NULL)
 
159
            {
 
160
              shandle = start_stab (dhandle, abfd, true, syms, symcount);
 
161
              if (shandle == NULL)
 
162
                return false;
 
163
            }
 
164
 
 
165
          *pfound = true;
 
166
 
 
167
          stroff = 0;
 
168
          next_stroff = 0;
 
169
          for (stab = stabs; stab < stabs + stabsize; stab += 12)
 
170
            {
 
171
              bfd_size_type strx;
 
172
              int type;
 
173
              int other;
 
174
              int desc;
 
175
              bfd_vma value;
 
176
 
 
177
              /* This code presumes 32 bit values.  */
 
178
 
 
179
              strx = bfd_get_32 (abfd, stab);
 
180
              type = bfd_get_8 (abfd, stab + 4);
 
181
              other = bfd_get_8 (abfd, stab + 5);
 
182
              desc = bfd_get_16 (abfd, stab + 6);
 
183
              value = bfd_get_32 (abfd, stab + 8);
 
184
 
 
185
              if (type == 0)
 
186
                {
 
187
                  /* Special type 0 stabs indicate the offset to the
 
188
                     next string table.  */
 
189
                  stroff = next_stroff;
 
190
                  next_stroff += value;
 
191
                }
 
192
              else
 
193
                {
 
194
                  char *f, *s;
 
195
 
 
196
                  f = NULL;
 
197
                  s = (char *) strings + stroff + strx;
 
198
                  while (s[strlen (s) - 1] == '\\'
 
199
                         && stab + 12 < stabs + stabsize)
 
200
                    {
 
201
                      char *p;
 
202
 
 
203
                      stab += 12;
 
204
                      p = s + strlen (s) - 1;
 
205
                      *p = '\0';
 
206
                      s = concat (s,
 
207
                                  ((char *) strings
 
208
                                   + stroff
 
209
                                   + bfd_get_32 (abfd, stab)),
 
210
                                  (const char *) NULL);
 
211
 
 
212
                      /* We have to restore the backslash, because, if
 
213
                         the linker is hashing stabs strings, we may
 
214
                         see the same string more than once.  */
 
215
                      *p = '\\';
 
216
 
 
217
                      if (f != NULL)
 
218
                        free (f);
 
219
                      f = s;
 
220
                    }
 
221
 
 
222
                  save_stab (type, desc, value, s);
 
223
 
 
224
                  if (! parse_stab (dhandle, shandle, type, desc, value, s))
 
225
                    {
 
226
#if 0
 
227
/*
 
228
 * JZ: skip the junk.
 
229
 */
 
230
                      stab_context ();
 
231
                      free_saved_stabs ();
 
232
                      return false;
 
233
#endif
 
234
                    }
 
235
 
 
236
                  /* Don't free f, since I think the stabs code
 
237
                     expects strings to hang around.  This should be
 
238
                     straightened out.  FIXME.  */
 
239
                }
 
240
            }
 
241
 
 
242
          free_saved_stabs ();
 
243
          free (stabs);
 
244
 
 
245
          /* Don't free strings, since I think the stabs code expects
 
246
             the strings to hang around.  This should be straightened
 
247
             out.  FIXME.  */
 
248
        }
 
249
    }
 
250
 
 
251
  if (shandle != NULL)
 
252
    {
 
253
      if (! finish_stab (dhandle, shandle))
 
254
        return false;
 
255
    }
 
256
 
 
257
  return true;
 
258
}
 
259
 
 
260
/* Read stabs in the symbol table.  */
 
261
 
 
262
static boolean
 
263
read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound)
 
264
     bfd *abfd;
 
265
     asymbol **syms;
 
266
     long symcount;
 
267
     PTR dhandle;
 
268
     boolean *pfound;
 
269
{
 
270
  PTR shandle;
 
271
  asymbol **ps, **symend;
 
272
 
 
273
  shandle = NULL;
 
274
  symend = syms + symcount;
 
275
  for (ps = syms; ps < symend; ps++)
 
276
    {
 
277
      symbol_info i;
 
278
 
 
279
      bfd_get_symbol_info (abfd, *ps, &i);
 
280
 
 
281
      if (i.type == '-')
 
282
        {
 
283
          const char *s;
 
284
          char *f;
 
285
 
 
286
          if (shandle == NULL)
 
287
            {
 
288
              shandle = start_stab (dhandle, abfd, false, syms, symcount);
 
289
              if (shandle == NULL)
 
290
                return false;
 
291
            }
 
292
 
 
293
          *pfound = true;
 
294
 
 
295
          s = i.name;
 
296
          f = NULL;
 
297
          while (s[strlen (s) - 1] == '\\'
 
298
                 && ps + 1 < symend)
 
299
            {
 
300
              char *sc, *n;
 
301
 
 
302
              ++ps;
 
303
              sc = xstrdup (s);
 
304
              sc[strlen (sc) - 1] = '\0';
 
305
              n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL);
 
306
              free (sc);
 
307
              if (f != NULL)
 
308
                free (f);
 
309
              f = n;
 
310
              s = n;
 
311
            }
 
312
 
 
313
          save_stab (i.stab_type, i.stab_desc, i.value, s);
 
314
 
 
315
          if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc,
 
316
                            i.value, s))
 
317
            {
 
318
              stab_context ();
 
319
              free_saved_stabs ();
 
320
              return false;
 
321
            }
 
322
 
 
323
          /* Don't free f, since I think the stabs code expects
 
324
             strings to hang around.  This should be straightened out.
 
325
             FIXME.  */
 
326
        }
 
327
    }
 
328
 
 
329
  free_saved_stabs ();
 
330
 
 
331
  if (shandle != NULL)
 
332
    {
 
333
      if (! finish_stab (dhandle, shandle))
 
334
        return false;
 
335
    }
 
336
 
 
337
  return true;
 
338
}
 
339
 
 
340
/* Read IEEE debugging information.  */
 
341
 
 
342
static boolean
 
343
read_ieee_debugging_info (abfd, dhandle, pfound)
 
344
     bfd *abfd;
 
345
     PTR dhandle;
 
346
     boolean *pfound;
 
347
{
 
348
  asection *dsec;
 
349
  bfd_size_type size;
 
350
  bfd_byte *contents;
 
351
 
 
352
  /* The BFD backend puts the debugging information into a section
 
353
     named .debug.  */
 
354
 
 
355
  dsec = bfd_get_section_by_name (abfd, ".debug");
 
356
  if (dsec == NULL)
 
357
    return true;
 
358
 
 
359
  size = bfd_section_size (abfd, dsec);
 
360
  contents = (bfd_byte *) xmalloc (size);
 
361
  if (! bfd_get_section_contents (abfd, dsec, contents, 0, size))
 
362
    return false;
 
363
 
 
364
  if (! parse_ieee (dhandle, abfd, contents, size))
 
365
    return false;
 
366
 
 
367
  free (contents);
 
368
 
 
369
  *pfound = true;
 
370
 
 
371
  return true;
 
372
}
 
373
 
 
374
/* Record stabs strings, so that we can give some context for errors.  */
 
375
 
 
376
#define SAVE_STABS_COUNT (16)
 
377
 
 
378
struct saved_stab
 
379
{
 
380
  int type;
 
381
  int desc;
 
382
  bfd_vma value;
 
383
  char *string;
 
384
};
 
385
 
 
386
static struct saved_stab saved_stabs[SAVE_STABS_COUNT];
 
387
static int saved_stabs_index;
 
388
 
 
389
/* Save a stabs string.  */
 
390
 
 
391
static void
 
392
save_stab (type, desc, value, string)
 
393
     int type;
 
394
     int desc;
 
395
     bfd_vma value;
 
396
     const char *string;
 
397
{
 
398
  if (saved_stabs[saved_stabs_index].string != NULL)
 
399
    free (saved_stabs[saved_stabs_index].string);
 
400
  saved_stabs[saved_stabs_index].type = type;
 
401
  saved_stabs[saved_stabs_index].desc = desc;
 
402
  saved_stabs[saved_stabs_index].value = value;
 
403
  saved_stabs[saved_stabs_index].string = xstrdup (string);
 
404
  saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT;
 
405
}
 
406
 
 
407
/* Provide context for an error.  */
 
408
 
 
409
static void
 
410
stab_context ()
 
411
{
 
412
  int i;
 
413
 
 
414
  fprintf (stderr, "Last stabs entries before error:\n");
 
415
  fprintf (stderr, "n_type n_desc n_value  string\n");
 
416
 
 
417
  i = saved_stabs_index;
 
418
  do
 
419
    {
 
420
      struct saved_stab *stabp;
 
421
 
 
422
      stabp = saved_stabs + i;
 
423
      if (stabp->string != NULL)
 
424
        {
 
425
          const char *s;
 
426
 
 
427
          s = bfd_get_stab_name (stabp->type);
 
428
          if (s != NULL)
 
429
            fprintf (stderr, "%-6s", s);
 
430
          else if (stabp->type == 0)
 
431
            fprintf (stderr, "HdrSym");
 
432
          else
 
433
            fprintf (stderr, "%-6d", stabp->type);
 
434
          fprintf (stderr, " %-6d ", stabp->desc);
 
435
          fprintf_vma (stderr, stabp->value);
 
436
          if (stabp->type != 0)
 
437
            fprintf (stderr, " %s", stabp->string);
 
438
          fprintf (stderr, "\n");
 
439
        }
 
440
      i = (i + 1) % SAVE_STABS_COUNT;
 
441
    }
 
442
  while (i != saved_stabs_index);
 
443
}
 
444
 
 
445
/* Free the saved stab strings.  */
 
446
 
 
447
static void
 
448
free_saved_stabs ()
 
449
{
 
450
  int i;
 
451
 
 
452
  for (i = 0; i < SAVE_STABS_COUNT; i++)
 
453
    {
 
454
      if (saved_stabs[i].string != NULL)
 
455
        {
 
456
          free (saved_stabs[i].string);
 
457
          saved_stabs[i].string = NULL;
 
458
        }
 
459
    }
 
460
 
 
461
  saved_stabs_index = 0;
 
462
}