Coverage Report

Created: 2025-10-10 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/elfutils/libelf/elf_begin.c
Line
Count
Source
1
/* Create descriptor for processing file.
2
   Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
3
   Copyright (C) 2021, 2022 Mark J. Wielaard <mark@klomp.org>
4
   This file is part of elfutils.
5
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6
7
   This file is free software; you can redistribute it and/or modify
8
   it under the terms of either
9
10
     * the GNU Lesser General Public License as published by the Free
11
       Software Foundation; either version 3 of the License, or (at
12
       your option) any later version
13
14
   or
15
16
     * the GNU General Public License as published by the Free
17
       Software Foundation; either version 2 of the License, or (at
18
       your option) any later version
19
20
   or both in parallel, as here.
21
22
   elfutils is distributed in the hope that it will be useful, but
23
   WITHOUT ANY WARRANTY; without even the implied warranty of
24
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
   General Public License for more details.
26
27
   You should have received copies of the GNU General Public License and
28
   the GNU Lesser General Public License along with this program.  If
29
   not, see <http://www.gnu.org/licenses/>.  */
30
31
#ifdef HAVE_CONFIG_H
32
# include <config.h>
33
#endif
34
35
#include <assert.h>
36
#include <ctype.h>
37
#include <errno.h>
38
#include <fcntl.h>
39
#include <stdbool.h>
40
#include <stddef.h>
41
#include <stdint.h>
42
#include <string.h>
43
#include <sys/stat.h>
44
45
#include "libelfP.h"
46
#include "common.h"
47
48
49
/* Create descriptor for archive in memory.  */
50
static inline Elf *
51
file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
52
        Elf_Cmd cmd, Elf *parent)
53
4
{
54
4
  Elf *elf;
55
56
  /* Create a descriptor.  */
57
4
  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
58
4
                      ELF_K_AR, 0);
59
4
  if (elf != NULL)
60
4
    {
61
      /* We don't read all the symbol tables in advance.  All this will
62
   happen on demand.  */
63
4
      elf->state.ar.offset = offset + SARMAG;
64
65
4
      elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
66
4
    }
67
68
4
  return elf;
69
4
}
70
71
72
static size_t
73
get_shnum (void *map_address, unsigned char *e_ident, int fildes,
74
     int64_t offset, size_t maxsize)
75
24.2k
{
76
24.2k
  size_t result;
77
24.2k
  union
78
24.2k
  {
79
24.2k
    Elf32_Ehdr *e32;
80
24.2k
    Elf64_Ehdr *e64;
81
24.2k
    void *p;
82
24.2k
  } ehdr;
83
24.2k
  union
84
24.2k
  {
85
24.2k
    Elf32_Ehdr e32;
86
24.2k
    Elf64_Ehdr e64;
87
24.2k
  } ehdr_mem;
88
24.2k
  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
89
90
24.2k
  if ((is32 && maxsize < sizeof (Elf32_Ehdr))
91
24.2k
      || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
92
20
    {
93
20
       __libelf_seterrno (ELF_E_INVALID_ELF);
94
20
      return (size_t) -1l;
95
20
    }
96
97
  /* Make the ELF header available.  */
98
24.2k
  if (e_ident[EI_DATA] == MY_ELFDATA
99
12.5k
      && (ALLOW_UNALIGNED
100
0
    || (((size_t) e_ident
101
0
         & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
102
0
      - 1)) == 0)))
103
12.5k
    ehdr.p = e_ident;
104
11.6k
  else
105
11.6k
    {
106
      /* We already read the ELF header.  We have to copy the header
107
   since we possibly modify the data here and the caller
108
   expects the memory it passes in to be preserved.  */
109
11.6k
      ehdr.p = &ehdr_mem;
110
111
11.6k
      if (is32)
112
9.32k
  {
113
9.32k
    if (ALLOW_UNALIGNED)
114
9.32k
      {
115
9.32k
        ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
116
9.32k
        ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
117
9.32k
      }
118
0
    else
119
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
120
121
9.32k
    if (e_ident[EI_DATA] != MY_ELFDATA)
122
9.32k
      {
123
9.32k
        CONVERT (ehdr_mem.e32.e_shnum);
124
9.32k
        CONVERT (ehdr_mem.e32.e_shoff);
125
9.32k
      }
126
9.32k
  }
127
2.34k
      else
128
2.34k
  {
129
2.34k
    if (ALLOW_UNALIGNED)
130
2.34k
      {
131
2.34k
        ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
132
2.34k
        ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
133
2.34k
      }
134
0
    else
135
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
136
137
2.34k
    if (e_ident[EI_DATA] != MY_ELFDATA)
138
2.34k
      {
139
2.34k
        CONVERT (ehdr_mem.e64.e_shnum);
140
2.34k
        CONVERT (ehdr_mem.e64.e_shoff);
141
2.34k
      }
142
2.34k
  }
143
11.6k
    }
144
145
24.2k
  if (is32)
146
18.2k
    {
147
      /* Get the number of sections from the ELF header.  */
148
18.2k
      result = ehdr.e32->e_shnum;
149
150
18.2k
      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
151
916
  {
152
916
    if (unlikely (ehdr.e32->e_shoff >= maxsize)
153
704
        || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
154
      /* Cannot read the first section header.  */
155
260
      return 0;
156
157
656
    if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
158
0
        && (ALLOW_UNALIGNED
159
0
      || (((size_t) ((char *) (map_address + ehdr.e32->e_shoff
160
0
             + offset)))
161
0
          & (__alignof__ (Elf32_Shdr) - 1)) == 0))
162
      /* We can directly access the memory.  */
163
141
      result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
164
141
              + offset))->sh_size;
165
515
    else
166
515
      {
167
515
        Elf32_Word size;
168
515
        ssize_t r;
169
170
515
        if (likely (map_address != NULL))
171
    /* gcc will optimize the memcpy to a simple memory
172
       access while taking care of alignment issues.  */
173
23
    memcpy (&size, ((char *) map_address
174
23
           + ehdr.e32->e_shoff
175
23
           + offset
176
23
           + offsetof (Elf32_Shdr, sh_size)),
177
23
      sizeof (Elf32_Word));
178
492
        else
179
492
    if (unlikely ((r = pread_retry (fildes, &size,
180
492
            sizeof (Elf32_Word),
181
492
            offset + ehdr.e32->e_shoff
182
492
            + offsetof (Elf32_Shdr,
183
492
                  sh_size)))
184
492
            != sizeof (Elf32_Word)))
185
0
      {
186
0
        if (r < 0)
187
0
          __libelf_seterrno (ELF_E_INVALID_FILE);
188
0
        else
189
0
          __libelf_seterrno (ELF_E_INVALID_ELF);
190
0
        return (size_t) -1l;
191
0
      }
192
193
515
        if (e_ident[EI_DATA] != MY_ELFDATA)
194
92
    CONVERT (size);
195
196
515
        result = size;
197
515
      }
198
656
  }
