Coverage Report

Created: 2025-11-11 06:45

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
72.3k
{
54
72.3k
  Elf *elf;
55
56
  /* Create a descriptor.  */
57
72.3k
  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
58
72.3k
                      ELF_K_AR, 0);
59
72.3k
  if (elf != NULL)
60
72.3k
    {
61
      /* We don't read all the symbol tables in advance.  All this will
62
   happen on demand.  */
63
72.3k
      elf->state.ar.offset = offset + SARMAG;
64
65
72.3k
      elf->state.ar.cur_ar_hdr.ar_rawname = elf->state.ar.raw_name;
66
72.3k
    }
67
68
72.3k
  return elf;
69
72.3k
}
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
15.1k
{
76
15.1k
  size_t result;
77
15.1k
  union
78
15.1k
  {
79
15.1k
    Elf32_Ehdr *e32;
80
15.1k
    Elf64_Ehdr *e64;
81
15.1k
    void *p;
82
15.1k
  } ehdr;
83
15.1k
  union
84
15.1k
  {
85
15.1k
    Elf32_Ehdr e32;
86
15.1k
    Elf64_Ehdr e64;
87
15.1k
  } ehdr_mem;
88
15.1k
  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
89
90
15.1k
  if ((is32 && maxsize < sizeof (Elf32_Ehdr))
91
15.1k
      || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
92
44
    {
93
44
       __libelf_seterrno (ELF_E_INVALID_ELF);
94
44
      return (size_t) -1l;
95
44
    }
96
97
  /* Make the ELF header available.  */
98
15.1k
  if (e_ident[EI_DATA] == MY_ELFDATA
99
10.5k
      && (ALLOW_UNALIGNED
100
0
    || (((size_t) e_ident
101
0
         & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
102
0
      - 1)) == 0)))
103
10.5k
    ehdr.p = e_ident;
104
4.64k
  else
105
4.64k
    {
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
4.64k
      ehdr.p = &ehdr_mem;
110
111
4.64k
      if (is32)
112
3.34k
  {
113
3.34k
    if (ALLOW_UNALIGNED)
114
3.34k
      {
115
3.34k
        ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
116
3.34k
        ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
117
3.34k
      }
118
0
    else
119
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
120
121
3.34k
    if (e_ident[EI_DATA] != MY_ELFDATA)
122
3.34k
      {
123
3.34k
        CONVERT (ehdr_mem.e32.e_shnum);
124
3.34k
        CONVERT (ehdr_mem.e32.e_shoff);
125
3.34k
      }
126
3.34k
  }
127
1.29k
      else
128
1.29k
  {
129
1.29k
    if (ALLOW_UNALIGNED)
130
1.29k
      {
131
1.29k
        ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
132
1.29k
        ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
133
1.29k
      }
134
0
    else
135
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
136
137
1.29k
    if (e_ident[EI_DATA] != MY_ELFDATA)
138
1.29k
      {
139
1.29k
        CONVERT (ehdr_mem.e64.e_shnum);
140
1.29k
        CONVERT (ehdr_mem.e64.e_shoff);
141
1.29k
      }
142
1.29k
  }
143
4.64k
    }
144
145
15.1k
  if (is32)
146
10.0k
    {
147
      /* Get the number of sections from the ELF header.  */
148
10.0k
      result = ehdr.e32->e_shnum;
149
150
10.0k
      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
151
1.80k
  {
152
1.80k
    if (unlikely (ehdr.e32->e_shoff >= maxsize)
153
855
        || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
154
      /* Cannot read the first section header.  */
155
1.19k
      return 0;
156
157
606
    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
522
      result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
164
522
              + offset))->sh_size;
165
84
    else
166
84
      {
167
84
        Elf32_Word size;
168
84
        ssize_t r;
169
170
84
        if (likely (map_address != NULL))
171
    /* gcc will optimize the memcpy to a simple memory
172
       access while taking care of alignment issues.  */
173
84
    memcpy (&size, ((char *) map_address
174
84
           + ehdr.e32->e_shoff
175
84
           + offset
176
84
           + offsetof (Elf32_Shdr, sh_size)),
177
84
      sizeof (Elf32_Word));
178
0
        else
179
0
    if (unlikely ((r = pread_retry (fildes, &size,
180
0
            sizeof (Elf32_Word),
181
0
            offset + ehdr.e32->e_shoff
182
0
            + offsetof (Elf32_Shdr,
183
0
                  sh_size)))
184
0
            != 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
84
        if (e_ident[EI_DATA] != MY_ELFDATA)
194
84
    CONVERT (size);
195
196
84
        result = size;
197
84
      }
198
606
  }
199
200
      /* If the section headers were truncated, pretend none were there.  */
201
8.82k
      if (ehdr.e32->e_shoff > maxsize
202
8.02k
    || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
203
2.20k
  result = 0;
204
8.82k
    }
205
5.12k
  else
206
5.12k
    {
207
      /* Get the number of sections from the ELF header.  */
208
5.12k
      result = ehdr.e64->e_shnum;
209
210
5.12k
      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
211
730
  {
212
730
    if (unlikely (ehdr.e64->e_shoff >= maxsize)
213
296
        || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
214
      /* Cannot read the first section header.  */
215
472
      return 0;
216
217
258
    Elf64_Xword size;
218
258
    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
199
      size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
225
199
            + offset))->sh_size;
226
59
    else
227
59
      {
228
59
        ssize_t r;
229
59
        if (likely (map_address != NULL))
230
    /* gcc will optimize the memcpy to a simple memory
231
       access while taking care of alignment issues.  */
232
59
    memcpy (&size, ((char *) map_address
233
59
           + ehdr.e64->e_shoff
234
59
           + offset
235
59
           + offsetof (Elf64_Shdr, sh_size)),
236
59
      sizeof (Elf64_Xword));
237
0
        else
238
0
    if (unlikely ((r = pread_retry (fildes, &size,
239
0
            sizeof (Elf64_Xword),
240
0
            offset + ehdr.e64->e_shoff
241
0
            + offsetof (Elf64_Shdr,
242
0
                  sh_size)))
243
0
            != 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
59
        if (e_ident[EI_DATA] != MY_ELFDATA)
253
59
    CONVERT (size);
254
59
      }
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
258
    if (size > ~((GElf_Word) 0))
260
65
      {
261
        /* Invalid value, it is too large.  */
262
65
        __libelf_seterrno (ELF_E_INVALID_ELF);
263
65
        return (size_t) -1l;
264
65
      }
265
266
193
    result = size;
267
193
  }
268
269
      /* If the section headers were truncated, pretend none were there.  */
270
4.59k
      if (ehdr.e64->e_shoff > maxsize
271
3.03k
    || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
272
2.03k
  result = 0;
273
4.59k
    }
274
275
13.4k
  return result;
276
15.1k
}
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
15.1k
{
284
  /* Verify the binary is of the class we can handle.  */
285
15.1k
  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
286
15.1k
     && e_ident[EI_CLASS] != ELFCLASS64)
287
    /* We also can only handle two encodings.  */
288
15.1k
    || (e_ident[EI_DATA] != ELFDATA2LSB
289
15.1k
        && 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
15.1k
  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
300
15.1k
  if (scncnt == (size_t) -1l)
301
    /* Could not determine the number of sections.  */
302
109
    return NULL;
303
304
  /* Check for too many sections.  */
305
15.0k
  if (e_ident[EI_CLASS] == ELFCLASS32)
306
10.0k
    {
307
10.0k
      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
10.0k
    }
313
5.06k
  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
15.0k
  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
322
8.03k
       ? 1 : 0);
323
15.0k
  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
324
15.0k
         ELF_K_ELF, scnmax * sizeof (Elf_Scn));
325
15.0k
  if (elf == NULL)
326
    /* Not enough memory.  allocate_elf will have set libelf errno.  */
327
0
    return NULL;
328
329
15.0k
  assert ((unsigned int) scncnt == scncnt);
330
15.0k
  assert (offsetof (struct Elf, state.elf32.scns)
331
15.0k
    == offsetof (struct Elf, state.elf64.scns));
332
15.0k
  elf->state.elf32.scns.cnt = scncnt;
333
15.0k
  elf->state.elf32.scns.max = scnmax;
334
335
  /* Some more or less arbitrary value.  */
336
15.0k
  elf->state.elf.scnincr = 10;
337
338
  /* Make the class easily available.  */
339
15.0k
  elf->class = e_ident[EI_CLASS];
340
341
15.0k
  if (e_ident[EI_CLASS] == ELFCLASS32)
342
10.0k
    {
343
      /* This pointer might not be directly usable if the alignment is
344
   not sufficient for the architecture.  */
345
10.0k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
346
347
      /* This is a 32-bit binary.  */
348
10.0k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
349
0
    && (ALLOW_UNALIGNED
350
0
        || (ehdr & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
351
6.67k
  {
352
    /* We can use the mmapped memory.  */
353
6.67k
    elf->state.elf32.ehdr = (Elf32_Ehdr *) ehdr;
354
6.67k
  }
355
3.34k
      else
356
3.34k
  {
357
    /* Copy the ELF header.  */
358
3.34k
    elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
359
3.34k
            sizeof (Elf32_Ehdr));
360
361
3.34k
    if (e_ident[EI_DATA] != MY_ELFDATA)
362
3.34k
      {
363
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_type);
364
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_machine);
365
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_version);
366
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_entry);
367
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
368
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
369
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_flags);
370
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
371
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
372
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
373
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
374
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
375
3.34k
        CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
376
3.34k
      }
377
3.34k
  }
