1*7304104dSAndroid Build Coastguard Worker /* Return section header.
2*7304104dSAndroid Build Coastguard Worker Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker Written by Ulrich Drepper <[email protected]>, 1998.
5*7304104dSAndroid Build Coastguard Worker
6*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
7*7304104dSAndroid Build Coastguard Worker it under the terms of either
8*7304104dSAndroid Build Coastguard Worker
9*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
10*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
11*7304104dSAndroid Build Coastguard Worker your option) any later version
12*7304104dSAndroid Build Coastguard Worker
13*7304104dSAndroid Build Coastguard Worker or
14*7304104dSAndroid Build Coastguard Worker
15*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
16*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
17*7304104dSAndroid Build Coastguard Worker your option) any later version
18*7304104dSAndroid Build Coastguard Worker
19*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
20*7304104dSAndroid Build Coastguard Worker
21*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
22*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
23*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24*7304104dSAndroid Build Coastguard Worker General Public License for more details.
25*7304104dSAndroid Build Coastguard Worker
26*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
27*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
28*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
29*7304104dSAndroid Build Coastguard Worker
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker
34*7304104dSAndroid Build Coastguard Worker #include <assert.h>
35*7304104dSAndroid Build Coastguard Worker #include <errno.h>
36*7304104dSAndroid Build Coastguard Worker #include <stdbool.h>
37*7304104dSAndroid Build Coastguard Worker
38*7304104dSAndroid Build Coastguard Worker #include "libelfP.h"
39*7304104dSAndroid Build Coastguard Worker #include "common.h"
40*7304104dSAndroid Build Coastguard Worker
41*7304104dSAndroid Build Coastguard Worker #ifndef LIBELFBITS
42*7304104dSAndroid Build Coastguard Worker # define LIBELFBITS 32
43*7304104dSAndroid Build Coastguard Worker #endif
44*7304104dSAndroid Build Coastguard Worker
45*7304104dSAndroid Build Coastguard Worker
ElfW2(LIBELFBITS,Shdr)46*7304104dSAndroid Build Coastguard Worker static ElfW2(LIBELFBITS,Shdr) *
47*7304104dSAndroid Build Coastguard Worker load_shdr_wrlock (Elf_Scn *scn)
48*7304104dSAndroid Build Coastguard Worker {
49*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *result;
50*7304104dSAndroid Build Coastguard Worker
51*7304104dSAndroid Build Coastguard Worker /* Read the section header table. */
52*7304104dSAndroid Build Coastguard Worker Elf *elf = scn->elf;
53*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
54*7304104dSAndroid Build Coastguard Worker
55*7304104dSAndroid Build Coastguard Worker /* Try again, maybe the data is there now. */
56*7304104dSAndroid Build Coastguard Worker result = scn->shdr.ELFW(e,LIBELFBITS);
57*7304104dSAndroid Build Coastguard Worker if (result != NULL)
58*7304104dSAndroid Build Coastguard Worker goto out;
59*7304104dSAndroid Build Coastguard Worker
60*7304104dSAndroid Build Coastguard Worker size_t shnum;
61*7304104dSAndroid Build Coastguard Worker if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
62*7304104dSAndroid Build Coastguard Worker || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
63*7304104dSAndroid Build Coastguard Worker goto out;
64*7304104dSAndroid Build Coastguard Worker size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
65*7304104dSAndroid Build Coastguard Worker
66*7304104dSAndroid Build Coastguard Worker /* Allocate memory for the section headers. We know the number
67*7304104dSAndroid Build Coastguard Worker of entries from the ELF header. */
68*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
69*7304104dSAndroid Build Coastguard Worker (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
70*7304104dSAndroid Build Coastguard Worker if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
71*7304104dSAndroid Build Coastguard Worker {
72*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_NOMEM);
73*7304104dSAndroid Build Coastguard Worker goto out;
74*7304104dSAndroid Build Coastguard Worker }
75*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
76*7304104dSAndroid Build Coastguard Worker
77*7304104dSAndroid Build Coastguard Worker if (elf->map_address != NULL)
78*7304104dSAndroid Build Coastguard Worker {
79*7304104dSAndroid Build Coastguard Worker /* First see whether the information in the ELF header is
80*7304104dSAndroid Build Coastguard Worker valid and it does not ask for too much. */
81*7304104dSAndroid Build Coastguard Worker if (unlikely (ehdr->e_shoff >= elf->maximum_size)
82*7304104dSAndroid Build Coastguard Worker || unlikely (elf->maximum_size - ehdr->e_shoff < size))
83*7304104dSAndroid Build Coastguard Worker {
84*7304104dSAndroid Build Coastguard Worker /* Something is wrong. */
85*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
86*7304104dSAndroid Build Coastguard Worker goto free_and_out;
87*7304104dSAndroid Build Coastguard Worker }
88*7304104dSAndroid Build Coastguard Worker
89*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *notcvt;
90*7304104dSAndroid Build Coastguard Worker
91*7304104dSAndroid Build Coastguard Worker /* All the data is already mapped. If we could use it
92*7304104dSAndroid Build Coastguard Worker directly this would already have happened. Unless
93*7304104dSAndroid Build Coastguard Worker we allocated the memory ourselves and the ELF_F_MALLOCED
94*7304104dSAndroid Build Coastguard Worker flag is set. */
95*7304104dSAndroid Build Coastguard Worker void *file_shdr = ((char *) elf->map_address
96*7304104dSAndroid Build Coastguard Worker + elf->start_offset + ehdr->e_shoff);
97*7304104dSAndroid Build Coastguard Worker
98*7304104dSAndroid Build Coastguard Worker assert ((elf->flags & ELF_F_MALLOCED)
99*7304104dSAndroid Build Coastguard Worker || ehdr->e_ident[EI_DATA] != MY_ELFDATA
100*7304104dSAndroid Build Coastguard Worker || elf->cmd == ELF_C_READ_MMAP
101*7304104dSAndroid Build Coastguard Worker || (! ALLOW_UNALIGNED
102*7304104dSAndroid Build Coastguard Worker && ((uintptr_t) file_shdr
103*7304104dSAndroid Build Coastguard Worker & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
104*7304104dSAndroid Build Coastguard Worker
105*7304104dSAndroid Build Coastguard Worker /* Now copy the data and at the same time convert the byte order. */
106*7304104dSAndroid Build Coastguard Worker if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
107*7304104dSAndroid Build Coastguard Worker {
108*7304104dSAndroid Build Coastguard Worker assert ((elf->flags & ELF_F_MALLOCED)
109*7304104dSAndroid Build Coastguard Worker || elf->cmd == ELF_C_READ_MMAP
110*7304104dSAndroid Build Coastguard Worker || ! ALLOW_UNALIGNED);
111*7304104dSAndroid Build Coastguard Worker memcpy (shdr, file_shdr, size);
112*7304104dSAndroid Build Coastguard Worker }
113*7304104dSAndroid Build Coastguard Worker else
114*7304104dSAndroid Build Coastguard Worker {
115*7304104dSAndroid Build Coastguard Worker bool copy = ! (ALLOW_UNALIGNED
116*7304104dSAndroid Build Coastguard Worker || ((uintptr_t) file_shdr
117*7304104dSAndroid Build Coastguard Worker & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
118*7304104dSAndroid Build Coastguard Worker == 0);
119*7304104dSAndroid Build Coastguard Worker if (! copy)
120*7304104dSAndroid Build Coastguard Worker notcvt = (ElfW2(LIBELFBITS,Shdr) *)
121*7304104dSAndroid Build Coastguard Worker ((char *) elf->map_address
122*7304104dSAndroid Build Coastguard Worker + elf->start_offset + ehdr->e_shoff);
123*7304104dSAndroid Build Coastguard Worker else
124*7304104dSAndroid Build Coastguard Worker {
125*7304104dSAndroid Build Coastguard Worker notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
126*7304104dSAndroid Build Coastguard Worker if (unlikely (notcvt == NULL))
127*7304104dSAndroid Build Coastguard Worker {
128*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_NOMEM);
129*7304104dSAndroid Build Coastguard Worker goto out;
130*7304104dSAndroid Build Coastguard Worker }
131*7304104dSAndroid Build Coastguard Worker memcpy (notcvt, ((char *) elf->map_address
132*7304104dSAndroid Build Coastguard Worker + elf->start_offset + ehdr->e_shoff),
133*7304104dSAndroid Build Coastguard Worker size);
134*7304104dSAndroid Build Coastguard Worker }
135*7304104dSAndroid Build Coastguard Worker
136*7304104dSAndroid Build Coastguard Worker for (size_t cnt = 0; cnt < shnum; ++cnt)
137*7304104dSAndroid Build Coastguard Worker {
138*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
139*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
140*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
141*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
142*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
143*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
144*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
145*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
146*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_addralign,
147*7304104dSAndroid Build Coastguard Worker notcvt[cnt].sh_addralign);
148*7304104dSAndroid Build Coastguard Worker CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
149*7304104dSAndroid Build Coastguard Worker
150*7304104dSAndroid Build Coastguard Worker /* If this is a section with an extended index add a
151*7304104dSAndroid Build Coastguard Worker reference in the section which uses the extended
152*7304104dSAndroid Build Coastguard Worker index. */
153*7304104dSAndroid Build Coastguard Worker if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
154*7304104dSAndroid Build Coastguard Worker && shdr[cnt].sh_link < shnum)
155*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
156*7304104dSAndroid Build Coastguard Worker = cnt;
157*7304104dSAndroid Build Coastguard Worker
158*7304104dSAndroid Build Coastguard Worker /* Set the own shndx_index field in case it has not yet
159*7304104dSAndroid Build Coastguard Worker been set. */
160*7304104dSAndroid Build Coastguard Worker if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
161*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
162*7304104dSAndroid Build Coastguard Worker = -1;
163*7304104dSAndroid Build Coastguard Worker }
164*7304104dSAndroid Build Coastguard Worker
165*7304104dSAndroid Build Coastguard Worker if (copy)
166*7304104dSAndroid Build Coastguard Worker free (notcvt);
167*7304104dSAndroid Build Coastguard Worker }
168*7304104dSAndroid Build Coastguard Worker }
169*7304104dSAndroid Build Coastguard Worker else if (likely (elf->fildes != -1))
170*7304104dSAndroid Build Coastguard Worker {
171*7304104dSAndroid Build Coastguard Worker /* Read the header. */
172*7304104dSAndroid Build Coastguard Worker ssize_t n = pread_retry (elf->fildes,
173*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).shdr, size,
174*7304104dSAndroid Build Coastguard Worker elf->start_offset + ehdr->e_shoff);
175*7304104dSAndroid Build Coastguard Worker if (unlikely ((size_t) n != size))
176*7304104dSAndroid Build Coastguard Worker {
177*7304104dSAndroid Build Coastguard Worker /* Severe problems. We cannot read the data. */
178*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_READ_ERROR);
179*7304104dSAndroid Build Coastguard Worker goto free_and_out;
180*7304104dSAndroid Build Coastguard Worker }
181*7304104dSAndroid Build Coastguard Worker
182*7304104dSAndroid Build Coastguard Worker /* If the byte order of the file is not the same as the one
183*7304104dSAndroid Build Coastguard Worker of the host convert the data now. */
184*7304104dSAndroid Build Coastguard Worker if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
185*7304104dSAndroid Build Coastguard Worker for (size_t cnt = 0; cnt < shnum; ++cnt)
186*7304104dSAndroid Build Coastguard Worker {
187*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_name);
188*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_type);
189*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_flags);
190*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_addr);
191*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_offset);
192*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_size);
193*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_link);
194*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_info);
195*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_addralign);
196*7304104dSAndroid Build Coastguard Worker CONVERT (shdr[cnt].sh_entsize);
197*7304104dSAndroid Build Coastguard Worker }
198*7304104dSAndroid Build Coastguard Worker }
199*7304104dSAndroid Build Coastguard Worker else
200*7304104dSAndroid Build Coastguard Worker {
201*7304104dSAndroid Build Coastguard Worker /* The file descriptor was already enabled and not all data was
202*7304104dSAndroid Build Coastguard Worker read. Undo the allocation. */
203*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_FD_DISABLED);
204*7304104dSAndroid Build Coastguard Worker
205*7304104dSAndroid Build Coastguard Worker free_and_out:
206*7304104dSAndroid Build Coastguard Worker free (shdr);
207*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
208*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
209*7304104dSAndroid Build Coastguard Worker
210*7304104dSAndroid Build Coastguard Worker goto out;
211*7304104dSAndroid Build Coastguard Worker }
212*7304104dSAndroid Build Coastguard Worker
213*7304104dSAndroid Build Coastguard Worker /* Set the pointers in the `scn's. */
214*7304104dSAndroid Build Coastguard Worker for (size_t cnt = 0; cnt < shnum; ++cnt)
215*7304104dSAndroid Build Coastguard Worker elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
216*7304104dSAndroid Build Coastguard Worker = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
217*7304104dSAndroid Build Coastguard Worker
218*7304104dSAndroid Build Coastguard Worker result = scn->shdr.ELFW(e,LIBELFBITS);
219*7304104dSAndroid Build Coastguard Worker assert (result != NULL);
220*7304104dSAndroid Build Coastguard Worker
221*7304104dSAndroid Build Coastguard Worker out:
222*7304104dSAndroid Build Coastguard Worker return result;
223*7304104dSAndroid Build Coastguard Worker }
224*7304104dSAndroid Build Coastguard Worker
225*7304104dSAndroid Build Coastguard Worker static bool
scn_valid(Elf_Scn * scn)226*7304104dSAndroid Build Coastguard Worker scn_valid (Elf_Scn *scn)
227*7304104dSAndroid Build Coastguard Worker {
228*7304104dSAndroid Build Coastguard Worker if (scn == NULL)
229*7304104dSAndroid Build Coastguard Worker return false;
230*7304104dSAndroid Build Coastguard Worker
231*7304104dSAndroid Build Coastguard Worker if (unlikely (scn->elf->state.elf.ehdr == NULL))
232*7304104dSAndroid Build Coastguard Worker {
233*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
234*7304104dSAndroid Build Coastguard Worker return false;
235*7304104dSAndroid Build Coastguard Worker }
236*7304104dSAndroid Build Coastguard Worker
237*7304104dSAndroid Build Coastguard Worker if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
238*7304104dSAndroid Build Coastguard Worker {
239*7304104dSAndroid Build Coastguard Worker __libelf_seterrno (ELF_E_INVALID_CLASS);
240*7304104dSAndroid Build Coastguard Worker return false;
241*7304104dSAndroid Build Coastguard Worker }
242*7304104dSAndroid Build Coastguard Worker
243*7304104dSAndroid Build Coastguard Worker return true;
244*7304104dSAndroid Build Coastguard Worker }
245*7304104dSAndroid Build Coastguard Worker
ElfW2(LIBELFBITS,Shdr)246*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *
247*7304104dSAndroid Build Coastguard Worker internal_function
248*7304104dSAndroid Build Coastguard Worker __elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn)
249*7304104dSAndroid Build Coastguard Worker {
250*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *result;
251*7304104dSAndroid Build Coastguard Worker
252*7304104dSAndroid Build Coastguard Worker if (!scn_valid (scn))
253*7304104dSAndroid Build Coastguard Worker return NULL;
254*7304104dSAndroid Build Coastguard Worker
255*7304104dSAndroid Build Coastguard Worker result = scn->shdr.ELFW(e,LIBELFBITS);
256*7304104dSAndroid Build Coastguard Worker if (result == NULL)
257*7304104dSAndroid Build Coastguard Worker {
258*7304104dSAndroid Build Coastguard Worker rwlock_unlock (scn->elf->lock);
259*7304104dSAndroid Build Coastguard Worker rwlock_wrlock (scn->elf->lock);
260*7304104dSAndroid Build Coastguard Worker result = scn->shdr.ELFW(e,LIBELFBITS);
261*7304104dSAndroid Build Coastguard Worker if (result == NULL)
262*7304104dSAndroid Build Coastguard Worker result = load_shdr_wrlock (scn);
263*7304104dSAndroid Build Coastguard Worker }
264*7304104dSAndroid Build Coastguard Worker
265*7304104dSAndroid Build Coastguard Worker return result;
266*7304104dSAndroid Build Coastguard Worker }
267*7304104dSAndroid Build Coastguard Worker
ElfW2(LIBELFBITS,Shdr)268*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *
269*7304104dSAndroid Build Coastguard Worker internal_function
270*7304104dSAndroid Build Coastguard Worker __elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn)
271*7304104dSAndroid Build Coastguard Worker {
272*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *result;
273*7304104dSAndroid Build Coastguard Worker
274*7304104dSAndroid Build Coastguard Worker if (!scn_valid (scn))
275*7304104dSAndroid Build Coastguard Worker return NULL;
276*7304104dSAndroid Build Coastguard Worker
277*7304104dSAndroid Build Coastguard Worker result = scn->shdr.ELFW(e,LIBELFBITS);
278*7304104dSAndroid Build Coastguard Worker if (result == NULL)
279*7304104dSAndroid Build Coastguard Worker result = load_shdr_wrlock (scn);
280*7304104dSAndroid Build Coastguard Worker
281*7304104dSAndroid Build Coastguard Worker return result;
282*7304104dSAndroid Build Coastguard Worker }
283*7304104dSAndroid Build Coastguard Worker
ElfW2(LIBELFBITS,Shdr)284*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *
285*7304104dSAndroid Build Coastguard Worker elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn)
286*7304104dSAndroid Build Coastguard Worker {
287*7304104dSAndroid Build Coastguard Worker ElfW2(LIBELFBITS,Shdr) *result;
288*7304104dSAndroid Build Coastguard Worker
289*7304104dSAndroid Build Coastguard Worker if (!scn_valid (scn))
290*7304104dSAndroid Build Coastguard Worker return NULL;
291*7304104dSAndroid Build Coastguard Worker
292*7304104dSAndroid Build Coastguard Worker rwlock_rdlock (scn->elf->lock);
293*7304104dSAndroid Build Coastguard Worker result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
294*7304104dSAndroid Build Coastguard Worker rwlock_unlock (scn->elf->lock);
295*7304104dSAndroid Build Coastguard Worker
296*7304104dSAndroid Build Coastguard Worker return result;
297*7304104dSAndroid Build Coastguard Worker }
298