199
200
      /* If the section headers were truncated, pretend none were there.  */
201
17.9k
      if (ehdr.e32->e_shoff > maxsize
202
17.8k
    || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
203
416
  result = 0;
204
17.9k
    }
205
5.99k
  else
206
5.99k
    {
207
      /* Get the number of sections from the ELF header.  */
208
5.99k
      result = ehdr.e64->e_shnum;
209
210
5.99k
      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
211
1.10k
  {
212
1.10k
    if (unlikely (ehdr.e64->e_shoff >= maxsize)
213
536
        || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
214
      /* Cannot read the first section header.  */
215
612
      return 0;
216
217
492
    Elf64_Xword size;
218
492
    if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
219
0
        && (ALLOW_UNALIGNED
220
0
      || (((size_t) ((char *) (map_address + ehdr.e64->e_shoff
221
0
             + offset)))
222
0
          & (__alignof__ (Elf64_Shdr) - 1)) == 0))
223
      /* We can directly access the memory.  */
224
52
      size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
225
52
            + offset))->sh_size;
226
440
    else
227
440
      {
228
440
        ssize_t r;
229
440
        if (likely (map_address != NULL))
230
    /* gcc will optimize the memcpy to a simple memory
231
       access while taking care of alignment issues.  */
232
71
    memcpy (&size, ((char *) map_address
233
71
           + ehdr.e64->e_shoff
234
71
           + offset
235
71
           + offsetof (Elf64_Shdr, sh_size)),
236
71
      sizeof (Elf64_Xword));
237
369
        else
238
369
    if (unlikely ((r = pread_retry (fildes, &size,
239
369
            sizeof (Elf64_Xword),
240
369
            offset + ehdr.e64->e_shoff
241
369
            + offsetof (Elf64_Shdr,
242
369
                  sh_size)))
243
369
            != sizeof (Elf64_Xword)))
244
0
      {
245
0
        if (r < 0)
246
0
          __libelf_seterrno (ELF_E_INVALID_FILE);
247
0
        else
248
0
          __libelf_seterrno (ELF_E_INVALID_ELF);
249
0
        return (size_t) -1l;
250
0
      }
251
252
440
        if (e_ident[EI_DATA] != MY_ELFDATA)
253
284
    CONVERT (size);
254
440
      }
255
256
    /* Although sh_size is an Elf64_Xword and can contain a 64bit
257
       value, we only expect an 32bit value max.  GElf_Word is
258
       32bit unsigned.  */
259
492
    if (size > ~((GElf_Word) 0))
260
284
      {
261
        /* Invalid value, it is too large.  */
262
284
        __libelf_seterrno (ELF_E_INVALID_ELF);
263
284
        return (size_t) -1l;
264
284
      }
265
266
208
    result = size;
267
208
  }
268
269
      /* If the section headers were truncated, pretend none were there.  */
270
5.10k
      if (ehdr.e64->e_shoff > maxsize
271
4.69k
    || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
272
684
  result = 0;
273
5.10k
    }
274
275
23.0k
  return result;
276
24.2k
}
277
278
279
/* Create descriptor for ELF file in memory.  */
280
static Elf *
281
file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
282
         int64_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
283
24.2k
{
284
  /* Verify the binary is of the class we can handle.  */
285
24.2k
  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
286
24.2k
     && e_ident[EI_CLASS] != ELFCLASS64)
287
    /* We also can only handle two encodings.  */
288
24.2k
    || (e_ident[EI_DATA] != ELFDATA2LSB
289
24.2k
        && e_ident[EI_DATA] != ELFDATA2MSB)))
290
0
    {
291
      /* Cannot handle this.  */
292
0
      __libelf_seterrno (ELF_E_INVALID_ELF);
293
0
      return NULL;
294
0
    }
295
296
  /* Determine the number of sections.  Returns -1 and sets libelf errno
297
     if the file handle or elf file is invalid.  Returns zero if there
298
     are no section headers (or they cannot be read).  */
299
24.2k
  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
300
24.2k
  if (scncnt == (size_t) -1l)
301
    /* Could not determine the number of sections.  */
302
304
    return NULL;
303
304
  /* Check for too many sections.  */
305
23.9k
  if (e_ident[EI_CLASS] == ELFCLASS32)
306
18.2k
    {
307
18.2k
      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
308
0
  {
309
0
    __libelf_seterrno (ELF_E_INVALID_ELF);
310
0
    return NULL;
311
0
  }
312
18.2k
    }
313
5.71k
  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
314
0
    {
315
0
      __libelf_seterrno (ELF_E_INVALID_ELF);
316
0
      return NULL;
317
0
    }
