8000 GEP is actually unsafe · Issue #33 · TheDan64/inkwell · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
GEP is actually unsafe #33
Open
Open
@Redrield

Description

@Redrield

In an attempt to get around #32, I've been trying to get a program working that can call printf with a string array. Looking at working IR, I see that to convert from an array to a pointer, an inbounds GEP instruction is used. This is the code I came up with to replicate that.

extern crate inkwell;
extern crate pest;

use inkwell::context::Context;
use inkwell::targets::{InitializationConfig, Target};
use inkwell::AddressSpace;
use inkwell::module::Linkage;
use inkwell::values::IntValue;

use std::path::Path;

fn main() {
    Target::initialize_native(&InitializationConfig::default()).unwrap();
    let ctx = Context::create();
    let module = ctx.create_module("program");
    let builder = ctx.create_builder();

    let str_type = ctx.i8_type().ptr_type(AddressSpace::Generic);
    let i32_type = ctx.i32_type();

    let my_message = "Hello, World!\n\0";
    let arr_type = ctx.i8_type().array_type(my_message.len() as u32);

    let mut chars = Vec::with_capacity(my_message.len());

    for ch in my_message.chars() {
        chars.push(ctx.i8_type().const_int(ch as u64, false));
    }

    let global = module.add_global(&arr_type, Some(AddressSpace::Generic), "message");
    let oof: Vec<&IntValue> = chars.iter().map(|x| x).collect();

    let str_array = arr_type.const_array(&oof[..]);

    global.set_initializer(&str_array);

    let printf_type = i32_type.fn_type(&[&str_type], true);
    let printf = module.add_function("printf", &printf_type, Some(&Linkage::ExternalLinkage));

    let main_fn_type = i32_type.fn_type(&[&i32_type, &str_type.ptr_type(AddressSpace::Generic)], false);

    let main_fn = module.add_function("main", &main_fn_type, None);
    let block = ctx.append_basic_block(&main_fn, "entry");
    builder.position_at_end(&block);

    let value = builder.build_in_bounds_gep(&global.as_pointer_value(), &oof[..], "");

    builder.build_call(&printf, &[&value], "", false);
    builder.build_return(Some(&i32_type.const_int(0, false)));

//    println!("{:?}", module.print_to_string());
    module.print_to_file(Path::new("test.ll"));
}

At the line where value is bound, the program exits with a SIGSEGV

Environment

Operating system: Arch Linux
Kernel version: 4.15.3-1-ARCH
LLVM version: 5.0.1-2
Inkwell version: 0.1.0#eafca272
rustc -vV output:

rustc 1.25.0-nightly (3ec5a99aa 2018-02-14)
binary: rustc
commit-hash: 3ec5a99aaa0084d97a9e845b34fdf03d1462c475
commit-date: 2018-02-14
host: x86_64-unknown-linux-gnu
release: 1.25.0-nightly
LLVM version: 6.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0