From bf972efda0c1647f31546ca4a3a4e3a38f902362 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 27 Apr 2024 22:10:47 +0200 Subject: [PATCH] Use clang pragmas to enable features rather than depend on compiler settings --- build.zig | 531 +++++++++++------- .../aes256gcm/aesni/aead_aes256gcm_aesni.c | 12 +- .../blake2b/ref/blake2b-compress-avx2.c | 13 +- .../blake2b/ref/blake2b-compress-sse41.c | 12 +- .../blake2b/ref/blake2b-compress-ssse3.c | 11 +- .../poly1305/sse2/poly1305_sse2.c | 8 +- .../argon2/argon2-fill-block-avx2.c | 14 +- .../argon2/argon2-fill-block-avx512f.c | 15 +- .../argon2/argon2-fill-block-ssse3.c | 12 +- .../sse/pwhash_scryptsalsa208sha256_sse.c | 14 +- .../chacha20/dolbeau/chacha20_dolbeau-avx2.c | 13 +- .../chacha20/dolbeau/chacha20_dolbeau-ssse3.c | 11 +- .../salsa20/xmm6int/salsa20_xmm6int-avx2.c | 23 +- .../salsa20/xmm6int/salsa20_xmm6int-sse2.c | 8 +- src/libsodium/crypto_verify/verify.c | 3 - .../internal/randombytes_internal_random.c | 12 +- 16 files changed, 452 insertions(+), 260 deletions(-) diff --git a/build.zig b/build.zig index ad2c50f2..0033c88b 100644 --- a/build.zig +++ b/build.zig @@ -3,16 +3,145 @@ const fmt = std.fmt; const fs = std.fs; const heap = std.heap; const mem = std.mem; -const LibExeObjStep = std.build.LibExeObjStep; +const Compile = std.Build.Step.Compile; const Target = std.Target; -pub fn build(b: *std.build.Builder) !void { +fn initLibConfig(target: std.Build.ResolvedTarget, lib: *Compile) void { + lib.linkLibC(); + lib.addIncludePath(.{ .path = "src/libsodium/include/sodium" }); + lib.defineCMacro("_GNU_SOURCE", "1"); + lib.defineCMacro("CONFIGURED", "1"); + lib.defineCMacro("DEV_MODE", "1"); + lib.defineCMacro("HAVE_ATOMIC_OPS", "1"); + lib.defineCMacro("HAVE_C11_MEMORY_FENCES", "1"); + lib.defineCMacro("HAVE_CET_H", "1"); + lib.defineCMacro("HAVE_GCC_MEMORY_FENCES", "1"); + lib.defineCMacro("HAVE_INLINE_ASM", "1"); + lib.defineCMacro("HAVE_INTTYPES_H", "1"); + lib.defineCMacro("HAVE_STDINT_H", "1"); + lib.defineCMacro("HAVE_TI_MODE", "1"); + lib.want_lto = false; + + const endian = target.result.cpu.arch.endian(); + switch (endian) { + .big => lib.defineCMacro("NATIVE_BIG_ENDIAN", "1"), + .little => lib.defineCMacro("NATIVE_LITTLE_ENDIAN", "1"), + } + + switch (target.result.os.tag) { + .linux => { + lib.defineCMacro("ASM_HIDE_SYMBOL", ".hidden"); + lib.defineCMacro("TLS", "_Thread_local"); + + lib.defineCMacro("HAVE_CATCHABLE_ABRT", "1"); + lib.defineCMacro("HAVE_CATCHABLE_SEGV", "1"); + lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); + lib.defineCMacro("HAVE_GETPID", "1"); + lib.defineCMacro("HAVE_INLINE_ASM", "1"); + lib.defineCMacro("HAVE_MADVISE", "1"); + lib.defineCMacro("HAVE_MLOCK", "1"); + lib.defineCMacro("HAVE_MMAP", "1"); + lib.defineCMacro("HAVE_MPROTECT", "1"); + lib.defineCMacro("HAVE_NANOSLEEP", "1"); + lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); + lib.defineCMacro("HAVE_PTHREAD_PRIO_INHERIT", "1"); + lib.defineCMacro("HAVE_PTHREAD", "1"); + lib.defineCMacro("HAVE_RAISE", "1"); + lib.defineCMacro("HAVE_SYSCONF", "1"); + lib.defineCMacro("HAVE_SYS_AUXV_H", "1"); + lib.defineCMacro("HAVE_SYS_MMAN_H", "1"); + lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); + lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); + lib.defineCMacro("HAVE_WEAK_SYMBOLS", "1"); + }, + .windows => { + lib.defineCMacro("HAVE_RAISE", "1"); + lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); + if (lib.isStaticLibrary()) { + lib.defineCMacro("SODIUM_STATIC", "1"); + } + }, + .macos => { + lib.defineCMacro("ASM_HIDE_SYMBOL", ".private_extern"); + lib.defineCMacro("TLS", "_Thread_local"); + + lib.defineCMacro("HAVE_ARC4RANDOM", "1"); + lib.defineCMacro("HAVE_ARC4RANDOM_BUF", "1"); + lib.defineCMacro("HAVE_CATCHABLE_ABRT", "1"); + lib.defineCMacro("HAVE_CATCHABLE_SEGV", "1"); + lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); + lib.defineCMacro("HAVE_GETENTROPY", "1"); + lib.defineCMacro("HAVE_GETPID", "1"); + lib.defineCMacro("HAVE_MADVISE", "1"); + lib.defineCMacro("HAVE_MEMSET_S", "1"); + lib.defineCMacro("HAVE_MLOCK", "1"); + lib.defineCMacro("HAVE_MMAP", "1"); + lib.defineCMacro("HAVE_MPROTECT", "1"); + lib.defineCMacro("HAVE_NANOSLEEP", "1"); + lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); + lib.defineCMacro("HAVE_PTHREAD", "1"); + lib.defineCMacro("HAVE_PTHREAD_PRIO_INHERIT", "1"); + lib.defineCMacro("HAVE_RAISE", "1"); + lib.defineCMacro("HAVE_SYSCONF", "1"); + lib.defineCMacro("HAVE_SYS_MMAN_H", "1"); + lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); + lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); + lib.defineCMacro("HAVE_WEAK_SYMBOLS", "1"); + }, + .wasi => { + lib.defineCMacro("HAVE_ARC4RANDOM", "1"); + lib.defineCMacro("HAVE_ARC4RANDOM_BUF", "1"); + lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); + lib.defineCMacro("HAVE_GETENTROPY", "1"); + lib.defineCMacro("HAVE_NANOSLEEP", "1"); + lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); + lib.defineCMacro("HAVE_SYS_AUXV_H", "1"); + lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); + lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); + }, + else => {}, + } + + switch (target.result.cpu.arch) { + .x86_64 => { + lib.defineCMacro("HAVE_AMD64_ASM", "1"); + lib.defineCMacro("HAVE_AVX_ASM", "1"); + lib.defineCMacro("HAVE_CPUID", "1"); + lib.defineCMacro("HAVE_MMINTRIN_H", "1"); + lib.defineCMacro("HAVE_EMMINTRIN_H", "1"); + lib.defineCMacro("HAVE_PMMINTRIN_H", "1"); + lib.defineCMacro("HAVE_TMMINTRIN_H", "1"); + lib.defineCMacro("HAVE_SMMINTRIN_H", "1"); + lib.defineCMacro("HAVE_AVXINTRIN_H", "1"); + lib.defineCMacro("HAVE_AVX2INTRIN_H", "1"); + lib.defineCMacro("HAVE_AVX512FINTRIN_H", "1"); + lib.defineCMacro("HAVE_WMMINTRIN_H", "1"); + lib.defineCMacro("HAVE_RDRAND", "1"); + }, + .aarch64, .aarch64_be => { + lib.defineCMacro("HAVE_ARMCRYPTO", "1"); + }, + .wasm32, .wasm64 => { + lib.defineCMacro("__wasm__", "1"); + }, + else => {}, + } + + switch (target.result.os.tag) { + .wasi => { + lib.defineCMacro("__wasi__", "1"); + }, + else => {}, + } +} + +pub fn build(b: *std.Build) !void { const root_path = b.pathFromRoot("."); var cwd = try fs.openDirAbsolute(root_path, .{}); defer cwd.close(); const src_path = "src/libsodium"; - const src_dir = try fs.Dir.openIterableDir(cwd, src_path, .{ .no_follow = true }); + const src_dir = try fs.Dir.openDir(cwd, src_path, .{ .iterate = true, .no_follow = true }); var target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); @@ -28,19 +157,11 @@ pub fn build(b: *std.build.Builder) !void { build_static = true; } - switch (target.getCpuArch()) { - // Features we assume are always available because they won't affect - // code generation in files that don't use them. - .x86_64 => { - target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.aes)); - target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.pclmul)); - target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.rdrnd)); - }, - .aarch64, .aarch64_be => { - target.cpu_features_add.addFeature(@intFromEnum(Target.aarch64.Feature.crypto)); - // ARM CPUs supported by Windows also support NEON. - if (target.isWindows()) { - target.cpu_features_add.addFeature(@intFromEnum(Target.aarch64.Feature.neon)); + switch (target.result.cpu.arch) { + .aarch64, .aarch64_be, .aarch64_32 => { + // ARM CPUs supported by Windows are assumed to have NEON support + if (target.result.isMinGW()) { + target.query.cpu_features_add.addFeature(@intFromEnum(Target.aarch64.Feature.neon)); } }, else => {}, @@ -52,13 +173,14 @@ pub fn build(b: *std.build.Builder) !void { .optimize = optimize, }); const shared_lib = b.addSharedLibrary(.{ - .name = if (target.isWindows()) "sodium_shared" else "sodium", + .name = if (target.result.isMinGW()) "sodium_shared" else "sodium", .target = target, .optimize = optimize, + .strip = optimize != .Debug and !target.result.isMinGW(), }); // work out which libraries we are building - var libs = std.ArrayList(*LibExeObjStep).init(b.allocator); + var libs = std.ArrayList(*Compile).init(b.allocator); defer libs.deinit(); if (build_static) { try libs.append(static_lib); @@ -70,203 +192,210 @@ pub fn build(b: *std.build.Builder) !void { const prebuilt_version_file_path = "builds/msvc/version.h"; const version_file_path = "include/sodium/version.h"; - if (src_dir.dir.access(version_file_path, .{ .mode = .read_only })) {} else |_| { - try cwd.copyFile(prebuilt_version_file_path, src_dir.dir, version_file_path, .{}); + if (src_dir.access(version_file_path, .{ .mode = .read_only })) {} else |_| { + try cwd.copyFile(prebuilt_version_file_path, src_dir, version_file_path, .{}); } for (libs.items) |lib| { if (lib.isDynamicLibrary() and - !(target.isDarwin() or target.isDragonFlyBSD() or target.isFreeBSD() or - target.isLinux() or target.isNetBSD() or target.isOpenBSD() or target.isWindows())) + !(target.result.isDarwin() or target.result.isBSD() or target.result.isGnu() or target.result.isAndroid() or target.result.isMinGW())) { continue; } - if (optimize != .Debug and !target.isWindows() and !lib.isStaticLibrary()) { - lib.strip = true; - } b.installArtifact(lib); - lib.installHeader(src_path ++ "/include/sodium.h", "sodium.h"); - lib.installHeadersDirectory(src_path ++ "/include/sodium", "sodium"); - lib.linkLibC(); + lib.installHeader(.{ .path = src_path ++ "/include/sodium.h" }, "sodium.h"); + lib.installHeadersDirectory(.{ .path = src_path ++ "/include/sodium" }, "sodium", .{}); - lib.addIncludePath(.{ .path = "src/libsodium/include/sodium" }); - lib.defineCMacro("_GNU_SOURCE", "1"); - lib.defineCMacro("CONFIGURED", "1"); - lib.defineCMacro("DEV_MODE", "1"); - lib.defineCMacro("HAVE_ATOMIC_OPS", "1"); - lib.defineCMacro("HAVE_C11_MEMORY_FENCES", "1"); - lib.defineCMacro("HAVE_CET_H", "1"); - lib.defineCMacro("HAVE_GCC_MEMORY_FENCES", "1"); - lib.defineCMacro("HAVE_INLINE_ASM", "1"); - lib.defineCMacro("HAVE_INTTYPES_H", "1"); - lib.defineCMacro("HAVE_STDINT_H", "1"); - lib.defineCMacro("HAVE_TI_MODE", "1"); + initLibConfig(target, lib); - if (target.cpu_arch) |arch| { - const endian = arch.endian(); - if (@hasField(@TypeOf(endian), "big")) { - switch (endian) { - .big => lib.defineCMacro("NATIVE_BIG_ENDIAN", "1"), - .little => lib.defineCMacro("NATIVE_LITTLE_ENDIAN", "1"), - } - } else { - switch (endian) { - .Big => lib.defineCMacro("NATIVE_BIG_ENDIAN", "1"), - .Little => lib.defineCMacro("NATIVE_LITTLE_ENDIAN", "1"), - } + const MFlags = enum { + sse2, + ssse3, + sse41, + avx, + avx2, + avx512f, + aes, + pclmul, + rdrnd, + crypto, + + fn f(flag: @This()) Target.Cpu.Feature.Set.Index { + return switch (flag) { + .sse2 => @intFromEnum(Target.x86.Feature.sse2), + .ssse3 => @intFromEnum(Target.x86.Feature.ssse3), + .sse41 => @intFromEnum(Target.x86.Feature.sse4_1), + .avx => @intFromEnum(Target.x86.Feature.avx), + .avx2 => @intFromEnum(Target.x86.Feature.avx2), + .avx512f => @intFromEnum(Target.x86.Feature.avx512f), + .aes => @intFromEnum(Target.x86.Feature.aes), + .pclmul => @intFromEnum(Target.x86.Feature.pclmul), + .rdrnd => @intFromEnum(Target.x86.Feature.rdrnd), + .crypto => @intFromEnum(Target.aarch64.Feature.crypto), + }; } - } + }; - switch (target.getOsTag()) { - .linux => { - lib.defineCMacro("ASM_HIDE_SYMBOL", ".hidden"); - lib.defineCMacro("TLS", "_Thread_local"); + const MLib = struct { + name: []const u8, + count: usize, + sources: []const []const u8, + flags: []const MFlags, + arches: []const std.Target.Cpu.Arch, + lib: *Compile = undefined, + }; - lib.defineCMacro("HAVE_CATCHABLE_ABRT", "1"); - lib.defineCMacro("HAVE_CATCHABLE_SEGV", "1"); - lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); - lib.defineCMacro("HAVE_GETPID", "1"); - lib.defineCMacro("HAVE_INLINE_ASM", "1"); - lib.defineCMacro("HAVE_MADVISE", "1"); - lib.defineCMacro("HAVE_MLOCK", "1"); - lib.defineCMacro("HAVE_MMAP", "1"); - lib.defineCMacro("HAVE_MPROTECT", "1"); - lib.defineCMacro("HAVE_NANOSLEEP", "1"); - lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); - lib.defineCMacro("HAVE_PTHREAD_PRIO_INHERIT", "1"); - lib.defineCMacro("HAVE_PTHREAD", "1"); - lib.defineCMacro("HAVE_RAISE", "1"); - lib.defineCMacro("HAVE_SYSCONF", "1"); - lib.defineCMacro("HAVE_SYS_AUXV_H", "1"); - lib.defineCMacro("HAVE_SYS_MMAN_H", "1"); - lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); - lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); - lib.defineCMacro("HAVE_WEAK_SYMBOLS", "1"); + var mlibs: [8]MLib = .{ + .{ + .name = "armcrypto", + .count = 3, + .sources = &.{ + "crypto_aead/aegis128l/aegis128l_armcrypto.c", + "crypto_aead/aegis256/aegis256_armcrypto.c", + "crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c", + }, + .flags = &.{.aes}, + .arches = &.{ .aarch64, .aarch64_be, .aarch64_32 }, }, - .windows => { - lib.defineCMacro("HAVE_RAISE", "1"); - lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); - if (lib.isStaticLibrary()) { - lib.defineCMacro("SODIUM_STATIC", "1"); - } - }, - .macos => { - lib.defineCMacro("ASM_HIDE_SYMBOL", ".private_extern"); - lib.defineCMacro("TLS", "_Thread_local"); - lib.defineCMacro("HAVE_ARC4RANDOM", "1"); - lib.defineCMacro("HAVE_ARC4RANDOM_BUF", "1"); - lib.defineCMacro("HAVE_CATCHABLE_ABRT", "1"); - lib.defineCMacro("HAVE_CATCHABLE_SEGV", "1"); - lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); - lib.defineCMacro("HAVE_GETENTROPY", "1"); - lib.defineCMacro("HAVE_GETPID", "1"); - lib.defineCMacro("HAVE_MADVISE", "1"); - lib.defineCMacro("HAVE_MEMSET_S", "1"); - lib.defineCMacro("HAVE_MLOCK", "1"); - lib.defineCMacro("HAVE_MMAP", "1"); - lib.defineCMacro("HAVE_MPROTECT", "1"); - lib.defineCMacro("HAVE_NANOSLEEP", "1"); - lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); - lib.defineCMacro("HAVE_PTHREAD", "1"); - lib.defineCMacro("HAVE_PTHREAD_PRIO_INHERIT", "1"); - lib.defineCMacro("HAVE_RAISE", "1"); - lib.defineCMacro("HAVE_SYSCONF", "1"); - lib.defineCMacro("HAVE_SYS_MMAN_H", "1"); - lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); - lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); - lib.defineCMacro("HAVE_WEAK_SYMBOLS", "1"); + .{ + .name = "sse2", + .count = 1, + .sources = &.{ + "crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c", + }, + .flags = &.{.sse2}, + .arches = &.{ .x86_64, .x86 }, }, - .wasi => { - lib.defineCMacro("HAVE_ARC4RANDOM", "1"); - lib.defineCMacro("HAVE_ARC4RANDOM_BUF", "1"); - lib.defineCMacro("HAVE_CLOCK_GETTIME", "1"); - lib.defineCMacro("HAVE_GETENTROPY", "1"); - lib.defineCMacro("HAVE_NANOSLEEP", "1"); - lib.defineCMacro("HAVE_POSIX_MEMALIGN", "1"); - lib.defineCMacro("HAVE_SYS_AUXV_H", "1"); - lib.defineCMacro("HAVE_SYS_PARAM_H", "1"); - lib.defineCMacro("HAVE_SYS_RANDOM_H", "1"); + .{ + .name = "ssse3", + .count = 3, + .sources = &.{ + "crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c", + "crypto_pwhash/argon2/argon2-fill-block-ssse3.c", + "crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c", + }, + .flags = &.{ .sse2, .ssse3 }, + .arches = &.{ .x86_64, .x86 }, }, - else => {}, - } + .{ + .name = "sse41", + .count = 1, + .sources = &.{ + "crypto_generichash/blake2b/ref/blake2b-compress-sse41.c", + }, + .flags = &.{ .sse2, .ssse3, .sse41 }, + .arches = &.{ .x86_64, .x86 }, + }, + .{ + .name = "avx2", + .count = 4, + .sources = &.{ + "crypto_generichash/blake2b/ref/blake2b-compress-avx2.c", + "crypto_pwhash/argon2/argon2-fill-block-avx2.c", + "crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c", + "crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c", + }, + .flags = &.{ .sse2, .ssse3, .sse41, .avx, .avx2 }, + .arches = &.{.x86_64}, + }, + .{ + .name = "avx512f", + .count = 1, + .sources = &.{ + "crypto_pwhash/argon2/argon2-fill-block-avx512f.c", + }, + .flags = &.{ .sse2, .ssse3, .sse41, .avx, .avx2, .avx512f }, + .arches = &.{.x86_64}, + }, + .{ + .name = "aesni", + .count = 3, + .sources = &.{ + "crypto_aead/aegis128l/aegis128l_aesni.c", + "crypto_aead/aegis256/aegis256_aesni.c", + "crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c", + }, + .flags = &.{ .avx, .aes, .pclmul }, + .arches = &.{.x86_64}, + }, + .{ + .name = "mrdrnd", + .count = 1, + .sources = &.{ + "randombytes/internal/randombytes_internal_random.c", + }, + .flags = &.{.rdrnd}, + .arches = &.{ .x86_64, .x86 }, + }, + }; - switch (target.getCpuArch()) { - .x86_64 => { - lib.defineCMacro("HAVE_AMD64_ASM", "1"); - lib.defineCMacro("HAVE_AVX_ASM", "1"); - lib.defineCMacro("HAVE_CPUID", "1"); - lib.defineCMacro("HAVE_MMINTRIN_H", "1"); - lib.defineCMacro("HAVE_EMMINTRIN_H", "1"); - - const cpu_features = target.getCpuFeatures(); - const has_sse3 = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.sse3)); - const has_ssse3 = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.ssse3)); - const has_sse4_1 = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.sse4_1)); - const has_avx = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.avx)); - const has_avx2 = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.avx2)); - const has_avx512f = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.avx512f)); - const has_aes = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.aes)); - const has_pclmul = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.pclmul)); - const has_rdrnd = cpu_features.isEnabled(@intFromEnum(Target.x86.Feature.rdrnd)); - - if (has_sse3) lib.defineCMacro("HAVE_PMMINTRIN_H", "1"); - if (has_ssse3) lib.defineCMacro("HAVE_TMMINTRIN_H", "1"); - if (has_sse4_1) lib.defineCMacro("HAVE_SMMINTRIN_H", "1"); - if (has_avx) lib.defineCMacro("HAVE_AVXINTRIN_H", "1"); - if (has_avx2) lib.defineCMacro("HAVE_AVX2INTRIN_H", "1"); - if (has_avx512f) lib.defineCMacro("HAVE_AVX512FINTRIN_H", "1"); - if (has_aes and has_pclmul) lib.defineCMacro("HAVE_WMMINTRIN_H", "1"); - if (has_rdrnd) lib.defineCMacro("HAVE_RDRAND", "1"); - }, - .aarch64, .aarch64_be => { - const cpu_features = target.getCpuFeatures(); - const has_neon = cpu_features.isEnabled(@intFromEnum(Target.aarch64.Feature.neon)); - const has_crypto = cpu_features.isEnabled(@intFromEnum(Target.aarch64.Feature.crypto)); - if (has_neon and has_crypto) { - lib.defineCMacro("HAVE_ARMCRYPTO", "1"); - } - }, - .wasm32, .wasm64 => { - lib.defineCMacro("__wasm__", "1"); - }, - else => {}, - } - - switch (target.getOsTag()) { - .wasi => { - lib.defineCMacro("__wasi__", "1"); - }, - else => {}, - } - - switch (target.getCpuArch()) { - .x86_64 => { - lib.target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.sse4_1)); - lib.target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.aes)); - lib.target.cpu_features_add.addFeature(@intFromEnum(Target.x86.Feature.pclmul)); - }, - else => {}, - } + const base_flags = &.{ + "-fvisibility=hidden", + "-fno-strict-aliasing", + "-fno-strict-overflow", + "-fwrapv", + "-flax-vector-conversions", + }; const allocator = heap.page_allocator; - var walker = try src_dir.walk(allocator); - while (try walker.next()) |entry| { - const name = entry.basename; - if (mem.endsWith(u8, name, ".c")) { - const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ src_path, entry.path }); - const flags = &.{ - "-fvisibility=hidden", - "-fno-strict-aliasing", - "-fno-strict-overflow", - "-fwrapv", - "-flax-vector-conversions", - }; - if (@hasDecl(std.Build.Step.Compile, "AddCSourceFilesOptions")) { - lib.addCSourceFiles(.{ .files = &.{full_path}, .flags = flags }); - } else { - lib.addCSourceFiles(&.{full_path}, flags); + + // compile CPU-specific library code + for (&mlibs) |*mlib| { + var target2 = target; + for (mlib.arches) |arch| { + if (target.result.cpu.arch == arch) { + for (mlib.flags) |flag| { + target2.query.cpu_features_add.addFeature(flag.f()); + } + break; } + } + + mlib.lib = b.addStaticLibrary(.{ + .name = mlib.name, + .target = target2, + .optimize = optimize, + }); + const elib = mlib.lib; + initLibConfig(target, elib); + + var flags = std.ArrayList([]const u8).init(allocator); + defer flags.deinit(); + try flags.appendSlice(base_flags); + + for (mlib.sources) |path| { + const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ src_path, path }); + elib.addCSourceFiles(.{ + .files = &.{full_path}, + .flags = flags.items, + }); + } + lib.linkLibrary(elib); + } + + // compile generic library code + var walker = try src_dir.walk(allocator); + files: while (try walker.next()) |entry| { + var flags = std.ArrayList([]const u8).init(allocator); + defer flags.deinit(); + try flags.appendSlice(base_flags); + + const name = entry.basename; + + if (mem.endsWith(u8, name, ".c")) { + for (mlibs) |mlib| { + for (mlib.sources) |path| { + if (mem.eql(u8, entry.path, path)) continue :files; + } + } + + const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ src_path, entry.path }); + + lib.addCSourceFiles(.{ + .files = &.{full_path}, + .flags = flags.items, + }); } else if (mem.endsWith(u8, name, ".S")) { const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ src_path, entry.path }); lib.addAssemblyFile(.{ .path = full_path }); @@ -276,17 +405,17 @@ pub fn build(b: *std.build.Builder) !void { const test_path = "test/default"; const out_bin_path = "zig-out/bin"; - const test_dir = try fs.Dir.openIterableDir(cwd, test_path, .{ .no_follow = true }); + const test_dir = try fs.Dir.openDir(cwd, test_path, .{ .iterate = true, .no_follow = true }); fs.Dir.makePath(cwd, out_bin_path) catch {}; const out_bin_dir = try fs.Dir.openDir(cwd, out_bin_path, .{}); - try test_dir.dir.copyFile("run.sh", out_bin_dir, "run.sh", .{}); + try test_dir.copyFile("run.sh", out_bin_dir, "run.sh", .{}); const allocator = heap.page_allocator; var walker = try test_dir.walk(allocator); if (build_tests) { while (try walker.next()) |entry| { const name = entry.basename; if (mem.endsWith(u8, name, ".exp")) { - try test_dir.dir.copyFile(name, out_bin_dir, name, .{}); + try test_dir.copyFile(name, out_bin_dir, name, .{}); continue; } if (!mem.endsWith(u8, name, ".c")) { @@ -297,18 +426,14 @@ pub fn build(b: *std.build.Builder) !void { .name = exe_name, .target = target, .optimize = optimize, + .strip = true, }); exe.linkLibC(); - exe.strip = true; exe.linkLibrary(static_lib); exe.addIncludePath(.{ .path = "src/libsodium/include" }); exe.addIncludePath(.{ .path = "test/quirks" }); const full_path = try fmt.allocPrint(allocator, "{s}/{s}", .{ test_path, entry.path }); - if (@hasDecl(std.Build.Step.Compile, "AddCSourceFilesOptions")) { - exe.addCSourceFiles(.{ .files = &.{full_path} }); - } else { - exe.addCSourceFiles(&.{full_path}, &.{}); - } + exe.addCSourceFiles(.{ .files = &.{full_path} }); if (enable_benchmarks) { exe.defineCMacro("BENCHMARKS", "1"); var buf: [16]u8 = undefined; diff --git a/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c index 91e578df..8dc9f840 100644 --- a/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c +++ b/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c @@ -16,9 +16,11 @@ #if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H) -#ifdef __GNUC__ -#pragma GCC target("avx,aes,pclmul") -#endif +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx,pclmul"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("aes,avx,pclmul") +# endif #if !defined(_MSC_VER) || _MSC_VER < 1800 #define __vectorcall @@ -1006,4 +1008,8 @@ crypto_aead_aes256gcm_is_available(void) return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni() & sodium_runtime_has_avx(); } +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c index 4945462d..3152e286 100644 --- a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c +++ b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c @@ -12,11 +12,10 @@ #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # include @@ -46,4 +45,8 @@ blake2b_compress_avx2(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c index f085c615..ecab7164 100644 --- a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c +++ b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c @@ -11,10 +11,10 @@ #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1") # endif # include @@ -84,4 +84,8 @@ blake2b_compress_sse41(blake2b_state *S, return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c index 6372da03..8d0e3e9d 100644 --- a/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c +++ b/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c @@ -7,9 +7,10 @@ #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # include @@ -87,4 +88,8 @@ blake2b_compress_ssse3(blake2b_state *S, return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c b/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c index 24859284..0576c86e 100644 --- a/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c +++ b/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c @@ -10,7 +10,9 @@ #if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif @@ -946,4 +948,8 @@ struct crypto_onetimeauth_poly1305_implementation SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_sse2_final }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c index a35e1f91..5c795663 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c @@ -22,11 +22,10 @@ #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # ifdef _MSC_VER @@ -236,4 +235,9 @@ argon2_fill_segment_avx2(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c index 6566804e..033f7c21 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c @@ -22,12 +22,10 @@ #if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") -# pragma GCC target("avx512f") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2,avx512f"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2,avx512f") # endif # ifdef _MSC_VER @@ -241,4 +239,9 @@ argon2_fill_segment_avx512f(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c index fc85a478..1930bc35 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c @@ -21,9 +21,10 @@ #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # ifdef _MSC_VER @@ -235,4 +236,9 @@ argon2_fill_segment_ssse3(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c index c3ea0a3b..89fe8aec 100644 --- a/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c +++ b/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c @@ -38,13 +38,14 @@ #ifdef HAVE_EMMINTRIN_H -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif + # include -# if defined(__XOP__) && defined(DISABLED) -# include -# endif + # include "private/sse2_64_32.h" # include "../crypto_scrypt.h" @@ -397,4 +398,9 @@ escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, /* Success! */ return 0; } + +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c b/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c index 61000500..2bf2250b 100644 --- a/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c +++ b/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c @@ -11,11 +11,10 @@ #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # include @@ -174,4 +173,8 @@ struct crypto_stream_chacha20_implementation SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic }; +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c b/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c index ad13c3af..eb52bda6 100644 --- a/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c +++ b/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c @@ -10,9 +10,10 @@ #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # include @@ -168,4 +169,8 @@ struct crypto_stream_chacha20_implementation SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic }; +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c b/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c index 507d7fed..87789bb4 100644 --- a/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c +++ b/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c @@ -10,18 +10,17 @@ #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif -#include -#include -#include -#include -#include "private/sse2_64_32.h" +# include +# include +# include +# include +# include "private/sse2_64_32.h" # include "../stream_salsa20.h" # include "salsa20_xmm6int-avx2.h" @@ -128,4 +127,8 @@ struct crypto_stream_salsa20_implementation SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c b/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c index 16cca0da..32ef354d 100644 --- a/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c +++ b/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c @@ -9,7 +9,9 @@ #ifdef HAVE_EMMINTRIN_H -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif # include @@ -119,4 +121,8 @@ struct crypto_stream_salsa20_implementation SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/src/libsodium/crypto_verify/verify.c b/src/libsodium/crypto_verify/verify.c index ffebf220..0c3323a5 100644 --- a/src/libsodium/crypto_verify/verify.c +++ b/src/libsodium/crypto_verify/verify.c @@ -26,9 +26,6 @@ crypto_verify_64_bytes(void) #if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# endif # include static inline int diff --git a/src/libsodium/randombytes/internal/randombytes_internal_random.c b/src/libsodium/randombytes/internal/randombytes_internal_random.c index 1176cd66..d39063c5 100644 --- a/src/libsodium/randombytes/internal/randombytes_internal_random.c +++ b/src/libsodium/randombytes/internal/randombytes_internal_random.c @@ -45,7 +45,11 @@ # include #endif #ifdef HAVE_RDRAND -# pragma GCC target("rdrnd") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("rdrnd"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("rdrnd") +# endif # include #endif @@ -633,3 +637,9 @@ struct randombytes_implementation randombytes_internal_implementation = { SODIUM_C99(.buf =) randombytes_internal_random_buf, SODIUM_C99(.close =) randombytes_internal_random_close }; + +#ifdef HAVE_RDRAND +# ifdef __clang__ +# pragma clang attribute pop +# endif +#endif