Coverage Report

Created: 2026-02-26 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libdw/dwarf_begin_elf.c
Line
Count
Source
1
/* Create descriptor from ELF descriptor for processing file.
2
   Copyright (C) 2002-2011, 2014, 2015, 2017, 2018 Red Hat, Inc.
3
   Copyright (C) 2023, Mark J. Wielaard <mark@klomp.org>
4
   This file is part of elfutils.
5
6
   This file is free software; you can redistribute it and/or modify
7
   it under the terms of either
8
9
     * the GNU Lesser General Public License as published by the Free
10
       Software Foundation; either version 3 of the License, or (at
11
       your option) any later version
12
13
   or
14
15
     * the GNU General Public License as published by the Free
16
       Software Foundation; either version 2 of the License, or (at
17
       your option) any later version
18
19
   or both in parallel, as here.
20
21
   elfutils is distributed in the hope that it will be useful, but
22
   WITHOUT ANY WARRANTY; without even the implied warranty of
23
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24
   General Public License for more details.
25
26
   You should have received copies of the GNU General Public License and
27
   the GNU Lesser General Public License along with this program.  If
28
   not, see <http://www.gnu.org/licenses/>.  */
29
30
#ifdef HAVE_CONFIG_H
31
# include <config.h>
32
#endif
33
34
#include <system.h>
35
36
#include <assert.h>
37
#include <stdbool.h>
38
#include <stddef.h>
39
#include <stdlib.h>
40
#include <stdio.h>
41
#include <string.h>
42
#include <sys/types.h>
43
#include <sys/stat.h>
44
#include <fcntl.h>
45
46
#include "libelfP.h"
47
#include "libdwP.h"
48
49
50
/* Section names.  (Note .debug_str_offsets is the largest 19 chars.)  */
51
static const char dwarf_scnnames[IDX_last][19] =
52
{
53
  [IDX_debug_info] = ".debug_info",
54
  [IDX_debug_types] = ".debug_types",
55
  [IDX_debug_abbrev] = ".debug_abbrev",
56
  [IDX_debug_addr] = ".debug_addr",
57
  [IDX_debug_aranges] = ".debug_aranges",
58
  [IDX_debug_line] = ".debug_line",
59
  [IDX_debug_line_str] = ".debug_line_str",
60
  [IDX_debug_frame] = ".debug_frame",
61
  [IDX_debug_loc] = ".debug_loc",
62
  [IDX_debug_loclists] = ".debug_loclists",
63
  [IDX_debug_pubnames] = ".debug_pubnames",
64
  [IDX_debug_str] = ".debug_str",
65
  [IDX_debug_str_offsets] = ".debug_str_offsets",
66
  [IDX_debug_macinfo] = ".debug_macinfo",
67
  [IDX_debug_macro] = ".debug_macro",
68
  [IDX_debug_ranges] = ".debug_ranges",
69
  [IDX_debug_rnglists] = ".debug_rnglists",
70
  [IDX_debug_cu_index] = ".debug_cu_index",
71
  [IDX_debug_tu_index] = ".debug_tu_index",
72
  [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
73
};
74
1.31M
#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
75
76
/* Map from section index to string section index.
77
   Non-string sections should have STR_SCN_IDX_last.  */
78
static const enum string_section_index scn_to_string_section_idx[IDX_last] =
79
{
80
  [IDX_debug_info] = STR_SCN_IDX_last,
81
  [IDX_debug_types] = STR_SCN_IDX_last,
82
  [IDX_debug_abbrev] = STR_SCN_IDX_last,
83
  [IDX_debug_addr] = STR_SCN_IDX_last,
84
  [IDX_debug_aranges] = STR_SCN_IDX_last,
85
  [IDX_debug_line] = STR_SCN_IDX_last,
86
  [IDX_debug_line_str] = STR_SCN_IDX_debug_line_str,
87
  [IDX_debug_frame] = STR_SCN_IDX_last,
88
  [IDX_debug_loc] = STR_SCN_IDX_last,
89
  [IDX_debug_loclists] = STR_SCN_IDX_last,
90
  [IDX_debug_pubnames] = STR_SCN_IDX_last,
91
  [IDX_debug_str] = STR_SCN_IDX_debug_str,
92
  [IDX_debug_str_offsets] = STR_SCN_IDX_last,
93
  [IDX_debug_macinfo] = STR_SCN_IDX_last,
94
  [IDX_debug_macro] = STR_SCN_IDX_last,
95
  [IDX_debug_ranges] = STR_SCN_IDX_last,
96
  [IDX_debug_rnglists] = STR_SCN_IDX_last,
97
  [IDX_debug_cu_index] = STR_SCN_IDX_last,
98
  [IDX_debug_tu_index] = STR_SCN_IDX_last,
99
  [IDX_gnu_debugaltlink] = STR_SCN_IDX_last
100
};
101
102
static enum dwarf_type
103
scn_dwarf_type (Dwarf *result, size_t shstrndx, Elf_Scn *scn)
104
2.79M
{
105
2.79M
  GElf_Shdr shdr_mem;
106
2.79M
  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
107
2.79M
  if (shdr == NULL)
108
0
    return TYPE_UNKNOWN;
109
110
2.79M
  const char *scnname = elf_strptr (result->elf, shstrndx,
111
2.79M
            shdr->sh_name);
112
2.79M
  if (scnname != NULL)
113
127k
    {
114
127k
      if (startswith (scnname, ".gnu.debuglto_.debug"))
115
708
  return TYPE_GNU_LTO;
116
126k
      else if (strcmp (scnname, ".debug_cu_index") == 0
117
107k
         || strcmp (scnname, ".debug_tu_index") == 0
118
107k
         || strcmp (scnname, ".zdebug_cu_index") == 0
119
99.7k
         || strcmp (scnname, ".zdebug_tu_index") == 0)
120
45.4k
  return TYPE_DWO;
121
81.2k
      else if (startswith (scnname, ".debug_") || startswith (scnname, ".zdebug_"))
122
8.60k
  {
123
8.60k
    size_t len = strlen (scnname);
124
8.60k
    if (strcmp (scnname + len - 4, ".dwo") == 0)
125
7.09k
      return TYPE_DWO;
126
1.51k
    else
127
1.51k
      return TYPE_PLAIN;
128
8.60k
  }
129
127k
    }
130
2.74M
  return TYPE_UNKNOWN;
131
2.79M
}
132
static Dwarf *
133
check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
134
371k
{
135
371k
  GElf_Shdr shdr_mem;
136
371k
  GElf_Shdr *shdr;
137
138
  /* Get the section header data.  */
139
371k
  shdr = gelf_getshdr (scn, &shdr_mem);
140
371k
  if (shdr == NULL)
141
    /* We may read /proc/PID/mem with only program headers mapped and section
142
       headers out of the mapped pages.  */
143
0
    goto err;
144
145
  /* Ignore any SHT_NOBITS sections.  Debugging sections should not
146
     have been stripped, but in case of a corrupt file we won't try
147
     to look at the missing data.  */
148
371k
  if (unlikely (shdr->sh_type == SHT_NOBITS))
149
2.98k
    return result;
150
151
  /* Make sure the section is part of a section group only iff we
152
     really need it.  If we are looking for the global (= non-section
153
     group debug info) we have to ignore all the info in section
154
     groups.  If we are looking into a section group we cannot look at
155
     a section which isn't part of the section group.  */
156
368k
  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
157
    /* Ignore the section.  */
158
206k
    return result;
159
160
161
  /* We recognize the DWARF section by their names.  This is not very
162
     safe and stable but the best we can do.  */
163
161k
  const char *scnname = elf_strptr (result->elf, shstrndx,
164
161k
            shdr->sh_name);
165
161k
  if (scnname == NULL)
166
1.73k
    {
167
      /* The section name must be valid.  Otherwise is the ELF file
168
   invalid.  */
169
1.84k
    err:
170
1.84k
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
171
1.84k
      __libdw_seterrno (DWARF_E_INVALID_ELF);
172
1.84k
      free (result);
173
1.84k
      return NULL;
174
1.73k
    }
175
176
  /* Recognize the various sections.  Most names start with .debug_.
177
     They might be compressed (and start with .z).  Or end with .dwo
178
     for split dwarf sections.  Or start with .gnu.debuglto_ for
179
     LTO debug sections.  We should only use one consistent set at
180
     a time.  We prefer PLAIN over DWO over LTO.  */
181
159k
  size_t cnt;
182
159k
  bool gnu_compressed = false;
183
1.15M
  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
184
1.13M
    {
185
      /* .debug_cu_index and .debug_tu_index don't have a .dwo suffix,
186
   but they are for DWO.  */
187
1.13M
      if (result->type != TYPE_DWO
188
737k
    && (cnt == IDX_debug_cu_index || cnt == IDX_debug_tu_index))
189
41.3k
  continue;
190
1.13M
      bool need_dot_dwo =
191
1.09M
  (result->type == TYPE_DWO
192
398k
   && cnt != IDX_debug_cu_index
193
376k
   && cnt != IDX_debug_tu_index);
194
1.09M
      size_t dbglen = strlen (dwarf_scnnames[cnt]);
195
1.09M
      size_t scnlen = strlen (scnname);
196
1.09M
      if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
197
26.7k
    && ((!need_dot_dwo && dbglen == scnlen)
198
1.62k
        || (need_dot_dwo
199
1.07k
      && scnlen == dbglen + 4
200
620
      && strstr (scnname, ".dwo") == scnname + dbglen)))
201
25.4k
  break;
202
1.06M
      else if (scnname[0] == '.' && scnname[1] == 'z'
203
353k
         && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1],
204
353k
          dbglen - 1) == 0
205
115k
       && ((!need_dot_dwo && scnlen == dbglen + 1)
206
5.45k
           || (need_dot_dwo
207
2.04k
         && scnlen == dbglen + 5
208
1.65k
         && strstr (scnname,
209
1.65k
              ".dwo") == scnname + dbglen + 1))))
