1 /* Unaligned memory access functionality.
2 Copyright (C) 2000, 2001, 2002, 2003, 2008 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2001.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 elfutils is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #define _UNALIGNED_H 1
26 #ifndef UNALIGNED_ACCESS_CLASS
27 # error "UNALIGNED_ACCESS_CLASS must be defined"
31 /* Macros to convert from the host byte order to that of the object file. */
32 #if UNALIGNED_ACCESS_CLASS == BYTE_ORDER
33 # define target_bswap_16(n) (n)
34 # define target_bswap_32(n) (n)
35 # define target_bswap_64(n) (n)
37 # define target_bswap_16(n) bswap_16 (n)
38 # define target_bswap_32(n) bswap_32 (n)
39 # define target_bswap_64(n) bswap_64 (n)
43 union u_2ubyte_unaligned
47 } __attribute__((packed));
49 union u_4ubyte_unaligned
53 } __attribute__((packed));
55 union u_8ubyte_unaligned
59 } __attribute__((packed));
62 /* Macros to store value at unaligned address. */
63 #define store_2ubyte_unaligned(ptr, value) \
64 (void) (((union u_2ubyte_unaligned *) (ptr))->u = target_bswap_16 (value))
65 #define store_4ubyte_unaligned(ptr, value) \
66 (void) (((union u_4ubyte_unaligned *) (ptr))->u = target_bswap_32 (value))
67 #define store_8ubyte_unaligned(ptr, value) \
68 (void) (((union u_8ubyte_unaligned *) (ptr))->u = target_bswap_64 (value))
71 /* Macros to add value to unaligned address. This is a bit more
72 complicated since the value must be read from memory and eventually
74 #if UNALIGNED_ACCESS_CLASS == BYTE_ORDER
75 # define add_2ubyte_unaligned(ptr, value) \
76 (void) (((union u_2ubyte_unaligned *) (ptr))->u += value)
77 # define add_4ubyte_unaligned(ptr, value) \
78 (void) (((union u_4ubyte_unaligned *) (ptr))->u += value)
79 # define add_8ubyte_unaligned(ptr, value) \
80 (void) (((union u_8ubyte_unaligned *) (ptr))->u += value)
82 # define add_2ubyte_unaligned(ptr, value) \
84 union u_2ubyte_unaligned *_ptr = (void *) (ptr); \
85 uint16_t _val = bswap_16 (_ptr->u) + (value); \
86 _ptr->u = bswap_16 (_val); \
88 # define add_4ubyte_unaligned(ptr, value) \
90 union u_4ubyte_unaligned *_ptr = (void *) (ptr); \
91 uint32_t _val = bswap_32 (_ptr->u) + (value); \
92 _ptr->u = bswap_32 (_val); \
94 # define add_8ubyte_unaligned(ptr, value) \
96 union u_8ubyte_unaligned *_ptr = (void *) (ptr); \
97 uint64_t _val = bswap_64 (_ptr->u) + (value); \
98 _ptr->u = bswap_64 (_val); \
102 #endif /* unaligned.h */