]>
git.ipfire.org Git - thirdparty/elfutils.git/blob - libelf/version_xlate.h
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.
7 This file is free software; you can redistribute it and/or modify
8 it under the terms of either
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
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
20 or both in parallel, as here.
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.
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/>. */
38 elf_cvt_Verdef (void *dest
, const void *src
, size_t len
, int encode
)
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
46 size_t def_offset
= 0;
50 /* We rely on the types being all the same size. */
51 assert (sizeof (GElf_Verdef
) == sizeof (Elf32_Verdef
));
52 assert (sizeof (GElf_Verdaux
) == sizeof (Elf32_Verdaux
));
53 assert (sizeof (GElf_Verdef
) == sizeof (Elf64_Verdef
));
54 assert (sizeof (GElf_Verdaux
) == sizeof (Elf64_Verdaux
));
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 memmove (dest
, src
, len
);
69 /* Test for correct offset. */
71 || len
- def_offset
< sizeof (GElf_Verdef
)
72 || (def_offset
& (__alignof__ (GElf_Verdef
) - 1)) != 0)
75 /* Work the tree from the first record. */
76 ddest
= (GElf_Verdef
*) ((char *) dest
+ def_offset
);
77 dsrc
= (GElf_Verdef
*) ((char *) src
+ def_offset
);
79 /* Decode first if necessary. */
82 ddest
->vd_version
= bswap_16 (dsrc
->vd_version
);
83 ddest
->vd_flags
= bswap_16 (dsrc
->vd_flags
);
84 ddest
->vd_ndx
= bswap_16 (dsrc
->vd_ndx
);
85 ddest
->vd_cnt
= bswap_16 (dsrc
->vd_cnt
);
86 ddest
->vd_hash
= bswap_32 (dsrc
->vd_hash
);
87 ddest
->vd_aux
= bswap_32 (dsrc
->vd_aux
);
88 ddest
->vd_next
= bswap_32 (dsrc
->vd_next
);
90 if (ddest
->vd_aux
> len
- def_offset
)
92 aux_offset
= def_offset
+ ddest
->vd_aux
;
96 if (dsrc
->vd_aux
> len
- def_offset
)
98 aux_offset
= def_offset
+ dsrc
->vd_aux
;
101 /* Handle all the auxiliary records belonging to this definition. */
106 /* Test for correct offset. */
108 || len
- aux_offset
< sizeof (GElf_Verdaux
)
109 || (aux_offset
& (__alignof__ (GElf_Verdaux
) - 1)) != 0)
112 adest
= (GElf_Verdaux
*) ((char *) dest
+ aux_offset
);
113 asrc
= (GElf_Verdaux
*) ((char *) src
+ aux_offset
);
117 if (asrc
->vda_next
> len
- aux_offset
)
119 aux_offset
+= asrc
->vda_next
;
122 adest
->vda_name
= bswap_32 (asrc
->vda_name
);
123 adest
->vda_next
= bswap_32 (asrc
->vda_next
);
127 if (adest
->vda_next
> len
- aux_offset
)
129 aux_offset
+= adest
->vda_next
;
132 while (asrc
->vda_next
!= 0);
134 /* Encode now if necessary. */
137 if (dsrc
->vd_next
> len
- def_offset
)
139 def_offset
+= dsrc
->vd_next
;
141 ddest
->vd_version
= bswap_16 (dsrc
->vd_version
);
142 ddest
->vd_flags
= bswap_16 (dsrc
->vd_flags
);
143 ddest
->vd_ndx
= bswap_16 (dsrc
->vd_ndx
);
144 ddest
->vd_cnt
= bswap_16 (dsrc
->vd_cnt
);
145 ddest
->vd_hash
= bswap_32 (dsrc
->vd_hash
);
146 ddest
->vd_aux
= bswap_32 (dsrc
->vd_aux
);
147 ddest
->vd_next
= bswap_32 (dsrc
->vd_next
);
151 if (ddest
->vd_next
> len
- def_offset
)
153 def_offset
+= ddest
->vd_next
;
156 while (dsrc
->vd_next
!= 0);
161 elf_cvt_Verneed (void *dest
, const void *src
, size_t len
, int encode
)
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
169 size_t need_offset
= 0;
173 /* We rely on the types being all the same size. */
174 assert (sizeof (GElf_Verneed
) == sizeof (Elf32_Verneed
));
175 assert (sizeof (GElf_Vernaux
) == sizeof (Elf32_Vernaux
));
176 assert (sizeof (GElf_Verneed
) == sizeof (Elf64_Verneed
));
177 assert (sizeof (GElf_Vernaux
) == sizeof (Elf64_Vernaux
));
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 memmove (dest
, src
, len
);
192 /* Test for correct offset. */
193 if (need_offset
> len
194 || len
- need_offset
< sizeof (GElf_Verneed
)
195 || (need_offset
& (__alignof__ (GElf_Verneed
) - 1)) != 0)
198 /* Work the tree from the first record. */
199 ndest
= (GElf_Verneed
*) ((char *) dest
+ need_offset
);
200 nsrc
= (GElf_Verneed
*) ((char *) src
+ need_offset
);
202 /* Decode first if necessary. */
205 ndest
->vn_version
= bswap_16 (nsrc
->vn_version
);
206 ndest
->vn_cnt
= bswap_16 (nsrc
->vn_cnt
);
207 ndest
->vn_file
= bswap_32 (nsrc
->vn_file
);
208 ndest
->vn_aux
= bswap_32 (nsrc
->vn_aux
);
209 ndest
->vn_next
= bswap_32 (nsrc
->vn_next
);
211 if (ndest
->vn_aux
> len
- need_offset
)
213 aux_offset
= need_offset
+ ndest
->vn_aux
;
217 if (nsrc
->vn_aux
> len
- need_offset
)
219 aux_offset
= need_offset
+ nsrc
->vn_aux
;
222 /* Handle all the auxiliary records belonging to this requirement. */
227 /* Test for correct offset. */
229 || len
- aux_offset
< sizeof (GElf_Vernaux
)
230 || (aux_offset
& (__alignof__ (GElf_Vernaux
) - 1)) != 0)
233 adest
= (GElf_Vernaux
*) ((char *) dest
+ aux_offset
);
234 asrc
= (GElf_Vernaux
*) ((char *) src
+ aux_offset
);
238 if (asrc
->vna_next
> len
- aux_offset
)
240 aux_offset
+= asrc
->vna_next
;
243 adest
->vna_hash
= bswap_32 (asrc
->vna_hash
);
244 adest
->vna_flags
= bswap_16 (asrc
->vna_flags
);
245 adest
->vna_other
= bswap_16 (asrc
->vna_other
);
246 adest
->vna_name
= bswap_32 (asrc
->vna_name
);
247 adest
->vna_next
= bswap_32 (asrc
->vna_next
);
251 if (adest
->vna_next
> len
- aux_offset
)
253 aux_offset
+= adest
->vna_next
;
256 while (asrc
->vna_next
!= 0);
258 /* Encode now if necessary. */
261 if (nsrc
->vn_next
> len
- need_offset
)
263 need_offset
+= nsrc
->vn_next
;
265 ndest
->vn_version
= bswap_16 (nsrc
->vn_version
);
266 ndest
->vn_cnt
= bswap_16 (nsrc
->vn_cnt
);
267 ndest
->vn_file
= bswap_32 (nsrc
->vn_file
);
268 ndest
->vn_aux
= bswap_32 (nsrc
->vn_aux
);
269 ndest
->vn_next
= bswap_32 (nsrc
->vn_next
);
273 if (ndest
->vn_next
> len
- need_offset
)
275 need_offset
+= ndest
->vn_next
;
278 while (nsrc
->vn_next
!= 0);