378
379
      /* Don't precache the phdr pointer here.
380
   elf32_getphdr will validate it against the size when asked.  */
381
382
10.0k
      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
383
10.0k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
384
6.67k
    && 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
6.67k
  {
388
6.67k
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
389
6.67k
        || unlikely (maxsize - e_shoff
390
6.67k
         < 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
6.67k
    if (scncnt > 0)
399
4.25k
      elf->state.elf32.shdr = (Elf32_Shdr *) (ehdr + e_shoff);
400
401
958k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
402
951k
      {
403
951k
        elf->state.elf32.scns.data[cnt].index = cnt;
404
951k
        elf->state.elf32.scns.data[cnt].elf = elf;
405
951k
        elf->state.elf32.scns.data[cnt].shdr.e32 =
406
951k
    &elf->state.elf32.shdr[cnt];
407
951k
        if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
408
520k
      && likely (elf->state.elf32.shdr[cnt].sh_size
409
951k
           <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
410
490k
    elf->state.elf32.scns.data[cnt].rawdata_base =
411
490k
      elf->state.elf32.scns.data[cnt].data_base =
412
490k
      ((char *) map_address + offset
413
490k
       + elf->state.elf32.shdr[cnt].sh_offset);
414
951k
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
415
951k
      }
416
6.67k
  }
417
3.34k
      else
418
3.34k
  {
419
459k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
420
456k
      {
421
456k
        elf->state.elf32.scns.data[cnt].index = cnt;
422
456k
        elf->state.elf32.scns.data[cnt].elf = elf;
423
456k
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
424
456k
      }
425
3.34k
  }
426
427
      /* So far only one block with sections.  */
428
10.0k
      elf->state.elf32.scns_last = &elf->state.elf32.scns;
429
10.0k
      eu_search_tree_init (&elf->state.elf32.rawchunk_tree);
430
10.0k
    }
431
5.06k
  else
432
5.06k
    {
433
      /* This pointer might not be directly usable if the alignment is
434
   not sufficient for the architecture.  */
435
5.06k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
436
437
      /* This is a 64-bit binary.  */
438
5.06k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
439
0
    && (ALLOW_UNALIGNED
440
0
        || (ehdr & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
441
3.79k
  {
442
    /* We can use the mmapped memory.  */
443
3.79k
    elf->state.elf64.ehdr = (Elf64_Ehdr *) ehdr;
444
3.79k
  }
445
1.26k
      else
446
1.26k
  {
447
    /* Copy the ELF header.  */
448
1.26k
    elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
449
1.26k
            sizeof (Elf64_Ehdr));
450
451
1.26k
    if (e_ident[EI_DATA] != MY_ELFDATA)
452
1.26k
      {
453
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_type);
454
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_machine);
455
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_version);
456
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_entry);
457
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
458
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
459
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_flags);
460
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
461
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
462
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
463
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
464
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
465
1.26k
        CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
