These come from kernel include/linux/unalignment directory. --- Makefile.am | 7 ++- include/unaligned.h | 54 +++++++++++++++++++++++ include/unaligned_be_byteshift.h | 90 +++++++++++++++++++++++++++++++++++++++ include/unaligned_be_struct.h | 58 +++++++++++++++++++++++++ include/unaligned_generic.h | 90 +++++++++++++++++++++++++++++++++++++++ include/unaligned_le_byteshift.h | 90 +++++++++++++++++++++++++++++++++++++++ include/unaligned_le_struct.h | 58 +++++++++++++++++++++++++ include/unaligned_packed_struct.h | 66 ++++++++++++++++++++++++++++ 8 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 include/unaligned.h create mode 100644 include/unaligned_be_byteshift.h create mode 100644 include/unaligned_be_struct.h create mode 100644 include/unaligned_generic.h create mode 100644 include/unaligned_le_byteshift.h create mode 100644 include/unaligned_le_struct.h create mode 100644 include/unaligned_packed_struct.h
diff --git a/Makefile.am b/Makefile.am index 31a42e4..5afa6a2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,7 +8,12 @@ include_HEADERS = include/types.h include/log.h include/plugin.h \ include/resolver.h include/ipconfig.h \ include/device.h include/network.h include/inet.h \ include/storage.h include/provision.h \ - include/session.h + include/session.h include/unaligned.h \ + include/unaligned_be_byteshift.h \ + include/unaligned_be_struct.h \ + include/unaligned_generic.h \ + include/unaligned_le_struct.h \ + include/unaligned_packed_struct.h nodist_include_HEADERS = include/version.h diff --git a/include/unaligned.h b/include/unaligned.h new file mode 100644 index 0000000..ca8edc2 --- /dev/null +++ b/include/unaligned.h @@ -0,0 +1,54 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_H +#define __CONNMAN_UNALIGNED_H + +#include <stdint.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +/* + * This is the most generic implementation of unaligned accesses + * and should work almost anywhere. + */ + +#if defined(__LITTLE_ENDIAN) +# include <connman/unaligned_le_struct.h> +# include <connman/unaligned_be_byteshift.h> +# include <connman/unaligned_generic.h> +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#elif defined(__BIG_ENDIAN) +# include <connman/unaligned_be_struct.h> +# include <connman/unaligned_le_byteshift.h> +# include <connman/unaligned_generic.h> +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#else +# error need to define endianess +#endif + +#endif /* __CONNMAN_UNALIGNED_H */ diff --git a/include/unaligned_be_byteshift.h b/include/unaligned_be_byteshift.h new file mode 100644 index 0000000..db249f8 --- /dev/null +++ b/include/unaligned_be_byteshift.h @@ -0,0 +1,90 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_BE_BYTESHIFT_H +#define __CONNMAN_UNALIGNED_BE_BYTESHIFT_H + +static inline u16 __get_unaligned_be16(const u8 *p) +{ + return p[0] << 8 | p[1]; +} + +static inline u32 __get_unaligned_be32(const u8 *p) +{ + return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; +} + +static inline u64 __get_unaligned_be64(const u8 *p) +{ + return (u64)__get_unaligned_be32(p) << 32 | + __get_unaligned_be32(p + 4); +} + +static inline void __put_unaligned_be16(u16 val, u8 *p) +{ + *p++ = val >> 8; + *p++ = val; +} + +static inline void __put_unaligned_be32(u32 val, u8 *p) +{ + __put_unaligned_be16(val >> 16, p); + __put_unaligned_be16(val, p + 2); +} + +static inline void __put_unaligned_be64(u64 val, u8 *p) +{ + __put_unaligned_be32(val >> 32, p); + __put_unaligned_be32(val, p + 4); +} + +static inline u16 get_unaligned_be16(const void *p) +{ + return __get_unaligned_be16((const u8 *)p); +} + +static inline u32 get_unaligned_be32(const void *p) +{ + return __get_unaligned_be32((const u8 *)p); +} + +static inline u64 get_unaligned_be64(const void *p) +{ + return __get_unaligned_be64((const u8 *)p); +} + +static inline void put_unaligned_be16(u16 val, void *p) +{ + __put_unaligned_be16(val, p); +} + +static inline void put_unaligned_be32(u32 val, void *p) +{ + __put_unaligned_be32(val, p); +} + +static inline void put_unaligned_be64(u64 val, void *p) +{ + __put_unaligned_be64(val, p); +} + +#endif /* __CONNMAN_UNALIGNED_BE_BYTESHIFT_H */ diff --git a/include/unaligned_be_struct.h b/include/unaligned_be_struct.h new file mode 100644 index 0000000..9f75e79 --- /dev/null +++ b/include/unaligned_be_struct.h @@ -0,0 +1,58 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_BE_STRUCT_H +#define __CONNMAN_UNALIGNED_BE_STRUCT_H + +#include <connman/unaligned_packed_struct.h> + +static inline u16 get_unaligned_be16(const void *p) +{ + return __get_unaligned_cpu16((const u8 *)p); +} + +static inline u32 get_unaligned_be32(const void *p) +{ + return __get_unaligned_cpu32((const u8 *)p); +} + +static inline u64 get_unaligned_be64(const void *p) +{ + return __get_unaligned_cpu64((const u8 *)p); +} + +static inline void put_unaligned_be16(u16 val, void *p) +{ + __put_unaligned_cpu16(val, p); +} + +static inline void put_unaligned_be32(u32 val, void *p) +{ + __put_unaligned_cpu32(val, p); +} + +static inline void put_unaligned_be64(u64 val, void *p) +{ + __put_unaligned_cpu64(val, p); +} + +#endif /* __CONNMAN_UNALIGNED_BE_STRUCT_H */ diff --git a/include/unaligned_generic.h b/include/unaligned_generic.h new file mode 100644 index 0000000..828ad0d --- /dev/null +++ b/include/unaligned_generic.h @@ -0,0 +1,90 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_GENERIC_H +#define __CONNMAN_UNALIGNED_GENERIC_H + +/* + * Cause a link-time error if we try an unaligned access other than + * 1,2,4 or 8 bytes long + */ +extern void __bad_unaligned_access_size(void); + +#define __get_unaligned_le(ptr) ((typeof(*(ptr)))({ \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),\ + __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),\ + __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),\ + __bad_unaligned_access_size())))); \ + })) + +#define __get_unaligned_be(ptr) ((typeof(*(ptr)))({ \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),\ + __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),\ + __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),\ + __bad_unaligned_access_size())))); \ + })) + +#define __put_unaligned_le(val, ptr) ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(u8 *)__gu_p = (u8)(val); \ + break; \ + case 2: \ + put_unaligned_le16((u16)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_le32((u32)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_le64((u64)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; }) + +#define __put_unaligned_be(val, ptr) ({ \ + void *__gu_p = (ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: \ + *(u8 *)__gu_p = (u8)(val); \ + break; \ + case 2: \ + put_unaligned_be16((u16)(val), __gu_p); \ + break; \ + case 4: \ + put_unaligned_be32((u32)(val), __gu_p); \ + break; \ + case 8: \ + put_unaligned_be64((u64)(val), __gu_p); \ + break; \ + default: \ + __bad_unaligned_access_size(); \ + break; \ + } \ + (void)0; }) + +#endif /* __CONNMAN_UNALIGNED_GENERIC_H */ diff --git a/include/unaligned_le_byteshift.h b/include/unaligned_le_byteshift.h new file mode 100644 index 0000000..82394a0 --- /dev/null +++ b/include/unaligned_le_byteshift.h @@ -0,0 +1,90 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_LE_BYTESHIFT_H +#define __CONNMAN_UNALIGNED_LE_BYTESHIFT_H + +static inline u16 __get_unaligned_le16(const u8 *p) +{ + return p[0] | p[1] << 8; +} + +static inline u32 __get_unaligned_le32(const u8 *p) +{ + return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; +} + +static inline u64 __get_unaligned_le64(const u8 *p) +{ + return (u64)__get_unaligned_le32(p + 4) << 32 | + __get_unaligned_le32(p); +} + +static inline void __put_unaligned_le16(u16 val, u8 *p) +{ + *p++ = val; + *p++ = val >> 8; +} + +static inline void __put_unaligned_le32(u32 val, u8 *p) +{ + __put_unaligned_le16(val >> 16, p + 2); + __put_unaligned_le16(val, p); +} + +static inline void __put_unaligned_le64(u64 val, u8 *p) +{ + __put_unaligned_le32(val >> 32, p + 4); + __put_unaligned_le32(val, p); +} + +static inline u16 get_unaligned_le16(const void *p) +{ + return __get_unaligned_le16((const u8 *)p); +} + +static inline u32 get_unaligned_le32(const void *p) +{ + return __get_unaligned_le32((const u8 *)p); +} + +static inline u64 get_unaligned_le64(const void *p) +{ + return __get_unaligned_le64((const u8 *)p); +} + +static inline void put_unaligned_le16(u16 val, void *p) +{ + __put_unaligned_le16(val, p); +} + +static inline void put_unaligned_le32(u32 val, void *p) +{ + __put_unaligned_le32(val, p); +} + +static inline void put_unaligned_le64(u64 val, void *p) +{ + __put_unaligned_le64(val, p); +} + +#endif /* __CONNMAN_UNALIGNED_LE_BYTESHIFT_H */ diff --git a/include/unaligned_le_struct.h b/include/unaligned_le_struct.h new file mode 100644 index 0000000..4849157 --- /dev/null +++ b/include/unaligned_le_struct.h @@ -0,0 +1,58 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_LE_STRUCT_H +#define __CONNMAN_UNALIGNED_LE_STRUCT_H + +#include <connman/unaligned_packed_struct.h> + +static inline u16 get_unaligned_le16(const void *p) +{ + return __get_unaligned_cpu16((const u8 *)p); +} + +static inline u32 get_unaligned_le32(const void *p) +{ + return __get_unaligned_cpu32((const u8 *)p); +} + +static inline u64 get_unaligned_le64(const void *p) +{ + return __get_unaligned_cpu64((const u8 *)p); +} + +static inline void put_unaligned_le16(u16 val, void *p) +{ + __put_unaligned_cpu16(val, p); +} + +static inline void put_unaligned_le32(u32 val, void *p) +{ + __put_unaligned_cpu32(val, p); +} + +static inline void put_unaligned_le64(u64 val, void *p) +{ + __put_unaligned_cpu64(val, p); +} + +#endif /* __CONNMAN_UNALIGNED_LE_STRUCT_H */ diff --git a/include/unaligned_packed_struct.h b/include/unaligned_packed_struct.h new file mode 100644 index 0000000..3ceed51 --- /dev/null +++ b/include/unaligned_packed_struct.h @@ -0,0 +1,66 @@ +/* + * + * Connection Manager + * + * The unaligned routines copied from linux kernel sources in + * include/linux/unaligned directory. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __CONNMAN_UNALIGNED_PACKED_STRUCT_H +#define __CONNMAN_UNALIGNED_PACKED_STRUCT_H + +struct __una_u16 { u16 x; } __attribute__((packed)); +struct __una_u32 { u32 x; } __attribute__((packed)); +struct __una_u64 { u64 x; } __attribute__((packed)); + +static inline u16 __get_unaligned_cpu16(const void *p) +{ + const struct __una_u16 *ptr = (const struct __una_u16 *)p; + return ptr->x; +} + +static inline u32 __get_unaligned_cpu32(const void *p) +{ + const struct __una_u32 *ptr = (const struct __una_u32 *)p; + return ptr->x; +} + +static inline u64 __get_unaligned_cpu64(const void *p) +{ + const struct __una_u64 *ptr = (const struct __una_u64 *)p; + return ptr->x; +} + +static inline void __put_unaligned_cpu16(u16 val, void *p) +{ + struct __una_u16 *ptr = (struct __una_u16 *)p; + ptr->x = val; +} + +static inline void __put_unaligned_cpu32(u32 val, void *p) +{ + struct __una_u32 *ptr = (struct __una_u32 *)p; + ptr->x = val; +} + +static inline void __put_unaligned_cpu64(u64 val, void *p) +{ + struct __una_u64 *ptr = (struct __una_u64 *)p; + ptr->x = val; +} + +#endif /* __CONNMAN_UNALIGNED_PACKED_STRUCT_H */ -- 1.7.11.4 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman