Coverage Report

Created: 2026-02-14 06:24

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
157k
{
54
157k
  Elf *elf;
55
56
  /* Create a descriptor.  */
57
157k
  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
58
157k
                      ELF_K_AR, 0);
59
157k
  if (elf != NULL)
60
157k
    {
61
      /* We don't read all the symbol tables in advance.  All this will
62
   happen on demand.  */
63
157k
      elf->state.ar.offset = offset + SARMAG;
64
65
157k
      elf->state.ar.cur_ar_hdr.ar_rawname = elf->state.ar.raw_name;
66
157k
    }
67
68
157k
  return elf;
69
157k
}
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
68.4k
{
76
68.4k
  size_t result;
77
68.4k
  union
78
68.4k
  {
79
68.4k
    Elf32_Ehdr *e32;
80
68.4k
    Elf64_Ehdr *e64;
81
68.4k
    void *p;
82
68.4k
  } ehdr;
83
68.4k
  union
84
68.4k
  {
85
68.4k
    Elf32_Ehdr e32;
86
68.4k
    Elf64_Ehdr e64;
87
68.4k
  } ehdr_mem;
88
68.4k
  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
89
90
68.4k
  if ((is32 && maxsize < sizeof (Elf32_Ehdr))
91
68.2k
      || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
92
493
    {
93
493
       __libelf_seterrno (ELF_E_INVALID_ELF);
94
493
      return (size_t) -1l;
95
493
    }
96
97
  /* Make the ELF header available.  */
98
67.9k
  if (e_ident[EI_DATA] == MY_ELFDATA
99
35.9k
      && (ALLOW_UNALIGNED
100
0
    || (((size_t) e_ident
101
0
         & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
102
0
      - 1)) == 0)))
103
35.9k
    ehdr.p = e_ident;
104
31.9k
  else
105
31.9k
    {
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
31.9k
      ehdr.p = &ehdr_mem;
110
111
31.9k
      if (is32)
112
26.8k
  {
113
26.8k
    if (ALLOW_UNALIGNED)
114
26.8k
      {
115
26.8k
        ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
116
26.8k
        ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
117
26.8k
      }
118
0
    else
119
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
120
121
26.8k
    if (e_ident[EI_DATA] != MY_ELFDATA)
122
26.8k
      {
123
26.8k
        CONVERT (ehdr_mem.e32.e_shnum);
124
26.8k
        CONVERT (ehdr_mem.e32.e_shoff);
125
26.8k
      }
126
26.8k
  }
127
5.16k
      else
128
5.16k
  {
129
5.16k
    if (ALLOW_UNALIGNED)
130
5.16k
      {
131
5.16k
        ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
132
5.16k
        ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
133
5.16k
      }
134
0
    else
135
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
136
137
5.16k
    if (e_ident[EI_DATA] != MY_ELFDATA)
138
5.16k
      {
139
5.16k
        CONVERT (ehdr_mem.e64.e_shnum);
140
5.16k
        CONVERT (ehdr_mem.e64.e_shoff);
141
5.16k
      }
142
5.16k
  }
143
31.9k
    }
144
145
67.9k
  if (is32)
146
49.0k
    {
147
      /* Get the number of sections from the ELF header.  */
148
49.0k
      result = ehdr.e32->e_shnum;
149
150
49.0k
      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
151
9.75k
  {
152
9.75k
    if (unlikely (ehdr.e32->e_shoff >= maxsize)
153
5.09k
        || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
154
      /* Cannot read the first section header.  */
155
6.00k
      return 0;
156
157
3.75k
    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
1.37k
      result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
164
1.37k
              + offset))->sh_size;
165
2.37k
    else
166
2.37k
      {
167
2.37k
        Elf32_Word size;
168
2.37k
        ssize_t r;
169
170
2.37k
        if (likely (map_address != NULL))
171
    /* gcc will optimize the memcpy to a simple memory
172
       access while taking care of alignment issues.  */
173
1.80k
    memcpy (&size, ((char *) map_address
174
1.80k
           + ehdr.e32->e_shoff
175
1.80k
           + offset
176
1.80k
           + offsetof (Elf32_Shdr, sh_size)),
177
1.80k
      sizeof (Elf32_Word));
178
570
        else
179
570
    if (unlikely ((r = pread_retry (fildes, &size,
180
570
            sizeof (Elf32_Word),
181
570
            offset + ehdr.e32->e_shoff
182
570
            + offsetof (Elf32_Shdr,
183
570
                  sh_size)))
184
570
            != 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
2.37k
        if (e_ident[EI_DATA] != MY_ELFDATA)
194
1.88k
    CONVERT (size);
195
196
2.37k
        result = size;
197
2.37k
      }
198
3.75k
  }
199
200
      /* If the section headers were truncated, pretend none were there.  */
201
43.0k
      if (ehdr.e32->e_shoff > maxsize
202
34.0k
    || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
203
15.4k
  result = 0;
204
43.0k
    }
205
18.9k
  else
206
18.9k
    {
207
      /* Get the number of sections from the ELF header.  */
208
18.9k
      result = ehdr.e64->e_shnum;
209
210
18.9k
      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
211
5.03k
  {
212
5.03k
    if (unlikely (ehdr.e64->e_shoff >= maxsize)
213
2.41k
        || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
214
      /* Cannot read the first section header.  */
215
3.01k
      return 0;
216
217
2.02k
    Elf64_Xword size;
218
2.02k
    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
1.15k
      size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
225
1.15k
            + offset))->sh_size;
226
874
    else
227
874
      {
228
874
        ssize_t r;
229
874
        if (likely (map_address != NULL))
230
    /* gcc will optimize the memcpy to a simple memory
231
       access while taking care of alignment issues.  */
232
532
    memcpy (&size, ((char *) map_address
233
532
           + ehdr.e64->e_shoff
234
532
           + offset
235
532
           + offsetof (Elf64_Shdr, sh_size)),
236
532
      sizeof (Elf64_Xword));
237
342
        else
238
342
    if (unlikely ((r = pread_retry (fildes, &size,
239
342
            sizeof (Elf64_Xword),
240
342
            offset + ehdr.e64->e_shoff
241
342
            + offsetof (Elf64_Shdr,
242
342
                  sh_size)))
243
342
            != 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
874
        if (e_ident[EI_DATA] != MY_ELFDATA)
253
781
    CONVERT (size);
254
874
      }
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
2.02k
    if (size > ~((GElf_Word) 0))
260
685
      {
261
        /* Invalid value, it is too large.  */
262
685
        __libelf_seterrno (ELF_E_INVALID_ELF);
263
685
        return (size_t) -1l;
264
685
      }
265
266
1.33k
    result = size;
267
1.33k
  }
268
269
      /* If the section headers were truncated, pretend none were there.  */
270
15.2k
      if (ehdr.e64->e_shoff > maxsize
271
9.88k
    || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
272
7.02k
  result = 0;
273
15.2k
    }
274
275
58.2k
  return result;
276
67.9k
}
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
68.4k
{
284
  /* Verify the binary is of the class we can handle.  */
285
68.4k
  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
286
68.4k
     && e_ident[EI_CLASS] != ELFCLASS64)
287
    /* We also can only handle two encodings.  */
288
68.4k
    || (e_ident[EI_DATA] != ELFDATA2LSB
289
68.4k
        && 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
68.4k
  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
300
68.4k
  if (scncnt == (size_t) -1l)
301
    /* Could not determine the number of sections.  */
302
1.17k
    return NULL;
303
304
  /* Check for too many sections.  */
305
67.2k
  if (e_ident[EI_CLASS] == ELFCLASS32)
306
49.0k
    {
307
49.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
49.0k
    }
313
18.2k
  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
67.2k
  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
322
35.0k
       ? 1 : 0);
323
67.2k
  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
324
67.2k
         ELF_K_ELF, scnmax * sizeof (Elf_Scn));
325
67.2k
  if (elf == NULL)
326
    /* Not enough memory.  allocate_elf will have set libelf errno.  */
327
0
    return NULL;
328
329
67.2k
  assert ((unsigned int) scncnt == scncnt);
330
67.2k
  assert (offsetof (struct Elf, state.elf32.scns)
331
67.2k
    == offsetof (struct Elf, state.elf64.scns));
332
67.2k
  elf->state.elf32.scns.cnt = scncnt;
333
67.2k
  elf->state.elf32.scns.max = scnmax;
334
335
  /* Some more or less arbitrary value.  */
336
67.2k
  elf->state.elf.scnincr = 10;
337
338
  /* Make the class easily available.  */
339
67.2k
  elf->class = e_ident[EI_CLASS];
340
341
67.2k
  if (e_ident[EI_CLASS] == ELFCLASS32)
342
49.0k
    {
343
      /* This pointer might not be directly usable if the alignment is
344
   not sufficient for the architecture.  */
345
49.0k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
346
347
      /* This is a 32-bit binary.  */
348
49.0k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
349
0
    && (ALLOW_UNALIGNED
350
0
        || (ehdr & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
351
16.1k
  {
352
    /* We can use the mmapped memory.  */
353
16.1k
    elf->state.elf32.ehdr = (Elf32_Ehdr *) ehdr;
354
16.1k
  }
355
32.8k
      else
356
32.8k
  {
357
    /* Copy the ELF header.  */
358
32.8k
    elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
359
32.8k
            sizeof (Elf32_Ehdr));
360
361
32.8k
    if (e_ident[EI_DATA] != MY_ELFDATA)
362
26.8k
      {
363
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_type);
364
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_machine);
365
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_version);
366
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_entry);
367
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
368
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
369
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_flags);
370
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
371
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
372
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
373
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
374
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
375
26.8k
        CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
376
26.8k
      }
377
32.8k
  }
