diff options
author | Greg Clayton <gclayton@apple.com> | 2011-05-14 01:50:35 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-05-14 01:50:35 +0000 |
commit | 2a48f525cdbd043ac6be814542a034aa09d25e0b (patch) | |
tree | d145a110aede294740bfa6f4fe678da78adff488 /lldb/source/Plugins | |
parent | a16b5be727be41439f086ca466bf3d5a726bd288 (diff) | |
download | bcm5719-llvm-2a48f525cdbd043ac6be814542a034aa09d25e0b.tar.gz bcm5719-llvm-2a48f525cdbd043ac6be814542a034aa09d25e0b.zip |
Expand the ABI prepare trivial function call to allow 6 simple args.
llvm-svn: 131334
Diffstat (limited to 'lldb/source/Plugins')
9 files changed, 284 insertions, 74 deletions
diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index ce9a9c3067d..074c31666fd 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -65,9 +65,12 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread, addr_t sp, addr_t function_addr, addr_t return_addr, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const + addr_t *arg1_ptr, + addr_t *arg2_ptr, + addr_t *arg3_ptr, + addr_t *arg4_ptr, + addr_t *arg5_ptr, + addr_t *arg6_ptr) const { RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) @@ -84,25 +87,41 @@ ABIMacOSX_arm::PrepareTrivialCall (Thread &thread, reg_value.SetUInt32(*arg1_ptr); if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r0"), reg_value)) return false; - } - - if (arg2_ptr) - { - assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) - reg_value.SetUInt32(*arg2_ptr); - if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value)) - return false; - } - - if (arg3_ptr) - { - assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) - assert (arg2_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) + if (arg2_ptr) + { + reg_value.SetUInt32(*arg2_ptr); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r1"), reg_value)) + return false; - reg_value.SetUInt32(*arg3_ptr); - if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value)) - return false; + if (arg3_ptr) + { + reg_value.SetUInt32(*arg3_ptr); + if (!reg_ctx->WriteRegister (reg_ctx->GetRegisterInfoByName("r2"), reg_value)) + return false; + if (arg4_ptr) + { + reg_value.SetUInt32(*arg4_ptr); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3"); + if (!reg_ctx->WriteRegister (reg_info, reg_value)) + return false; + if (arg5_ptr) + { + reg_value.SetUInt32(*arg5_ptr); + sp -= 4; + if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp, reg_info->byte_size, reg_value).Fail()) + return false; + if (arg6_ptr) + { + reg_value.SetUInt32(*arg6_ptr); + sp -= 4; + if (reg_ctx->WriteRegisterValueToMemory (reg_info, sp, reg_info->byte_size, reg_value).Fail()) + return false; + } + } + } + } + } } // Set "lr" to the return address into "lr" diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h index d7a2f3ee66e..ffa2170c6a1 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h @@ -30,9 +30,12 @@ public: lldb::addr_t sp, lldb::addr_t func_addr, lldb::addr_t returnAddress, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const; + lldb::addr_t *arg1_ptr = NULL, + lldb::addr_t *arg2_ptr = NULL, + lldb::addr_t *arg3_ptr = NULL, + lldb::addr_t *arg4_ptr = NULL, + lldb::addr_t *arg5_ptr = NULL, + lldb::addr_t *arg6_ptr = NULL) const; virtual bool GetArgumentValues (lldb_private::Thread &thread, diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 609618bcf31..0217f2fd197 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -57,15 +57,15 @@ ABIMacOSX_i386::CreateInstance (const ArchSpec &arch) bool ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, - lldb::addr_t sp, - lldb::addr_t func_addr, - lldb::addr_t return_addr, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const -// lldb::addr_t arg, -// lldb::addr_t *this_arg, -// lldb::addr_t *cmd_arg) const + addr_t sp, + addr_t func_addr, + addr_t return_addr, + addr_t *arg1_ptr, + addr_t *arg2_ptr, + addr_t *arg3_ptr, + addr_t *arg4_ptr, + addr_t *arg5_ptr, + addr_t *arg6_ptr) const { RegisterContext *reg_ctx = thread.GetRegisterContext().get(); if (!reg_ctx) @@ -85,12 +85,30 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, RegisterValue reg_value; // Write any arguments onto the stack - if (arg1_ptr && arg2_ptr && arg3_ptr) - sp -= 12; - else if (arg1_ptr && arg2_ptr) - sp -= 8; - else if (arg1_ptr) + if (arg1_ptr) + { sp -= 4; + if (arg2_ptr) + { + sp -= 4; + if (arg3_ptr) + { + sp -= 4; + if (arg4_ptr) + { + sp -= 4; + if (arg5_ptr) + { + sp -= 4; + if (arg6_ptr) + { + sp -= 4; + } + } + } + } + } + } // Align the SP sp &= ~(0xfull); // 16-byte alignment @@ -107,7 +125,6 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, if (arg2_ptr) { - assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) reg_value.SetUInt32(*arg2_ptr); // The register info used to write memory just needs to have the correct // size of a 32 bit register, the actual register it pertains to is not @@ -121,8 +138,6 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, if (arg3_ptr) { - assert (arg1_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) - assert (arg2_ptr != NULL); // Remove this after we know the assertion isn't firing (5/11/2011) reg_value.SetUInt32(*arg3_ptr); // The register info used to write memory just needs to have the correct // size of a 32 bit register, the actual register it pertains to is not @@ -133,6 +148,46 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, reg_value); if (error.Fail()) return false; + + if (arg4_ptr) + { + reg_value.SetUInt32(*arg4_ptr); + // The register info used to write memory just needs to have the correct + // size of a 32 bit register, the actual register it pertains to is not + // important, just the size needs to be correct. Here we use "eax"... + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp + 12, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) + return false; + if (arg5_ptr) + { + reg_value.SetUInt32(*arg5_ptr); + // The register info used to write memory just needs to have the correct + // size of a 32 bit register, the actual register it pertains to is not + // important, just the size needs to be correct. Here we use "eax"... + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp + 16, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) + return false; + if (arg6_ptr) + { + reg_value.SetUInt32(*arg6_ptr); + // The register info used to write memory just needs to have the correct + // size of a 32 bit register, the actual register it pertains to is not + // important, just the size needs to be correct. Here we use "eax"... + error = reg_ctx->WriteRegisterValueToMemory (reg_info_32, + sp + 20, + reg_info_32->byte_size, + reg_value); + if (error.Fail()) + return false; + } + } + } } } } @@ -164,9 +219,9 @@ ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, bool ABIMacOSX_i386::PrepareNormalCall (Thread &thread, - lldb::addr_t sp, - lldb::addr_t func_addr, - lldb::addr_t return_addr, + addr_t sp, + addr_t func_addr, + addr_t return_addr, ValueList &args) const { RegisterContext *reg_ctx = thread.GetRegisterContext().get(); diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index 5bc820620fc..62490ab8fed 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -146,9 +146,12 @@ public: lldb::addr_t sp, lldb::addr_t func_addr, lldb::addr_t return_addr, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const; + lldb::addr_t *arg1_ptr = NULL, + lldb::addr_t *arg2_ptr = NULL, + lldb::addr_t *arg3_ptr = NULL, + lldb::addr_t *arg4_ptr = NULL, + lldb::addr_t *arg5_ptr = NULL, + lldb::addr_t *arg6_ptr = NULL) const; virtual bool PrepareNormalCall (lldb_private::Thread &thread, diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index a943bcd9d46..d0b85039c57 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -60,13 +60,19 @@ ABISysV_x86_64::CreateInstance (const ArchSpec &arch) bool ABISysV_x86_64::PrepareTrivialCall (Thread &thread, - lldb::addr_t sp, - lldb::addr_t func_addr, - lldb::addr_t return_addr, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const + addr_t sp, + addr_t func_addr, + addr_t return_addr, + addr_t *arg1_ptr, + addr_t *arg2_ptr, + addr_t *arg3_ptr, + addr_t *arg4_ptr, + addr_t *arg5_ptr, + addr_t *arg6_ptr) const { + if (arg4_ptr || arg5_ptr || arg6_ptr) + return false; + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); if (log) diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h index d47cbf8381f..4cc702f98a3 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h @@ -172,9 +172,12 @@ public: lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, - lldb::addr_t *arg1_ptr, - lldb::addr_t *arg2_ptr, - lldb::addr_t *arg3_ptr) const; + lldb::addr_t *arg1_ptr = NULL, + lldb::addr_t *arg2_ptr = NULL, + lldb::addr_t *arg3_ptr = NULL, + lldb::addr_t *arg4_ptr = NULL, + lldb::addr_t *arg5_ptr = NULL, + lldb::addr_t *arg6_ptr = NULL) const; virtual bool GetArgumentValues (lldb_private::Thread &thread, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index f8eb8de7bb8..5e685e000c7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -45,6 +45,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_supports_vCont_s (eLazyBoolCalculate), m_supports_vCont_S (eLazyBoolCalculate), m_qHostInfo_is_valid (eLazyBoolCalculate), + m_supports__m (eLazyBoolCalculate), + m_supports__M (eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -130,6 +132,9 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings() m_supports_vCont_s = eLazyBoolCalculate; m_supports_vCont_S = eLazyBoolCalculate; m_qHostInfo_is_valid = eLazyBoolCalculate; + m_supports__m = eLazyBoolCalculate; + m_supports__M = eLazyBoolCalculate; + m_supports_qProcessInfoPID = true; m_supports_qfProcessInfo = true; m_supports_qUserName = true; @@ -1016,17 +1021,23 @@ GDBRemoteCommunicationClient::GetHostArchitecture () addr_t GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions) { - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, - permissions & lldb::ePermissionsReadable ? "r" : "", - permissions & lldb::ePermissionsWritable ? "w" : "", - permissions & lldb::ePermissionsExecutable ? "x" : ""); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) + if (m_supports__M != eLazyBoolNo) { - if (!response.IsErrorResponse()) - return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); + m_supports__M = eLazyBoolYes; + char packet[64]; + const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, + permissions & lldb::ePermissionsReadable ? "r" : "", + permissions & lldb::ePermissionsWritable ? "w" : "", + permissions & lldb::ePermissionsExecutable ? "x" : ""); + assert (packet_len < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) + { + if (response.IsUnsupportedResponse()) + m_supports__M = eLazyBoolNo; + else if (!response.IsErrorResponse()) + return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); + } } return LLDB_INVALID_ADDRESS; } @@ -1034,14 +1045,20 @@ GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions) bool GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) { - char packet[64]; - const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) + if (m_supports__m != eLazyBoolNo) { - if (response.IsOKResponse()) - return true; + m_supports__m = eLazyBoolYes; + char packet[64]; + const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); + assert (packet_len < sizeof(packet)); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) + { + if (response.IsOKResponse()) + return true; + else if (response.IsUnsupportedResponse()) + m_supports__m = eLazyBoolNo; + } } return false; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index d8f317ae7e1..e1d17be8105 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -305,6 +305,18 @@ public: bool SetCurrentThreadForRun (int tid); + lldb_private::LazyBool + SupportsAllocateMemory () const + { + return m_supports__M; + } + + lldb_private::LazyBool + SupportsDeallocateMemory () const + { + return m_supports__m; + } + protected: //------------------------------------------------------------------ @@ -319,6 +331,9 @@ protected: lldb_private::LazyBool m_supports_vCont_s; lldb_private::LazyBool m_supports_vCont_S; lldb_private::LazyBool m_qHostInfo_is_valid; + lldb_private::LazyBool m_supports__m; + lldb_private::LazyBool m_supports__M; + bool m_supports_qProcessInfoPID:1, m_supports_qfProcessInfo:1, @@ -330,6 +345,7 @@ protected: m_supports_z2:1, m_supports_z3:1, m_supports_z4:1; + lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index cba830ebad9..14f31004a85 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -11,8 +11,9 @@ #include <errno.h> #include <spawn.h> #include <stdlib.h> -#include <sys/types.h> +#include <sys/mman.h> // for mmap #include <sys/stat.h> +#include <sys/types.h> #include <time.h> // C++ Includes @@ -38,6 +39,7 @@ #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" +#include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/PseudoTerminal.h" // Project includes @@ -1541,7 +1543,93 @@ ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Erro lldb::addr_t ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) { - addr_t allocated_addr = m_gdb_comm.AllocateMemory (size, permissions); + addr_t allocated_addr = LLDB_INVALID_ADDRESS; + + LazyBool supported = m_gdb_comm.SupportsAllocateMemory(); + switch (supported) + { + case eLazyBoolCalculate: + case eLazyBoolYes: + allocated_addr = m_gdb_comm.AllocateMemory (size, permissions); + if (allocated_addr != LLDB_INVALID_ADDRESS || supported == eLazyBoolYes) + return allocated_addr; + + case eLazyBoolNo: + // Call mmap() to create executable memory in the inferior.. + { + Thread *thread = GetThreadList().GetSelectedThread().get(); + if (thread == NULL) + thread = GetThreadList().GetThreadAtIndex(0).get(); + + const bool append = true; + const bool include_symbols = true; + SymbolContextList sc_list; + const uint32_t count = m_target.GetImages().FindFunctions (ConstString ("mmap"), + eFunctionNameTypeFull, + include_symbols, + append, + sc_list); + if (count > 0) + { + SymbolContext sc; + if (sc_list.GetContextAtIndex(0, sc)) + { + const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; + const bool use_inline_block_range = false; + const bool stop_other_threads = true; + const bool discard_on_error = true; + const bool try_all_threads = true; + const uint32_t single_thread_timeout_usec = 500000; + addr_t arg1_addr = 0; + addr_t arg2_len = size; + addr_t arg3_prot = PROT_NONE; + addr_t arg4_flags = MAP_ANON; + addr_t arg5_fd = -1; + addr_t arg6_offset = 0; + if (permissions & lldb::ePermissionsReadable) + arg3_prot |= PROT_READ; + if (permissions & lldb::ePermissionsWritable) + arg3_prot |= PROT_WRITE; + if (permissions & lldb::ePermissionsExecutable) + arg3_prot |= PROT_EXEC; + + AddressRange mmap_range; + if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) + { + lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, + mmap_range.GetBaseAddress(), + stop_other_threads, + discard_on_error, + &arg1_addr, + &arg2_len, + &arg3_prot, + &arg4_flags, + &arg5_fd, + &arg6_offset)); + if (call_plan_sp) + { + StreamFile error_strm; + StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); + if (frame) + { + ExecutionContext exe_ctx; + frame->CalculateExecutionContext (exe_ctx); + ExecutionResults results = RunThreadPlan (exe_ctx, + call_plan_sp, + stop_other_threads, + try_all_threads, + discard_on_error, + single_thread_timeout_usec, + error_strm); + } + } + } + } + } + } + break; + } + if (allocated_addr == LLDB_INVALID_ADDRESS) error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %u", size, permissions); else |