[llvm] [hwasan] Add hwasan-static-linking option (PR #154529)

Vadim Marchenko via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 20 06:08:05 PDT 2025


https://github.com/jakosv created https://github.com/llvm/llvm-project/pull/154529

Discarding the `.note.hwasan.globals` section in ldscript causes a linker error, since `hwasan_globals` refers to the discarded section. The issue comes from `hwasan.dummy.global` being associated via metadata with `.note.hwasan.globals`.

Add a new `-hwasan-static-linking` option to skip inserting `.note.hwasan.globals` for static binaries, as it is only needed for instrumenting globals from dynamic libraries. In static binaries, the global variables section can be accessed directly via the `__start_hwasan_globals` and `__stop_hwasan_globals` symbols inserted by the linker.

>From a0a9e519d2ae29a70e6b8a68842ecf1e27bc0975 Mon Sep 17 00:00:00 2001
From: Vadim Marchenko <jakosvadim at gmail.com>
Date: Wed, 20 Aug 2025 14:38:53 +0300
Subject: [PATCH] [hwasan] Add hwasan-static-linking option

Discarding the `.note.hwasan.globals` section in ldscript causes a
linker error, since `hwasan_globals` refers to the discarded section.
The issue comes from `hwasan.dummy.global` being associated via metadata
with `.note.hwasan.globals`.

Add a new `-hwasan-static-linking` option to skip inserting
`.note.hwasan.globals` for static binaries, as it is only needed for
instrumenting globals from dynamic libraries. In static binaries, the
global variables section can be accessed directly via the
`__start_hwasan_globals` and `__stop_hwasan_globals` symbols inserted by
the linker.
---
 .../Instrumentation/HWAddressSanitizer.cpp    |  9 +++++
 .../globals-static-linking.ll                 | 34 +++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 llvm/test/Instrumentation/HWAddressSanitizer/globals-static-linking.ll

diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index fc34d14259d1f..c5d3af1a1b42e 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -212,6 +212,12 @@ static cl::opt<float>
                               "OR because of the hot percentile cutoff, if "
                               "both are supplied."));
 
+static cl::opt<bool> ClStaticLinking(
+    "hwasan-static-linking",
+    cl::desc("don't use .note.hwasan.globals section to instrument globals "
+             "from loadable libraries"),
+    cl::Hidden, cl::init(false));
+
 STATISTIC(NumTotalFuncs, "Number of total funcs");
 STATISTIC(NumInstrumentedFuncs, "Number of instrumented funcs");
 STATISTIC(NumNoProfileSummaryFuncs, "Number of funcs without PS");
@@ -547,6 +553,9 @@ void HWAddressSanitizer::createHwasanCtorComdat() {
             appendToGlobalCtors(M, Ctor, 0, Ctor);
           });
 
+  if (ClStaticLinking)
+    return;
+
   // Create a note that contains pointers to the list of global
   // descriptors. Adding a note to the output file will cause the linker to
   // create a PT_NOTE program header pointing to the note that we can use to
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/globals-static-linking.ll b/llvm/test/Instrumentation/HWAddressSanitizer/globals-static-linking.ll
new file mode 100644
index 0000000000000..a3bb49d61f274
--- /dev/null
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/globals-static-linking.ll
@@ -0,0 +1,34 @@
+; RUN: opt < %s -S -passes=hwasan -mtriple=aarch64--linux-android29 -hwasan-static-linking=1 | FileCheck --check-prefixes=CHECK,CHECK29 %s
+; RUN: opt < %s -S -passes=hwasan -mtriple=aarch64--linux-android30 -hwasan-static-linking=1 | FileCheck --check-prefixes=CHECK,CHECK30 %s
+; RUN: opt < %s -S -passes=hwasan -mtriple=riscv64-unknown-elf -hwasan-globals=1 -hwasan-static-linking=1 | FileCheck --check-prefixes=CHECK,CHECK30 %s
+
+; CHECK29: @four = global
+
+; CHECK: @specialcaselisted = global i16 2, no_sanitize_hwaddress
+
+; CHECK30: @four.hwasan = private global { i32, [12 x i8] } { i32 1, [12 x i8] c"\00\00\00\00\00\00\00\00\00\00\00\AC" }, align 16
+; CHECK30: @four.hwasan.descriptor = private constant { i32, i32 } { i32 trunc (i64 sub (i64 ptrtoint (ptr @four.hwasan to i64), i64 ptrtoint (ptr @four.hwasan.descriptor to i64)) to i32), i32 -1409286140 }, section "hwasan_globals", !associated [[FOUR:![0-9]+]]
+
+; CHECK30: @sixteen.hwasan = private global [16 x i8] zeroinitializer, align 16
+; CHECK30: @sixteen.hwasan.descriptor = private constant { i32, i32 } { i32 trunc (i64 sub (i64 ptrtoint (ptr @sixteen.hwasan to i64), i64 ptrtoint (ptr @sixteen.hwasan.descriptor to i64)) to i32), i32 -1392508912 }, section "hwasan_globals", !associated [[SIXTEEN:![0-9]+]]
+
+; CHECK30: @huge.hwasan = private global [16777232 x i8] zeroinitializer, align 16
+; CHECK30: @huge.hwasan.descriptor = private constant { i32, i32 } { i32 trunc (i64 sub (i64 ptrtoint (ptr @huge.hwasan to i64), i64 ptrtoint (ptr @huge.hwasan.descriptor to i64)) to i32), i32 -1358954512 }, section "hwasan_globals", !associated [[HUGE:![0-9]+]]
+; CHECK30: @huge.hwasan.descriptor.1 = private constant { i32, i32 } { i32 trunc (i64 add (i64 sub (i64 ptrtoint (ptr @huge.hwasan to i64), i64 ptrtoint (ptr @huge.hwasan.descriptor.1 to i64)), i64 16777200) to i32), i32 -1375731680 }, section "hwasan_globals", !associated [[HUGE]]
+
+; CHECK-NOT: @hwasan.note = private constant { i32, i32, i32, [8 x i8], i32, i32 } { i32 8, i32 8, i32 3, [8 x i8] c"LLVM\00\00\00\00", i32 trunc (i64 sub (i64 ptrtoint (ptr @__start_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @__stop_hwasan_globals to i64), i64 ptrtoint (ptr @hwasan.note to i64)) to i32) }, section ".note.hwasan.globals", comdat($hwasan.module_ctor), align 4
+
+; CHECK30: @four = alias i32, inttoptr (i64 add (i64 ptrtoint (ptr @four.hwasan to i64), i64 -6052837899185946624) to ptr)
+; CHECK30: @sixteen = alias [16 x i8], inttoptr (i64 add (i64 ptrtoint (ptr @sixteen.hwasan to i64), i64 -5980780305148018688) to ptr)
+; CHECK30: @huge = alias [16777232 x i8], inttoptr (i64 add (i64 ptrtoint (ptr @huge.hwasan to i64), i64 -5908722711110090752) to ptr)
+
+; CHECK30: [[FOUR]] = !{ptr @four.hwasan}
+; CHECK30: [[SIXTEEN]] = !{ptr @sixteen.hwasan}
+; CHECK30: [[HUGE]] = !{ptr @huge.hwasan}
+
+source_filename = "foo"
+
+ at four = global i32 1
+ at sixteen = global [16 x i8] zeroinitializer
+ at huge = global [16777232 x i8] zeroinitializer
+ at specialcaselisted = global i16 2, no_sanitize_hwaddress



More information about the llvm-commits mailing list