In the implementation of C++ virtual methods, hidden function pointers will be generated by the C++ compiler (in the form of vtables). If you have a great C++ shared library design with no global variables, then all is fine; you do not need to worry about XFLAT-related issues.
Every instance of function pointer passed between shared modules must pass through a special layer of thunk code if the callee is going to successfully access global variables. XFLAT fixes up such function pointers for libc.so for things like signal handlers, atexit callback functions, etc. Every function address has to go through a custom, hand-made thunk layer. Fortunately, the C library does not use many function pointers -- there are only a handful in the entire libc API.
But as much as XFLAT is function-pointer-challenged, C++ is function-pointer-happy: Any C++ class is may be implemented with a vtable -- essentially an array of function pointers. For example:
class foo { public: virtual void bar(void) = 0; }
Then the following would not work (if foo::bar() references global variables) because there is no thunk for the foo::bar function pointer.
foo *pfoo = new foo; pfoo->bar();
But something like the following should work:
namespace shared { class foo { public: volatile void bar(void) = 0; }; }; class foo : shared::foo { private: void *m_pvPicAddress; public: foo(void) : m_pvPicAddress(get_pic_address()) {} // must execute in shared library void bar(void) { void *pvSavePicAddress = get_pic_address(); // must execute in main program set_pic_address(m_pvPicAddress); shared::foo::bar(); set_pic_address(pvSavePicAddress); } };
Where get_pic_address() and set_pic_address() are some processor-specific functions to get and set the PIC base register. The following should then work correctly
foo *pfoo = new foo; // PIC address is samples in constructor inside shared library pfoo->bar(); // PIC address of main program is saved in pvSavePicAddress
<<Index>>