Coverage Report

Created: 2025-07-18 06:08

/src/elfutils/libdw/dwarf_begin_elf.c
Line
Count
Source (jump to first uncovered line)
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.57M
#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
3.33M
{
105
3.33M
  GElf_Shdr shdr_mem;
106
3.33M
  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
107
3.33M
  if (shdr == NULL)
108
0
    return TYPE_UNKNOWN;
109
110
3.33M
  const char *scnname = elf_strptr (result->elf, shstrndx,
111
3.33M
            shdr->sh_name);
112
3.33M
  if (scnname != NULL)
113
92.6k
    {
114
92.6k
      if (startswith (scnname, ".gnu.debuglto_.debug"))
115
757
  return TYPE_GNU_LTO;
116
91.8k
      else if (strcmp (scnname, ".debug_cu_index") == 0
117
91.8k
         || strcmp (scnname, ".debug_tu_index") == 0
118
91.8k
         || strcmp (scnname, ".zdebug_cu_index") == 0
119
91.8k
         || strcmp (scnname, ".zdebug_tu_index") == 0)
120
3.56k
  return TYPE_DWO;
121
88.2k
      else if (startswith (scnname, ".debug_") || startswith (scnname, ".zdebug_"))
122
13.4k
  {
123
13.4k
    size_t len = strlen (scnname);
124
13.4k
    if (strcmp (scnname + len - 4, ".dwo") == 0)
125
11.9k
      return TYPE_DWO;
126
1.56k
    else
127
1.56k
      return TYPE_PLAIN;
128
13.4k
  }
129
92.6k
    }
130
3.32M
  return TYPE_UNKNOWN;
131
3.33M
}
132
static Dwarf *
133
check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
134
517k
{
135
517k
  GElf_Shdr shdr_mem;
136
517k
  GElf_Shdr *shdr;
137
138
  /* Get the section header data.  */
139
517k
  shdr = gelf_getshdr (scn, &shdr_mem);
140
517k
  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
517k
  if (unlikely (shdr->sh_type == SHT_NOBITS))
149
3.63k
    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
513k
  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
157
    /* Ignore the section.  */
158
363k
    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
149k
  const char *scnname = elf_strptr (result->elf, shstrndx,
164
149k
            shdr->sh_name);
165
149k
  if (scnname == NULL)
166
1.68k
    {
167
      /* The section name must be valid.  Otherwise is the ELF file
168
   invalid.  */
169
1.79k
    err:
170
1.79k
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
171
1.79k
      __libdw_seterrno (DWARF_E_INVALID_ELF);
172
1.79k
      free (result);
173
1.79k
      return NULL;
174
1.68k
    }
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
148k
  size_t cnt;
182
148k
  bool gnu_compressed = false;
183
1.42M
  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
184
1.37M
    {
185
      /* .debug_cu_index and .debug_tu_index don't have a .dwo suffix,
186
   but they are for DWO.  */
187
1.37M
      if (result->type != TYPE_DWO
188
1.37M
    && (cnt == IDX_debug_cu_index || cnt == IDX_debug_tu_index))
189
107k
  continue;
190
1.26M
      bool need_dot_dwo =
191
1.26M
  (result->type == TYPE_DWO
192
1.26M
   && cnt != IDX_debug_cu_index
193
1.26M
   && cnt != IDX_debug_tu_index);
194
1.26M
      size_t dbglen = strlen (dwarf_scnnames[cnt]);
195
1.26M
      size_t scnlen = strlen (scnname);
196
1.26M
      if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
197
1.26M
    && ((!need_dot_dwo && dbglen == scnlen)
198
15.1k
        || (need_dot_dwo
199
13.0k
      && scnlen == dbglen + 4
200
13.0k
      && strstr (scnname, ".dwo") == scnname + dbglen)))
201
2.57k
  break;
202
1.26M
      else if (scnname[0] == '.' && scnname[1] == 'z'
203
1.26M
         && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1],
204
283k
          dbglen - 1) == 0
