~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/dwarf1.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
 
2
   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
3
 
 
4
Written by Gavin Romig-Koch of Cygnus Solutions (gavin@cygnus.com).
 
5
 
 
6
This file is part of BFD.
 
7
 
 
8
This program is free software; you can redistribute it and/or modify
 
9
it under the terms of the GNU General Public License as published by
 
10
the Free Software Foundation; either version 2 of the License, or (at
 
11
your option) any later version.
 
12
 
 
13
This program is distributed in the hope that it will be useful, but
 
14
WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU General Public License
 
19
along with this program; if not, write to the Free Software
 
20
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
21
 
 
22
#include "bfd.h"
 
23
#include "sysdep.h"
 
24
#include "libiberty.h"
 
25
#include "libbfd.h"
 
26
#include "elf-bfd.h"
 
27
#include "elf/dwarf.h"
 
28
 
 
29
/* dwarf1_debug is the starting point for all dwarf1 info.  */
 
30
 
 
31
struct dwarf1_debug {
 
32
 
 
33
  /* The bfd we are working with.  */
 
34
  bfd* abfd;
 
35
 
 
36
  /* List of already parsed compilation units.  */
 
37
  struct dwarf1_unit* lastUnit;
 
38
 
 
39
  /* The buffer for the .debug section.
 
40
     Zero indicates that the .debug section failed to load.  */
 
41
  char* debug_section;
 
42
 
 
43
  /* Pointer to the end of the .debug_info section memory buffer.  */
 
44
  char* debug_section_end;
 
45
 
 
46
  /* The buffer for the .line section.  */
 
47
  char* line_section;
 
48
 
 
49
  /* End of that buffer.  */
 
50
  char* line_section_end;
 
51
 
 
52
  /* The current or next unread die within the .debug section.  */
 
53
  char* currentDie;
 
54
};
 
55
 
 
56
/* One dwarf1_unit for each parsed compilation unit die.  */
 
57
 
 
58
struct dwarf1_unit {
 
59
  /* Linked starting from stash->lastUnit.  */
 
60
  struct dwarf1_unit* prev;
 
61
 
 
62
  /* Name of the compilation unit.  */
 
63
  char* name;
 
64
 
 
65
  /* The highest and lowest address used in the compilation unit.  */
 
66
  unsigned long low_pc;
 
67
  unsigned long high_pc;
 
68
 
 
69
  /* Does this unit have a statement list? */
 
70
  int has_stmt_list;
 
71
 
 
72
  /* If any, the offset of the line number table in the .line section.  */
 
73
  unsigned long stmt_list_offset;
 
74
 
 
75
  /* If non-zero, a pointer to the first child of this unit.  */
 
76
  char* first_child;
 
77
 
 
78
  /* How many line entries? */
 
79
  unsigned long line_count;
 
80
 
 
81
  /* The decoded line number table (line_count entries).  */
 
82
  struct linenumber* linenumber_table;
 
83
 
 
84
  /* The list of functions in this unit.  */
 
85
  struct dwarf1_func* func_list;
 
86
};
 
87
 
 
88
/* One dwarf1_func for each parsed function die.  */
 
89
 
 
90
struct dwarf1_func {
 
91
  /* Linked starting from aUnit->func_list.  */
 
92
  struct dwarf1_func* prev;
 
93
 
 
94
  /* Name of function.  */
 
95
  char* name;
 
96
 
 
97
  /* The highest and lowest address used in the compilation unit.  */
 
98
  unsigned long low_pc;
 
99
  unsigned long high_pc;
 
100
};
 
101
 
 
102
/* Used to return info about a parsed die.  */
 
103
struct die_info {
 
104
  unsigned long length;
 
105
  unsigned long sibling;
 
106
  unsigned long low_pc;
 
107
  unsigned long high_pc;
 
108
  unsigned long stmt_list_offset;
 
109
 
 
110
  char* name;
 
111
 
 
112
  int has_stmt_list;
 
113
 
 
114
  unsigned short tag;
 
115
};
 
116
 
 
117
/* Parsed line number information.  */
 
118
struct linenumber {
 
119
  /* First address in the line.  */
 
120
  unsigned long addr;
 
121
 
 
122
  /* The line number.  */
 
123
  unsigned long linenumber;
 
124
};
 
125
 
 
126
/* Find the form of an attr, from the attr field.  */
 
127
#define FORM_FROM_ATTR(attr)    ((attr) & 0xF)  /* Implicitly specified */
 