210
111k
  {
211
111k
    gnu_compressed = true;
212
111k
    break;
213
111k
  }
214
957k
      else if (scnlen > 14 /* .gnu.debuglto_ prefix. */
215
445k
         && startswith (scnname, ".gnu.debuglto_")
216
16.0k
         && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0)
217
889
  {
218
889
    if (result->type == TYPE_GNU_LTO)
219
595
      break;
220
889
  }
221
1.09M
    }
222
223
159k
  if (cnt >= ndwarf_scnnames)
224
    /* Not a debug section; ignore it. */
225
22.6k
    return result;
226
227
137k
  if (unlikely (result->sectiondata[cnt] != NULL))
228
    /* A section appears twice.  That's bad.  We ignore the section.  */
229
114k
    return result;
230
231
  /* We cannot know whether or not a GNU compressed section has already
232
     been uncompressed or not, so ignore any errors.  */
233
23.1k
  if (gnu_compressed)
234
8.43k
    elf_compress_gnu (scn, 0, 0);
235
236
23.1k
  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
237
4.65k
    {
238
4.65k
      if (elf_compress (scn, 0, 0) < 0)
239
3.91k
  {
240
    /* It would be nice if we could fail with a specific error.
241
       But we don't know if this was an essential section or not.
242
       So just continue for now. See also valid_p().  */
243
3.91k
    return result;
244
3.91k
  }
245
4.65k
    }