205
283k
       && ((!need_dot_dwo && scnlen == dbglen + 1)
206
101k
           || (need_dot_dwo
207
13.8k
         && scnlen == dbglen + 5
208
13.8k
         && strstr (scnname,
209
2.78k
              ".dwo") == scnname + dbglen + 1))))
210
90.4k
  {
211
90.4k
    gnu_compressed = true;
212
90.4k
    break;
213
90.4k
  }
214
1.17M
      else if (scnlen > 14 /* .gnu.debuglto_ prefix. */
215
1.17M
         && startswith (scnname, ".gnu.debuglto_")
216
1.17M
         && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0)
217
755
  {
218
755
    if (result->type == TYPE_GNU_LTO)
219
477
      break;
220
755
  }
221
1.26M
    }
222
223
148k
  if (cnt >= ndwarf_scnnames)
224
    /* Not a debug section; ignore it. */
225
54.5k
    return result;
226
227
93.5k
  if (unlikely (result->sectiondata[cnt] != NULL))
228
    /* A section appears twice.  That's bad.  We ignore the section.  */
229
80.4k
    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
13.1k
  if (gnu_compressed)
234
10.5k
    elf_compress_gnu (scn, 0, 0);
235
236
13.1k
  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
237
4.75k
    {
238
4.75k
      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.75k
    }
246
247
  /* Get the section data.  Should be raw bytes, no conversion needed.  */
248
9.18k
  Elf_Data *data = elf_rawdata (scn, NULL);
249
9.18k
  if (data == NULL)
250
110
    goto err;
251
252
9.07k
  if (data->d_buf == NULL || data->d_size == 0)
253
    /* No data actually available, ignore it. */
254
8.09k
    return result;
255
256
  /* We can now read the section data into results. */
257
988
  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
988
  enum string_section_index string_section_idx = scn_to_string_section_idx[cnt];
262
988
  if (string_section_idx < STR_SCN_IDX_last)
263
161
    {
264
161
      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
2.83M
      while (size > 0 && *((const char *) data->d_buf + size - 1) != '\0')
268
2.83M
  --size;
269
161
      result->string_section_size[string_section_idx] = size;
270
161
    }
271
272
988
  return result;
273
9.07k
}
274
275
char *
276
__libdw_elfpath (int fd)
277
15.8k
{
278
  /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25.  */
279
15.8k
  char devfdpath[25];
280
15.8k
  sprintf (devfdpath, "/proc/self/fd/%u", fd);
281
15.8k
  return realpath (devfdpath, NULL);
282
15.8k
}
283
284
285
void
286
__libdw_set_debugdir (Dwarf *dbg)
287
252
{
288
252
  if (dbg->elfpath == NULL || dbg->elfpath[0] != '/')
289
138
    return;
290
114
  size_t dirlen = strrchr (dbg->elfpath, '/') - dbg->elfpath + 1;
291
114
  dbg->debugdir = malloc (dirlen + 1);
292
114
  if (dbg->debugdir == NULL)
293
0
    return;
294
114
  memcpy (dbg->debugdir, dbg->elfpath, dirlen);
295
114
  dbg->debugdir[dirlen] = '\0';
296
114
}
297
298
299
/* Check whether all the necessary DWARF information is available.  */
300
static Dwarf *
301
valid_p (Dwarf *result)
302
6.13k
{
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
6.13k
  if (likely (result != NULL)
308
6.13k
      && unlikely (result->sectiondata[IDX_debug_info] == NULL
309
6.13k
       && result->sectiondata[IDX_debug_line] == NULL
310
6.13k
       && result->sectiondata[IDX_debug_frame] == NULL))
311
4.19k
    {
312
4.19k
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
313
4.19k
      __libdw_seterrno (DWARF_E_NO_DWARF);
314
4.19k
      free (result);
315
4.19k
      result = NULL;
316
4.19k
    }
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
6.13k
  int elf_addr_size = 8;
321
6.13k
  if (result != NULL)
322
138
    {
323
138
      GElf_Ehdr ehdr;
324
138
      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
138
      else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
332
49
  elf_addr_size = 4;
333
138
    }
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
6.13k
  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
    eu_search_tree_init (&result->fake_loc_cu->locs_tree);
362
2
    rwlock_init (result->fake_loc_cu->abbrev_lock);
363
2
    rwlock_init (result->fake_loc_cu->split_lock);
364
2
    mutex_init (result->fake_loc_cu->src_lock);
365
2
    mutex_init (result->fake_loc_cu->str_off_base_lock);
366
2
    mutex_init (result->fake_loc_cu->intern_lock);
367
2
  }