128
 
 
129
static struct dwarf1_unit *alloc_dwarf1_unit PARAMS ((struct dwarf1_debug *));
 
130
static struct dwarf1_func *alloc_dwarf1_func
 
131
  PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
 
132
static boolean parse_die PARAMS ((bfd *, struct die_info *, char *, char *));
 
133
static boolean parse_line_table
 
134
  PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
 
135
static boolean parse_functions_in_unit
 
136
  PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *));
 
137
static boolean dwarf1_unit_find_nearest_line
 
138
  PARAMS ((struct dwarf1_debug *, struct dwarf1_unit *, unsigned long,
 
139
           const char **, const char **, unsigned int *));
 
140
 
 
141
/* Return a newly allocated dwarf1_unit.  It should be cleared and
 
142
   then attached into the 'stash' at 'stash->lastUnit'.  */
 
143
 
 
144
static struct dwarf1_unit*
 
145
alloc_dwarf1_unit (stash)
 
146
  struct dwarf1_debug* stash;
 
147
{
 
148
  bfd_size_type amt = sizeof (struct dwarf1_unit);
 
149
 
 
150
  struct dwarf1_unit* x = (struct dwarf1_unit*) bfd_zalloc (stash->abfd, amt);
 
151
  x->prev = stash->lastUnit;
 
152
  stash->lastUnit = x;
 
153
 
 
154
  return x;
 
155
}
 
156
 
 
157
/* Return a newly allocated dwarf1_func.  It must be cleared and
 
158
   attached into 'aUnit' at 'aUnit->func_list'.  */
 
159
 
 
160
static struct dwarf1_func*
 
161
alloc_dwarf1_func (stash, aUnit)
 
162
     struct dwarf1_debug* stash;
 
163
     struct dwarf1_unit* aUnit;
 
164
{
 
165
  bfd_size_type amt = sizeof (struct dwarf1_func);
 
166
 
 
167
  struct dwarf1_func* x = (struct dwarf1_func*) bfd_zalloc (stash->abfd, amt);
 
168
  x->prev = aUnit->func_list;
 
169
  aUnit->func_list = x;
 
170
 
 
171
  return x;
 
172
}
 
173
 
 
174
/* parse_die - parse a Dwarf1 die.
 
175
   Parse the die starting at 'aDiePtr' into 'aDieInfo'.
 
176
   'abfd' must be the bfd from which the section that 'aDiePtr'
 
177
   points to was pulled from.
 
178
 
 
179
   Return false if the die is invalidly formatted; true otherwise.  */
 
180
 
 
181
static boolean
 
182
parse_die (abfd, aDieInfo, aDiePtr, aDiePtrEnd)
 
183
     bfd* abfd;
 
184
     struct die_info* aDieInfo;
 
185
     char*            aDiePtr;
 
186
     char*            aDiePtrEnd;
 
187
{
 
188
  char* this_die = aDiePtr;
 
189
  char* xptr = this_die;
 
190
 
 
191
  memset (aDieInfo,0,sizeof (*aDieInfo));
 
192
 
 
193
  /* First comes the length.  */
 
194
  aDieInfo->length = bfd_get_32 (abfd, (bfd_byte *) xptr);
 
195
  xptr += 4;
 
196
  if (aDieInfo->length == 0
 
197
      || (this_die + aDieInfo->length) >= aDiePtrEnd)
 
198
    return false;
 
199
  if (aDieInfo->length < 6)
 
200
    {
 
201
      /* Just padding bytes.  */
 
202
      aDieInfo->tag = TAG_padding;
 
203
      return true;
 
204
    }
 
205
 
 
206
  /* Then the tag.  */
 
207
  aDieInfo->tag = bfd_get_16 (abfd, (bfd_byte *) xptr);
 
208
  xptr += 2;
 
209
 
 
210
  /* Then the attributes.  */
 
211
  while (xptr < (this_die + aDieInfo->length))
 
212
    {
 
213
      unsigned short attr;
 
214
 
 
215
      /* Parse the attribute based on its form.  This section
 
216
         must handle all dwarf1 forms, but need only handle the
 
217
         actual attributes that we care about.  */
 
218
 
 
219
      attr = bfd_get_16 (abfd, (bfd_byte *) xptr);
 
220
      xptr += 2;
 
221
 
 
222
      switch (FORM_FROM_ATTR (attr))
 
223
        {
 
224
        case FORM_DATA2:
 
225
          xptr += 2;
 
226
          break;
 
227
        case FORM_DATA4:
 
228
        case FORM_REF:
 
229
          if (attr == AT_sibling)
 
230
            aDieInfo->sibling = bfd_get_32 (abfd, (bfd_byte *) xptr);
 
231
          else if (attr == AT_stmt_list)
 
232
            {
 
233
              aDieInfo->stmt_list_offset = bfd_get_32 (abfd, (bfd_byte *) xptr);
 
234
              aDieInfo->has_stmt_list = 1;
 
235
            }
 
236
          xptr += 4;
 
237
          break;
 
238
        case FORM_DATA8:
 
239
          xptr += 8;
 
240
          break;
 
241
        case FORM_ADDR:
 
242
          if (attr == AT_low_pc)
 
243
            aDieInfo->low_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
 
244
          else if (attr == AT_high_pc)
 
245
            aDieInfo->high_pc = bfd_get_32 (abfd, (bfd_byte *) xptr);
 
246
          xptr += 4;
 
247
          break;
 
248
        case FORM_BLOCK2:
 
249
          xptr += 2 + bfd_get_16 (abfd, (bfd_byte *) xptr);
 
250
          break;
 
251
        case FORM_BLOCK4:
 
252
          xptr += 4 + bfd_get_32 (abfd, (bfd_byte *) xptr);
 
253
          break;
 
254
        case FORM_STRING:
 
255
          if (attr == AT_name)
 
256
            aDieInfo->name = xptr;
 
257
          xptr += strlen (xptr) + 1;
 
258
          break;
 
259
        }
 
260
    }
 
261
 
 
262
  return true;
 
263
}
 
