2013-07-10 5 views
6

Próbuję użyć GCC’s abi::__cxa_demangle do zniekształcenia symboli wyeksportowanych z pliku obiektu, który został wyprodukowany przez g++. Ja jednak niezmienne pojawia się błądInterfejs API GCC nie jest w stanie rozdzielić własnych eksportowanych symboli.

mangled_name nie jest poprawną nazwą zgodnie z zasadami C++ ABI maglowania

Oto jak wywołać funkcję:

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

(obsługa błędów pominięty, jest obecny w complete online demo.)

Symbole, które testowałem z uzyskuje się z tego małego kodu:

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

void baz(int x) { } 

template struct foo::bar<int>; 

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

EH_frame1 
__Z3bazi 
__ZN3foo3barIiEC1Ev 
__ZN3foo3barIiEC2Ev 

Nie jestem pewien, które Cel demangling API GCC służy, jeśli nie może demangle tych symboli - to może jednak , udało się zdemontować reprezentacje C++ typeid. Na przykład. zapisanie w kodzie testowym typeid(foo::bar<int>*).name() przyniesie PN3foo3barIiEE, co z kolei jest poprawnie zniekształcone przez powyższą funkcję.

Czy robię coś nie tak? Jak mogę zminimalizować eksportowane symbole z pliku obiektów GCC?

+0

Jeśli plik obiektowy jest skierowany na ARM, powiedzmy, że schemat wymazywania nazw będzie się różnić. Fakt, że został stworzony przez G ++, nie gwarantuje spójnego schematu mangowania nazw. Jednak tak naprawdę widzę, że te symbole mają z przodu zbyt wiele podkreśleń. Spróbuj wyciąć przednią. – Puppy

+0

@DeadMG Ciekawe, nie wiedziałem o tym, ale w moim przypadku nie jest to w rzeczywistości ARM. Mimo to może to wyjaśnić. Pozostają pytania: co ma rozwiązać '__cxa_demangle' i w jaki sposób rozplątać te symbole. –

+0

Dokładnie to, co "karmisz" w funkcji demangle? –

Odpowiedz

3

Twoje symbole mają przed sobą zbyt wiele podkreśleń. Nie jestem pewien dlaczego, ale jeśli sprawdzasz C++filtjs, zgłasza to samo - nie są one prawidłowymi symbolami Itanium ABI z dwoma podkreśleniami z przodu, ale są z jednym. W tym przypadku chciałbym powiedzieć, że wynik nm jest niepoprawny, a funkcja demangle nie jest poprawna. The Itanium ABI określa i wiem, że Clang używa tylko jednego podkreślenia.

Wiecie, to naprawdę mówi coś, co już prawie potrafię odczytać Itanium ABI. Zbyt dużo czasu na czytanie wyjścia LLVM IR Clanga.

Powiązane problemy