Coverage Report

Created: 2026-02-24 06:49

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