Coverage Report

Created: 2026-02-26 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libbpf/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
1
{
53
1
  Elf *elf;
54
55
  /* Create a descriptor.  */
56
1
  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
57
1
                      ELF_K_AR, 0);
58
1
  if (elf != NULL)
59
1
    {
60
      /* We don't read all the symbol tables in advance.  All this will
61
   happen on demand.  */
62
1
      elf->state.ar.offset = offset + SARMAG;
63
64
1
      elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
65
1
    }
66
67
1
  return elf;
68
1
}
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
8.98k
{
75
8.98k
  size_t result;
76
8.98k
  union
77
8.98k
  {
78
8.98k
    Elf32_Ehdr *e32;
79
8.98k
    Elf64_Ehdr *e64;
80
8.98k
    void *p;
81
8.98k
  } ehdr;
82
8.98k
  union
83
8.98k
  {
84
8.98k
    Elf32_Ehdr e32;
85
8.98k
    Elf64_Ehdr e64;
86
8.98k
  } ehdr_mem;
87
8.98k
  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
88
89
8.98k
  if ((is32 && maxsize < sizeof (Elf32_Ehdr))
90
8.97k
      || (!is32 && maxsize < sizeof (Elf64_Ehdr)))
91
21
    {
92
21
       __libelf_seterrno (ELF_E_INVALID_ELF);
93
21
      return (size_t) -1l;
94
21
    }
95
96
  /* Make the ELF header available.  */
97
8.96k
  if (e_ident[EI_DATA] == MY_ELFDATA
98
7.37k
      && (ALLOW_UNALIGNED
99
0
    || (((size_t) e_ident
100
0
         & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
101
0
      - 1)) == 0)))
102
7.37k
    ehdr.p = e_ident;
103
1.59k
  else
104
1.59k
    {
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
1.59k
      ehdr.p = &ehdr_mem;
109
110
1.59k
      if (is32)
111
52
  {
112
52
    if (ALLOW_UNALIGNED)
113
52
      {
114
52
        ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
115
52
        ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
116
52
      }
117
0
    else
118
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
119
120
52
    if (e_ident[EI_DATA] != MY_ELFDATA)
121
52
      {
122
52
        CONVERT (ehdr_mem.e32.e_shnum);
123
52
        CONVERT (ehdr_mem.e32.e_shoff);
124
52
      }
125
52
  }
126
1.54k
      else
127
1.54k
  {
128
1.54k
    if (ALLOW_UNALIGNED)
129
1.54k
      {
130
1.54k
        ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
131
1.54k
        ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
132
1.54k
      }
133
0
    else
134
0
      memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
135
136
1.54k
    if (e_ident[EI_DATA] != MY_ELFDATA)
137
1.54k
      {
138
1.54k
        CONVERT (ehdr_mem.e64.e_shnum);
139
1.54k
        CONVERT (ehdr_mem.e64.e_shoff);
140
1.54k
      }
141
1.54k
  }
142
1.59k
    }
143
144
8.96k
  if (is32)