318
319
  /* We can now allocate the memory.  Even if there are no section headers,
320
     we allocate space for a zeroth section in case we need it later.  */
321
23.9k
  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
322
2.06k
       ? 1 : 0);
323
23.9k
  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
324
23.9k
         ELF_K_ELF, scnmax * sizeof (Elf_Scn));
325
23.9k
  if (elf == NULL)
326
    /* Not enough memory.  allocate_elf will have set libelf errno.  */
327
0
    return NULL;
328
329
23.9k
  assert ((unsigned int) scncnt == scncnt);
330
23.9k
  assert (offsetof (struct Elf, state.elf32.scns)
331
23.9k
    == offsetof (struct Elf, state.elf64.scns));
332
23.9k
  elf->state.elf32.scns.cnt = scncnt;
333
23.9k
  elf->state.elf32.scns.max = scnmax;
334
335
  /* Some more or less arbitrary value.  */
336
23.9k
  elf->state.elf.scnincr = 10;
337
338
  /* Make the class easily available.  */
339
23.9k
  elf->class = e_ident[EI_CLASS];
340
341
23.9k
  if (e_ident[EI_CLASS] == ELFCLASS32)
342
18.2k
    {
343
      /* This pointer might not be directly usable if the alignment is
344
   not sufficient for the architecture.  */
345
18.2k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
346
347
      /* This is a 32-bit binary.  */
348
18.2k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
349
0
    && (ALLOW_UNALIGNED
350
0
        || (ehdr & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
351
2.23k
  {
352
    /* We can use the mmapped memory.  */
353
2.23k
    elf->state.elf32.ehdr = (Elf32_Ehdr *) ehdr;
354
2.23k
  }
355
16.0k
      else
356
16.0k
  {
357
    /* Copy the ELF header.  */
358
16.0k
    elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
359
16.0k
            sizeof (Elf32_Ehdr));
360
361
16.0k
    if (e_ident[EI_DATA] != MY_ELFDATA)
362
9.32k
      {
363
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_type);
364
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_machine);
365
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_version);
366
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_entry);
367
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
368
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
369
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_flags);
370
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
371
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
372
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
373
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
374
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
375
9.32k
        CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
376
9.32k
      }
377
16.0k
  }
378
379
      /* Don't precache the phdr pointer here.
380
   elf32_getphdr will validate it against the size when asked.  */
381
382
18.2k
      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
383
18.2k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
384
2.23k
    && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
385
0
    && (ALLOW_UNALIGNED
386
0
        || (((ehdr + e_shoff) & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
387
0
  {
388
0
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
389
0
        || unlikely (maxsize - e_shoff
390
0
         < scncnt * sizeof (Elf32_Shdr)))
391
0
      {
392
0
      free_and_out:
393
0
        free (elf);
394
0
        __libelf_seterrno (ELF_E_INVALID_ELF);
395
0
        return NULL;
396
0
      }
397
398
0
    if (scncnt > 0)
399
0
      elf->state.elf32.shdr = (Elf32_Shdr *) (ehdr + e_shoff);
400
401
0
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
402
0
      {
403
0
        elf->state.elf32.scns.data[cnt].index = cnt;
404
0
        elf->state.elf32.scns.data[cnt].elf = elf;
405
0
        elf->state.elf32.scns.data[cnt].shdr.e32 =
406
0
    &elf->state.elf32.shdr[cnt];
407
0
        if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
408
0
      && likely (elf->state.elf32.shdr[cnt].sh_size
409
0
           <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
410
0
    elf->state.elf32.scns.data[cnt].rawdata_base =
411
0
      elf->state.elf32.scns.data[cnt].data_base =
412
0
      ((char *) map_address + offset
413
0
       + elf->state.elf32.shdr[cnt].sh_offset);
414
0
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
415
0
      }
416
0
  }
417
18.2k
      else
418
18.2k
  {
419
4.96M
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
420
4.94M
      {
421
4.94M
        elf->state.elf32.scns.data[cnt].index = cnt;
422
4.94M
        elf->state.elf32.scns.data[cnt].elf = elf;
423
4.94M
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
424
4.94M
      }
425
18.2k
  }
426
427
      /* So far only one block with sections.  */
428
18.2k
      elf->state.elf32.scns_last = &elf->state.elf32.scns;
429
18.2k
      eu_search_tree_init (&elf->state.elf32.rawchunk_tree);
430
18.2k
    }
431
5.71k
  else
432
5.71k
    {
433
      /* This pointer might not be directly usable if the alignment is
434
   not sufficient for the architecture.  */
435
5.71k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
436
437
      /* This is a 64-bit binary.  */
438
5.71k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
439
0
    && (ALLOW_UNALIGNED
440
0
        || (ehdr & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
441
893
  {
442
    /* We can use the mmapped memory.  */
443
893
    elf->state.elf64.ehdr = (Elf64_Ehdr *) ehdr;
444
893
  }
445
4.81k
      else
446
4.81k
  {
447
    /* Copy the ELF header.  */
448
4.81k
    elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
449
4.81k
            sizeof (Elf64_Ehdr));
450
451
4.81k
    if (e_ident[EI_DATA] != MY_ELFDATA)
452
2.14k
      {
453
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_type);
454
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_machine);
455
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_version);
456
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_entry);
457
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
458
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
459
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_flags);
460
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
461
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
462
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
463
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
464
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
465
2.14k
        CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
466
2.14k
      }
467
4.81k
  }
468
469
      /* Don't precache the phdr pointer here.
470
   elf64_getphdr will validate it against the size when asked.  */
471
472
5.71k
      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
473
5.71k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
474
893
    && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