378
379
      /* Don't precache the phdr pointer here.
380
   elf32_getphdr will validate it against the size when asked.  */
381
382
49.0k
      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
383
49.0k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
384
16.1k
    && 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
11.5k
  {
388
11.5k
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
389
11.5k
        || unlikely (maxsize - e_shoff
390
11.5k
         < 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
11.5k
    if (scncnt > 0)
399
4.63k
      elf->state.elf32.shdr = (Elf32_Shdr *) (ehdr + e_shoff);
400
401
3.12M
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
402
3.11M
      {
403
3.11M
        elf->state.elf32.scns.data[cnt].index = cnt;
404
3.11M
        elf->state.elf32.scns.data[cnt].elf = elf;
405
3.11M
        elf->state.elf32.scns.data[cnt].shdr.e32 =
406
3.11M
    &elf->state.elf32.shdr[cnt];
407
3.11M
        if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
408
1.15M
      && likely (elf->state.elf32.shdr[cnt].sh_size
409
3.11M
           <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
410
987k
    elf->state.elf32.scns.data[cnt].rawdata_base =
411
987k
      elf->state.elf32.scns.data[cnt].data_base =
412
987k
      ((char *) map_address + offset
413
987k
       + elf->state.elf32.shdr[cnt].sh_offset);
414
3.11M
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
415
3.11M
      }
416
11.5k
  }
417
37.5k
      else
418
37.5k
  {
419
5.21M
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
420
5.17M
      {
421
5.17M
        elf->state.elf32.scns.data[cnt].index = cnt;
422
5.17M
        elf->state.elf32.scns.data[cnt].elf = elf;
423
5.17M
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
424
5.17M
      }
425
37.5k
  }
426
427
      /* So far only one block with sections.  */
428
49.0k
      elf->state.elf32.scns_last = &elf->state.elf32.scns;
429
49.0k
      eu_search_tree_init (&elf->state.elf32.rawchunk_tree);
430
49.0k
    }
431
18.2k
  else
432
18.2k
    {
433
      /* This pointer might not be directly usable if the alignment is
434
   not sufficient for the architecture.  */
435
18.2k
      uintptr_t ehdr = (uintptr_t) map_address + offset;
436
437
      /* This is a 64-bit binary.  */
438
18.2k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
439
0
    && (ALLOW_UNALIGNED
440
0
        || (ehdr & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
441
11.0k
  {
442
    /* We can use the mmapped memory.  */
443
11.0k
    elf->state.elf64.ehdr = (Elf64_Ehdr *) ehdr;
444
11.0k
  }
445
7.18k
      else
446
7.18k
  {
447
    /* Copy the ELF header.  */
448
7.18k
    elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
449
7.18k
            sizeof (Elf64_Ehdr));
450
451
7.18k
    if (e_ident[EI_DATA] != MY_ELFDATA)
452
4.85k
      {
453
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_type);
454
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_machine);
455
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_version);
456
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_entry);
457
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
458
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
459
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_flags);
460
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
461
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
462
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
463
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
464
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
465
4.85k
        CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
