Skip to content

Commit 4110867

Browse files
ahmedbougachaahatanak
authored andcommitted
[clang] Resign type-discriminated function pointers on cast.
1 parent a147bce commit 4110867

22 files changed

+907
-103
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
12841284
getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD);
12851285

12861286
/// Return the "other" type-specific discriminator for the given type.
1287-
uint16_t getPointerAuthTypeDiscriminator(QualType T) const;
1287+
uint16_t getPointerAuthTypeDiscriminator(QualType T);
12881288

12891289
/// Apply Objective-C protocol qualifiers to the given type.
12901290
/// \param allowOnPointerType specifies if we can apply protocol

clang/include/clang/AST/Type.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2507,6 +2507,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
25072507
bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
25082508
bool isPointerType() const;
25092509
bool isSignableType() const;
2510+
bool isSignablePointerType() const;
25102511
bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
25112512
bool isCountAttributedType() const;
25122513
bool isBlockPointerType() const;
@@ -8002,7 +8003,9 @@ inline bool Type::isAnyPointerType() const {
80028003
return isPointerType() || isObjCObjectPointerType();
80038004
}
80048005

8005-
inline bool Type::isSignableType() const { return isPointerType(); }
8006+
inline bool Type::isSignableType() const { return isSignablePointerType(); }
8007+
8008+
inline bool Type::isSignablePointerType() const { return isPointerType(); }
80068009

80078010
inline bool Type::isBlockPointerType() const {
80088011
return isa<BlockPointerType>(CanonicalType);

clang/lib/AST/ASTContext.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,7 +3400,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
34003400
}
34013401
}
34023402

