Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC API unable to demangle its own exported symbols

I’m trying to use GCC’s abi::__cxa_demangle to demangle symbols exported from an object file that was produced by g++. However, I invariable get the error

mangled_name is not a valid name under the C++ ABI mangling rules

Here’s how I call the function:

std::string demangled(std::string const& sym) {
    std::unique_ptr<char, void(*)(void*)>
        name{abi::__cxa_demangle(sym.c_str(), nullptr, nullptr, nullptr), std::free};
    return {name.get()};
}

(Error handling omitted; it’s present in the complete online demo.)

The symbols I tested it with are obtained from this small code:

namespace foo {
    template <typename T>
    struct bar { bar() { } };
}

void baz(int x) { }

template struct foo::bar<int>;

via g++ -c test.cpp; nm test.o | cut -d ' ' -f3:

EH_frame1
__Z3bazi
__ZN3foo3barIiEC1Ev
__ZN3foo3barIiEC2Ev

I’m not really sure which purpose the GCC demangling API serves if it cannot demangle these symbols – it can, however, successfully demangle the C++ typeid representations. E.g. writing in the test code typeid(foo::bar<int>*).name() will yield PN3foo3barIiEE, which in turn is correctly demangled by the above function.

Am I doing something wrong? How can I demangle the exported symbols from a GCC object file?

like image 544
Konrad Rudolph Avatar asked Jul 10 '13 14:07

Konrad Rudolph


1 Answers

Your symbols have one too many underscores in front. I'm not sure why, but if you check C++filtjs, it reports the same thing- they are not valid Itanium ABI symbols with two underscores in front but are with just one. In this case, I would say that the output of nm is incorrect, not that the demangle function is wrong. The Itanium ABI specifies and I know that Clang uses just one underscore.

Y'know, it really says something that I can almost read Itanium ABI mangled names by now. Way too much time reading Clang's LLVM IR output.

like image 121
Puppy Avatar answered Oct 13 '22 16:10

Puppy