2013-07-10 13 views
6

Sto tentando di utilizzare GCC’s abi::__cxa_demangle per demilirizzare i simboli esportati da un file oggetto prodotto da g++. Tuttavia, ho invariabili l'erroreAPI GCC non è in grado di separare i propri simboli esportati

mangled_name non è un nome valido ai sensi delle norme C++ ABI di mutilazione

Ecco come io chiamo la funzione:

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()}; 
} 

(Gestione degli errori omesso; è presente nel complete online demo.)

I simboli l'ho provato con sono ottenuti da questo piccolo codice:

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 

Io non sono davvero sicuro di quale scopo l'API di decodifica GCC serve se non può decodifica i questi simboli - è può, tuttavia , con successo demangolare le rappresentazioni C++ typeid. Per esempio. la scrittura nel codice di prova typeid(foo::bar<int>*).name() produrrà PN3foo3barIiEE, che a sua volta è correttamente distrutto dalla funzione precedente.

Sto facendo qualcosa di sbagliato? Come posso demag giare i simboli esportati da un file oggetto GCC?

+0

Se il file oggetto ha come target ARM, ad esempio, lo schema del nome mangling sarà diverso. Il fatto che sia stato creato da G ++ non garantisce uno schema di mangling dei nomi coerente. Tuttavia, quello che sto realmente vedendo è che quei simboli hanno uno troppi underscore in primo piano. Prova a tagliare quello anteriore. – Puppy

+0

@DeadMG Interessante, non lo sapevo, ma nel mio caso non è in realtà ARM. Tuttavia, questo potrebbe spiegarlo. Le domande rimangono: cosa si suppone che '__cxa_demangle' risolva, e come posso demangolare quei simboli. –

+0

Cosa stai "alimentando" nella funzione di demarcazione? –

risposta

3

I simboli presentano troppi caratteri di sottolineatura nella parte anteriore. Non sono sicuro del perché, ma se controlli lo C++filtjs, riporta la stessa cosa: non sono validi simboli Itanium ABI con due underscore in primo piano ma con uno solo. In questo caso, direi che l'output di nm non è corretto, non che la funzione di demangle è sbagliata. L'ABI Itanium specifica e so che Clang usa solo un trattino basso.

Sai, davvero dice qualcosa che posso quasi leggere i nomi storti di Itanium ABI ormai. Troppo tempo a leggere l'output IR di LLVM di Clang.