C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Standard support for different ABI's for class vtables

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 5 Jun 2025 21:27:09 -0400
On Thu, Jun 5, 2025 at 8:50 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On Tue, Jun 3, 2025 at 12:29 PM Oliver Hunt wrote:
> >>
> >>
> > > (1) Get the vtable pointer from the object, conveniently always located at [base + 0x00]
> > > (2) Dereference the vtable pointer and substract 16 to yield the address of the "distance
> > > to most derived" offset.
> >
> > And this faults immediately because you failed to authenticate the load, and so the load is invalid.
> >
> > > (3) Add the offset to the address of the sub-object.
> >
> > You don’t get this far.
>
>
> I gave up trying to run Qemu in user mode on an x86_64 macOS computer
> to run an arm64 macOS executable.
>
> So I'm using the Github Actions runner, 'macos-15', to build and run
> my test program.
>
> Here's the code I've got up on GitHub:
>
> https://github.com/healytpk/polyhandle/blob/main/research_machine_code.cpp
>
> It fails to link. I have identified the compiler option that's causing
> the problem, it's "-fptrauth-calls". If I use this compiler option
> then I get linker relocation errors about 'std::type_info' as follows:
>
> ld: relocation at '__ZTV4Frog'+0x0018 is not supported:
> r_address=0x48, r_type=11, r_extern=1, r_pcrel=0, r_length=3 in
> research_machine_code.o'
> clang++: error: linker command failed with exit code 1 (use -v to
> see invocation)
>
> Note that '__ZTV4Frog' is the mangled name for the 'std::type_info'
> for the 'Frog' class.
>
> Note that I still get these errors even if I use "-fno-rtti". I've
> been searching the web and asking AI but I can't get this code to
> compile.
>
> I'm confident that I can figure out getting 'polyhandle' to work on
> new Apple computers with pointer authentication, but first I need to
> figure out why "-fptrauth-calls" is giving linker errors.
>
> Here's my end game which I think might work:
>
> A pointer on arm64 is 64-Bit, however on arm64 you can only
> address 256 terrabytes of memory. So only 49 of those bits are needed
> for a memory address. That leaves 15 bits to play around with. Plus,
> since we know that any polymorphic object begins with a vtable
> pointer, this means that alignof(any polymorphic class) >= 8. This
> means that we can play around also with the lowest 3 bits because
> they'll always be zero. So in total we have 18 bits we can manipulate
> for our own purposes. The secret number needed to decode the vtable is
> only 16 bits. So I'll put that 16-bit secret number + 46 bits memory
> address into a " void * ". And I'll still have two bits left over to
> play around with.
>
> I'm not absolutely certain that the above paragraph will work -- but
> even if it doesn't, I've got two other strategies in mind. I _will_
> get 'polyhandle' working on pointer authenticated systems, one way or
> another. The above paragraph would be ideal though.

But if it's not a `void*`, then... what's the point? It's just an
arbitrary object, created from a known type, which you can unpack into
that type or a type derived from it.

You can already accomplish that by using `base_class*`, where
`base_class` is the lowest inherited base class with a virtual
function in that class hierarchy. So how are you in a situation where:

1. You have a "pointer" to something that you don't know exactly what it is,
2. You know what you've been given is in an inheritance graph of some
known type, and
3. You couldn't receive a pointer to a known base class in that
inheritance graph?

How exactly does that circumstance happen and why is that so common
that we need a specialized type to deal with it?

Received on 2025-06-06 01:27:21