I don't think that fvisibility=hidden on its own is sufficient, it does not allow the compiler to break the call abi as the function could still be called from another .o (which will only know the mangled name of the original function). You need fvisibility=internal (or maybe fno-semantic-interposition but I'm not sure if it's enough).