145
418
    {
146
      /* Get the number of sections from the ELF header.  */
147
418
      result = ehdr.e32->e_shnum;
148
149
418
      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
150
138
  {
151
138
    if (unlikely (ehdr.e32->e_shoff >= maxsize)
152
75
        || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
153
      /* Cannot read the first section header.  */
154
70
      return 0;
155
156
68
    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
60
      result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
163
60
              + offset))->sh_size;
164
8
    else
165
8
      {
166
8
        Elf32_Word size;
167
8
        ssize_t r;
168
169
8
        if (likely (map_address != NULL))
170
    /* gcc will optimize the memcpy to a simple memory
171
       access while taking care of alignment issues.  */
172
8
    memcpy (&size, ((char *) map_address
173
8
           + ehdr.e32->e_shoff
174
8
           + offset
175
8
           + offsetof (Elf32_Shdr, sh_size)),
176
8
      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
8
        if (e_ident[EI_DATA] != MY_ELFDATA)
193
8
    CONVERT (size);
194
195
8
        result = size;
196
8
      }
197
68
  }
198
199
      /* If the section headers were truncated, pretend none were there.  */
200
348
      if (ehdr.e32->e_shoff > maxsize
201
304
    || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
202
95
  result = 0;
203
348
    }
204
8.54k
  else
205
8.54k
    {
206
      /* Get the number of sections from the ELF header.  */
207
8.54k
      result = ehdr.e64->e_shnum;
208
209
8.54k
      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
210
344
  {
211
344
    if (unlikely (ehdr.e64->e_shoff >= maxsize)
212
193
        || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
213
      /* Cannot read the first section header.  */
214
159
      return 0;
215
216
185
    Elf64_Xword size;
217
185
    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
87
      size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
224
87
            + offset))->sh_size;
225
98
    else
226
98
      {
227
98
        ssize_t r;
228
98
        if (likely (map_address != NULL))
229
    /* gcc will optimize the memcpy to a simple memory
230
       access while taking care of alignment issues.  */
231
98
    memcpy (&size, ((char *) map_address
232
98
           + ehdr.e64->e_shoff
233
98
           + offset
234
98
           + offsetof (Elf64_Shdr, sh_size)),
235
98
      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
98
        if (e_ident[EI_DATA] != MY_ELFDATA)
252
98
    CONVERT (size);
253
98
      }
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
185
    if (size > ~((GElf_Word) 0))
259
52
      {
260
        /* Invalid value, it is too large.  */
261
52
        __libelf_seterrno (ELF_E_INVALID_ELF);
262
52
        return (size_t) -1l;
263
52
      }
264
265
133
    result = size;
266
133
  }
267
268
      /* If the section headers were truncated, pretend none were there.  */
269
8.33k
      if (ehdr.e64->e_shoff > maxsize
270
8.21k
    || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
271
189
  result = 0;
272
8.33k
    }
273
274
8.68k
  return result;
275
8.96k
}
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
8.98k
{
283
  /* Verify the binary is of the class we can handle.  */
284
8.98k
  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
285
8.98k
     && e_ident[EI_CLASS] != ELFCLASS64)
286
    /* We also can only handle two encodings.  */
287
8.98k
    || (e_ident[EI_DATA] != ELFDATA2LSB
288
8.98k
        && 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
8.98k
  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
299
8.98k
  if (scncnt == (size_t) -1l)
300
    /* Could not determine the number of sections.  */
301
73
    return NULL;
302
303
  /* Check for too many sections.  */
304
8.91k
  if (e_ident[EI_CLASS] == ELFCLASS32)
305
418
    {
306
418
      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
418
    }
312
8.49k
  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
8.91k
  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
321
534
       ? 1 : 0);
322
8.91k
  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
323
8.91k
         ELF_K_ELF, scnmax * sizeof (Elf_Scn));
324
8.91k
  if (elf == NULL)
325
    /* Not enough memory.  allocate_elf will have set libelf errno.  */
326
0
    return NULL;
327
328
8.91k
  assert ((unsigned int) scncnt == scncnt);
329
8.91k
  assert (offsetof (struct Elf, state.elf32.scns)
330
8.91k
    == offsetof (struct Elf, state.elf64.scns));
331
8.91k
  elf->state.elf32.scns.cnt = scncnt;
332
8.91k
  elf->state.elf32.scns.max = scnmax;
333
334
  /* Some more or less arbitrary value.  */
335
8.91k
  elf->state.elf.scnincr = 10;
336
337
  /* Make the class easily available.  */
338
8.91k
  elf->class = e_ident[EI_CLASS];
339
340
8.91k
  if (e_ident[EI_CLASS] == ELFCLASS32)
341
418
    {
342
      /* This pointer might not be directly usable if the alignment is
343
   not sufficient for the architecture.  */
344
418
      Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
345
346
      /* This is a 32-bit binary.  */
347
418
      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
366
  {
351
    /* We can use the mmapped memory.  */
352
366
    elf->state.elf32.ehdr = ehdr;
353
366
  }
354
52
      else
355
52
  {
356
    /* Copy the ELF header.  */
357
52
    elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
358
52
            sizeof (Elf32_Ehdr));
359
360
52
    if (e_ident[EI_DATA] != MY_ELFDATA)
361
52
      {
362
52
        CONVERT (elf->state.elf32.ehdr_mem.e_type);
363
52
        CONVERT (elf->state.elf32.ehdr_mem.e_machine);
364
52
        CONVERT (elf->state.elf32.ehdr_mem.e_version);
365
52
        CONVERT (elf->state.elf32.ehdr_mem.e_entry);
366
52
        CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
367
52
        CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
368
52
        CONVERT (elf->state.elf32.ehdr_mem.e_flags);
369
52
        CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
370
52
        CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
371
52
        CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
372
52
        CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
373
52
        CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
374
52
        CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
375
52
      }
376
52
  }
