hm.... I think, that is valid in c but next code too doesn't works right: ; ModuleID = 'sample.lz' @.str1 = internal global [6 x i8] c"world\00" ; <[6 x i8]*> [#uses=1] @.str2 = internal global [7 x i8] c"hello \00" ; <[7 x i8]*> [#uses=1] @.str7 = internal global [7 x i8] c"father\00" ; <[7 x i8]*> [#uses=1] @.str8 = internal global [8 x i8] c"mother \00" ; <[8 x i8]*> [#uses=1] declare i32 @puts(i8*) declare i8* @strcat(i8*, i8*) declare i32 @strlen(i8*) declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) define i32 @main() { mainBlock: %str3 = getelementptr [7 x i8]* @.str2, i64 0, i64 0 ; <i8*> [#uses=2] %str4 = getelementptr [6 x i8]* @.str1, i64 0, i64 0 ; <i8*> [#uses=1] call i8* @strcat( i8* %str3, i8* %str4 ) ; <i8*>:0 [#uses=0] %tmp6 = call i32 @puts( i8* %str3 ) ; <i32> [#uses=0] %str9 = getelementptr [8 x i8]* @.str8, i64 0, i64 0 ; <i8*> [#uses=2] %str10 = getelementptr [7 x i8]* @.str7, i64 0, i64 0 ; <i8*> [#uses=1] call i8* @strcat( i8* %str9, i8* %str10 ) ; <i8*>:1 [#uses=0] %tmp12 = call i32 @puts( i8* %str9 ) ; <i32> [#uses=0] ret i32 0 } writes: % hello world mother orld I tried decompile code: main(int argc, char **argv) { char str1[] = "mother "; strcat(str1, "father"); return 0; } 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 Best regards, Zalunin Pavel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080106/7f9b54f1/attachment.html>
Zalunin Pavel wrote:> hm.... I think, that is valid in c > [...] > but next code too doesn't works right: > I tried decompile code: > main(int argc, char **argv) { > char str1[] = "mother "; > strcat(str1, "father"); > return 0; > } >Valid C doesn't mean only that it compiles, but also that you are properly using library functions. Consult the manpage for strcat(3): "the dest string must have enough space for the result"; in your example it doesn't have. Best regards, --Edwin
well this is invalid in c as u need to allocate enough memory to be able to copy the 2nd string , if not enough allocated mem is available then it will overwrite address available, corrupting the memory. :) regards faraz On Jan 6, 2008 11:52 PM, Zalunin Pavel <wr4bbit at gmail.com> wrote:> hm.... I think, that is valid in c > > but next code too doesn't works right: > ; ModuleID = 'sample.lz' > @.str1 = internal global [6 x i8] c"world\00" ; <[6 x i8]*> > [#uses=1] > @.str2 = internal global [7 x i8] c"hello \00" ; <[7 x i8]*> > [#uses=1] > @.str7 = internal global [7 x i8] c"father\00" ; <[7 x i8]*> > [#uses=1] > @.str8 = internal global [8 x i8] c"mother \00" ; <[8 x i8]*> > [#uses=1] > > declare i32 @puts(i8*) > > declare i8* @strcat(i8*, i8*) > > declare i32 @strlen(i8*) > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) > > define i32 @main() { > mainBlock: > %str3 = getelementptr [7 x i8]* @.str2, i64 0, i64 0 ; > <i8*> [#uses=2] > %str4 = getelementptr [6 x i8]* @.str1, i64 0, i64 0 ; > <i8*> [#uses=1] > call i8* @strcat( i8* %str3, i8* %str4 ) ; <i8*>:0 > [#uses=0] > %tmp6 = call i32 @puts( i8* %str3 ) ; <i32> [#uses=0] > %str9 = getelementptr [8 x i8]* @.str8, i64 0, i64 0 ; > <i8*> [#uses=2] > %str10 = getelementptr [7 x i8]* @.str7, i64 0, i64 0 ; > <i8*> [#uses=1] > call i8* @strcat( i8* %str9, i8* %str10 ) ; <i8*>:1 > [#uses=0] > %tmp12 = call i32 @puts( i8* %str9 ) ; <i32> [#uses=0] > ret i32 0 > } > > > writes: > % > hello world > mother orld > > > I tried decompile code: > main(int argc, char **argv) { > char str1[] = "mother "; > strcat(str1, "father"); > return 0; > } > > 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 > > Best regards, > Zalunin Pavel > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-- Syed Faraz Mahmood web : http://www.farazmahmood.com blog : http://farazmahmood.wordpress.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080107/aa628ccd/attachment.html>
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? > ThanksAnother 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
so, thanx to all.... now I understand my fault and now I have another question: how I can write those code with using API: %final = alloca [256 x i8], align 16 ; <[256 x i8]*> [#uses=1] %final1 = getelementptr [256 x i8]* %final, i32 0, i32 0 ; <i8*> [#uses=2] call void @llvm.memcpy.i32( i8* %final1, i8* getelementptr ([3 x i8]* @.str, i32 0, i32 0), i32 3, i32 1 ) %tmp5 = call i8* bitcast (i8* (i8*, i8*)* @strcat to i8* (i8* noalias , i8* noalias )*)( i8* %final1 noalias , i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0) noalias ) ; <i8*> [#uses=0] ret i32 1 I interested for last string : %tmp5 = call i8* bitcast (i8* (i8*, i8*)* @strcat to i8* (i8* noalias , i8* noalias )*)( i8* %final1 noalias , i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0) noalias ) ; <i8*> [#uses=0] Best Regards, Zalunin Pavel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080106/0f2c935d/attachment.html>