368
2
    }
369
370
6.13k
  if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
371
1
    {
372
1
      result->fake_loclists_cu = malloc (sizeof (Dwarf_CU));
373
1
      if (unlikely (result->fake_loclists_cu == NULL))
374
0
  {
375
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
376
0
    __libdw_seterrno (DWARF_E_NOMEM);
377
0
    free (result->fake_loc_cu);
378
0
    free (result);
379
0
    result = NULL;
380
0
  }
381
1
      else
382
1
  {
383
1
    result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
384
1
    result->fake_loclists_cu->dbg = result;
385
1
    result->fake_loclists_cu->startp
386
1
      = result->sectiondata[IDX_debug_loclists]->d_buf;
387
1
    result->fake_loclists_cu->endp
388
1
      = (result->sectiondata[IDX_debug_loclists]->d_buf
389
1
         + result->sectiondata[IDX_debug_loclists]->d_size);
390
1
    result->fake_loclists_cu->address_size = elf_addr_size;
391
1
    result->fake_loclists_cu->offset_size = 4;
392
1
    result->fake_loclists_cu->version = 5;
393
1
    result->fake_loclists_cu->split = NULL;
394
1
    eu_search_tree_init (&result->fake_loclists_cu->locs_tree);
395
1
    rwlock_init (result->fake_loclists_cu->abbrev_lock);
396
1
    rwlock_init (result->fake_loclists_cu->split_lock);
397
1
    mutex_init (result->fake_loclists_cu->src_lock);
398
1
    mutex_init (result->fake_loclists_cu->str_off_base_lock);
399
1
    mutex_init (result->fake_loclists_cu->intern_lock);
400
1
  }
401
1
    }
402
403
  /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
404
     the dwarf_location_attr () will need a "fake" address CU to
405
     indicate where the attribute data comes from.  This is a just
406
     inside the .debug_addr section, if it exists.  */
407
6.13k
  if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
408
6
    {
409
6
      result->fake_addr_cu = malloc (sizeof (Dwarf_CU));
410
6
      if (unlikely (result->fake_addr_cu == NULL))
411
0
  {
412
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
413
0
    __libdw_seterrno (DWARF_E_NOMEM);
414
0
    free (result->fake_loc_cu);
415
0
    free (result->fake_loclists_cu);
416
0
    free (result);
417
0
    result = NULL;
418
0
  }
419
6
      else
420
6
  {
421
6
    result->fake_addr_cu->sec_idx = IDX_debug_addr;
422
6
    result->fake_addr_cu->dbg = result;
423
6
    result->fake_addr_cu->startp
424
6
      = result->sectiondata[IDX_debug_addr]->d_buf;
425
6
    result->fake_addr_cu->endp
426
6
      = (result->sectiondata[IDX_debug_addr]->d_buf
427
6
         + result->sectiondata[IDX_debug_addr]->d_size);
428
6
    result->fake_addr_cu->address_size = elf_addr_size;
429
6
    result->fake_addr_cu->offset_size = 4;
430
6
    result->fake_addr_cu->version = 5;
431
6
    result->fake_addr_cu->split = NULL;
432
6
    eu_search_tree_init (&result->fake_addr_cu->locs_tree);
433
6
    rwlock_init (result->fake_addr_cu->abbrev_lock);
434
6
    rwlock_init (result->fake_addr_cu->split_lock);
435
6
    mutex_init (result->fake_addr_cu->src_lock);
436
6
    mutex_init (result->fake_addr_cu->str_off_base_lock);
437
6
    mutex_init (result->fake_addr_cu->intern_lock);
438
6
  }
439
6
    }
