Coverage Report

Created: 2025-07-11 06:46

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