Coverage Report

Created: 2026-09-03 06:53

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