475
0
    && (ALLOW_UNALIGNED
476
0
        || (((ehdr + e_shoff) & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
477
0
  {
478
0
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
479
0
        || unlikely (maxsize - e_shoff
480
0
         < scncnt * sizeof (Elf64_Shdr)))
481
0
      goto free_and_out;
482
483
0
    if (scncnt > 0)
484
0
      elf->state.elf64.shdr = (Elf64_Shdr *) (ehdr + (ptrdiff_t) e_shoff);
485
486
0
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
487
0
      {
488
0
        elf->state.elf64.scns.data[cnt].index = cnt;
489
0
        elf->state.elf64.scns.data[cnt].elf = elf;
490
0
        elf->state.elf64.scns.data[cnt].shdr.e64 =
491
0
    &elf->state.elf64.shdr[cnt];
492
0
        if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
493
0
      && likely (elf->state.elf64.shdr[cnt].sh_size
494
0
           <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
495
0
    elf->state.elf64.scns.data[cnt].rawdata_base =
496
0
      elf->state.elf64.scns.data[cnt].data_base =
497
0
      ((char *) map_address + offset
498
0
       + elf->state.elf64.shdr[cnt].sh_offset);
499
0
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
500
0
      }
501
0
  }
502
5.71k
      else
503
5.71k
  {
504
698k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
505
692k
      {
506
692k
        elf->state.elf64.scns.data[cnt].index = cnt;
507
692k
        elf->state.elf64.scns.data[cnt].elf = elf;
508
692k
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
509
692k
      }
510
5.71k
  }
511
512
      /* So far only one block with sections.  */
513
5.71k
      elf->state.elf64.scns_last = &elf->state.elf64.scns;
514
5.71k
      eu_search_tree_init (&elf->state.elf64.rawchunk_tree);
515
5.71k
    }
516
517
23.9k
  return elf;
518
23.9k
}
519
520
521
Elf *
522
internal_function
523
__libelf_read_mmaped_file (int fildes, void *map_address,  int64_t offset,
524
         size_t maxsize, Elf_Cmd cmd, Elf *parent)
525
6.19k
{
526
  /* We have to find out what kind of file this is.  We handle ELF
527
     files and archives.  To find out what we have we must look at the
528
     header.  The header for an ELF file is EI_NIDENT bytes in size,
529
     the header for an archive file SARMAG bytes long.  */
530
6.19k
  unsigned char *e_ident = (unsigned char *) map_address + offset;
531
532
  /* See what kind of object we have here.  */
533
6.19k
  Elf_Kind kind = determine_kind (e_ident, maxsize);
534
535
6.19k
  switch (kind)
536
6.19k
    {
537
6.08k
    case ELF_K_ELF:
538
6.08k
      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
539
6.08k
          cmd, parent);
540
541
1
    case ELF_K_AR:
542
1
      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
543
544
116
    default:
545
116
      break;
546
6.19k
    }
547
548
  /* This case is easy.  Since we cannot do anything with this file
549
     create a dummy descriptor.  */
550
116
  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
551
116
           ELF_K_NONE, 0);
552
6.19k
}
553
554
555
static Elf *
556
read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
557
        Elf *parent)
558
30.9k
{
559
  /* We have to find out what kind of file this is.  We handle ELF
560
     files and archives.  To find out what we have we must read the
561
     header.  The identification header for an ELF file is EI_NIDENT
562
     bytes in size, but we read the whole ELF header since we will
563
     need it anyway later.  For archives the header in SARMAG bytes
564
     long.  Read the maximum of these numbers.
565
566
     XXX We have to change this for the extended `ar' format some day.
567
568
     Use a union to ensure alignment.  We might later access the
569
     memory as a ElfXX_Ehdr.  */
570
30.9k
  union
571
30.9k
  {
572
30.9k
    Elf64_Ehdr ehdr;
573
30.9k
    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
574
30.9k
  } mem;
575
576
  /* Read the head of the file.  */
577
30.9k
  ssize_t nread = pread_retry (fildes, mem.header,
578
30.9k
             MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
579
30.9k
            maxsize),
580
30.9k
             offset);
581
30.9k
  if (unlikely (nread == -1))
582
12.3k
    {
583
      /* We cannot even read the head of the file.  Maybe FILDES is associated
584
   with an unseekable device.  This is nothing we can handle.  */
585
12.3k
      __libelf_seterrno (ELF_E_INVALID_FILE);
586
12.3k
      return NULL;
587
12.3k
    }
588
589
  /* See what kind of object we have here.  */
590
18.5k
  Elf_Kind kind = determine_kind (mem.header, nread);
591
592
18.5k
  switch (kind)
593
18.5k
    {
594
3
    case ELF_K_AR:
595
3
      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
596
597
18.2k
    case ELF_K_ELF:
598
      /* Make sure at least the ELF header is contained in the file.  */
599
18.2k
      if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
600
18.2k
           ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
601
18.1k
  return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
602
18.1k
            parent);
603
60
      FALLTHROUGH;
604
605
408
    default:
606
408
      break;
607
18.5k
    }
608
609
  /* This case is easy.  Since we cannot do anything with this file
610
     create a dummy descriptor.  */
611
408
  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
612
408
           ELF_K_NONE, 0);
613
18.5k
}
614
615
616
/* Open a file for reading.  If possible we will try to mmap() the file.  */
617
static struct Elf *
618
read_file (int fildes, int64_t offset, size_t maxsize,
619
     Elf_Cmd cmd, Elf *parent)
620
37.1k
{
621
37.1k
  void *map_address = NULL;
622
37.1k
  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
623
24.7k
      || cmd == ELF_C_WRITE_MMAP
624
24.7k
      || cmd == ELF_C_READ_MMAP_PRIVATE);
625
626
37.1k
  if (parent == NULL)
