~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
}