377
378
      /* Don't precache the phdr pointer here.
379
   elf32_getphdr will validate it against the size when asked.  */
380
381
418
      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
382
418
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
383
366
    && 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
366
  {
388
366
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
389
366
        || unlikely (maxsize - e_shoff
390
366
         < 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
366
    if (scncnt > 0)
399
216
      elf->state.elf32.shdr
400
216
        = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
401
402
202k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
403
202k
      {
404
202k
        elf->state.elf32.scns.data[cnt].index = cnt;
405
202k
        elf->state.elf32.scns.data[cnt].elf = elf;
406
202k
        elf->state.elf32.scns.data[cnt].shdr.e32 =
407
202k
    &elf->state.elf32.shdr[cnt];
408
202k
        if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
409
112k
      && likely (elf->state.elf32.shdr[cnt].sh_size
410
202k
           <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
411
88.6k
    elf->state.elf32.scns.data[cnt].rawdata_base =
412
88.6k
      elf->state.elf32.scns.data[cnt].data_base =
413
88.6k
      ((char *) map_address + offset
414
88.6k
       + elf->state.elf32.shdr[cnt].sh_offset);
415
202k
        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
202k
        if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
421
8.17k
      && elf->state.elf32.shdr[cnt].sh_link < scncnt)
422
5.37k
    elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
423
5.37k
      = cnt;
424
425
        /* Set the own shndx_index field in case it has not yet
426
     been set.  */
427
202k
        if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
428
202k
    elf->state.elf32.scns.data[cnt].shndx_index = -1;
429
202k
      }
430
366
  }
431
52
      else
432
52
  {
433
6.71k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
434
6.66k
      {
435
6.66k
        elf->state.elf32.scns.data[cnt].index = cnt;
436
6.66k
        elf->state.elf32.scns.data[cnt].elf = elf;
437
6.66k
        elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
438
6.66k
      }
439
52
  }
440
441
      /* So far only one block with sections.  */
442
418
      elf->state.elf32.scns_last = &elf->state.elf32.scns;
443
418
    }
444
8.49k
  else
445
8.49k
    {
446
      /* This pointer might not be directly usable if the alignment is
447
   not sufficient for the architecture.  */
448
8.49k
      Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
449
450
      /* This is a 64-bit binary.  */
451
8.49k
      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
6.97k
  {
455
    /* We can use the mmapped memory.  */
456
6.97k
    elf->state.elf64.ehdr = ehdr;
457
6.97k
  }
458
1.52k
      else
459
1.52k
  {
460
    /* Copy the ELF header.  */
461
1.52k
    elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
462
1.52k
            sizeof (Elf64_Ehdr));
463
464
1.52k
    if (e_ident[EI_DATA] != MY_ELFDATA)
465
1.52k
      {
466
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_type);
467
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_machine);
468
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_version);
469
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_entry);
470
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
471
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
472
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_flags);
473
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
474
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
475
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
476
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
477
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
478
1.52k
        CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
479
1.52k
      }
480
1.52k
  }
481
482
      /* Don't precache the phdr pointer here.
483
   elf64_getphdr will validate it against the size when asked.  */
484
485
8.49k
      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
486
8.49k
      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
487
6.97k
    && 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