246
247
  /* Get the section data.  Should be raw bytes, no conversion needed.  */
248
19.2k
  Elf_Data *data = elf_rawdata (scn, NULL);
249
19.2k
  if (data == NULL)
250
106
    goto err;
251
252
19.1k
  if (data->d_buf == NULL || data->d_size == 0)
253
    /* No data actually available, ignore it. */
254
18.1k
    return result;
255
256
  /* We can now read the section data into results. */
257
981
  result->sectiondata[cnt] = data;
258
259
  /* If the section contains string data, we want to know a size of a prefix
260
     where any string will be null-terminated. */
261
981
  enum string_section_index string_section_idx = scn_to_string_section_idx[cnt];
262
981
  if (string_section_idx < STR_SCN_IDX_last)
263
145
    {
264
145
      size_t size = data->d_size;
265
      /* Reduce the size by the number of non-zero bytes at the end of the
266
   section.  */
267
1.33M
      while (size > 0 && *((const char *) data->d_buf + size - 1) != '\0')
268
1.33M
  --size;
269
145
      result->string_section_size[string_section_idx] = size;
270
145
    }
271
272
981
  return result;
273
19.1k
}
274
275
char *
276
__libdw_elfpath (int fd)
277
13.9k
{
278
  /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25.  */
279
13.9k
  char devfdpath[25];
280
13.9k
  sprintf (devfdpath, "/proc/self/fd/%u", fd);
281
13.9k
  return realpath (devfdpath, NULL);
282
13.9k
}
283
284
285
void
286
__libdw_set_debugdir (Dwarf *dbg)
287
335
{
288
335
  if (dbg->elfpath == NULL || dbg->elfpath[0] != '/')
289
180
    return;
290
155
  size_t dirlen = strrchr (dbg->elfpath, '/') - dbg->elfpath + 1;
291
155
  dbg->debugdir = malloc (dirlen + 1);
292
155
  if (dbg->debugdir == NULL)
293
0
    return;
294
155
  memcpy (dbg->debugdir, dbg->elfpath, dirlen);
295
155
  dbg->debugdir[dirlen] = '\0';
296
155
}
297
298
299
/* Check whether all the necessary DWARF information is available.  */
300
static Dwarf *
301
valid_p (Dwarf *result)
302
5.96k
{
303
  /* We looked at all the sections.  Now determine whether all the
304
     sections with debugging information we need are there.
305
306
     Require at least one section that can be read "standalone".  */
307
5.96k
  if (likely (result != NULL)
308
4.12k
      && unlikely (result->sectiondata[IDX_debug_info] == NULL
309
5.96k
       && result->sectiondata[IDX_debug_line] == NULL
310
5.96k
       && result->sectiondata[IDX_debug_frame] == NULL))
311
3.94k
    {
312
3.94k
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
313
3.94k
      __libdw_seterrno (DWARF_E_NO_DWARF);
314
3.94k
      free (result);
315
3.94k
      result = NULL;
316
3.94k
    }
317
318
  /* We are setting up some "fake" CUs, which need an address size.
319
     Check the ELF class to come up with something reasonable.  */
320
5.96k
  int elf_addr_size = 8;
321
5.96k
  if (result != NULL)
322
180
    {
323
180
      GElf_Ehdr ehdr;
324
180
      if (gelf_getehdr (result->elf, &ehdr) == NULL)
325
0
  {
326
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
327
0
    __libdw_seterrno (DWARF_E_INVALID_ELF);
328
0
    free (result);
329
0
    result = NULL;
330
0
  }
331
180
      else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
332
83
  elf_addr_size = 4;
333
180
    }
334
335
  /* For dwarf_location_attr () we need a "fake" CU to indicate
336
     where the "fake" attribute data comes from.  This is a block
337
     inside the .debug_loc or .debug_loclists section.  */
338
5.96k
  if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
339
2
    {
340
2
      result->fake_loc_cu = malloc (sizeof (Dwarf_CU));
341
2
      if (unlikely (result->fake_loc_cu == NULL))
342
0
  {
343
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
344
0
    __libdw_seterrno (DWARF_E_NOMEM);
345
0
    free (result);
346
0
    result = NULL;
347
0
  }
348
2
      else
349
2
  {
350
2
    result->fake_loc_cu->sec_idx = IDX_debug_loc;
351
2
    result->fake_loc_cu->dbg = result;
352
2
    result->fake_loc_cu->startp
353
2
      = result->sectiondata[IDX_debug_loc]->d_buf;
354
2
    result->fake_loc_cu->endp
355
2
      = (result->sectiondata[IDX_debug_loc]->d_buf
356
2
         + result->sectiondata[IDX_debug_loc]->d_size);
357
2
    result->fake_loc_cu->address_size = elf_addr_size;
358
2
    result->fake_loc_cu->offset_size = 4;
359
2
    result->fake_loc_cu->version = 4;
360
2
    result->fake_loc_cu->split = NULL;
361
2
  }
362
2
    }
363
364
5.96k
  if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
365
3
    {
366
3
      result->fake_loclists_cu = malloc (sizeof (Dwarf_CU));
367
3
      if (unlikely (result->fake_loclists_cu == NULL))
368
0
  {
369
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
370
0
    __libdw_seterrno (DWARF_E_NOMEM);
371
0
    free (result->fake_loc_cu);
372
0
    free (result);
373
0
    result = NULL;
374
0
  }
375
3
      else
376
3
  {
377
3
    result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
378
3
    result->fake_loclists_cu->dbg = result;
379
3
    result->fake_loclists_cu->startp
380
3
      = result->sectiondata[IDX_debug_loclists]->d_buf;
381
3
    result->fake_loclists_cu->endp
382
3
      = (result->sectiondata[IDX_debug_loclists]->d_buf
383
3
         + result->sectiondata[IDX_debug_loclists]->d_size);
384
3
    result->fake_loclists_cu->address_size = elf_addr_size;
385
3
    result->fake_loclists_cu->offset_size = 4;
386
3
    result->fake_loclists_cu->version = 5;
387
3
    result->fake_loclists_cu->split = NULL;
388
3
  }
389
3
    }
390
391
  /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
392
     the dwarf_location_attr () will need a "fake" address CU to
393
     indicate where the attribute data comes from.  This is a just
394
     inside the .debug_addr section, if it exists.  */
395
5.96k
  if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
396
8
    {
397
8
      result->fake_addr_cu = malloc (sizeof (Dwarf_CU));
398
8
      if (unlikely (result->fake_addr_cu == NULL))
399
0
  {
400
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
401
0
    __libdw_seterrno (DWARF_E_NOMEM);
402
0
    free (result->fake_loc_cu);
403
0
    free (result->fake_loclists_cu);
404
0
    free (result);
405
0
    result = NULL;
406
0
  }
407
8
      else
408
8
  {
409
8
    result->fake_addr_cu->sec_idx = IDX_debug_addr;
410
8
    result->fake_addr_cu->dbg = result;
411
8
    result->fake_addr_cu->startp
412
8
      = result->sectiondata[IDX_debug_addr]->d_buf;
413
8
    result->fake_addr_cu->endp
414
8
      = (result->sectiondata[IDX_debug_addr]->d_buf
415
8
         + result->sectiondata[IDX_debug_addr]->d_size);
416
8
    result->fake_addr_cu->address_size = elf_addr_size;
417
8
    result->fake_addr_cu->offset_size = 4;
418
8
    result->fake_addr_cu->version = 5;
419
8
    result->fake_addr_cu->split = NULL;
420
8
  }
421
8
    }
422
423
5.96k
  if (result != NULL)
424
180
    {
425
180
      if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
426
0
  {
427
0
    free (result->fake_loc_cu);
428
0
    free (result->fake_loclists_cu);
429
0
    free (result->fake_addr_cu);
430
0
    free (result);
431
0
    __libdw_seterrno (DWARF_E_NOMEM); /* no memory.  */
432
0
    return NULL;
433
0
  }
434
435
180
      result->elfpath = __libdw_elfpath (result->elf->fildes);
436
180
      __libdw_set_debugdir(result);
437
438
      /* Initialize locks and search_trees.  */
439
180
      mutex_init (result->dwarf_lock);
440
180
      mutex_init (result->macro_lock);
441
180
      eu_search_tree_init (&result->cu_tree);
442
180
      eu_search_tree_init (&result->tu_tree);
443
180
      eu_search_tree_init (&result->split_tree);
444
180
      eu_search_tree_init (&result->macro_ops_tree);
445
180
      eu_search_tree_init (&result->files_lines_tree);
446
447
180
      if (result->fake_loc_cu != NULL)
448
2
  {
449
2
    eu_search_tree_init (&result->fake_loc_cu->locs_tree);
450
2
    rwlock_init (result->fake_loc_cu->split_lock);
451
2
    mutex_init (result->fake_loc_cu->abbrev_lock);
452
2
    mutex_init (result->fake_loc_cu->src_lock);
453
2
    mutex_init (result->fake_loc_cu->str_off_base_lock);
454
2
    mutex_init (result->fake_loc_cu->intern_lock);
455
2
  }
456
457
180
      if (result->fake_loclists_cu != NULL)
458
3
  {
459
3
    eu_search_tree_init (&result->fake_loclists_cu->locs_tree);
460
3
    rwlock_init (result->fake_loclists_cu->split_lock);
461
3
    mutex_init (result->fake_loclists_cu->abbrev_lock);
462
3
    mutex_init (result->fake_loclists_cu->src_lock);
463
3
    mutex_init (result->fake_loclists_cu->str_off_base_lock);
464
3
    mutex_init (result->fake_loclists_cu->intern_lock);
465
3
  }
466
467
180
      if (result->fake_addr_cu != NULL)
468
8
  {
469
8
    eu_search_tree_init (&result->fake_addr_cu->locs_tree);
470
8
    rwlock_init (result->fake_addr_cu->split_lock);
471
8
    mutex_init (result->fake_addr_cu->abbrev_lock);
472
8
    mutex_init (result->fake_addr_cu->src_lock);
473
8
    mutex_init (result->fake_addr_cu->str_off_base_lock);
474
8
    mutex_init (result->fake_addr_cu->intern_lock);
475
8
  }
476
180
    }
477
478
5.96k
  return result;
479
5.96k
}
480
481
482
static Dwarf *
483
global_read (Dwarf *result, Elf *elf, size_t shstrndx)
484
5.96k
{
485
5.96k
  Elf_Scn *scn = NULL;
486
487
  /* First check the type (PLAIN, DWO, LTO) we are looking for.  We
488
     prefer PLAIN if available over DWO, over LTO.  */
489
2.80M
  while ((scn = elf_nextscn (elf, scn)) != NULL && result->type != TYPE_PLAIN)
490
2.79M
    {
491
2.79M
      enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
492
2.79M
      if (type > result->type)
493
1.93k
  result->type = type;
494
2.79M
    }
495
496
5.96k
  scn = NULL;
497
377k
  while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
498
371k
    result = check_section (result, shstrndx, scn, false);
499
500
5.96k
  return valid_p (result);
501
5.96k
}
502
503
504
static Dwarf *
505
scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
506
0
{
507
0
  GElf_Shdr shdr_mem;
508
0
  GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
509
0
  if (shdr == NULL)
510
0
    {
511
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
512
0
      __libdw_seterrno (DWARF_E_INVALID_ELF);
513
0
      free (result);
514
0
      return NULL;
515
0
    }
516
517
0
  if ((shdr->sh_flags & SHF_COMPRESSED) != 0
518
0
      && elf_compress (scngrp, 0, 0) < 0)
519
0
    {
520
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
521
0
      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
522
0
      free (result);
523
0
      return NULL;
524
0
    }
525
526
  /* SCNGRP is the section descriptor for a section group which might
527
     contain debug sections.  */
528
0
  Elf_Data *data = elf_getdata (scngrp, NULL);
529
0
  if (data == NULL)
530
0
    {
531
      /* We cannot read the section content.  Fail!  */
532
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
533
0
      free (result);
534
0
      return NULL;
535
0
    }
536
537
  /* The content of the section is a number of 32-bit words which
538
     represent section indices.  The first word is a flag word.  */
539
0
  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
540
0
  size_t cnt;
541
542
  /* First check the type (PLAIN, DWO, LTO) we are looking for.  We
543
     prefer PLAIN if available over DWO, over LTO.  */
544
0
  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
545
0
    {
546
0
      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
547
0
      if (scn == NULL)
548
0
  {
549
    /* A section group refers to a non-existing section.  Should
550
       never happen.  */
551
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
552
0
    __libdw_seterrno (DWARF_E_INVALID_ELF);
553
0
    free (result);
554
0
    return NULL;
555
0
  }
556
557
0
      enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
558
0
      if (type > result->type)
559
0
  result->type = type;
560
0
    }
561
562
0
  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && result != NULL; ++cnt)