627
37.1k
    {
628
37.1k
      if (maxsize == ~((size_t) 0))
629
37.1k
  {
630
    /* We don't know in the moment how large the file is.
631
       Determine it now.  */
632
37.1k
    struct stat st;
633
634
37.1k
    if (fstat (fildes, &st) == 0
635
37.1k
        && (sizeof (size_t) >= sizeof (st.st_size)
636
0
      || st.st_size <= ~((size_t) 0)))
637
37.1k
      maxsize = (size_t) st.st_size;
638
37.1k
  }
639
37.1k
    }
640
0
  else
641
0
    {
642
      /* The parent is already loaded.  Use it.  */
643
0
      assert (maxsize != ~((size_t) 0));
644
0
    }
645
646
37.1k
  if (use_mmap)
647
12.3k
    {
648
12.3k
      if (parent == NULL)
649
12.3k
  {
650
    /* We try to map the file ourself.  */
651
12.3k
    map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
652
12.3k
                ? PROT_READ
653
12.3k
                : PROT_READ|PROT_WRITE),
654
12.3k
            cmd == ELF_C_READ_MMAP_PRIVATE
655
12.3k
            || cmd == ELF_C_READ_MMAP
656
12.3k
            ? MAP_PRIVATE : MAP_SHARED,
657
12.3k
            fildes, offset);
658
659
12.3k
    if (map_address == MAP_FAILED)
660
6.19k
      map_address = NULL;
661
12.3k
  }
662
0
      else
663
0
  {
664
0
    map_address = parent->map_address;
665
0
  }
666
12.3k
    }
667
668
  /* If we have the file in memory optimize the access.  */
669
37.1k
  if (map_address != NULL)
670
6.19k
    {
671
6.19k
      assert (map_address != MAP_FAILED);
672
673
6.19k
      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
674
6.19k
                  offset, maxsize, cmd,
675
6.19k
                  parent);
676
677
      /* If something went wrong during the initialization unmap the
678
   memory if we mmaped here.  */
679
6.19k
      if (result == NULL
680
91
    && (parent == NULL
681
0
        || parent->map_address != map_address))
682
91
  munmap (map_address, maxsize);
683
6.10k
      else if (parent == NULL)
684
  /* Remember that we mmap()ed the memory.  */
685
6.10k
  result->flags |= ELF_F_MMAPPED;
686
687
6.19k
      return result;
688
6.19k
    }
689
690
  /* Otherwise we have to do it the hard way.  We read as much as necessary
691
     from the file whenever we need information which is not available.  */
692
30.9k
  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
693
37.1k
}
694
695
696
/* Find the entry with the long names for the content of this archive.  */
697
static const char *
698
read_long_names (Elf *elf)
699
0
{
700
0
  off_t offset = SARMAG; /* This is the first entry.  */
701
0
  struct ar_hdr hdrm;
702
0
  struct ar_hdr *hdr;
703
0
  char *newp;
704
0
  size_t len;
705
706
0
  while (1)
707
0
    {
708
0
      if (elf->map_address != NULL)
709
0
  {
710
0
    if ((size_t) offset > elf->maximum_size
711
0
        || elf->maximum_size - offset < sizeof (struct ar_hdr))
712
0
      return NULL;
713
714
    /* The data is mapped.  */
715
0
    hdr = (struct ar_hdr *) (elf->map_address + offset);
716
0
  }
717
0
      else
718
0
  {
719
    /* Read the header from the file.  */
720
0
    if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
721
0
             elf->start_offset + offset)
722
0
      != sizeof (hdrm)))
723
0
      return NULL;
724
725
0
    hdr = &hdrm;
726
0
  }
727
728
      /* The ar_size is given as a fixed size decimal string, right
729
   padded with spaces.  Make sure we read it properly even if
730
   there is no terminating space.  */
731
0
      char buf[sizeof (hdr->ar_size) + 1];
732
0
      const char *string = hdr->ar_size;
733
0
      if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
734
0
  {
735
0
    *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
736
0
    string = buf;
737
0
  }
738
739
      /* atol expects to see at least one digit.
740
   It also cannot be negative (-).  */
741
0
      if (!isdigit(string[0]))
742
0
  return NULL;
743
0
      len = atol (string);
744
745
0
      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
746
0
  break;
747
748
0
      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
749
0
    }
750
751
  /* Sanity check len early if we can.  */
752
0
  if (elf->map_address != NULL)
753
0
    {
754
0
      if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
755
0
  return NULL;
756
0
    }
757
758
  /* Due to the stupid format of the long name table entry (which are not
759
     NUL terminted) we have to provide an appropriate representation anyhow.
760
     Therefore we always make a copy which has the appropriate form.  */
761
0
  newp = malloc (len);
762
0
  if (newp != NULL)
763
0
    {
764
0
      char *runp;
765
766
0
      if (elf->map_address != NULL)
767
0
  {
768
    /* Simply copy it over.  */
769
0
    elf->state.ar.long_names = (char *) memcpy (newp,
770
0
                  elf->map_address + offset
771
0
                  + sizeof (struct ar_hdr),
772
0
                  len);
773
0
  }
774
0
      else
775
0
  {
776
0
    if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
777
0
                elf->start_offset + offset
778
0
                + sizeof (struct ar_hdr))
779
0
      != len))
780
0
      {
781
        /* We were not able to read all data.  */
782
0
        free (newp);
783
0
        elf->state.ar.long_names = NULL;
784
0
        return NULL;
785
0
      }
786
0
    elf->state.ar.long_names = newp;
787
0
  }
788
789
0
      elf->state.ar.long_names_len = len;
790
791
      /* Now NUL-terminate the strings.  */
792
0
      runp = newp;
793
0
      while (1)
