1 /* Return section header.
2 Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
44 # define LIBELFBITS 32
48 static ElfW2(LIBELFBITS,Shdr) *
49 load_shdr_wrlock (Elf_Scn *scn)
51 ElfW2(LIBELFBITS,Shdr) *result;
53 /* Read the section header table. */
55 ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
57 /* Try again, maybe the data is there now. */
58 result = scn->shdr.ELFW(e,LIBELFBITS);
63 if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
64 || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
66 size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
68 /* Allocate memory for the section headers. We know the number
69 of entries from the ELF header. */
70 ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
71 (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
72 if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
74 __libelf_seterrno (ELF_E_NOMEM);
77 elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
79 if (elf->map_address != NULL)
81 /* First see whether the information in the ELF header is
82 valid and it does not ask for too much. */
83 if (unlikely (ehdr->e_shoff >= elf->maximum_size)
84 || unlikely (elf->maximum_size - ehdr->e_shoff < size))
86 /* Something is wrong. */
87 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
91 ElfW2(LIBELFBITS,Shdr) *notcvt;
93 /* All the data is already mapped. If we could use it
94 directly this would already have happened. Unless
95 we allocated the memory ourselves and the ELF_F_MALLOCED
97 void *file_shdr = ((char *) elf->map_address
98 + elf->start_offset + ehdr->e_shoff);
100 assert ((elf->flags & ELF_F_MALLOCED)
101 || ehdr->e_ident[EI_DATA] != MY_ELFDATA
102 || elf->cmd == ELF_C_READ_MMAP
103 || (! ALLOW_UNALIGNED
104 && ((uintptr_t) file_shdr
105 & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
107 /* Now copy the data and at the same time convert the byte order. */
108 if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
110 assert ((elf->flags & ELF_F_MALLOCED)
111 || elf->cmd == ELF_C_READ_MMAP
112 || ! ALLOW_UNALIGNED);
113 memcpy (shdr, file_shdr, size);
117 bool copy = ! (ALLOW_UNALIGNED
118 || ((uintptr_t) file_shdr
119 & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
122 notcvt = (ElfW2(LIBELFBITS,Shdr) *)
123 ((char *) elf->map_address
124 + elf->start_offset + ehdr->e_shoff);
127 notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
128 if (unlikely (notcvt == NULL))
130 __libelf_seterrno (ELF_E_NOMEM);
133 memcpy (notcvt, ((char *) elf->map_address
134 + elf->start_offset + ehdr->e_shoff),
138 for (size_t cnt = 0; cnt < shnum; ++cnt)
140 CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
141 CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
142 CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
143 CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
144 CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
145 CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
146 CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
147 CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
148 CONVERT_TO (shdr[cnt].sh_addralign,
149 notcvt[cnt].sh_addralign);
150 CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
152 /* If this is a section with an extended index add a
153 reference in the section which uses the extended
155 if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
156 && shdr[cnt].sh_link < shnum)
157 elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
160 /* Set the own shndx_index field in case it has not yet
162 if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
163 elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
171 else if (likely (elf->fildes != -1))
173 /* Read the header. */
174 ssize_t n = pread_retry (elf->fildes,
175 elf->state.ELFW(elf,LIBELFBITS).shdr, size,
176 elf->start_offset + ehdr->e_shoff);
177 if (unlikely ((size_t) n != size))
179 /* Severe problems. We cannot read the data. */
180 __libelf_seterrno (ELF_E_READ_ERROR);
184 /* If the byte order of the file is not the same as the one
185 of the host convert the data now. */
186 if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
187 for (size_t cnt = 0; cnt < shnum; ++cnt)
189 CONVERT (shdr[cnt].sh_name);
190 CONVERT (shdr[cnt].sh_type);
191 CONVERT (shdr[cnt].sh_flags);
192 CONVERT (shdr[cnt].sh_addr);
193 CONVERT (shdr[cnt].sh_offset);
194 CONVERT (shdr[cnt].sh_size);
195 CONVERT (shdr[cnt].sh_link);
196 CONVERT (shdr[cnt].sh_info);
197 CONVERT (shdr[cnt].sh_addralign);
198 CONVERT (shdr[cnt].sh_entsize);
203 /* The file descriptor was already enabled and not all data was
204 read. Undo the allocation. */
205 __libelf_seterrno (ELF_E_FD_DISABLED);
209 elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
210 elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
215 /* Set the pointers in the `scn's. */
216 for (size_t cnt = 0; cnt < shnum; ++cnt)
217 elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
218 = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
220 result = scn->shdr.ELFW(e,LIBELFBITS);
221 assert (result != NULL);
228 scn_valid (Elf_Scn *scn)
233 if (unlikely (scn->elf->state.elf.ehdr == NULL))
235 __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
239 if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
241 __libelf_seterrno (ELF_E_INVALID_CLASS);
248 ElfW2(LIBELFBITS,Shdr) *
250 __elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn)
252 ElfW2(LIBELFBITS,Shdr) *result;
254 if (!scn_valid (scn))
257 result = scn->shdr.ELFW(e,LIBELFBITS);
260 rwlock_unlock (scn->elf->lock);
261 rwlock_wrlock (scn->elf->lock);
262 result = scn->shdr.ELFW(e,LIBELFBITS);
264 result = load_shdr_wrlock (scn);
270 ElfW2(LIBELFBITS,Shdr) *
272 __elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn)
274 ElfW2(LIBELFBITS,Shdr) *result;
276 if (!scn_valid (scn))
279 result = scn->shdr.ELFW(e,LIBELFBITS);
281 result = load_shdr_wrlock (scn);
286 ElfW2(LIBELFBITS,Shdr) *
287 elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn)
289 ElfW2(LIBELFBITS,Shdr) *result;
291 if (!scn_valid (scn))
294 rwlock_rdlock (scn->elf->lock);
295 result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
296 rwlock_unlock (scn->elf->lock);