[LLVMdev] nested function's static link gets clobbered
Török Edwin
edwintorok at gmail.com
Fri Oct 31 15:12:35 PDT 2008
On 2008-10-31 23:57, Yale Zhang wrote:
> Fellow developers,
>
> I'm parallelizing loops to be called by pthread. The thread body that
> I pass to pthread_create looks like
>
> define i8* @loop1({ i32*, i32* }* nest %parent_frame, i8*
> %arg) parent_frame is pointer to shared variables in
> original function
>
> 0x00007f0de11c41f0: mov (%r10),%rax
> 0x00007f0de11c41f3: cmpl $0x63,(%rax)
> 0x00007f0de11c41f6: jg 0x7f0de11c420c
> 0x00007f0de11c41fc: mov 0x8(%r10),%rax
> 0x00007f0de11c4200: incl (%rax)
> 0x00007f0de11c4202: mov (%r10),%rax
> 0x00007f0de11c4205: incl (%rax)
> 0x00007f0de11c4207: jmpq 0x7f0de11c41f0
> 0x00007f0de11c420c: xor %rax,%rax
> 0x00007f0de11c420f: retq
>
> I use init_trampoline to generate code that sets up the static link:
>
> 0x00007fffee982316: mov $0x7f48e1a08fb0,%r11
> 0x00007fffee982320: mov $0x7fffee982330,%r10 the
> static link
> 0x00007fffee98232a: rex.WB jmpq *%r11
>
> The program crashes in loop1 on the 2nd instruction. r10, which
> contained the static link was different from the value set by the
> trampoline.
>
> Upon closer inspection, it looks like the trampoline first jumps to a
> stub that compiles loop1:
>
> 0x00007f48e1a08fb0: mov $0x5c61c0,%r10
> 0x00007f48e1a08fba: callq *%r10
> 0x00007f48e1a08fbd: int $0x0
>
> But that clobbers r10 which loop1 needs. According to the x86-64 ABI,
> r10 isn't preserved across functions, but here it needs to be. Is
> there anyway
> to force LLVM to do that? I tried telling lli to compile the entire
> program (-no-lazy) so that the stub won't be generated, but gives the
> error:
>
> LLVM JIT requested to do lazy compilation of function
> '_Z41__static_initialization_and_destruction_0ii' when lazy compiles
> are disabled!
>
> Any ideas?
Hmm, lli.cpp does this:
if (NoLazyCompilation)
EE->DisableLazyCompilation();
[....]
// Run static constructors.
EE->runStaticConstructorsDestructors(false);
if (NoLazyCompilation) {
for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
Function *Fn = &*I;
if (Fn != MainFn && !Fn->isDeclaration())
EE->getPointerToFunction(Fn);
}
}
If you actually have static constructors and destructors then nolazy may
not work. You could try moving the runStatic... below the NoLazy block,
but it could be that compiling the functions themselves could need those
constructors to be run already.
The easiest way out seems to move the DisableLazyCompilation just after
you've run the static constructors.
Best regards,
--Edwin
More information about the llvm-dev
mailing list