The need for name mangeling arises because the name of a symbol in a file is very restricted. It can not contain spaces, brackets or columns, for example. With name mangling, the linker is able to distinguish overloaded functions in C++ like
int bla();
int bla(double);
The wikipedia article and this describe name mangling quite well.You'll see a lot of mangled names when you try
nm someexecutable
So I created a small C++ program demangles the names. Save below code in a file named mydemangle.cpp, and compile it with
g++ -o mydemangle mydemangle.cpp
Now you can try it with
mydemangle _ZN9wikipedia7article6formatEv
and the result iswikipedia::article::format()
But demangle can do more: It can read input from stdin. So you might try
nm someexecutable | mydemangle
Now mydemangle demangles all names it can demangle and leaves the rest as it is.
There's a quite handy way in C++ to demangle names via the function
char * __cxa_demangle (const char *mangled_name, char *output_buffer, size_t *length, int *status);
Be aware that this will not be available for all processors/compilers.
Here's the code:
mydemangle.cpp
#include <iostream> #include <cxxabi.h> #include <stdlib.h> #include <string> #include <stdio.h> using namespace std; int main(int argc, char *argv[]) { int status; if(argc == 2) { // we have one argument: demangle it char *realname = abi::__cxa_demangle(argv[1], 0, 0, &status); if(status==0) cout << "\n" << realname << "\n"; else cout << "\ncould not demangle " << argv[1] << "\n"; free(realname); } else { // we have no argument: read from stdin char c, lastc=0x00; string s; while((c = getchar()) != EOF) { // mangled names start with _ . consider only if last sign was space or tab or newline if(c == '_' && (lastc==' ' || lastc == '\n' || lastc == '\t')) { s = "_"; // add all characters to the string until space, tab or newline while((c = getchar()) != EOF) { if(c == ' ' || c == '\n' || c == '\t') break; s += c; } // some compilers add an additional _ in front. skip it. const char *p = s.c_str(); if(s.length() > 2 && s[1] == '_') p = p+1; char *realname = abi::__cxa_demangle(p, 0, 0, &status); if(status==0) cout << realname; // demangle successfull else cout<< s; // demangling failed, print normal string free(realname); } cout << c; lastc =c; } } return 0; }
Of course, there is some easy way in bash to do it. This requires demangle (part of KDE Dev Kit) and is not as fast and convenient as above method.
case #!/bin/bash while read LINE do for WORD in $LINE do echo -n $WORD | demangle done echo done
No comments:
Post a Comment