[LLVMdev] Possible bug in the dragonegg

Duncan Sands baldrick at free.fr
Tue Jan 24 00:52:23 PST 2012


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
>




More information about the llvm-dev mailing list