Skip to content

Commit 655e0c4

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.8-beta.1
2 parents 0fc05aa + 0bb5449 commit 655e0c4

File tree

23 files changed

+382
-98
lines changed

23 files changed

+382
-98
lines changed

clang/docs/AllocToken.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ The default mode to calculate tokens is:
3737
pointers.
3838

3939
Other token ID assignment modes are supported, but they may be subject to
40-
change or removal. These may (experimentally) be selected with ``-mllvm
41-
-alloc-token-mode=<mode>``:
40+
change or removal. These may (experimentally) be selected with ``-Xclang
41+
-falloc-token-mode=<mode>``:
4242

4343
* ``typehash``: This mode assigns a token ID based on the hash of the allocated
4444
type's name.

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
447447

448448
std::optional<double> AllowRuntimeCheckSkipHotCutoff;
449449

450-
/// Maximum number of allocation tokens (0 = no max), nullopt if none set (use
451-
/// pass default).
452-
std::optional<uint64_t> AllocTokenMax;
453-
454450
/// List of backend command-line options for -fembed-bitcode.
455451
std::vector<uint8_t> CmdArgs;
456452

clang/include/clang/Basic/LangOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/FloatingPointMode.h"
2626
#include "llvm/ADT/StringRef.h"
2727
#include "llvm/BinaryFormat/DXContainer.h"
28+
#include "llvm/Support/AllocToken.h"
2829
#include "llvm/TargetParser/Triple.h"
2930
#include <optional>
3031
#include <string>
@@ -565,6 +566,13 @@ class LangOptions : public LangOptionsBase {
565566
bool AtomicFineGrainedMemory = false;
566567
bool AtomicIgnoreDenormalMode = false;
567568

569+
/// Maximum number of allocation tokens (0 = no max), nullopt if none set (use
570+
/// target default).
571+
std::optional<uint64_t> AllocTokenMax;
572+
573+
/// The allocation token mode.
574+
std::optional<llvm::AllocTokenMode> AllocTokenMode;
575+
568576
LangOptions();
569577

570578
/// Set language defaults for the given input language and

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,10 @@ def falloc_token_max_EQ : Joined<["-"], "falloc-token-max=">,
27512751
MetaVarName<"<N>">,
27522752
HelpText<"Limit to maximum N allocation tokens (0 = no max)">;
27532753

2754+
def falloc_token_mode_EQ : Joined<["-"], "falloc-token-mode=">,
2755+
Group<f_Group>, Visibility<[CC1Option]>,
2756+
HelpText<"Set the allocation token mode (experimental)">;
2757+
27542758
def fallow_runtime_check_skip_hot_cutoff_EQ
27552759
: Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
27562760
Group<f_clang_Group>,

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,12 @@ class EmitAssemblyHelper {
234234
};
235235
} // namespace
236236

237-
static AllocTokenOptions getAllocTokenOptions(const CodeGenOptions &CGOpts) {
237+
static AllocTokenOptions getAllocTokenOptions(const LangOptions &LangOpts,
238+
const CodeGenOptions &CGOpts) {
238239
AllocTokenOptions Opts;
239-
Opts.MaxTokens = CGOpts.AllocTokenMax;
240+
if (LangOpts.AllocTokenMode)
241+
Opts.Mode = *LangOpts.AllocTokenMode;
242+
Opts.MaxTokens = LangOpts.AllocTokenMax;
240243
Opts.Extended = CGOpts.SanitizeAllocTokenExtended;
241244
Opts.FastABI = CGOpts.SanitizeAllocTokenFastABI;
242245
return Opts;
@@ -808,7 +811,7 @@ static void addSanitizers(const Triple &TargetTriple,
808811
// memory allocation function detection.
809812
MPM.addPass(InferFunctionAttrsPass());
810813
}
811-
MPM.addPass(AllocTokenPass(getAllocTokenOptions(CodeGenOpts)));
814+
MPM.addPass(AllocTokenPass(getAllocTokenOptions(LangOpts, CodeGenOpts)));
812815
}
813816
};
814817
if (ClSanitizeOnOptimizerEarlyEP) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,10 +1833,6 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
18331833
serializeSanitizerKinds(Opts.SanitizeAnnotateDebugInfo))
18341834
GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer);
18351835