466
4.85k
      }
467
7.18k
  }
468
469
      /* Don't precache the phdr pointer here.
470
   elf64_getphdr will validate it against the size when asked.  */
471
472
18.2k
      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
473
18.2k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
474
11.0k
    && 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
6.78k
  {
478
6.78k
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
479
6.78k
        || unlikely (maxsize - e_shoff
480
6.78k
         < scncnt * sizeof (Elf64_Shdr)))
481
0
      goto free_and_out;
482
483
6.78k
    if (scncnt > 0)
484
1.27k
      elf->state.elf64.shdr = (Elf64_Shdr *) (ehdr + (ptrdiff_t) e_shoff);
485
486
76.0k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
487
69.2k
      {
488
69.2k
        elf->state.elf64.scns.data[cnt].index = cnt;
489
69.2k
        elf->state.elf64.scns.data[cnt].elf = elf;
490
69.2k
        elf->state.elf64.scns.data[cnt].shdr.e64 =
491
69.2k
    &elf->state.elf64.shdr[cnt];
492
69.2k
        if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
493
29.3k
      && likely (elf->state.elf64.shdr[cnt].sh_size
494
69.2k
           <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
495
24.5k
    elf->state.elf64.scns.data[cnt].rawdata_base =
496
24.5k
      elf->state.elf64.scns.data[cnt].data_base =
497
24.5k
      ((char *) map_address + offset
498
24.5k
       + elf->state.elf64.shdr[cnt].sh_offset);
499
69.2k
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
500
69.2k
      }
501
6.78k
  }