3403-
uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
3403+
uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) {
34043404
assert(!T->isDependentType() &&
34053405
"cannot compute type discriminator of a dependent type");
34063406

@@ -3410,11 +3410,13 @@ uint16_t ASTContext::getPointerAuthTypeDiscriminator(QualType T) const {
34103410
if (T->isFunctionPointerType() || T->isFunctionReferenceType())
34113411
T = T->getPointeeType();
34123412

3413-
if (T->isFunctionType())
3413+
if (T->isFunctionType()) {
34143414
encodeTypeForFunctionPointerAuth(*this, Out, T);
3415-
else
3416-
llvm_unreachable(
3417-
"type discrimination of non-function type not implemented yet");
3415+
} else {
3416+
T = T.getUnqualifiedType();
3417+
std::unique_ptr<MangleContext> MC(createMangleContext());
3418+
MC->mangleCanonicalTypeName(T, Out);
3419+
}
34183420

34193421
return llvm::getPointerAuthStableSipHash(Str);
34203422
}

clang/lib/CodeGen/Address.h

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
1515
#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H
1616

17+
#include "CGPointerAuthInfo.h"
1718
#include "clang/AST/CharUnits.h"
1819
#include "clang/AST/Type.h"
1920
#include "llvm/ADT/PointerIntPair.h"
@@ -141,7 +142,11 @@ class Address {
141142

142143
CharUnits Alignment;
143144

144-
/// Offset from the base pointer.
145+
/// The ptrauth information needed to authenticate the base pointer.
146+
CGPointerAuthInfo PtrAuthInfo;
147+
148+
/// Offset from the base pointer. This is non-null only when the base
149+
/// pointer is signed.
145150
llvm::Value *Offset = nullptr;
146151

147152
llvm::Value *emitRawPointerSlow(CodeGenFunction &CGF) const;
@@ -160,12 +165,14 @@ class Address {
160165
}
161166

162167
Address(llvm::Value *BasePtr, llvm::Type *ElementType, CharUnits Alignment,
163-
llvm::Value *Offset, KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
168+
CGPointerAuthInfo PtrAuthInfo, llvm::Value *Offset,
169+
KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
164170
: Pointer(BasePtr, IsKnownNonNull), ElementType(ElementType),
165-
Alignment(Alignment), Offset(Offset) {}
171+
Alignment(Alignment), PtrAuthInfo(PtrAuthInfo), Offset(Offset) {}
166172

167173
Address(RawAddress RawAddr)
168-
: Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr),
174+
: Pointer(RawAddr.isValid() ? RawAddr.getPointer() : nullptr,
175+
RawAddr.isValid() ? RawAddr.isKnownNonNull() : NotKnownNonNull),
169176
ElementType(RawAddr.isValid() ? RawAddr.getElementType() : nullptr),
170177
Alignment(RawAddr.isValid() ? RawAddr.getAlignment()
171178
: CharUnits::Zero()) {}
@@ -175,7 +182,7 @@ class Address {
175182

176183
llvm::Value *getPointerIfNotSigned() const {
177184
assert(isValid() && "pointer isn't valid");
178-
return Pointer.getPointer();
185+
return !isSigned() ? Pointer.getPointer() : nullptr;
179186
}
180187

181188
/// This function is used in situations where the caller is doing some sort of
@@ -197,7 +204,10 @@ class Address {
197204
return Pointer.getPointer();
198205
}
199206

200-
llvm::Value *getUnsignedPointer() const { return getBasePointer(); }
207+
llvm::Value *getUnsignedPointer() const {
208+
assert(!isSigned() && "cannot call this function if pointer is signed");
209+
return getBasePointer();
210+
}
201211

202212
/// Return the type of the pointer value.
203213
llvm::PointerType *getType() const {
@@ -219,14 +229,18 @@ class Address {
219229
/// Return the IR name of the pointer value.
220230
llvm::StringRef getName() const { return Pointer.getPointer()->getName(); }
221231

232+
const CGPointerAuthInfo &getPointerAuthInfo() const { return PtrAuthInfo; }
233+
void setPointerAuthInfo(const CGPointerAuthInfo &Info) { PtrAuthInfo = Info; }
234+
222235
// This function is called only in CGBuilderBaseTy::CreateElementBitCast.
223236
void setElementType(llvm::Type *Ty) {
224237
assert(hasOffset() &&
225238
"this funcion shouldn't be called when there is no offset");
226239
ElementType = Ty;
227240
}
228241

229-
/// Whether the pointer is known not to be null.
242+
bool isSigned() const { return PtrAuthInfo.isSigned(); }
243+
230244
KnownNonNull_t isKnownNonNull() const {
231245
assert(isValid());
232246
return (KnownNonNull_t)Pointer.getInt();
@@ -250,10 +264,15 @@ class Address {
250264

251265
llvm::Value *getOffset() const { return Offset; }
252266

267+
Address getResignedAddress(const CGPointerAuthInfo &NewInfo,
268+
CodeGenFunction &CGF) const;
269+
253270
/// Return the pointer contained in this class after authenticating it and
254271
/// adding offset to it if necessary.
255272
llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
256-
return getUnsignedPointer();
273+
if (!isSigned())
274+
return getUnsignedPointer();
275+
return emitRawPointerSlow(CGF);
257276
}
258277

259278
/// Return address with different pointer, but same element type and
@@ -275,8 +294,8 @@ class Address {
275294
/// alignment.
276295
Address withElementType(llvm::Type *ElemTy) const {
277296
if (!hasOffset())
278-
return Address(getBasePointer(), ElemTy, getAlignment(), nullptr,
279-
isKnownNonNull());
297+
return Address(getBasePointer(), ElemTy, getAlignment(),
298+
getPointerAuthInfo(), nullptr, isKnownNonNull());
280299
Address A(*this);
281300
A.ElementType = ElemTy;
282301
return A;

clang/lib/CodeGen/CGBuilder.h

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ class CGBuilderTy : public CGBuilderBaseTy {
5757
CodeGenFunction *getCGF() const { return getInserter().CGF; }
5858

5959
llvm::Value *emitRawPointerFromAddress(Address Addr) const {
60-
return Addr.getUnsignedPointer();
60+
if (!Addr.isSigned())
61+
return Addr.getUnsignedPointer();
62+
assert(getCGF() && "CGF not set");
63+
return Addr.emitRawPointerSlow(*getCGF());
6164
}
6265

6366
/// Helper function to compute a GEP's offset and add it to Addr.
@@ -208,8 +211,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
208211
const llvm::Twine &Name = "") {
209212
if (!Addr.hasOffset())
210213
return Address(CreateAddrSpaceCast(Addr.getBasePointer(), Ty, Name),
211-
ElementTy, Addr.getAlignment(), nullptr,
212-
Addr.isKnownNonNull());
214+
ElementTy, Addr.getAlignment(), Addr.getPointerAuthInfo(),
215+
nullptr, Addr.isKnownNonNull());
213216
// Eagerly force a raw address if these is an offset.
214217
return RawAddress(
215218
CreateAddrSpaceCast(Addr.emitRawPointer(*getCGF()), Ty, Name),
@@ -240,11 +243,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
240243
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
241244
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
242245

243-
return Address(CreateStructGEP(Addr.getElementType(),
244-
Addr.getUnsignedPointer(), Index, Name),
245-
ElTy->getElementType(Index),
246-
Addr.getAlignment().alignmentAtOffset(Offset),
247-
Addr.isKnownNonNull());
246+
if (!Addr.isSigned())
247+
return Address(CreateStructGEP(Addr.getElementType(),
248+
Addr.getUnsignedPointer(), Index, Name),
249+
ElTy->getElementType(Index),
250+
Addr.getAlignment().alignmentAtOffset(Offset),
251+
Addr.isKnownNonNull());
252+
Addr.addOffset(Offset, ElTy->getTypeAtIndex(Index), *this);
253+
return Addr;
248254
}
249255

250256
/// Given
@@ -262,12 +268,15 @@ class CGBuilderTy : public CGBuilderBaseTy {
262268
CharUnits EltSize =
263269
CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
264270

265-
return Address(
266-
CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
267-
{getSize(CharUnits::Zero()), getSize(Index)}, Name),
268-
ElTy->getElementType(),
269-
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
270-
Addr.isKnownNonNull());
271+
if (!Addr.isSigned())
272+
return Address(
273+
CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
274+
{getSize(CharUnits::Zero()), getSize(Index)}, Name),
275+
ElTy->getElementType(),
276+
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
277+
Addr.isKnownNonNull());
278+
Addr.addOffset(Index * EltSize, ElTy, *this);
279+
return Addr;
271280
}
272281

273282
/// Given
@@ -281,10 +290,14 @@ class CGBuilderTy : public CGBuilderBaseTy {
281290
const llvm::DataLayout &DL = BB->getDataLayout();
282291
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
283292

284-
return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
285-
getSize(Index), Name),
286-
ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
287-
Addr.isKnownNonNull());
293+
if (!Addr.isSigned())
294+
return Address(CreateInBoundsGEP(ElTy, Addr.getUnsignedPointer(),
295+
getSize(Index), Name),
296+
ElTy,
297+
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
298+
Addr.isKnownNonNull());
299+
Addr.addOffset(Index * EltSize, ElTy, *this);
300+
return Addr;
288301
}
289302

290303
/// Given
@@ -298,10 +311,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
298311
const llvm::DataLayout &DL = BB->getDataLayout();
299312
CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
300313

301-
return Address(
302-
CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
303-
Addr.getElementType(),
304-
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
314+
if (!Addr.isSigned())
315+
return Address(
316+
CreateGEP(ElTy, Addr.getUnsignedPointer(), getSize(Index), Name),
317+
ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize));
318+
Addr.addOffset(Index * EltSize, ElTy, *this);
319+
return Addr;
305320
}
306321

307322
/// Create GEP with single dynamic index. The address alignment is reduced
@@ -323,21 +338,28 @@ class CGBuilderTy : public CGBuilderBaseTy {
323338
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset,
324339
const llvm::Twine &Name = "") {
325340
assert(Addr.getElementType() == TypeCache.Int8Ty);
326-
return Address(
327-
CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
328-
getSize(Offset), Name),
329-
Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
330-
Addr.isKnownNonNull());
341+
342+
if (!Addr.isSigned())
343+
return Address(
344+
CreateInBoundsGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
345+
getSize(Offset), Name),
346+
Addr.getElementType(), Addr.getAlignment().alignmentAtOffset(Offset),
347+
Addr.isKnownNonNull());
348+
Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
349+
return Addr;
331350
}
332351

333352
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
334353
const llvm::Twine &Name = "") {
335354
assert(Addr.getElementType() == TypeCache.Int8Ty);
336355

337-
return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
338-
getSize(Offset), Name),
339-
Addr.getElementType(),
340-
Addr.getAlignment().alignmentAtOffset(Offset));
356+
if (!Addr.isSigned())
357+
return Address(CreateGEP(Addr.getElementType(), Addr.getUnsignedPointer(),
358+
getSize(Offset), Name),
359+
Addr.getElementType(),
360+
Addr.getAlignment().alignmentAtOffset(Offset));
361+
Addr.addOffset(Offset, TypeCache.Int8Ty, *this);
362+
return Addr;
341363
}
342364