1836-
if (Opts.AllocTokenMax)
1837-
GenerateArg(Consumer, OPT_falloc_token_max_EQ,
1838-
std::to_string(*Opts.AllocTokenMax));
1839-
18401836
if (!Opts.EmitVersionIdentMetadata)
18411837
GenerateArg(Consumer, OPT_Qn);
18421838

@@ -2350,15 +2346,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
23502346
}
23512347
}
23522348

2353-
if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_max_EQ)) {
2354-
StringRef S = Arg->getValue();
2355-
uint64_t Value = 0;
2356-
if (S.getAsInteger(0, Value))
2357-
Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S;
2358-
else
2359-
Opts.AllocTokenMax = Value;
2360-
}
2361-
23622349
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
23632350

23642351
if (!LangOpts->CUDAIsDevice)
@@ -3966,6 +3953,29 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
39663953

39673954
if (!Opts.RandstructSeed.empty())
39683955
GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3956+
3957+
if (Opts.AllocTokenMax)
3958+
GenerateArg(Consumer, OPT_falloc_token_max_EQ,
3959+
std::to_string(*Opts.AllocTokenMax));
3960+
3961+
if (Opts.AllocTokenMode) {
3962+
StringRef S;
3963+
switch (*Opts.AllocTokenMode) {
3964+
case llvm::AllocTokenMode::Increment:
3965+
S = "increment";
3966+
break;
3967+
case llvm::AllocTokenMode::Random:
3968+
S = "random";
3969+
break;
3970+
case llvm::AllocTokenMode::TypeHash:
3971+
S = "typehash";
3972+
break;
3973+
case llvm::AllocTokenMode::TypeHashPointerSplit:
3974+
S = "typehashpointersplit";
3975+
break;
3976+
}
3977+
GenerateArg(Consumer, OPT_falloc_token_mode_EQ, S);
3978+
}
39693979
}
39703980

39713981
bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@@ -4544,6 +4554,30 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
45444554
if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
45454555
Opts.RandstructSeed = A->getValue(0);
45464556