6.97k
  {
492
6.97k
    if (unlikely (scncnt > 0 && e_shoff >= maxsize)
493
6.97k
        || unlikely (maxsize - e_shoff
494
6.97k
         < scncnt * sizeof (Elf64_Shdr)))
495
0
      goto free_and_out;
496
497
6.97k
    if (scncnt > 0)
498
6.70k
      elf->state.elf64.shdr
499
6.70k
        = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
500
501
104k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
502
97.1k
      {
503
97.1k
        elf->state.elf64.scns.data[cnt].index = cnt;
504
97.1k
        elf->state.elf64.scns.data[cnt].elf = elf;
505
97.1k
        elf->state.elf64.scns.data[cnt].shdr.e64 =
506
97.1k
    &elf->state.elf64.shdr[cnt];
507
97.1k
        if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
508
53.3k
      && likely (elf->state.elf64.shdr[cnt].sh_size
509
97.1k
           <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
510
48.5k
    elf->state.elf64.scns.data[cnt].rawdata_base =
511
48.5k
      elf->state.elf64.scns.data[cnt].data_base =
512
48.5k
      ((char *) map_address + offset
513
48.5k
       + elf->state.elf64.shdr[cnt].sh_offset);
514
97.1k
        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
97.1k
        if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
520
2.97k
      && elf->state.elf64.shdr[cnt].sh_link < scncnt)
521
1.48k
    elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
522
1.48k
      = cnt;
523
524
        /* Set the own shndx_index field in case it has not yet
525
     been set.  */
526
97.1k
        if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
527
97.0k
    elf->state.elf64.scns.data[cnt].shndx_index = -1;
528
97.1k
      }
529
6.97k
  }
530
1.52k
      else
531
1.52k
  {
532
80.6k
    for (size_t cnt = 0; cnt < scncnt; ++cnt)
533
79.1k
      {
534
79.1k
        elf->state.elf64.scns.data[cnt].index = cnt;
535
79.1k
        elf->state.elf64.scns.data[cnt].elf = elf;
536
79.1k
        elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
537
79.1k
      }
538
1.52k
  }
539
540
      /* So far only one block with sections.  */
541
8.49k
      elf->state.elf64.scns_last = &elf->state.elf64.scns;
542
8.49k
    }
543
544
8.91k
  return elf;
545
8.91k
}
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
9.09k
{
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
9.09k
  unsigned char *e_ident = (unsigned char *) map_address + offset;
558
559
  /* See what kind of object we have here.  */
560
9.09k
  Elf_Kind kind = determine_kind (e_ident, maxsize);
561
562
9.09k
  switch (kind)
563
9.09k
    {
564
8.98k
    case ELF_K_ELF:
565
8.98k
      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
566
8.98k
          cmd, parent);
567
568
1
    case ELF_K_AR:
569
1
      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
570
571
110
    default:
572
110
      break;
573
9.09k
    }
574
575
  /* This case is easy.  Since we cannot do anything with this file
576
     create a dummy descriptor.  */
577
110
  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
578
110
           ELF_K_NONE, 0);
579
9.09k
}
580
581
582
static Elf *
583
read_unmmaped_file (int fildes, int64_t offset, size_t maxsize, Elf_Cmd cmd,
584
        Elf *parent)
585
0
{
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
0
  union
598
0
  {
599
0
    Elf64_Ehdr ehdr;
600
0
    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
601
0
  } mem;
602
603
  /* Read the head of the file.  */
604
0
  ssize_t nread = pread_retry (fildes, mem.header,
605
0
             MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
606
0
            maxsize),
607
0
             offset);
608
0
  if (unlikely (nread == -1))
609
0
    {
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
0
      __libelf_seterrno (ELF_E_INVALID_FILE);
613
0
      return NULL;
614
0
    }
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
0
{
648
0
  void *map_address = NULL;
649
0
  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
650
0
      || cmd == ELF_C_WRITE_MMAP
651
0
      || cmd == ELF_C_READ_MMAP_PRIVATE);
652
653
0
  if (parent == NULL)
654
0
    {
655
0
      if (maxsize == ~((size_t) 0))
656
0
  {
657
    /* We don't know in the moment how large the file is.
658
       Determine it now.  */
659
0
    struct stat st;
660
661
0
    if (fstat (fildes, &st) == 0
662
0
        && (sizeof (size_t) >= sizeof (st.st_size)
663
0
      || st.st_size <= ~((size_t) 0)))
664
0
      maxsize = (size_t) st.st_size;
665
0
  }
666
0
    }
667
0
  else
668
0
    {
669
      /* The parent is already loaded.  Use it.  */
670
0
      assert (maxsize != ~((size_t) 0));
671
0
    }
