Branch data Line data Source code
1 : : /* Get information from auxiliary vector at the given index.
2 : : Copyright (C) 2007 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 <assert.h>
34 : : #include <gelf.h>
35 : : #include <string.h>
36 : :
37 : : #include "libelfP.h"
38 : :
39 : :
40 : : GElf_auxv_t *
41 : 56 : gelf_getauxv (data, ndx, dst)
42 : : Elf_Data *data;
43 : : int ndx;
44 : : GElf_auxv_t *dst;
45 : : {
46 : 56 : Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
47 : 56 : GElf_auxv_t *result = NULL;
48 : : Elf *elf;
49 : :
50 [ + - ]: 56 : if (data_scn == NULL)
51 : : return NULL;
52 : :
53 [ - + ]: 56 : if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
54 : : {
55 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE);
56 : 0 : return NULL;
57 : : }
58 : :
59 : 56 : elf = data_scn->s->elf;
60 : :
61 : : rwlock_rdlock (elf->lock);
62 : :
63 : : /* This is the one place where we have to take advantage of the fact
64 : : that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
65 : : The interface is broken so that it requires this hack. */
66 [ + + ]: 56 : if (elf->class == ELFCLASS32)
67 : : {
68 : : Elf32_auxv_t *src;
69 : :
70 : : /* Here it gets a bit more complicated. The format of the vector
71 : : entries has to be converted. The user better have provided a
72 : : buffer where we can store the information. While copying the data
73 : : we convert the format. */
74 [ - + ]: 37 : if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
75 : : {
76 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
77 : 0 : goto out;
78 : : }
79 : :
80 : 37 : src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
81 : :
82 : : /* This might look like a simple copy operation but it's
83 : : not. There are zero- and sign-extensions going on. */
84 : 37 : dst->a_type = src->a_type;
85 : 37 : dst->a_un.a_val = src->a_un.a_val;
86 : : }
87 : : else
88 : : {
89 : : /* If this is a 64 bit object it's easy. */
90 : : assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t));
91 : :
92 : : /* The data is already in the correct form. Just make sure the
93 : : index is OK. */
94 [ - + ]: 19 : if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size))
95 : : {
96 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX);
97 : 0 : goto out;
98 : : }
99 : :
100 : 19 : *dst = ((GElf_auxv_t *) data_scn->d.d_buf)[ndx];
101 : : }
102 : :
103 : 56 : result = dst;
104 : :
105 : : out:
106 : : rwlock_unlock (elf->lock);
107 : :
108 : 56 : return result;
109 : : }
|