Skip to content

Commit a49dc5d

Browse files
committed
SIL: add needsStackProtection flags for address_to_pointer and index_addr instructions.
Also add new "unprotected" variants of the `addressof` builtins: * `Builtin.unprotectedAddressOf` * `Builtin.unprotectedAddressOfBorrow`
1 parent 7febdd1 commit a49dc5d

31 files changed

+271
-56
lines changed

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,11 @@ final public
341341
class RawPointerToRefInst : SingleValueInstruction, UnaryInstruction {}
342342

343343
final public
344-
class AddressToPointerInst : SingleValueInstruction, UnaryInstruction {}
344+
class AddressToPointerInst : SingleValueInstruction, UnaryInstruction {
345+
public var needsStackProtection: Bool {
346+
AddressToPointerInst_needsStackProtection(bridged) != 0
347+
}
348+
}
345349

346350
final public
347351
class PointerToAddressInst : SingleValueInstruction, UnaryInstruction {}
@@ -350,6 +354,10 @@ final public
350354
class IndexAddrInst : SingleValueInstruction {
351355
public var base: Value { operands[0].value }
352356
public var index: Value { operands[1].value }
357+
358+
public var needsStackProtection: Bool {
359+
IndexAddrInst_needsStackProtection(bridged) != 0
360+
}
353361
}
354362

355363
final public

docs/SIL.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4298,7 +4298,7 @@ index_addr
42984298
``````````
42994299
::
43004300

4301-
sil-instruction ::= 'index_addr' sil-operand ',' sil-operand
4301+
sil-instruction ::= 'index_addr' ('[' 'stack_protection' ']')? sil-operand ',' sil-operand
43024302

43034303
%2 = index_addr %0 : $*T, %1 : $Builtin.Int<n>
43044304
// %0 must be of an address type $*T
@@ -4314,6 +4314,9 @@ special behavior in this regard, unlike ``char*`` or ``void*`` in C.) It is
43144314
also undefined behavior to index out of bounds of an array, except to index
43154315
the "past-the-end" address of the array.
43164316

