Coverage Report

Created: 2026-07-25 10:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/dwarf1.c
Line
Count
Source
1
/* DWARF 1 find nearest line (_bfd_dwarf1_find_nearest_line).
2
   Copyright (C) 1998-2026 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 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
30.5k
#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
20
{
143
20
  size_t amt = sizeof (struct dwarf1_unit);
144
145
20
  struct dwarf1_unit* x = (struct dwarf1_unit *) bfd_zalloc (stash->abfd, amt);
146
20
  if (x)
147
20
    {
148
20
      x->prev = stash->lastUnit;
149
20
      stash->lastUnit = x;
150
20
    }
151
152
20
  return x;
153
20
}
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
0
{
161
0
  size_t amt = sizeof (struct dwarf1_func);
162
163
0
  struct dwarf1_func* x = (struct dwarf1_func *) bfd_zalloc (stash->abfd, amt);
164
0
  if (x)
165
0
    {
166
0
      x->prev = aUnit->func_list;
167
0
      aUnit->func_list = x;
168
0
    }
169
170
0
  return x;
171
0
}
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 bool
181
parse_die (bfd *       abfd,
182
     struct die_info * aDieInfo,
183
     bfd_byte *      aDiePtr,
184
     bfd_byte *      aDiePtrEnd)
185
1.89k
{
186
1.89k
  bfd_byte *this_die = aDiePtr;
187
1.89k
  bfd_byte *xptr = this_die;
188
189
1.89k
  memset (aDieInfo, 0, sizeof (* aDieInfo));
190
191
  /* First comes the length.  */
192
1.89k
  if (xptr + 4 > aDiePtrEnd)
193
188
    return false;
194
1.70k
  aDieInfo->length = bfd_get_32 (abfd, xptr);
195
1.70k
  xptr += 4;
196
1.70k
  if (aDieInfo->length <= 4
197
1.39k
      || (size_t) (aDiePtrEnd - this_die) < aDieInfo->length)
198
866
    return false;
199
842
  aDiePtrEnd = this_die + aDieInfo->length;
200
842
  if (aDieInfo->length < 6)
201
2
    {
202
      /* Just padding bytes.  */
203
2
      aDieInfo->tag = TAG_padding;
204
2
      return true;
205
2
    }
206
207
  /* Then the tag.  */
208
840
  if (xptr + 2 > aDiePtrEnd)
209
0
    return false;
210
840
  aDieInfo->tag = bfd_get_16 (abfd, xptr);
211
840
  xptr += 2;
212
213
  /* Then the attributes.  */
214
30.5k
  while (xptr + 2 <= aDiePtrEnd)
215
30.5k
    {
216
30.5k
      unsigned int   block_len;
217
30.5k
      unsigned short attr;
218
219
      /* Parse the attribute based on its form.  This section
220
   must handle all dwarf1 forms, but need only handle the
221
   actual attributes that we care about.  */
222
30.5k
      attr = bfd_get_16 (abfd, xptr);
223
30.5k
      xptr += 2;
224
225
30.5k
      switch (FORM_FROM_ATTR (attr))
226
30.5k
  {
227
1.03k
  case FORM_DATA2:
228
1.03k
    xptr += 2;
229
1.03k
    break;
230
673
  case FORM_DATA4:
231
2.16k
  case FORM_REF:
232
2.16k
    if (xptr + 4 <= aDiePtrEnd)
233
2.16k
      {
234
2.16k
        if (attr == AT_sibling)
235
243
    aDieInfo->sibling = bfd_get_32 (abfd, xptr);
236
1.92k
        else if (attr == AT_stmt_list)
237
22
    {
238
22
      aDieInfo->stmt_list_offset = bfd_get_32 (abfd, xptr);
239
22
      aDieInfo->has_stmt_list = 1;
240
22
    }
241
2.16k
      }
242
2.16k
    xptr += 4;
243
2.16k
    break;
244
363
  case FORM_DATA8:
245
363
    xptr += 8;
246
363
    break;
247
2.25k
  case FORM_ADDR:
248
2.25k
    if (xptr + 4 <= aDiePtrEnd)
249
2.25k
      {
250
2.25k
        if (attr == AT_low_pc)
251
59
    aDieInfo->low_pc = bfd_get_32 (abfd, xptr);
252
2.19k
        else if (attr == AT_high_pc)
253
51
    aDieInfo->high_pc = bfd_get_32 (abfd, xptr);
254
2.25k
      }
255
2.25k
    xptr += 4;
256
2.25k
    break;
257
987
  case FORM_BLOCK2:
258
987
    if (xptr + 2 <= aDiePtrEnd)
259
985
      {
260
985
        block_len = bfd_get_16 (abfd, xptr);
261
985
        if ((size_t) (aDiePtrEnd - xptr) < block_len)
262
545
    return false;
263
440
        xptr += block_len;
264
440
      }
265
442
    xptr += 2;
266
442
    break;
267
535
  case FORM_BLOCK4:
268
535
    if (xptr + 4 <= aDiePtrEnd)
269
516
      {
270
516
        block_len = bfd_get_32 (abfd, xptr);
271
516
        if ((size_t) (aDiePtrEnd - xptr) < block_len)
272
222
    return false;
273
294
        xptr += block_len;
274
294
      }
275
313
    xptr += 4;
276
313
    break;
277
1.01k
  case FORM_STRING:
278
1.01k
    if (attr == AT_name)
279
33
      aDieInfo->name = (char *) xptr;
280
1.01k
    xptr += strnlen ((char *) xptr, aDiePtrEnd - xptr) + 1;
281
1.01k
    break;
282
30.5k
  }
283
30.5k
    }