343365
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -364,10 +386,12 @@ class CGBuilderTy : public CGBuilderBaseTy {
364386
Address CreateInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
365387
llvm::Type *ElementType, CharUnits Align,
366388
const Twine &Name = "") {
367-
return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
368-
emitRawPointerFromAddress(Addr),
369-
IdxList, Name),
370-
ElementType, Align, Addr.isKnownNonNull());
389+
if (!Addr.isSigned())
390+
return RawAddress(CreateInBoundsGEP(Addr.getElementType(),
391+
emitRawPointerFromAddress(Addr),
392+
IdxList, Name),
393+
ElementType, Align, Addr.isKnownNonNull());
394+
return addGEPOffset(Addr, IdxList, Align, true, Name);
371395
}
372396

373397
using CGBuilderBaseTy::CreateIsNull;

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2151,7 +2151,8 @@ RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
21512151

21522152
// Ignore argument 1, the format string. It is not currently used.
21532153
CallArgList Args;
2154-
Args.add(RValue::get(BufAddr.emitRawPointer(*this)), Ctx.VoidPtrTy);
2154+
Args.add(RValue::get(getAsNaturalPointerTo(BufAddr, Ctx.VoidTy)),
2155+
Ctx.VoidPtrTy);
21552156

21562157
for (const auto &Item : Layout.Items) {
21572158
int Size = Item.getSizeByte();

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4135,8 +4135,8 @@ static bool isProvablyNull(llvm::Value *addr) {
41354135
}
41364136

41374137
static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
4138-
return llvm::isKnownNonZero(Addr.getUnsignedPointer(),
4139-
CGF.CGM.getDataLayout());
4138+
return !Addr.isSigned() && llvm::isKnownNonZero(Addr.getUnsignedPointer(),
4139+
CGF.CGM.getDataLayout());
41404140
}
41414141