794
0
        {
795
0
    char *startp = runp;
796
0
    runp = (char *) memchr (runp, '/', newp + len - runp);
797
0
    if (runp == NULL)
798
0
      {
799
        /* This was the last entry.  Clear any left overs.  */
800
0
        memset (startp, '\0', newp + len - startp);
801
0
        break;
802
0
      }
803
804
    /* NUL-terminate the string.  */
805
0
    *runp++ = '\0';
806
807
    /* A sanity check.  Somebody might have generated invalid
808
       archive.  */
809
0
    if (runp >= newp + len)
810
0
      break;
811
0
  }
812
0
    }
813
814
0
  return newp;
815
0
}
816
817
818
/* Copy archive header from parent archive ref to member descriptor elf.  */
819
static int
820
copy_arhdr (Elf_Arhdr *dest, Elf *ref)
821
0
{
822
0
  Elf_Arhdr *hdr;
823
824
0
  if (ref->kind == ELF_K_AR)
825
0
    hdr = &ref->state.ar.elf_ar_hdr;
826
0
  else
827
0
    hdr = &ref->state.elf.elf_ar_hdr;
828
829
0
  char *ar_name = hdr->ar_name;
830
0
  char *ar_rawname = hdr->ar_rawname;
831
0
  if (ar_name == NULL || ar_rawname == NULL)
832
0
    {
833
      /* ref doesn't have an Elf_Arhdr or it was marked as unusable.  */
834
0
      return 0;
835
0
    }
836
837
  /* Allocate copies of ar_name and ar_rawname.  */
838
0
  size_t name_len = strlen (ar_name) + 1;
839
0
  char *name_copy = malloc (MAX (name_len, 16));
840
0
  if (name_copy == NULL)
841
0
    {
842
0
      __libelf_seterrno (ELF_E_NOMEM);
843
0
      return -1;
844
0
    }
845
0
  memcpy (name_copy, ar_name, name_len);
846
847
0
  size_t rawname_len = strlen (ar_rawname) + 1;
848
0
  char *rawname_copy = malloc (MAX (rawname_len, 17));
849
0
  if (rawname_copy == NULL)
850
0
    {
851
0
      free (name_copy);
852
0
      __libelf_seterrno (ELF_E_NOMEM);
853
0
      return -1;
854
0
    }
855
0
  memcpy (rawname_copy, ar_rawname, rawname_len);
856
857
0
  *dest = *hdr;
858
0
  dest->ar_name = name_copy;
859
0
  dest->ar_rawname = rawname_copy;
860
861
0
  return 0;
862
0
}
863
864
865
/* Read the next archive header.  */
866
int
867
internal_function
868
__libelf_next_arhdr_wrlock (Elf *elf)
869
0
{
870
0
  struct ar_hdr *ar_hdr;
871
0
  Elf_Arhdr *elf_ar_hdr;
872
873
0
  if (elf->map_address != NULL)
874
0
    {
875
      /* See whether this entry is in the file.  */
876
0
      if (unlikely ((size_t) elf->state.ar.offset
877
0
        > elf->start_offset + elf->maximum_size
878
0
        || (elf->start_offset + elf->maximum_size
879
0
      - elf->state.ar.offset) < sizeof (struct ar_hdr)))
880
0
  {
881
    /* This record is not anymore in the file.  */
882
0
    __libelf_seterrno (ELF_E_RANGE);
883
0
    return -1;
884
0
  }
885
0
      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
886
0
    }
887
0
  else
888
0
    {
889
0
      ar_hdr = &elf->state.ar.ar_hdr;
890
891
0
      if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
892
0
         elf->state.ar.offset)
893
0
        != sizeof (struct ar_hdr)))
894
0
  {
895
    /* Something went wrong while reading the file.  */
896
0
    __libelf_seterrno (ELF_E_RANGE);
897
0
    return -1;
898
0
  }
899
0
    }
900
901
  /* One little consistency check.  */
902
0
  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
903
0
    {
904
      /* This is no valid archive.  */
905
0
      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
906
0
      return -1;
907
0
    }
908
909
  /* Copy the raw name over to a NUL terminated buffer.  */
910
0
  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
911
912
0
  elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
913
914
  /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
915
     Determine whether this is a special entry.  */
916
0
  if (ar_hdr->ar_name[0] == '/')
