feature, either build the JIT in debug mode to enable it by default or pass
-jit-emit-debug to lli.
Right now, the only debug information that this communicates to GDB is call
frame information, since it's already being generated to support exceptions in
the JIT. Eventually, when DWARF generation isn't tied so tightly to AsmPrinter,
it will be easy to push that information to GDB through this interface.
Here's a step-by-step breakdown of how the feature works:
- The JIT generates the machine code and DWARF call frame info
(.eh_frame/.debug_frame) for a function into memory.
- The JIT copies that info into an in-memory ELF file with a symbol for the
function.
- The JIT creates a code entry pointing to the ELF buffer and adds it to a
linked list hanging off of a global descriptor at a special symbol that GDB
knows about.
- The JIT calls a function marked noinline that GDB knows about and has put an
internal breakpoint in.
- GDB catches the breakpoint and reads the global descriptor to look for new
code.
- When sees there is new code, it reads the ELF from the inferior's memory and
adds it to itself as an object file.
- The JIT continues, and the next time we stop the program, we are able to
produce a proper backtrace.
Consider running the following program through the JIT:
#include <stdio.h>
void baz(short z) {
long w = z + 1;
printf("%d, %x\n", w, *((int*)NULL)); // SEGFAULT here
}
void bar(short y) {
int z = y + 1;
baz(z);
}
void foo(char x) {
short y = x + 1;
bar(y);
}
int main(int argc, char** argv) {
char x = 1;
foo(x);
}
Here is a backtrace before this patch:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x2aaaabdfbd10 (LWP 25476)]
0x00002aaaabe7d1a8 in ?? ()
(gdb) bt
#0 0x00002aaaabe7d1a8 in ?? ()
#1 0x0000000000000003 in ?? ()
#2 0x0000000000000004 in ?? ()
#3 0x00032aaaabe7cfd0 in ?? ()
#4 0x00002aaaabe7d12c in ?? ()
#5 0x00022aaa00000003 in ?? ()
#6 0x00002aaaabe7d0aa in ?? ()
#7 0x01000002abe7cff0 in ?? ()
#8 0x00002aaaabe7d02c in ?? ()
#9 0x0100000000000001 in ?? ()
#10 0x00000000014388e0 in ?? ()
#11 0x00007fff00000001 in ?? ()
#12 0x0000000000b870a2 in llvm::JIT::runFunction (this=0x1405b70,
F=0x14024e0, ArgValues=@0x7fffffffe050)
at /home/rnk/llvm-gdb/lib/ExecutionEngine/JIT/JIT.cpp:395
#13 0x0000000000baa4c5 in llvm::ExecutionEngine::runFunctionAsMain
(this=0x1405b70, Fn=0x14024e0, argv=@0x13f06f8, envp=0x7fffffffe3b0)
at /home/rnk/llvm-gdb/lib/ExecutionEngine/ExecutionEngine.cpp:377
#14 0x00000000007ebd52 in main (argc=2, argv=0x7fffffffe398,
envp=0x7fffffffe3b0) at /home/rnk/llvm-gdb/tools/lli/lli.cpp:208
And a backtrace after this patch:
Program received signal SIGSEGV, Segmentation fault.
0x00002aaaabe7d1a8 in baz ()
(gdb) bt
#0 0x00002aaaabe7d1a8 in baz ()
#1 0x00002aaaabe7d12c in bar ()
#2 0x00002aaaabe7d0aa in foo ()
#3 0x00002aaaabe7d02c in main ()
#4 0x0000000000b870a2 in llvm::JIT::runFunction (this=0x1405b70,
F=0x14024e0, ArgValues=...)
at /home/rnk/llvm-gdb/lib/ExecutionEngine/JIT/JIT.cpp:395
#5 0x0000000000baa4c5 in llvm::ExecutionEngine::runFunctionAsMain
(this=0x1405b70, Fn=0x14024e0, argv=..., envp=0x7fffffffe3c0)
at /home/rnk/llvm-gdb/lib/ExecutionEngine/ExecutionEngine.cpp:377
#6 0x00000000007ebd52 in main (argc=2, argv=0x7fffffffe3a8,
envp=0x7fffffffe3c0) at /home/rnk/llvm-gdb/tools/lli/lli.cpp:208
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82418 91177308-0d34-0410-b5e6-96231b3b80d8
default, this option is not enabled to support clients who rely on
this behavior.
Fixes http://llvm.org/PR4483
A patch to allocate additional memory for globals after we run out is
forthcoming.
Patch by Reid Kleckner!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75059 91177308-0d34-0410-b5e6-96231b3b80d8
emitted or the machine code for a function is freed. Chris mentioned that we
may also want a notification when a stub is emitted, but that'll be a future
change. I intend to use this to tell oprofile where functions are emitted and
what lines correspond to what addresses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74157 91177308-0d34-0410-b5e6-96231b3b80d8
Introduce a new class (MachineCodeInfo) that the JIT can fill in with details. Right now, just the address and the size of the machine code are reported.
Patch by Evan Phoenix!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72040 91177308-0d34-0410-b5e6-96231b3b80d8
an optimization level instead of a simple boolean telling it to generate code
"fast" or the other type of "fast".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70347 91177308-0d34-0410-b5e6-96231b3b80d8
that has not been JIT'd yet, the callee is put on a list of pending functions
to JIT. The call is directed through a stub, which is updated with the address
of the function after it has been JIT'd. A new interface for allocating and
updating empty stubs is provided.
Add support for removing the ModuleProvider the JIT was created with, which
would otherwise invalidate the JIT's PassManager, which is initialized with the
ModuleProvider's Module.
Add support under a new ExecutionEngine flag for emitting the infomration
necessary to update Function and GlobalVariable stubs after JITing them, by
recording the address of the stub and the name of the GlobalValue. This allows
code to be copied from one address space to another, where libraries may live
at different virtual addresses, and have the stubs updated with their new
correct target addresses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64906 91177308-0d34-0410-b5e6-96231b3b80d8
SingleSource/UnitTests/2007-04-25-weak.c in JIT mode. The test
now passes on systems which are able to produce a correct
reference output to compare with.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61674 91177308-0d34-0410-b5e6-96231b3b80d8
variable is moved to the execution engine. The JIT calls the TargetJITInfo
to allocate thread local storage. Currently, only linux/x86 knows how to
allocate thread local global variables.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58142 91177308-0d34-0410-b5e6-96231b3b80d8
1. The "JITState" object creates a PassManager with the ModuleProvider that the
jit is created with. If the ModuleProvider is removed and deleted, the
PassManager is invalid.
2. The Global maps in the JIT were not invalidated with a ModuleProvider was
removed. This could lead to a case where the Module would be freed, and a
new Module with Globals at the same addresses could return invalid results.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51384 91177308-0d34-0410-b5e6-96231b3b80d8
to create a JIT. This lets you specify JIT-specific configuration items
like the JITMemoryManager to use.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44647 91177308-0d34-0410-b5e6-96231b3b80d8
This patch completes the changes for making lli thread-safe. Here's the list
of changes:
* The Support/ThreadSupport* files were removed and replaced with the
MutexGuard.h file since all ThreadSupport* declared was a Mutex Guard.
The implementation of MutexGuard.h is now based on sys::Mutex which hides
its implementation and makes it unnecessary to have the -NoSupport.h and
-PThreads.h versions of ThreadSupport.
* All places in ExecutionEngine that previously referred to "Mutex" now
refer to sys::Mutex
* All places in ExecutionEngine that previously referred to "MutexLocker"
now refer to MutexGuard (this is frivolous but I believe the technically
correct name for such a class is "Guard" not a "Locker").
These changes passed all of llvm-test. All we need now are some test cases
that actually use multiple threads.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22404 91177308-0d34-0410-b5e6-96231b3b80d8
VM.cpp and JIT.cpp files into JIT.cpp. This also splits some nasty code out
into TargetSelect.cpp so that people hopefully won't notice it. :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10544 91177308-0d34-0410-b5e6-96231b3b80d8
Switch Interpreter and JIT's "run" methods to take a Function and a vector of
GenericValues.
Move (almost all of) the stuff that constructs a canonical call to main()
into lli (new methods "callAsMain", "makeStringVector").
Nuke getCurrentExecutablePath(), enableTracing(), getCurrentFunction(),
isStopped(), and many dead decls from interpreter.
Add linux strdup() support to interpreter.
Make interpreter's atexit handler runner and JIT's runAtExitHandlers() look
more alike, in preparation for refactoring.
atexit() is spelled "atexit", not "at_exit".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8366 91177308-0d34-0410-b5e6-96231b3b80d8
static method here.
Remove some extra blank lines.
ExecutionEngine.h: Add its prototype.
lli.cpp: Call it.
Make creation method for each type of EE into a static method of its
own subclass.
Interpreter/Interpreter.cpp: ExecutionEngine::createInterpreter -->
Interpreter::create
Interpreter/Interpreter.h: Likewise.
JIT/JIT.cpp: ExecutionEngine::createJIT --> VM::create
JIT/VM.h: Likewise.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8343 91177308-0d34-0410-b5e6-96231b3b80d8
* No more createX86Emitter() vs. createSparcEmitter() -- there can be only one
* As a result, the memory management semantics must be handled according to
platform -- the parameters to mmap() are particularly sensitive to the host
architecture.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6527 91177308-0d34-0410-b5e6-96231b3b80d8