packaging: update homepage url
[platform/upstream/elfutils.git] / libelf / version_xlate.h
1 /* Conversion functions for versioning information.
2    Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
3    This file is part of elfutils.
4    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5
6    This file is free software; you can redistribute it and/or modify
7    it under the terms of either
8
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
12
13    or
14
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
18
19    or both in parallel, as here.
20
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.
25
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/>.  */
29
30 #include <assert.h>
31 #include <gelf.h>
32
33 #include "libelfP.h"
34
35
36 static void
37 elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
38 {
39   /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
40      To recognize them we have to walk the data structure and convert
41      them one after the other.  The ENCODE parameter specifies whether
42      we are encoding or decoding.  When we are encoding we can immediately
43      use the data in the buffer; if not, we have to decode the data before
44      using it.  */
45   size_t def_offset = 0;
46   GElf_Verdef *ddest;
47   GElf_Verdef *dsrc;
48
49   /* We rely on the types being all the same size.  */
50   assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
51   assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
52   assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
53   assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
54
55   if (len == 0)
56     return;
57
58   /* Below we rely on the next field offsets to be correct, start by
59      copying over all data as is in case some data isn't translated.
60      We don't want to leave (undefined) garbage in the dest buffer.  */
61   memmove (dest, src, len);
62
63   do
64     {
65       size_t aux_offset;
66       GElf_Verdaux *asrc;
67
68       /* Test for correct offset.  */
69       if (def_offset > len || len - def_offset < sizeof (GElf_Verdef))
70         return;
71
72       /* Work the tree from the first record.  */
73       ddest = (GElf_Verdef *) ((char *) dest + def_offset);
74       dsrc = (GElf_Verdef *) ((char *) src + def_offset);
75
76       /* Decode first if necessary.  */
77       if (! encode)
78         {
79           ddest->vd_version = bswap_16 (dsrc->vd_version);
80           ddest->vd_flags = bswap_16 (dsrc->vd_flags);
81           ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
82           ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
83           ddest->vd_hash = bswap_32 (dsrc->vd_hash);
84           ddest->vd_aux = bswap_32 (dsrc->vd_aux);
85           ddest->vd_next = bswap_32 (dsrc->vd_next);
86
87           aux_offset = def_offset + ddest->vd_aux;
88         }
89       else
90         aux_offset = def_offset + dsrc->vd_aux;
91
92       /* Handle all the auxiliary records belonging to this definition.  */
93       do
94         {
95           GElf_Verdaux *adest;
96
97           /* Test for correct offset.  */
98           if (aux_offset > len || len - aux_offset < sizeof (GElf_Verdaux))
99             return;
100
101           adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
102           asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
103
104           if (encode)
105             aux_offset += asrc->vda_next;
106
107           adest->vda_name = bswap_32 (asrc->vda_name);
108           adest->vda_next = bswap_32 (asrc->vda_next);
109
110           if (! encode)
111             aux_offset += adest->vda_next;
112         }
113       while (asrc->vda_next != 0);
114
115       /* Encode now if necessary.  */
116       if (encode)
117         {
118           def_offset += dsrc->vd_next;
119
120           ddest->vd_version = bswap_16 (dsrc->vd_version);
121           ddest->vd_flags = bswap_16 (dsrc->vd_flags);
122           ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
123           ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
124           ddest->vd_hash = bswap_32 (dsrc->vd_hash);
125           ddest->vd_aux = bswap_32 (dsrc->vd_aux);
126           ddest->vd_next = bswap_32 (dsrc->vd_next);
127         }
128       else
129         def_offset += ddest->vd_next;
130     }
131   while (dsrc->vd_next != 0);
132 }
133
134
135 static void
136 elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
137 {
138   /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
139      To recognize them we have to walk the data structure and convert
140      them one after the other.  The ENCODE parameter specifies whether
141      we are encoding or decoding.  When we are encoding we can immediately
142      use the data in the buffer; if not, we have to decode the data before
143      using it.  */
144   size_t need_offset = 0;
145   GElf_Verneed *ndest;
146   GElf_Verneed *nsrc;
147
148   /* We rely on the types being all the same size.  */
149   assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
150   assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
151   assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
152   assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
153
154   if (len == 0)
155     return;
156
157   /* Below we rely on the next field offsets to be correct, start by
158      copying over all data as is in case some data isn't translated.
159      We don't want to leave (undefined) garbage in the dest buffer.  */
160   memmove (dest, src, len);
161
162   do
163     {
164       size_t aux_offset;
165       GElf_Vernaux *asrc;
166
167       /* Test for correct offset.  */
168       if (need_offset > len || len - need_offset < sizeof (GElf_Verneed))
169         return;
170
171       /* Work the tree from the first record.  */
172       ndest = (GElf_Verneed *) ((char *) dest + need_offset);
173       nsrc = (GElf_Verneed *) ((char *) src + need_offset);
174
175       /* Decode first if necessary.  */
176       if (! encode)
177         {
178           ndest->vn_version = bswap_16 (nsrc->vn_version);
179           ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
180           ndest->vn_file = bswap_32 (nsrc->vn_file);
181           ndest->vn_aux = bswap_32 (nsrc->vn_aux);
182           ndest->vn_next = bswap_32 (nsrc->vn_next);
183
184           aux_offset = need_offset + ndest->vn_aux;
185         }
186       else
187         aux_offset = need_offset + nsrc->vn_aux;
188
189       /* Handle all the auxiliary records belonging to this requirement.  */
190       do
191         {
192           GElf_Vernaux *adest;
193
194           /* Test for correct offset.  */
195           if (aux_offset > len || len - aux_offset < sizeof (GElf_Vernaux))
196             return;
197
198           adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
199           asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
200
201           if (encode)
202             aux_offset += asrc->vna_next;
203
204           adest->vna_hash = bswap_32 (asrc->vna_hash);
205           adest->vna_flags = bswap_16 (asrc->vna_flags);
206           adest->vna_other = bswap_16 (asrc->vna_other);
207           adest->vna_name = bswap_32 (asrc->vna_name);
208           adest->vna_next = bswap_32 (asrc->vna_next);
209
210           if (! encode)
211             aux_offset += adest->vna_next;
212         }
213       while (asrc->vna_next != 0);
214
215       /* Encode now if necessary.  */
216       if (encode)
217         {
218           need_offset += nsrc->vn_next;
219
220           ndest->vn_version = bswap_16 (nsrc->vn_version);
221           ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
222           ndest->vn_file = bswap_32 (nsrc->vn_file);
223           ndest->vn_aux = bswap_32 (nsrc->vn_aux);
224           ndest->vn_next = bswap_32 (nsrc->vn_next);
225         }
226       else
227         need_offset += ndest->vn_next;
228     }
229   while (nsrc->vn_next != 0);
230 }