502
11.4k
      else
503
11.4k
  {
504
1.92M
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
505
1.90M
      {
506
1.90M
        elf->state.elf64.scns.data[cnt].index = cnt;
507
1.90M
        elf->state.elf64.scns.data[cnt].elf = elf;
508
1.90M
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
509
1.90M
      }
510
11.4k
  }
511
512
      /* So far only one block with sections.  */
513
18.2k
      elf->state.elf64.scns_last = &elf->state.elf64.scns;
514
18.2k
      eu_search_tree_init (&elf->state.elf64.rawchunk_tree);
515
18.2k
    }
516
517
67.2k
  return elf;
518
67.2k
}
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
217k
{
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
217k
  unsigned char *e_ident = (unsigned char *) map_address + offset;
531
532
  /* See what kind of object we have here.  */
533
217k
  Elf_Kind kind = determine_kind (e_ident, maxsize);
534
535
217k
  switch (kind)
536
217k
    {
537
50.5k
    case ELF_K_ELF:
538
50.5k
      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
539
50.5k
          cmd, parent);
540
541
157k
    case ELF_K_AR:
542
157k
      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
543
544
9.80k
    default:
545
9.80k
      break;
546
217k
    }
547
548
  /* This case is easy.  Since we cannot do anything with this file
549
     create a dummy descriptor.  */
550
9.80k
  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
551
9.80k
           ELF_K_NONE, 0);
552
217k
}
553
554
555
static Elf *
556
read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
557
        Elf *parent)
558
31.2k
{
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
31.2k
  union
571
31.2k
  {
572
31.2k
    Elf64_Ehdr ehdr;
573
31.2k
    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
574
31.2k
  } mem;
575
576
  /* Read the head of the file.  */
577
31.2k
  ssize_t nread = pread_retry (fildes, mem.header,
578
31.2k
             MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
579
31.2k
            maxsize),
580
31.2k
             offset);
581
31.2k
  if (unlikely (nread == -1))
582
12.8k
    {
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.8k
      __libelf_seterrno (ELF_E_INVALID_FILE);
586
12.8k
      return NULL;
587
12.8k
    }
588
589
  /* See what kind of object we have here.  */
590
18.4k
  Elf_Kind kind = determine_kind (mem.header, nread);
591
592
18.4k
  switch (kind)
593
18.4k
    {
594
3
    case ELF_K_AR:
595
3
      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
596
597
18.0k
    case ELF_K_ELF:
598
      /* Make sure at least the ELF header is contained in the file.  */
599
18.0k
      if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
600
18.0k
           ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
601
17.9k
  return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
602
17.9k
            parent);