466
1.26k
      }
467
1.26k
  }
468
469
      /* Don't precache the phdr pointer here.
470
   elf64_getphdr will validate it against the size when asked.  */
471
472
5.06k
      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
473
5.06k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
474
3.79k
    && 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
3.79k
  {
478
3.79k
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
479
3.79k
        || unlikely (maxsize - e_shoff
480
3.79k
         < scncnt * sizeof (Elf64_Shdr)))
481
0
      goto free_and_out;
482
483
3.79k
    if (scncnt > 0)
484
877
      elf->state.elf64.shdr = (Elf64_Shdr *) (ehdr + (ptrdiff_t) e_shoff);
485
486
42.1k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
487
38.3k
      {
488
38.3k
        elf->state.elf64.scns.data[cnt].index = cnt;
489
38.3k
        elf->state.elf64.scns.data[cnt].elf = elf;
490
38.3k
        elf->state.elf64.scns.data[cnt].shdr.e64 =
491
38.3k
    &elf->state.elf64.shdr[cnt];
492
38.3k
        if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
493
5.11k
      && likely (elf->state.elf64.shdr[cnt].sh_size
494
38.3k
           <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
495
1.50k
    elf->state.elf64.scns.data[cnt].rawdata_base =
496
1.50k
      elf->state.elf64.scns.data[cnt].data_base =
497
1.50k
      ((char *) map_address + offset
498
1.50k
       + elf->state.elf64.shdr[cnt].sh_offset);
499
38.3k
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
500
38.3k
      }
501
3.79k
  }
502
1.26k
      else
503
1.26k
  {
504
1.02M
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
505
1.02M
      {
506
1.02M
        elf->state.elf64.scns.data[cnt].index = cnt;
507
1.02M
        elf->state.elf64.scns.data[cnt].elf = elf;
508
1.02M
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
509
1.02M
      }
510
1.26k
  }
511
512
      /* So far only one block with sections.  */
513
5.06k
      elf->state.elf64.scns_last = &elf->state.elf64.scns;
514
5.06k
      eu_search_tree_init (&elf->state.elf64.rawchunk_tree);
515
5.06k
    }
516
517
15.0k
  return elf;
