1 /* Very simple endian-ness layer for LTO object file handling
2 Copyright 2010 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* This header file provides a simple way to handle object files in
21 another endian-ness than the host machine. This is necesarry to
22 enable cross-compilation with LTO enabled. Targets that use the
23 ELF binary object format do not need this (libelf already handles
24 endian-ness) but for COFF and Mach-O the functions in this header
25 are used in the minimal binary object reader/writer.
27 For all functions in this header, the user is responsible for
28 making sure that the memory accesses are valid. */
30 #ifndef GCC_LTO_ENDIAN_H
31 #define GCC_LTO_ENDIAN_H
36 static inline uint16_t
37 get_uint16_le (const unsigned char *ptr
)
39 return ptr
[0] | (ptr
[1] << 8);
42 static inline uint32_t
43 get_uint32_le (const unsigned char *ptr
)
45 return ptr
[0] | (ptr
[1] << 8) | (ptr
[2] << 16) | (ptr
[3] << 24);
48 static inline uint64_t
49 get_uint64_le (const unsigned char *ptr_
)
51 #define ptr (uint64_t) ptr_
52 return ptr
[0] | (ptr
[1] << 8) | (ptr
[2] << 16) | (ptr
[3] << 24)
53 | (ptr
[4] << 32) | (ptr
[5] << 40) | (ptr
[6] << 48) | (ptr
[7] << 56);
57 static inline uint16_t
58 get_uint16_be (const unsigned char *ptr
)
60 return ptr
[1] | (ptr
[2] << 8);
63 static inline uint32_t
64 get_uint32_be (const unsigned char *ptr
)
66 return ptr
[3] | (ptr
[2] << 8) | (ptr
[1] << 16) | (ptr
[0] << 24);
69 static inline uint64_t
70 get_uint64_be (const unsigned char *ptr_
)
72 #define ptr (uint64_t) ptr_
73 return ptr
[7] | (ptr
[6] << 8) | (ptr
[5] << 16) | (ptr
[4] << 24)
74 | (ptr
[3] << 32) | (ptr
[2] << 40) | (ptr
[1] << 48) | (ptr
[0] << 56);
79 put_uint16_le (unsigned char *ptr
, uint16_t data
)
82 ptr
[1] = (data
>> 8) & 0xff;
86 put_uint32_le (unsigned char *ptr
, uint32_t data
)
89 ptr
[1] = (data
>> 8) & 0xff;
90 ptr
[2] = (data
>> 16) & 0xff;
91 ptr
[3] = (data
>> 24) & 0xff;
95 put_uint64_le (unsigned char *ptr
, uint64_t data
)
98 ptr
[1] = (data
>> 8) & 0xff;
99 ptr
[2] = (data
>> 16) & 0xff;
100 ptr
[3] = (data
>> 24) & 0xff;
101 ptr
[4] = (data
>> 32) & 0xff;
102 ptr
[5] = (data
>> 40) & 0xff;
103 ptr
[6] = (data
>> 48) & 0xff;
104 ptr
[7] = (data
>> 56) & 0xff;
108 put_uint16_be (unsigned char *ptr
, uint16_t data
)
110 ptr
[1] = data
& 0xff;
111 ptr
[0] = (data
>> 8) & 0xff;
115 put_uint32_be (unsigned char *ptr
, uint32_t data
)
117 ptr
[3] = data
& 0xff;
118 ptr
[2] = (data
>> 8) & 0xff;
119 ptr
[1] = (data
>> 16) & 0xff;
120 ptr
[0] = (data
>> 24) & 0xff;
124 put_uint64_be (unsigned char *ptr
, uint64_t data
)
126 ptr
[7] = data
& 0xff;
127 ptr
[6] = (data
>> 8) & 0xff;
128 ptr
[5] = (data
>> 16) & 0xff;
129 ptr
[4] = (data
>> 24) & 0xff;
130 ptr
[3] = (data
>> 32) & 0xff;
131 ptr
[2] = (data
>> 40) & 0xff;
132 ptr
[1] = (data
>> 48) & 0xff;
133 ptr
[0] = (data
>> 56) & 0xff;
137 get_string (unsigned char *ptr
, char *dest
, size_t len
)
139 memcpy (dest
, ptr
, len
);
143 put_string (unsigned char *ptr
, char *src
, size_t len
)
145 memcpy (ptr
, src
, len
);
148 /* Use the target macro BYTES_BIG_ENDIAN to choose. */
150 static inline uint16_t
151 get_uint16 (const unsigned char *ptr
)
153 if (BYTES_BIG_ENDIAN
)
154 return get_uint16_be (ptr
);
156 return get_uint16_le (ptr
);
159 static inline uint32_t
160 get_uint32 (const unsigned char *ptr
)
162 if (BYTES_BIG_ENDIAN
)
163 return get_uint32_be (ptr
);
165 return get_uint32_le (ptr
);
168 static inline uint64_t
169 get_uint64 (const unsigned char *ptr
)
171 if (BYTES_BIG_ENDIAN
)
172 return get_uint64_be (ptr
);
174 return get_uint64_le (ptr
);
178 put_uint16 (unsigned char *ptr
, uint16_t data
)
180 if (BYTES_BIG_ENDIAN
)
181 put_uint16_be (ptr
, data
);
183 put_uint16_le (ptr
, data
);
187 put_uint32 (unsigned char *ptr
, uint32_t data
)
189 if (BYTES_BIG_ENDIAN
)
190 put_uint32_be (ptr
, data
);
192 put_uint32_le (ptr
, data
);
196 put_uint64 (unsigned char *ptr
, uint64_t data
)
198 if (BYTES_BIG_ENDIAN
)
199 put_uint64_be (ptr
, data
);
201 put_uint64_le (ptr
, data
);
204 #endif /* GCC_LTO_ENDIAN_H */