1 /* Return symbol table of archive.
2 Copyright (C) 1998-2000, 2002, 2005, 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/>. */
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 *elf, size_t *ptr)
79 if (elf->kind != ELF_K_AR)
81 /* This is no archive. */
82 __libelf_seterrno (ELF_E_NO_ARCHIVE);
87 /* In case of an error or when we know the value store the expected
88 value now. Doing this allows us easier exits in an error case. */
89 *ptr = elf->state.ar.ar_sym_num;
91 if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l)
93 /* There is no index. */
94 __libelf_seterrno (ELF_E_NO_INDEX);
98 Elf_Arsym *result = elf->state.ar.ar_sym;
101 /* We have not yet read the index. */
102 rwlock_wrlock (elf->lock);
104 /* In case we find no index remember this for the next call. */
105 elf->state.ar.ar_sym = (Elf_Arsym *) -1l;
107 /* We might have to allocate some temporary data for reading. */
108 void *temp_data = NULL;
110 struct ar_hdr *index_hdr;
111 if (elf->map_address == NULL)
113 /* We must read index from the file. */
114 assert (elf->fildes != -1);
115 if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr,
116 sizeof (struct ar_hdr), elf->start_offset + SARMAG)
117 != sizeof (struct ar_hdr))
119 /* It is not possible to read the index. Maybe it does not
121 __libelf_seterrno (ELF_E_READ_ERROR);
125 index_hdr = &elf->state.ar.ar_hdr;
129 if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size)
131 /* There is no room for the full archive. */
132 __libelf_seterrno (ELF_E_NO_INDEX);
136 index_hdr = (struct ar_hdr *) (elf->map_address
137 + elf->start_offset + SARMAG);
140 /* Now test whether this really is an archive. */
141 if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0)
143 /* Invalid magic bytes. */
144 __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
149 /* Now test whether this is the index. If the name is "/", this
150 is 32-bit index, if it's "/SYM64/", it's 64-bit index.
152 XXX This is not entirely true. There are some more forms.
153 Which of them shall we handle? */
154 if (memcmp (index_hdr->ar_name, "/ ", 16) == 0)
156 else if (memcmp (index_hdr->ar_name, "/SYM64/ ", 16) == 0)
160 /* If the index is not the first entry, there is no index.
163 __libelf_seterrno (ELF_E_NO_INDEX);
166 int w = index64_p ? 8 : 4;
168 /* We have an archive. The first word in there is the number of
169 entries in the table. */
171 size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr);
172 if (read_number_entries (&n, elf, &off, index64_p) < 0)
174 /* Cannot read the number of entries. */
175 __libelf_seterrno (ELF_E_NO_INDEX);
179 /* Now we can perform some first tests on whether all the data
180 needed for the index is available. */
182 memcpy (tmpbuf, index_hdr->ar_size, 10);
184 size_t index_size = atol (tmpbuf);
186 if (index_size > elf->maximum_size
187 || elf->maximum_size - index_size < SARMAG + sizeof (struct ar_hdr)
188 #if SIZE_MAX <= 4294967295U
189 || n >= SIZE_MAX / sizeof (Elf_Arsym)
191 || n > index_size / w)
193 /* This index table cannot be right since it does not fit into
195 __libelf_seterrno (ELF_E_NO_INDEX);
199 /* Now we can allocate the arrays needed to store the index. */
200 size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym);
201 elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
202 if (elf->state.ar.ar_sym != NULL)
204 void *file_data; /* unit32_t[n] or uint64_t[n] */
208 if (elf->map_address == NULL)
210 temp_data = malloc (sz);
211 if (unlikely (temp_data == NULL))
213 __libelf_seterrno (ELF_E_NOMEM);
216 file_data = temp_data;
218 ar_sym_len += index_size - n * w;
219 Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym,
223 free (elf->state.ar.ar_sym);
224 elf->state.ar.ar_sym = NULL;
225 __libelf_seterrno (ELF_E_NOMEM);
228 elf->state.ar.ar_sym = newp;
230 char *new_str = (char *) (elf->state.ar.ar_sym + n + 1);
232 /* Now read the data from the file. */
233 if ((size_t) pread_retry (elf->fildes, file_data, sz, off) != sz
234 || ((size_t) pread_retry (elf->fildes, new_str,
235 index_size - sz, off + sz)
238 /* We were not able to read the data. */
239 free (elf->state.ar.ar_sym);
240 elf->state.ar.ar_sym = NULL;
241 __libelf_seterrno (ELF_E_NO_INDEX);
245 str_data = (char *) new_str;
249 file_data = (void *) (elf->map_address + off);
251 && ((uintptr_t) file_data & -(uintptr_t) n) != 0)
253 temp_data = malloc (sz);
254 if (unlikely (temp_data == NULL))
256 __libelf_seterrno (ELF_E_NOMEM);
259 file_data = memcpy (temp_data, elf->map_address + off, sz);
261 str_data = (char *) (elf->map_address + off + sz);
264 /* Now we can build the data structure. */
265 Elf_Arsym *arsym = elf->state.ar.ar_sym;
266 uint64_t (*u64)[n] = file_data;
267 uint32_t (*u32)[n] = file_data;
268 for (size_t cnt = 0; cnt < n; ++cnt)
270 arsym[cnt].as_name = str_data;
273 uint64_t tmp = (*u64)[cnt];
274 if (__BYTE_ORDER == __LITTLE_ENDIAN)
275 tmp = bswap_64 (tmp);
277 arsym[cnt].as_off = tmp;
279 /* Check whether 64-bit offset fits into 32-bit
281 if (sizeof (arsym[cnt].as_off) < 8
282 && arsym[cnt].as_off != tmp)
284 if (elf->map_address == NULL)
286 free (elf->state.ar.ar_sym);
287 elf->state.ar.ar_sym = NULL;
290 __libelf_seterrno (ELF_E_RANGE);
294 else if (__BYTE_ORDER == __LITTLE_ENDIAN)
295 arsym[cnt].as_off = bswap_32 ((*u32)[cnt]);
297 arsym[cnt].as_off = (*u32)[cnt];
299 arsym[cnt].as_hash = _dl_elf_hash (str_data);
300 str_data = rawmemchr (str_data, '\0') + 1;
303 /* At the end a special entry. */
304 arsym[n].as_name = NULL;
306 arsym[n].as_hash = ~0UL;
308 /* Tell the caller how many entries we have. */
309 elf->state.ar.ar_sym_num = n + 1;
312 result = elf->state.ar.ar_sym;
316 rwlock_unlock (elf->lock);
320 *ptr = elf->state.ar.ar_sym_num;