672
673
0
  if (use_mmap)
674
0
    {
675
0
      if (parent == NULL)
676
0
  {
677
    /* We try to map the file ourself.  */
678
0
    map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
679
0
                ? PROT_READ
680
0
                : PROT_READ|PROT_WRITE),
681
0
            cmd == ELF_C_READ_MMAP_PRIVATE
682
0
            || cmd == ELF_C_READ_MMAP
683
0
            ? MAP_PRIVATE : MAP_SHARED,
684
0
            fildes, offset);
685
686
0
    if (map_address == MAP_FAILED)
687
0
      map_address = NULL;
688
0
  }
689
0
      else
690
0
  {
691
0
    map_address = parent->map_address;
692
0
  }
693
0
    }
694
695
  /* If we have the file in memory optimize the access.  */
696
0
  if (map_address != NULL)
697
0
    {
698
0
      assert (map_address != MAP_FAILED);
699
700
0
      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
701
0
                  offset, maxsize, cmd,
702
0
                  parent);
703
704
      /* If something went wrong during the initialization unmap the
705
   memory if we mmaped here.  */
706
0
      if (result == NULL
707
0
    && (parent == NULL
708
0
        || parent->map_address != map_address))
709
0
  munmap (map_address, maxsize);
710
0
      else if (parent == NULL)
711
  /* Remember that we mmap()ed the memory.  */
712
0
  result->flags |= ELF_F_MMAPPED;
713
714
0
      return result;
715
0
    }
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
0
  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
