aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLucas Perlind <perlindluca@gmail.com>2025-05-01 20:42:21 +1000
committerLucas Perlind <perlindluca@gmail.com>2025-05-01 20:42:21 +1000
commit5c73b4ef5829f0d722fdbb8ba8d84709563505a0 (patch)
treede05451132196b8adb43d44a57414f9e8ffa267d /src
parentb04a83ce9fa0a3ed36ce5c774280e47f28246e0a (diff)
Add attribute @(no_sanitize_address)
The purposes of this attribute is to let procedures opt-out of being instrumented with asan. Typically an allocator that includes 'in-band' meta-data will be accessing poisoned values (such as tlsf). Making asan work with these allocators becomes very challenging so just being to ignore asan within specific allocator procedures makes it easier to reason and removes the need to temporarily poison and unpoison allocator data.
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp1
-rw-r--r--src/checker.cpp6
-rw-r--r--src/checker.hpp3
-rw-r--r--src/entity.cpp1
-rw-r--r--src/llvm_backend_proc.cpp2
5 files changed, 11 insertions, 2 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index ba6445ea4..2392775b1 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -1229,6 +1229,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
e->Procedure.has_instrumentation = has_instrumentation;
+ e->Procedure.no_sanitize_address = ac.no_sanitize_address;
e->deprecated_message = ac.deprecated_message;
e->warning_message = ac.warning_message;
diff --git a/src/checker.cpp b/src/checker.cpp
index 038c5aa1a..5e1517875 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -3711,6 +3711,12 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
}
ac->instrumentation_exit = true;
return true;
+ } else if (name == "no_sanitize_address") {
+ if (value != nullptr) {
+ error(value, "'%.*s' expects no parameter", LIT(name));
+ }
+ ac->no_sanitize_address = true;
+ return true;
}
return false;
}
diff --git a/src/checker.hpp b/src/checker.hpp
index d3b2d7d89..dd82d9bdd 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -139,6 +139,7 @@ struct AttributeContext {
bool entry_point_only : 1;
bool instrumentation_enter : 1;
bool instrumentation_exit : 1;
+ bool no_sanitize_address : 1;
bool rodata : 1;
bool ignore_duplicates : 1;
u32 optimization_mode; // ProcedureOptimizationMode
@@ -629,4 +630,4 @@ gb_internal void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap
gb_internal GenTypesData *ensure_polymorphic_record_entity_has_gen_types(CheckerContext *ctx, Type *original_type);
-gb_internal void init_map_internal_types(Type *type); \ No newline at end of file
+gb_internal void init_map_internal_types(Type *type);
diff --git a/src/entity.cpp b/src/entity.cpp
index b2148aa7b..9946a3a5f 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -258,6 +258,7 @@ struct Entity {
bool is_memcpy_like : 1;
bool uses_branch_location : 1;
bool is_anonymous : 1;
+ bool no_sanitize_address : 1;
} Procedure;
struct {
Array<Entity *> entities;
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 3212abd9a..c442f3d58 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -333,7 +333,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i
}
if (p->body && entity->pkg && ((entity->pkg->kind == Package_Normal) || (entity->pkg->kind == Package_Init))) {
- if (build_context.sanitizer_flags & SanitizerFlag_Address) {
+ if (build_context.sanitizer_flags & SanitizerFlag_Address && !entity->Procedure.no_sanitize_address) {
lb_add_attribute_to_proc(m, p->value, "sanitize_address");
}
if (build_context.sanitizer_flags & SanitizerFlag_Memory) {