518
15.0k
}
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
92.5k
{
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
92.5k
  unsigned char *e_ident = (unsigned char *) map_address + offset;
531
532
  /* See what kind of object we have here.  */
533
92.5k
  Elf_Kind kind = determine_kind (e_ident, maxsize);
534
535
92.5k
  switch (kind)
536
92.5k
    {
537
15.1k
    case ELF_K_ELF:
538
15.1k
      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
539
15.1k
          cmd, parent);
540
541
72.3k
    case ELF_K_AR:
542
72.3k
      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
543
544
4.98k
    default:
545
4.98k
      break;
546
92.5k
    }
547
548
  /* This case is easy.  Since we cannot do anything with this file
549
     create a dummy descriptor.  */
550
4.98k
  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
551
4.98k
           ELF_K_NONE, 0);
552
92.5k
}
553
554
555
static Elf *
556
read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
557
        Elf *parent)
558
12
{
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
12
  union
571
12
  {
572
12
    Elf64_Ehdr ehdr;
573
12
    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
574
12
  } mem;
575
576
  /* Read the head of the file.  */
577
12
  ssize_t nread = pread_retry (fildes, mem.header,
578
12
             MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
579
12
            maxsize),
580
12
             offset);
581
12
  if (unlikely (nread == -1))
582
12
    {
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
      __libelf_seterrno (ELF_E_INVALID_FILE);
586
12
      return NULL;
587
12
    }
588
589
  /* See what kind of object we have here.  */
590
0
  Elf_Kind kind = determine_kind (mem.header, nread);
591
592
0
  switch (kind)
593
0
    {
594
0
    case ELF_K_AR:
595
0
      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
596
597
0
    case ELF_K_ELF:
598
      /* Make sure at least the ELF header is contained in the file.  */
599
0
      if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
600
0
           ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
601
0
  return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
602
0
            parent);
603
0
      FALLTHROUGH;
604
605
0
    default:
606
0
      break;
607
0
    }
608
609
  /* This case is easy.  Since we cannot do anything with this file
610
     create a dummy descriptor.  */
611
0
  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
612
0
           ELF_K_NONE, 0);
613
0
}
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
90.1k
{
621
90.1k
  void *map_address = NULL;
622
90.1k
  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
623
90.1k
      || cmd == ELF_C_WRITE_MMAP
624
90.1k
      || cmd == ELF_C_READ_MMAP_PRIVATE);
625
626
90.1k
  if (parent == NULL)
627
8.66k
    {
628
8.66k
      if (maxsize == ~((size_t) 0))
629
8.66k
  {
630
    /* We don't know in the moment how large the file is.
631
       Determine it now.  */
632
8.66k
    struct stat st;
633
634
8.66k
    if (fstat (fildes, &st) == 0
635
8.66k
        && (sizeof (size_t) >= sizeof (st.st_size)
636
0
      || st.st_size <= ~((size_t) 0)))
637
8.66k
      maxsize = (size_t) st.st_size;
638
8.66k
  }
639
8.66k
    }
640
81.5k
  else
641
81.5k
    {
642
      /* The parent is already loaded.  Use it.  */
643
81.5k
      assert (maxsize != ~((size_t) 0));
644
81.5k
    }
645
646
90.1k
  if (use_mmap)
647
90.1k
    {
648
90.1k
      if (parent == NULL)
649
8.66k
  {
650
    /* We try to map the file ourself.  */
651
8.66k
    map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
652
8.66k
                ? PROT_READ
653
8.66k
                : PROT_READ|PROT_WRITE),
654
8.66k
            cmd == ELF_C_READ_MMAP_PRIVATE
655
0
            || cmd == ELF_C_READ_MMAP
656
8.66k
            ? MAP_PRIVATE : MAP_SHARED,
657
8.66k
            fildes, offset);
658
659
8.66k
    if (map_address == MAP_FAILED)
660
12
      map_address = NULL;
661
8.66k
  }
662
81.5k
      else
663
81.5k
  {
664
81.5k
    map_address = parent->map_address;
665
81.5k
  }
666
90.1k
    }
667
668
  /* If we have the file in memory optimize the access.  */
669
90.1k
  if (map_address != NULL)
670
90.1k
    {
671
90.1k
      assert (map_address != MAP_FAILED);
672
673
90.1k
      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
674
90.1k
                  offset, maxsize, cmd,
675
90.1k
                  parent);
676
677
      /* If something went wrong during the initialization unmap the
678
   memory if we mmaped here.  */
679
90.1k
      if (result == NULL
680
101
    && (parent == NULL
681
23
        || parent->map_address != map_address))
682
78
  munmap (map_address, maxsize);
683
90.1k
      else if (parent == NULL)
684
  /* Remember that we mmap()ed the memory.  */
685
8.57k
  result->flags |= ELF_F_MMAPPED;
686
687
90.1k
      return result;
688
90.1k
    }
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
12
  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
