Я пытаюсь создавать и выполнять модули LLVM. Мой код для создания модулей довольно длинный, поэтому я не буду публиковать его здесь. Вместо этого мой вопрос о том, как Clang и LLVM работают вместе, чтобы достичь наименования. Я объясню свой конкретный вопрос, чтобы мотивировать вопрос.
Вот исходный код одного из моих модулей LLVM:
#include <iostream>
int main() {
std::cout << "Hello, world. " << std::endl;
return 0;
}
Вот сгенерированный LLVM IR; он слишком велик для StackOverflow.
Когда я пытаюсь выполнить мой модуль с помощью lli
, я получаю следующую ошибку:
LLVM ERROR: программа использовала внешнюю функцию '__ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc', которая не может быть решена!
Запуск символа через деманглер, отсутствующий символ:
_std:: __ 1:: basic_string, std:: __ 1:: allocator > :: basic_string (unsigned long, char)
Дополнительный _
является подозрительным, и функция без главного подчеркивания, похоже, существует в IR!
; Function Attrs: alwaysinline ssp uwtable
define available_externally hidden void @_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc(%"class.std::__1::basic_string"*, i64, i8 signext) unnamed_addr #2 align 2 {
%4 = alloca %"class.std::__1::basic_string"*, align 8
%5 = alloca i64, align 8
%6 = alloca i8, align 1
store %"class.std::__1::basic_string"* %0, %"class.std::__1::basic_string"** %4, align 8
store i64 %1, i64* %5, align 8
store i8 %2, i8* %6, align 1
%7 = load %"class.std::__1::basic_string"*, %"class.std::__1::basic_string"** %4, align 8
%8 = load i64, i64* %5, align 8
%9 = load i8, i8* %6, align 1
call void @_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2Emc(%"class.std::__1::basic_string"* %7, i64 %8, i8 signext %9)
ret void
}
Я нахожусь на macOS, поэтому следует ожидать главного подчеркивания, но я думаю, что Clang мог бы добавить его дважды.
Я просмотрел источник LLVM/Clang, и кажется, что есть два шага:
- Взяв возможно перегруженные функции С++ и переведя их в уникальные имена для LLVM IR
- Взятие измененного имени из LLVM IR и добавление каких-либо специфических особенностей платформы, например, подчеркивание
Однако это только моя теория. Может ли кто-нибудь объяснить, как работает процесс манипуляции в Clang и LLVM? Как мне создать объекты llvm::DataLayout
, чтобы получить правильное управление для моей платформы?
nm -gU /usr/lib/libc++.dylib
и nm -gU /usr/lib/libc++abi.dylib
не содержат __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1Emc
Когда я пытаюсь скомпилировать IR, я получаю эту ошибку:
llc generated.ll
clang++ generated.s
Undefined символы для архитектуры x86_64: "std:: __ 1:: basic_string, std:: __ 1:: allocator > :: data() const", на который ссылаются: std:: __ 1:: ostreambuf_iterator > std:: __ 1:: __ pad_and_output > (std:: __ 1:: ostreambuf_iterator > , char const *, char const *, char const *, std:: __ 1:: ios_base &, char) в сгенерированном-b4252a.o "std:: __ 1:: basic_ostream > :: sentry:: operator bool() const", на который ссылаются: std:: __ 1:: basic_ostream > & std:: __ 1:: __ put_character_sequence > (std:: __ 1:: basic_ostream > &, char const *, unsigned long) в сгенерированном-b4252a.o "std:: __ 1:: basic_ios > :: fill() const", на который ссылаются: std:: __ 1:: basic_ostream > & std:: __ 1:: __ put_character_sequence > (std:: __ 1:: basic_ostream > &, char const *, unsigned long) в сгенерированном-b4252a.o "std:: __ 1:: basic_ios > :: rdbuf() const", на который ссылаются: std:: __ 1:: ostreambuf_iterator > :: ostreambuf_iterator (std:: __ 1:: basic_ostream > &) в сгенерированном-b4252a.o "std:: __ 1:: basic_ios > :: widen (char) const", на который ссылаются: std:: __ 1:: basic_ostream > & std:: __ 1:: endl > (std:: __ 1:: basic_ostream > &) в сгенерированном-b4252a.o "std:: __ 1:: basic_string, std:: __ 1:: allocator > :: basic_string (unsigned long, char)", на который ссылаются: std:: __ 1:: ostreambuf_iterator > std:: __ 1:: __ pad_and_output > (std:: __ 1:: ostreambuf_iterator > , char const *, char const *, char const *, std:: __ 1:: ios_base &, char) в сгенерированном-b4252a.o "std:: __ 1:: basic_ios > :: setstate (unsigned int)", на который ссылаются: std:: __ 1:: basic_ostream > & std:: __ 1:: __ put_character_sequence > (std:: __ 1:: basic_ostream > &, char const *, unsigned long) в сгенерированном-b4252a.o ld: символ (-ы) не найден для архитектуры x86_64 clang-3.9: ошибка: команда компоновщика завершилась с кодом выхода 1 (используйте -v для вызова вызова)