4317+
The ``stack_protection`` flag indicates that stack protection is done for
4318+
the pointer origin.
4319+
43174320
tail_addr
43184321
`````````
43194322
::
@@ -6548,7 +6551,7 @@ address_to_pointer
65486551
``````````````````
65496552
::
65506553

6551-
sil-instruction ::= 'address_to_pointer' sil-operand 'to' sil-type
6554+
sil-instruction ::= 'address_to_pointer' ('[' 'stack_protection' ']')? sil-operand 'to' sil-type
65526555

65536556
%1 = address_to_pointer %0 : $*T to $Builtin.RawPointer
65546557
// %0 must be of an address type $*T
@@ -6560,6 +6563,9 @@ an address equivalent to ``%0``. It is undefined behavior to cast the
65606563
``RawPointer`` to any address type other than its original address type or
65616564
any `layout compatible types`_.
65626565

6566+
The ``stack_protection`` flag indicates that stack protection is done for
6567+
the pointer origin.
6568+
65636569
pointer_to_address
65646570
``````````````````
65656571
::

include/swift/AST/Builtins.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,25 @@ BUILTIN_SIL_OPERATION(ReinterpretCast, "reinterpretCast", Special)
339339
/// only valid for the duration of the original binding.
340340
BUILTIN_SIL_OPERATION(AddressOf, "addressof", Special)
341341

342+
/// unprotectedAddressOf (inout T) -> Builtin.RawPointer
343+
/// Returns a RawPointer pointing to a physical lvalue. The returned pointer is
344+
/// only valid for the duration of the original binding.
345+
/// In contrast to `addressof`, this builtin doesn't trigger an insertion of
346+
/// stack protectors.
347+
BUILTIN_SIL_OPERATION(UnprotectedAddressOf, "unprotectedAddressOf", Special)
348+
342349
/// addressOfBorrow (__shared T) -> Builtin.RawPointer
343350
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
344351
/// valid within the scope of the borrow.
345352
BUILTIN_SIL_OPERATION(AddressOfBorrow, "addressOfBorrow", Special)
346353

354+
/// unprotectedAddressOfBorrow (__shared T) -> Builtin.RawPointer
355+
/// Returns a RawPointer pointing to a borrowed rvalue. The returned pointer is only
356+
/// valid within the scope of the borrow.
357+
/// In contrast to `addressOfBorrow`, this builtin doesn't trigger an insertion of
358+
/// stack protectors.
359+
BUILTIN_SIL_OPERATION(UnprotectedAddressOfBorrow, "unprotectedAddressOfBorrow", Special)
360+
347361
/// GepRaw(Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer
348362
///
349363
/// Adds index bytes to a base pointer.

include/swift/SIL/SILBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ BridgedArrayRef TermInst_getSuccessors(BridgedInstruction term);
362362

363363
llvm::StringRef CondFailInst_getMessage(BridgedInstruction cfi);
364364
BridgedBuiltinID BuiltinInst_getID(BridgedInstruction bi);
365+
SwiftInt AddressToPointerInst_needsStackProtection(BridgedInstruction atp);
366+
SwiftInt IndexAddrInst_needsStackProtection(BridgedInstruction ia);
365367
BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst);
366368
BridgedFunction FunctionRefBaseInst_getReferencedFunction(BridgedInstruction fri);
367369
llvm::StringRef StringLiteralInst_getValue(BridgedInstruction sli);

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,9 +1094,9 @@ class SILBuilder {
10941094
}
10951095

10961096
AddressToPointerInst *createAddressToPointer(SILLocation Loc, SILValue Op,
1097-
SILType Ty) {
1097+
SILType Ty, bool needsStackProtection) {
10981098
return insert(new (getModule()) AddressToPointerInst(
1099-
getSILDebugLocation(Loc), Op, Ty));
1099+
getSILDebugLocation(Loc), Op, Ty, needsStackProtection));
11001100
}
11011101

11021102
PointerToAddressInst *
@@ -2136,9 +2136,9 @@ class SILBuilder {
21362136
//===--------------------------------------------------------------------===//
21372137

21382138
IndexAddrInst *createIndexAddr(SILLocation Loc, SILValue Operand,
2139-
SILValue Index) {
2139+
SILValue Index, bool needsStackProtection) {
21402140
return insert(new (getModule()) IndexAddrInst(getSILDebugLocation(Loc),
2141-
Operand, Index));
2141+
Operand, Index, needsStackProtection));
21422142
}
21432143

21442144
TailAddrInst *createTailAddr(SILLocation Loc, SILValue Operand,

include/swift/SIL/SILCloner.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,8 @@ SILCloner<ImplClass>::visitAddressToPointerInst(AddressToPointerInst *Inst) {
14611461
recordClonedInstruction(
14621462
Inst, getBuilder().createAddressToPointer(getOpLocation(Inst->getLoc()),
14631463
getOpValue(Inst->getOperand()),
1464-
getOpType(Inst->getType())));
1464+
getOpType(Inst->getType()),
1465+
Inst->needsStackProtection()));
14651466
}
14661467

14671468
template<typename ImplClass>
@@ -2627,7 +2628,8 @@ SILCloner<ImplClass>::visitIndexAddrInst(IndexAddrInst *Inst) {
26272628
recordClonedInstruction(
26282629
Inst, getBuilder().createIndexAddr(getOpLocation(Inst->getLoc()),
26292630
getOpValue(Inst->getBase()),
2630-
getOpValue(Inst->getIndex())));
2631+
getOpValue(Inst->getIndex()),
2632+
Inst->needsStackProtection()));
26312633
}
26322634

26332635
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5304,9 +5304,18 @@ class AddressToPointerInst
53045304
ConversionInst>
53055305
{
53065306
friend SILBuilder;
5307+
USE_SHARED_UINT8;
53075308

5308-
AddressToPointerInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty)
5309-
: UnaryInstructionBase(DebugLoc, Operand, Ty) {}
5309+
AddressToPointerInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
5310+
bool needsStackProtection)
5311+
: UnaryInstructionBase(DebugLoc, Operand, Ty) {
5312+
sharedUInt8().AddressToPointerInst.needsStackProtection = needsStackProtection;
5313+
}
5314+
5315+
public:
5316+
bool needsStackProtection() const {
5317+
return sharedUInt8().AddressToPointerInst.needsStackProtection;
5318+
}
53105319
};
53115320

53125321
/// PointerToAddressInst - Convert a Builtin.RawPointer value to a SIL address.
@@ -8086,11 +8095,20 @@ class IndexAddrInst
80868095
: public InstructionBase<SILInstructionKind::IndexAddrInst,
80878096
IndexingInst> {
80888097
friend SILBuilder;
8098+
USE_SHARED_UINT8;
80898099

80908100
enum { Base, Index };
80918101

8092-
IndexAddrInst(SILDebugLocation DebugLoc, SILValue Operand, SILValue Index)
8093-
: InstructionBase(DebugLoc, Operand->getType(), Operand, Index) {}
8102+
IndexAddrInst(SILDebugLocation DebugLoc, SILValue Operand, SILValue Index,
8103+
bool needsStackProtection)
8104+
: InstructionBase(DebugLoc, Operand->getType(), Operand, Index) {
8105+
sharedUInt8().IndexAddrInst.needsStackProtection = needsStackProtection;
8106+
}
8107+
8108+
public:
8109+
bool needsStackProtection() const {
8110+
return sharedUInt8().IndexAddrInst.needsStackProtection;
8111+
}
80948112
};
80958113

80968114
/// TailAddrInst - like IndexingInst, but aligns-up the resulting address to a

include/swift/SIL/SILNode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ class alignas(8) SILNode :
194194
SHARED_FIELD(EndAccessInst, bool aborting);
195195
SHARED_FIELD(RefElementAddrInst, bool immutable);
196196
SHARED_FIELD(RefTailAddrInst, bool immutable);
197+
SHARED_FIELD(AddressToPointerInst, bool needsStackProtection);
198+
SHARED_FIELD(IndexAddrInst, bool needsStackProtection);
197199
SHARED_FIELD(HopToExecutorInst, bool mandatory);
198200
SHARED_FIELD(DestroyValueInst, bool poisonRefs);
199201
SHARED_FIELD(EndCOWMutationInst, bool keepUnique);

lib/AST/Builtins.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2710,13 +2710,15 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
27102710
return getReinterpretCastOperation(Context, Id);
27112711

27122712
case BuiltinValueKind::AddressOf:
2713+
case BuiltinValueKind::UnprotectedAddressOf:
27132714
if (!Types.empty()) return nullptr;
27142715
return getAddressOfOperation(Context, Id);
27152716

27162717
case BuiltinValueKind::LegacyCondFail:
27172718
return getLegacyCondFailOperation(Context, Id);
27182719

27192720
case BuiltinValueKind::AddressOfBorrow:
2721+
case BuiltinValueKind::UnprotectedAddressOfBorrow:
27202722
if (!Types.empty()) return nullptr;
27212723
return getAddressOfBorrowOperation(Context, Id);
27222724

lib/SIL/IR/SILInstruction.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,8 @@ namespace {
663663
}
664664

665665
bool visitIndexAddrInst(IndexAddrInst *RHS) {
666-
// We have already compared the operands/types, so we should have equality
667-
// at this point.
668-
return true;
666+
auto *lhs = cast<IndexAddrInst>(LHS);
667+
return lhs->needsStackProtection() == RHS->needsStackProtection();
669668
}
670669

671670
bool visitTailAddrInst(TailAddrInst *RHS) {
@@ -772,7 +771,8 @@ namespace {
772771
}
773772

774773
bool visitAddressToPointerInst(AddressToPointerInst *RHS) {
775-
return true;
774+
auto *lhs = cast<AddressToPointerInst>(LHS);
775+
return lhs->needsStackProtection() == RHS->needsStackProtection();
776776
}
777777

778778
bool visitPointerToAddressInst(PointerToAddressInst *RHS) {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
18551855
printUncheckedConversionInst(CI, CI->getOperand());
18561856
}
18571857
void visitAddressToPointerInst(AddressToPointerInst *CI) {
1858+
*this << (CI->needsStackProtection() ? "[stack_protection] " : "");
18581859
printUncheckedConversionInst(CI, CI->getOperand());
18591860
}
18601861
void visitPointerToAddressInst(PointerToAddressInst *CI) {
@@ -2361,7 +2362,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
23612362
}
23622363

23632364
void visitIndexAddrInst(IndexAddrInst *IAI) {
2364-
*this << getIDAndType(IAI->getBase()) << ", "
2365+
*this << (IAI->needsStackProtection() ? "[stack_protection] " : "")
2366+
<< getIDAndType(IAI->getBase()) << ", "
23652367
<< getIDAndType(IAI->getIndex());
23662368
}
23672369

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,6 +3721,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
37213721
SourceLoc ToLoc;
37223722
bool not_guaranteed = false;
37233723
bool without_actually_escaping = false;
3724+
bool needsStackProtection = false;
37243725
if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
37253726
StringRef attrName;
37263727
if (parseSILOptional(attrName, *this)) {
@@ -3729,7 +3730,11 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
37293730
else
37303731
return true;
37313732
}
3733+
} if (Opcode == SILInstructionKind::AddressToPointerInst) {
3734+
if (parseSILOptional(needsStackProtection, *this, "stack_protection"))
3735+
return true;
37323736
}
3737+
37333738
if (parseTypedValueRef(Val, B) ||
37343739
parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
37353740
"to"))
@@ -3793,7 +3798,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
37933798
B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, !not_guaranteed);
37943799
break;
37953800
case SILInstructionKind::AddressToPointerInst:
3796-
ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
3801+
ResultVal = B.createAddressToPointer(InstLoc, Val, Ty, needsStackProtection);
37973802
break;
37983803
case SILInstructionKind::BridgeObjectToRefInst:
37993804
ResultVal =
@@ -5119,11 +5124,13 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
51195124
}
51205125
case SILInstructionKind::IndexAddrInst: {
51215126
SILValue IndexVal;
5122-
if (parseTypedValueRef(Val, B) ||
5127+
bool needsStackProtection = false;
5128+
if (parseSILOptional(needsStackProtection, *this, "stack_protection") ||
5129+
parseTypedValueRef(Val, B) ||
51235130
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
51245131
parseTypedValueRef(IndexVal, B) || parseSILDebugLocation(InstLoc, B))
51255132
return true;
5126-
ResultVal = B.createIndexAddr(InstLoc, Val, IndexVal);
5133+
ResultVal = B.createIndexAddr(InstLoc, Val, IndexVal, needsStackProtection);
51275134
break;
51285135
}
51295136
case SILInstructionKind::TailAddrInst: {

lib/SIL/Utils/Projection.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,9 @@ Projection::createAddressProjection(SILBuilder &B, SILLocation Loc,
272272
SILType::getBuiltinIntegerType(64, B.getModule().getASTContext());
273273
auto IntLiteralIndex =
274274
B.createIntegerLiteral(Loc, IntLiteralTy, getIndex());
275-
return B.createIndexAddr(Loc, Base, IntLiteralIndex);
275+
return B.createIndexAddr(Loc, Base, IntLiteralIndex,
276+
// TODO: do we need to be conservative here?
277+
/*needsStackProtection=*/ true);
276278
}
277279
case ProjectionKind::Enum:
278280
return B.createUncheckedTakeEnumDataAddr(Loc, Base,

lib/SIL/Utils/SILBridging.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,14 @@ BridgedBuiltinID BuiltinInst_getID(BridgedInstruction bi) {
768768
return (BridgedBuiltinID)castToInst<BuiltinInst>(bi)->getBuiltinInfo().ID;
769769
}
770770

771+
SwiftInt AddressToPointerInst_needsStackProtection(BridgedInstruction atp) {
772+
return castToInst<AddressToPointerInst>(atp)->needsStackProtection() ? 1 : 0;
773+
}
774+
775+
SwiftInt IndexAddrInst_needsStackProtection(BridgedInstruction ia) {
776+
return castToInst<IndexAddrInst>(ia)->needsStackProtection() ? 1 : 0;
777+
}
778+
771779
BridgedGlobalVar GlobalAccessInst_getGlobal(BridgedInstruction globalInst) {
772780
return {castToInst<GlobalAccessInst>(globalInst)->getReferencedGlobal()};
773781
}

0 commit comments

Comments
 (0)