693
90.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
842
{
700
842
  off_t offset = SARMAG; /* This is the first entry.  */
701
842
  struct ar_hdr hdrm;
702
842
  struct ar_hdr *hdr;
703
842
  char *newp;
704
842
  size_t len;
705
706
1.50k
  while (1)
707
1.50k
    {
708
1.50k
      if (elf->map_address != NULL)
709
1.50k
  {
710
1.50k
    if ((size_t) offset > elf->maximum_size
711
1.37k
        || elf->maximum_size - offset < sizeof (struct ar_hdr))
712
182
      return NULL;
713
714
    /* The data is mapped.  */
715
1.32k
    hdr = (struct ar_hdr *) (elf->map_address + offset);
716
1.32k
  }
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
1.32k
      char buf[sizeof (hdr->ar_size) + 1];
732
1.32k
      const char *string = hdr->ar_size;
733
1.32k
      if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
734
1.21k
  {
735
1.21k
    *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
736
1.21k
    string = buf;
737
1.21k
  }
738
739
      /* atol expects to see at least one digit.
740
   It also cannot be negative (-).  */
741
1.32k
      if (!isdigit(string[0]))
742
444
  return NULL;
743
880
      len = atol (string);
744
745
880
      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
746
216
  break;
747
748
664
      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
749
664
    }
750
751
  /* Sanity check len early if we can.  */
752
216
  if (elf->map_address != NULL)
753
216
    {
754
216
      if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
755
79
  return NULL;
756
216
    }
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
137
  newp = malloc (len);
762
137
  if (newp != NULL)
763
137
    {
764
137
      char *runp;
765
766
137
      if (elf->map_address != NULL)
767
137
  {
768
    /* Simply copy it over.  */
769
137
    elf->state.ar.long_names = (char *) memcpy (newp,
770
137
                  elf->map_address + offset
771
137
                  + sizeof (struct ar_hdr),
772
137
                  len);
773
137
  }
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
137
      elf->state.ar.long_names_len = len;
790
791
      /* Now NUL-terminate the strings.  */
792
137
      runp = newp;
793
437
      while (1)
794
437
        {
795
437
    char *startp = runp;
796
437
    runp = (char *) memchr (runp, '/', newp + len - runp);
797
437
    if (runp == NULL)
798
114
      {
799
        /* This was the last entry.  Clear any left overs.  */
800
114
        memset (startp, '\0', newp + len - startp);
801
114
        break;
802
114
      }
803
804
    /* NUL-terminate the string.  */
805
323
    *runp++ = '\0';
806
807
    /* A sanity check.  Somebody might have generated invalid
808
       archive.  */
809
323
    if (runp >= newp + len)
810
23
      break;
811
323
  }
812
137
    }
813
814
137
  return newp;
815
137
}
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
81.5k
{
822
81.5k
  Elf_Arhdr *hdr;
823
824
81.5k
  hdr = &ref->state.ar.cur_ar_hdr;
825
826
81.5k
  char *ar_name = hdr->ar_name;
827
81.5k
  char *ar_rawname = hdr->ar_rawname;
828
81.5k
  if (ar_name == NULL || ar_rawname == NULL)
829
161
    {
830
      /* ref doesn't have an Elf_Arhdr or it was marked as unusable.  */
831
161
      return 0;
832
161
    }
833
834
  /* Allocate copies of ar_name and ar_rawname.  */
835
81.3k
  size_t name_len = strlen (ar_name) + 1;
836
81.3k
  char *name_copy = malloc (MAX (name_len, 16));
837
81.3k
  if (name_copy == NULL)
838
0
    {
839
0
      __libelf_seterrno (ELF_E_NOMEM);
840
0
      return -1;
841
0
    }
842
81.3k
  memcpy (name_copy, ar_name, name_len);
843
844
81.3k
  size_t rawname_len = strlen (ar_rawname) + 1;
845
81.3k
  char *rawname_copy = malloc (MAX (rawname_len, 17));
846
81.3k
  if (rawname_copy == NULL)
847
0
    {
848
0
      free (name_copy);
849
0
      __libelf_seterrno (ELF_E_NOMEM);
850
0
      return -1;
851
0
    }
852
81.3k
  memcpy (rawname_copy, ar_rawname, rawname_len);
853
854
81.3k
  *dest = *hdr;
855
81.3k
  dest->ar_name = name_copy;
856
81.3k
  dest->ar_rawname = rawname_copy;
857
858
81.3k
  return 0;
859
81.3k
}
860
861
862
/* Read the next archive header.  */
863
int
864
internal_function
865
__libelf_next_arhdr_wrlock (Elf *elf)
866
85.5k
{
867
85.5k
  struct ar_hdr *ar_hdr;
868
85.5k
  Elf_Arhdr *elf_ar_hdr;
869
870
85.5k
  if (elf->map_address != NULL)
871
85.5k
    {
872
      /* See whether this entry is in the file.  */
873
85.5k
      if (unlikely ((size_t) elf->state.ar.offset
874
85.5k
        > elf->start_offset + elf->maximum_size
875
85.5k
        || (elf->start_offset + elf->maximum_size
876
85.5k
      - elf->state.ar.offset) < sizeof (struct ar_hdr)))
877
2.93k
  {
878
    /* This record is not anymore in the file.  */
879
2.93k
    __libelf_seterrno (ELF_E_RANGE);
880
2.93k
    return -1;
881
2.93k
  }
882
82.6k
      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
883
82.6k
    }
884
0
  else
885
0
    {
886
0
      ar_hdr = &elf->state.ar.ar_hdr;
887
888
0
      if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
889
0
         elf->state.ar.offset)
890
0
        != sizeof (struct ar_hdr)))