720
0
}
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
0
{
727
0
  off_t offset = SARMAG; /* This is the first entry.  */
728
0
  struct ar_hdr hdrm;
729
0
  struct ar_hdr *hdr;
730
0
  char *newp;
731
0
  size_t len;
732
733
0
  while (1)
734
0
    {
735
0
      if (elf->map_address != NULL)
736
0
  {
737
0
    if ((size_t) offset > elf->maximum_size
738
0
        || elf->maximum_size - offset < sizeof (struct ar_hdr))
739
0
      return NULL;
740
741
    /* The data is mapped.  */
742
0
    hdr = (struct ar_hdr *) (elf->map_address + offset);
743
0
  }
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
0
      char buf[sizeof (hdr->ar_size) + 1];
759
0
      const char *string = hdr->ar_size;
760
0
      if (hdr->ar_size[sizeof (hdr->ar_size) - 1] != ' ')
761
0
  {
762
0
    *((char *) mempcpy (buf, hdr->ar_size, sizeof (hdr->ar_size))) = '\0';
763
0
    string = buf;
764
0
  }
765
766
      /* atol expects to see at least one digit.
767
   It also cannot be negative (-).  */
768
0
      if (!isdigit(string[0]))
769
0
  return NULL;
770
0
      len = atol (string);
771
772
0
      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
773
0
  break;
774
775
0
      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
776
0
    }
777
778
  /* Sanity check len early if we can.  */
779
0
  if (elf->map_address != NULL)
780
0
    {
781
0
      if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
782
0
  return NULL;
783
0
    }
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
0
  newp = malloc (len);
789
0
  if (newp != NULL)
790
0
    {
791
0
      char *runp;
792
793
0
      if (elf->map_address != NULL)
794
0
  {
795
    /* Simply copy it over.  */
796
0
    elf->state.ar.long_names = (char *) memcpy (newp,
797
0
                  elf->map_address + offset
798
0
                  + sizeof (struct ar_hdr),
799
0
                  len);
800
0
  }
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
0
      elf->state.ar.long_names_len = len;
817
818
      /* Now NUL-terminate the strings.  */
819
0
      runp = newp;
820
0
      while (1)
821
0
        {
822
0
    char *startp = runp;
823
0
    runp = (char *) memchr (runp, '/', newp + len - runp);
824
0
    if (runp == NULL)
825
0
      {
826
        /* This was the last entry.  Clear any left overs.  */
827
0
        memset (startp, '\0', newp + len - startp);
828
0
        break;
829
0
      }
830
831
    /* NUL-terminate the string.  */
832
0
    *runp++ = '\0';
833
834
    /* A sanity check.  Somebody might have generated invalid
835
       archive.  */
836
0
    if (runp >= newp + len)
837
0
      break;
838
0
  }
839
0
    }
840
841
0
  return newp;
842
0
}
843
844
845
/* Read the next archive header.  */
846
int
847
internal_function
848
__libelf_next_arhdr_wrlock (Elf *elf)
849
0
{
850
0
  struct ar_hdr *ar_hdr;
851
0
  Elf_Arhdr *elf_ar_hdr;
852
853
0
  if (elf->map_address != NULL)
854
0
    {
855
      /* See whether this entry is in the file.  */
856
0
      if (unlikely ((size_t) elf->state.ar.offset
857
0
        > elf->start_offset + elf->maximum_size
858
0
        || (elf->start_offset + elf->maximum_size
859
0
      - elf->state.ar.offset) < sizeof (struct ar_hdr)))
860
0
  {
861
    /* This record is not anymore in the file.  */
862
0
    __libelf_seterrno (ELF_E_RANGE);
863
0
    return -1;
864
0
  }
865
0
      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
866
0
    }
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
0
  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
883
0
    {
884
      /* This is no valid archive.  */
885
0
      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
886
0
      return -1;
887
0
    }
888
889
  /* Copy the raw name over to a NUL terminated buffer.  */
890
0
  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
891
892
0
  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
0
  if (ar_hdr->ar_name[0] == '/')
897
0
    {
898
0
      if (ar_hdr->ar_name[1] == ' '
899
0
    && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
900
  /* This is the index.  */
901
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
902
0
      else if (ar_hdr->ar_name[1] == 'S'
903
0
         && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
904
  /* 64-bit index.  */
905
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
906
0
      else if (ar_hdr->ar_name[1] == '/'
907
0
         && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
908
  /* This is the array with the long names.  */
909
0
  elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
910
0
      else if (likely  (isdigit (ar_hdr->ar_name[1])))
911
0
  {
912
0
    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
0
    if (unlikely (elf->state.ar.long_names == NULL
917
0
      && read_long_names (elf) == NULL))
918
0
      {
919
        /* No long name table although it is reference.  The archive is
920
     broken.  */
921
0
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
922
0
        return -1;
923
0
      }
924
925
0
    offset = atol (ar_hdr->ar_name + 1);
926
0
    if (unlikely (offset >= elf->state.ar.long_names_len))
927
0
      {
928
        /* The index in the long name table is larger than the table.  */
929
0
        __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
930
0
        return -1;
931
0
      }
932
0
    elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
933
0
  }
934
0
      else
935
0
  {
936
    /* This is none of the known special entries.  */
937
0
    __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
938
0
    return -1;
939
0
  }
940
0
    }
941
0
  else
942
0
    {
943
0
      char *endp;
944
945
      /* It is a normal entry.  Copy over the name.  */
946
0
      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
947
0
             '/', 16);
948
0
      if (endp != NULL)
949
0
  endp[-1] = '\0';
950
0
      else
951
0
  {
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
0
    size_t i = 15;
955
0
    do
956
0
      elf->state.ar.ar_name[i] = '\0';
957
0
    while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
958
0
  }
959
960
0
      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
961
0
    }
962
963
0
  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
0
    {
968
0
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
969
0
      return -1;
970
0
    }
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
0
#define INT_FIELD(FIELD)                  \
981
0
  do                        \
982
0
    {                       \
983
0
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
984
0
      const char *string = ar_hdr->FIELD;             \
985
0
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
986
0
  {                     \
987
0
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
988
0
      = '\0';                   \
989
0
    string = buf;                   \
990
0
  }                      \
991
0
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
992
0
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
993
0
      else                      \
994
0
  elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
995
0
    }                       \
996
0
  while (0)
997
998
0
#define OCT_FIELD(FIELD)                  \
999
0
  do                        \
1000
0
    {                       \
1001
0
      char buf[sizeof (ar_hdr->FIELD) + 1];             \
1002
0
      const char *string = ar_hdr->FIELD;             \
1003
0
      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')         \
1004
0
  {                     \
1005
0
    *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
1006
0
      = '\0';                   \
1007
0
    string = buf;                   \
1008
0
  }                      \
1009
0
      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))         \
1010
0
  elf_ar_hdr->FIELD                 \
1011
0
    = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8);       \
1012
0
      else                      \
1013
0
  elf_ar_hdr->FIELD                 \
1014
0
    = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8);       \
