From: Mark Wielaard Date: Sun, 25 Oct 2020 19:40:33 +0000 (+0100) Subject: tests: Add read_unaligned testcase X-Git-Tag: elfutils-0.182~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4c39dc18bbba4801c016c0b24d03d697fb14aa24;p=platform%2Fupstream%2Felfutils.git tests: Add read_unaligned testcase Run tests/read_unaligned 1 on a big endian and little endian machine to generate the le_mem and be_mem arrays. The one byte variants are kind of impossible to get wrong, but including them makes sure the other variants are not naturally aligned in memory. Signed-off-by: Mark Wielaard --- diff --git a/tests/ChangeLog b/tests/ChangeLog index 91aeada..d0149ba 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2020-10-25 Mark Wielaard + + * read_unaligned.c: New test. + * Makefile.am (check_PROGRAMS, TESTS): Add read_unaligned. + (read_unaligned_LDADD): New variable. + 2020-10-28 Tom Tromey PR26773 diff --git a/tests/Makefile.am b/tests/Makefile.am index 1b51ab8..84f6e88 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -63,7 +63,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \ all-dwarf-ranges unit-info next_cfi \ elfcopy addsections xlate_notes elfrdwrnop \ dwelf_elf_e_machine_string \ - getphdrnum leb128 + getphdrnum leb128 read_unaligned asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \ asm-tst6 asm-tst7 asm-tst8 asm-tst9 @@ -186,7 +186,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \ run-disasm-riscv64.sh \ run-pt_gnu_prop-tests.sh \ run-getphdrnum.sh run-test-includes.sh \ - leb128 + leb128 read_unaligned if !BIARCH export ELFUTILS_DISABLE_BIARCH = 1 @@ -696,6 +696,7 @@ elfrdwrnop_LDADD = $(libelf) dwelf_elf_e_machine_string_LDADD = $(libelf) $(libdw) getphdrnum_LDADD = $(libelf) $(libdw) leb128_LDADD = $(libelf) $(libdw) +read_unaligned_LDADD = $(libelf) $(libdw) # We want to test the libelf header against the system elf.h header. # Don't include any -I CPPFLAGS. Except when we install our own elf.h. diff --git a/tests/read_unaligned.c b/tests/read_unaligned.c new file mode 100644 index 0000000..15e0c00 --- /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 . */ + +#include +#include +#include +#include +#include +#include + +#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; +}