Subversion Repositories Kolibri OS

Rev

Rev 5197 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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