blob: 5a718f82e2621ba9e652bb939feab20bb989fc91 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Return the next data element from the section after possibly converting it.
Ulrich Drepperc07fbb32007-03-30 19:14:59 +00002 Copyright (C) 1998-2005, 2006, 2007 Red Hat, Inc.
Ulrich Drepper361df7d2006-04-04 21:38:57 +00003 This file is part of Red Hat elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5
Ulrich Drepper361df7d2006-04-04 21:38:57 +00006 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00009
Ulrich Drepper361df7d2006-04-04 21:38:57 +000010 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000014
Ulrich Drepper361df7d2006-04-04 21:38:57 +000015 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
Ulrich Drepper1e9ef502006-04-04 22:29:06 +000017 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
Ulrich Drepper361df7d2006-04-04 21:38:57 +000018
19 In addition, as a special exception, Red Hat, Inc. gives You the
20 additional right to link the code of Red Hat elfutils with code licensed
21 under any Open Source Initiative certified open source license
22 (http://www.opensource.org/licenses/index.php) which requires the
23 distribution of source code with any binary distribution and to
24 distribute linked combinations of the two. Non-GPL Code permitted under
25 this exception must only link to the code of Red Hat elfutils through
26 those well defined interfaces identified in the file named EXCEPTION
27 found in the source code files (the "Approved Interfaces"). The files
28 of Non-GPL Code may instantiate templates or use macros or inline
29 functions from the Approved Interfaces without causing the resulting
30 work to be covered by the GNU General Public License. Only Red Hat,
31 Inc. may make changes or additions to the list of Approved Interfaces.
32 Red Hat's grant of this exception is conditioned upon your not adding
33 any new exceptions. If you wish to add a new Approved Interface or
34 exception, please contact Red Hat. You must obey the GNU General Public
35 License in all respects for all of the Red Hat elfutils code and other
36 code used in conjunction with Red Hat elfutils except the Non-GPL Code
37 covered by this exception. If you modify this file, you may extend this
38 exception to your version of the file, but you are not obligated to do
39 so. If you do not wish to provide this exception without modification,
40 you must delete this exception statement from your version and license
41 this file solely under the GPL without exception.
42
43 Red Hat elfutils is an included package of the Open Invention Network.
44 An included package of the Open Invention Network is a package for which
45 Open Invention Network licensees cross-license their patents. No patent
46 license is granted, either expressly or impliedly, by designation as an
47 included package. Should you wish to participate in the Open Invention
48 Network licensing program, please visit www.openinventionnetwork.com
49 <http://www.openinventionnetwork.com>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000050
51#ifdef HAVE_CONFIG_H
52# include <config.h>
53#endif
54
Ulrich Drepperfbe998a2005-08-29 16:27:10 +000055#include <errno.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000056#include <stddef.h>
57#include <string.h>
58#include <unistd.h>
59
60#include "libelfP.h"
Ulrich Drepperfbe998a2005-08-29 16:27:10 +000061#include <system.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000062#include "common.h"
63#include "elf-knowledge.h"
64
65
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000066#define TYPEIDX(Sh_Type) \
67 (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM \
68 ? Sh_Type \
Ulrich Drepper8ae58142006-07-12 05:22:32 +000069 : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW \
70 ? SHT_NUM + Sh_Type - SHT_GNU_HASH \
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000071 : 0))
72
Ulrich Drepperc07fbb32007-03-30 19:14:59 +000073/* Associate section types with libelf types. */
74static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000075 {
Ulrich Drepperc07fbb32007-03-30 19:14:59 +000076 [EV_CURRENT - 1] =
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000077 {
Ulrich Drepperc07fbb32007-03-30 19:14:59 +000078 [SHT_SYMTAB] = ELF_T_SYM,
79 [SHT_RELA] = ELF_T_RELA,
80 [SHT_HASH] = ELF_T_WORD,
81 [SHT_DYNAMIC] = ELF_T_DYN,
82 [SHT_REL] = ELF_T_REL,
83 [SHT_DYNSYM] = ELF_T_SYM,
84 [SHT_INIT_ARRAY] = ELF_T_ADDR,
85 [SHT_FINI_ARRAY] = ELF_T_ADDR,
86 [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
87 [SHT_GROUP] = ELF_T_WORD,
88 [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
Roland McGrathc76f0b02007-09-27 07:31:33 +000089 [SHT_NOTE] = ELF_T_NHDR,
Ulrich Drepperc07fbb32007-03-30 19:14:59 +000090 [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
91 [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
92 [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
93 [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
94 [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
95 [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
96 [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000097 }
Ulrich Drepperc07fbb32007-03-30 19:14:59 +000098 };
99
100#if !ALLOW_UNALIGNED
101/* Associate libelf types with their internal alignment requirements. */
102const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
103 {
104# define TYPE_ALIGNS(Bits) \
105 { \
106 [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)), \
107 [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)), \
108 [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)), \
109 [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)), \
110 [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)), \
111 [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)), \
112 [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)), \
113 [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)), \
114 [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)), \
115 [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)), \
116 [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)), \
117 [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)), \
118 [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)), \
119 [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)), \
Roland McGrathc76f0b02007-09-27 07:31:33 +0000120 [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)), \
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000121 }
122 [EV_CURRENT - 1] =
123 {
124 [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
125 [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
126 }
127# undef TYPE_ALIGNS
128 };
129#endif
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000130
131
132/* Convert the data in the current section. */
133static void
134convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000135 int data, size_t size, Elf_Type type)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000136{
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000137 const size_t align = __libelf_type_align (eclass, type);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000138
139 if (data == MY_ELFDATA)
140 {
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000141 if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000142 /* No need to copy, we can use the raw data. */
143 scn->data_base = scn->rawdata_base;
144 else
145 {
146 scn->data_base = (char *) malloc (size);
147 if (scn->data_base == NULL)
148 {
149 __libelf_seterrno (ELF_E_NOMEM);
150 return;
151 }
152
153 /* The copy will be appropriately aligned for direct access. */
154 memcpy (scn->data_base, scn->rawdata_base, size);
155 }
156 }
157 else
158 {
159 xfct_t fp;
160
161 scn->data_base = (char *) malloc (size);
162 if (scn->data_base == NULL)
163 {
164 __libelf_seterrno (ELF_E_NOMEM);
165 return;
166 }
167
168 /* Get the conversion function. */
169#if EV_NUM != 2
170 fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
171#else
172 fp = __elf_xfctstom[0][0][eclass - 1][type];
173#endif
174
175 fp (scn->data_base, scn->rawdata_base, size, 0);
176 }
177
178 scn->data_list.data.d.d_buf = scn->data_base;
179 scn->data_list.data.d.d_size = size;
180 scn->data_list.data.d.d_type = type;
181 scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
182 scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
183 scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
184
185 scn->data_list.data.s = scn;
186}
187
188
189/* Store the information for the raw data in the `rawdata' element. */
190int
Ulrich Drepper077c65f2006-07-12 19:54:51 +0000191internal_function
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000192__libelf_set_rawdata_wrlock (Elf_Scn *scn)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000193{
194 size_t offset;
195 size_t size;
196 size_t align;
197 int type;
198 Elf *elf = scn->elf;
199
200 if (elf->class == ELFCLASS32)
201 {
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000202 Elf32_Shdr *shdr
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000203 = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000204
205 if (shdr == NULL)
206 /* Something went terribly wrong. */
207 return 1;
208
209 offset = shdr->sh_offset;
210 size = shdr->sh_size;
211 type = shdr->sh_type;
212 align = shdr->sh_addralign;
213 }
214 else
215 {
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000216 Elf64_Shdr *shdr
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000217 = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000218
219 if (shdr == NULL)
220 /* Something went terribly wrong. */
221 return 1;
222
223 offset = shdr->sh_offset;
224 size = shdr->sh_size;
225 type = shdr->sh_type;
226 align = shdr->sh_addralign;
227 }
228
229 /* If the section has no data (for whatever reason), leave the `d_buf'
230 pointer NULL. */
231 if (size != 0 && type != SHT_NOBITS)
232 {
233 /* First a test whether the section is valid at all. */
234 size_t entsize;
235
236 if (type == SHT_HASH)
237 {
238 GElf_Ehdr ehdr_mem;
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000239 GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000240 entsize = SH_ENTSIZE_HASH (ehdr);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000241 }
242 else
243 {
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000244 Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
Roland McGrathc76f0b02007-09-27 07:31:33 +0000245 if (t == ELF_T_VDEF || t == ELF_T_NHDR
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000246 || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
247 entsize = 1;
248 else
249 entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000250 }
251
252 /* We assume it is an array of bytes if it is none of the structured
253 sections we know of. */
254 if (entsize == 0)
255 entsize = 1;
256
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000257 if (unlikely (size % entsize != 0))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000258 {
259 __libelf_seterrno (ELF_E_INVALID_DATA);
260 return 1;
261 }
262
263 /* We can use the mapped or loaded data if available. */
264 if (elf->map_address != NULL)
265 {
266 /* First see whether the information in the section header is
267 valid and it does not ask for too much. */
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000268 if (unlikely (offset + size > elf->maximum_size))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000269 {
270 /* Something is wrong. */
271 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
272 return 1;
273 }
274
275 scn->rawdata_base = scn->rawdata.d.d_buf
276 = (char *) elf->map_address + elf->start_offset + offset;
277 }
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000278 else if (likely (elf->fildes != -1))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000279 {
280 /* We have to read the data from the file. Allocate the needed
281 memory. */
282 scn->rawdata_base = scn->rawdata.d.d_buf
283 = (char *) malloc (size);
284 if (scn->rawdata.d.d_buf == NULL)
285 {
286 __libelf_seterrno (ELF_E_NOMEM);
287 return 1;
288 }
289
Ulrich Drepperfbe998a2005-08-29 16:27:10 +0000290 ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
291 elf->start_offset + offset);
292 if (unlikely ((size_t) n != size))
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000293 {
294 /* Cannot read the data. */
295 free (scn->rawdata.d.d_buf);
296 scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
297 __libelf_seterrno (ELF_E_READ_ERROR);
298 return 1;
299 }
300 }
301 else
302 {
303 /* The file descriptor is already closed, we cannot get the data
304 anymore. */
305 __libelf_seterrno (ELF_E_FD_DISABLED);
306 return 1;
307 }
308 }
309
310 scn->rawdata.d.d_size = size;
311 /* Some broken ELF ABI for 64-bit machines use the wrong hash table
312 entry size. See elf-knowledge.h for more information. */
313 if (type == SHT_HASH && elf->class == ELFCLASS64)
314 {
315 GElf_Ehdr ehdr_mem;
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000316 GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000317 scn->rawdata.d.d_type
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000318 = (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000319 }
320 else
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000321 scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000322 scn->rawdata.d.d_off = 0;
323 scn->rawdata.d.d_align = align;
324 if (elf->class == ELFCLASS32
325 || (offsetof (struct Elf, state.elf32.ehdr)
326 == offsetof (struct Elf, state.elf64.ehdr)))
327 scn->rawdata.d.d_version =
328 elf->state.elf32.ehdr->e_ident[EI_VERSION];
329 else
330 scn->rawdata.d.d_version =
331 elf->state.elf64.ehdr->e_ident[EI_VERSION];
332
333 scn->rawdata.s = scn;
334
335 scn->data_read = 1;
336
337 /* We actually read data from the file. At least we tried. */
338 scn->flags |= ELF_F_FILEDATA;
339
340 return 0;
341}
342
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000343int
344internal_function
345__libelf_set_rawdata (Elf_Scn *scn)
346{
347 int result;
348
349 if (scn == NULL)
350 return 1;
351
352 rwlock_wrlock (scn->elf->lock);
353 result = __libelf_set_rawdata_wrlock (scn);
354 rwlock_unlock (scn->elf->lock);
355
356 return result;
357}
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000358
359Elf_Data *
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000360internal_function
361__elf_getdata_rdlock (scn, data)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000362 Elf_Scn *scn;
363 Elf_Data *data;
364{
365 Elf_Data *result = NULL;
366 Elf *elf;
Ulrich Drepper02f66452008-12-04 05:58:16 +0000367 int locked = 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000368
369 if (scn == NULL)
370 return NULL;
371
372 if (unlikely (scn->elf->kind != ELF_K_ELF))
373 {
374 __libelf_seterrno (ELF_E_INVALID_HANDLE);
375 return NULL;
376 }
377
378 /* We will need this multiple times later on. */
379 elf = scn->elf;
380
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000381 /* If `data' is not NULL this means we are not addressing the initial
382 data in the file. But this also means this data is already read
383 (since otherwise it is not possible to have a valid `data' pointer)
384 and all the data structures are initialized as well. In this case
385 we can simply walk the list of data records. */
386 if (data != NULL)
387 {
388 Elf_Data_List *runp;
389
390 /* It is not possible that if DATA is not NULL the first entry is
391 returned. But this also means that there must be a first data
392 entry. */
393 if (scn->data_list_rear == NULL
394 /* The section the reference data is for must match the section
395 parameter. */
396 || unlikely (((Elf_Data_Scn *) data)->s != scn))
397 {
398 __libelf_seterrno (ELF_E_DATA_MISMATCH);
399 goto out;
400 }
401
402 /* We start searching with the first entry. */
403 runp = &scn->data_list;
404
405 while (1)
406 {
407 /* If `data' does not match any known record punt. */
408 if (runp == NULL)
409 {
410 __libelf_seterrno (ELF_E_DATA_MISMATCH);
411 goto out;
412 }
413
414 if (&runp->data.d == data)
415 /* Found the entry. */
416 break;
417
418 runp = runp->next;
419 }
420
421 /* Return the data for the next data record. */
422 result = runp->next ? &runp->next->data.d : NULL;
423 goto out;
424 }
425
426 /* If the data for this section was not yet initialized do it now. */
427 if (scn->data_read == 0)
428 {
429 /* We cannot acquire a write lock while we are holding a read
430 lock. Therefore give up the read lock and then get the write
431 lock. But this means that the data could meanwhile be
432 modified, therefore start the tests again. */
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000433 rwlock_unlock (elf->lock);
434 rwlock_wrlock (elf->lock);
Ulrich Drepper02f66452008-12-04 05:58:16 +0000435 locked = 1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000436
437 /* Read the data from the file. There is always a file (or
438 memory region) associated with this descriptor since
439 otherwise the `data_read' flag would be set. */
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000440 if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000441 /* Something went wrong. The error value is already set. */
442 goto out;
443 }
444
445 /* At this point we know the raw data is available. But it might be
446 empty in case the section has size zero (for whatever reason).
447 Now create the converted data in case this is necessary. */
448 if (scn->data_list_rear == NULL)
449 {
450 if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
Ulrich Drepper02f66452008-12-04 05:58:16 +0000451 {
452 if (!locked)
453 {
454 rwlock_unlock (elf->lock);
455 rwlock_wrlock (elf->lock);
456 if (scn->data_list_rear != NULL)
457 goto pass;
458 }
459
460 /* Convert according to the version and the type. */
461 convert_data (scn, __libelf_version, elf->class,
462 (elf->class == ELFCLASS32
463 || (offsetof (struct Elf, state.elf32.ehdr)
464 == offsetof (struct Elf, state.elf64.ehdr))
465 ? elf->state.elf32.ehdr->e_ident[EI_DATA]
466 : elf->state.elf64.ehdr->e_ident[EI_DATA]),
467 scn->rawdata.d.d_size, scn->rawdata.d.d_type);
468 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000469 else
Petr Machatad7b12c62010-04-06 14:17:41 +0200470 {
471 /* This is an empty or NOBITS section. There is no buffer but
472 the size information etc is important. */
473 scn->data_list.data.d = scn->rawdata.d;
474 scn->data_list.data.s = scn;
475 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000476
477 scn->data_list_rear = &scn->data_list;
478 }
479
480 /* If no data is present we cannot return any. */
481 if (scn->data_list_rear != NULL)
Ulrich Drepper02f66452008-12-04 05:58:16 +0000482 pass:
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000483 /* Return the first data element in the list. */
484 result = &scn->data_list.data.d;
485
486 out:
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000487 return result;
488}
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000489
490Elf_Data *
491elf_getdata (scn, data)
492 Elf_Scn *scn;
493 Elf_Data *data;
494{
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000495 Elf_Data *result;
496
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000497 if (scn == NULL)
498 return NULL;
499
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000500 rwlock_rdlock (scn->elf->lock);
501 result = __elf_getdata_rdlock (scn, data);
502 rwlock_unlock (scn->elf->lock);
503
504 return result;
Ulrich Drepperd56e2322008-08-16 03:09:13 +0000505}
Roland McGrathb4d6f0f2008-08-25 22:55:17 +0000506INTDEF(elf_getdata)