1015
0
    }                       \
1016
0
  while (0)
1017
1018
0
  INT_FIELD (ar_date);
1019
0
  INT_FIELD (ar_uid);
1020
0
  INT_FIELD (ar_gid);
1021
0
  OCT_FIELD (ar_mode);
1022
0
  INT_FIELD (ar_size);
1023
1024
0
  if (elf_ar_hdr->ar_size < 0)
1025
0
    {
1026
0
      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
1027
0
      return -1;
1028
0
    }
1029
1030
  /* Truncated file?  */
1031
0
  size_t maxsize;
1032
0
  maxsize = (elf->start_offset + elf->maximum_size
1033
0
       - elf->state.ar.offset - sizeof (struct ar_hdr));
1034
0
  if ((size_t) elf_ar_hdr->ar_size > maxsize)
1035
0
    elf_ar_hdr->ar_size = maxsize;
1036
1037
0
  return 0;
1038
0
}
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
0
{
1047
0
  struct Elf *result;
1048
1049
0
  if (fildes == -1)
1050
    /* Allow the user to pass -1 as the file descriptor for the new file.  */
1051
0
    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
0
  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
0
  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
1064
0
    && ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
1065
0
    && ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
1066
0
    && 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
0
  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
0
  if (ref->state.ar.elf_ar_hdr.ar_name == NULL
1086
0
      && __libelf_next_arhdr_wrlock (ref) != 0)
1087
    /* Something went wrong.  Maybe there is no member left.  */
1088
0
    return NULL;
1089
1090
  /* We have all the information we need about the next archive member.
1091
     Now create a descriptor for it.  */
1092
0
  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
1093
0
          ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
1094
1095
  /* Enlist this new descriptor in the list of children.  */
1096
0
  if (result != NULL)
1097
0
    {
1098
0
      result->next = ref->state.ar.children;
1099
0
      ref->state.ar.children = result;
1100
0
    }
1101
1102
0
  return result;
1103
0
}
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
0
{
1137
  /* We need wrlock to dup an archive.  */
1138
0
  if (ref->kind == ELF_K_AR)
1139
0
    {
1140
0
      rwlock_unlock (ref->lock);
1141
0
      rwlock_wrlock (ref->lock);
1142
0
    }
1143
    /* Duplicate the descriptor.  */
1144
0
  return dup_elf (fildes, cmd, ref);
1145
0
}
1146
1147
/* Return a descriptor for the file belonging to FILDES.  */
1148
Elf *
1149
elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
1150
0
{
1151
0
  Elf *retval;
1152
1153
0
  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
0
  if (ref != NULL)
1161
    /* Make sure the descriptor is not suddenly going away.  */
1162
0
    rwlock_rdlock (ref->lock);
1163
0
  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
0
  switch (cmd)
1171
0
    {
1172
0
    case ELF_C_NULL:
1173
      /* We simply return a NULL pointer.  */
1174
0
      retval = NULL;
1175
0
      break;
1176
1177
0
    case ELF_C_READ_MMAP_PRIVATE:
1178
      /* If we have a reference it must also be opened this way.  */
1179
0
      if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
1180
0
  {
1181
0
    __libelf_seterrno (ELF_E_INVALID_CMD);
1182
0
    retval = NULL;
1183
0
    break;
1184
0
  }
1185
0
      FALLTHROUGH;
1186
1187
0
    case ELF_C_READ:
1188
0
    case ELF_C_READ_MMAP:
1189
0
      if (ref != NULL)
1190
0
  retval = lock_dup_elf (fildes, cmd, ref);
1191
0
      else
1192
  /* Create descriptor for existing file.  */
1193
0
  retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
1194
0
      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
0
    }
1229
1230
  /* Release the lock.  */
1231
0
  if (ref != NULL)
1232
0
    rwlock_unlock (ref->lock);
1233
1234
0
  return retval;
1235
0
}
1236
INTDEF(elf_begin)