Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -2853,7 +2853,15 @@ def int_ptrauth_blend :
def int_ptrauth_sign_generic :
DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;

//===----------------- AllocToken Intrinsics ------------------------------===//

// Return the token ID for the given !alloc_token metadata.
def int_alloc_token_id :
DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrNoMem, NoUndef<RetIndex>]>;

//===----------------------------------------------------------------------===//

//===------- Convergence Intrinsics ---------------------------------------===//

def int_experimental_convergence_entry
Expand Down
62 changes: 62 additions & 0 deletions llvm/include/llvm/Support/AllocToken.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//===- llvm/Support/AllocToken.h - Allocation Token Calculation -----*- C++ -*//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Definition of AllocToken modes and shared calculation of stateless token IDs.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SUPPORT_ALLOCTOKEN_H
#define LLVM_SUPPORT_ALLOCTOKEN_H

#include "llvm/ADT/SmallString.h"
#include <cstdint>
#include <optional>

namespace llvm {

/// Modes for generating allocation token IDs.
enum class AllocTokenMode {
/// Incrementally increasing token ID.
Increment,

/// Simple mode that returns a statically-assigned random token ID.
Random,

/// Token ID based on allocated type hash.
TypeHash,

/// Token ID based on allocated type hash, where the top half ID-space is
/// reserved for types that contain pointers and the bottom half for types
/// that do not contain pointers.
TypeHashPointerSplit,
};

/// The default allocation token mode.
inline constexpr AllocTokenMode DefaultAllocTokenMode =
AllocTokenMode::TypeHashPointerSplit;

/// Metadata about an allocation used to generate a token ID.
struct AllocTokenMetadata {
SmallString<64> TypeName;
bool ContainsPointer;
};

/// Calculates stable allocation token ID. Returns std::nullopt for stateful
/// modes that are only available in the AllocToken pass.
///
/// \param Mode The token generation mode.
/// \param Metadata The metadata about the allocation.
/// \param MaxTokens The maximum number of tokens (must not be 0)
/// \return The calculated allocation token ID, or std::nullopt.
std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
const AllocTokenMetadata &Metadata,
uint64_t MaxTokens);

} // end namespace llvm

#endif // LLVM_SUPPORT_ALLOCTOKEN_H
2 changes: 2 additions & 0 deletions llvm/include/llvm/Transforms/Instrumentation/AllocToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@

#include "llvm/IR/Analysis.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/AllocToken.h"
#include <optional>

namespace llvm {

class Module;

struct AllocTokenOptions {
AllocTokenMode Mode = DefaultAllocTokenMode;
std::optional<uint64_t> MaxTokens;
bool FastABI = false;
bool Extended = false;
Expand Down
32 changes: 32 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,38 @@ Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
return Result;
}

Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
AllocTokenOptions Result;
while (!Params.empty()) {
StringRef ParamName;
std::tie(ParamName, Params) = Params.split(';');

if (ParamName.consume_front("mode=")) {
auto Mode = StringSwitch<std::optional<AllocTokenMode>>(ParamName)
.Case("increment", AllocTokenMode::Increment)
.Case("random", AllocTokenMode::Random)
.Case("typehash", AllocTokenMode::TypeHash)
.Case("typehashpointersplit",
AllocTokenMode::TypeHashPointerSplit)
.Default(std::nullopt);
if (Mode)
Result.Mode = *Mode;
else
return make_error<StringError>(
formatv("invalid argument to AllocToken pass mode "
"parameter: '{}'",
ParamName)
.str(),
inconvertibleErrorCode());
} else {
return make_error<StringError>(
formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
inconvertibleErrorCode());
}
}
return Result;
}

/// Parser of parameters for SimplifyCFG pass.
Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
SimplifyCFGOptions Result;
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ MODULE_PASS("openmp-opt", OpenMPOptPass())
MODULE_PASS("openmp-opt-postlink",
OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink))
MODULE_PASS("partial-inliner", PartialInlinerPass())
MODULE_PASS("alloc-token", AllocTokenPass())
MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion())
MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
Expand Down Expand Up @@ -181,6 +180,10 @@ MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
#ifndef MODULE_PASS_WITH_PARAMS
#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
#endif
MODULE_PASS_WITH_PARAMS(
"alloc-token", "AllocTokenPass",
[](AllocTokenOptions Opts) { return AllocTokenPass(Opts); },
parseAllocTokenPassOptions, "mode=<mode>")
MODULE_PASS_WITH_PARAMS(
"asan", "AddressSanitizerPass",
[](AddressSanitizerOptions Opts) { return AddressSanitizerPass(Opts); },
Expand Down
46 changes: 46 additions & 0 deletions llvm/lib/Support/AllocToken.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===- AllocToken.cpp - Allocation Token Calculation ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Definition of AllocToken modes and shared calculation of stateless token IDs.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/AllocToken.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SipHash.h"

namespace llvm {
std::optional<uint64_t> getAllocTokenHash(AllocTokenMode Mode,
const AllocTokenMetadata &Metadata,
uint64_t MaxTokens) {
assert(MaxTokens && "Must provide concrete max tokens");

switch (Mode) {
case AllocTokenMode::Increment:
case AllocTokenMode::Random:
// Stateful modes cannot be implemented as a pure function.
return std::nullopt;

case AllocTokenMode::TypeHash: {
return getStableSipHash(Metadata.TypeName) % MaxTokens;
}

case AllocTokenMode::TypeHashPointerSplit: {
if (MaxTokens == 1)
return 0;
const uint64_t HalfTokens = MaxTokens / 2;
uint64_t Hash = getStableSipHash(Metadata.TypeName) % HalfTokens;
if (Metadata.ContainsPointer)
Hash += HalfTokens;
return Hash;
}
}

llvm_unreachable("");
}
} // namespace llvm
1 change: 1 addition & 0 deletions llvm/lib/Support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ add_llvm_component_library(LLVMSupport
AArch64BuildAttributes.cpp
ARMAttributeParser.cpp
ARMWinEH.cpp
AllocToken.cpp
Allocator.cpp
AutoConvert.cpp
Base64.cpp
Expand Down
Loading
Loading