603
63
      FALLTHROUGH;
604
605
462
    default:
606
462
      break;
607
18.4k
    }
608
609
  /* This case is easy.  Since we cannot do anything with this file
610
     create a dummy descriptor.  */
611
462
  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
612
462
           ELF_K_NONE, 0);
613
18.4k
}
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
232k
{
621
232k
  void *map_address = NULL;
622
232k
  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
623
202k
      || cmd == ELF_C_WRITE_MMAP
624
202k
      || cmd == ELF_C_READ_MMAP_PRIVATE);
625
626
232k
  if (parent == NULL)
627
64.2k
    {
628
64.2k
      if (maxsize == ~((size_t) 0))
629
64.2k
  {
630
    /* We don't know in the moment how large the file is.
631
       Determine it now.  */
632
64.2k
    struct stat st;
633
634
64.2k
    if (fstat (fildes, &st) == 0
635
64.2k
        && (sizeof (size_t) >= sizeof (st.st_size)
636
0
      || st.st_size <= ~((size_t) 0)))
637
64.2k
      maxsize = (size_t) st.st_size;
638
64.2k
  }
639
64.2k
    }
640
168k
  else
641
168k
    {
642
      /* The parent is already loaded.  Use it.  */
643
168k
      assert (maxsize != ~((size_t) 0));
644
168k
    }
645
646
232k
  if (use_mmap)
647
208k
    {
648
208k
      if (parent == NULL)
649
39.6k
  {
650
    /* We try to map the file ourself.  */
651
39.6k
    map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
652
39.6k
                ? PROT_READ
653
39.6k
                : PROT_READ|PROT_WRITE),
654
39.6k
            cmd == ELF_C_READ_MMAP_PRIVATE
655
29.8k
            || cmd == ELF_C_READ_MMAP
656
39.6k
            ? MAP_PRIVATE : MAP_SHARED,
657
39.6k
            fildes, offset);
658
659
39.6k
    if (map_address == MAP_FAILED)
660
6.71k
      map_address = NULL;
661
39.6k
  }
662
168k
      else
663
168k
  {
664
168k
    map_address = parent->map_address;
665
168k
  }
666
208k
    }
667
668
  /* If we have the file in memory optimize the access.  */
669
232k
  if (map_address != NULL)
670
201k
    {
671
201k
      assert (map_address != MAP_FAILED);
672
673
201k
      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
674
201k
                  offset, maxsize, cmd,
675
201k
                  parent);
676
677
      /* If something went wrong during the initialization unmap the
678
   memory if we mmaped here.  */
679
201k
      if (result == NULL
680
232
    && (parent == NULL
681
17
        || parent->map_address != map_address))
682
215
  munmap (map_address, maxsize);
683
201k
      else if (parent == NULL)
684
  /* Remember that we mmap()ed the memory.  */
685
32.7k
  result->flags |= ELF_F_MMAPPED;
686
687
201k
      return result;
688
201k
    }
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
31.2k
  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