264
 
 
265
/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
 
266
   into 'aUnit->linenumber_table'.  Return false if an error
 
267
   occurs; true otherwise.  */
 
268
 
 
269
static boolean
 
270
parse_line_table (stash, aUnit)
 
271
  struct dwarf1_debug* stash;
 
272
  struct dwarf1_unit* aUnit;
 
273
{
 
274
  char* xptr;
 
275
 
 
276
  /* Load the ".line" section from the bfd if we haven't already.  */
 
277
  if (stash->line_section == 0)
 
278
    {
 
279
      asection *msec;
 
280
      bfd_size_type size;
 
281
 
 
282
      msec = bfd_get_section_by_name (stash->abfd, ".line");
 
283
      if (! msec)
 
284
        return false;
 
285
 
 
286
      size = bfd_get_section_size_before_reloc (msec);
 
287
      stash->line_section = (char *) bfd_alloc (stash->abfd, size);
 
288
 
 
289
      if (! stash->line_section)
 
290
        return false;
 
291
 
 
292
      if (! bfd_get_section_contents (stash->abfd, msec, stash->line_section,
 
293
                                      (bfd_vma) 0, size))
 
294
        {
 
295
          stash->line_section = 0;
 
296
          return false;
 
297
        }
 
298
 
 
299
      stash->line_section_end = stash->line_section + size;
 
300
    }
 
301
 
 
302
  xptr = stash->line_section + aUnit->stmt_list_offset;
 
303
  if (xptr < stash->line_section_end)
 
304
    {
 
305
      unsigned long eachLine;
 
306
      char *tblend;
 
307
      unsigned long base;
 
308
      bfd_size_type amt;
 
309
 
 
310
      /* First comes the length.  */
 
311
      tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr;
 
312
      xptr += 4;
 
313
 
 
314
      /* Then the base address for each address in the table.  */
 
315
      base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
 
316
      xptr += 4;
 
317
 
 
318
      /* How many line entrys?
 
319
         10 = 4 (line number) + 2 (pos in line) + 4 (address in line) */
 
320
      aUnit->line_count = (tblend - xptr) / 10;
 
321
 
 
322
      /* Allocate an array for the entries.  */
 
323
      amt = sizeof (struct linenumber) * aUnit->line_count;
 
324
      aUnit->linenumber_table = ((struct linenumber *)
 
325
                                 bfd_alloc (stash->abfd, amt));
 
326
 
 
327
      for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
 
328
        {
 
329
          /* A line number.  */
 
330
          aUnit->linenumber_table[eachLine].linenumber
 
331
            = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
 
332
          xptr += 4;
 
333
 
 
334
          /* Skip the position within the line.  */
 
335
          xptr += 2;
 
336
 
 
337
          /* And finally the address.  */
 
338
          aUnit->linenumber_table[eachLine].addr
 
339
            = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
 
340
          xptr += 4;
 
341
        }
 
342
    }
 
343
 
 
344
  return true;
 
345
}
 
