diff options
author | Greg Clayton <gclayton@apple.com> | 2011-05-18 22:01:49 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-05-18 22:01:49 +0000 |
commit | 3f5c08f5c25b5012a1f71a820657324c0ea2f273 (patch) | |
tree | e8acd0cdc71964e8ac4e06b9d0ce136c63bf6fc0 /lldb/source/Core/Address.cpp | |
parent | 8b2e426555a1308e8570565816d61e37862d22f6 (diff) | |
download | bcm5719-llvm-3f5c08f5c25b5012a1f71a820657324c0ea2f273.tar.gz bcm5719-llvm-3f5c08f5c25b5012a1f71a820657324c0ea2f273.zip |
Added a function to lldb_private::Address:
addr_t
Address::GetCallableLoadAddress (Target *target) const;
This will resolve the load address in the Address object and optionally
decorate the address up to be able to be called. For all non ARM targets, this
just essentially returns the result of "Address::GetLoadAddress (target)". But
for ARM targets, it checks if the address is Thumb, and if so, it returns
an address with bit zero set to indicate a mode switch to Thumb. This is how
we need function pointers to be for return addresses and when resolving
function addresses for the JIT. It is also nice to centralize this in one spot
to avoid having multiple copies of this code.
llvm-svn: 131588
Diffstat (limited to 'lldb/source/Core/Address.cpp')
-rw-r--r-- | lldb/source/Core/Address.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index b7dd694be1c..de4e4d39164 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -15,6 +15,8 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/Triple.h" + using namespace lldb; using namespace lldb_private; @@ -294,6 +296,42 @@ Address::GetLoadAddress (Target *target) const return LLDB_INVALID_ADDRESS; } +addr_t +Address::GetCallableLoadAddress (Target *target) const +{ + addr_t code_addr = GetLoadAddress (target); + + if (m_section && code_addr != LLDB_INVALID_ADDRESS) + { + switch (target->GetArchitecture().GetMachine()) + { + case llvm::Triple::arm: + case llvm::Triple::thumb: + // Check if bit zero it no set? + if ((code_addr & 1ull) == 0) + { + // Bit zero isn't set, check if the address is a multiple of 2? + if (code_addr & 2ull) + { + // The address is a multiple of 2 so it must be thumb, set bit zero + code_addr |= 1ull; + } + else if (GetAddressClass() == eAddressClassCodeAlternateISA) + { + // We checked the address and the address claims to be the alternate ISA + // which means thumb, so set bit zero. + code_addr |= 1ull; + } + } + break; + + default: + break; + } + } + return code_addr; +} + bool Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const { |