f.zz.de
posts /

c++ symbol mangling

Posted Sat Mar 18 12:05:06 2023 Florian Lohoff
in

Rebuilding Debian/Stretch for MIPSel with --march=mips2 caused some packages to fail with symbol changes. Which at first puzzled me a bit but i just built the packages with ignoring the symbols.

Now we are at the last 10% of packages and i thought to dig into this a bit deeper.

So i found that some symbols simply changed. They did not disappear but changes in some subtle issue that i did not understand. So i dug into dpkg-gensymbols and how it actually did the decoding - and - Oh boy ... i wish i had not have a look.

I saw the c++ symbols from binaries for at least 15 years and had no clue on what that actually was, but now it was time to find out. Basically the c++ compiler mangles the complete function/method declaration into the c++ symbol.

Consider you have this little c++ snippet:

#include <string>

typedef std::basic_string<char> bstring;

int bar(bstring& foo) {
    foo="baz";
}

If you compile this into a shared object the symbol for bar gets:

_Z3barRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

So how does one decode this, or how is this constructed? So c++filt comes to help to decode:

root@stretch:~# c++filt -n _Z3barRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
bar(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)

So you can decode the full symbol to the functions declaration.

Now - after staring at the Debian/Mipsel symbol issues i found something to be missing. Compiling the same test code, with the same compiler on Mipsel and on amd64 caused the __cxx11 to be dropped from the symbol on Mipsel. So i have a broken c++ compiler on Mipsel. I transitioned from Jessies gcc 4.9 to gcc 5.1.1-23 (Which had c++11) to gcc 6.1.1 to gcc 6.3.0 and now i am generating broken symbols. So some libstdc++ abi transition has failed.