917
0
    {
918
0
      if (ar_hdr->ar_name[1] == ' '
919
0
    && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
920
  /* This is the index.  */
921
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
922
0
      else if (ar_hdr->ar_name[1] == 'S'
923
0
         && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
924
  /* 64-bit index.  */
925
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
926
0
      else if (ar_hdr->ar_name[1] == '/'
927
0
         && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
928
  /* This is the array with the long names.  */
929
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
930
0
      else if (likely  (isdigit (ar_hdr->ar_name[1])))
931
0
  {
932
0
    size_t offset;
933
934
    /* This is a long name.  First we have to read the long name
935
       table, if this hasn't happened already.  */
936
0
    if (unlikely (elf->state.ar.long_names == NULL
937
0
      && read_long_names (elf) == NULL))
938
0
      {
939
        /* No long name table although it is reference.  The archive is
940
     broken.  */
941
0
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
942
0
        return -1;
943
0
      }
944
945
0
    offset = atol (ar_hdr->ar_name + 1);
946
0
    if (unlikely (offset >= elf->state.ar.long_names_len))
947
0
      {
948
        /* The index in the long name table is larger than the table.  */
949
0
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
950
0
        return -1;
951
0
      }
952
0
    elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
953
0
  }
954
0
      else
955
0
  {
956
    /* This is none of the known special entries.  */
957
0
    __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
958
0
    return -1;
959
0
  }
960
0
    }
961
0
  else
962
0
    {
963
0
      char *endp;
964
965
      /* It is a normal entry.  Copy over the name.  */
966
0
      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
967
0
             '/', 16);
968
0
      if (endp != NULL)
969
0
  endp[-1] = '\0';
970
0
      else
971
0
  {
972
    /* In the old BSD style of archive, there is no / terminator.
973
       Instead, there is space padding at the end of the name.  */
974
0
    size_t i = 15;
975
0
    do
976
0
      elf->state.ar.ar_name[i] = '\0';
977
0
    while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
978
0
  }
979
980
0
      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
981
0
    }
982
983
0
  if (unlikely (ar_hdr->ar_size[0] == ' '))
984
    /* Something is really wrong.  We cannot live without a size for
985
       the member since it will not be possible to find the next
986
       archive member.  */
987
0
    {
988
0
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
989
0
      return -1;
990
0
    }
991
992
  /* Since there are no specialized functions to convert ASCII to
993
     time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
994
     atoll depending on the size of the types.  We are also prepared
995
     for the case where the whole field in the `struct ar_hdr' is
996
     filled in which case we cannot simply use atol/l but instead have
997
     to create a temporary copy.  Note that all fields use decimal
998
     encoding, except ar_mode which uses octal.  */
999
1000
0
#define INT_FIELD(FIELD)                  \
1001
0
  do                        \
1002
0
    {                       \
1003
0
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1004
0
      const char *string = ar_hdr->FIELD;             \
1005
0
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1006
0
  {                     \
1007
0
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1008
0
      = '\0';                   \
1009
0
    string = buf;                   \
1010
0
  }                      \
1011
0
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1012
0
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
1013
0
      else                      \
1014
0
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
1015
0
    }                       \
1016
0
  while (0)
1017
1018
0
#define OCT_FIELD(FIELD)                  \
1019
0
  do                        \
1020
0
    {                       \
1021
0
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1022
0
      const char *string = ar_hdr->FIELD;             \
1023
0
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1024
0
  {                     \
1025
0
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1026
0
      = '\0';                   \
1027
0
    string = buf;                   \
1028
0
  }                      \
1029
0
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1030
0
  elf_ar_hdr->FIELD                 \
1031
0
    = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8);       \
1032
0
      else                      \
1033
0
  elf_ar_hdr->FIELD                 \
1034
0
    = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8);       \
1035
0
    }                       \
1036
0
  while (0)
1037
1038
0
  INT_FIELD (ar_date);
1039
0
  INT_FIELD (ar_uid);
1040
0
  INT_FIELD (ar_gid);
1041
0
  OCT_FIELD (ar_mode);
1042
0
  INT_FIELD (ar_size);
1043
1044
0
  if (elf_ar_hdr->ar_size < 0)
1045
0
    {
1046
0
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
1047
0
      return -1;
1048
0
    }
1049
1050
  /* Truncated file?  */
1051
0
  size_t maxsize;
1052
0
  maxsize = (elf->start_offset + elf->maximum_size
1053
0
       - elf->state.ar.offset - sizeof (struct ar_hdr));
1054
0
  if ((size_t) elf_ar_hdr->ar_size > maxsize)
1055
0
    elf_ar_hdr->ar_size = maxsize;
1056
1057
0
  return 0;
1058
0
}
1059
1060
1061
/* We were asked to return a clone of an existing descriptor.  This
1062
   function must be called with the lock on the parent descriptor
1063
   being held. */
1064
static Elf *
1065
dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1066
0
{
1067
0
  struct Elf *result;
1068
1069
0
  if (fildes == -1)
1070
    /* Allow the user to pass -1 as the file descriptor for the new file.  */
1071
0
    fildes = ref->fildes;
1072
  /* The file descriptor better should be the same.  If it was disconnected
1073
     already (using `elf_cntl') we do not test it.  */
1074
0
  else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
1075
0
    {
1076
0
      __libelf_seterrno (ELF_E_FD_MISMATCH);
1077
0
      return NULL;
1078
0
    }
1079
1080
  /* The mode must allow reading.  I.e., a descriptor creating with a
1081
     command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
1082
     not allowed.  */
1083
0
  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
1084
0
    && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1085
0
    && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1086
0
    && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1087
0
    {
1088
0
      __libelf_seterrno (ELF_E_INVALID_OP);
1089
0
      return NULL;
1090
0
    }
1091
1092
  /* Now it is time to distinguish between reading normal files and
1093
     archives.  Normal files can easily be handled be incrementing the
1094
     reference counter and return the same descriptor.  */
1095
0
  if (ref->kind != ELF_K_AR)
1096
0
    {
1097
0
      ++ref->ref_count;
1098
0
      return ref;
1099
0
    }
1100
1101
  /* This is an archive.  We must create a descriptor for the archive
1102
     member the internal pointer of the archive file descriptor is
1103
     pointing to.  First read the header of the next member if this
1104
     has not happened already.  */
1105
0
  if (ref->state.ar.elf_ar_hdr.ar_name == NULL
1106
0
      && __libelf_next_arhdr_wrlock (ref) != 0)
1107
    /* Something went wrong.  Maybe there is no member left.  */
1108
0
    return NULL;
1109
1110
  /* We have all the information we need about the next archive member.
1111
     Now create a descriptor for it. Check parent size can contain member.  */
1112
0
  if (ref->state.ar.offset < ref->start_offset)
1113
0
    return NULL;
1114
0
  size_t max_size = ref->maximum_size;
1115
0
  size_t offset = (size_t) (ref->state.ar.offset - ref->start_offset);
1116
0
  size_t hdr_size = sizeof (struct ar_hdr);
1117
0
  size_t ar_size = (size_t) ref->state.ar.elf_ar_hdr.ar_size;
1118
0
  if (max_size < hdr_size || max_size - hdr_size < offset)
1119
0
    return NULL;
1120
1121
0
  Elf_Arhdr ar_hdr = {0};
1122
0
  if (copy_arhdr (&ar_hdr, ref) != 0)
1123
    /* Out of memory.  */
1124
0
    return NULL;
1125
1126
0
  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1127
0
          MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
1128
1129
0
  if (result != NULL)
1130
0
    {
1131
      /* Enlist this new descriptor in the list of children.  */
1132
0
      result->next = ref->state.ar.children;
1133
0
      result->state.elf.elf_ar_hdr = ar_hdr;
1134
0
      ref->state.ar.children = result;
1135
0
    }
1136
0
  else
1137
0
    {
1138
0
      free (ar_hdr.ar_name);
1139
0
      free (ar_hdr.ar_rawname);
1140
0
    }
1141
1142
0
  return result;
1143
0
}
1144
1145
1146
/* Return descriptor for empty file ready for writing.  */
1147
static struct Elf *
1148
write_file (int fd, Elf_Cmd cmd)
1149
0
{
1150
  /* We simply create an empty `Elf' structure.  */
1151
0
#define NSCNSALLOC  10
1152
0
  Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
1153
0
            NSCNSALLOC * sizeof (Elf_Scn));
