Date: Tue, 23 Jan 2024 12:59:02 -0800
On Tuesday, 23 January 2024 08:55:20 PST Frederick Virchanza Gotham via Std-
Proposals wrote:
> Let's say that the type_info is stored in the ELF file inside the
> ."ro.data.rel" section, at offset 48 inside the section, and that its size
> is 72 bytes.
>
> Well, when the compiler is writing the type_info to the object file, it can
> append two things onto the end of it:
> First Thing: A predefined 128-Bit value (i.e. a UUID)
> Second Thing: The address of the vtable
>
> And so then the C++ function to get a vtable pointer from a type_info would
> be something like:
>
> void const *get_polymorphic_facilitator(type_info const &ti)
> {
> __uint128_t n;
> memcpy(&n, (char*)ti + 72u, 16u);
> if ( n != my_predefined_uuid ) return nullptr;
> void const *p;
> memcpy(&p, (char*)ti + 72u + 16u, sizeof(void*) );
> return p;
> }
>
> I don't think this would be an ABI break. Am I wrong?
So you're saying it should basically emit a larger structure with a magic up
front, where the type info is a sub-object. That way, it is possible to scan
backwards to find out if it part of such a sub-object and thus whether more
information is present.
Problems with this:
1) I still don't see why we should bother. There's no use-case for going from
the type_info to the vtable.
2) get_polymorphic_facilitator() can fail, as you've shown. That means the
functionality you build on top of it must also be allowed to fail, and I don't
think you want that.
3) there's a non-zero chance of false positive. It might be only 1 in 2^128
for random data (and read-only data is not random), but it's there.
4) scanning backwards can crash, if the pointer to the typeinfo happened to be
within 16 bytes of the start of its page. This can be mitigated by requiring
the larger object to be aligned to 32 bytes, so the typeinfo sub-object is
always aligned to 16 and mis-aligned on 32, therefore any typeinfo whose
address's bit 4 is not set or whose bits 2 or 3 are set is not an extended
typeinfo.
5) the typeinfo grows by 32 bytes (16 of the magic marker, 8 for the new
pointer and 8 of padding due to the alignment). A __vmi_class_type_info today
is a mere 8 bytes plus 2 pointers per base, so for the typical single-
inheritance hierarchy, the growth is 200%.
Proposals wrote:
> Let's say that the type_info is stored in the ELF file inside the
> ."ro.data.rel" section, at offset 48 inside the section, and that its size
> is 72 bytes.
>
> Well, when the compiler is writing the type_info to the object file, it can
> append two things onto the end of it:
> First Thing: A predefined 128-Bit value (i.e. a UUID)
> Second Thing: The address of the vtable
>
> And so then the C++ function to get a vtable pointer from a type_info would
> be something like:
>
> void const *get_polymorphic_facilitator(type_info const &ti)
> {
> __uint128_t n;
> memcpy(&n, (char*)ti + 72u, 16u);
> if ( n != my_predefined_uuid ) return nullptr;
> void const *p;
> memcpy(&p, (char*)ti + 72u + 16u, sizeof(void*) );
> return p;
> }
>
> I don't think this would be an ABI break. Am I wrong?
So you're saying it should basically emit a larger structure with a magic up
front, where the type info is a sub-object. That way, it is possible to scan
backwards to find out if it part of such a sub-object and thus whether more
information is present.
Problems with this:
1) I still don't see why we should bother. There's no use-case for going from
the type_info to the vtable.
2) get_polymorphic_facilitator() can fail, as you've shown. That means the
functionality you build on top of it must also be allowed to fail, and I don't
think you want that.
3) there's a non-zero chance of false positive. It might be only 1 in 2^128
for random data (and read-only data is not random), but it's there.
4) scanning backwards can crash, if the pointer to the typeinfo happened to be
within 16 bytes of the start of its page. This can be mitigated by requiring
the larger object to be aligned to 32 bytes, so the typeinfo sub-object is
always aligned to 16 and mis-aligned on 32, therefore any typeinfo whose
address's bit 4 is not set or whose bits 2 or 3 are set is not an extended
typeinfo.
5) the typeinfo grows by 32 bytes (16 of the magic marker, 8 for the new
pointer and 8 of padding due to the alignment). A __vmi_class_type_info today
is a mere 8 bytes plus 2 pointers per base, so for the typical single-
inheritance hierarchy, the growth is 200%.
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Software Architect - Intel DCAI Cloud Engineering
Received on 2024-01-23 20:59:05