Skip to content

Commit

Permalink
Use compiler intrinsics for rz_swap_* functions (#3300)
Browse files Browse the repository at this point in the history
* Using `__builtin_swap*()` whenever available instead of `rz_swap*()`
* Moved `test_endian()` from test_utils.c to test_endian.h
* Added test cases
  • Loading branch information
ZanF21 authored Jan 22, 2023
1 parent 9703de3 commit bbc5457
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 21 deletions.
28 changes: 28 additions & 0 deletions librz/include/rz_endian.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define RZ_ENDIAN_H

#include <rz_types.h>
#include <rz_userconf.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -592,36 +593,63 @@ static inline void rz_write_ble_double(void *src, double val, bool big_endian) {
}

/*swap*/

/* Use compiler intrinsics if present */

#if HAVE___BUILTIN_BSWAP16
#define rz_swap_ut16 __builtin_bswap16
#else
static inline ut16 rz_swap_ut16(ut16 val) {
return (val << 8) | (val >> 8);
}
#endif

#if HAVE___BUILTIN_BSWAP16
#define rz_swap_st16 __builtin_bswap16
#else
static inline st16 rz_swap_st16(st16 val) {
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
return (val << 16) | (val >> 16);
}
#endif

#if HAVE___BUILTIN_BSWAP32
#define rz_swap_ut32 __builtin_bswap32
#else
static inline ut32 rz_swap_ut32(ut32 val) {
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
return (val << 16) | (val >> 16);
}
#endif

#if HAVE___BUILTIN_BSWAP32
#define rz_swap_st32 __builtin_bswap32
#else
static inline st32 rz_swap_st32(st32 val) {
val = ((val << 8) & 0xFF00FF00) | ((val >> 8) & 0xFF00FF);
return (val << 16) | ((val >> 16) & 0xFFFF);
}
#endif

#if HAVE___BUILTIN_BSWAP64
#define rz_swap_ut64 __builtin_bswap64
#else
static inline ut64 rz_swap_ut64(ut64 val) {
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL);
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL);
return (val << 32) | (val >> 32);
}
#endif

#if HAVE___BUILTIN_BSWAP64
#define rz_swap_st64 __builtin_bswap64
#else
static inline st64 rz_swap_st64(st64 val) {
val = ((val << 8) & 0xFF00FF00FF00FF00ULL) | ((val >> 8) & 0x00FF00FF00FF00FFULL);
val = ((val << 16) & 0xFFFF0000FFFF0000ULL) | ((val >> 16) & 0x0000FFFF0000FFFFULL);
return (val << 32) | ((val >> 32) & 0xFFFFFFFFULL);
}
#endif

/* Some "secured" functions, to do basic operation (mul, sub, add...) on integers */
static inline int UT64_ADD(ut64 *r, ut64 a, ut64 b) {
Expand Down
3 changes: 3 additions & 0 deletions librz/include/rz_userconf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
#define HAVE_COPYFILE @HAVE_COPYFILE@
#define HAVE_COPY_FILE_RANGE @HAVE_COPY_FILE_RANGE@
#define HAVE_BACKTRACE @HAVE_BACKTRACE@
#define HAVE___BUILTIN_BSWAP16 @HAVE___BUILTIN_BSWAP16@
#define HAVE___BUILTIN_BSWAP32 @HAVE___BUILTIN_BSWAP32@
#define HAVE___BUILTIN_BSWAP64 @HAVE___BUILTIN_BSWAP64@

#define HAVE_HEADER_LINUX_ASHMEM_H @HAVE_HEADER_LINUX_ASHMEM_H@
#define HAVE_HEADER_SYS_SHM_H @HAVE_HEADER_SYS_SHM_H@
Expand Down
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ foreach it : ccs
# copy_file_range for now disable on freebsd as it s not reliable even for small chunks
['copy_file_range', '#ifdef __linux__\n#define _GNU_SOURCE\n#include <unistd.h>\n#endif', []],
['backtrace', '', []],
['__builtin_bswap16', '', []],
['__builtin_bswap32', '', []],
['__builtin_bswap64', '', []],
]
func = item[0]
ok = it_cc.has_function(func, prefix: item[1], dependencies: item[2])
Expand Down Expand Up @@ -794,3 +797,4 @@ summary({
'Parse Plugins': parse_plugins.get('list'),
'Demangler Plugins': demangler_plugins.get('list'),
}, section: 'Plugins', list_sep: ', ')

45 changes: 45 additions & 0 deletions test/unit/test_endian.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,47 @@
#include <stdlib.h>
#include "minunit.h"

bool test_endian(void) {
ut8 buf[8];
rz_write_be16(buf, 0x1122);
mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "be16");
rz_write_le16(buf, 0x1122);
mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "le16");

rz_write_be32(buf, 0x11223344);
mu_assert_memeq((ut8 *)"\x11\x22\x33\x44", buf, 4, "be32");
rz_write_le32(buf, 0x11223344);
mu_assert_memeq((ut8 *)"\x44\x33\x22\x11", buf, 4, "le32");

rz_write_ble(buf, 0x1122, true, 16);
mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "ble 16 true");
rz_write_ble(buf, 0x1122, false, 16);
mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "ble 16 false");

mu_end;
}

bool test_rz_swap_ut64(void) {
ut64 a = 0x1122334455667788;
ut64 b = rz_swap_ut64(a);
mu_assert_eq(b, 0x8877665544332211, "rz_swap_ut64");
mu_end;
}

bool test_rz_swap_ut32(void) {
ut32 a = 0x11223344;
ut32 b = rz_swap_ut32(a);
mu_assert_eq(b, 0x44332211, "rz_swap_ut32");
mu_end;
}

bool test_rz_swap_ut16(void) {
ut16 a = 0x1122;
ut16 b = rz_swap_ut16(a);
mu_assert_eq(b, 0x2211, "rz_swap_ut16");
mu_end;
}

bool test_be(void) {
const float f32 = 5.728f;
const ut8 bf32[4] = { 0x40, 0xb7, 0x4b, 0xc7 };
Expand Down Expand Up @@ -85,6 +126,10 @@ bool test_me(void) {
}

int all_tests() {
mu_run_test(test_endian);
mu_run_test(test_rz_swap_ut64);
mu_run_test(test_rz_swap_ut32);
mu_run_test(test_rz_swap_ut16);
mu_run_test(test_be);
mu_run_test(test_le);
mu_run_test(test_me);
Expand Down
21 changes: 0 additions & 21 deletions test/unit/test_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,8 @@ bool test_file_slurp(void) {
mu_end;
}

bool test_endian(void) {
ut8 buf[8];
rz_write_be16(buf, 0x1122);
mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "be16");
rz_write_le16(buf, 0x1122);
mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "le16");

rz_write_be32(buf, 0x11223344);
mu_assert_memeq((ut8 *)"\x11\x22\x33\x44", buf, 4, "be32");
rz_write_le32(buf, 0x11223344);
mu_assert_memeq((ut8 *)"\x44\x33\x22\x11", buf, 4, "le32");

rz_write_ble(buf, 0x1122, true, 16);
mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "ble 16 true");
rz_write_ble(buf, 0x1122, false, 16);
mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "ble 16 false");

mu_end;
}

int all_tests() {
mu_run_test(test_file_slurp);
mu_run_test(test_endian);
return tests_passed != tests_run;
}

Expand Down

0 comments on commit bbc5457

Please sign in to comment.