rust llvm lli

LLVM producido por rustc da error sobre el tipo de argumento de main cuando se ejecuta con lli



(1)

Estoy tratando de aprender un poco sobre el IR de LLVM, particularmente qué resultados exactamente rustc. Estoy teniendo problemas para ejecutar incluso un caso muy simple.

Puse lo siguiente en un archivo fuente simple.rs :

fn main() { let x = 7u32; let y = x + 2; }

y ejecuta rustc --emit llvm-ir simple.rs para obtener el archivo simple.ll , que contiene

; ModuleID = ''simple.cgu-0.rs'' source_filename = "simple.cgu-0.rs" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: uwtable define internal void @_ZN6simple4main17h8ac50d7470339b75E() unnamed_addr #0 { start: br label %bb1 bb1: ; preds = %start ret void } define i64 @main(i64, i8**) unnamed_addr { top: %2 = call i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void ()* @_ZN6simple4main17h8ac50d7470339b75E, i64 %0, i8** %1) ret i64 %2 } declare i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void ()*, i64, i8**) unnamed_addr attributes #0 = { uwtable } !llvm.module.flags = !{!0} !0 = !{i32 1, !"PIE Level", i32 2}

Luego trato de ejecutar esto con el comando

lli-3.9 -load ~/.multirust/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.so simple.ll

pero recibo el mensaje de error

LLVM ERROR: Invalid type for first argument of main() supplied

Puedo hacer una reproducción mínima de esto de la siguiente manera: hago un archivo llamado s2.ll , que contiene

define i32 @main(i64, i8**) { ret i32 42 }

y ejecutar lli-3.9 s2.ll da el mismo mensaje de error. Pero si cambio los contenidos de s2.ll a

define i32 @main(i32, i8**) { ret i32 42 }

(es decir, he cambiado el tipo de argc en main), luego lli-3.9 s2.ll ejecuta y echo $? revela que efectivamente regresó 42 .

No creo que deba pasar el i64 explícita: mi lista de argumentos o las cadenas C deben ponerse en la memoria en algún lugar y el puntero y la longitud pasarán a la main automáticamente, ¿verdad? Por lo tanto, supongo que estoy haciendo algo mal en el camino para invocar a lli , pero no tengo ni idea de qué.


Rust marca su punto de entrada (la función marcada con #[start] atributo #[start] , por defecto la función lang_start en la biblioteca estándar) como tomar un parámetro argc de tipo isize . Este es un error porque debería tener el tipo de C int, por lo que debería ser de 32 bits en una plataforma de 64 bits, pero isize es de 64 bits. Sin embargo, debido a la forma en que funcionan las convenciones de llamadas de 64 bits, esto todavía funciona correctamente. El mismo problema también existe para el tipo de devolución.

Se ha confirmado una solución para esto en 2017-10-01 y debería estar presente en Rust 1.22.

lli es aparentemente más estricto al verificar el tipo de main razón por la cual da el error. Pero si usa llc lugar, debería funcionar correctamente.

Para obtener la firma main correcta, puede cancelar la main predeterminada colocando #![no_main] en la parte superior del módulo, y proporcione su propia marca main con #[no_mangle] . Pero tenga en cuenta que esto omitirá la inicialización de la biblioteca estándar.

#![no_main] #[no_mangle] pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 { 0 }

Ver también: