1*7304104dSAndroid Build Coastguard Worker /* Unaligned memory access functionality.
2*7304104dSAndroid Build Coastguard Worker Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker Written by Ulrich Drepper <[email protected]>, 2001.
4*7304104dSAndroid Build Coastguard Worker
5*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
6*7304104dSAndroid Build Coastguard Worker it under the terms of either
7*7304104dSAndroid Build Coastguard Worker
8*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
9*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
10*7304104dSAndroid Build Coastguard Worker your option) any later version
11*7304104dSAndroid Build Coastguard Worker
12*7304104dSAndroid Build Coastguard Worker or
13*7304104dSAndroid Build Coastguard Worker
14*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
15*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
16*7304104dSAndroid Build Coastguard Worker your option) any later version
17*7304104dSAndroid Build Coastguard Worker
18*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
19*7304104dSAndroid Build Coastguard Worker
20*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
21*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
22*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23*7304104dSAndroid Build Coastguard Worker General Public License for more details.
24*7304104dSAndroid Build Coastguard Worker
25*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
26*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
27*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
28*7304104dSAndroid Build Coastguard Worker
29*7304104dSAndroid Build Coastguard Worker #ifndef _MEMORY_ACCESS_H
30*7304104dSAndroid Build Coastguard Worker #define _MEMORY_ACCESS_H 1
31*7304104dSAndroid Build Coastguard Worker
32*7304104dSAndroid Build Coastguard Worker #include <limits.h>
33*7304104dSAndroid Build Coastguard Worker #include <stdint.h>
34*7304104dSAndroid Build Coastguard Worker
35*7304104dSAndroid Build Coastguard Worker #include <system.h>
36*7304104dSAndroid Build Coastguard Worker
37*7304104dSAndroid Build Coastguard Worker /* When loading this file we require the macro MACHINE_ENCODING to be
38*7304104dSAndroid Build Coastguard Worker defined to signal the endianness of the architecture which is
39*7304104dSAndroid Build Coastguard Worker defined. */
40*7304104dSAndroid Build Coastguard Worker #ifndef MACHINE_ENCODING
41*7304104dSAndroid Build Coastguard Worker # error "MACHINE_ENCODING needs to be defined"
42*7304104dSAndroid Build Coastguard Worker #endif
43*7304104dSAndroid Build Coastguard Worker #if MACHINE_ENCODING != BIG_ENDIAN && MACHINE_ENCODING != LITTLE_ENDIAN
44*7304104dSAndroid Build Coastguard Worker # error "MACHINE_ENCODING must signal either big or little endian"
45*7304104dSAndroid Build Coastguard Worker #endif
46*7304104dSAndroid Build Coastguard Worker
47*7304104dSAndroid Build Coastguard Worker
48*7304104dSAndroid Build Coastguard Worker /* We use simple memory access functions in case the hardware allows it.
49*7304104dSAndroid Build Coastguard Worker The caller has to make sure we don't have alias problems. */
50*7304104dSAndroid Build Coastguard Worker #if ALLOW_UNALIGNED
51*7304104dSAndroid Build Coastguard Worker
52*7304104dSAndroid Build Coastguard Worker # define read_2ubyte_unaligned(Addr) \
53*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
54*7304104dSAndroid Build Coastguard Worker ? bswap_16 (*((const uint16_t *) (Addr))) \
55*7304104dSAndroid Build Coastguard Worker : *((const uint16_t *) (Addr)))
56*7304104dSAndroid Build Coastguard Worker # define read_2sbyte_unaligned(Addr) \
57*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
58*7304104dSAndroid Build Coastguard Worker ? (int16_t) bswap_16 (*((const int16_t *) (Addr))) \
59*7304104dSAndroid Build Coastguard Worker : *((const int16_t *) (Addr)))
60*7304104dSAndroid Build Coastguard Worker
61*7304104dSAndroid Build Coastguard Worker # define read_4ubyte_unaligned_noncvt(Addr) \
62*7304104dSAndroid Build Coastguard Worker *((const uint32_t *) (Addr))
63*7304104dSAndroid Build Coastguard Worker # define read_4ubyte_unaligned(Addr) \
64*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
65*7304104dSAndroid Build Coastguard Worker ? bswap_32 (*((const uint32_t *) (Addr))) \
66*7304104dSAndroid Build Coastguard Worker : *((const uint32_t *) (Addr)))
67*7304104dSAndroid Build Coastguard Worker # define read_4sbyte_unaligned(Addr) \
68*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
69*7304104dSAndroid Build Coastguard Worker ? (int32_t) bswap_32 (*((const int32_t *) (Addr))) \
70*7304104dSAndroid Build Coastguard Worker : *((const int32_t *) (Addr)))
71*7304104dSAndroid Build Coastguard Worker
72*7304104dSAndroid Build Coastguard Worker # define read_8ubyte_unaligned(Addr) \
73*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
74*7304104dSAndroid Build Coastguard Worker ? bswap_64 (*((const uint64_t *) (Addr))) \
75*7304104dSAndroid Build Coastguard Worker : *((const uint64_t *) (Addr)))
76*7304104dSAndroid Build Coastguard Worker # define read_8sbyte_unaligned(Addr) \
77*7304104dSAndroid Build Coastguard Worker (unlikely (MACHINE_ENCODING != BYTE_ORDER) \
78*7304104dSAndroid Build Coastguard Worker ? (int64_t) bswap_64 (*((const int64_t *) (Addr))) \
79*7304104dSAndroid Build Coastguard Worker : *((const int64_t *) (Addr)))
80*7304104dSAndroid Build Coastguard Worker
81*7304104dSAndroid Build Coastguard Worker #else
82*7304104dSAndroid Build Coastguard Worker
83*7304104dSAndroid Build Coastguard Worker union unaligned
84*7304104dSAndroid Build Coastguard Worker {
85*7304104dSAndroid Build Coastguard Worker void *p;
86*7304104dSAndroid Build Coastguard Worker uint16_t u2;
87*7304104dSAndroid Build Coastguard Worker uint32_t u4;
88*7304104dSAndroid Build Coastguard Worker uint64_t u8;
89*7304104dSAndroid Build Coastguard Worker int16_t s2;
90*7304104dSAndroid Build Coastguard Worker int32_t s4;
91*7304104dSAndroid Build Coastguard Worker int64_t s8;
92*7304104dSAndroid Build Coastguard Worker } attribute_packed;
93*7304104dSAndroid Build Coastguard Worker
94*7304104dSAndroid Build Coastguard Worker static inline uint16_t
read_2ubyte_unaligned(const void * p)95*7304104dSAndroid Build Coastguard Worker read_2ubyte_unaligned (const void *p)
96*7304104dSAndroid Build Coastguard Worker {
97*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
98*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
99*7304104dSAndroid Build Coastguard Worker return bswap_16 (up->u2);
100*7304104dSAndroid Build Coastguard Worker return up->u2;
101*7304104dSAndroid Build Coastguard Worker }
102*7304104dSAndroid Build Coastguard Worker static inline int16_t
read_2sbyte_unaligned(const void * p)103*7304104dSAndroid Build Coastguard Worker read_2sbyte_unaligned (const void *p)
104*7304104dSAndroid Build Coastguard Worker {
105*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
106*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
107*7304104dSAndroid Build Coastguard Worker return (int16_t) bswap_16 (up->u2);
108*7304104dSAndroid Build Coastguard Worker return up->s2;
109*7304104dSAndroid Build Coastguard Worker }
110*7304104dSAndroid Build Coastguard Worker
111*7304104dSAndroid Build Coastguard Worker static inline uint32_t
read_4ubyte_unaligned_noncvt(const void * p)112*7304104dSAndroid Build Coastguard Worker read_4ubyte_unaligned_noncvt (const void *p)
113*7304104dSAndroid Build Coastguard Worker {
114*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
115*7304104dSAndroid Build Coastguard Worker return up->u4;
116*7304104dSAndroid Build Coastguard Worker }
117*7304104dSAndroid Build Coastguard Worker static inline uint32_t
read_4ubyte_unaligned(const void * p)118*7304104dSAndroid Build Coastguard Worker read_4ubyte_unaligned (const void *p)
119*7304104dSAndroid Build Coastguard Worker {
120*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
121*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
122*7304104dSAndroid Build Coastguard Worker return bswap_32 (up->u4);
123*7304104dSAndroid Build Coastguard Worker return up->u4;
124*7304104dSAndroid Build Coastguard Worker }
125*7304104dSAndroid Build Coastguard Worker static inline int32_t
read_4sbyte_unaligned(const void * p)126*7304104dSAndroid Build Coastguard Worker read_4sbyte_unaligned (const void *p)
127*7304104dSAndroid Build Coastguard Worker {
128*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
129*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
130*7304104dSAndroid Build Coastguard Worker return (int32_t) bswap_32 (up->u4);
131*7304104dSAndroid Build Coastguard Worker return up->s4;
132*7304104dSAndroid Build Coastguard Worker }
133*7304104dSAndroid Build Coastguard Worker
134*7304104dSAndroid Build Coastguard Worker static inline uint64_t
read_8ubyte_unaligned(const void * p)135*7304104dSAndroid Build Coastguard Worker read_8ubyte_unaligned (const void *p)
136*7304104dSAndroid Build Coastguard Worker {
137*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
138*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
139*7304104dSAndroid Build Coastguard Worker return bswap_64 (up->u8);
140*7304104dSAndroid Build Coastguard Worker return up->u8;
141*7304104dSAndroid Build Coastguard Worker }
142*7304104dSAndroid Build Coastguard Worker static inline int64_t
read_8sbyte_unaligned(const void * p)143*7304104dSAndroid Build Coastguard Worker read_8sbyte_unaligned (const void *p)
144*7304104dSAndroid Build Coastguard Worker {
145*7304104dSAndroid Build Coastguard Worker const union unaligned *up = p;
146*7304104dSAndroid Build Coastguard Worker if (MACHINE_ENCODING != BYTE_ORDER)
147*7304104dSAndroid Build Coastguard Worker return (int64_t) bswap_64 (up->u8);
148*7304104dSAndroid Build Coastguard Worker return up->s8;
149*7304104dSAndroid Build Coastguard Worker }
150*7304104dSAndroid Build Coastguard Worker
151*7304104dSAndroid Build Coastguard Worker #endif /* allow unaligned */
152*7304104dSAndroid Build Coastguard Worker
153*7304104dSAndroid Build Coastguard Worker
154*7304104dSAndroid Build Coastguard Worker #define read_2ubyte_unaligned_inc(Addr) \
155*7304104dSAndroid Build Coastguard Worker ({ uint16_t t_ = read_2ubyte_unaligned (Addr); \
156*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \
157*7304104dSAndroid Build Coastguard Worker t_; })
158*7304104dSAndroid Build Coastguard Worker #define read_2sbyte_unaligned_inc(Addr) \
159*7304104dSAndroid Build Coastguard Worker ({ int16_t t_ = read_2sbyte_unaligned (Addr); \
160*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2); \
161*7304104dSAndroid Build Coastguard Worker t_; })
162*7304104dSAndroid Build Coastguard Worker
163*7304104dSAndroid Build Coastguard Worker #define read_4ubyte_unaligned_inc(Addr) \
164*7304104dSAndroid Build Coastguard Worker ({ uint32_t t_ = read_4ubyte_unaligned (Addr); \
165*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \
166*7304104dSAndroid Build Coastguard Worker t_; })
167*7304104dSAndroid Build Coastguard Worker #define read_4sbyte_unaligned_inc(Addr) \
168*7304104dSAndroid Build Coastguard Worker ({ int32_t t_ = read_4sbyte_unaligned (Addr); \
169*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4); \
170*7304104dSAndroid Build Coastguard Worker t_; })
171*7304104dSAndroid Build Coastguard Worker
172*7304104dSAndroid Build Coastguard Worker #define read_8ubyte_unaligned_inc(Addr) \
173*7304104dSAndroid Build Coastguard Worker ({ uint64_t t_ = read_8ubyte_unaligned (Addr); \
174*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \
175*7304104dSAndroid Build Coastguard Worker t_; })
176*7304104dSAndroid Build Coastguard Worker #define read_8sbyte_unaligned_inc(Addr) \
177*7304104dSAndroid Build Coastguard Worker ({ int64_t t_ = read_8sbyte_unaligned (Addr); \
178*7304104dSAndroid Build Coastguard Worker Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8); \
179*7304104dSAndroid Build Coastguard Worker t_; })
180*7304104dSAndroid Build Coastguard Worker
181*7304104dSAndroid Build Coastguard Worker #endif /* memory-access.h */
182