1154
1155
0
  if (result != NULL)
1156
0
    {
1157
      /* We have to write to the file in any case.  */
1158
0
      result->flags = ELF_F_DIRTY;
1159
1160
      /* Some more or less arbitrary value.  */
1161
0
      result->state.elf.scnincr = NSCNSALLOC;
1162
1163
      /* We have allocated room for some sections.  */
1164
0
      assert (offsetof (struct Elf, state.elf32.scns)
1165
0
        == offsetof (struct Elf, state.elf64.scns));
1166
0
      result->state.elf.scns_last = &result->state.elf32.scns;
1167
0
      result->state.elf32.scns.max = NSCNSALLOC;
1168
0
    }
1169
1170
0
  return result;
1171
0
}
1172
1173
/* Lock if necessary before dup an archive.  */
1174
static inline Elf *
1175
lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1176
0
{
1177
  /* We need wrlock to dup an archive.  */
1178
0
  if (ref->kind == ELF_K_AR)
1179
0
    {
1180
0
      rwlock_unlock (ref->lock);
1181
0
      rwlock_wrlock (ref->lock);
1182
0
    }
1183
    /* Duplicate the descriptor.  */
1184
0
  return dup_elf (fildes, cmd, ref);
1185
0
}
1186
1187
/* Return a descriptor for the file belonging to FILDES.  */
1188
Elf *
1189
elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1190
37.1k
{
1191
37.1k
  Elf *retval;
1192
1193
37.1k
  if (unlikely (__libelf_version != EV_CURRENT))
1194
0
    {
1195
      /* Version wasn't set so far.  */
1196
0
      __libelf_seterrno (ELF_E_NO_VERSION);
1197
0
      return NULL;
1198
0
    }
1199
1200
37.1k
  if (ref != NULL)
1201
    /* Make sure the descriptor is not suddenly going away.  */
1202
0
    rwlock_rdlock (ref->lock);
1203
37.1k
  else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
1204
0
    {
1205
      /* We cannot do anything productive without a file descriptor.  */
1206
0
      __libelf_seterrno (ELF_E_INVALID_FILE);
1207
0
      return NULL;
1208
0
    }
1209
1210
37.1k
  switch (cmd)
1211
37.1k
    {
1212
0
    case ELF_C_NULL:
1213
      /* We simply return a NULL pointer.  */
1214
0
      retval = NULL;
1215
0
      break;
1216
1217
0
    case ELF_C_READ_MMAP_PRIVATE:
1218
      /* If we have a reference it must also be opened this way.  */
1219
0
      if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1220
0
  {
1221
0
    __libelf_seterrno (ELF_E_INVALID_CMD);
1222
0
    retval = NULL;
1223
0
    break;
1224
0
  }
1225
0
      FALLTHROUGH;
1226
1227
18.5k
    case ELF_C_READ:
1228
24.7k
    case ELF_C_READ_MMAP:
1229
24.7k
      if (ref != NULL)
1230
0
  retval = lock_dup_elf (fildes, cmd, ref);
1231
24.7k
      else
1232
  /* Create descriptor for existing file.  */
1233
24.7k
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1234
24.7k
      break;
1235
1236
6.19k
    case ELF_C_RDWR:
1237
12.3k
    case ELF_C_RDWR_MMAP:
1238
      /* If we have a REF object it must also be opened using this
1239
   command.  */
1240
12.3k
      if (ref != NULL)
1241
0
  {
1242
0
    if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1243
0
      && ref->cmd != ELF_C_WRITE
1244
0
      && ref->cmd != ELF_C_WRITE_MMAP))
1245
0
      {
1246
        /* This is not ok.  REF must also be opened for writing.  */
1247
0
        __libelf_seterrno (ELF_E_INVALID_CMD);
1248
0
        retval = NULL;
1249
0
      }
1250
0
    else
1251
0
      retval = lock_dup_elf (fildes, cmd, ref);
1252
0
  }
1253
12.3k
      else
1254
  /* Create descriptor for existing file.  */
1255
12.3k
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1256
12.3k
      break;
1257
1258
0
    case ELF_C_WRITE:
1259
0
    case ELF_C_WRITE_MMAP:
1260
      /* We ignore REF and prepare a descriptor to write a new file.  */
1261
0
      retval = write_file (fildes, cmd);
1262
0
      break;
1263
1264
0
    default:
1265
0
      __libelf_seterrno (ELF_E_INVALID_CMD);
1266
0
      retval = NULL;
1267
0
      break;
1268
37.1k
    }
1269
1270
  /* Release the lock.  */
1271
37.1k
  if (ref != NULL)
1272
0
    rwlock_unlock (ref->lock);
1273
1274
37.1k
  return retval;
1275
37.1k
}
1276
INTDEF(elf_begin)