diff options
| author | Jason Molenda <jmolenda@apple.com> | 2014-12-21 10:44:54 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2014-12-21 10:44:54 +0000 |
| commit | 5c45c541a20b0f82fb9e2c065db500b7d4412fc3 (patch) | |
| tree | 5baee809004715c301fa5171f717517113259721 /lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp | |
| parent | 23a55f1eeeb15ef6b8002e98e90cd025d53c97f2 (diff) | |
| download | bcm5719-llvm-5c45c541a20b0f82fb9e2c065db500b7d4412fc3.tar.gz bcm5719-llvm-5c45c541a20b0f82fb9e2c065db500b7d4412fc3.zip | |
Various unwinder work.
Most of the changes are to the FuncUnwinders class -- as we've added
more types of unwind information, the way this class was written was
making it a mess to maintain. Instead of trying to keep one
"non-call site" unwind plan and one "call site" unwind plan, track
all the different types of unwind plans we can possibly retrieve for
each function and have the call-site/non-call-site accessor methods
retrieve those.
Add a real "fast unwind plan" for x86_64 / i386 -- when doing an
unwind through a function, this only has to read the first 4 bytes
to tell if the function has a standard prologue sequence. If so,
we can use the architecture default unwind plan to backtrace
through this function. If we try to retrieve the save location for
other registers later on, a real unwind plan will be used. This
one is just for doing fast backtraces.
Change the compact unwind plan importer to fill in the valid address
range it is valid for.
Compact unwind, in theory, may have multiple entries for a single
function. The FuncUnwinders rewrite includes the start of supporting
this correctly. In practice compact unwind encodings are used for
the entire range of the function today -- in fact, sometimes the same
encoding is used for multiple functions that have the same unwind
rules. But I want to handle a single function that has multiple
different compact unwind UnwindPlans eventually.
llvm-svn: 224689
Diffstat (limited to 'lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp')
| -rw-r--r-- | lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 0daa7c82498..411e95e75ae 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -1259,9 +1259,41 @@ UnwindAssembly_x86::AugmentUnwindPlanFromCallSite (AddressRange& func, Thread& t bool UnwindAssembly_x86::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan) { - ExecutionContext exe_ctx (thread.shared_from_this()); - AssemblyParse_x86 asm_parse(exe_ctx, m_cpu, m_arch, func); - return asm_parse.get_fast_unwind_plan (func, unwind_plan); + // if prologue is + // 55 pushl %ebp + // 89 e5 movl %esp, %ebp + // or + // 55 pushq %rbp + // 48 89 e5 movq %rsp, %rbp + + // We should pull in the ABI architecture default unwind plan and return that + + llvm::SmallVector <uint8_t, 4> opcode_data; + + ProcessSP process_sp = thread.GetProcess(); + if (process_sp) + { + Target &target (process_sp->GetTarget()); + const bool prefer_file_cache = true; + Error error; + if (target.ReadMemory (func.GetBaseAddress (), prefer_file_cache, opcode_data.data(), + 4, error) == 4) + { + uint8_t i386_push_mov[] = {0x55, 0x89, 0xe5}; + uint8_t x86_64_push_mov[] = {0x55, 0x48, 0x89, 0xe5}; + + if (memcmp (opcode_data.data(), i386_push_mov, sizeof (i386_push_mov)) == 0 + || memcmp (opcode_data.data(), x86_64_push_mov, sizeof (x86_64_push_mov)) == 0) + { + ABISP abi_sp = process_sp->GetABI(); + if (abi_sp) + { + return abi_sp->CreateDefaultUnwindPlan (unwind_plan); + } + } + } + } + return false; } bool |