4557+
if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_max_EQ)) {
4558+
StringRef S = Arg->getValue();
4559+
uint64_t Value = 0;
4560+
if (S.getAsInteger(0, Value))
4561+
Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S;
4562+
else
4563+
Opts.AllocTokenMax = Value;
4564+
}
4565+
4566+
if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_mode_EQ)) {
4567+
StringRef S = Arg->getValue();
4568+
auto Mode = llvm::StringSwitch<std::optional<llvm::AllocTokenMode>>(S)
4569+
.Case("increment", llvm::AllocTokenMode::Increment)
4570+
.Case("random", llvm::AllocTokenMode::Random)
4571+
.Case("typehash", llvm::AllocTokenMode::TypeHash)
4572+
.Case("typehashpointersplit",
4573+
llvm::AllocTokenMode::TypeHashPointerSplit)
4574+
.Default(std::nullopt);
4575+
if (Mode)
4576+
Opts.AllocTokenMode = Mode;
4577+
else
4578+
Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S;
4579+
}
4580+
45474581
// Validate options for HLSL
45484582
if (Opts.HLSL) {
45494583
// TODO: Revisit restricting SPIR-V to logical once we've figured out how to

clang/test/Driver/fsanitize-alloc-token.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,14 @@
4141
// CHECK-MAX: "-falloc-token-max=42"
4242
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=alloc-token -falloc-token-max=-1 %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-MAX %s
4343
// CHECK-INVALID-MAX: error: invalid value
44+
45+
// RUN: %clang --target=x86_64-linux-gnu -Xclang -falloc-token-mode=increment %s -### 2>&1 | FileCheck -check-prefix=CHECK-MODE-INCREMENT %s
46+
// CHECK-MODE-INCREMENT: "-falloc-token-mode=increment"
47+
// RUN: %clang --target=x86_64-linux-gnu -Xclang -falloc-token-mode=random %s -### 2>&1 | FileCheck -check-prefix=CHECK-MODE-RANDOM %s
48+
// CHECK-MODE-RANDOM: "-falloc-token-mode=random"
49+
// RUN: %clang --target=x86_64-linux-gnu -Xclang -falloc-token-mode=typehash %s -### 2>&1 | FileCheck -check-prefix=CHECK-MODE-TYPEHASH %s
50+
// CHECK-MODE-TYPEHASH: "-falloc-token-mode=typehash"
51+
// RUN: %clang --target=x86_64-linux-gnu -Xclang -falloc-token-mode=typehashpointersplit %s -### 2>&1 | FileCheck -check-prefix=CHECK-MODE-TYPEHASHPTRSPLIT %s
52+
// CHECK-MODE-TYPEHASHPTRSPLIT: "-falloc-token-mode=typehashpointersplit"
53+
// RUN: not %clang --target=x86_64-linux-gnu -Xclang -falloc-token-mode=asdf %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-MODE %s
54+
// CHECK-INVALID-MODE: error: invalid value 'asdf'

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,7 +2853,15 @@ def int_ptrauth_blend :
28532853
def int_ptrauth_sign_generic :
28542854
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
28552855

2856+
//===----------------- AllocToken Intrinsics ------------------------------===//
2857+
2858+
// Return the token ID for the given !alloc_token metadata.
2859+
def int_alloc_token_id :
2860+
DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
2861+
[IntrNoMem, NoUndef<RetIndex>]>;
2862+
28562863
//===----------------------------------------------------------------------===//
2864+
28572865
//===------- Convergence Intrinsics ---------------------------------------===//
28582866

28592867
def int_experimental_convergence_entry
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===- llvm/Support/AllocToken.h - Allocation Token Calculation -----*- C++ -*//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Definition of AllocToken modes and shared calculation of stateless token IDs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_SUPPORT_ALLOCTOKEN_H
14+
#define LLVM_SUPPORT_ALLOCTOKEN_H
15+
16+
#include "llvm/ADT/SmallString.h"
17+
#include <cstdint>
18+
#include <optional>
19+
20+
namespace llvm {
21+
22+
/// Modes for generating allocation token IDs.
23+
enum class AllocTokenMode {
24+
/// Incrementally increasing token ID.
25+
Increment,
26+
27+
/// Simple mode that returns a statically-assigned random token ID.
28+
Random,
29+
30+
/// Token ID based on allocated type hash.
31+
TypeHash,
32+
33+
/// Token ID based on allocated type hash, where the top half ID-space is
34+
/// reserved for types that contain pointers and the bottom half for types
35+
/// that do not contain pointers.
36+
TypeHashPointerSplit,
37+
};
38+
39+
/// The default allocation token mode.
40+
inline constexpr AllocTokenMode DefaultAllocTokenMode =
41+
AllocTokenMode::TypeHashPointerSplit;
42+
43+
/// Metadata about an allocation used to generate a token ID.
44+
struct AllocTokenMetadata {
45+
SmallString<64> TypeName;
46+
bool ContainsPointer;
47+
};
48+
49+
/// Calculates stable allocation token ID. Returns std::nullopt for stateful
50+
/// modes that are only available in the AllocToken pass.
51+
///
52+
/// \param Mode The token generation mode.
53+
/// \param Metadata The metadata about the allocation.
54+
/// \param MaxTokens The maximum number of tokens (must not be 0)
55+
/// \return The calculated allocation token ID, or std::nullopt.
56+
std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
57+
const AllocTokenMetadata &Metadata,
58+
uint64_t MaxTokens);
59+
60+
} // end namespace llvm
61+
62+
#endif // LLVM_SUPPORT_ALLOCTOKEN_H

llvm/include/llvm/Transforms/Instrumentation/AllocToken.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616

1717
#include "llvm/IR/Analysis.h"
1818
#include "llvm/IR/PassManager.h"
19+
#include "llvm/Support/AllocToken.h"
1920
#include <optional>
2021

2122
namespace llvm {
2223

2324
class Module;
2425

2526
struct AllocTokenOptions {
27+
AllocTokenMode Mode = DefaultAllocTokenMode;
2628
std::optional<uint64_t> MaxTokens;
2729
bool FastABI = false;
2830
bool Extended = false;

0 commit comments

Comments
 (0)