Hello,the attached program changes the output from "true" to "false" when the -Bsymbolic / -Bsymbolic-functions options are passed to GCC. This happens on ARM -- on x86-64 output is always "true".
The program involves a comparison, within a shared library, of a PMF defined inside the shared library itself with the same PMF passed by the application.
At this stage I still don't know if it's a GCC problem, a ld.so problem, ABI constraints, undefined behaviour, or whatnot; but any help is appreciated.
Compile with:
g++ -fPIC -shared -Wall -o libshared.so -Wl,-Bsymbolic shared.cpp g++ -fPIE -Wall -o main main.cpp -L. -lshared
(The long story is that Qt 5 is taking PMFs in its public API, and the comparison failing inside of Qt shared libraries is breaking code on ARM, as -Bsymbolic is set by default there.)
Thanks, -- Giuseppe D'Angelo | giuseppe.dangelo@xxxxxxxx | Software Engineer KDAB (UK) Ltd., a KDAB Group company Tel. UK +44-1738-450410, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions
#include <iostream> #include "shared.h" struct T : S { T() { foo(); } }; bool magic(Spmf f) { return test(reinterpret_cast<void **>(&f)); } int main() { using namespace std; T t; cout << boolalpha << magic(&T::foo) << endl; }
#include "shared.h" #include <cstring> S::~S() {} void S::foo() {} void S::bar() {} static const Spmf spmfArray[] = { 0, &S::foo, 0 }; static const size_t spmfArraySize = sizeof(spmfArray) / sizeof(spmfArray[0]); bool test(void **f) { for (size_t i = 0; i < spmfArraySize; ++i) { if (spmfArray[i] == *reinterpret_cast<Spmf *>(f)) return true; } return false; }
#ifndef SHARED_H #define SHARED_H struct S { virtual ~S(); void foo(); void bar(); }; typedef void (S::*Spmf)(); bool test(void **f); #endif // SHARED_H
Attachment:
smime.p7s
Description: Firma crittografica S/MIME