284
285
73
  return true;
286
840
}
287
288
/* Parse a dwarf1 line number table for 'aUnit->stmt_list_offset'
289
   into 'aUnit->linenumber_table'.  Return FALSE if an error
290
   occurs; TRUE otherwise.  */
291
292
static bool
293
parse_line_table (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
294
0
{
295
0
  bfd_byte *xptr;
296
297
  /* Load the ".line" section from the bfd if we haven't already.  */
298
0
  if (stash->line_section == 0)
299
0
    {
300
0
      asection *msec;
301
0
      bfd_size_type size;
302
303
0
      msec = bfd_get_section_by_name (stash->abfd, ".line");
304
0
      if (! msec || (msec->flags & SEC_HAS_CONTENTS) == 0)
305
0
  return false;
306
307
0
      size = msec->rawsize ? msec->rawsize : msec->size;
308
0
      stash->line_section
309
0
  = bfd_simple_get_relocated_section_contents (stash->abfd, msec, NULL,
310
0
                 stash->syms);
311
312
0
      if (! stash->line_section)
313
0
  return false;
314
315
0
      stash->line_section_end = stash->line_section + size;
316
0
    }
317
318
0
  xptr = stash->line_section + aUnit->stmt_list_offset;
319
0
  if (xptr + 8 <= stash->line_section_end)
320
0
    {
321
0
      unsigned long eachLine;
322
0
      bfd_byte *tblend;
323
0
      unsigned long base;
324
0
      bfd_size_type amt;
325
326
      /* First comes the length.  */
327
0
      tblend = bfd_get_32 (stash->abfd, (bfd_byte *) xptr) + xptr;
328
0
      xptr += 4;
329
330
      /* Then the base address for each address in the table.  */
331
0
      base = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
332
0
      xptr += 4;
333
334
      /* How many line entrys?
335
   10 = 4 (line number) + 2 (pos in line) + 4 (address in line).  */
336
0
      aUnit->line_count = (tblend - xptr) / 10;
337
338
      /* Allocate an array for the entries.  */
339
0
      amt = sizeof (struct linenumber) * aUnit->line_count;
340
0
      aUnit->linenumber_table = (struct linenumber *) bfd_alloc (stash->abfd,
341
0
                 amt);
342
0
      if (!aUnit->linenumber_table)
343
0
  return false;
344
345
0
      for (eachLine = 0; eachLine < aUnit->line_count; eachLine++)
346
0
  {
347
0
    if (xptr + 10 > stash->line_section_end)
348
0
      {
349
0
        aUnit->line_count = eachLine;
350
0
        break;
351
0
      }
352
    /* A line number.  */
353
0
    aUnit->linenumber_table[eachLine].linenumber
354
0
      = bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
355
0
    xptr += 4;
356
357
    /* Skip the position within the line.  */
358
0
    xptr += 2;
359
360
    /* And finally the address.  */
361
0
    aUnit->linenumber_table[eachLine].addr
362
0
      = base + bfd_get_32 (stash->abfd, (bfd_byte *) xptr);
363
0
    xptr += 4;
364
0
  }
365
0
    }
366
367
0
  return true;
368
0
}
369
370
/* Parse each function die in a compilation unit 'aUnit'.
371
   The first child die of 'aUnit' should be in 'aUnit->first_child',
372
   the result is placed in 'aUnit->func_list'.
373
   Return FALSE if error; TRUE otherwise.  */
374
375
static bool
376
parse_functions_in_unit (struct dwarf1_debug* stash, struct dwarf1_unit* aUnit)
377
0
{
378
0
  bfd_byte *eachDie;
379
380
0
  if (aUnit->first_child)
381
0
    for (eachDie = aUnit->first_child;
382
0
   eachDie < stash->debug_section_end;
383
0
   )
384
0
      {
385
0
  struct die_info eachDieInfo;
386
387
0
  if (! parse_die (stash->abfd, &eachDieInfo, eachDie,
388
0
       stash->debug_section_end))
389
0
    return false;
390
391
0
  if (eachDieInfo.tag == TAG_global_subroutine
392
0
      || eachDieInfo.tag == TAG_subroutine
393
0
      || eachDieInfo.tag == TAG_inlined_subroutine
394
0
      || eachDieInfo.tag == TAG_entry_point)
395
0
    {
396
0
      struct dwarf1_func* aFunc = alloc_dwarf1_func (stash,aUnit);
397
0
      if (!aFunc)
398
0
        return false;
399
400
0
      aFunc->name = eachDieInfo.name;
401
0
      aFunc->low_pc = eachDieInfo.low_pc;
402
0
      aFunc->high_pc = eachDieInfo.high_pc;
403
0
    }
404
405
  /* Move to next sibling, if none, end loop */
406
0
  if (eachDieInfo.sibling)
407
0
    eachDie = stash->debug_section + eachDieInfo.sibling;
408
0
  else
409
0
    break;
410
0
      }
411
412
0
  return true;
413
0
}
414
415
/* Find the nearest line to 'addr' in 'aUnit'.
416
   Return whether we found the line (or a function) without error.  */
417
418
static bool
419
dwarf1_unit_find_nearest_line (struct dwarf1_debug* stash,
420
             struct dwarf1_unit* aUnit,
421
             unsigned long addr,
422
             const char **filename_ptr,
423
             const char **functionname_ptr,
424
             unsigned int *linenumber_ptr)
425
44
{
426
44
  int line_p = false;
427
44
  int func_p = false;
428
429
44
  if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
430
44
    {
431
44
      if (aUnit->has_stmt_list)
432
0
  {
433
0
    unsigned long i;
434
0
    struct dwarf1_func* eachFunc;
435
436
0
    if (! aUnit->linenumber_table)
437
0
      {
438
0
        if (! parse_line_table (stash, aUnit))
439
0
    return false;
440
0
      }
441
442
0
    if (! aUnit->func_list)
443
0
      {
444
0
        if (! parse_functions_in_unit (stash, aUnit))
445
0
    return false;
446
0
      }
447
448
0
    for (i = 0; i < aUnit->line_count; i++)
449
0
      {
450
0
        if (aUnit->linenumber_table[i].addr <= addr
451
0
      && addr < aUnit->linenumber_table[i+1].addr)
452
0
    {
453
0
      *filename_ptr = aUnit->name;
454
0
      *linenumber_ptr = aUnit->linenumber_table[i].linenumber;
455
0
      line_p = true;
456
0
      break;
457
0
    }
458
0
      }
459
460
0
    for (eachFunc = aUnit->func_list;
461
0
         eachFunc;
462
0
         eachFunc = eachFunc->prev)
463
0
      {
464
0
        if (eachFunc->low_pc <= addr
465
0
      && addr < eachFunc->high_pc)
466
0
    {
467
0
      *functionname_ptr = eachFunc->name;
468
0
      func_p = true;
469
0
      break;
470
0
    }
471
0
      }
472
0
  }
473
44
    }
474
475
44
  return line_p || func_p;
476
44
}
477
478
/* The DWARF 1 version of find_nearest line.
479
   Return TRUE if the line is found without error.  */
480
481
bool
482
_bfd_dwarf1_find_nearest_line (bfd *abfd,
483
             asymbol **symbols,
484
             asection *section,
485
             bfd_vma offset,
486
             const char **filename_ptr,
487
             const char **functionname_ptr,
488
             unsigned int *linenumber_ptr)
489
32.0k
{
490
32.0k
  struct dwarf1_debug *stash = elf_tdata (abfd)->dwarf1_find_line_info;
491
492
32.0k
  struct dwarf1_unit* eachUnit;
493
494
  /* What address are we looking for? */
495
32.0k
  unsigned long addr = (unsigned long)(offset + section->vma);
496
497
32.0k
  *filename_ptr = NULL;
498
32.0k
  *functionname_ptr = NULL;
499
32.0k
  *linenumber_ptr = 0;
500
501
32.0k
  if (! stash)
502
4.83k
    {
503
4.83k
      asection *msec;
504
4.83k
      bfd_size_type size = sizeof (struct dwarf1_debug);
505
506
4.83k
      stash = elf_tdata (abfd)->dwarf1_find_line_info
507
4.83k
  = (struct dwarf1_debug *) bfd_zalloc (abfd, size);
508
509
4.83k
      if (! stash)
510
0
  return false;
511
512
4.83k
      msec = bfd_get_section_by_name (abfd, ".debug");
513
4.83k
      if (! msec
514
1.11k
    || (msec->flags & SEC_HAS_CONTENTS) == 0)
515
  /* No dwarf1 info.  Note that at this point the stash
516
     has been allocated, but contains zeros, this lets
517
     future calls to this function fail quicker.  */
518
3.73k
  return false;
519
520
1.10k
      size = msec->rawsize ? msec->rawsize : msec->size;
521
1.10k
      stash->debug_section
522
1.10k
  = bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
523
1.10k
                 symbols);
524
525
1.10k
      if (! stash->debug_section)
526
869
  return false;
527
528
238
      stash->debug_section_end = stash->debug_section + size;
529
238
      stash->currentDie = stash->debug_section;
530
238
      stash->abfd = abfd;
531
238
      stash->syms = symbols;
532
238
    }
533
534
  /* A null debug_section indicates that there was no dwarf1 info
535
     or that an error occured while setting up the stash.  */
536
537
27.4k
  if (! stash->debug_section)
538
25.4k
    return false;
539
540
  /* Look at the previously parsed units to see if any contain
541
     the addr.  */
542
2.17k
  for (eachUnit = stash->lastUnit; eachUnit; eachUnit = eachUnit->prev)
543
213
    if (eachUnit->low_pc <= addr && addr < eachUnit->high_pc)
544
38
      return dwarf1_unit_find_nearest_line (stash, eachUnit, addr,
545
38
              filename_ptr,
546
38
              functionname_ptr,
547
38
              linenumber_ptr);
548
549
2.03k
  while (stash->currentDie < stash->debug_section_end)
550
1.89k
    {
551
1.89k
      struct die_info aDieInfo;
552
553
1.89k
      if (! parse_die (stash->abfd, &aDieInfo, stash->currentDie,
554
1.89k
           stash->debug_section_end))
555
1.82k
  return false;
556
557
75
      if (aDieInfo.tag == TAG_compile_unit)
558
20
  {
559
20
    struct dwarf1_unit* aUnit
560
20
      = alloc_dwarf1_unit (stash);
561
20
    if (!aUnit)
562
0
      return false;
563
564
20
    aUnit->name = aDieInfo.name;
565
20
    aUnit->low_pc = aDieInfo.low_pc;
566
20
    aUnit->high_pc = aDieInfo.high_pc;
567
20
    aUnit->has_stmt_list = aDieInfo.has_stmt_list;
568
20
    aUnit->stmt_list_offset = aDieInfo.stmt_list_offset;
569
570
    /* A die has a child if it's followed by a die that is
571
       not it's sibling.  */
572
20
    if (aDieInfo.sibling
573
0
        && stash->currentDie + aDieInfo.length
574
0
        < stash->debug_section_end
575
0
        && stash->currentDie + aDieInfo.length
576
0
        != stash->debug_section + aDieInfo.sibling)
577
0
      aUnit->first_child = stash->currentDie + aDieInfo.length;
578
20
    else
579
20
      aUnit->first_child = 0;
580
581
20
    if (aUnit->low_pc <= addr && addr < aUnit->high_pc)
582
6
      return dwarf1_unit_find_nearest_line (stash, aUnit, addr,
583
6
              filename_ptr,
584
6
              functionname_ptr,
585
6
              linenumber_ptr);
586
20
  }
587
588
69
      if (aDieInfo.sibling != 0)
589
10
  stash->currentDie = stash->debug_section + aDieInfo.sibling;
590
59
      else
591
59
  stash->currentDie += aDieInfo.length;
592
69
    }
593
594
137
  return false;
595
1.96k
}
596
597
void
598
_bfd_dwarf1_cleanup_debug_info (bfd *abfd ATTRIBUTE_UNUSED, void **pinfo)
599
45.1k
{
600
45.1k
  struct dwarf1_debug* stash = *pinfo;
601
602
45.1k
  if (stash == NULL)
603
40.3k
    return;
604
605
4.83k
  free (stash->debug_section);
606
4.83k
  free (stash->line_section);
607
4.83k
}