Coverage Report

Created: 2026-07-24 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
215k
  (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM              \
46
215k
   ? Sh_Type                      \
47
215k
   : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW            \
48
79.7k
      ? SHT_NUM + Sh_Type - SHT_GNU_HASH              \
49
79.7k
      : 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
56.0k
{
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
56.0k
  if (sh_type == SHT_HASH && ehdr->e_ident[EI_CLASS] == ELFCLASS64)
123
1.62k
    {
124
1.62k
      return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
125
1.62k
    }
126
54.4k
  else
127
54.4k
    {
128
54.4k
      Elf_Type t = shtype_map[TYPEIDX (sh_type)];
129
      /* Special case for GNU Property notes.  */
130
54.4k
      if (t == ELF_T_NHDR && align == 8)
131
2.05k
  t = ELF_T_NHDR8;
132
54.4k
      return t;
133
54.4k
    }
134
56.0k
}
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
122k
{
141
122k
  const size_t align = __libelf_type_align (eclass, type);
142
143
  /* Do we need to convert the data and/or adjust for alignment?  */
144
122k
  if (data == MY_ELFDATA || type == ELF_T_BYTE)
145
63.5k
    {
146
63.5k
      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
147
  /* No need to copy, we can use the raw data.  */
148
61.7k
  scn->data_base = scn->rawdata_base;
149
1.81k
      else
150
1.81k
  {
151
1.81k
    scn->data_base = malloc (size);
152
1.81k
    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
1.81k
    memcpy (scn->data_base, scn->rawdata_base, size);
160
1.81k
  }
161
63.5k
    }
162
58.4k
  else
163
58.4k
    {
164
58.4k
      xfct_t fp;
165
166
58.4k
      scn->data_base = malloc (size);
167
58.4k
      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
58.4k
      char *rawdata_source;
176
58.4k
      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
177
56.4k
  rawdata_source = scn->rawdata_base;
178
2.06k
      else
179
2.06k
  {
180
2.06k
    rawdata_source = malloc (size);
181
2.06k
    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
2.06k
    memcpy (rawdata_source, scn->rawdata_base, size);
189
2.06k
  }
190
191
      /* Get the conversion function.  */
192
58.4k
      fp = __elf_xfctstom[eclass - 1][type];
193
194
58.4k
      fp (scn->data_base, rawdata_source, size, 0);
195
196
58.4k
      if (rawdata_source != scn->rawdata_base)
197
2.06k
  free (rawdata_source);
198
58.4k
    }
199
200
122k
  scn->data_list.data.d.d_buf = scn->data_base;
201
122k
  scn->data_list.data.d.d_size = size;
202
122k
  scn->data_list.data.d.d_type = type;
203
122k
  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
204
122k
  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
205
122k
  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
206
207
122k
  scn->data_list.data.s = scn;
208
122k
}
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
846k
{
216
846k
  Elf64_Off offset;
217
846k
  Elf64_Xword size;
218
846k
  Elf64_Xword align;
219
846k
  Elf64_Xword flags;
220
846k
  int type;
221
846k
  Elf *elf = scn->elf;
222
223
846k
  if (elf->class == ELFCLASS32)
224
657k
    {
225
657k
      Elf32_Shdr *shdr
226
657k
  = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
227
228
657k
      if (shdr == NULL)
229
  /* Something went terribly wrong.  */
230
0
  return 1;
231
232
657k
      offset = shdr->sh_offset;
233
657k
      size = shdr->sh_size;
234
657k
      type = shdr->sh_type;
235
657k
      align = shdr->sh_addralign;
236
657k
      flags = shdr->sh_flags;
237
657k
    }
238
188k
  else
239
188k
    {
240
188k
      Elf64_Shdr *shdr
241
188k
  = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
242
243
188k
      if (shdr == NULL)
244
  /* Something went terribly wrong.  */
245
0
  return 1;
246
247
188k
      offset = shdr->sh_offset;
248
188k
      size = shdr->sh_size;
249
188k
      type = shdr->sh_type;
250
188k
      align = shdr->sh_addralign;
251
188k
      flags = shdr->sh_flags;
252
188k
    }
253
254
  /* If the section has no data (for whatever reason), leave the `d_buf'
255
     pointer NULL.  */
256
846k
  if (size != 0 && type != SHT_NOBITS)
257
795k
    {
258
      /* First a test whether the section is valid at all.  */
259
795k
      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
795k
      if ((flags & SHF_COMPRESSED) != 0)
266
631k
  {
267
631k
    entsize = 1;
268
631k
    align = __libelf_type_align (elf->class, ELF_T_CHDR);
269
631k
  }
270
164k
      else if (type == SHT_HASH)
271
4.11k
  {
272
4.11k
    GElf_Ehdr ehdr_mem;
273
4.11k
    GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
274
4.11k
    if (unlikely (ehdr == NULL))
275
0
      return 1;
276
4.11k
    entsize = SH_ENTSIZE_HASH (ehdr);
277
4.11k
  }
278
160k
      else
279
160k
  {
280
160k
    Elf_Type t = shtype_map[TYPEIDX (type)];
281
160k
    if (t == ELF_T_NHDR && align == 8)
282
1.90k
      t = ELF_T_NHDR8;
283
160k
    if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
284
151k
        || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
285
10.9k
      entsize = 1;
286
149k
    else
287
149k
      entsize = __libelf_type_sizes[elf->class - 1][t];
288
160k
  }
289
290
      /* We assume it is an array of bytes if it is none of the structured
291
   sections we know of.  */
292
795k
      if (entsize == 0)
293
0
  entsize = 1;
294
295
795k
      if (unlikely (size % entsize != 0))
296
1.66k
  {
297
1.66k
    __libelf_seterrno (ELF_E_INVALID_DATA);
298
1.66k
    return 1;
299
1.66k
  }
300
301
      /* We can use the mapped or loaded data if available.  */
302
794k
      if (elf->map_address != NULL)
303
135k
  {
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
135k
    if (unlikely (offset > elf->maximum_size
308
135k
        || elf->maximum_size - offset < size))
309
125k
      {
310
        /* Something is wrong.  */
311
125k
        __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
312
125k
        return 1;
313
125k
      }
314
315
10.7k
    scn->rawdata_base = scn->rawdata.d.d_buf
316
10.7k
      = (char *) elf->map_address + elf->start_offset + offset;
317
10.7k
  }
318
658k
      else if (likely (elf->fildes != -1))
319
658k
  {
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
658k
    if (unlikely (offset > elf->maximum_size
324
658k
      || elf->maximum_size - offset < size))
325
563k
      {
326
        /* Something is wrong.  */
327
563k
        __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
328
563k
        return 1;
329
563k
      }
330
331
    /* We have to read the data from the file.  Allocate the needed
332
       memory.  */
333
95.0k
    scn->rawdata_base = scn->rawdata.d.d_buf = malloc (size);
334
95.0k
    if (scn->rawdata.d.d_buf == NULL)
335
0
      {
336
0
        __libelf_seterrno (ELF_E_NOMEM);
337
0
        return 1;
338
0
      }
339
340
95.0k
    ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
341
95.0k
           elf->start_offset + offset);
342
95.0k
    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
95.0k
  }
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
794k
    }
359
360
156k
  scn->rawdata.d.d_size = size;
361
362
  /* Compressed data always has type ELF_T_CHDR regardless of the
363
     section type.  */
364
156k
  if ((flags & SHF_COMPRESSED) != 0)
365
104k
    scn->rawdata.d.d_type = ELF_T_CHDR;
366
52.3k
  else
367
52.3k
    {
368
52.3k
      GElf_Ehdr ehdr_mem;
369
52.3k
      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
370
52.3k
      if (unlikely (ehdr == NULL))
371
0
  return 1;
372
52.3k
      scn->rawdata.d.d_type = __libelf_data_type (ehdr, type, align);
373
52.3k
    }
374
156k
  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
156k
  align = align ?: 1;
387
156k
  if (type != SHT_NOBITS && align > offset)
388
99.0k
    {
389
      /* Align the offset to the next power of two. Uses algorithm from
390
         https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
391
99.0k
      align = offset - 1;
392
99.0k
      align |= align >> 1;
393
99.0k
      align |= align >> 2;
394
99.0k
      align |= align >> 4;
395
99.0k
      align |= align >> 8;
396
99.0k
      align |= align >> 16;
397
99.0k
      align |= align >> 32;
398
99.0k
      align++;
399
99.0k
    }
400
156k
  scn->rawdata.d.d_align = align;
401
156k
  if (elf->class == ELFCLASS32
402
20.4k
      || (offsetof (struct Elf, state.elf32.ehdr)
403
20.4k
    == offsetof (struct Elf, state.elf64.ehdr)))
404
156k
    scn->rawdata.d.d_version =
405
156k
      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
156k
  scn->rawdata.s = scn;
411
412
156k
  scn->data_read = 1;
413
414
  /* We actually read data from the file.  At least we tried.  */
415
156k
  scn->flags |= ELF_F_FILEDATA;
416
417
156k
  return 0;
418
156k
}
419
420
int
421
internal_function
422
__libelf_set_rawdata (Elf_Scn *scn)
423
3.46k
{
424
3.46k
  int result;
425
426
3.46k
  if (scn == NULL)
427
0
    return 1;
428
429
3.46k
  rwlock_wrlock (scn->elf->lock);
430
3.46k
  result = __libelf_set_rawdata_wrlock (scn);
431
3.46k
  rwlock_unlock (scn->elf->lock);
432
433
3.46k
  return result;
434
3.46k
}
435
436
void
437
internal_function
438
__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
439
173k
{
440
173k
  if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
441
122k
    {
442
122k
      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
122k
      if (!wrlocked)
447
699
  {
448
699
    rwlock_unlock (elf->lock);
449
699
    rwlock_wrlock (elf->lock);
450
699
    if (scn->data_list_rear != NULL)
451
0
      return;
452
699
  }
453
454
      /* Convert according to the version and the type.   */
455
122k
      convert_data (scn, elf->class,
456
122k
        (elf->class == ELFCLASS32
457
13.6k
         || (offsetof (struct Elf, state.elf32.ehdr)
458
13.6k
       == offsetof (struct Elf, state.elf64.ehdr))
459
122k
         ? elf->state.elf32.ehdr->e_ident[EI_DATA]
460
122k
         : elf->state.elf64.ehdr->e_ident[EI_DATA]),
461
122k
        scn->rawdata.d.d_size, scn->rawdata.d.d_type);
462
122k
    }
463
51.1k
  else
464
51.1k
    {
465
      /* This is an empty or NOBITS section.  There is no buffer but
466
   the size information etc is important.  */
467
51.1k
      scn->data_list.data.d = scn->rawdata.d;
468
51.1k
      scn->data_list.data.s = scn;
469
51.1k
    }
470
471
173k
  scn->data_list_rear = &scn->data_list;
472
173k
}
473
474
Elf_Data *
475
internal_function
476
__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
477
1.69M
{
478
1.69M
  Elf_Data *result = NULL;
479
1.69M
  Elf *elf;
480
1.69M
  int locked = 0;
481
482
1.69M
  if (scn == NULL)
483
0
    return NULL;
484
485
1.69M
  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
1.69M
  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
1.69M
  if (data != NULL)
500
48.9k
    {
501
48.9k
      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
48.9k
      if (scn->data_list_rear == NULL
507
    /* The section the reference data is for must match the section
508
       parameter.  */
509
48.9k
    || 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
48.9k
      runp = &scn->data_list;
517
518
48.9k
      while (1)
519
48.9k
  {
520
    /* If `data' does not match any known record punt.  */
521
48.9k
    if (runp == NULL)
522
0
      {
523
0
        __libelf_seterrno (ELF_E_DATA_MISMATCH);
524
0
        goto out;
525
0
      }
526
527
48.9k
    if (&runp->data.d == data)
528
      /* Found the entry.  */
529
48.9k
      break;
530
531
0
    runp = runp->next;
532
0
  }
533
534
      /* Return the data for the next data record.  */
535
48.9k
      result = runp->next ? &runp->next->data.d : NULL;
536
48.9k
      goto out;
537
48.9k
    }
538
539
  /* If the data for this section was not yet initialized do it now.  */
540
1.64M
  if (scn->data_read == 0)
541
741k
    {
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
741k
      rwlock_unlock (elf->lock);
547
741k
      rwlock_wrlock (elf->lock);
548
741k
      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
741k
      if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
554
  /* Something went wrong.  The error value is already set.  */
555
593k
  goto out;
556
741k
    }
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
1.05M
  if (scn->data_list_rear == NULL)
562
149k
    __libelf_set_data_list_rdlock (scn, locked);
563
564
  /* Return the first data element in the list.  */
565
1.05M
  result = &scn->data_list.data.d;
566
567
1.69M
 out:
568
1.69M
  return result;
569
1.05M
}
570
571
Elf_Data *
572
elf_getdata (Elf_Scn *scn, Elf_Data *data)
573
1.69M
{
574
1.69M
  Elf_Data *result;
575
576
1.69M
  if (scn == NULL)
577
0
    return NULL;
578
579
1.69M
  rwlock_rdlock (scn->elf->lock);
580
1.69M
  result = __elf_getdata_rdlock (scn, data);
581
1.69M
  rwlock_unlock (scn->elf->lock);
582
583
1.69M
  return result;
584
1.69M
}
585
586
Elf_Data *
587
internal_function
588
__elf_getdata_wrlock (Elf_Scn *scn, Elf_Data *data)
589
0
{
590
0
  Elf_Data *result;
591
592
0
  if (scn == NULL)
593
0
    return NULL;
594
595
0
  result = __elf_getdata_rdlock (scn, data);
596
597
0
  return result;
598
0
}
599
INTDEF(elf_getdata)