Coverage Report

Created: 2026-10-02 09:53

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