891
0
  {
892
    /* Something went wrong while reading the file.  */
893
0
    __libelf_seterrno (ELF_E_RANGE);
894
0
    return -1;
895
0
  }
896
0
    }
897
898
  /* One little consistency check.  */
899
82.6k
  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
900
279
    {
901
      /* This is no valid archive.  */
902
279
      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
903
279
      return -1;
904
279
    }
905
906
  /* Copy the raw name over to a NUL terminated buffer.  */
907
82.3k
  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
908
909
82.3k
  elf_ar_hdr = &elf->state.ar.cur_ar_hdr;
910
911
  /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
912
     Determine whether this is a special entry.  */
913
82.3k
  if (ar_hdr->ar_name[0] == '/')
914
1.73k
    {
915
1.73k
      if (ar_hdr->ar_name[1] == ' '
916
163
    && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
917
  /* This is the index.  */
918
138
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
919
1.59k
      else if (ar_hdr->ar_name[1] == 'S'
920
132
         && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
921
  /* 64-bit index.  */
922
92
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
923
1.50k
      else if (ar_hdr->ar_name[1] == '/'
924
527
         && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
925
  /* This is the array with the long names.  */
926
499
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
927
1.00k
      else if (likely  (isdigit (ar_hdr->ar_name[1])))
928
898
  {
929
898
    size_t offset;
930
931
    /* This is a long name.  First we have to read the long name
932
       table, if this hasn't happened already.  */
933
898
    if (unlikely (elf->state.ar.long_names == NULL
934
898
      && read_long_names (elf) == NULL))
935
705
      {
936
        /* No long name table although it is reference.  The archive is
937
     broken.  */
938
705
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
939
705
        return -1;
940
705
      }
941
942
193
    offset = atol (ar_hdr->ar_name + 1);
943
193
    if (unlikely (offset >= elf->state.ar.long_names_len))
944
102
      {
945
        /* The index in the long name table is larger than the table.  */
946
102
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
947
102
        return -1;
948
102
      }
949
91
    elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
950
91
  }
951
110
      else
952
110
  {
953
    /* This is none of the known special entries.  */
954
110
    __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
955
110
    return -1;
956
110
  }
957
1.73k
    }
958
80.5k
  else
959
80.5k
    {
960
80.5k
      char *endp;
961
962
      /* It is a normal entry.  Copy over the name.  */
963
80.5k
      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
964
80.5k
             '/', 16);
965
80.5k
      if (endp != NULL)
966
69.9k
  endp[-1] = '\0';
967
10.6k
      else
968
10.6k
  {
969
    /* In the old BSD style of archive, there is no / terminator.
970
       Instead, there is space padding at the end of the name.  */
971
10.6k
    size_t i = 15;
972
10.6k
    do
973
16.8k
      elf->state.ar.ar_name[i] = '\0';
974
16.8k
    while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
975
10.6k
  }
976
977
80.5k
      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
978
80.5k
    }
979
980
81.4k
  if (unlikely (ar_hdr->ar_size[0] == ' '))
981
    /* Something is really wrong.  We cannot live without a size for
982
       the member since it will not be possible to find the next
983
       archive member.  */
984
8
    {
985
8
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
986
8
      return -1;
987
8
    }
988
989
  /* Since there are no specialized functions to convert ASCII to
990
     time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
991
     atoll depending on the size of the types.  We are also prepared
992
     for the case where the whole field in the `struct ar_hdr' is
993
     filled in which case we cannot simply use atol/l but instead have
994
     to create a temporary copy.  Note that all fields use decimal
995
     encoding, except ar_mode which uses octal.  */
996
997
81.4k
#define INT_FIELD(FIELD)                  \
998
325k
  do                        \
999
325k
    {                       \
1000
325k
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1001
325k
      const char *string = ar_hdr->FIELD;             \
1002
325k
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1003
325k
  {                     \
1004
263k
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1005
263k
      = '\0';                   \
1006
263k
    string = buf;                   \
1007
263k
  }                      \
1008
325k
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1009
325k
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
1010
325k
      else                      \
1011
325k
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
1012
325k
    }                       \
1013
325k
  while (0)
1014
1015
81.4k
#define OCT_FIELD(FIELD)                  \
1016
81.4k
  do                        \
1017
81.4k
    {                       \
1018
81.4k
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1019
81.4k
      const char *string = ar_hdr->FIELD;             \
1020
81.4k
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1021
81.4k
  {                     \
1022
81.2k
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1023
81.2k
      = '\0';                   \
1024
81.2k
    string = buf;                   \
1025
81.2k
  }                      \
1026
81.4k
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1027
81.4k
  elf_ar_hdr->FIELD                 \
1028
81.4k
    = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8);       \
1029
81.4k
      else                      \
1030
81.4k
  elf_ar_hdr->FIELD                 \
1031
0
    = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8);       \
1032
81.4k
    }                       \
