Branch data Line data Source code
1 : : /* Get information from auxiliary vector at the given index.
2 : : Copyright (C) 2007, 2015 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : :
5 : : This file is free software; you can redistribute it and/or modify
6 : : it under the terms of either
7 : :
8 : : * the GNU Lesser General Public License as published by the Free
9 : : Software Foundation; either version 3 of the License, or (at
10 : : your option) any later version
11 : :
12 : : or
13 : :
14 : : * the GNU General Public License as published by the Free
15 : : Software Foundation; either version 2 of the License, or (at
16 : : your option) any later version
17 : :
18 : : or both in parallel, as here.
19 : :
20 : : elfutils is distributed in the hope that it will be useful, but
21 : : WITHOUT ANY WARRANTY; without even the implied warranty of
22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 : : General Public License for more details.
24 : :
25 : : You should have received copies of the GNU General Public License and
26 : : the GNU Lesser General Public License along with this program. If
27 : : not, see <http://www.gnu.org/licenses/>. */
28 : :
29 : : #ifdef HAVE_CONFIG_H
30 : : # include <config.h>
31 : : #endif
32 : :
33 : : #include <gelf.h>
34 : : #include <string.h>
35 : :
36 : : #include "libelfP.h"
37 : :
38 : :
39 : : GElf_auxv_t *
40 : 336 : gelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst)
41 : : {
42 : 336 : Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
43 : 336 : GElf_auxv_t *result = NULL;
44 : 336 : Elf *elf;
45 : :
46 [ - + ]: 336 : if (data_scn == NULL)
47 : : return NULL;
48 : :
49 [ - + ]: 336 : if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
50 : : {
51 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
52 : 0 : return NULL;
53 : : }
54 : :
55 : 336 : elf = data_scn->s->elf;
56 : :
57 : 336 : rwlock_rdlock (elf->lock);
58 : :
59 : : /* This is the one place where we have to take advantage of the fact
60 : : that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
61 : : The interface is broken so that it requires this hack. */
62 [ + + ]: 336 : if (elf->class == ELFCLASS32)
63 : : {
64 : 186 : Elf32_auxv_t *src;
65 : :
66 : : /* Here it gets a bit more complicated. The format of the vector
67 : : entries has to be converted. The user better have provided a
68 : : buffer where we can store the information. While copying the data
69 : : we convert the format. */
70 [ - + ]: 186 : if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
71 : : {
72 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
73 : 0 : goto out;
74 : : }
75 : :
76 : 186 : src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
77 : :
78 : : /* This might look like a simple copy operation but it's
79 : : not. There are zero- and sign-extensions going on. */
80 : 186 : dst->a_type = src->a_type;
81 : 186 : dst->a_un.a_val = src->a_un.a_val;
82 : : }
83 : : else
84 : : {
85 : : /* If this is a 64 bit object it's easy. */
86 : 150 : eu_static_assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t));
87 : :
88 : : /* The data is already in the correct form. Just make sure the
89 : : index is OK. */
90 [ - + ]: 150 : if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size))
91 : : {
92 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
93 : 0 : goto out;
94 : : }
95 : :
96 : 150 : memcpy (dst, data_scn->d.d_buf + ndx * sizeof (GElf_auxv_t),
97 : : sizeof (GElf_auxv_t));
98 : : }
99 : :
100 : : result = dst;
101 : :
102 : : out:
103 : : rwlock_unlock (elf->lock);
104 : :
105 : : return result;
106 : : }
|