-
-
Notifications
You must be signed in to change notification settings - Fork 357
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make dyld_chained_ptr_* parsing endian-independent
Fixes test/db/cmd/cmd_tc on big endian
- Loading branch information
1 parent
7685bfe
commit a22ad57
Showing
4 changed files
with
230 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// SPDX-FileCopyrightText: 2022 Florian Märkl <info@florianmaerkl.de> | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
#include <rz_util.h> | ||
#include "../../librz/bin/format/mach0/mach0_defines.h" | ||
#include "minunit.h" | ||
|
||
/* | ||
* In real dyld, the dyld_chained_ptr_* structs are parsed by simply | ||
* reinterpreting a 64bit value as the respective bitfield struct. This of | ||
* course only works on little endian hosts, but we want to be | ||
* endian-independent, so we define or own readers. | ||
* The tests below compare the output of our readers against the dyld-style | ||
* reinterpretation to make sure we are parsing correctly. For adding tests for | ||
* a new struct, simply add a TEST_READ_DEF(...) and | ||
* mu_run_test(test_dyld_chained_..._read); line. | ||
*/ | ||
|
||
#if !RZ_SYS_ENDIAN | ||
|
||
#define SAMPLES 10000 | ||
|
||
static ut64 rand_ut64() { | ||
ut64 r = 0; | ||
for (int i = 0; i < 8; i++) { | ||
r = (rand() % 0xff) | (r << 8); | ||
} | ||
return r; | ||
} | ||
|
||
#define TEST_READ_DEF(name) \ | ||
bool test_##name##_read() { \ | ||
RZ_STATIC_ASSERT(sizeof(struct name) == sizeof(ut64)); \ | ||
for (int i = 0; i < SAMPLES; i++) { \ | ||
ut64 raw_val = rand_ut64(); /* this is the value we want to parse */ \ | ||
\ | ||
/* Parse with our endian-independent function */ \ | ||
struct name s; \ | ||
ut64 *s_direct = (ut64 *)&s; \ | ||
*s_direct = rand_ut64(); /* init with garbage */ \ | ||
name##_read(&s, raw_val); \ | ||
\ | ||
/* Compare our parsed value against a direct copy into the struct. */ \ | ||
/* This only works on little endian hosts! */ \ | ||
if (*s_direct != raw_val) { /* manual check to avoid rz_strf below */ \ | ||
char message[128]; \ | ||
snprintf(message, sizeof(message), #name "_read(0x%" PFMT64x ")", raw_val); \ | ||
mu_assert_eq(*s_direct, raw_val, message); \ | ||
} \ | ||
} \ | ||
mu_end; \ | ||
} | ||
|
||
TEST_READ_DEF(dyld_chained_ptr_arm64e_rebase) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_bind) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_auth_rebase) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_auth_bind) | ||
TEST_READ_DEF(dyld_chained_ptr_64_rebase) | ||
TEST_READ_DEF(dyld_chained_ptr_64_bind) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_cache_rebase) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_cache_auth_rebase) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_bind24) | ||
TEST_READ_DEF(dyld_chained_ptr_arm64e_auth_bind24) | ||
|
||
#endif | ||
|
||
bool all_tests() { | ||
srand(time(0)); | ||
#if !RZ_SYS_ENDIAN | ||
mu_run_test(test_dyld_chained_ptr_arm64e_rebase_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_bind_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_auth_rebase_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_auth_bind_read); | ||
mu_run_test(test_dyld_chained_ptr_64_rebase_read); | ||
mu_run_test(test_dyld_chained_ptr_64_bind_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_cache_rebase_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_cache_auth_rebase_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_bind24_read); | ||
mu_run_test(test_dyld_chained_ptr_arm64e_auth_bind24_read); | ||
#endif | ||
return tests_passed != tests_run; | ||
} | ||
|
||
mu_main(all_tests) |