693
232k
}
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
983
{
700
983
  off_t offset = SARMAG; /* This is the first entry.  */
701
983
  struct ar_hdr hdrm;
702
983
  struct ar_hdr *hdr;
703
983
  char *newp;
704
983
  size_t len;
705
706
1.56k
  while (1)
707
1.56k
    {
708
1.56k
      if (elf->map_address != NULL)
709
1.56k
  {
710
1.56k
    if ((size_t) offset > elf->maximum_size
711
1.43k
        || elf->maximum_size - offset < sizeof (struct ar_hdr))
712
202
      return NULL;
713
714
    /* The data is mapped.  */
715
1.36k
    hdr = (struct ar_hdr *) (elf->map_address + offset);
716
1.36k
  }
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.36k
      char buf[sizeof (hdr->ar_size) + 1];
732
1.36k
      const char *string = hdr->ar_size;
733
1.36k
      if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
734
1.35k
  {
735
1.35k
    *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
736
1.35k
    string = buf;
737
1.35k
  }
738
739
      /* atol expects to see at least one digit.
740
   It also cannot be negative (-).  */
741
1.36k
      if (!isdigit(string[0]))
742
500
  return NULL;
743
866
      len = atol (string);
744
745
866
      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
746
281
  break;
747
748
585
      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
749
585
    }
750
751
  /* Sanity check len early if we can.  */
752
281
  if (elf->map_address != NULL)
753
281
    {
754
281
      if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
755
127
  return NULL;
756
281
    }
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
154
  newp = malloc (len);
762
154
  if (newp != NULL)
763
154
    {
764
154
      char *runp;
765
766
154
      if (elf->map_address != NULL)
767
154
  {
768
    /* Simply copy it over.  */
769
154
    elf->state.ar.long_names = (char *) memcpy (newp,
770
154
                  elf->map_address + offset
771
154
                  + sizeof (struct ar_hdr),
772
154
                  len);
773
154
  }
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
154
      elf->state.ar.long_names_len = len;
790
791
      /* Now NUL-terminate the strings.  */
792
154
      runp = newp;
793
919k
      while (1)
794
919k
        {
795
919k
    char *startp = runp;
796
919k
    runp = (char *) memchr (runp, '/', newp + len - runp);
797
919k
    if (runp == NULL)
798
135
      {
799
        /* This was the last entry.  Clear any left overs.  */
800
135
        memset (startp, '\0', newp + len - startp);
801
135
        break;
802
135
      }
803
804
    /* NUL-terminate the string.  */
805
919k
    *runp++ = '\0';
806
807
    /* A sanity check.  Somebody might have generated invalid
808
       archive.  */
809
919k
    if (runp >= newp + len)
810
19
      break;
811
919k
  }
812
154
    }
813
814
154
  return newp;
815
154
}
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
168k
{
822
168k
  Elf_Arhdr *hdr;
823
824
168k
  hdr = &ref->state.ar.cur_ar_hdr;
825
826
168k
  char *ar_name = hdr->ar_name;
827
168k
  char *ar_rawname = hdr->ar_rawname;
828
168k
  if (ar_name == NULL || ar_rawname == NULL)
829
165
    {
830
      /* ref doesn't have an Elf_Arhdr or it was marked as unusable.  */
831
165
      return 0;
832
165
    }
833
834
  /* Allocate copies of ar_name and ar_rawname.  */
835
168k
  size_t name_len = strlen (ar_name) + 1;
836
168k
  char *name_copy = malloc (MAX (name_len, 16));
837
168k
  if (name_copy == NULL)
838
0
    {
839
0
      __libelf_seterrno (ELF_E_NOMEM);
840
0
      return -1;
841
0
    }
842
168k
  memcpy (name_copy, ar_name, name_len);
843
844
168k
  size_t rawname_len = strlen (ar_rawname) + 1;
845
168k
  char *rawname_copy = malloc (MAX (rawname_len, 17));
846
168k
  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
168k
  memcpy (rawname_copy, ar_rawname, rawname_len);
853
854
168k
  *dest = *hdr;
855
168k
  dest->ar_name = name_copy;
856
168k
  dest->ar_rawname = rawname_copy;
857
858
168k
  return 0;
859
168k
}
860
861
862
/* Read the next archive header.  */
863
int
864
internal_function
865
__libelf_next_arhdr_wrlock (Elf *elf)
866
174k
{
867
174k
  struct ar_hdr *ar_hdr;
868
174k
  Elf_Arhdr *elf_ar_hdr;
869
870
174k
  if (elf->map_address != NULL)
871
174k
    {
872
      /* See whether this entry is in the file.  */
873
174k
      if (unlikely ((size_t) elf->state.ar.offset
874
174k
        > elf->start_offset + elf->maximum_size
875
174k
        || (elf->start_offset + elf->maximum_size
876
174k
      - elf->state.ar.offset) < sizeof (struct ar_hdr)))
877
5.21k
  {
878
    /* This record is not anymore in the file.  */
879
5.21k
    __libelf_seterrno (ELF_E_RANGE);
880
5.21k
    return -1;
881
5.21k
  }
882
169k
      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
883
169k
    }
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
169k
  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
900
291
    {
901
      /* This is no valid archive.  */
902
291
      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
903
291
      return -1;
904
291
    }
905
906
  /* Copy the raw name over to a NUL terminated buffer.  */
907
169k
  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
908
909
169k
  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
169k
  if (ar_hdr->ar_name[0] == '/')
914
1.71k
    {
915
1.71k
      if (ar_hdr->ar_name[1] == ' '
916
211
    && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
917
  /* This is the index.  */
918
193
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
919
1.51k
      else if (ar_hdr->ar_name[1] == 'S'
920
94
         && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
921
  /* 64-bit index.  */
922
61
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
923
1.45k
      else if (ar_hdr->ar_name[1] == '/'
924
329
         && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
925
  /* This is the array with the long names.  */
926
293
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
927
1.16k
      else if (likely  (isdigit (ar_hdr->ar_name[1])))
928
1.06k
  {
929
1.06k
    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
1.06k
    if (unlikely (elf->state.ar.long_names == NULL
934
1.06k
      && read_long_names (elf) == NULL))
935
829
      {
936
        /* No long name table although it is reference.  The archive is
937
     broken.  */
938
829
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
939
829
        return -1;
940
829
      }
941
942
240
    offset = atol (ar_hdr->ar_name + 1);
943
240
    if (unlikely (offset >= elf->state.ar.long_names_len))
944
95
      {
945
        /* The index in the long name table is larger than the table.  */
946
95
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
947
95
        return -1;
948
95
      }
949
145
    elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
950
145
  }
951
96
      else
952
96
  {
953
    /* This is none of the known special entries.  */
954
96
    __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
955
96
    return -1;
956
96
  }
957
1.71k
    }
958
167k
  else
959
167k
    {
960
167k
      char *endp;
961
962
      /* It is a normal entry.  Copy over the name.  */
963
167k
      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
964
167k
             '/', 16);
965
167k
      if (endp != NULL)
966
154k
  endp[-1] = '\0';
967
13.0k
      else
968
13.0k
  {
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
13.0k
    size_t i = 15;
972
13.0k
    do
973
22.3k
      elf->state.ar.ar_name[i] = '\0';
974
22.3k
    while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
975
13.0k
  }
976
977
167k
      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
978
167k
    }
979
980
168k
  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
10
    {
985
10
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
986
10
      return -1;
987
10
    }
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
168k
#define INT_FIELD(FIELD)                  \
998
673k
  do                        \
999
673k
    {                       \
1000
673k
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1001
673k
      const char *string = ar_hdr->FIELD;             \
1002
673k
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1003
673k
  {                     \
1004
539k
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1005
539k
      = '\0';                   \
1006
539k
    string = buf;                   \
1007
539k
  }                      \
1008
673k
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1009
673k
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
1010
673k
      else                      \
1011
673k
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
1012
673k
    }                       \
1013
673k
  while (0)
1014
1015
168k
#define OCT_FIELD(FIELD)                  \
1016
168k
  do                        \
1017
168k
    {                       \
1018
168k
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1019
168k
      const char *string = ar_hdr->FIELD;             \
1020
168k
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1021
168k
  {                     \
1022
168k
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1023
168k
      = '\0';                   \
1024
168k
    string = buf;                   \
1025
168k
  }                      \
1026
168k
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1027
168k
  elf_ar_hdr->FIELD                 \
1028
168k
    = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8);       \
1029
168k
      else                      \
1030
168k
  elf_ar_hdr->FIELD                 \
1031
0
    = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8);       \
1032
168k
    }                       \
1033
168k
  while (0)
1034
1035
168k
  INT_FIELD (ar_date);
1036
168k
  INT_FIELD (ar_uid);
1037
168k
  INT_FIELD (ar_gid);
1038
168k
  OCT_FIELD (ar_mode);
1039
168k
  INT_FIELD (ar_size);
1040
1041
168k
  if (elf_ar_hdr->ar_size < 0)
1042
10
    {
1043
10
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
1044
10
      return -1;
1045
10
    }
1046
1047
  /* Truncated file?  */
1048
168k
  size_t maxsize;
1049
168k
  maxsize = (elf->start_offset + elf->maximum_size
1050
168k
       - elf->state.ar.offset - sizeof (struct ar_hdr));
1051
168k
  if ((size_t) elf_ar_hdr->ar_size > maxsize)
1052
155k
    elf_ar_hdr->ar_size = maxsize;
1053
1054
168k
  return 0;
1055
168k
}
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
168k
{
1064
168k
  struct Elf *result;
1065
1066
168k
  if (fildes == -1)
1067
    /* Allow the user to pass -1 as the file descriptor for the new file.  */
1068
3.90k
    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
164k
  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
168k
  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
1081
168k
    && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1082
168k
    && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1083
168k
    && 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
168k
  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
168k
  if (ref->state.ar.cur_ar_hdr.ar_name == NULL
1103
157k
      && __libelf_next_arhdr_wrlock (ref) != 0)
1104
    /* Something went wrong.  Maybe there is no member left.  */
1105
332
    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
168k
  if (ref->state.ar.offset < ref->start_offset)
1110
0
    return NULL;
1111
168k
  size_t max_size = ref->maximum_size;
1112
168k
  size_t offset = (size_t) (ref->state.ar.offset - ref->start_offset);
1113
168k
  size_t hdr_size = sizeof (struct ar_hdr);
1114
168k
  size_t ar_size = (size_t) ref->state.ar.cur_ar_hdr.ar_size;
1115
168k
  if (max_size < hdr_size || max_size - hdr_size < offset)
1116
0
    return NULL;
1117
1118
168k
  Elf_Arhdr ar_hdr = {0};
1119
168k
  if (copy_arhdr (&ar_hdr, ref) != 0)
1120
    /* Out of memory.  */
1121
0
    return NULL;
1122
1123
168k
  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1124
168k
          MIN (max_size - hdr_size - offset, ar_size), cmd, ref);
