Imported Upstream version 0.155
[platform/upstream/elfutils.git] / libelf / version_xlate.h
1 /* Conversion functions for versioning information.
2    Copyright (C) 1998, 1999, 2000, 2002, 2003 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   do
59     {
60       size_t aux_offset;
61       GElf_Verdaux *asrc;
62
63       /* Test for correct offset.  */
64       if (def_offset + sizeof (GElf_Verdef) > len)
65         return;
66
67       /* Work the tree from the first record.  */
68       ddest = (GElf_Verdef *) ((char *) dest + def_offset);
69       dsrc = (GElf_Verdef *) ((char *) src + def_offset);
70
71       /* Decode first if necessary.  */
72       if (! encode)
73         {
74           ddest->vd_version = bswap_16 (dsrc->vd_version);
75           ddest->vd_flags = bswap_16 (dsrc->vd_flags);
76           ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
77           ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
78           ddest->vd_hash = bswap_32 (dsrc->vd_hash);
79           ddest->vd_aux = bswap_32 (dsrc->vd_aux);
80           ddest->vd_next = bswap_32 (dsrc->vd_next);
81
82           aux_offset = def_offset + ddest->vd_aux;
83         }
84       else
85         aux_offset = def_offset + dsrc->vd_aux;
86
87       /* Handle all the auxiliary records belonging to this definition.  */
88       do
89         {
90           GElf_Verdaux *adest;
91
92           /* Test for correct offset.  */
93           if (aux_offset + sizeof (GElf_Verdaux) > len)
94             return;
95
96           adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
97           asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
98
99           if (encode)
100             aux_offset += asrc->vda_next;
101
102           adest->vda_name = bswap_32 (asrc->vda_name);
103           adest->vda_next = bswap_32 (asrc->vda_next);
104
105           if (! encode)
106             aux_offset += adest->vda_next;
107         }
108       while (asrc->vda_next != 0);
109
110       /* Encode now if necessary.  */
111       if (encode)
112         {
113           def_offset += dsrc->vd_next;
114
115           ddest->vd_version = bswap_16 (dsrc->vd_version);
116           ddest->vd_flags = bswap_16 (dsrc->vd_flags);
117           ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
118           ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
119           ddest->vd_hash = bswap_32 (dsrc->vd_hash);
120           ddest->vd_aux = bswap_32 (dsrc->vd_aux);
121           ddest->vd_next = bswap_32 (dsrc->vd_next);
122         }
123       else
124         def_offset += ddest->vd_next;
125     }
126   while (dsrc->vd_next != 0);
127 }
128
129
130 static void
131 elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
132 {
133   /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
134      To recognize them we have to walk the data structure and convert
135      them one after the other.  The ENCODE parameter specifies whether
136      we are encoding or decoding.  When we are encoding we can immediately
137      use the data in the buffer; if not, we have to decode the data before
138      using it.  */
139   size_t need_offset = 0;
140   GElf_Verneed *ndest;
141   GElf_Verneed *nsrc;
142
143   /* We rely on the types being all the same size.  */
144   assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
145   assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
146   assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
147   assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
148
149   if (len == 0)
150     return;
151
152   do
153     {
154       size_t aux_offset;
155       GElf_Vernaux *asrc;
156
157       /* Test for correct offset.  */
158       if (need_offset + sizeof (GElf_Verneed) > len)
159         return;
160
161       /* Work the tree from the first record.  */
162       ndest = (GElf_Verneed *) ((char *) dest + need_offset);
163       nsrc = (GElf_Verneed *) ((char *) src + need_offset);
164
165       /* Decode first if necessary.  */
166       if (! encode)
167         {
168           ndest->vn_version = bswap_16 (nsrc->vn_version);
169           ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
170           ndest->vn_file = bswap_32 (nsrc->vn_file);
171           ndest->vn_aux = bswap_32 (nsrc->vn_aux);
172           ndest->vn_next = bswap_32 (nsrc->vn_next);
173
174           aux_offset = need_offset + ndest->vn_aux;
175         }
176       else
177         aux_offset = need_offset + nsrc->vn_aux;
178
179       /* Handle all the auxiliary records belonging to this requirement.  */
180       do
181         {
182           GElf_Vernaux *adest;
183
184           /* Test for correct offset.  */
185           if (aux_offset + sizeof (GElf_Vernaux) > len)
186             return;
187
188           adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
189           asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
190
191           if (encode)
192             aux_offset += asrc->vna_next;
193
194           adest->vna_hash = bswap_32 (asrc->vna_hash);
195           adest->vna_flags = bswap_16 (asrc->vna_flags);
196           adest->vna_other = bswap_16 (asrc->vna_other);
197           adest->vna_name = bswap_32 (asrc->vna_name);
198           adest->vna_next = bswap_32 (asrc->vna_next);
199
200           if (! encode)
201             aux_offset += adest->vna_next;
202         }
203       while (asrc->vna_next != 0);
204
205       /* Encode now if necessary.  */
206       if (encode)
207         {
208           need_offset += nsrc->vn_next;
209
210           ndest->vn_version = bswap_16 (nsrc->vn_version);
211           ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
212           ndest->vn_file = bswap_32 (nsrc->vn_file);
213           ndest->vn_aux = bswap_32 (nsrc->vn_aux);
214           ndest->vn_next = bswap_32 (nsrc->vn_next);
215         }
216       else
217         need_offset += ndest->vn_next;
218     }
219   while (nsrc->vn_next != 0);
220 }