[LLVMdev] Another memory fun

Richard Pennington rich at pennware.com
Sun Jan 6 13:09:40 PST 2008


Zalunin Pavel wrote:
> hm.... I think, that is valid in c
[snip]
> I tried decompile code:
>  main(int argc, char **argv) {
>   char str1[] = "mother ";
>   strcat(str1, "father");
>   return 0;
> }
> 

This is valid C but you forget that str1 is not magically expanded by 
strcat. It starts out as, and remains a char array with 8 elements.

> decompiler gives to me code, in this code string " mother\0" presents as:
> 
> %str1 = 
> alloca [8 x i8], align 16		; <[8 x i8]*> [#uses=9]
> 	%tmp1 = getelementptr [8 x i8
> ]* %str1, i32 0, i32 0		; <i8*> [#uses=2]
> 	store i8 109, 
> i8* %tmp1, align 16
> 	%tmp4 = getelementptr [8 x i8]* %str1, i32 0, 
> i32 1		; <i8*> [#uses=1]
> 	store i8 111, i8* %tmp4, align 1
> 	%tmp7 = 
> getelementptr [8 x i8]* %str1, i32 0, i32 2		; <i8*> [#uses=1]
> 	
> store i8 116, i8* %tmp7, align 1
> 	%tmp10 = getelementptr [8 x i8]* %str1, 
> i32 0, i32 3		; <i8*> [#uses=1]
> 	store i8 104, i8
> * %tmp10, align 1
> 	%tmp13 = getelementptr [8 x i8]* %str1, i32 0, i32 4		; <
> i8*> [#uses=1]
> 	store i8 101, i8* %tmp13, align 1
> 	%tmp16 = getelementptr [8 x 
> i8]* %str1, i32 0, i32 5		; <i8*> [#uses=1]
> 	store 
> i8 114, i8* %tmp16, align 1
> 	%tmp19 = getelementptr [8 x i8]* %str1, i32 0, 
> i32 6		; <i8*> [#uses=1]
> 	store i8 32, i8* %tmp19, align 1
> 	%tmp22 = 
> getelementptr [8 x i8]* %str1, i32 0, i32 7		; <i8*> [#uses=1]
> 
> 	
> store i8 0, i8* %tmp22, align 1
> 
> 
> it's looks funny, can you say another less complex way to do this operation?
> Thanks

Another way:

define i32 @main(i32, i8**) {
entry:
         %argc = alloca i32              ; <i32*> [#uses=1]
         store i32 %0, i32* %argc
         %argv = alloca i8**             ; <i8***> [#uses=1]
         store i8** %1, i8*** %argv
         %retval = alloca i32            ; <i32*> [#uses=3]
         store i32 0, i32* %retval
         %str1 = alloca [8 x i8]         ; <[8 x i8]*> [#uses=2]
         bitcast [8 x i8]* %str1 to i8*          ; <i8*>:2 [#uses=1]
         call void @llvm.memcpy.i32( i8* %2, i8* getelementptr ([8 x 
i8]* @.str, i32 0, i32 0), i32 ptrtoint (i8* getelementptr (i8* null, 
i32 1) to i32), i32 0 )
         bitcast [8 x i8]* %str1 to i8*          ; <i8*>:3 [#uses=1]
         call i8* @strcat( i8* %3, i8* getelementptr ([7 x i8]* @.str1, 
i32 0, i32 0) )          ; <i8*>:4 [#uses=0]
         store i32 0, i32* %retval
         br label %return

return:         ; preds = %entry
         load i32* %retval               ; <i32>:5 [#uses=1]
         ret i32 %5
}


It will still segfault, however. ;-)

-Rich



More information about the llvm-dev mailing list