Óscar Fuentes
2008-Nov-17 10:47 UTC
[LLVMdev] Bug? Call to pointer function does not adjust the stack.
On the transition from 2.1 to ToT some test cases on my JIT compiler are failing due to stack corruption. This is how it happens: the function define internal void @Addr_0x89c8b78([4 x i8]* sret) { %2 = bitcast [4 x i8]* %0 to i8* ; <i8*> [#uses=1] %3 = bitcast [4 x i8]* @0 to i8* ; <i8*> [#uses=1] tail call void @Addr_0x80f88d4(i8* inttoptr (i32 144403792 to i8*), i8* %3, i8* %2) ret void } ([4 x i8] is for representing a foreign struct type with sizeof 4 and unknown structure. The compiler only knows its size, constructor, destructor and copy constructor. Actually, it is a std::string). is tranlated to this machine code (the important bit is the `ret $0x4' at the end): 0xf6bb8040: sub $0xc,%esp 0xf6bb8043: mov 0x10(%esp),%ecx 0xf6bb8047: mov %ecx,0x8(%esp) 0xf6bb804b: movl $0x89cb968,0x4(%esp) 0xf6bb8053: movl $0x89b9d50,(%esp) 0xf6bb805a: call 0x80f8928 <_ZN3lp011BasicCopierISsEEvRNS_8TipoInfoEPvS3_> 0xf6bb805f: add $0xc,%esp 0xf6bb8062: ret $0x4 The crucial detail is that the stack corruption only happens if the above function is called through a function pointer: define internal void @Addr_0x89c8a68([4 x i8]* sret, void ([4 x i8]*)*) { %3 = alloca void ([4 x i8]*)* ; <void ([4 x i8]*)**> [#uses=2] store void ([4 x i8]*)* %1, void ([4 x i8]*)** %3 %4 = load void ([4 x i8]*)** %3 ; <void ([4 x i8]*)*> [#uses=1] call void %4([4 x i8]* %0) ret void } which is translated to 0xf6c59070: sub $0xc,%esp 0xf6c59073: mov 0x14(%esp),%eax 0xf6c59077: mov %eax,0x8(%esp) 0xf6c5907b: mov 0x10(%esp),%ecx 0xf6c5907f: mov %ecx,(%esp) 0xf6c59082: call *%eax 0xf6c59084: add $0xc,%esp 0xf6c59087: ret $0x4 after the "call *%eax" the stack is unadjusted by 4 bytes, hence the stack corruption. 2.1 works fine when the JIT produces code with the same llvm assembly code. What can be causing this? A suspicious is in the absence of `sret' on call void %4([4 x i8]* %0) but, on the call site, the function has the sret attribute: assert( f->paramHasAttr(1, Attribute::StructRet) ); so why the assembly does not reflect this is beyond me. -- Oscar
Óscar Fuentes
2008-Nov-17 10:58 UTC
[LLVMdev] Bug? Call to pointer function does not adjust the stack.
Óscar Fuentes <ofv at wanadoo.es> writes: [snip] Solved: had to set the sret attribute on the call instuction. The "function" actually was a value containing the pointer to the function. -- Oscar