1 /* Return section index of section header string table.
2 Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
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/>. */
46 elf_getshdrstrndx (Elf *elf, size_t *dst)
53 if (unlikely (elf->kind != ELF_K_ELF))
55 __libelf_seterrno (ELF_E_INVALID_HANDLE);
59 rwlock_rdlock (elf->lock);
61 /* We rely here on the fact that the `elf' element is a common prefix
62 of `elf32' and `elf64'. */
63 assert (offsetof (struct Elf, state.elf.ehdr)
64 == offsetof (struct Elf, state.elf32.ehdr));
65 assert (sizeof (elf->state.elf.ehdr)
66 == sizeof (elf->state.elf32.ehdr));
67 assert (offsetof (struct Elf, state.elf.ehdr)
68 == offsetof (struct Elf, state.elf64.ehdr));
69 assert (sizeof (elf->state.elf.ehdr)
70 == sizeof (elf->state.elf64.ehdr));
72 if (unlikely (elf->state.elf.ehdr == NULL))
74 __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
81 num = (elf->class == ELFCLASS32
82 ? elf->state.elf32.ehdr->e_shstrndx
83 : elf->state.elf64.ehdr->e_shstrndx);
85 /* Determine whether the index is too big to fit in the ELF
87 if (unlikely (num == SHN_XINDEX))
89 /* Yes. Search the zeroth section header. */
90 if (elf->class == ELFCLASS32)
93 if (unlikely (elf->state.elf32.scns.cnt == 0))
95 /* Cannot use SHN_XINDEX without section headers. */
96 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
101 if (elf->state.elf32.scns.data[0].shdr.e32 != NULL)
103 num = elf->state.elf32.scns.data[0].shdr.e32->sh_link;
107 offset = elf->state.elf32.ehdr->e_shoff;
109 if (elf->map_address != NULL
110 && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
112 || (((size_t) ((char *) elf->map_address
113 + elf->start_offset + offset))
114 & (__alignof__ (Elf32_Shdr) - 1)) == 0))
116 /* First see whether the information in the ELF header is
117 valid and it does not ask for too much. */
118 if (unlikely (elf->maximum_size - offset
119 < sizeof (Elf32_Shdr)))
121 /* Something is wrong. */
122 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
127 /* We can directly access the memory. */
128 num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
133 /* We avoid reading in all the section headers. Just read
137 if (unlikely (pread_retry (elf->fildes, &shdr_mem,
138 sizeof (Elf32_Shdr), offset)
139 != sizeof (Elf32_Shdr)))
141 /* We must be able to read this ELF section header. */
142 __libelf_seterrno (ELF_E_INVALID_FILE);
147 if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
148 CONVERT (shdr_mem.sh_link);
149 num = shdr_mem.sh_link;
154 if (unlikely (elf->state.elf64.scns.cnt == 0))
156 /* Cannot use SHN_XINDEX without section headers. */
157 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
162 if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
164 num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
168 size_t offset = elf->state.elf64.ehdr->e_shoff;
170 if (elf->map_address != NULL
171 && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
173 || (((size_t) ((char *) elf->map_address
174 + elf->start_offset + offset))
175 & (__alignof__ (Elf64_Shdr) - 1)) == 0))
177 /* First see whether the information in the ELF header is
178 valid and it does not ask for too much. */
179 if (unlikely (elf->maximum_size - offset
180 < sizeof (Elf64_Shdr)))
182 /* Something is wrong. */
183 __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
188 /* We can directly access the memory. */
189 num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
194 /* We avoid reading in all the section headers. Just read
198 if (unlikely (pread_retry (elf->fildes, &shdr_mem,
199 sizeof (Elf64_Shdr), offset)
200 != sizeof (Elf64_Shdr)))
202 /* We must be able to read this ELF section header. */
203 __libelf_seterrno (ELF_E_INVALID_FILE);
208 if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
209 CONVERT (shdr_mem.sh_link);
210 num = shdr_mem.sh_link;
215 /* Store the result. */
221 rwlock_unlock (elf->lock);
225 INTDEF(elf_getshdrstrndx)
226 /* Alias for the deprecated name. */
227 strong_alias (elf_getshdrstrndx, elf_getshstrndx)