xref: /aosp_15_r20/external/elfutils/libelf/elf32_getshdr.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
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