563
0
    {
564
0
      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
565
0
      assert (scn != NULL); // checked above
566
0
      result = check_section (result, shstrndx, scn, true);
567
0
      if (result == NULL)
568
0
  break;
569
0
    }
570
571
0
  return valid_p (result);
572
0
}
573
574
575
Dwarf *
576
dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
577
5.98k
{
578
5.98k
  GElf_Ehdr *ehdr;
579
5.98k
  GElf_Ehdr ehdr_mem;
580
581
  /* Get the ELF header of the file.  We need various pieces of
582
     information from it.  */
583
5.98k
  ehdr = gelf_getehdr (elf, &ehdr_mem);
584
5.98k
  if (ehdr == NULL)
585
0
    {
586
0
      if (elf_kind (elf) != ELF_K_ELF)
587
0
  __libdw_seterrno (DWARF_E_NOELF);
588
0
      else
589
0
  __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
590
591
0
      return NULL;
592
0
    }
593
594
595
  /* Default memory allocation size.  */
596
5.98k
  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
597
5.98k
  assert (sizeof (struct Dwarf) < mem_default_size);
598
599
  /* Allocate the data structure.  */
600
5.98k
  Dwarf *result = calloc (1, sizeof (Dwarf));
601
5.98k
  if (unlikely (result == NULL)
602
5.98k
      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
603
0
    {
604
0
      free (result);
605
0
      __libdw_seterrno (DWARF_E_NOMEM);
606
0
      return NULL;
607
0
    }
608
609
  /* Fill in some values.  */
610
5.98k
  if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
611
0
      || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
612
2.16k
    result->other_byte_order = true;
613
614
5.98k
  result->elf = elf;
615
5.98k
  result->alt_fd = -1;
616
5.98k
  result->dwp_fd = -1;
617
618
  /* Initialize the memory handling.  Initial blocks are allocated on first
619
     actual allocation.  */
620
5.98k
  result->mem_default_size = mem_default_size;
621
5.98k
  result->oom_handler = __libdw_oom;
622
623
5.98k
  result->mem_stacks = 0;
624
5.98k
  result->mem_tails = NULL;
625
626
5.98k
  if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
627
5.98k
    {
628
      /* All sections are recognized by name, so pass the section header
629
   string index along to easily get the section names.  */
630
5.98k
      size_t shstrndx;
631
5.98k
      if (elf_getshdrstrndx (elf, &shstrndx) != 0)
632
24
  {
633
24
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
634
24
    __libdw_seterrno (DWARF_E_INVALID_ELF);
635
24
    free (result);
636
24
    return NULL;
637
24
  }
638
639
      /* If the caller provides a section group we get the DWARF
640
   sections only from this section group.  Otherwise we search
641
   for the first section with the required name.  Further
642
   sections with the name are ignored.  The DWARF specification
643
   does not really say this is allowed.  */
644
5.96k
      if (scngrp == NULL)
645
5.96k
  return global_read (result, elf, shstrndx);
646
0
      else
647
0
  return scngrp_read (result, elf, shstrndx, scngrp);
648
5.96k
    }
649
0
  else if (cmd == DWARF_C_WRITE)
650
0
    {
651
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
652
0
      __libdw_seterrno (DWARF_E_UNIMPL);
653
0
      free (result);
654
0
      return NULL;
655
0
    }
656
657
0
  Dwarf_Sig8_Hash_free (&result->sig8_hash);
658
0
  __libdw_seterrno (DWARF_E_INVALID_CMD);
659
0
  free (result);
660
  return NULL;
661
5.98k
}
662
INTDEF(dwarf_begin_elf)