346
 
 
347
/* Parse each function die in a compilation unit 'aUnit'.
 
348
   The first child die of 'aUnit' should be in 'aUnit->first_child',
 
349
   the result is placed in 'aUnit->func_list'.
 
350
   Return false if error; true otherwise.  */
 
351
 
 
352
static boolean
 
353
parse_functions_in_unit (stash, aUnit)
 
354
     struct dwarf1_debug* stash;
 
355
     struct dwarf1_unit* aUnit;
 
356
{
 
357
  char* eachDie;
 
358
 
 
359
  if (aUnit->first_child)
 
360
    for (eachDie = aUnit->first_child;
 
361
         eachDie < stash->debug_section_end;
 
362
         )
 
363
      {
 
364
        struct die_info eachDieInfo;
 
365
 
 
366
        if (! parse_die (stash->abfd, &eachDieInfo, eachDie,
 
367
                         stash->debug_section_end))
 
368
          return false;
 
369
 
 
370
        if (eachDieInfo.tag == TAG_global_subroutine
 
371
            || eachDieInfo.tag == TAG_subroutine
 
372
            || eachDieInfo.tag == TAG_inlined_subroutine
 
373
            || eachDieInfo.tag == TAG_entry_point)
 
374
          {
 
375
            struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
 
376
 
 
377
            aFunc->name = eachDieInfo.name;
 
378
            aFunc->low_pc = eachDieInfo.low_pc;
 
379
            aFunc->high_pc = eachDieInfo.high_pc;
 
380
          }
 
381
 
 
382
        /* Move to next sibling, if none, end loop */
 
383
        if (eachDieInfo.sibling)
 
384
          eachDie = stash->debug_section + eachDieInfo.sibling;
 
385
        else
 
386
          break;
 
387
      }
 
388
 
 
389
  return true;
 
390
}
 
391
 
 
392
/* Find the nearest line to 'addr' in 'aUnit'.
 
393
   Return whether we found the line (or a function) without error.  */
 
394
 
 
395
static boolean
 
396
dwarf1_unit_find_nearest_line (stash, aUnit, addr,
 
397
                       filename_ptr, functionname_ptr,
 
398
                       linenumber_ptr)
 
399
  struct dwarf1_debug* stash;
 
400
  struct dwarf1_unit* aUnit;
 
401
  unsigned long addr;
 
402
  const char **filename_ptr;
 
403
  const char **functionname_ptr;
 
404
  unsigned int *linenumber_ptr;
 
405
{
 
406
  int line_p = false;
 
407
  int func_p = false;
 
408
 
 
409
  if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
 
410
    {
 
411
      if (aUnit->has_stmt_list)
 
412
        {
 
413
          unsigned long i;
 
414
          struct dwarf1_func* eachFunc;
 
415
 
 
416
          if (! aUnit->linenumber_table)
 
417
            {
 
418
              if (! parse_line_table (stash, aUnit))
 
419
                return false;
 
420
            }
 
421
 
 
422
          if (! aUnit->func_list)
 
423
            {
 
424
              if (! parse_functions_in_unit (stash, aUnit))
 
425
                return false;
 
426
            }
 
427
 
 
428
          for (i = 0; i < aUnit->line_count; i++)
 
429
            {
 
430
              if (aUnit->linenumber_table[i].addr <= addr
 
431
                  && addr < aUnit->linenumber_table[i+1].addr)
 
432
                {
 
433
                  *filename_ptr = aUnit->name;
 
434
                  *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
 
435
                  line_p = true;
 
436
                  break;
 
437
                }
 
438
            }
 
439
 
 
440
          for (eachFunc = aUnit->func_list;
 
441
               eachFunc;
 
442
               eachFunc = eachFunc->prev)
 
443
            {
 
444
              if (eachFunc->low_pc <= addr
 
445
                  && addr < eachFunc->high_pc)
 
446
                {
 
447
                  *functionname_ptr = eachFunc->name;
 
448
                  func_p = true;
 
449
                  break;
 
450
                }
 
451
            }
 
452
        }
 
453
    }
 
454
 
 
455
  return line_p || func_p;
 
456
}
 
457
 
 
458
/* The DWARF 1 version of find_nearest line.
 
459
   Return true if the line is found without error.  */
 
460
 
 
461
boolean
 
462
_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
 
463
                              filename_ptr, functionname_ptr, linenumber_ptr)
 
464
     bfd *abfd;
 
465
     asection *section;
 
466
     asymbol **symbols ATTRIBUTE_UNUSED;
 