1033
81.4k
  while (0)
1034
1035
81.4k
  INT_FIELD (ar_date);
1036
81.4k
  INT_FIELD (ar_uid);
1037
81.4k
  INT_FIELD (ar_gid);
1038
81.4k
  OCT_FIELD (ar_mode);
1039
81.4k
  INT_FIELD (ar_size);
1040
1041
81.4k
  if (elf_ar_hdr->ar_size < 0)
1042
35
    {
1043
35
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
1044
35
      return -1;
1045
35
    }
1046
1047
  /* Truncated file?  */
1048
81.3k
  size_t maxsize;
1049
81.3k
  maxsize = (elf->start_offset + elf->maximum_size
1050
81.3k
       - elf->state.ar.offset - sizeof (struct ar_hdr));
1051
81.3k
  if ((size_t) elf_ar_hdr->ar_size > maxsize)
1052
70.6k
    elf_ar_hdr->ar_size = maxsize;
1053
1054
81.3k
  return 0;
1055
81.4k
}
1056
1057
1058
/* We were asked to return a clone of an existing descriptor.  This
1059
   function must be called with the lock on the parent descriptor
1060
   being held. */
1061
static Elf *
1062
dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1063
81.9k
{
1064
81.9k
  struct Elf *result;
1065
1066
81.9k
  if (fildes == -1)
1067
    /* Allow the user to pass -1 as the file descriptor for the new file.  */
1068
4.28k
    fildes = ref->fildes;
1069
  /* The file descriptor better should be the same.  If it was disconnected
1070
     already (using `elf_cntl') we do not test it.  */
1071
77.6k
  else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
1072
0
    {
1073
0
      __libelf_seterrno (ELF_E_FD_MISMATCH);
1074
0
      return NULL;
1075
0
    }
1076
1077
  /* The mode must allow reading.  I.e., a descriptor creating with a
1078
     command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
1079
     not allowed.  */
1080
81.9k
  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
1081
81.9k
    && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1082
81.9k
    && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1083
81.9k
    && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1084
0
    {
1085
0
      __libelf_seterrno (ELF_E_INVALID_OP);
1086
0
      return NULL;
1087
0
    }
1088
1089
  /* Now it is time to distinguish between reading normal files and
1090
     archives.  Normal files can easily be handled be incrementing the
1091
     reference counter and return the same descriptor.  */
1092
81.9k
  if (ref->kind != ELF_K_AR)
1093
0
    {
1094
0
      ++ref->ref_count;
1095
0
      return ref;
1096
0
    }
1097
1098
  /* This is an archive.  We must create a descriptor for the archive
1099
     member the internal pointer of the archive file descriptor is
1100
     pointing to.  First read the header of the next member if this
1101
     has not happened already.  */
1102
81.9k
  if (ref->state.ar.cur_ar_hdr.ar_name == NULL
1103
72.3k
      && __libelf_next_arhdr_wrlock (ref) != 0)
1104
    /* Something went wrong.  Maybe there is no member left.  */
1105
407
    return NULL;
1106
1107
  /* We have all the information we need about the next archive member.
1108
     Now create a descriptor for it. Check parent size can contain member.  */
1109
81.5k
  if (ref->state.ar.offset < ref->start_offset)
1110
0
    return NULL;
1111
81.5k
  size_t max_size = ref->maximum_size;
1112
81.5k
  size_t offset = (size_t) (ref->state.ar.offset - ref->start_offset);
1113
81.5k
  size_t hdr_size = sizeof (struct ar_hdr);
1114
81.5k
  size_t ar_size = (size_t) ref->state.ar.cur_ar_hdr.ar_size;
1115
81.5k
  if (max_size < hdr_size || max_size - hdr_size < offset)
1116
0
    return NULL;
1117
1118
81.5k
  Elf_Arhdr ar_hdr = {0};
1119
81.5k
  if (copy_arhdr (&ar_hdr, ref) != 0)
1120
    /* Out of memory.  */
1121
0
    return NULL;
1122
1123
81.5k
  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1124
81.5k
          MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
1125
1126
81.5k
  if (result != NULL)
1127
81.5k
    {
1128
      /* Enlist this new descriptor in the list of children.  */
1129
81.5k
      result->next = ref->state.ar.children;
1130
81.5k
      ref->state.ar.children = result;
1131
1132
81.5k
      result->elf_ar_hdr = ar_hdr;
1133
81.5k
    }
1134
23
  else
1135
23
    {
1136
23
      free (ar_hdr.ar_name);
1137
23
      free (ar_hdr.ar_rawname);
1138
23
    }
1139
1140
81.5k
  return result;
1141
81.5k
}
1142
1143
1144
/* Return descriptor for empty file ready for writing.  */
1145
static struct Elf *
1146
write_file (int fd, Elf_Cmd cmd)
1147
0
{
1148
  /* We simply create an empty `Elf' structure.  */
1149
0
#define NSCNSALLOC  10
1150
0
  Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
1151
0
            NSCNSALLOC * sizeof (Elf_Scn));
