Rename R_CONST to R_TAG and add unit tests for them ##api

This commit is contained in:
pancake 2023-04-12 21:40:49 +02:00 committed by pancake
parent eaea585b0d
commit 60f8492f2b
3 changed files with 47 additions and 10 deletions

View File

@ -18,7 +18,7 @@
#define IFDBG if (esil && esil->verbose > 1)
static inline void free_ornot(void *p) {
R_CONST_FREE (p);
R_TAG_FREE (p);
}
/* Returns the number that has bits + 1 least significant bits set. */
@ -54,7 +54,7 @@ static bool r_esil_runpending(REsil *esil, char *pending) {
} else if (esil->pending) {
char *expr = esil->pending;
esil->pending = NULL;
r_esil_parse (esil, R_CONST_UNTAG (expr));
r_esil_parse (esil, R_TAG_NOP (expr));
free_ornot (expr);
return true;
}

View File

@ -263,11 +263,24 @@ typedef struct _utX {
#define R_IS_DIRTY(x) (x)->is_dirty
#define R_DIRTY_VAR bool is_dirty
#define R_CONST_MAYBE
#define R_CONST_TAG(x) ((x)|1)
#define R_CONST_UNTAG(x) (void*)((((size_t)x)>>1)<<1)
#define R_CONST_FREE(x) do { if (!((size_t)(x)&1)) { R_FREE(x); }} while(0)
#define R_IS_CONST(x) ((size_t)(x)&1))
#define R_TAG(x) (void*)((size_t)(x)|1)
#define R_UNTAG(x) (void*)((((size_t)(x))&(size_t)-2))
#define R_TAG_FREE(x) do { if (!((size_t)(x)&1)) { R_FREE(x); }} while(0)
#define R_TAG_NOP(x) untagged_pointer_check(x)
#define R_IS_TAGGED(x) ((size_t)(x)&1)
#define R_TAGGED
#if R_CHECKS_LEVEL == 0
static inline void *untagged_pointer_check(void *x) {
return x;
}
#else
static inline void *untagged_pointer_check(void *x) {
if (R_IS_TAGGED(x)) {
int *p = (int*)0; *p = 0;
}
return x;
}
#endif
#ifdef __cplusplus
}

View File

@ -151,11 +151,34 @@ bool test_file_slurp(void) {
mu_end;
}
R_ALIGNED(4) static const char msg[] = "Hello World"; // const strings can have the lowerbit set
R_TAGGED void *tagged(bool owned) {
if (owned) {
void *res = strdup ("hello world");
return R_TAG_NOP (res);
}
return R_TAG (msg);
}
bool test_tagged_pointers(void) {
void *a = tagged (false);
void *b = tagged (true);
// eprintf ("%p %p\n", a, b);
// eprintf ("%d %d\n", (size_t)a&1, (size_t)b&1);
mu_assert_eq (R_IS_TAGGED (a), 1, "tagged");
char *msg = R_UNTAG (a);
mu_assert_streq (msg, "Hello World", "faileq");
mu_assert_eq (R_IS_TAGGED (b), 0, "not tagged");
char *msg2 = R_UNTAG (b);
mu_assert_streq (msg2, "hello world", "faileq");
R_TAG_FREE (a);
R_TAG_FREE (b);
mu_end;
}
bool test_initial_underscore(void) {
Sdb *TDB = setup_sdb ();
char *s;
s = r_type_func_guess (TDB, "sym._strchr");
char *s = r_type_func_guess (TDB, "sym._strchr");
mu_assert_notnull (s, "sym._ should be ignored");
mu_assert_streq (s, "strchr", "strchr should be identified");
free (s);
@ -212,6 +235,7 @@ int all_tests() {
mu_run_test (test_autonames);
mu_run_test (test_file_slurp);
mu_run_test (test_initial_underscore);
mu_run_test (test_tagged_pointers);
return tests_passed != tests_run;
}