MetadataAccessFunctionPtr Pointer Authentication Required?

I've recently been messing with an old thread of mine a while ago, Bitcast pointer to Swift function?, where I was having difficulties calling the metadata access function from Swift. After coming back to this it seems I had a silly mistake that was causing the @convention(thin) suggestion to not work, but in reality it works great! Given the title of this topic, I'm having an issue calling this function on arm64e where pointer authentication is enabled. I'm still a little new to pointer authentication and what is and isn't possible, but I think I'm doing something similar that the Swift runtime has below:

// shim.c

// 0xae86 == SpecialPointerAuthDiscriminator::TypeDescriptor
#define __ptrauth_swift_type_descriptor \
  __ptrauth(ptrauth_key_process_independent_data, 1, 0xae86)

typedef struct StructMetadata {
  size_t kind;
  const void * __ptrauth_swift_type_descriptor descriptor;
} StructMetadata;

// I have a shim function here because it doesn't seem like the ClangImporter imports
// structs with these ptrauth qualifiers.
const void *getStructDescriptor(const void *metadata) {
  const StructMetadata *structMetadata = (const StructMetadata *)metadata;
  return structMetadata->descriptor;
}
// someSwiftFile.swift
typealias Accessor0 = @convention(thin) (MetadataRequest) -> MetadataResponse

let intMetadata = ...
let accessor = unsafeBitCast(intMetadata.descriptor.accessor, to: Accessor0.self)
print(accessor(.complete).type) // crash

Obviously the Swift example isn't great because I already have the Int metadata, so calling the access function will return what I already have. From what it looks like the Swift runtime only has to use that ptrauth qualifier on the type descriptor and doesn't have to worry about ptrauth when it comes to calling the accessFunction, but maybe the runtime has special privileges? (Most likely I'm doing something wrong, but I don't know what).

Would love to hear what thoughts or suggestions you all might have. Thanks!

cc: @Joe_Groff @John_McCall

I'm not entirely sure what it is that you're trying to do/what the relevant IRGen code is, but one way to check if it's alright is inspect the top bits of the pointer. You can also check if your code is working fine on an Intel Mac or under Rosetta.

You're probably not signing the accessor function pointer in the accessor getter after resolving the relative reference.

Oh I see now. There's a specialization that was hiding in RelativePointer.h to sign for function pointers. Sorry bout the noise, nothing to see here :slightly_smiling_face:

Terms of Service

Privacy Policy

Cookie Policy