Подтвердить что ты не робот

Что такое утилита Linux, чтобы кастовать имя символа С++?

У меня есть команда c++filt для демонстрации символа, что является инструментом для выполнения противоположного и калечения имени символа?

Это было бы полезно, если бы я захотел вызвать dlsym() на измененное имя функции С++. Я бы предпочел не жестко кодировать имя в коде, поскольку он может меняться со временем из-за новых версий компилятора или новых брендов компилятора, которые используются или в настоящее время из-за компиляции для нескольких платформ.

Есть ли программный способ получить строку, которая представляет собой функцию С++ во время выполнения, чтобы код был независимым от компилятора? Один из способов сделать это - вызвать утилиту во время компиляции, которая выполняет манипуляцию имени для используемого компилятора и вставляет соответствующее закодированное имя символа С++ в строку для dlsym() для использования.

Вот наиболее близкое к решению, которое я нашел на этом сайте, которое выполняется с использованием фиксированного имени стиля C для косвенных символов С++, которые определены в библиотеку, которую вы хотите dlsym(), но если у вас нет контроля над тем, что предоставляет эта библиотека, это не вариант.

4b9b3361

Ответ 1

Вы можете получить то, что хотите, взглянув на таблицу символов из .so вы смотрите: кто-то еще ответил на это уже Возврат таблицы символов разделяемой библиотеки.

Однако, если слишком много символов... это может не сработать.
Так вот сумасшедшая идея. Предостережение emptor!

Потенциальное решение состоит в следующем:

  • создайте файл с заглушкой с одним именем: имя, которое вы хотите: void myfunction() {}

  • скомпилируйте этот файл (с -fPIC и -shared, так что это динамическая библиотека)

  • вызов dlopen/dlsym в этом конкретном файле

  • Итерации по символам (там должен быть только один желаемый плюс другой обычный нежелательный фильтр, который вы можете фильтровать). Итерация через символы неуклюжая, но вы можете это сделать:  Возврат таблицы символов общедоступной библиотеки

  • dlclose(), чтобы освободить его (потерять заглушку из ваших символов)

  • Откройте файл, который вы хотите, с помощью dlopen

В принципе, вы должны вызывать компилятор из вашего кода, он будет создавать .so вы могли бы посмотреть, получить единственное значение, а затем выгрузить это .so так что вы можете загрузить в тот, который вам нужен.

Это безумие.

Ответ 2

То, как g++ управляет именами. Вы можете реализовать эти правила в своей программе.

Другим (сумасшедшим) решением было бы перечислить все символы в библиотеке, которую вы хотите использовать (это не так сложно, если вы понимаете формат), разберите их все и выполните поиск имени своей функции в этом списке. Преимущество этого метода заключается в том, что деманлинг проще, так как есть вызов функции: abi::__cxa_demangle, из заголовка cxxabi.h.

Ответ 3

Назначение имени является специфичным для реализации.

Нет никакого стандарта для сортировки имени, поэтому лучше всего найти компилятор, чтобы сделать это за вас.

Название mangling

Здесь есть таблица, которая может помочь вам, если вы хотите сделать это вручную

Ответ 4

Более простой метод, чем первый. Напишите небольшую программу на С++, например:

#include <stdlib.h>

extern int doit(const char *toto, bool is);

int main(int argc, char *argv[])
{
  exit(doit (argv[0], true));
}

Постройте его с помощью

# g++ -S test.cpp

И извлечение имени символа из источника ассемблера

# cat test.s | grep call | grep doit | awk '{print $2}'

Вы получаете:

[email protected]:/tmp/TestC++$ cat test.s | grep call | grep doit | awk '{print $2}'
_Z4doitPKcb
[email protected]:/tmp/TestC++$ 

Символ doit mangled is _Z4doitPKcb Используйте компилятор, который вы планируете использовать, потому что у каждого компилятора есть свои правила управления именами (как это было сказано ранее от одного компилятора к другому, эти правила могут меняться).

Удачи!