LLVM Генерация кода, вызывающая ошибку сегмента? - PullRequest
9 голосов
/ 09 августа 2010

Я заинтересован в создании языка и построении компилятора, и работал над примером здесь: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/. Автор использовал LLVM 2.6, и после внесения нескольких изменений в LLVM 2.7 я получил весь код генерация кода для компиляции. При подаче компилятору тестового кода,

int do_math( int a ) {
  int x = a * 5 + 3
}

do_math( 10 )

программа работает корректно до тех пор, пока не попытается запустить код, после чего она завершится ошибкой. Я нахожусь в процессе создания LLDB в моей системе, но тем временем кто-нибудь видит очевидную ошибку сегмента в этом ассемблере LLVM?

; ModuleID = 'main'

define internal void @main() {
entry:
  %0 = call i64 @do_math(i64 10)                  ; <i64> [#uses=0]
  ret void
}

define internal i64 @do_math(i64) {
entry:
  %a = alloca i64                                 ; <i64*> [#uses=1]
  %x = alloca i64                                 ; <i64*> [#uses=1]
  %1 = add i64 5, 3                               ; <i64> [#uses=1]
  %2 = load i64* %a                               ; <i64> [#uses=1]
  %3 = mul i64 %2, %1                             ; <i64> [#uses=1]
  store i64 %3, i64* %x
  ret void
}

Вывод просто:

Segmentation fault

Моя арка - OS X x86_64.

Спасибо.

Ответы [ 2 ]

16 голосов
/ 29 апреля 2011

У меня такая же проблема.Я разобрал компилятор Лорен, и все работало нормально, кроме выполнения.

Ошибка сегментации была вызвана тем, что:

ExecutionEngine * ee = EngineBuilder (module) .create ();

возвращает NULL.Чтобы увидеть фактическую ошибку, вам нужно получить строку ошибки:

std :: string error;ExecutionEngine * ee = EngineBuilder (модуль) .setErrorStr (& error) .create ();

В вашем случае вы должны увидеть:

"Невозможно найти цель дляэта тройка (цели не зарегистрированы)

Чтобы исправить это, вам нужно позвонить

InitializeNativeTarget ();

Но если вы получите:

JIT не был связан в.

Вы должны включить:

llvm / ExecutionEngine / MCJIT.h

, который свяжет двигатель JIT.

0 голосов
/ 10 августа 2010

LLVM ASM, который вы опубликовали, не является правильным переводом кода C, который вы представили. Вы выделяете %a как переменную стека, а затем загружаете из нее неинициализированные данные и используете их. То, что вы хотите сделать, это присвоить свой аргумент %a и использовать это значение. Попробуйте использовать этот код вместо:

define internal i64 @do_math(i64 %a) {
entry:
  %x = alloca i64                                 ; <i64*> [#uses=1]
  %1 = add i64 5, 3                               ; <i64> [#uses=1]
  %2 = mul i64 %a, %1                             ; <i64> [#uses=1]
  store i64 %2, i64* %x
  ret void
}

Кроме того, ваш main() прототип может не соответствовать ожиданиям вашей библиотеки времени выполнения C. Кроме того, вы понимаете, что не возвращаете результат из do_math(), верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...