Let's say I'm writing a C++ library which must export a variable, a data structure, called, for example, ExpData
. So, programs linked against my libray can access this variable (there is a public header defining it as extern void *ExpData[]
).
However, this data structure is internally the vtable of a C++ class. The class' name is, for example, InternalType
. So, after looking at the generated assembly code, I found out that InternalType
's vtable is exported as _ZTV12InternalType
.
Then, I need a way to make my library exported variable ExpData
be resolved with the same address than _ZTV12InternalType
, so that, when an external program reads my library's ExpData
variable, it is actually reading InternalType
's vtable.
Just to clarify, InternalType
's vtable assembly code is:
.type _ZTV12InternalType,@object # @_ZTV12InternalType
.section .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
.weak _ZTV12InternalType
.align 16
_ZTV12InternalType:
.quad 0
.quad _ZTI12InternalType
.quad _ZN12InternalType8vMethodXEi
.size _ZTV12InternalType, 24
So, I need a way to achieve this (or something else with the same effect):
.type ExpData,@object
.globl ExpData
.type _ZTV12InternalType,@object
.section .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
.weak _ZTV12InternalType
.align 16
_ZTV12InternalType:
ExpData:
.quad 0
.quad _ZTI12InternalType
.quad _ZN12InternalType8vMethodXEi
.size _ZTV12InternalType, 24
Is it possible in the C++ side?
P.S.: I know I shouldn't rely on implementation-dependent details, like name mangling and C++ classes internal data, but just consider my library is going to run on very specific environments.
EDIT
I could solve my problem by passing --defsym ExpData=_ZTV12InternalType
to the linker. However, I don't want to attach implementation details to external resources. Let's say I decide to map the class' vtable as a C structure called InternalTypeVTable
. So, I could declare ExpData
as InternalTypeVTable ExpData;
. It would be great if I had to change only the source file, not the makefiles and linker scripts.
GCC's __attribute__ ((alias()))
does exactly why I need.
If I declare ExpData
like :
void *ExpData[0] __attribute__ ((alias("_ZTV12InternalType")));
in my library's source file, I get the following assembly code:
.globl ExpData
ExpData = _ZTV12InternalType
So, the exported symbol ExpData
references the same memory address than _ZTV12InternalType
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With