Branch data Line data Source code
1 : : /* Conversion functions for versioning information.
2 : : Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
3 : : Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
4 : : This file is part of elfutils.
5 : : Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6 : :
7 : : This file is free software; you can redistribute it and/or modify
8 : : it under the terms of either
9 : :
10 : : * the GNU Lesser General Public License as published by the Free
11 : : Software Foundation; either version 3 of the License, or (at
12 : : your option) any later version
13 : :
14 : : or
15 : :
16 : : * the GNU General Public License as published by the Free
17 : : Software Foundation; either version 2 of the License, or (at
18 : : your option) any later version
19 : :
20 : : or both in parallel, as here.
21 : :
22 : : elfutils is distributed in the hope that it will be useful, but
23 : : WITHOUT ANY WARRANTY; without even the implied warranty of
24 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 : : General Public License for more details.
26 : :
27 : : You should have received copies of the GNU General Public License and
28 : : the GNU Lesser General Public License along with this program. If
29 : : not, see <http://www.gnu.org/licenses/>. */
30 : :
31 : : #include <assert.h>
32 : : #include <gelf.h>
33 : :
34 : : #include "libelfP.h"
35 : :
36 : :
37 : : static void
38 : 22 : elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
39 : : {
40 : : /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
41 : : To recognize them we have to walk the data structure and convert
42 : : them one after the other. The ENCODE parameter specifies whether
43 : : we are encoding or decoding. When we are encoding we can immediately
44 : : use the data in the buffer; if not, we have to decode the data before
45 : : using it. */
46 : 22 : size_t def_offset = 0;
47 : 22 : GElf_Verdef *ddest;
48 : 22 : GElf_Verdef *dsrc;
49 : :
50 : : /* We rely on the types being all the same size. */
51 : 22 : assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
52 : 22 : assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
53 : 22 : assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
54 : 22 : assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
55 : :
56 [ + - ]: 22 : if (len == 0)
57 : : return;
58 : :
59 : : /* Below we rely on the next field offsets to be correct, start by
60 : : copying over all data as is in case some data isn't translated.
61 : : We don't want to leave (undefined) garbage in the dest buffer. */
62 : 22 : memmove (dest, src, len);
63 : :
64 : 44 : do
65 : : {
66 : 44 : size_t aux_offset;
67 : 44 : GElf_Verdaux *asrc;
68 : :
69 : : /* Test for correct offset. */
70 [ + - ]: 44 : if (def_offset > len
71 [ + - ]: 44 : || len - def_offset < sizeof (GElf_Verdef)
72 [ + - ]: 44 : || (def_offset & (__alignof__ (GElf_Verdef) - 1)) != 0)
73 : : return;
74 : :
75 : : /* Work the tree from the first record. */
76 : 44 : ddest = (GElf_Verdef *) ((char *) dest + def_offset);
77 : 44 : dsrc = (GElf_Verdef *) ((char *) src + def_offset);
78 : :
79 : : /* Decode first if necessary. */
80 [ + + ]: 44 : if (! encode)
81 : : {
82 [ + - ]: 28 : ddest->vd_version = bswap_16 (dsrc->vd_version);
83 : 28 : ddest->vd_flags = bswap_16 (dsrc->vd_flags);
84 : 28 : ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
85 : 28 : ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
86 [ + - ]: 28 : ddest->vd_hash = bswap_32 (dsrc->vd_hash);
87 : 28 : ddest->vd_aux = bswap_32 (dsrc->vd_aux);
88 : 28 : ddest->vd_next = bswap_32 (dsrc->vd_next);
89 : :
90 [ + - ]: 28 : if (ddest->vd_aux > len - def_offset)
91 : : return;
92 : 28 : aux_offset = def_offset + ddest->vd_aux;
93 : : }
94 : : else
95 : : {
96 [ + - ]: 16 : if (dsrc->vd_aux > len - def_offset)
97 : : return;
98 : 16 : aux_offset = def_offset + dsrc->vd_aux;
99 : : }
100 : :
101 : : /* Handle all the auxiliary records belonging to this definition. */
102 : 44 : do
103 : : {
104 : 44 : GElf_Verdaux *adest;
105 : :
106 : : /* Test for correct offset. */
107 [ + - ]: 44 : if (aux_offset > len
108 [ + - ]: 44 : || len - aux_offset < sizeof (GElf_Verdaux)
109 [ + - ]: 44 : || (aux_offset & (__alignof__ (GElf_Verdaux) - 1)) != 0)
110 : : return;
111 : :
112 : 44 : adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
113 : 44 : asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
114 : :
115 [ + + ]: 44 : if (encode)
116 : : {
117 [ + - ]: 16 : if (asrc->vda_next > len - aux_offset)
118 : : return;
119 : 16 : aux_offset += asrc->vda_next;
120 : : }
121 : :
122 [ + + ]: 44 : adest->vda_name = bswap_32 (asrc->vda_name);
123 : 44 : adest->vda_next = bswap_32 (asrc->vda_next);
124 : :
125 [ + + ]: 44 : if (! encode)
126 : : {
127 [ + - ]: 28 : if (adest->vda_next > len - aux_offset)
128 : : return;
129 : 28 : aux_offset += adest->vda_next;
130 : : }
131 : : }
132 [ - + ]: 44 : while (asrc->vda_next != 0);
133 : :
134 : : /* Encode now if necessary. */
135 [ + + ]: 44 : if (encode)
136 : : {
137 [ + - ]: 16 : if (dsrc->vd_next > len - def_offset)
138 : : return;
139 : 16 : def_offset += dsrc->vd_next;
140 : :
141 : 16 : ddest->vd_version = bswap_16 (dsrc->vd_version);
142 : 16 : ddest->vd_flags = bswap_16 (dsrc->vd_flags);
143 : 16 : ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
144 : 16 : ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
145 : 16 : ddest->vd_hash = bswap_32 (dsrc->vd_hash);
146 : 16 : ddest->vd_aux = bswap_32 (dsrc->vd_aux);
147 : 16 : ddest->vd_next = bswap_32 (dsrc->vd_next);
148 : : }
149 : : else
150 : : {
151 [ + - ]: 28 : if (ddest->vd_next > len - def_offset)
152 : : return;
153 : 28 : def_offset += ddest->vd_next;
154 : : }
155 : : }
156 [ + + ]: 44 : while (dsrc->vd_next != 0);
157 : : }
158 : :
159 : :
160 : : static void
161 : 404 : elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
162 : : {
163 : : /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
164 : : To recognize them we have to walk the data structure and convert
165 : : them one after the other. The ENCODE parameter specifies whether
166 : : we are encoding or decoding. When we are encoding we can immediately
167 : : use the data in the buffer; if not, we have to decode the data before
168 : : using it. */
169 : 404 : size_t need_offset = 0;
170 : 404 : GElf_Verneed *ndest;
171 : 404 : GElf_Verneed *nsrc;
172 : :
173 : : /* We rely on the types being all the same size. */
174 : 404 : assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
175 : 404 : assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
176 : 404 : assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
177 : 404 : assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
178 : :
179 [ + - ]: 404 : if (len == 0)
180 : : return;
181 : :
182 : : /* Below we rely on the next field offsets to be correct, start by
183 : : copying over all data as is in case some data isn't translated.
184 : : We don't want to leave (undefined) garbage in the dest buffer. */
185 : 404 : memmove (dest, src, len);
186 : :
187 : 416 : do
188 : : {
189 : 416 : size_t aux_offset;
190 : 416 : GElf_Vernaux *asrc;
191 : :
192 : : /* Test for correct offset. */
193 [ + - ]: 416 : if (need_offset > len
194 [ + - ]: 416 : || len - need_offset < sizeof (GElf_Verneed)
195 [ + - ]: 416 : || (need_offset & (__alignof__ (GElf_Verneed) - 1)) != 0)
196 : : return;
197 : :
198 : : /* Work the tree from the first record. */
199 : 416 : ndest = (GElf_Verneed *) ((char *) dest + need_offset);
200 : 416 : nsrc = (GElf_Verneed *) ((char *) src + need_offset);
201 : :
202 : : /* Decode first if necessary. */
203 [ + + ]: 416 : if (! encode)
204 : : {
205 [ + - ]: 306 : ndest->vn_version = bswap_16 (nsrc->vn_version);
206 : 306 : ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
207 [ + - ]: 306 : ndest->vn_file = bswap_32 (nsrc->vn_file);
208 : 306 : ndest->vn_aux = bswap_32 (nsrc->vn_aux);
209 : 306 : ndest->vn_next = bswap_32 (nsrc->vn_next);
210 : :
211 [ + - ]: 306 : if (ndest->vn_aux > len - need_offset)
212 : : return;
213 : 306 : aux_offset = need_offset + ndest->vn_aux;
214 : : }
215 : : else
216 : : {
217 [ + - ]: 110 : if (nsrc->vn_aux > len - need_offset)
218 : : return;
219 : 110 : aux_offset = need_offset + nsrc->vn_aux;
220 : : }
221 : :
222 : : /* Handle all the auxiliary records belonging to this requirement. */
223 : 460 : do
224 : : {
225 : 460 : GElf_Vernaux *adest;
226 : :
227 : : /* Test for correct offset. */
228 [ + - ]: 460 : if (aux_offset > len
229 [ + - ]: 460 : || len - aux_offset < sizeof (GElf_Vernaux)
230 [ + - ]: 460 : || (aux_offset & (__alignof__ (GElf_Vernaux) - 1)) != 0)
231 : : return;
232 : :
233 : 460 : adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
234 : 460 : asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
235 : :
236 [ + + ]: 460 : if (encode)
237 : : {
238 [ + - ]: 120 : if (asrc->vna_next > len - aux_offset)
239 : : return;
240 : 120 : aux_offset += asrc->vna_next;
241 : : }
242 : :
243 [ + + ]: 460 : adest->vna_hash = bswap_32 (asrc->vna_hash);
244 [ + + ]: 460 : adest->vna_flags = bswap_16 (asrc->vna_flags);
245 : 460 : adest->vna_other = bswap_16 (asrc->vna_other);
246 : 460 : adest->vna_name = bswap_32 (asrc->vna_name);
247 : 460 : adest->vna_next = bswap_32 (asrc->vna_next);
248 : :
249 [ + + ]: 460 : if (! encode)
250 : : {
251 [ + - ]: 340 : if (adest->vna_next > len - aux_offset)
252 : : return;
253 : 340 : aux_offset += adest->vna_next;
254 : : }
255 : : }
256 [ + + ]: 460 : while (asrc->vna_next != 0);
257 : :
258 : : /* Encode now if necessary. */
259 [ + + ]: 416 : if (encode)
260 : : {
261 [ + - ]: 110 : if (nsrc->vn_next > len - need_offset)
262 : : return;
263 : 110 : need_offset += nsrc->vn_next;
264 : :
265 : 110 : ndest->vn_version = bswap_16 (nsrc->vn_version);
266 : 110 : ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
267 : 110 : ndest->vn_file = bswap_32 (nsrc->vn_file);
268 : 110 : ndest->vn_aux = bswap_32 (nsrc->vn_aux);
269 : 110 : ndest->vn_next = bswap_32 (nsrc->vn_next);
270 : : }
271 : : else
272 : : {
273 [ + - ]: 306 : if (ndest->vn_next > len - need_offset)
274 : : return;
275 : 306 : need_offset += ndest->vn_next;
276 : : }
277 : : }
278 [ + + ]: 416 : while (nsrc->vn_next != 0);
279 : : }
|