Coverage Report

Created: 2026-08-30 07:12

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