Coverage Report

Created: 2026-08-13 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libbpf/elfutils/libelf/elf_getdata.c
Line
Count
Source
1
/* Return the next data element from the section after possibly converting it.
2
   Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc.
3
   Copyright (C) 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 <errno.h>
36
#include <stddef.h>
37
#include <string.h>
38
39
#include "libelfP.h"
40
#include "common.h"
41
#include "elf-knowledge.h"
42
43
44
#define TYPEIDX(Sh_Type) \
45
87.6k
  (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM              \
46
87.6k
   ? Sh_Type                      \
47
87.6k
   : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW            \
48
31.0k
      ? SHT_NUM + Sh_Type - SHT_GNU_HASH              \
49
31.0k
      : 0))
50
51
/* Associate section types with libelf types.  */
52
static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] =
53
  {
54
      [SHT_SYMTAB] = ELF_T_SYM,
55
      [SHT_RELA] = ELF_T_RELA,
56
      [SHT_HASH] = ELF_T_WORD,
57
      [SHT_DYNAMIC] = ELF_T_DYN,
58
      [SHT_REL] = ELF_T_REL,
59
      [SHT_DYNSYM] = ELF_T_SYM,
60
      [SHT_INIT_ARRAY] = ELF_T_ADDR,
61
      [SHT_FINI_ARRAY] = ELF_T_ADDR,
62
      [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
63
      [SHT_GROUP] = ELF_T_WORD,
64
      [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
65
      [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8.  */
66
      [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
67
      [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
68
      [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
69
      [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
70
      [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
71
      [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
72
      [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
73
  };
74
75
/* Associate libelf types with their internal alignment requirements.  */
76
const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
77
  {
78
# define TYPE_ALIGNS(Bits)                  \
79
      [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),            \
80
      [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),            \
81
      [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),            \
82
      [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)),            \
83
      [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)),            \
84
      [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)),            \
85
      [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)),            \
86
      [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),            \
87
      [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)),            \
88
      [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)),          \
89
      [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),            \
90
      [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),          \
91
      [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),            \
92
      [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),            \
93
      [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),            \
94
      [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),            \
95
      [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),          \
96
      [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),          \
97
      [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),          \
98
      [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),            \
99
      [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),            \
100
      [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),            \
101
      [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),            \
102
      [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),            \
103
      [ELF_T_NHDR8] = 8 /* Special case for GNU Property note.  */
104
    [ELFCLASS32 - 1] =  {
105
  TYPE_ALIGNS (32),
106
  [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),
107
    },
108
    [ELFCLASS64 - 1] = {
109
  TYPE_ALIGNS (64),
110
  [ELF_T_GNUHASH] = __alignof__ (Elf64_Xword),
111
    },
112
# undef TYPE_ALIGNS
113
  };
114
115
116
Elf_Type
117
internal_function
118
__libelf_data_type (GElf_Ehdr *ehdr, int sh_type, GElf_Xword align)
119
50.2k
{
120
  /* Some broken ELF ABI for 64-bit machines use the wrong hash table
121
     entry size.  See elf-knowledge.h for more information.  */
122
50.2k
  if (sh_type == SHT_HASH && ehdr->e_ident[EI_CLASS] == ELFCLASS64)
123
1.79k
    {
124
1.79k
      return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
125
1.79k
    }
126
48.4k
  else
127
48.4k
    {
128
48.4k
      Elf_Type t = shtype_map[TYPEIDX (sh_type)];
129
      /* Special case for GNU Property notes.  */
130
48.4k
      if (t == ELF_T_NHDR && align == 8)
131
355
  t = ELF_T_NHDR8;
132
48.4k
      return t;
133
48.4k
    }
134
50.2k
}
135
136
/* Convert the data in the current section.  */
137
static void
138
convert_data (Elf_Scn *scn, int eclass,
139
        int data, size_t size, Elf_Type type)
140
40.2k
{
141
40.2k
  const size_t align = __libelf_type_align (eclass, type);
142
143
  /* Do we need to convert the data and/or adjust for alignment?  */
144
40.2k
  if (data == MY_ELFDATA || type == ELF_T_BYTE)
145
23.7k
    {
146
23.7k
      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
147
  /* No need to copy, we can use the raw data.  */
148
20.0k
  scn->data_base = scn->rawdata_base;
149
3.71k
      else
150
3.71k
  {
151
3.71k
    scn->data_base = malloc (size);
152
3.71k
    if (scn->data_base == NULL)
153
0
      {
154
0
        __libelf_seterrno (ELF_E_NOMEM);
155
0
        return;
156
0
      }
157
158
    /* The copy will be appropriately aligned for direct access.  */
159
3.71k
    memcpy (scn->data_base, scn->rawdata_base, size);
160
3.71k
  }
161
23.7k
    }
162
16.5k
  else
163
16.5k
    {
164
16.5k
      xfct_t fp;
165
166
16.5k
      scn->data_base = malloc (size);
167
16.5k
      if (scn->data_base == NULL)
168
0
  {
169
0
    __libelf_seterrno (ELF_E_NOMEM);
170
0
    return;
171
0
  }
172
173
      /* Make sure the source is correctly aligned for the conversion
174
   function to directly access the data elements.  */
175
16.5k
      char *rawdata_source;
176
16.5k
      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
177
2.92k
  rawdata_source = scn->rawdata_base;
178
13.5k
      else
179
13.5k
  {
180
13.5k
    rawdata_source = malloc (size);
181
13.5k
    if (rawdata_source == NULL)
182
0
      {
183
0
        __libelf_seterrno (ELF_E_NOMEM);
184
0
        return;
185
0
      }
186
187
    /* The copy will be appropriately aligned for direct access.  */
188
13.5k
    memcpy (rawdata_source, scn->rawdata_base, size);
189
13.5k
  }
190
191
      /* Get the conversion function.  */
192
16.5k
      fp = __elf_xfctstom[eclass - 1][type];
193
194
16.5k
      fp (scn->data_base, rawdata_source, size, 0);
195
196
16.5k
      if (rawdata_source != scn->rawdata_base)
197
13.5k
  free (rawdata_source);
198
16.5k
    }
199
200
40.2k
  scn->data_list.data.d.d_buf = scn->data_base;
201
40.2k
  scn->data_list.data.d.d_size = size;
202
40.2k
  scn->data_list.data.d.d_type = type;
203
40.2k
  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
204
40.2k
  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
205
40.2k
  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
206
207
40.2k
  scn->data_list.data.s = scn;
208
40.2k
}
209
210
211
/* Store the information for the raw data in the `rawdata' element.  */
212
int
213
internal_function
214
__libelf_set_rawdata_wrlock (Elf_Scn *scn)
215
64.6k
{
216
64.6k
  Elf64_Off offset;
217
64.6k
  Elf64_Xword size;
218
64.6k
  Elf64_Xword align;
219
64.6k
  Elf64_Xword flags;
220
64.6k
  int type;
221
64.6k
  Elf *elf = scn->elf;
222
223
64.6k
  if (elf->class == ELFCLASS32)
224
0
    {
225
0
      Elf32_Shdr *shdr
226
0
  = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
227
228
0
      if (shdr == NULL)
229
  /* Something went terribly wrong.  */
230
0
  return 1;
231
232
0
      offset = shdr->sh_offset;
233
0
      size = shdr->sh_size;
234
0
      type = shdr->sh_type;
235
0
      align = shdr->sh_addralign;
236
0
      flags = shdr->sh_flags;
237
0
    }
238
64.6k
  else
239
64.6k
    {
240
64.6k
      Elf64_Shdr *shdr
241
64.6k
  = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
242
243
64.6k
      if (shdr == NULL)
244
  /* Something went terribly wrong.  */
245
0
  return 1;
246
247
64.6k
      offset = shdr->sh_offset;
248
64.6k
      size = shdr->sh_size;
249
64.6k
      type = shdr->sh_type;
250
64.6k
      align = shdr->sh_addralign;
251
64.6k
      flags = shdr->sh_flags;
252
64.6k
    }
253
254
  /* If the section has no data (for whatever reason), leave the `d_buf'
255
     pointer NULL.  */
256
64.6k
  if (size != 0 && type != SHT_NOBITS)
257
50.2k
    {
258
      /* First a test whether the section is valid at all.  */
259
50.2k
      size_t entsize;
260
261
      /* Compressed data has a header, but then compressed data.
262
   Make sure to set the alignment of the header explicitly,
263
   don't trust the file alignment for the section, it is
264
   often wrong.  */
265
50.2k
      if ((flags & SHF_COMPRESSED) != 0)
266
9.32k
  {
267
9.32k
    entsize = 1;
268
9.32k
    align = __libelf_type_align (elf->class, ELF_T_CHDR);
269
9.32k
  }
270
40.9k
      else if (type == SHT_HASH)
271
1.77k
  {
272
1.77k
    GElf_Ehdr ehdr_mem;
273
1.77k
    GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
274
1.77k
    if (unlikely (ehdr == NULL))
275
0
      return 1;
276
1.77k
    entsize = SH_ENTSIZE_HASH (ehdr);
277
1.77k
  }
278
39.1k
      else
279
39.1k
  {
280
39.1k
    Elf_Type t = shtype_map[TYPEIDX (type)];
281
39.1k
    if (t == ELF_T_NHDR && align == 8)
282
355
      t = ELF_T_NHDR8;
283
39.1k
    if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
284
36.7k
        || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
285
5.48k
      entsize = 1;
286
33.7k
    else
287
33.7k
      entsize = __libelf_type_sizes[elf->class - 1][t];
288
39.1k
  }
289
290
      /* We assume it is an array of bytes if it is none of the structured
291
   sections we know of.  */
292
50.2k
      if (entsize == 0)
293
0
  entsize = 1;
294
295
50.2k
      if (unlikely (size % entsize != 0))
296
147
  {
297
147
    __libelf_seterrno (ELF_E_INVALID_DATA);
298
147
    return 1;
299
147
  }
300
301
      /* We can use the mapped or loaded data if available.  */
302
50.1k
      if (elf->map_address != NULL)
303
50.1k
  {
304
    /* First see whether the information in the section header is
305
       valid and it does not ask for too much.  Check for unsigned
306
       overflow.  */
307
50.1k
    if (unlikely (offset > elf->maximum_size
308
50.1k
        || elf->maximum_size - offset < size))
309
2.06k
      {
310
        /* Something is wrong.  */
311
2.06k
        __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
312
2.06k
        return 1;
313
2.06k
      }
314
315
48.0k
    scn->rawdata_base = scn->rawdata.d.d_buf
316
48.0k
      = (char *) elf->map_address + elf->start_offset + offset;
317
48.0k
  }
318
0
      else if (likely (elf->fildes != -1))
319
0
  {
320
    /* First see whether the information in the section header is
321
       valid and it does not ask for too much.  Check for unsigned
322
       overflow.  */
323
0
    if (unlikely (offset > elf->maximum_size
324
0
      || elf->maximum_size - offset < size))
325
0
      {
326
        /* Something is wrong.  */
327
0
        __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
328
0
        return 1;
329
0
      }
330
331
    /* We have to read the data from the file.  Allocate the needed
332
       memory.  */
333
0
    scn->rawdata_base = scn->rawdata.d.d_buf = malloc (size);
334
0
    if (scn->rawdata.d.d_buf == NULL)
335
0
      {
336
0
        __libelf_seterrno (ELF_E_NOMEM);
337
0
        return 1;
338
0
      }
339
340
0
    ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
341
0
           elf->start_offset + offset);
342
0
    if (unlikely ((size_t) n != size))
343
0
      {
344
        /* Cannot read the data.  */
345
0
        free (scn->rawdata.d.d_buf);
346
0
        scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
347
0
        __libelf_seterrno (ELF_E_READ_ERROR);
348
0
        return 1;
349
0
      }
350
0
  }
351
0
      else
352
0
  {
353
    /* The file descriptor is already closed, we cannot get the data
354
       anymore.  */
355
0
    __libelf_seterrno (ELF_E_FD_DISABLED);
356
0
    return 1;
357
0
  }
358
50.1k
    }
359
360
62.4k
  scn->rawdata.d.d_size = size;
361
362
  /* Compressed data always has type ELF_T_CHDR regardless of the
363
     section type.  */
364
62.4k
  if ((flags & SHF_COMPRESSED) != 0)
365
12.1k
    scn->rawdata.d.d_type = ELF_T_CHDR;
366
50.2k
  else
367
50.2k
    {
368
50.2k
      GElf_Ehdr ehdr_mem;
369
50.2k
      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
370
50.2k
      if (unlikely (ehdr == NULL))
371
0
  return 1;
372
50.2k
      scn->rawdata.d.d_type = __libelf_data_type (ehdr, type, align);
373
50.2k
    }
374
62.4k
  scn->rawdata.d.d_off = 0;
375
376
  /* Make sure the alignment makes sense.  d_align should be aligned both
377
     in the section (trivially true since d_off is zero) and in the file.
378
     Unfortunately we cannot be too strict because there are ELF files
379
     out there that fail this requirement.  We will try to fix those up
380
     in elf_update when writing out the image.  But for very large
381
     alignment values this can bloat the image considerably.  So here
382
     just check and clamp the alignment value to not be bigger than the
383
     actual offset of the data in the file.  Given that there is always
384
     at least an ehdr this will only trigger for alignment values > 64
385
     which should be uncommon.  */
386
62.4k
  align = align ?: 1;
387
62.4k
  if (type != SHT_NOBITS && align > offset)
388
40.6k
    {
389
      /* Align the offset to the next power of two. Uses algorithm from
390
         https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
391
40.6k
      align = offset - 1;
392
40.6k
      align |= align >> 1;
393
40.6k
      align |= align >> 2;
394
40.6k
      align |= align >> 4;
395
40.6k
      align |= align >> 8;
396
40.6k
      align |= align >> 16;
397
40.6k
      align |= align >> 32;
398
40.6k
      align++;
399
40.6k
    }
400
62.4k
  scn->rawdata.d.d_align = align;
401
62.4k
  if (elf->class == ELFCLASS32
402
62.4k
      || (offsetof (struct Elf, state.elf32.ehdr)
403
62.4k
    == offsetof (struct Elf, state.elf64.ehdr)))
404
62.4k
    scn->rawdata.d.d_version =
405
62.4k
      elf->state.elf32.ehdr->e_ident[EI_VERSION];
406
0
  else
407
0
    scn->rawdata.d.d_version =
408
0
      elf->state.elf64.ehdr->e_ident[EI_VERSION];
409
410
62.4k
  scn->rawdata.s = scn;
411
412
62.4k
  scn->data_read = 1;
413
414
  /* We actually read data from the file.  At least we tried.  */
415
62.4k
  scn->flags |= ELF_F_FILEDATA;
416
417
62.4k
  return 0;
418
62.4k
}
419
420
int
421
internal_function
422
__libelf_set_rawdata (Elf_Scn *scn)
423
8.99k
{
424
8.99k
  int result;
425
426
8.99k
  if (scn == NULL)
427
0
    return 1;
428
429
8.99k
  rwlock_wrlock (scn->elf->lock);
430
8.99k
  result = __libelf_set_rawdata_wrlock (scn);
431
8.99k
  rwlock_unlock (scn->elf->lock);
432
433
8.99k
  return result;
434
8.99k
}
435
436
void
437
internal_function
438
__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
439
54.2k
{
440
54.2k
  if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
441
40.2k
    {
442
40.2k
      Elf *elf = scn->elf;
443
444
      /* Upgrade the lock to a write lock if necessary and check
445
   nobody else already did the work.  */
446
40.2k
      if (!wrlocked)
447
376
  {
448
376
    rwlock_unlock (elf->lock);
449
376
    rwlock_wrlock (elf->lock);
450
376
    if (scn->data_list_rear != NULL)
451
0
      return;
452
376
  }
453
454
      /* Convert according to the version and the type.   */
455
40.2k
      convert_data (scn, elf->class,
456
40.2k
        (elf->class == ELFCLASS32
457
40.2k
         || (offsetof (struct Elf, state.elf32.ehdr)
458
40.2k
       == offsetof (struct Elf, state.elf64.ehdr))
459
40.2k
         ? elf->state.elf32.ehdr->e_ident[EI_DATA]
460
40.2k
         : elf->state.elf64.ehdr->e_ident[EI_DATA]),
461
40.2k
        scn->rawdata.d.d_size, scn->rawdata.d.d_type);
462
40.2k
    }
463
14.0k
  else
464
14.0k
    {
465
      /* This is an empty or NOBITS section.  There is no buffer but
466
   the size information etc is important.  */
467
14.0k
      scn->data_list.data.d = scn->rawdata.d;
468
14.0k
      scn->data_list.data.s = scn;
469
14.0k
    }
470
471
54.2k
  scn->data_list_rear = &scn->data_list;
472
54.2k
}
473
474
Elf_Data *
475
internal_function
476
__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
477
66.8k
{
478
66.8k
  Elf_Data *result = NULL;
479
66.8k
  Elf *elf;
480
66.8k
  int locked = 0;
481
482
66.8k
  if (scn == NULL)
483
0
    return NULL;
484
485
66.8k
  if (unlikely (scn->elf->kind != ELF_K_ELF))
486
0
    {
487
0
      __libelf_seterrno (ELF_E_INVALID_HANDLE);
488
0
      return NULL;
489
0
    }
490
491
  /* We will need this multiple times later on.  */
492
66.8k
  elf = scn->elf;
493
494
  /* If `data' is not NULL this means we are not addressing the initial
495
     data in the file.  But this also means this data is already read
496
     (since otherwise it is not possible to have a valid `data' pointer)
497
     and all the data structures are initialized as well.  In this case
498
     we can simply walk the list of data records.  */
499
66.8k
  if (data != NULL)
500
0
    {
501
0
      Elf_Data_List *runp;
502
503
      /* It is not possible that if DATA is not NULL the first entry is
504
   returned.  But this also means that there must be a first data
505
   entry.  */
506
0
      if (scn->data_list_rear == NULL
507
    /* The section the reference data is for must match the section
508
       parameter.  */
509
0
    || unlikely (((Elf_Data_Scn *) data)->s != scn))
510
0
  {
511
0
    __libelf_seterrno (ELF_E_DATA_MISMATCH);
512
0
    goto out;
513
0
  }
514
515
      /* We start searching with the first entry.  */
516
0
      runp = &scn->data_list;
517
518
0
      while (1)
519
0
  {
520
    /* If `data' does not match any known record punt.  */
521
0
    if (runp == NULL)
522
0
      {
523
0
        __libelf_seterrno (ELF_E_DATA_MISMATCH);
524
0
        goto out;
525
0
      }
526
527
0
    if (&runp->data.d == data)
528
      /* Found the entry.  */
529
0
      break;
530
531
0
    runp = runp->next;
532
0
  }
533
534
      /* Return the data for the next data record.  */
535
0
      result = runp->next ? &runp->next->data.d : NULL;
536
0
      goto out;
537
0
    }
538
539
  /* If the data for this section was not yet initialized do it now.  */
540
66.8k
  if (scn->data_read == 0)
541
55.2k
    {
542
      /* We cannot acquire a write lock while we are holding a read
543
         lock.  Therefore give up the read lock and then get the write
544
         lock.  But this means that the data could meanwhile be
545
         modified, therefore start the tests again.  */
546
55.2k
      rwlock_unlock (elf->lock);
547
55.2k
      rwlock_wrlock (elf->lock);
548
55.2k
      locked = 1;
549
550
      /* Read the data from the file.  There is always a file (or
551
   memory region) associated with this descriptor since
552
   otherwise the `data_read' flag would be set.  */
553
55.2k
      if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
554
  /* Something went wrong.  The error value is already set.  */
555
1.36k
  goto out;
556
55.2k
    }
557
558
  /* At this point we know the raw data is available.  But it might be
559
     empty in case the section has size zero (for whatever reason).
560
     Now create the converted data in case this is necessary.  */
561
65.4k
  if (scn->data_list_rear == NULL)
562
54.2k
    __libelf_set_data_list_rdlock (scn, locked);
563
564
  /* Return the first data element in the list.  */
565
65.4k
  result = &scn->data_list.data.d;
566
567
66.8k
 out:
568
66.8k
  return result;
569
65.4k
}
570
571
Elf_Data *
572
elf_getdata (Elf_Scn *scn, Elf_Data *data)
573
66.8k
{
574
66.8k
  Elf_Data *result;
575
576
66.8k
  if (scn == NULL)
577
0
    return NULL;
578
579
66.8k
  rwlock_rdlock (scn->elf->lock);
580
66.8k
  result = __elf_getdata_rdlock (scn, data);
581
66.8k
  rwlock_unlock (scn->elf->lock);
582
583
66.8k
  return result;
584
66.8k
}
585
INTDEF(elf_getdata)