diff options
Diffstat (limited to 'tests/read_unaligned.c')
-rw-r--r-- | tests/read_unaligned.c | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/tests/read_unaligned.c b/tests/read_unaligned.c new file mode 100644 index 00000000..15e0c002 --- /dev/null +++ b/tests/read_unaligned.c @@ -0,0 +1,564 @@ +/* Test program for read_[type]_unaligned. + Copyright (C) 2020, Red Hat Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + elfutils 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, see <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <endian.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "../libdw/libdwP.h" +#include "../libdw/memory-access.h" + +union u8 +{ + uint8_t v; + unsigned char c[1]; +}; + +union s8 +{ + int8_t v; + unsigned char c[1]; +}; + +union u16 +{ + uint16_t v; + unsigned char c[2]; +}; + +union s16 +{ + int16_t v; + unsigned char c[2]; +}; + +union u24 +{ + uint32_t v:24; + unsigned char c[3]; +} __attribute__((packed)); + +union u32 +{ + uint32_t v; + unsigned char c[4]; +}; + +union s32 +{ + int32_t v; + unsigned char c[4]; +}; + +union u64 +{ + uint64_t v; + unsigned char c[8]; +}; + +union s64 +{ + uint64_t v; + unsigned char c[8]; +}; + +uint8_t u8_nums[] = + { + 0, + 1, + UINT8_MAX / 2 - 1, + UINT8_MAX / 2, + UINT8_MAX / 2 + 1, + UINT8_MAX, + UINT8_MAX -1 + }; + +int8_t s8_nums[] = + { + INT8_MIN, + INT8_MIN + 1, + -1, + 0, + 1, + INT8_MAX, + INT8_MAX - 1 + }; + +uint16_t u16_nums[] = + { + 0, + 1, + UINT16_MAX / 2 - 1, + UINT16_MAX / 2, + UINT16_MAX / 2 + 1, + UINT16_MAX, + UINT16_MAX -1 + }; + +int16_t s16_nums[] = + { + INT16_MIN, + INT16_MIN + 1, + -1, + 0, + 1, + INT16_MAX, + INT16_MAX - 1 + }; + +#define UINT24_MAX 0xffffff + +uint32_t u24_nums[] = + { + 0, + 1, + UINT24_MAX / 2 - 1, + UINT24_MAX / 2, + UINT24_MAX / 2 + 1, + UINT24_MAX, + UINT24_MAX -1 + }; + +uint32_t u32_nums[] = + { + 0, + 1, + UINT32_MAX / 2 - 1, + UINT32_MAX / 2, + UINT32_MAX / 2 + 1, + UINT32_MAX, + UINT32_MAX -1 + }; + +int32_t s32_nums[] = + { + INT32_MIN, + INT32_MIN + 1, + -1, + 0, + 1, + INT32_MAX, + INT32_MAX - 1 + }; + +uint64_t u64_nums[] = + { + 0, + 1, + UINT64_MAX / 2 - 1, + UINT64_MAX / 2, + UINT64_MAX / 2 + 1, + UINT64_MAX, + UINT64_MAX -1 + }; + +int64_t s64_nums[] = + { + INT64_MIN, + INT64_MIN + 1, + -1, + 0, + 1, + INT64_MAX, + INT64_MAX - 1 + }; + +static unsigned char le_mem[] = + { + /* u8 */ + 0x00, + 0x01, + 0x7e, + 0x7f, + 0x80, + 0xff, + 0xfe, + /* s8 */ + 0x80, + 0x81, + 0xff, + 0x00, + 0x01, + 0x7f, + 0x7e, + /* u16 */ + 0x00, 0x00, + 0x01, 0x00, + 0xfe, 0x7f, + 0xff, 0x7f, + 0x00, 0x80, + 0xff, 0xff, + 0xfe, 0xff, + /* s16 */ + 0x00, 0x80, + 0x01, 0x80, + 0xff, 0xff, + 0x00, 0x00, + 0x01, 0x00, + 0xff, 0x7f, + 0xfe, 0x7f, + /* u24 */ + 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, + 0xfe, 0xff, 0x7f, + 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xff, + /* u32 */ + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xff, 0xff, + /* s32 */ + 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x7f, + 0xfe, 0xff, 0xff, 0x7f, + /* u64 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* s64 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + }; + +static unsigned char be_mem[] = + { + /* u8 */ + 0x00, + 0x01, + 0x7e, + 0x7f, + 0x80, + 0xff, + 0xfe, + /* s8 */ + 0x80, + 0x81, + 0xff, + 0x00, + 0x01, + 0x7f, + 0x7e, + /* u16 */ + 0x00, 0x00, + 0x00, 0x01, + 0x7f, 0xfe, + 0x7f, 0xff, + 0x80, 0x00, + 0xff, 0xff, + 0xff, 0xfe, + /* s16 */ + 0x80, 0x00, + 0x80, 0x01, + 0xff, 0xff, + 0x00, 0x00, + 0x00, 0x01, + 0x7f, 0xff, + 0x7f, 0xfe, + /* u24 */ + 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + 0x7f, 0xff, 0xfe, + 0x7f, 0xff, 0xff, + 0x80, 0x00, 0x00, + 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, + /* u32 */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x7f, 0xff, 0xff, 0xfe, + 0x7f, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, + /* s32 */ + 0x80, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x7f, 0xff, 0xff, 0xff, + 0x7f, 0xff, 0xff, 0xfe, + /* u64 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + /* s64 */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + }; + +int +main (int argc, char **argv __attribute__((unused))) +{ + /* No arguments means check, otherwise Write out the memory array. */ + bool write = false; + if (argc > 1) + write = true; + + bool is_le = (BYTE_ORDER == LITTLE_ENDIAN); + + if (write) + { + if (is_le) + printf ("static unsigned char le_mem[] =\n"); + else + printf ("static unsigned char be_mem[] =\n"); + printf (" {\n"); + } + + Dwarf dbg_le = { .other_byte_order = !is_le }; + Dwarf dbg_be = { .other_byte_order = is_le }; + + unsigned char *p_le = le_mem; + unsigned char *p_be = be_mem; + + union u8 u8; + if (write) + printf (" /* u8 */\n"); + for (size_t i = 0; i < sizeof (u8_nums) / sizeof (u8); i++) + { + if (write) + { + u8.v = u8_nums[i]; + printf (" 0x%02" PRIx8 ",\n", u8.c[0]); + } + else + { + uint8_t v = *p_le++; + assert (v == u8_nums[i]); + v = *p_be++; + assert (v == u8_nums[i]); + } + } + + union s8 s8; + if (write) + printf (" /* s8 */\n"); + for (size_t i = 0; i < sizeof (s8_nums) / sizeof (s8); i++) + { + if (write) + { + s8.v = s8_nums[i]; + printf (" 0x%02" PRIx8 ",\n", s8.c[0]); + } + else + { + int8_t v = *p_le++; + assert (v == s8_nums[i]); + v = *p_be++; + assert (v == s8_nums[i]); + } + } + + union u16 u16; + if (write) + printf (" /* u16 */\n"); + for (size_t i = 0; i < sizeof (u16_nums) / sizeof (u16); i++) + { + if (write) + { + u16.v = u16_nums[i]; + printf (" 0x%02" PRIx8 ", ", u16.c[0]); + printf ("0x%02" PRIx8 ",\n", u16.c[1]); + } + else + { + uint16_t v = read_2ubyte_unaligned_inc (&dbg_le, p_le); + assert (v == u16_nums[i]); + v = read_2ubyte_unaligned_inc (&dbg_be, p_be); + assert (v == u16_nums[i]); + } + } + + union s16 s16; + if (write) + printf (" /* s16 */\n"); + for (size_t i = 0; i < sizeof (s16_nums) / sizeof (s16); i++) + { + if (write) + { + s16.v = s16_nums[i]; + printf (" 0x%02" PRIx8 ", ", s16.c[0]); + printf ("0x%02" PRIx8 ",\n", s16.c[1]); + } + else + { + int16_t v = read_2sbyte_unaligned_inc (&dbg_le, p_le); + assert (v == s16_nums[i]); + v = read_2sbyte_unaligned_inc (&dbg_be, p_be); + assert (v == s16_nums[i]); + } + } + + union u24 u24; + if (write) + printf (" /* u24 */\n"); + for (size_t i = 0; i < sizeof (u24_nums) / sizeof (uint32_t); i++) + { + if (write) + { + u24.v = u24_nums[i]; + printf (" 0x%02" PRIx8 ", ", u24.c[0]); + printf ("0x%02" PRIx8 ", ", u24.c[1]); + printf ("0x%02" PRIx8 ",\n", u24.c[2]); + } + else + { + uint32_t v = read_3ubyte_unaligned_inc (&dbg_le, p_le); + assert (v == u24_nums[i]); + v = read_3ubyte_unaligned_inc (&dbg_be, p_be); + assert (v == u24_nums[i]); + } + } + + union u32 u32; + if (write) + printf (" /* u32 */\n"); + for (size_t i = 0; i < sizeof (u32_nums) / sizeof (u32); i++) + { + if (write) + { + u32.v = u32_nums[i]; + printf (" 0x%02" PRIx8 ", ", u32.c[0]); + printf ("0x%02" PRIx8 ", ", u32.c[1]); + printf ("0x%02" PRIx8 ", ", u32.c[2]); + printf ("0x%02" PRIx8 ",\n", u32.c[3]); + } + else + { + uint32_t v = read_4ubyte_unaligned_inc (&dbg_le, p_le); + assert (v == u32_nums[i]); + v = read_4ubyte_unaligned_inc (&dbg_be, p_be); + assert (v == u32_nums[i]); + } + } + + union s32 s32; + if (write) + printf (" /* s32 */\n"); + for (size_t i = 0; i < sizeof (s32_nums) / sizeof (s32); i++) + { + if (write) + { + s32.v = s32_nums[i]; + printf (" 0x%02" PRIx8 ", ", s32.c[0]); + printf ("0x%02" PRIx8 ", ", s32.c[1]); + printf ("0x%02" PRIx8 ", ", s32.c[2]); + printf ("0x%02" PRIx8 ",\n", s32.c[3]); + } + else + { + int32_t v = read_4sbyte_unaligned_inc (&dbg_le, p_le); + assert (v == s32_nums[i]); + v = read_4sbyte_unaligned_inc (&dbg_be, p_be); + assert (v == s32_nums[i]); + } + } + + union u64 u64; + if (write) + printf (" /* u64 */\n"); + for (size_t i = 0; i < sizeof (u64_nums) / sizeof (u64); i++) + { + if (write) + { + u64.v = u64_nums[i]; + printf (" 0x%02" PRIx8 ", ", u64.c[0]); + printf ("0x%02" PRIx8 ", ", u64.c[1]); + printf ("0x%02" PRIx8 ", ", u64.c[2]); + printf ("0x%02" PRIx8 ", ", u64.c[3]); + printf ("0x%02" PRIx8 ", ", u64.c[4]); + printf ("0x%02" PRIx8 ", ", u64.c[5]); + printf ("0x%02" PRIx8 ", ", u64.c[6]); + printf ("0x%02" PRIx8 ",\n", u64.c[7]); + } + else + { + uint64_t v = read_8ubyte_unaligned_inc (&dbg_le, p_le); + assert (v == u64_nums[i]); + v = read_8ubyte_unaligned_inc (&dbg_be, p_be); + assert (v == u64_nums[i]); + } + } + + union s64 s64; + if (write) + printf (" /* s64 */\n"); + for (size_t i = 0; i < sizeof (s64_nums) / sizeof (s64); i++) + { + if (write) + { + s64.v = s64_nums[i]; + printf (" 0x%02" PRIx8 ", ", s64.c[0]); + printf ("0x%02" PRIx8 ", ", s64.c[1]); + printf ("0x%02" PRIx8 ", ", s64.c[2]); + printf ("0x%02" PRIx8 ", ", s64.c[3]); + printf ("0x%02" PRIx8 ", ", s64.c[4]); + printf ("0x%02" PRIx8 ", ", s64.c[5]); + printf ("0x%02" PRIx8 ", ", s64.c[6]); + printf ("0x%02" PRIx8 ",\n", s64.c[7]); + } + else + { + int64_t v = read_8sbyte_unaligned_inc (&dbg_le, p_le); + assert (v == s64_nums[i]); + v = read_8sbyte_unaligned_inc (&dbg_be, p_be); + assert (v == s64_nums[i]); + } + } + + if (write) + printf (" };\n"); + else + { + assert (p_le == le_mem + sizeof (le_mem)); + assert (p_be == be_mem + sizeof (be_mem)); + } + + return 0; +} |