440
441
6.13k
  if (result != NULL)
442
138
    {
443
138
      result->elfpath = __libdw_elfpath (result->elf->fildes);
444
138
      __libdw_set_debugdir(result);
445
138
    }
446
447
6.13k
  return result;
448
6.13k
}
449
450
451
static Dwarf *
452
global_read (Dwarf *result, Elf *elf, size_t shstrndx)
453
6.13k
{
454
6.13k
  Elf_Scn *scn = NULL;
455
456
  /* First check the type (PLAIN, DWO, LTO) we are looking for.  We
457
     prefer PLAIN if available over DWO, over LTO.  */
458
3.34M
  while ((scn = elf_nextscn (elf, scn)) != NULL && result->type != TYPE_PLAIN)
459
3.33M
    {
460
3.33M
      enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
461
3.33M
      if (type > result->type)
462
2.01k
  result->type = type;
463
3.33M
    }
464
465
6.13k
  scn = NULL;
466
523k
  while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
467
517k
    result = check_section (result, shstrndx, scn, false);
468
469
6.13k
  return valid_p (result);
470
6.13k
}
471
472
473
static Dwarf *
474
scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
475
0
{
476
0
  GElf_Shdr shdr_mem;
477
0
  GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
478
0
  if (shdr == NULL)
479
0
    {
480
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
481
0
      __libdw_seterrno (DWARF_E_INVALID_ELF);
482
0
      free (result);
483
0
      return NULL;
484
0
    }
485
486
0
  if ((shdr->sh_flags & SHF_COMPRESSED) != 0
487
0
      && elf_compress (scngrp, 0, 0) < 0)
488
0
    {
489
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
490
0
      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
491
0
      free (result);
492
0
      return NULL;
493
0
    }
494
495
  /* SCNGRP is the section descriptor for a section group which might
496
     contain debug sections.  */
497
0
  Elf_Data *data = elf_getdata (scngrp, NULL);
498
0
  if (data == NULL)
499
0
    {
500
      /* We cannot read the section content.  Fail!  */
501
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
502
0
      free (result);
503
0
      return NULL;
504
0
    }
505
506
  /* The content of the section is a number of 32-bit words which
507
     represent section indices.  The first word is a flag word.  */
508
0
  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
509
0
  size_t cnt;
510
511
  /* First check the type (PLAIN, DWO, LTO) we are looking for.  We
512
     prefer PLAIN if available over DWO, over LTO.  */
513
0
  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
514
0
    {
515
0
      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
516
0
      if (scn == NULL)
517
0
  {
518
    /* A section group refers to a non-existing section.  Should
519
       never happen.  */
520
0
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
521
0
    __libdw_seterrno (DWARF_E_INVALID_ELF);
522
0
    free (result);
523
0
    return NULL;
524
0
  }
525
526
0
      enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
527
0
      if (type > result->type)
528
0
  result->type = type;
529
0
    }
530
531
0
  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && result != NULL; ++cnt)
532
0
    {
533
0
      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
534
0
      assert (scn != NULL); // checked above
535
0
      result = check_section (result, shstrndx, scn, true);
536
0
      if (result == NULL)
537
0
  break;
538
0
    }
539
540
0
  return valid_p (result);
541
0
}
542
543
544
Dwarf *
545
dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
546
6.17k
{
547
6.17k
  GElf_Ehdr *ehdr;
548
6.17k
  GElf_Ehdr ehdr_mem;
549
550
  /* Get the ELF header of the file.  We need various pieces of
551
     information from it.  */
552
6.17k
  ehdr = gelf_getehdr (elf, &ehdr_mem);
553
6.17k
  if (ehdr == NULL)
554
0
    {
555
0
      if (elf_kind (elf) != ELF_K_ELF)
556
0
  __libdw_seterrno (DWARF_E_NOELF);
557
0
      else
558
0
  __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
559
560
0
      return NULL;
561
0
    }
562
563
564
  /* Default memory allocation size.  */
565
6.17k
  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
566
6.17k
  assert (sizeof (struct Dwarf) < mem_default_size);
567
568
  /* Allocate the data structure.  */
569
6.17k
  Dwarf *result = calloc (1, sizeof (Dwarf));
570
6.17k
  if (unlikely (result == NULL)
571
6.17k
      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
572
0
    {
573
0
      free (result);
574
0
      __libdw_seterrno (DWARF_E_NOMEM);
575
0
      return NULL;
576
0
    }
577
578
  /* Fill in some values.  */
579
6.17k
  if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
580
6.17k
      || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
581
2.16k
    result->other_byte_order = true;
582
583
6.17k
  result->elf = elf;
584
6.17k
  result->alt_fd = -1;
585
6.17k
  result->dwp_fd = -1;
586
587
  /* Initialize the memory handling.  Initial blocks are allocated on first
588
     actual allocation.  */
589
6.17k
  result->mem_default_size = mem_default_size;
590
6.17k
  result->oom_handler = __libdw_oom;
591
6.17k
  if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
592
0
    {
593
0
      free (result);
594
0
      __libdw_seterrno (DWARF_E_NOMEM); /* no memory.  */
595
0
      return NULL;
596
0
    }
597
6.17k
  mutex_init (result->dwarf_lock);
598
6.17k
  mutex_init (result->macro_lock);
599
6.17k
  eu_search_tree_init (&result->cu_tree);
600
6.17k
  eu_search_tree_init (&result->tu_tree);
601
6.17k
  eu_search_tree_init (&result->split_tree);
602
6.17k
  eu_search_tree_init (&result->macro_ops_tree);
603
6.17k
  eu_search_tree_init (&result->files_lines_tree);
604
605
6.17k
  result->mem_stacks = 0;
606
6.17k
  result->mem_tails = NULL;
607
608
6.17k
  if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
609
6.17k
    {
610
      /* All sections are recognized by name, so pass the section header
611
   string index along to easily get the section names.  */
612
6.17k
      size_t shstrndx;
613
6.17k
      if (elf_getshdrstrndx (elf, &shstrndx) != 0)
614
43
  {
615
43
    Dwarf_Sig8_Hash_free (&result->sig8_hash);
616
43
    __libdw_seterrno (DWARF_E_INVALID_ELF);
617
43
    free (result);
618
43
    return NULL;
619
43
  }
620
621
      /* If the caller provides a section group we get the DWARF
622
   sections only from this section group.  Otherwise we search
623
   for the first section with the required name.  Further
624
   sections with the name are ignored.  The DWARF specification
625
   does not really say this is allowed.  */
626
6.13k
      if (scngrp == NULL)
627
6.13k
  return global_read (result, elf, shstrndx);
628
0
      else
629
0
  return scngrp_read (result, elf, shstrndx, scngrp);
630
6.13k
    }
631
0
  else if (cmd == DWARF_C_WRITE)
632
0
    {
633
0
      Dwarf_Sig8_Hash_free (&result->sig8_hash);
634
0
      __libdw_seterrno (DWARF_E_UNIMPL);
635
0
      free (result);
636
0
      return NULL;
637
0
    }
638
639
0
  Dwarf_Sig8_Hash_free (&result->sig8_hash);
640
0
  __libdw_seterrno (DWARF_E_INVALID_CMD);
641
0
  free (result);
642
0
  return NULL;
643
6.17k
}
644
INTDEF(dwarf_begin_elf)