0

I have the following code:

@.str_specifier = constant [4 x i8] c"%s\0A\00"
@.int_specifier = constant [4 x i8] c"%d\0A\00"
@.string_var1 = constant [2 x i8] c"f\00"
@.string_var2 = constant [6 x i8] c"Error\00"

;    >>> Start Program
declare i32 @printf(i8*, ...)
declare void @exit(i32)
define void @print(i8*) {
    call i32 (i8*, ...) @printf(i8* getelementptr ([4 x i8], [4 x i8]* @.str_specifier, i32 0, i32 0), i8* %0)
    ret void
}
define void @printi(i32) {
    call i32 (i8*, ...) @printf(i8* getelementptr ([4 x i8], [4 x i8]* @.int_specifier, i32 0, i32 0), i32 %0)
    ret void
}
declare i8* @malloc(i32)
declare void @free(i8*)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)


define void @main()
{   ; >>> Adding function scope
    %funcArgs1 = alloca [50 x i32]

    ; >>> Adding function arguments allocation

    ; >>> Function body of main
    call void @print(i8* getelementptr ([2 x i8], [2 x i8]* @.string_var1, i32 0, i32 0))
    %register1 = call i8* @malloc(i32 48)
    %register2 = bitcast i8* %register1 to i32*
    %register3 = getelementptr inbounds [50 x i32], [50 x i32]* %funcArgs1, i32 0, i32 0
    %register4 = ptrtoint i32* %register2 to i32
    store i32 %register4, i32* %register3
    %register5 = getelementptr inbounds i32, i32* %register2, i32 0
    %register6 = add i32 0, 12
    store i32 %register6, i32* %register5
    %register7 = getelementptr inbounds i32, i32* %register2, i32 1
    %register8 = add i32 0, 2
    store i32 %register8, i32* %register7
    %register9 = getelementptr inbounds i32, i32* %register2, i32 2
    store i32 0, i32* %register9
    %register10 = getelementptr inbounds i32, i32* %register2, i32 3
    store i32 0, i32* %register10
    %register11 = getelementptr inbounds i32, i32* %register2, i32 4
    store i32 0, i32* %register11
    %register12 = getelementptr inbounds i32, i32* %register2, i32 5
    store i32 0, i32* %register12
    %register13 = getelementptr inbounds i32, i32* %register2, i32 6
    store i32 0, i32* %register13
    %register14 = getelementptr inbounds i32, i32* %register2, i32 7
    store i32 0, i32* %register14
    %register15 = getelementptr inbounds i32, i32* %register2, i32 8
    store i32 0, i32* %register15
    %register16 = getelementptr inbounds i32, i32* %register2, i32 9
    store i32 0, i32* %register16
    %register17 = getelementptr inbounds i32, i32* %register2, i32 10
    store i32 0, i32* %register17
    %register18 = getelementptr inbounds i32, i32* %register2, i32 11
    store i32 0, i32* %register18
    %register19 = load i32, i32* %register3 ; Get variable x
    %register20 = add i32 0, 2
    %register21 = inttoptr i32 %register20 to i32*
    %register22 = getelementptr inbounds i32, i32* %register21, i32 1
    %register23 = load i32, i32* %register22
    %register24 = getelementptr inbounds i32, i32* %register21, i32 0
    %register25 = load i32, i32* %register24
    %register26 = add i32 %register23, %register25
    %register27 = sub i32 %register26, 4
    %register28 = icmp sgt i32 %register20, %register27
    br i1 %register28, label %label1, label %label_cont1
label_cont1:
    br label %label2
label1:
    call void @print(i8* getelementptr ([6 x i8], [6 x i8]* @.string_var2, i32 0, i32 0))
    call void @exit(i32 1)
    %register200 = add i32 0, 2
    br label %label2
label2:
    ret void

}   ; >>> Closing function scope

For some reason when I run it, it fails with Segmentation fault (core dumped) without printing an understandable error. The strange thing is if I comment the commands in label1 and keep it:

    ;call void @print(i8* getelementptr ([6 x i8], [6 x i8]* @.string_var2, i32 0, i32 0))
    ;call void @exit(i32 1)
    ;%register200 = add i32 0, 2
    br label %label2

It does not result with Segmentation fault. If I comment out at least one of those commands (for example print or the sum), it will fail. Why does it happen?

EDIT: I think I'm getting the same result here. (Here with comments)

I understand that "Segmentation fault" means that I tried to access memory that I do not have access to. but why can't I even create an new register with some value?

EDIT2: It looks like br i1 %register28, label %label1, label %label_cont1 is the real reason.

Edit3: The actual full code I'm trying to figure can be found here. The problem is that changing it to alloca i32 will result with Error (instead of printing 1). It also contains the C code I'm trying to copy to LLVM.

1 Answer 1

1

The segfault originates from this line

%register21 = inttoptr i32 %register20 to i32*

After the cast, register21 supposedly points to some memory location. But what memory location ?? It's value is a non existent address that wasn't gotten through a an alloca instr or malloc call. Therefore all the other registers that try to dereference this pointer get disappointed.

I've altered the inttptr line

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the answer! It does solve the segmented fault but why do I need %register20 then? I actually have the full code (given by the professor) with that error but for some reason, changing it to alloca leads to other behavior. Do you mind look into it? I added the URL in the question. It should return 1 but instead it returns the Error.
I opened a separate topic so it will be more organized. If you might help, please take a look. thanks again :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.