Clang-3.8 undefined ссылка на `main 'при компиляции объектного файла из байт-кода llvm с глобальными переменными

Я пытаюсь реализовать вложенные функции в llvm через C ++ API. После того, как я выполняю семантическую проверку (чтобы убедиться, что программа, которая будет скомпилирована, имеет правильные ссылки на вложение и т. Д.), Я определяю все функции в той же области в llvm и устанавливаю все переменные как глобальные. Я ожидал, что это сработает, но у меня возникла огромная проблема при получении исполняемого файла из файла .o с помощью команды:

"llvm-as-3.8 output.ll| llc-3.8 -filetype=obj | clang-3.8 ../library/library.a  -v -o out"

Используя связь llvm::GlobalValue::WeakAnyLinkage или llvm::GlobalValue::ExternalLinkage для глобальных переменных, я получаю:

/ usr / bin / ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): перемещение 0 имеет недопустимый индекс символа 11

/ usr / bin / ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): перемещение 1 имеет недопустимый индекс символа 12

/ usr / bin / ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): перемещение 8 имеет недопустимый индекс символа 12

...

/ usr / bin / ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): перемещение 0 имеет недопустимый индекс символа 2

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: В функции `_start ':

(.text + 0x20): неопределенная ссылка на `main '

Что, похоже, связано с определением main, который в определении моего кода ir стоит как:

; Function Attrs: nounwind uwtable define void @main() #0 {

Дело в том, что у той же команды не было никаких проблем, когда я не использовал глобальные переменные, за исключением, конечно, случая, когда переменная использовалась в дочерней функции, что было причиной, по которой я попытался изменить alloca на глобальную.

Помогите найти решение этой проблемы. Заранее спасибо. Примечание 1: я использую llvm-3.8

ОБНОВЛЕНИЕ: когда я удалил -v из команды clang, результат был:

refined_output.o: В функции bsort': refined_output.ll:(.text+0x4): undefined reference tox 'refined_output.ll :(. text + 0xa): неопределенная ссылка на n' refined_output.ll:(.text+0x10): undefined reference tochanged' refined_output.ll :(. text + 0x22): неопределенная ссылка на i' refined_output.ll:(.text+0x2c): undefined reference tochanged 'refined_output.ll :(. text + 0x42) : undefined ссылка на i' refined_output.ll:(.text+0x48): undefined reference ton 'refined_output.ll :(. text + 0x50): undefined ссылка на i' refined_output.ll:(.text+0x59): undefined reference tox' refined_output.ll :(. text + 0x60): неопределенная ссылка на i' refined_output.ll:(.text+0x75): undefined reference tox 'refined_output.ll :(. text + 0x7c): undefined ссылка на i' refined_output.ll:(.text+0x95): undefined reference tochanged 'refined_output.ll :(. text + 0xa3): undefined ссылка на changed' refined_output.o: In functionswap': refined_output.ll :(. text + 0xc3): неопределенная ссылка на x.1' refined_output.ll:(.text+0xca): undefined reference toy 'refined_output.ll :(. text + 0xd1): неопределенная ссылка to x.1' refined_output.ll:(.text+0xd9): undefined reference tot 'refined_output.ll :(. text + 0xe0): неопределенная ссылка на x.1' refined_output.ll:(.text+0xe7): undefined reference toy' refined_output.ll :(. text + 0xf2): неопределенная ссылка на y' refined_output.ll:(.text+0xf8): undefined reference tot 'refined_output.o: в функции main': refined_output.ll:(.text+0x102): undefined reference toi.4' refined_output.ll :( .text + 0x10c): неопределенная ссылка на seed' refined_output.ll:(.text+0x123): undefined reference tox.2 'refined_output.ll :(. text + 0x12a): неопределенная ссылка на i.4' refined_output.ll:(.text+0x130): undefined reference toseed' refined_output.ll :(. text + 0x15d): неопределенная ссылка на seed' refined_output.ll:(.text+0x166): undefined reference toi.4 ' refined_output.ll :(. text + 0x16c): неопределенная ссылка на i.4' refined_output.ll:(.text+0x177): undefined reference tox.2 'refined_output.ll :(. text + 0x18d): неопределенная ссылка на x.2' refined_output.ll:(.text+0x19e): undefined reference tox.2' refined_output.o: в функции printArray': refined_output.ll:(.text+0x1c4): undefined reference tomsg 'refined_output.ll :(. text + 0x1cb): неопределенная ссылка на x.2' refined_output.ll:(.text+0x1d1): undefined reference ton.3 'refined_output.ll :(. text + 0x1d8): неопределенная ссылка на msg' refined_output.ll:(.text+0x1e3): undefined reference toi.4' refined_output.ll :(. text + 0x1f3): неопределенная ссылка на x.2' refined_output.ll:(.text+0x1fa): undefined reference toi.4 'refined_output. ll :(. text + 0x208): неопределенная ссылка на i.4' refined_output.ll:(.text+0x20e): undefined reference toi.4 'refined_output.ll :(. text + 0x214): неопределенная ссылка на n.3' refined_output.ll:(.text+0x21c): undefined reference toi.4'

clang: error: команда компоновщика завершилась неудачно с кодом выхода 1 (используйте -v, чтобы увидеть вызов)

Все эти переменные были определены в начале моей программы в llvm IR как:

@x = external global i32*
@n = external global i32
@i = external global i32
@changed = external global i1
@x.1 = external global i32*
@y = external global i32*
@t = external global i32
@msg = external global i8*
@x.2 = external global i32*
@n.3 = external global i32
@i.4 = external global i32
@const_string_temp = private constant [3 x i8] c", \00", align 1
@const_string_temp.5 = private constant [2 x i8] c"\0A\00", align 1
@i.6 = external global i32
@x.7 = external global i32
@seed = external global i32
@const_string_temp.8 = private constant [16 x i8] c"Initial array: \00", align 1
@const_string_temp.9 = private constant [15 x i8] c"Sorted array: \00", align 1

Я надеюсь, что это поможет мне, иначе я найду проблему в моей генерации кода IR.

Я с нетерпением жду этого ..


person John Sig    schedule 26.08.2016    source источник
comment
пустая функция? Вы уверены?   -  person kfsone    schedule 26.08.2016
comment
Изменение его на int main () ничего не меняет.   -  person John Sig    schedule 27.08.2016


Ответы (1)


@x = external global i32*

и так далее - это объявления глобальных переменных, а не определения. Следовательно, ошибка «неопределенная ссылка» допустима, и вам действительно нужно их определить.

См. http://llvm.org/docs/LangRef.html#global-variables для получения дополнительной информации

Также обратите внимание, что часть llvm-as / llc является избыточной - clang может отлично компилировать файлы .ll / .bc.

person Anton Korobeynikov    schedule 28.08.2016
comment
Должен ли я делать это в каждой функции, которая использует переменную или хотя бы одну (например, первую, которая предназначена для ее использования)? Во-вторых, можете ли вы указать некоторые вызовы API C ++, с помощью которых я могу успешно сделать определение? Заранее спасибо! - person John Sig; 29.08.2016
comment
Задача решена! Решение состоит в том, чтобы установить инициализатор в каждой глобальной переменной с помощью вызова API-интерфейса c ++ gvar- ›setInitializer (). Чтобы узнать, как это сделать правильно, вы можете использовать clang следующим образом: clang-3.8 -c -emit-llvm input.cpp -o input.ll и после этого llc-3.8 -march = cpp -o output.ll.cpp input. лл. Каждый раз напишите нужную глобальную переменную, как в c ++, и посмотрите, с какими вызовами api c ++ она связана для каждого типа переменной. - person John Sig; 30.08.2016