authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-12-18 08:19:06-08:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2025-02-25 11:22:33-08:00
logc27b7973c9a54cd4ae0f8c9aa489fca50e13542b
treeb1c0b3e2afc9919cb479086ecbd0db2253c78789
parenteef8d4ff4fff849c7b214bed05e49e7906cc7809

Compilation: use the minimal runtime in `ReleaseSafe`


2 files changed, 60 insertions(+), 24 deletions(-)

lib/std/ubsan.zig+56-24
......@@ -321,17 +321,12 @@ const TypeMismatchData = extern struct {
321321 },
322322};
323323
324fn simpleHandler(
325 comptime sym_name: []const u8,
326 comptime error_name: []const u8,
327 comptime abort: bool,
328) void {
329 const S = struct {
324fn SimpleHandler(comptime error_name: []const u8) type {
325 return struct {
330326 fn handler() callconv(.C) noreturn {
331327 logMessage("{s}", .{error_name});
332328 }
333329 };
334 exportHandler(&S.handler, sym_name, abort);
335330}
336331
337332inline fn logMessage(comptime fmt: []const u8, args: anytype) noreturn {
......@@ -354,6 +349,31 @@ fn exportHandler(
354349 }
355350}
356351
352fn exportMinimal(
353 handler: anytype,
354 comptime sym_name: []const u8,
355 comptime abort: bool,
356) void {
357 const linkage = if (builtin.is_test) .internal else .weak;
358 {
359 const N = "__ubsan_handle_" ++ sym_name ++ "_minimal";
360 @export(handler, .{ .name = N, .linkage = linkage });
361 }
362 if (abort) {
363 const N = "__ubsan_handle_" ++ sym_name ++ "_minimal_abort";
364 @export(handler, .{ .name = N, .linkage = linkage });
365 }
366}
367
368fn exportHelper(
369 comptime err_name: []const u8,
370 comptime sym_name: []const u8,
371 comptime abort: bool,
372) void {
373 exportHandler(&SimpleHandler(err_name).handler, sym_name, abort);
374 exportMinimal(&SimpleHandler(err_name).handler, sym_name, abort);
375}
376
357377comptime {
358378 overflowHandler("add_overflow", "+");
359379 overflowHandler("sub_overflow", "-");
......@@ -365,24 +385,36 @@ comptime {
365385 exportHandler(&outOfBounds, "out_of_bounds", true);
366386 exportHandler(&pointerOverflow, "pointer_overflow", true);
367387
368 simpleHandler("type_mismatch_v1", "type-mismatch-v1", true);
369 simpleHandler("builtin_unreachable", "builtin-unreachable", false);
370 simpleHandler("missing_return", "missing-return", false);
371 simpleHandler("vla_bound_not_positive", "vla-bound-not-positive", true);
372 simpleHandler("float_cast_overflow", "float-cast-overflow", true);
373 simpleHandler("load_invalid_value", "load-invalid-value", true);
374 simpleHandler("invalid_builtin", "invalid-builtin", true);
375 simpleHandler("function_type_mismatch", "function-type-mismatch", true);
376 simpleHandler("implicit_conversion", "implicit-conversion", true);
377 simpleHandler("nonnull_arg", "nonnull-arg", true);
378 simpleHandler("nonnull_return", "nonnull-return", true);
379 simpleHandler("nullability_arg", "nullability-arg", true);
380 simpleHandler("nullability_return", "nullability-return", true);
381 simpleHandler("cfi_check_fail", "cfi-check-fail", true);
382 simpleHandler("function_type_mismatch_v1", "function-type-mismatch-v1", true);
388 exportMinimal("add-overflow", "add_overflow", true);
389 exportMinimal("sub-overflow", "sub_overflow", true);
390 exportMinimal("mul-overflow", "mul_overflow", true);
391 exportMinimal("negation-handler", "negate_overflow", true);
392 exportMinimal("divrem-handler", "divrem_overflow", true);
393 exportMinimal("alignment-assumption-handler", "alignment_assumption", true);
394 exportMinimal("shift-oob", "shift_out_of_bounds", true);
395 exportMinimal("out-of-bounds", "out_of_bounds", true);
396 exportMinimal("pointer-overflow", "pointer_overflow", true);
397
398 exportHandler(&SimpleHandler("type-mismatch-v1").handler, "type_mismatch_v1", true);
399 exportMinimal(&SimpleHandler("type-mismatch").handler, "type_mismatch", true);
400
401 exportHelper("builtin-unreachable", "builtin_unreachable", true);
402 exportHelper("missing-return", "missing_return", false);
403 exportHelper("vla-bound-not-positive", "vla_bound_not_positive", true);
404 exportHelper("float-cast-overflow", "float_cast_overflow", true);
405 exportHelper("load-invalid-value", "load_invalid_value", true);
406 exportHelper("invalid-builtin", "invalid_builtin", true);
407 exportHelper("function-type-mismatch", "function_type_mismatch", true);
408 exportHelper("implicit-conversion", "implicit_conversion", true);
409 exportHelper("nonnull-arg", "nonnull_arg", true);
410 exportHelper("nonnull-return", "nonnull_return", true);
411 exportHelper("nullability-arg", "nullability_arg", true);
412 exportHelper("nullability-return", "nullability_return", true);
413 exportHelper("cfi-check-fail", "cfi_check_fail", true);
414 exportHelper("function-type-mismatch-v1", "function_type_mismatch_v1", true);
383415
384416 // these checks are nearly impossible to duplicate in zig, as they rely on nuances
385417 // in the Itanium C++ ABI.
386 simpleHandler("dynamic_type_cache_miss", "dynamic-type-cache-miss", true);
387 simpleHandler("vptr_type_cache", "vptr-type-cache", true);
418 // exportHelper("dynamic_type_cache_miss", "dynamic-type-cache-miss", true);
419 // exportHelper("vptr_type_cache", "vptr-type-cache", true);
388420}
src/Compilation.zig+4
......@@ -5925,6 +5925,10 @@ pub fn addCCArgs(
59255925 // Without this flag, Clang would invoke UBSAN when such an extern
59265926 // function was called.
59275927 try argv.append("-fno-sanitize=function");
5928
5929 if (mod.optimize_mode == .ReleaseSafe) {
5930 try argv.append("-fsanitize-minimal-runtime");
5931 }
59285932 }
59295933 }
59305934