<div dir="ltr"><div dir="ltr">On Tue, Dec 8, 2020 at 4:31 AM Tim Northover via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">To put signed pointers into global initializers (e.g. vtables) and other<br>
desirable features there needs to be a Constant that represents "sign this<br>
pointer in such and such way". I propose adding a new child of Constant,<br>
ConstantPtrAuth to represent this:<br>
<br>
    @var = global i32* ptrauth(i32* @something, ; Pointer to be signed<br>
                               i32 0,           ; Key to use for the signature<br>
                               i32* @var,       ; Address<br>
discriminator, null if none<br>
                               i16 1234)        ; Discriminator<br>
<br>
Anyone who has looked at the Xcode compiler output for arm64e will recognise<br>
this as a pretty close analogue of the pseudo-Global that it emits<br>
currently.<br>
<br>
That was always intended to be a placeholder while the code was internal so that<br>
we didn't introduce bitcode incompatibility with OSS. Now that arm64e is being<br>
upstreamed, it's a good time to fix what was always really a ConstantExpr<br>
pretending to be a global.<br>
<br>
The fields specified were chosen to broadly match the features and relocations<br>
available in arm64e MachO files: a 16-bit discriminator, possibly address<br>
discriminated too.<br>
<br>
I've posted the initial patch on Phabricator at<br>
<a href="https://reviews.llvm.org/D92834" rel="noreferrer" target="_blank">https://reviews.llvm.org/D92834</a>. I've anticipated some<br>
questions and done my best to respond below. What else occurs to people?<br></blockquote><div><br></div><div>Could we make the discriminator a 64-bit field? For non-address-discriminated pointers it is possible to materialize the discriminator in a single instruction with almost 19 bits of entropy by making use of bit 30 (i.e. the selection between MOVN and MOVZ) and the HW bits. And I suppose that multi-instruction materialization of the discriminator is also possible (although it may not be practical to fit all of the bits into common object formats).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
Shouldn't this be a ConstantExpr?<br>
---------------------------------<br>
<br>
There is one key interface for ConstantExpr we cannot currently support:<br>
getAsInstruction. When an address discriminator is present, the ptrauth constant<br>
represents an @llvm.ptrauth.blend followed by an @llvm.ptrauth.sign, two<br>
separate instructions.<br>
<br>
Because of that I've so far implemented it as its own separate entity in the<br>
Constant hierarchy (kind of like blockaddress).<br>
<br>
It might well be better to give up on intrinsic orthogonality and add one for<br>
this case though. It would simplify the changes to lib/IR etc.<br></blockquote><div><br></div><div>I mildly prefer keeping it as a Constant and not a ConstantExpr if we don't realistically expect this to be converted between constant and non-constant operands. That's similar to what we did for DSOLocalEquivalent for example. But I think I'd be fine either way.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Shouldn't the key be i2 or something?<br>
-------------------------------------<br>
<br>
Possibly. That has legality implications in CodeGen though and is really not a<br>
commonly used part of LLVM (there's currently no llvm_i2_ty in<br>
Intrinsics.td). i32 generally signals "don't care".<br></blockquote><div><br></div><div>It seems like it should be wider than i2 at least. There is also the GA key which I suppose it's conceivable that someone may want to use. And making it an i32 would easily allow future expansion, e.g. if more keys are added in the future, without requiring a bitcode upgrade path.</div><div><br></div><div>Peter</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Why is the address discriminator not just a bool?<br>
-------------------------------------------------<br>
<br>
The relocations in MachO only allow you to use the address being relocated as<br>
the address-discriminator, so at first sight it seems excessive to have an<br>
entire pointer field that has only one legitimate value anyway when an i1 would<br>
suffice.<br>
<br>
However, transformations like constant propagation can separate these<br>
ptrauth(...) constants from their storage location, at which point CodeGen would<br>
have no idea what address to use. So the field does need to be the actual<br>
address.<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr">-- <div>Peter</div></div></div></div>