1 /* Return symbol table of archive.
2 Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014 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/>. */
50 read_number_entries (uint64_t *nump, Elf *elf, size_t *offp, bool index64_p)
58 size_t w = index64_p ? 8 : 4;
59 if (elf->map_address != NULL)
60 /* Use memcpy instead of pointer dereference so as not to assume the
61 field is naturally aligned within the file. */
62 memcpy (&u, elf->map_address + *offp, sizeof u);
63 else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w)
68 if (__BYTE_ORDER == __LITTLE_ENDIAN)
69 *nump = index64_p ? bswap_64 (u.ret64) : bswap_32 (u.ret32);
71 *nump = index64_p ? u.ret64 : u.ret32;
77 elf_getarsym (elf, ptr)
81 if (elf->kind != ELF_K_AR)
83 /* This is no archive. */
84 __libelf_seterrno (ELF_E_NO_ARCHIVE);
89 /* In case of an error or when we know the value store the expected
90 value now. Doing this allows us easier exits in an error case. */
91 *ptr = elf->state.ar.ar_sym_num;
93 if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l)
95 /* There is no index. */
96 __libelf_seterrno (ELF_E_NO_INDEX);
100 Elf_Arsym *result = elf->state.ar.ar_sym;
103 /* We have not yet read the index. */
104 rwlock_wrlock (elf->lock);
106 /* In case we find no index remember this for the next call. */
107 elf->state.ar.ar_sym = (Elf_Arsym *) -1l;
109 struct ar_hdr *index_hdr;
110 if (elf->map_address == NULL)
112 /* We must read index from the file. */
113 assert (elf->fildes != -1);
114 if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr,
115 sizeof (struct ar_hdr), elf->start_offset + SARMAG)
116 != sizeof (struct ar_hdr))
118 /* It is not possible to read the index. Maybe it does not
120 __libelf_seterrno (ELF_E_READ_ERROR);
124 index_hdr = &elf->state.ar.ar_hdr;
128 if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size)
130 /* There is no room for the full archive. */
131 __libelf_seterrno (ELF_E_NO_INDEX);
135 index_hdr = (struct ar_hdr *) (elf->map_address
136 + elf->start_offset + SARMAG);
139 /* Now test whether this really is an archive. */
140 if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0)
142 /* Invalid magic bytes. */
143 __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
148 /* Now test whether this is the index. If the name is "/", this
149 is 32-bit index, if it's "/SYM64/", it's 64-bit index.
151 XXX This is not entirely true. There are some more forms.
152 Which of them shall we handle? */
153 if (memcmp (index_hdr->ar_name, "/ ", 16) == 0)
155 else if (memcmp (index_hdr->ar_name, "/SYM64/ ", 16) == 0)
159 /* If the index is not the first entry, there is no index.
162 __libelf_seterrno (ELF_E_NO_INDEX);
165 int w = index64_p ? 8 : 4;
167 /* We have an archive. The first word in there is the number of
168 entries in the table. */
170 size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr);
171 if (read_number_entries (&n, elf, &off, index64_p) < 0)
173 /* Cannot read the number of entries. */
174 __libelf_seterrno (ELF_E_NO_INDEX);
178 /* Now we can perform some first tests on whether all the data
179 needed for the index is available. */
181 memcpy (tmpbuf, index_hdr->ar_size, 10);
183 size_t index_size = atol (tmpbuf);
185 if (SARMAG + sizeof (struct ar_hdr) + index_size > elf->maximum_size
186 #if SIZE_MAX <= 4294967295U
187 || n >= SIZE_MAX / sizeof (Elf_Arsym)
189 || n * w > index_size)
191 /* This index table cannot be right since it does not fit into
193 __libelf_seterrno (ELF_E_NO_INDEX);
197 /* Now we can allocate the arrays needed to store the index. */
198 size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym);
199 elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
200 if (elf->state.ar.ar_sym != NULL)
210 if (elf->map_address == NULL)
212 file_data = alloca (sz);
214 ar_sym_len += index_size - n * w;
215 Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym,
219 free (elf->state.ar.ar_sym);
220 elf->state.ar.ar_sym = NULL;
221 __libelf_seterrno (ELF_E_NOMEM);
224 elf->state.ar.ar_sym = newp;
226 char *new_str = (char *) (elf->state.ar.ar_sym + n + 1);
228 /* Now read the data from the file. */
229 if ((size_t) pread_retry (elf->fildes, file_data, sz, off) != sz
230 || ((size_t) pread_retry (elf->fildes, new_str,
231 index_size - sz, off + sz)
234 /* We were not able to read the data. */
235 free (elf->state.ar.ar_sym);
236 elf->state.ar.ar_sym = NULL;
237 __libelf_seterrno (ELF_E_NO_INDEX);
241 str_data = (char *) new_str;
245 file_data = (void *) (elf->map_address + off);
247 && ((uintptr_t) file_data & -(uintptr_t) n) != 0)
248 file_data = memcpy (alloca (sz), elf->map_address + off, sz);
249 str_data = (char *) (elf->map_address + off + sz);
252 /* Now we can build the data structure. */
253 Elf_Arsym *arsym = elf->state.ar.ar_sym;
254 for (size_t cnt = 0; cnt < n; ++cnt)
256 arsym[cnt].as_name = str_data;
259 uint64_t tmp = file_data->u64[cnt];
260 if (__BYTE_ORDER == __LITTLE_ENDIAN)
261 tmp = bswap_64 (tmp);
263 arsym[cnt].as_off = tmp;
265 /* Check whether 64-bit offset fits into 32-bit
267 if (sizeof (arsym[cnt].as_off) < 8
268 && arsym[cnt].as_off != tmp)
270 if (elf->map_address == NULL)
272 free (elf->state.ar.ar_sym);
273 elf->state.ar.ar_sym = NULL;
276 __libelf_seterrno (ELF_E_RANGE);
280 else if (__BYTE_ORDER == __LITTLE_ENDIAN)
281 arsym[cnt].as_off = bswap_32 (file_data->u32[cnt]);
283 arsym[cnt].as_off = file_data->u32[cnt];
285 arsym[cnt].as_hash = _dl_elf_hash (str_data);
286 str_data = rawmemchr (str_data, '\0') + 1;
289 /* At the end a special entry. */
290 arsym[n].as_name = NULL;
292 arsym[n].as_hash = ~0UL;
294 /* Tell the caller how many entries we have. */
295 elf->state.ar.ar_sym_num = n + 1;
298 result = elf->state.ar.ar_sym;
301 rwlock_unlock (elf->lock);
305 *ptr = elf->state.ar.ar_sym_num;