467
     bfd_vma offset;
 
468
     const char **filename_ptr;
 
469
     const char **functionname_ptr;
 
470
     unsigned int *linenumber_ptr;
 
471
{
 
472
  struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;
 
473
 
 
474
  struct dwarf1_unit* eachUnit;
 
475
 
 
476
  /* What address are we looking for? */
 
477
  unsigned long addr = (unsigned long)(offset + section->vma);
 
478
 
 
479
  *filename_ptr = NULL;
 
480
  *functionname_ptr = NULL;
 
481
  *linenumber_ptr = 0;
 
482
 
 
483
  if (! stash)
 
484
    {
 
485
      asection *msec;
 
486
      bfd_size_type size = sizeof (struct dwarf1_debug);
 
487
 
 
488
      stash = elf_tdata (abfd)->dwarf1_find_line_info
 
489
        = (struct dwarf1_debug *) bfd_zalloc (abfd, size);
 
490
 
 
491
      if (! stash)
 
492
        return false;
 
493
 
 
494
      msec = bfd_get_section_by_name (abfd, ".debug");
 
495
      if (! msec)
 
496
        {
 
497
          /* No dwarf1 info.  Note that at this point the stash
 
498
             has been allocated, but contains zeros, this lets
 
499
             future calls to this function fail quicker.  */
 
500
          return false;
 
501
        }
 
502
 
 
503
      size = bfd_get_section_size_before_reloc (msec);
 
504
      stash->debug_section = (char *) bfd_alloc (abfd, size);
 
505
 
 
506
      if (! stash->debug_section)
 
507
        return false;
 
508
 
 
509
      if (! bfd_get_section_contents (abfd, msec, stash->debug_section,
 
510
                                      (bfd_vma) 0, size))
 
511
        {
 
512
          stash->debug_section = 0;
 
513
          return false;
 
514
        }
 
515
 
 
516
      stash->debug_section_end = stash->debug_section + size;
 
517
      stash->currentDie = stash->debug_section;
 
518
      stash->abfd = abfd;
 
519
    }
 
520
 
 
521
  /* A null debug_section indicates that there was no dwarf1 info
 
522
     or that an error occured while setting up the stash.  */
 
523
 
 
524
  if (! stash->debug_section)
 
525
    return false;
 
526
 
 
527
  /* Look at the previously parsed units to see if any contain
 
528
     the addr.  */
 
529
  for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
 
530
    {
 
531
      if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
 
532
        return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
 
533
                                              filename_ptr,
 
534
                                              functionname_ptr,
 
535
                                              linenumber_ptr);
 
536
    }
 
537
 
 
538
  while (stash->currentDie < stash->debug_section_end)
 
539
    {
 
540
      struct die_info aDieInfo;
 
541
 
 
542
      if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie,
 
543
                       stash->debug_section_end))
 
544
        return false;
 
545
 
 
546
      if (aDieInfo.tag == TAG_compile_unit)
 
547
        {
 
548
          struct dwarf1_unit* aUnit
 
549
            = alloc_dwarf1_unit (stash);
 
550
 
 
551
          aUnit->name = aDieInfo.name;
 
552
          aUnit->low_pc = aDieInfo.low_pc;
 
553
          aUnit->high_pc = aDieInfo.high_pc;
 
554
          aUnit->has_stmt_list = aDieInfo.has_stmt_list;
 
555
          aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
 
556
 
 
557
          /* A die has a child if it's followed by a die that is
 
558
             not it's sibling.  */
 
559
          if (aDieInfo.sibling
 
560
              && stash->currentDie + aDieInfo.length
 
561
                    < stash->debug_section_end
 
562
              && stash->currentDie + aDieInfo.length
 
563
                    != stash->debug_section + aDieInfo.sibling)
 
564
            aUnit->first_child = stash->currentDie + aDieInfo.length;
 
565
          else
 
566
            aUnit->first_child = 0;
 
567
 
 
568
          if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
 
569
            return dwarf1_unit_find_nearest_line (stash, aUnit, addr,
 
570
                                                  filename_ptr,
 
571
                                                  functionname_ptr,
 
572
                                                  linenumber_ptr);
 
573
        }
 
574
 
 
575
      if (aDieInfo.sibling != 0)
 
576
        stash->currentDie = stash->debug_section + aDieInfo.sibling;
 
577
      else
 
578
        stash->currentDie += aDieInfo.length;
 
579
    }
 
580
 
 
581
  return false;
 
582
}
 
583
 
 
584
/* EOF */