41424142
/// Emit the actual writing-back of a writeback.
@@ -5101,7 +5101,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
51015101
llvm::Value *UnusedReturnSizePtr = nullptr;
51025102
if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
51035103
if (!ReturnValue.isNull()) {
5104-
SRetPtr = ReturnValue.getAddress();
5104+
SRetPtr = ReturnValue.getValue();
51055105
} else {
51065106
SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
51075107
if (HaveInsertPoint() && ReturnValue.isUnused()) {

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,8 @@ static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo,
13111311
if (CE->getCastKind() == CK_AddressSpaceConversion)
13121312
Addr = CGF.Builder.CreateAddrSpaceCast(
13131313
Addr, CGF.ConvertType(E->getType()), ElemTy);
1314-
return Addr;
1314+
return CGF.AuthPointerToPointerCast(Addr, CE->getSubExpr()->getType(),
1315+
CE->getType());
13151316
}
13161317
break;
13171318

@@ -1785,8 +1786,11 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
17851786
}
17861787

17871788
// Emit as a constant.
1788-
auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
1789-
result.Val, resultType);
1789+
// Try to emit as a constant.
1790+
llvm::Constant *C =
1791+
ConstantEmitter(*this).tryEmitAbstract(result.Val, resultType);
1792+
if (!C)
1793+
return ConstantEmission();
17901794

17911795
// Make sure we emit a debug reference to the global variable.
17921796
// This should probably fire even for

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ void AggExprEmitter::withReturnValueSlot(
330330
if (!UseTemp)
331331
return;
332332

333-
assert(Dest.isIgnored() || Dest.emitRawPointer(CGF) !=
334-
Src.getAggregatePointer(E->getType(), CGF));
333+
assert(Dest.getAddress().isSigned() || Dest.isIgnored() ||
334+
Dest.emitRawPointer(CGF) != Src.getAggregatePointer(E->getType(), CGF));
335335
EmitFinalDestCopy(E->getType(), Src);
336336

337337
if (!RequiresDestruction && LifetimeStartInst) {

0 commit comments

Comments
 (0)