summaryrefslogtreecommitdiff
path: root/tests/read_unaligned.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/read_unaligned.c')
-rw-r--r--tests/read_unaligned.c564
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;
+}