1125
1126
168k
  if (result != NULL)
1127
168k
    {
1128
      /* Enlist this new descriptor in the list of children.  */
1129
168k
      result->next = ref->state.ar.children;
1130
168k
      ref->state.ar.children = result;
1131
1132
168k
      result->elf_ar_hdr = ar_hdr;
1133
168k
    }
1134
17
  else
1135
17
    {
1136
17
      free (ar_hdr.ar_name);
1137
17
      free (ar_hdr.ar_rawname);
1138
17
    }
1139
1140
168k
  return result;
1141
168k
}
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
168k
{
1175
  /* We need wrlock to dup an archive.  */
1176
168k
  if (ref->kind == ELF_K_AR)
1177
168k
    {
1178
168k
      rwlock_unlock (ref->lock);
1179
168k
      rwlock_wrlock (ref->lock);
1180
168k
    }
1181
    /* Duplicate the descriptor.  */
1182
168k
  return dup_elf (fildes, cmd, ref);
1183
168k
}
1184
1185
/* Return a descriptor for the file belonging to FILDES.  */
1186
Elf *
1187
elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1188
233k
{
1189
233k
  Elf *retval;
1190
1191
233k
  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
233k
  if (ref != NULL)
1199
    /* Make sure the descriptor is not suddenly going away.  */
1200
168k
    rwlock_rdlock (ref->lock);
1201
64.2k
  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
233k
  switch (cmd)
1209
233k
    {
1210
0
    case ELF_C_NULL:
1211
      /* We simply return a NULL pointer.  */
1212
0
      retval = NULL;
1213
0
      break;
1214
1215
178k
    case ELF_C_READ_MMAP_PRIVATE:
1216
      /* If we have a reference it must also be opened this way.  */
1217
178k
      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
178k
      FALLTHROUGH;
1224
1225
197k
    case ELF_C_READ:
1226
220k
    case ELF_C_READ_MMAP:
1227
220k
      if (ref != NULL)
1228
168k
  retval = lock_dup_elf (fildes, cmd, ref);
1229
51.9k
      else
1230
  /* Create descriptor for existing file.  */
1231
51.9k
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1232
220k
      break;
1233
1234
6.14k
    case ELF_C_RDWR:
1235
12.2k
    case ELF_C_RDWR_MMAP:
1236
      /* If we have a REF object it must also be opened using this
1237
   command.  */
1238
12.2k
      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
12.2k
      else
1252
  /* Create descriptor for existing file.  */
1253
12.2k
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1254
12.2k
      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
233k
    }
1267
1268
  /* Release the lock.  */
1269
233k
  if (ref != NULL)
1270
168k
    rwlock_unlock (ref->lock);
1271
1272
233k
  return retval;
1273
233k
}
1274
INTDEF(elf_begin)