Thanks to visit codestin.com
Credit goes to github.com

Skip to content

JIT stub offsets silently truncated to 32 bits in call instruction #5573

@llvmbot

Description

@llvmbot
Bugzilla Link 5201
Resolution FIXED
Resolved on Nov 17, 2015 11:45
Version trunk
OS Linux
Attachments Add asserts, against trunk r84189, Add a test for the bug, against trunk r84531
Reporter LLVM Bugzilla Contributor
CC @comex,@echristo,@edwintorok,@rnk

Extended Description

On x86-64 systems, we're observing segfaults that we believe to have tracked down to a codegen problem in the JIT:

Disassembling the buggy function in gdb gives us this:
... asm ...
0x00002aaab33482b1 <_23_u_23___init__45+673>: incq (%r14)
0x00002aaab33482b4 <_23_u_23___init__45+676>: mov 0x18(%rsp),%rbx
0x00002aaab33482b9 <_23_u_23___init__45+681>: mov %r14,(%rbx)
0x00002aaab33482bc <_23_u_23___init__45+684>: mov $0x2dd8b48,%rbx
0x00002aaab33482c6 <_23_u_23___init__45+694>: mov 0x18(%rbx),%rsi
0x00002aaab33482ca <_23_u_23___init__45+698>: mov %r14,%rdi
0x00002aaab33482cd <_23_u_23___init__45+701>: callq 0x2aaaa5c810b0
0x00002aaab33482d2 <_23_u_23___init__45+706>: mov (%r14),%rbx
0x00002aaab33482d5 <_23_u_23___init__45+709>: dec %rbx
... asm ...

(gdb) x 0x2aaaa5c810b0
0x2aaaa5c810b0: Cannot access memory at address 0x2aaaa5c810b0

That callq 0x2aaaa5c810b0 instruction is the problem: it's calling to invalid memory. Looking at the other callq instructions in this function, gdb can't
access any of them. callq addresses in other functions can be accessed by gdb.

What's happening is that now that the JIT memory manager can allocate multiple code slabs, there's no protection against having stub slabs and code slabs more than 32 bits distant from each other. If the memory manager allocates a new code slab far away from the stub, the offset will be truncated to 32 bits, which means that Bad Things Happen.

I'm working on a reduced test case, but in the meantime, I think the attached patch should be applied to trunk so that the offset is no longer silently truncated.

Applying this patch and passing -debug-only=jit will show this output when running part of Unladen Swallow's test suite:

[...tests...]
test_importhooks
test_enumerate
test_getopt
test_codecencodings_cn
JIT: Allocating another slab of memory for function.
python: /usr/local/google/collinwinter/us/trunk/Util/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:652:
void*::JITEmitter::getPointerToGlobal(llvm::GlobalValue*, void*, bool): Assertion `(Offset & 0xFFFFFFFF) == Offset && "Offset
too big for 32 bits"' failed.
Stack dump:
0. Running pass 'X86 Machine Code Emitter' on function '@"#u#readline241"

Without this, you'd see a segfault instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzilla

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions