Hi Duncan,>> #include<stdio.h> >> #include<string.h> >> >> int main(int argc, char** argv){ >> >> char a[8] = "aaaaaaa"; >> char b[8] = "bbbbbbb"; >> >> char *c = (char*) malloc(sizeof(char)*(strlen(a)+strlen(b)+1)); >> memcpy(c, a, strlen(a)); >> memcpy(c + strlen(a), b, strlen(b) + 1); >> >> printf("a = %s, b = %s, c = %s\n", a, b, c); >> } >> * >> and compiling and executing in the following way: >> >> $> gcc -fplugin=~/dragonegg.so -O1 -fplugin-arg-dragonegg-enable-gcc-optzns >> test.c -S -fplugin-arg-dragonegg-emit-ir -o test.ll > What happens if you compile without -fplugin-arg-dragonegg-enable-gcc-optzns?Then I can increase the string sizes up to 8 instead of 7, but anything above that segfaults.> Also, what is the contents of test.ll?For string sizes of 15 for a and b: ; ModuleID = 'test.c' target datalayout = "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64" target triple = "x86_64--linux-gnu" module asm "\09.ident\09\22GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 LLVM: exported\22" @.cst = linker_private unnamed_addr constant [15 x i8] c"aaaaaaaaaaaaaa\00", align 8 @.cst1 = linker_private unnamed_addr constant [15 x i8] c"bbbbbbbbbbbbbb\00", align 8 @.cst2 = linker_private unnamed_addr constant [24 x i8] c"a = %s, b = %s, c = %s\0A\00", align 8 define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable ssp { entry: %memtmp = alloca [15 x i8], align 1 %memtmp1 = alloca [15 x i8], align 1 %0 = getelementptr inbounds [15 x i8]* %memtmp, i64 0, i64 0 %1 = getelementptr inbounds [15 x i8]* %memtmp1, i64 0, i64 0 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr inbounds ([15 x i8]* @.cst, i64 0, i64 0), i64 15, i32 1, i1 false) call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* getelementptr inbounds ([15 x i8]* @.cst1, i64 0, i64 0), i64 15, i32 1, i1 false) %2 = call i64 @strlen(i8* %0) nounwind readonly %3 = call i64 @strlen(i8* %1) nounwind readonly %4 = add i64 %2, 1 %5 = add i64 %4, %3 %6 = call noalias i8* @malloc(i64 %5) nounwind %7 = call i64 @strlen(i8* %0) nounwind readonly %8 = call i64 @llvm.objectsize.i64(i8* %6, i1 false) %9 = call i8* @__memcpy_chk(i8* %6, i8* %0, i64 %7, i64 %8) nounwind %10 = call i64 @strlen(i8* %1) nounwind readonly %11 = add i64 %10, 1 %12 = call i64 @strlen(i8* %0) nounwind readonly %13 = getelementptr i8* %6, i64 %12 %14 = call i64 @llvm.objectsize.i64(i8* %13, i1 false) %15 = call i8* @__memcpy_chk(i8* %13, i8* %1, i64 %11, i64 %14) nounwind %16 = call i32 (i32, i8*, ...)* @__printf_chk(i32 1, i8* getelementptr inbounds ([24 x i8]* @.cst2, i64 0, i64 0), [15 x i8]* %memtmp, [15 x i8]* %memtmp1, i8* %6) nounwind ret i32 undef } declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind declare i64 @strlen(i8* nocapture) nounwind readonly declare noalias i8* @malloc(i64) nounwind declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone declare i8* @__memcpy_chk(i8*, i8*, i64, i64) nounwind declare i32 @__printf_chk(i32, i8*, ...) Please let me know if you can execute that file. Thanks!>> $> lli test.ll >> >> it segfaults. If I compile without "-S -fplugin-arg-dragonegg-emit-ir", >> everything's fine. Also, if I add "-force-interpreter=true" as an lli parameter, >> I get a "LLVM ERROR: Tried to execute an unknown external function: memcpy". >> Amazingly, if I change the string sizes below 8 (e.g. char a[7], char b[7]), >> everything works just fine!! It also works if I move a and b outside the >> function (as a global), or if I malloc the arrays. Possibly a problem of >> allocation of local vars in the stack? >> >> I also tried to link and create an assembler file so the interpreter could >> resolve the memcpy call, but neither of them work with lli: >> >> $> llvm-link -S test.ll> test.ir >> >> $> llvm-as test.ir -o test.s >> >> -- >> Pablo Barrio >> Dpt. Electrical Engineering - Technical University of Madrid >> Office C-203 >> Avda. Complutense s/n, 28040 Madrid >> Tel. (+34) 915495700 ext. 4234 >> @:pbarrio at die.upm.es<mailto:pbarrio at die.upm.es> >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-- Pablo Barrio Dpt. Electrical Engineering - Technical University of Madrid Office C-203 Avda. Complutense s/n, 28040 Madrid Tel. (+34) 915495700 ext. 4234 @: pbarrio at die.upm.es
Hi Pablo, I can reproduce this with the supplied IR. It is related to the use of __memcpy_chk. As far as I can see it is a bug in lli or the LLVM code generators. Can you please open a bugreport, attaching the LLVM IR. Ciao, Duncan. On 23/01/12 17:00, Pablo Barrio wrote:> Hi Duncan, >>> #include<stdio.h> >>> #include<string.h> >>> >>> int main(int argc, char** argv){ >>> >>> char a[8] = "aaaaaaa"; >>> char b[8] = "bbbbbbb"; >>> >>> char *c = (char*) malloc(sizeof(char)*(strlen(a)+strlen(b)+1)); >>> memcpy(c, a, strlen(a)); >>> memcpy(c + strlen(a), b, strlen(b) + 1); >>> >>> printf("a = %s, b = %s, c = %s\n", a, b, c); >>> } >>> * >>> and compiling and executing in the following way: >>> >>> $> gcc -fplugin=~/dragonegg.so -O1 -fplugin-arg-dragonegg-enable-gcc-optzns >>> test.c -S -fplugin-arg-dragonegg-emit-ir -o test.ll >> What happens if you compile without -fplugin-arg-dragonegg-enable-gcc-optzns? > Then I can increase the string sizes up to 8 instead of 7, but anything > above that segfaults. >> Also, what is the contents of test.ll? > > For string sizes of 15 for a and b: > > > ; ModuleID = 'test.c' > target datalayout > "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64" > target triple = "x86_64--linux-gnu" > > module asm "\09.ident\09\22GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 > LLVM: exported\22" > > @.cst = linker_private unnamed_addr constant [15 x i8] > c"aaaaaaaaaaaaaa\00", align 8 > @.cst1 = linker_private unnamed_addr constant [15 x i8] > c"bbbbbbbbbbbbbb\00", align 8 > @.cst2 = linker_private unnamed_addr constant [24 x i8] c"a = %s, b > %s, c = %s\0A\00", align 8 > > define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable ssp { > entry: > %memtmp = alloca [15 x i8], align 1 > %memtmp1 = alloca [15 x i8], align 1 > %0 = getelementptr inbounds [15 x i8]* %memtmp, i64 0, i64 0 > %1 = getelementptr inbounds [15 x i8]* %memtmp1, i64 0, i64 0 > call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr > inbounds ([15 x i8]* @.cst, i64 0, i64 0), i64 15, i32 1, i1 false) > call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* getelementptr > inbounds ([15 x i8]* @.cst1, i64 0, i64 0), i64 15, i32 1, i1 false) > %2 = call i64 @strlen(i8* %0) nounwind readonly > %3 = call i64 @strlen(i8* %1) nounwind readonly > %4 = add i64 %2, 1 > %5 = add i64 %4, %3 > %6 = call noalias i8* @malloc(i64 %5) nounwind > %7 = call i64 @strlen(i8* %0) nounwind readonly > %8 = call i64 @llvm.objectsize.i64(i8* %6, i1 false) > %9 = call i8* @__memcpy_chk(i8* %6, i8* %0, i64 %7, i64 %8) nounwind > %10 = call i64 @strlen(i8* %1) nounwind readonly > %11 = add i64 %10, 1 > %12 = call i64 @strlen(i8* %0) nounwind readonly > %13 = getelementptr i8* %6, i64 %12 > %14 = call i64 @llvm.objectsize.i64(i8* %13, i1 false) > %15 = call i8* @__memcpy_chk(i8* %13, i8* %1, i64 %11, i64 %14) nounwind > %16 = call i32 (i32, i8*, ...)* @__printf_chk(i32 1, i8* > getelementptr inbounds ([24 x i8]* @.cst2, i64 0, i64 0), [15 x i8]* > %memtmp, [15 x i8]* %memtmp1, i8* %6) nounwind > ret i32 undef > } > > declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, > i64, i32, i1) nounwind > > declare i64 @strlen(i8* nocapture) nounwind readonly > > declare noalias i8* @malloc(i64) nounwind > > declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone > > declare i8* @__memcpy_chk(i8*, i8*, i64, i64) nounwind > > declare i32 @__printf_chk(i32, i8*, ...) > > > > > > Please let me know if you can execute that file. Thanks! > >>> $> lli test.ll >>> >>> it segfaults. If I compile without "-S -fplugin-arg-dragonegg-emit-ir", >>> everything's fine. Also, if I add "-force-interpreter=true" as an lli parameter, >>> I get a "LLVM ERROR: Tried to execute an unknown external function: memcpy". >>> Amazingly, if I change the string sizes below 8 (e.g. char a[7], char b[7]), >>> everything works just fine!! It also works if I move a and b outside the >>> function (as a global), or if I malloc the arrays. Possibly a problem of >>> allocation of local vars in the stack? >>> >>> I also tried to link and create an assembler file so the interpreter could >>> resolve the memcpy call, but neither of them work with lli: >>> >>> $> llvm-link -S test.ll> test.ir >>> >>> $> llvm-as test.ir -o test.s >>> >>> -- >>> Pablo Barrio >>> Dpt. Electrical Engineering - Technical University of Madrid >>> Office C-203 >>> Avda. Complutense s/n, 28040 Madrid >>> Tel. (+34) 915495700 ext. 4234 >>> @:pbarrio at die.upm.es<mailto:pbarrio at die.upm.es> >>> >>> >>> >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Hi Pablo, in fact this is coming from the "ssp" attribute on main, which turns on LLVM's stack protection logic. I have no idea what that does exactly, but it seems to be causing the problem. On ubuntu systems it is enabled by default. You can turn it off by passing -fno-stack-protector to dragonegg. However please still open a bugreport since stack protection is supposed to work. Ciao, Duncan. On 24/01/12 09:52, Duncan Sands wrote:> Hi Pablo, I can reproduce this with the supplied IR. It is related to the use of > __memcpy_chk. As far as I can see it is a bug in lli or the LLVM code > generators. Can you please open a bugreport, attaching the LLVM IR. > > Ciao, Duncan. > > On 23/01/12 17:00, Pablo Barrio wrote: >> Hi Duncan, >>>> #include<stdio.h> >>>> #include<string.h> >>>> >>>> int main(int argc, char** argv){ >>>> >>>> char a[8] = "aaaaaaa"; >>>> char b[8] = "bbbbbbb"; >>>> >>>> char *c = (char*) malloc(sizeof(char)*(strlen(a)+strlen(b)+1)); >>>> memcpy(c, a, strlen(a)); >>>> memcpy(c + strlen(a), b, strlen(b) + 1); >>>> >>>> printf("a = %s, b = %s, c = %s\n", a, b, c); >>>> } >>>> * >>>> and compiling and executing in the following way: >>>> >>>> $> gcc -fplugin=~/dragonegg.so -O1 -fplugin-arg-dragonegg-enable-gcc-optzns >>>> test.c -S -fplugin-arg-dragonegg-emit-ir -o test.ll >>> What happens if you compile without -fplugin-arg-dragonegg-enable-gcc-optzns? >> Then I can increase the string sizes up to 8 instead of 7, but anything >> above that segfaults. >>> Also, what is the contents of test.ll? >> >> For string sizes of 15 for a and b: >> >> >> ; ModuleID = 'test.c' >> target datalayout >> "e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64" >> >> target triple = "x86_64--linux-gnu" >> >> module asm "\09.ident\09\22GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 >> LLVM: exported\22" >> >> @.cst = linker_private unnamed_addr constant [15 x i8] >> c"aaaaaaaaaaaaaa\00", align 8 >> @.cst1 = linker_private unnamed_addr constant [15 x i8] >> c"bbbbbbbbbbbbbb\00", align 8 >> @.cst2 = linker_private unnamed_addr constant [24 x i8] c"a = %s, b >> %s, c = %s\0A\00", align 8 >> >> define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable ssp { >> entry: >> %memtmp = alloca [15 x i8], align 1 >> %memtmp1 = alloca [15 x i8], align 1 >> %0 = getelementptr inbounds [15 x i8]* %memtmp, i64 0, i64 0 >> %1 = getelementptr inbounds [15 x i8]* %memtmp1, i64 0, i64 0 >> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* getelementptr >> inbounds ([15 x i8]* @.cst, i64 0, i64 0), i64 15, i32 1, i1 false) >> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* getelementptr >> inbounds ([15 x i8]* @.cst1, i64 0, i64 0), i64 15, i32 1, i1 false) >> %2 = call i64 @strlen(i8* %0) nounwind readonly >> %3 = call i64 @strlen(i8* %1) nounwind readonly >> %4 = add i64 %2, 1 >> %5 = add i64 %4, %3 >> %6 = call noalias i8* @malloc(i64 %5) nounwind >> %7 = call i64 @strlen(i8* %0) nounwind readonly >> %8 = call i64 @llvm.objectsize.i64(i8* %6, i1 false) >> %9 = call i8* @__memcpy_chk(i8* %6, i8* %0, i64 %7, i64 %8) nounwind >> %10 = call i64 @strlen(i8* %1) nounwind readonly >> %11 = add i64 %10, 1 >> %12 = call i64 @strlen(i8* %0) nounwind readonly >> %13 = getelementptr i8* %6, i64 %12 >> %14 = call i64 @llvm.objectsize.i64(i8* %13, i1 false) >> %15 = call i8* @__memcpy_chk(i8* %13, i8* %1, i64 %11, i64 %14) nounwind >> %16 = call i32 (i32, i8*, ...)* @__printf_chk(i32 1, i8* >> getelementptr inbounds ([24 x i8]* @.cst2, i64 0, i64 0), [15 x i8]* >> %memtmp, [15 x i8]* %memtmp1, i8* %6) nounwind >> ret i32 undef >> } >> >> declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, >> i64, i32, i1) nounwind >> >> declare i64 @strlen(i8* nocapture) nounwind readonly >> >> declare noalias i8* @malloc(i64) nounwind >> >> declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone >> >> declare i8* @__memcpy_chk(i8*, i8*, i64, i64) nounwind >> >> declare i32 @__printf_chk(i32, i8*, ...) >> >> >> >> >> >> Please let me know if you can execute that file. Thanks! >> >>>> $> lli test.ll >>>> >>>> it segfaults. If I compile without "-S -fplugin-arg-dragonegg-emit-ir", >>>> everything's fine. Also, if I add "-force-interpreter=true" as an lli >>>> parameter, >>>> I get a "LLVM ERROR: Tried to execute an unknown external function: memcpy". >>>> Amazingly, if I change the string sizes below 8 (e.g. char a[7], char b[7]), >>>> everything works just fine!! It also works if I move a and b outside the >>>> function (as a global), or if I malloc the arrays. Possibly a problem of >>>> allocation of local vars in the stack? >>>> >>>> I also tried to link and create an assembler file so the interpreter could >>>> resolve the memcpy call, but neither of them work with lli: >>>> >>>> $> llvm-link -S test.ll> test.ir >>>> >>>> $> llvm-as test.ir -o test.s >>>> >>>> -- >>>> Pablo Barrio >>>> Dpt. Electrical Engineering - Technical University of Madrid >>>> Office C-203 >>>> Avda. Complutense s/n, 28040 Madrid >>>> Tel. (+34) 915495700 ext. 4234 >>>> @:pbarrio at die.upm.es<mailto:pbarrio at die.upm.es> >>>> >>>> >>>> >>>> _______________________________________________ >>>> LLVM Developers mailing list >>>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>> _______________________________________________ >>> LLVM Developers mailing list >>> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >