1 // elfcpp_swap.h -- Handle swapping for elfcpp -*- C++ -*-
3 // Copyright 2006, 2007, Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
6 // This file is part of elfcpp.
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public License
10 // as published by the Free Software Foundation; either version 2, or
11 // (at your option) any later version.
13 // In addition to the permissions in the GNU Library General Public
14 // License, the Free Software Foundation gives you unlimited
15 // permission to link the compiled version of this file into
16 // combinations with other programs, and to distribute those
17 // combinations without any restriction coming from the use of this
18 // file. (The Library Public License restrictions do apply in other
19 // respects; for example, they cover modification of the file, and
20 /// distribution when not linked into a combined executable.)
22 // This program 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 // Library General Public License for more details.
27 // You should have received a copy of the GNU Library General Public
28 // License along with this program; if not, write to the Free Software
29 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
32 // This header file defines basic template classes to efficiently swap
33 // numbers between host form and target form. When the host and
34 // target have the same endianness, these turn into no-ops.
46 // Endian simply indicates whether the host is big endian or not.
51 // Used for template specializations.
52 static const bool host_big_endian
= __BYTE_ORDER
== __BIG_ENDIAN
;
55 // Valtype_base is a template based on size (8, 16, 32, 64) which
56 // defines the type Valtype as the unsigned integer of the specified
63 struct Valtype_base
<8>
65 typedef unsigned char Valtype
;
69 struct Valtype_base
<16>
71 typedef uint16_t Valtype
;
75 struct Valtype_base
<32>
77 typedef uint32_t Valtype
;
81 struct Valtype_base
<64>
83 typedef uint64_t Valtype
;
86 // Convert_endian is a template based on size and on whether the host
87 // and target have the same endianness. It defines the type Valtype
88 // as Valtype_base does, and also defines a function convert_host
89 // which takes an argument of type Valtype and returns the same value,
90 // but swapped if the host and target have different endianness.
92 template<int size
, bool same_endian
>
93 struct Convert_endian
;
96 struct Convert_endian
<size
, true>
98 typedef typename Valtype_base
<size
>::Valtype Valtype
;
100 static inline Valtype
101 convert_host(Valtype v
)
106 struct Convert_endian
<8, false>
108 typedef Valtype_base
<8>::Valtype Valtype
;
110 static inline Valtype
111 convert_host(Valtype v
)
116 struct Convert_endian
<16, false>
118 typedef Valtype_base
<16>::Valtype Valtype
;
120 static inline Valtype
121 convert_host(Valtype v
)
122 { return bswap_16(v
); }
126 struct Convert_endian
<32, false>
128 typedef Valtype_base
<32>::Valtype Valtype
;
130 static inline Valtype
131 convert_host(Valtype v
)
132 { return bswap_32(v
); }
136 struct Convert_endian
<64, false>
138 typedef Valtype_base
<64>::Valtype Valtype
;
140 static inline Valtype
141 convert_host(Valtype v
)
142 { return bswap_64(v
); }
145 // Convert is a template based on size and on whether the target is
146 // big endian. It defines Valtype and convert_host like
147 // Convert_endian. That is, it is just like Convert_endian except in
148 // the meaning of the second template parameter.
150 template<int size
, bool big_endian
>
153 typedef typename Valtype_base
<size
>::Valtype Valtype
;
155 static inline Valtype
156 convert_host(Valtype v
)
158 return Convert_endian
<size
, big_endian
== Endian::host_big_endian
>
163 // Swap is a template based on size and on whether the target is big
164 // endian. It defines the type Valtype and the functions readval and
165 // writeval. The functions read and write values of the appropriate
166 // size out of buffers, swapping them if necessary. readval and
167 // writeval are overloaded to take pointers to the appropriate type or
168 // pointers to unsigned char.
170 template<int size
, bool big_endian
>
173 typedef typename Valtype_base
<size
>::Valtype Valtype
;
175 static inline Valtype
176 readval(const Valtype
* wv
)
177 { return Convert
<size
, big_endian
>::convert_host(*wv
); }
180 writeval(Valtype
* wv
, Valtype v
)
181 { *wv
= Convert
<size
, big_endian
>::convert_host(v
); }
183 static inline Valtype
184 readval(const unsigned char* wv
)
185 { return readval(reinterpret_cast<const Valtype
*>(wv
)); }
188 writeval(unsigned char* wv
, Valtype v
)
189 { writeval(reinterpret_cast<Valtype
*>(wv
), v
); }
192 // We need to specialize the 8-bit version of Swap to avoid
193 // conflicting overloads, since both versions of readval and writeval
194 // will have the same type parameters.
196 template<bool big_endian
>
197 struct Swap
<8, big_endian
>
199 typedef typename Valtype_base
<8>::Valtype Valtype
;
201 static inline Valtype
202 readval(const Valtype
* wv
)
206 writeval(Valtype
* wv
, Valtype v
)
210 // Swap_unaligned is a template based on size and on whether the
211 // target is big endian. It defines the type Valtype and the
212 // functions readval and writeval. The functions read and write
213 // values of the appropriate size out of buffers which may be
216 template<int size
, bool big_endian
>
217 struct Swap_unaligned
;
219 template<bool big_endian
>
220 struct Swap_unaligned
<8, big_endian
>
222 typedef typename Valtype_base
<8>::Valtype Valtype
;
224 static inline Valtype
225 readval(const unsigned char* wv
)
229 writeval(unsigned char* wv
, Valtype v
)
234 struct Swap_unaligned
<16, false>
236 typedef Valtype_base
<16>::Valtype Valtype
;
238 static inline Valtype
239 readval(const unsigned char* wv
)
241 return (wv
[1] << 8) | wv
[0];
245 writeval(unsigned char* wv
, Valtype v
)
253 struct Swap_unaligned
<16, true>
255 typedef Valtype_base
<16>::Valtype Valtype
;
257 static inline Valtype
258 readval(const unsigned char* wv
)
260 return (wv
[0] << 8) | wv
[1];
264 writeval(unsigned char* wv
, Valtype v
)
272 struct Swap_unaligned
<32, false>
274 typedef Valtype_base
<32>::Valtype Valtype
;
276 static inline Valtype
277 readval(const unsigned char* wv
)
279 return (wv
[3] << 24) | (wv
[2] << 16) | (wv
[1] << 8) | wv
[0];
283 writeval(unsigned char* wv
, Valtype v
)
293 struct Swap_unaligned
<32, true>
295 typedef Valtype_base
<32>::Valtype Valtype
;
297 static inline Valtype
298 readval(const unsigned char* wv
)
300 return (wv
[0] << 24) | (wv
[1] << 16) | (wv
[2] << 8) | wv
[3];
304 writeval(unsigned char* wv
, Valtype v
)
314 struct Swap_unaligned
<64, false>
316 typedef Valtype_base
<64>::Valtype Valtype
;
318 static inline Valtype
319 readval(const unsigned char* wv
)
321 return ((static_cast<Valtype
>(wv
[7]) << 56)
322 | (static_cast<Valtype
>(wv
[6]) << 48)
323 | (static_cast<Valtype
>(wv
[5]) << 40)
324 | (static_cast<Valtype
>(wv
[4]) << 32)
325 | (static_cast<Valtype
>(wv
[3]) << 24)
326 | (static_cast<Valtype
>(wv
[2]) << 16)
327 | (static_cast<Valtype
>(wv
[1]) << 8)
328 | static_cast<Valtype
>(wv
[0]));
332 writeval(unsigned char* wv
, Valtype v
)
346 struct Swap_unaligned
<64, true>
348 typedef Valtype_base
<64>::Valtype Valtype
;
350 static inline Valtype
351 readval(const unsigned char* wv
)
353 return ((static_cast<Valtype
>(wv
[0]) << 56)
354 | (static_cast<Valtype
>(wv
[1]) << 48)
355 | (static_cast<Valtype
>(wv
[2]) << 40)
356 | (static_cast<Valtype
>(wv
[3]) << 32)
357 | (static_cast<Valtype
>(wv
[4]) << 24)
358 | (static_cast<Valtype
>(wv
[5]) << 16)
359 | (static_cast<Valtype
>(wv
[6]) << 8)
360 | static_cast<Valtype
>(wv
[7]));
364 writeval(unsigned char* wv
, Valtype v
)
377 } // End namespace elfcpp.
379 #endif // !defined(ELFCPP_SWAP_H)
This page took 0.036267 seconds and 4 git commands to generate.