1152
1153
0
  if (result != NULL)
1154
0
    {
1155
      /* We have to write to the file in any case.  */
1156
0
      result->flags = ELF_F_DIRTY;
1157
1158
      /* Some more or less arbitrary value.  */
1159
0
      result->state.elf.scnincr = NSCNSALLOC;
1160
1161
      /* We have allocated room for some sections.  */
1162
0
      assert (offsetof (struct Elf, state.elf32.scns)
1163
0
        == offsetof (struct Elf, state.elf64.scns));
1164
0
      result->state.elf.scns_last = &result->state.elf32.scns;
1165
0
      result->state.elf32.scns.max = NSCNSALLOC;
1166
0
    }
1167
1168
0
  return result;
1169
0
}
1170
1171
/* Lock if necessary before dup an archive.  */
1172
static inline Elf *
1173
lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
1174
81.9k
{
1175
  /* We need wrlock to dup an archive.  */
1176
81.9k
  if (ref->kind == ELF_K_AR)
1177
81.9k
    {
1178
81.9k
      rwlock_unlock (ref->lock);
1179
81.9k
      rwlock_wrlock (ref->lock);
1180
81.9k
    }
1181
    /* Duplicate the descriptor.  */
1182
81.9k
  return dup_elf (fildes, cmd, ref);
1183
81.9k
}
1184
1185
/* Return a descriptor for the file belonging to FILDES.  */
1186
Elf *
1187
elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1188
90.6k
{
1189
90.6k
  Elf *retval;
1190
1191
90.6k
  if (unlikely (__libelf_version != EV_CURRENT))
1192
0
    {
1193
      /* Version wasn't set so far.  */
1194
0
      __libelf_seterrno (ELF_E_NO_VERSION);
1195
0
      return NULL;
1196
0
    }
1197
1198
90.6k
  if (ref != NULL)
1199
    /* Make sure the descriptor is not suddenly going away.  */
1200
81.9k
    rwlock_rdlock (ref->lock);
1201
8.66k
  else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
1202
0
    {
1203
      /* We cannot do anything productive without a file descriptor.  */
1204
0
      __libelf_seterrno (ELF_E_INVALID_FILE);
1205
0
      return NULL;
1206
0
    }
1207
1208
90.6k
  switch (cmd)
1209
90.6k
    {
1210
0
    case ELF_C_NULL:
1211
      /* We simply return a NULL pointer.  */
1212
0
      retval = NULL;
1213
0
      break;
1214
1215
90.6k
    case ELF_C_READ_MMAP_PRIVATE:
1216
      /* If we have a reference it must also be opened this way.  */
1217
90.6k
      if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1218
0
  {
1219
0
    __libelf_seterrno (ELF_E_INVALID_CMD);
1220
0
    retval = NULL;
1221
0
    break;
1222
0
  }
1223
90.6k
      FALLTHROUGH;
1224
1225
90.6k
    case ELF_C_READ:
1226
90.6k
    case ELF_C_READ_MMAP:
1227
90.6k
      if (ref != NULL)
1228
81.9k
  retval = lock_dup_elf (fildes, cmd, ref);
1229
8.66k
      else
1230
  /* Create descriptor for existing file.  */
1231
8.66k
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1232
90.6k
      break;
1233
1234
0
    case ELF_C_RDWR:
1235
0
    case ELF_C_RDWR_MMAP:
1236
      /* If we have a REF object it must also be opened using this
1237
   command.  */
1238
0
      if (ref != NULL)
1239
0
  {
1240
0
    if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1241
0
      && ref->cmd != ELF_C_WRITE
1242
0
      && ref->cmd != ELF_C_WRITE_MMAP))
1243
0
      {
1244
        /* This is not ok.  REF must also be opened for writing.  */
1245
0
        __libelf_seterrno (ELF_E_INVALID_CMD);
1246
0
        retval = NULL;
1247
0
      }
1248
0
    else
1249
0
      retval = lock_dup_elf (fildes, cmd, ref);
1250
0
  }
1251
0
      else
1252
  /* Create descriptor for existing file.  */
1253
0
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1254
0
      break;
1255
1256
0
    case ELF_C_WRITE:
1257
0
    case ELF_C_WRITE_MMAP:
1258
      /* We ignore REF and prepare a descriptor to write a new file.  */
1259
0
      retval = write_file (fildes, cmd);
1260
0
      break;
1261
1262
0
    default:
1263
0
      __libelf_seterrno (ELF_E_INVALID_CMD);
1264
0
      retval = NULL;
1265
0
      break;
1266
90.6k
    }
1267
1268
  /* Release the lock.  */
1269
90.6k
  if (ref != NULL)
1270
81.9k
    rwlock_unlock (ref->lock);
1271
1272
90.6k
  return retval;
1273
90.6k
}
1274
INTDEF(elf_begin)