arg_conv_cleanup = None,
ret_conv = (ty_info.c_ty + " " + ty_info.var_name + "_conv = " + ret_pfx, ret_sfx + ";"),
ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
- base_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)(((uint64_t)" + ty_info.var_name + ") & ~1);"
+ base_conv = "void* " + ty_info.var_name + "_ptr = (void*)(((uint64_t)" + ty_info.var_name + ") & ~1);\n"
+ base_conv += "CHECK_ACCESS(" + ty_info.var_name + "_ptr);\n"
+ base_conv += ty_info.rust_obj + " " + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)(" + ty_info.var_name + "_ptr);"
if ty_info.rust_obj in self.trait_structs:
ret_conv = (ty_info.rust_obj + "* " + ty_info.var_name + "_ret =MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*" + ty_info.var_name + "_ret = ", ";")
if holds_ref:
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", from_hu_sfx))
elif ty_info.rust_obj in self.trait_structs:
if ty_info.nonnull_ptr:
- arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)(((uint64_t)" + ty_info.var_name + ") & ~1);"
+ arg_conv = "void* " + ty_info.var_name + "_ptr = (void*)(((uint64_t)" + ty_info.var_name + ") & ~1);\n"
+ arg_conv += "if (!(" + ty_info.var_name + " & 1)) { CHECK_ACCESS(" + ty_info.var_name + "_ptr); }\n"
+ arg_conv += ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + "_ptr;"
arg_conv_name = ty_info.var_name + "_conv"
else:
# We map Option<Trait> as *mut Trait, which we can differentiate from &Trait by the NONNULL_PTR annotation.
arg_conv = ty_info.rust_obj + " *" + ty_info.var_name + "_conv_ptr = NULL;\n"
arg_conv += "if (" + ty_info.var_name + " != 0) {\n"
arg_conv += "\t" + ty_info.rust_obj + " " + ty_info.var_name + "_conv;\n"
- arg_conv += "\t" + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)(((uint64_t)" + ty_info.var_name + ") & ~1);"
+ arg_conv += "void* " + ty_info.var_name + "_ptr = (void*)(((uint64_t)" + ty_info.var_name + ") & ~1);\n"
+ arg_conv += "CHECK_ACCESS(" + ty_info.var_name + "_ptr);\n"
+ arg_conv += "\t" + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)" + ty_info.var_name + "_ptr;"
arg_conv += self.consts.trait_struct_inc_refcnt(ty_info).replace("\n", "\n\t")
arg_conv += "\n\t" + ty_info.var_name + "_conv_ptr = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n"
arg_conv += "\t*" + ty_info.var_name + "_conv_ptr = " + ty_info.var_name + "_conv;\n"
if not DEBUG or sys.platform == "darwin":
self.c_file_pfx = self.c_file_pfx + """#define MALLOC(a, _) malloc(a)
#define FREE(p) if ((uint64_t)(p) > 1024) { free(p); }
+#define CHECK_ACCESS(p)
"""
if not DEBUG:
self.c_file_pfx += """#define DO_ASSERT(a) (void)(a)
while (it->ptr != ptr) {
p = it; it = it->next;
if (it == NULL) {
- DEBUG_PRINT("Tried to free unknown pointer %p at:\\n", ptr);
+ DEBUG_PRINT("ERROR: Tried to free unknown pointer %p at:\\n", ptr);
void* bt[BT_MAX];
int bt_len = backtrace(bt, BT_MAX);
backtrace_symbols_fd(bt, bt_len, STDERR_FILENO);
__real_free(ptr);
}
+static void CHECK_ACCESS(void* ptr) {
+ DO_ASSERT(!pthread_mutex_lock(&allocation_mtx));
+ allocation* it = allocation_ll;
+ while (it->ptr != ptr) {
+ it = it->next;
+ if (it == NULL) {
+ DEBUG_PRINT("ERROR: Tried to access unknown pointer %p at:\\n", ptr);
+ void* bt[BT_MAX];
+ int bt_len = backtrace(bt, BT_MAX);
+ backtrace_symbols_fd(bt, bt_len, STDERR_FILENO);
+ DEBUG_PRINT("\\n\\n");
+ DO_ASSERT(!pthread_mutex_unlock(&allocation_mtx));
+ return; // addrsan should catch and print more info than we have
+ }
+ }
+ DO_ASSERT(!pthread_mutex_unlock(&allocation_mtx));
+}
+
void* __real_realloc(void* ptr, size_t newlen);
void* __wrap_realloc(void* ptr, size_t len) {
if (ptr != NULL) alloc_freed(ptr);
#define FREE(p) if ((unsigned long)(p) > 1024) { free(p); }
#define DO_ASSERT(a) (void)(a)
#define CHECK(a)
+#define CHECK_ACCESS(p)
"""
else:
self.c_file_pfx = self.c_file_pfx + """
__real_free(ptr);
}
+static void CHECK_ACCESS(void* ptr) {
+ allocation* it = allocation_ll;
+ while (it->ptr != ptr) {
+ it = it->next;
+ if (it == NULL) {
+ return; // addrsan should catch malloc-unknown and print more info than we have
+ }
+ }
+}
+
void* __wrap_malloc(size_t len) {
void* res = __real_malloc(len);
new_allocation(res, "malloc call");