[llvm-branch-commits] [lldb] r179679 - Merge trunk rev 179594 back into the Windows branch.
Carlo Kok
ck at remobjects.com
Wed Apr 17 01:38:53 PDT 2013
Modified: lldb/branches/windows/tools/debugserver/source/ARM_DWARF_Registers.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/ARM_DWARF_Registers.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/ARM_DWARF_Registers.h (original)
+++ lldb/branches/windows/tools/debugserver/source/ARM_DWARF_Registers.h Wed Apr 17 03:38:48 2013
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_ARM_DWARF_Registers_h_
-#define utility_ARM_DWARF_Registers_h_
+#ifndef ARM_DWARF_Registers_h_
+#define ARM_DWARF_Registers_h_
+
enum
{
@@ -73,7 +74,7 @@ enum
dwarf_f6,
dwarf_f7,
- // Intel wireless MMX general purpose registers 0â7
+ // Intel wireless MMX general purpose registers 0 - 7
dwarf_wCGR0 = 104,
dwarf_wCGR1,
dwarf_wCGR2,
@@ -93,7 +94,7 @@ enum
dwarf_ACC6,
dwarf_ACC7,
- // Intel wireless MMX data registers 0â15
+ // Intel wireless MMX data registers 0 - 15
dwarf_wR0 = 112,
dwarf_wR1,
dwarf_wR2,
@@ -141,7 +142,7 @@ enum
dwarf_r13_svc,
dwarf_r14_svc,
- // Intel wireless MMX control register in co-processor 0â7
+ // Intel wireless MMX control register in co-processor 0 - 7
dwarf_wC0 = 192,
dwarf_wC1,
dwarf_wC2,
@@ -183,8 +184,26 @@ enum
dwarf_d28,
dwarf_d29,
dwarf_d30,
- dwarf_d31
+ dwarf_d31,
+
+ // Neon quadword registers
+ dwarf_q0 = 288,
+ dwarf_q1,
+ dwarf_q2,
+ dwarf_q3,
+ dwarf_q4,
+ dwarf_q5,
+ dwarf_q6,
+ dwarf_q7,
+ dwarf_q8,
+ dwarf_q9,
+ dwarf_q10,
+ dwarf_q11,
+ dwarf_q12,
+ dwarf_q13,
+ dwarf_q14,
+ dwarf_q15
};
-#endif // utility_ARM_DWARF_Registers_h_
+#endif // ARM_DWARF_Registers_h_
Modified: lldb/branches/windows/tools/debugserver/source/ARM_GCC_Registers.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/ARM_GCC_Registers.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/ARM_GCC_Registers.h (original)
+++ lldb/branches/windows/tools/debugserver/source/ARM_GCC_Registers.h Wed Apr 17 03:38:48 2013
@@ -31,5 +31,116 @@ enum
gcc_cpsr
};
+enum
+{
+// Name Nr Rel Offset Size Type Raw value
+ gdb_arm_r0 = 0, // 0 0 4 int32_t
+ gdb_arm_r1 = 1, // 1 4 4 int32_t
+ gdb_arm_r2 = 2, // 2 8 4 int32_t
+ gdb_arm_r3 = 3, // 3 12 4 int32_t
+ gdb_arm_r4 = 4, // 4 16 4 int32_t
+ gdb_arm_r5 = 5, // 5 20 4 int32_t
+ gdb_arm_r6 = 6, // 6 24 4 int32_t
+ gdb_arm_r7 = 7, // 7 28 4 int32_t
+ gdb_arm_r8 = 8, // 8 32 4 int32_t
+ gdb_arm_r9 = 9, // 9 36 4 int32_t
+ gdb_arm_r10 = 10, // 10 40 4 int32_t
+ gdb_arm_r11 = 11, // 11 44 4 int32_t
+ gdb_arm_r12 = 12, // 12 48 4 int32_t
+ gdb_arm_sp = 13, // 13 52 4 int32_t
+ gdb_arm_lr = 14, // 14 56 4 int32_t
+ gdb_arm_pc = 15, // 15 60 4 int32_t
+ gdb_arm_f0 = 16, // 16 64 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f1 = 17, // 17 76 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f2 = 18, // 18 88 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f3 = 19, // 19 100 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f4 = 20, // 20 112 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f5 = 21, // 21 124 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f6 = 22, // 22 136 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f7 = 23, // 23 148 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f8 = 24, // 24 160 12 _arm_ext_littlebyte_bigword
+ gdb_arm_cpsr = 25, // 25 172 4 int32_t
+ gdb_arm_s0 = 26, // 26 176 4 _ieee_single_little
+ gdb_arm_s1 = 27, // 27 180 4 _ieee_single_little
+ gdb_arm_s2 = 28, // 28 184 4 _ieee_single_little
+ gdb_arm_s3 = 29, // 29 188 4 _ieee_single_little
+ gdb_arm_s4 = 30, // 30 192 4 _ieee_single_little
+ gdb_arm_s5 = 31, // 31 196 4 _ieee_single_little
+ gdb_arm_s6 = 32, // 32 200 4 _ieee_single_little
+ gdb_arm_s7 = 33, // 33 204 4 _ieee_single_little
+ gdb_arm_s8 = 34, // 34 208 4 _ieee_single_little
+ gdb_arm_s9 = 35, // 35 212 4 _ieee_single_little
+ gdb_arm_s10 = 36, // 36 216 4 _ieee_single_little
+ gdb_arm_s11 = 37, // 37 220 4 _ieee_single_little
+ gdb_arm_s12 = 38, // 38 224 4 _ieee_single_little
+ gdb_arm_s13 = 39, // 39 228 4 _ieee_single_little
+ gdb_arm_s14 = 40, // 40 232 4 _ieee_single_little
+ gdb_arm_s15 = 41, // 41 236 4 _ieee_single_little
+ gdb_arm_s16 = 42, // 42 240 4 _ieee_single_little
+ gdb_arm_s17 = 43, // 43 244 4 _ieee_single_little
+ gdb_arm_s18 = 44, // 44 248 4 _ieee_single_little
+ gdb_arm_s19 = 45, // 45 252 4 _ieee_single_little
+ gdb_arm_s20 = 46, // 46 256 4 _ieee_single_little
+ gdb_arm_s21 = 47, // 47 260 4 _ieee_single_little
+ gdb_arm_s22 = 48, // 48 264 4 _ieee_single_little
+ gdb_arm_s23 = 49, // 49 268 4 _ieee_single_little
+ gdb_arm_s24 = 50, // 50 272 4 _ieee_single_little
+ gdb_arm_s25 = 51, // 51 276 4 _ieee_single_little
+ gdb_arm_s26 = 52, // 52 280 4 _ieee_single_little
+ gdb_arm_s27 = 53, // 53 284 4 _ieee_single_little
+ gdb_arm_s28 = 54, // 54 288 4 _ieee_single_little
+ gdb_arm_s29 = 55, // 55 292 4 _ieee_single_little
+ gdb_arm_s30 = 56, // 56 296 4 _ieee_single_little
+ gdb_arm_s31 = 57, // 57 300 4 _ieee_single_little
+ gdb_arm_fpscr = 58, // 58 304 4 int32_t
+ gdb_arm_d16 = 59, // 59 308 8 _ieee_double_little
+ gdb_arm_d17 = 60, // 60 316 8 _ieee_double_little
+ gdb_arm_d18 = 61, // 61 324 8 _ieee_double_little
+ gdb_arm_d19 = 62, // 62 332 8 _ieee_double_little
+ gdb_arm_d20 = 63, // 63 340 8 _ieee_double_little
+ gdb_arm_d21 = 64, // 64 348 8 _ieee_double_little
+ gdb_arm_d22 = 65, // 65 356 8 _ieee_double_little
+ gdb_arm_d23 = 66, // 66 364 8 _ieee_double_little
+ gdb_arm_d24 = 67, // 67 372 8 _ieee_double_little
+ gdb_arm_d25 = 68, // 68 380 8 _ieee_double_little
+ gdb_arm_d26 = 69, // 69 388 8 _ieee_double_little
+ gdb_arm_d27 = 70, // 70 396 8 _ieee_double_little
+ gdb_arm_d28 = 71, // 71 404 8 _ieee_double_little
+ gdb_arm_d29 = 72, // 72 412 8 _ieee_double_little
+ gdb_arm_d30 = 73, // 73 420 8 _ieee_double_little
+ gdb_arm_d31 = 74, // 74 428 8 _ieee_double_little
+ gdb_arm_d0 = 75, // 0 436 8 _ieee_double_little
+ gdb_arm_d1 = 76, // 1 444 8 _ieee_double_little
+ gdb_arm_d2 = 77, // 2 452 8 _ieee_double_little
+ gdb_arm_d3 = 78, // 3 460 8 _ieee_double_little
+ gdb_arm_d4 = 79, // 4 468 8 _ieee_double_little
+ gdb_arm_d5 = 80, // 5 476 8 _ieee_double_little
+ gdb_arm_d6 = 81, // 6 484 8 _ieee_double_little
+ gdb_arm_d7 = 82, // 7 492 8 _ieee_double_little
+ gdb_arm_d8 = 83, // 8 500 8 _ieee_double_little
+ gdb_arm_d9 = 84, // 9 508 8 _ieee_double_little
+ gdb_arm_d10 = 85, // 10 516 8 _ieee_double_little
+ gdb_arm_d11 = 86, // 11 524 8 _ieee_double_little
+ gdb_arm_d12 = 87, // 12 532 8 _ieee_double_little
+ gdb_arm_d13 = 88, // 13 540 8 _ieee_double_little
+ gdb_arm_d14 = 89, // 14 548 8 _ieee_double_little
+ gdb_arm_d15 = 90, // 15 556 8 _ieee_double_little
+ gdb_arm_q0 = 91, // 16 564 16 _vec128
+ gdb_arm_q1 = 92, // 17 580 16 _vec128
+ gdb_arm_q2 = 93, // 18 596 16 _vec128
+ gdb_arm_q3 = 94, // 19 612 16 _vec128
+ gdb_arm_q4 = 95, // 20 628 16 _vec128
+ gdb_arm_q5 = 96, // 21 644 16 _vec128
+ gdb_arm_q6 = 97, // 22 660 16 _vec128
+ gdb_arm_q7 = 98, // 23 676 16 _vec128
+ gdb_arm_q8 = 99, // 24 692 16 _vec128
+ gdb_arm_q9 = 100, // 25 708 16 _vec128
+ gdb_arm_q10 = 101, // 26 724 16 _vec128
+ gdb_arm_q11 = 102, // 27 740 16 _vec128
+ gdb_arm_q12 = 103, // 28 756 16 _vec128
+ gdb_arm_q13 = 104, // 29 772 16 _vec128
+ gdb_arm_q14 = 105, // 30 788 16 _vec128
+ gdb_arm_q15 = 106 // 31 804 16 _vec128
+};
#endif // utility_ARM_GCC_Registers_h_
Modified: lldb/branches/windows/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNB.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNB.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/DNB.cpp Wed Apr 17 03:38:48 2013
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "DNB.h"
+#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -1219,22 +1220,22 @@ DNBProcessMemoryRegionInfo (nub_process_
}
std::string
-DNBProcessGetProfileData (nub_process_t pid)
+DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType)
{
MachProcessSP procSP;
if (GetProcessSP (pid, procSP))
- return procSP->Task().GetProfileData();
+ return procSP->Task().GetProfileData(scanType);
return std::string("");
}
nub_bool_t
-DNBProcessSetAsyncEnableProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec)
+DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
{
MachProcessSP procSP;
if (GetProcessSP (pid, procSP))
{
- procSP->SetAsyncEnableProfiling(enable, interval_usec);
+ procSP->SetEnableAsyncProfiling(enable, interval_usec, scan_type);
return true;
}
@@ -1385,7 +1386,7 @@ DNBPrintf (nub_process_t pid, nub_thread
}
else
{
- fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.4x\n", register_name.c_str(), pid, tid);
+ fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.8" PRIx64 "\n", register_name.c_str(), pid, tid);
return total_bytes_read;
}
}
@@ -1771,6 +1772,18 @@ DNBProcessGetCurrentThread (nub_process_
return 0;
}
+//----------------------------------------------------------------------
+// Get the mach port number of the current thread.
+//----------------------------------------------------------------------
+nub_thread_t
+DNBProcessGetCurrentThreadMachPort (nub_process_t pid)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ return procSP->GetCurrentThreadMachPort();
+ return 0;
+}
+
//----------------------------------------------------------------------
// Change the current thread.
//----------------------------------------------------------------------
Modified: lldb/branches/windows/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNB.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNB.h (original)
+++ lldb/branches/windows/tools/debugserver/source/DNB.h Wed Apr 17 03:38:48 2013
@@ -63,8 +63,8 @@ nub_size_t DNBProcessMemoryWrite
nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT;
nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
int DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT;
-std::string DNBProcessGetProfileData (nub_process_t pid) DNB_EXPORT;
-nub_bool_t DNBProcessSetAsyncEnableProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec) DNB_EXPORT;
+std::string DNBProcessGetProfileData (nub_process_t pid, DNBProfileDataScanType scanType) DNB_EXPORT;
+nub_bool_t DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec, DNBProfileDataScanType scan_type) DNB_EXPORT;
//----------------------------------------------------------------------
// Process status
@@ -75,6 +75,7 @@ nub_bool_t DNBProcessGetExitStatus
nub_bool_t DNBProcessSetExitStatus (nub_process_t pid, int status) DNB_EXPORT;
nub_size_t DNBProcessGetNumThreads (nub_process_t pid) DNB_EXPORT;
nub_thread_t DNBProcessGetCurrentThread (nub_process_t pid) DNB_EXPORT;
+nub_thread_t DNBProcessGetCurrentThreadMachPort (nub_process_t pid) DNB_EXPORT;
nub_thread_t DNBProcessSetCurrentThread (nub_process_t pid, nub_thread_t tid) DNB_EXPORT;
nub_thread_t DNBProcessGetThreadAtIndex (nub_process_t pid, nub_size_t thread_idx) DNB_EXPORT;
nub_bool_t DNBProcessSyncThreadState (nub_process_t pid, nub_thread_t tid) DNB_EXPORT;
Modified: lldb/branches/windows/tools/debugserver/source/DNBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBBreakpoint.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBBreakpoint.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBBreakpoint.cpp Wed Apr 17 03:38:48 2013
@@ -13,6 +13,7 @@
#include "DNBBreakpoint.h"
#include <algorithm>
+#include <inttypes.h>
#include "DNBLog.h"
@@ -77,7 +78,7 @@ DNBBreakpoint::Dump() const
{
if (IsBreakpoint())
{
- DNBLog ("DNBBreakpoint %u: tid = %4.4x addr = 0x%llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
+ DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 " addr = 0x%llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
m_breakID,
m_tid,
(uint64_t)m_addr,
@@ -91,7 +92,7 @@ DNBBreakpoint::Dump() const
}
else
{
- DNBLog ("DNBBreakpoint %u: tid = %4.4x addr = 0x%llx size = %llu state = %s type = %s watchpoint (%s%s) hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
+ DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 " addr = 0x%llx size = %llu state = %s type = %s watchpoint (%s%s) hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
m_breakID,
m_tid,
(uint64_t)m_addr,
Modified: lldb/branches/windows/tools/debugserver/source/DNBDataRef.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBDataRef.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBDataRef.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBDataRef.cpp Wed Apr 17 03:38:48 2013
@@ -195,105 +195,6 @@ DNBDataRef::GetPointer(offset_t *offset_
assert(m_ptrSize != 0);
return GetMax64(offset_ptr, m_ptrSize);
}
-
-//----------------------------------------------------------------------
-// GetDwarfEHPtr
-//
-// Used for calls when the value type is specified by a DWARF EH Frame
-// pointer encoding.
-//----------------------------------------------------------------------
-/*
-uint64_t
-DNBDataRef::GetDwarfEHPtr(offset_t *offset_ptr, uint32_t encoding) const
-{
- if (encoding == DW_EH_PE_omit)
- return ULLONG_MAX; // Value isn't in the buffer...
-
- uint64_t baseAddress = 0;
- uint64_t addressValue = 0;
-
- BOOL signExtendValue = NO;
- // Decode the base part or adjust our offset
- switch (encoding & 0x70)
- {
- case DW_EH_PE_pcrel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrPCRelative != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = *offset_ptr + m_addrPCRelative;
- break;
-
- case DW_EH_PE_textrel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrTEXT != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = m_addrTEXT;
- break;
-
- case DW_EH_PE_datarel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrDATA != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = m_addrDATA;
- break;
-
- case DW_EH_PE_funcrel:
- signExtendValue = YES;
- break;
-
- case DW_EH_PE_aligned:
- // SetPointerSize should be called prior to extracting these so the
- // pointer size is cached
- assert(m_ptrSize != 0);
- if (m_ptrSize)
- {
- // Align to a address size boundary first
- uint32_t alignOffset = *offset_ptr % m_ptrSize;
- if (alignOffset)
- offset_ptr += m_ptrSize - alignOffset;
- }
- break;
-
- default:
- break;
- }
-
- // Decode the value part
- switch (encoding & DW_EH_PE_MASK_ENCODING)
- {
- case DW_EH_PE_absptr : addressValue = GetPointer(offset_ptr); break;
- case DW_EH_PE_uleb128 : addressValue = Get_ULEB128(offset_ptr); break;
- case DW_EH_PE_udata2 : addressValue = Get16(offset_ptr); break;
- case DW_EH_PE_udata4 : addressValue = Get32(offset_ptr); break;
- case DW_EH_PE_udata8 : addressValue = Get64(offset_ptr); break;
- case DW_EH_PE_sleb128 : addressValue = Get_SLEB128(offset_ptr); break;
- case DW_EH_PE_sdata2 : addressValue = (int16_t)Get16(offset_ptr); break;
- case DW_EH_PE_sdata4 : addressValue = (int32_t)Get32(offset_ptr); break;
- case DW_EH_PE_sdata8 : addressValue = (int64_t)Get64(offset_ptr); break;
- default:
- // Unhandled encoding type
- assert(encoding);
- break;
- }
-
- // Since we promote everything to 64 bit, we may need to sign extend
- if (signExtendValue && m_ptrSize < sizeof(baseAddress))
- {
- uint64_t sign_bit = 1ull << ((m_ptrSize * 8ull) - 1ull);
- if (sign_bit & addressValue)
- {
- uint64_t mask = ~sign_bit + 1;
- addressValue |= mask;
- }
- }
- return baseAddress + addressValue;
-}
-*/
-
-
//----------------------------------------------------------------------
// GetCStr
//----------------------------------------------------------------------
Modified: lldb/branches/windows/tools/debugserver/source/DNBDataRef.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBDataRef.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBDataRef.h (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBDataRef.h Wed Apr 17 03:38:48 2013
@@ -56,8 +56,22 @@ public:
m_swap = false;
}
- bool ValidOffset(offset_t offset) const { return (m_start < m_end) && ((uint32_t)(m_end - m_start) > offset); }
- bool ValidOffsetForDataOfSize(offset_t offset, uint32_t num_bytes) const { return (m_start < m_end) && ((uint32_t)(m_end - m_start) > (offset + ((num_bytes > 0) ? (num_bytes - 1) : 0))); }
+ offset_t BytesLeft (offset_t offset) const
+ {
+ const offset_t size = GetSize();
+ if (size > offset)
+ return size - offset;
+ return 0;
+ }
+
+ bool ValidOffset(offset_t offset) const
+ {
+ return BytesLeft(offset) > 0;
+ }
+ bool ValidOffsetForDataOfSize(offset_t offset, uint32_t num_bytes) const
+ {
+ return num_bytes <= BytesLeft (offset);
+ }
size_t GetSize() const { return m_end - m_start; }
const uint8_t * GetDataStart() const { return m_start; }
const uint8_t * GetDataEnd() const { return m_end; }
Modified: lldb/branches/windows/tools/debugserver/source/DNBDefs.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBDefs.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBDefs.h (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBDefs.h Wed Apr 17 03:38:48 2013
@@ -73,7 +73,7 @@ typedef uint32_t nub_break_t;
typedef uint32_t nub_watch_t;
typedef uint32_t nub_index_t;
typedef pid_t nub_process_t;
-typedef unsigned int nub_thread_t;
+typedef uint64_t nub_thread_t;
typedef uint32_t nub_event_t;
typedef uint32_t nub_bool_t;
@@ -230,6 +230,8 @@ struct DNBRegisterInfo
uint32_t reg_dwarf; // DWARF register number (INVALID_NUB_REGNUM when none)
uint32_t reg_generic; // Generic register number (INVALID_NUB_REGNUM when none)
uint32_t reg_gdb; // The GDB register number (INVALID_NUB_REGNUM when none)
+ uint32_t *pseudo_regs; // If this register is a part of another register, list the one or more registers
+ uint32_t *update_regs; // If modifying this register will invalidate other registers, list them here
};
struct DNBRegisterSetInfo
@@ -356,6 +358,23 @@ struct DNBRegionInfo
uint32_t permissions;
};
+enum DNBProfileDataScanType
+{
+ eProfileHostCPU = (1 << 0),
+ eProfileCPU = (1 << 1),
+
+ eProfileThreadsCPU = (1 << 2), // By default excludes eProfileThreadName and eProfileQueueName.
+ eProfileThreadName = (1 << 3), // Assume eProfileThreadsCPU, get thread name as well.
+ eProfileQueueName = (1 << 4), // Assume eProfileThreadsCPU, get queue name as well.
+
+ eProfileHostMemory = (1 << 5),
+
+ eProfileMemory = (1 << 6), // By default, excludes eProfileMemoryDirtyPage.
+ eProfileMemoryDirtyPage = (1 << 7), // Assume eProfileMemory, get Dirty Page size as well.
+
+ eProfileAll = 0xffffffff
+};
+
typedef nub_bool_t (*DNBCallbackBreakpointHit)(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton);
typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid, const char *name, const char *shlib_regex, void *baton);
typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(nub_process_t pid, struct DNBExecutableImageInfo **image_infos, nub_bool_t only_changed, void *baton);
Modified: lldb/branches/windows/tools/debugserver/source/DNBLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBLog.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBLog.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBLog.cpp Wed Apr 17 03:38:48 2013
@@ -84,6 +84,12 @@ DNBLogSetLogCallback (DNBCallbackLog cal
g_log_baton = baton;
}
+DNBCallbackLog
+DNBLogGetLogCallback ()
+{
+ return g_log_callback;
+}
+
bool
DNBLogEnabled ()
{
Modified: lldb/branches/windows/tools/debugserver/source/DNBLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNBLog.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNBLog.h (original)
+++ lldb/branches/windows/tools/debugserver/source/DNBLog.h Wed Apr 17 03:38:48 2013
@@ -50,6 +50,7 @@ bool DNBLogCheckLogBit (uint32_t
uint32_t DNBLogSetLogMask (uint32_t mask) DNB_EXPORT;
uint32_t DNBLogGetLogMask () DNB_EXPORT;
void DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) DNB_EXPORT;
+DNBCallbackLog DNBLogGetLogCallback () DNB_EXPORT;
bool DNBLogEnabled () DNB_EXPORT;
bool DNBLogEnabledForAny (uint32_t mask) DNB_EXPORT;
int DNBLogGetDebug () DNB_EXPORT;
Removed: lldb/branches/windows/tools/debugserver/source/FunctionProfiler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/FunctionProfiler.cpp?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/FunctionProfiler.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/FunctionProfiler.cpp (removed)
@@ -1,288 +0,0 @@
-//===-- FunctionProfiler.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 10/8/08.
-//
-//===----------------------------------------------------------------------===//
-
-#include "FunctionProfiler.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "DNB.h"
-
-// Project includes
-
-//----------------------------------------------------------------------
-// FunctionProfiler constructor
-//----------------------------------------------------------------------
-FunctionProfiler::FunctionProfiler(nub_addr_t start_addr, nub_addr_t stop_addr) :
- m_pid(INVALID_NUB_PROCESS),
- m_start_addr(start_addr),
- m_stop_addr(stop_addr),
- m_start_break_id(INVALID_NUB_BREAK_ID),
- m_stop_break_id(INVALID_NUB_BREAK_ID),
- m_func_entered_count(0),
- m_last_pc(0),
- m_last_flags(0),
- m_consecutive_opcode_count(0),
- m_total_opcode_count(0)
-{
-}
-
-
-FunctionProfiler::~FunctionProfiler()
-{
- Clear();
-}
-
-
-void
-FunctionProfiler::Clear()
-{
- if (m_pid != INVALID_NUB_PROCESS)
- {
- if (m_start_break_id != INVALID_NUB_BREAK_ID)
- DNBBreakpointClear(m_pid, m_start_break_id);
- if (m_stop_break_id != INVALID_NUB_BREAK_ID)
- DNBBreakpointClear(m_pid, m_stop_break_id);
- }
- m_start_break_id = INVALID_NUB_BREAK_ID;
- m_stop_break_id = INVALID_NUB_BREAK_ID;
- m_func_entered_count = 0;
- m_last_pc = 0;
- m_last_flags = 0;
- m_consecutive_opcode_count = 0;
-}
-
-void
-FunctionProfiler::Initialize(nub_process_t pid)
-{
- //printf("FunctionProfiler::%s(0x%4.4x)\n", __FUNCTION__, pid);
- Clear();
- m_pid = pid;
-}
-
-#include "DNBDataRef.h"
-
-void
-FunctionProfiler::SetBreakpoints()
-{
-#if defined (__i386__)
- nub_size_t bp_opcode_size = 1;
-#elif defined (__powerpc__) || defined (__ppc__)
- nub_size_t bp_opcode_size = 4;
-#endif
- if (m_start_addr != INVALID_NUB_ADDRESS && !NUB_BREAK_ID_IS_VALID(m_start_break_id))
- {
-#if defined (__arm__)
- m_start_break_id = DNBBreakpointSet(m_pid, m_start_addr & 0xFFFFFFFEu, m_start_addr & 1 ? 2 : 4, false);
-#else
- m_start_break_id = DNBBreakpointSet(m_pid, m_start_addr, bp_opcode_size, false);
-#endif
- if (NUB_BREAK_ID_IS_VALID(m_start_break_id))
- DNBBreakpointSetCallback(m_pid, m_start_break_id, FunctionProfiler::BreakpointHitCallback, this);
- }
- if (m_stop_addr != INVALID_NUB_ADDRESS && !NUB_BREAK_ID_IS_VALID(m_stop_break_id))
- {
-#if defined (__arm__)
- m_stop_break_id = DNBBreakpointSet(m_pid, m_stop_addr & 0xFFFFFFFEu, m_stop_addr & 1 ? 2 : 4, false);
-#else
- m_stop_break_id = DNBBreakpointSet(m_pid, m_stop_addr, bp_opcode_size, false);
-#endif
- if (NUB_BREAK_ID_IS_VALID(m_stop_break_id))
- DNBBreakpointSetCallback(m_pid, m_stop_break_id, FunctionProfiler::BreakpointHitCallback, this);
- }
-}
-
-nub_bool_t
-FunctionProfiler::BreakpointHitCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
-{
- printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u, baton = %p)\n", __FUNCTION__, pid, tid, breakID, baton);
- return ((FunctionProfiler*) baton)->BreakpointHit(pid, tid, breakID);
-}
-
-nub_bool_t
-FunctionProfiler::BreakpointHit(nub_process_t pid, nub_thread_t tid, nub_break_t breakID)
-{
- printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u)\n", __FUNCTION__, pid, tid, breakID);
- if (breakID == m_start_break_id)
- {
- m_func_entered_count++;
- printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u) START breakpoint hit (%u)\n", __FUNCTION__, pid, tid, breakID, m_func_entered_count);
- }
- else if (breakID == m_stop_break_id)
- {
- if (m_func_entered_count > 0)
- m_func_entered_count--;
- printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u) STOP breakpoint hit (%u)\n", __FUNCTION__, pid, tid, breakID, m_func_entered_count);
- }
- return true;
-}
-
-void
-FunctionProfiler::ProcessStateChanged(nub_state_t state)
-{
-// printf("FunctionProfiler::%s(%s)\n", __FUNCTION__, DNBStateAsString(state));
-
- switch (state)
- {
- case eStateInvalid:
- case eStateUnloaded:
- case eStateAttaching:
- case eStateLaunching:
- break;
-
- case eStateDetached:
- case eStateExited:
- // No sense is clearing out breakpoints if our process has exited...
- m_start_break_id = INVALID_NUB_BREAK_ID;
- m_stop_break_id = INVALID_NUB_BREAK_ID;
- printf("[0x%8.8x - 0x%8.8x) executed %u total opcodes.\n", m_total_opcode_count);
- break;
-
- case eStateStopped:
- // Keep trying find dyld each time we stop until we do
- if (!NUB_BREAK_ID_IS_VALID(m_start_break_id))
- SetBreakpoints();
-
- if (ShouldStepProcess())
- {
-
- // TODO: do logging/tracing here
- nub_thread_t tid = DNBProcessGetCurrentThread(m_pid);
- DNBRegisterValue reg;
- m_total_opcode_count++;
-
- if (DNBThreadGetRegisterValueByID(m_pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, ®))
- {
- const nub_addr_t pc = reg.value.uint32;
-
-#if defined (__i386__)
- uint8_t buf[16];
- uint32_t bytes_read = DNBProcessMemoryRead(m_pid, pc, 1, buf);
- if (bytes_read == 1)
- printf("0x%8.8x: %2.2x\n", pc, buf[0]);
- else
- printf("0x%8.8x: error: can't read opcode byte.\n", pc);
-
-// if (bytes_read > 0)
-// {
-// for (uint32_t i=0; i<bytes_read; ++i)
-// {
-// printf(" %2.2x", buf[i]);
-// }
-// }
-// printf("\n");
-
-#elif defined (__powerpc__) || defined (__ppc__)
-
- uint32_t opcode = 0;
- if (DNBProcessMemoryRead(m_pid, pc, 4, &opcode) == 4)
- {
- printf("0x%8.8x: 0x%8.8x\n", pc, opcode);
- }
-
-#elif defined (__arm__)
- #define CPSR_T (1u << 5)
- // Read the CPSR into flags
- if (DNBThreadGetRegisterValueByID(m_pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FLAGS, ®))
- {
- const uint32_t flags = reg.value.uint32;
-
- const bool curr_pc_is_thumb = (flags & CPSR_T) != 0; // check the CPSR T bit
- const bool last_pc_was_thumb = (m_last_flags & CPSR_T) != 0; // check the CPSR T bit
- bool opcode_is_sequential = false;
-
- uint32_t opcode;
- // Always read four bytes for the opcode
- if (DNBProcessMemoryRead(m_pid, pc, 4, &opcode) == 4)
- {
- if (curr_pc_is_thumb)
- {
- // Trim off the high 16 bits if this is a 16 bit thumb instruction
- if ((opcode & 0xe000) != 0xe000 || (opcode & 0x1800) == 0)
- {
- opcode &= 0xFFFFu;
- printf("0x%8.8x: %4.4x Thumb\n", pc, opcode);
- }
- else
- printf("0x%8.8x: %8.8x Thumb\n", pc, opcode);
- }
- else
- printf("0x%8.8x: %8.8x ARM\n", pc, opcode);
- }
-
- if (m_last_flags != 0 && curr_pc_is_thumb == last_pc_was_thumb)
- {
- if (curr_pc_is_thumb)
- {
- if (pc == m_last_pc + 2)
- {
- opcode_is_sequential = true;
- }
- else if (pc == m_last_pc + 4)
- {
- // Check for 32 bit thumb instruction...
- uint16_t opcode16;
- if (DNBProcessMemoryRead(m_pid, m_last_pc, 2, &opcode16) == 2)
- {
- if ((opcode16 & 0xe000) == 0xe000 && (opcode16 & 0x1800) != 0)
- {
- // Last opcode was a 32 bit thumb instruction...
- opcode_is_sequential = true;
- }
- }
- }
- }
- else
- {
- if (pc == m_last_pc + 4)
- {
- opcode_is_sequential = true;
- }
- }
- }
-
-
- if (opcode_is_sequential)
- {
- m_consecutive_opcode_count++;
- }
- else
- {
- if (m_consecutive_opcode_count > 0)
- {
- // printf(" x %u\n", m_consecutive_opcode_count);
- }
- m_consecutive_opcode_count = 1;
- //printf("0x%8.8x: %-5s", pc, curr_pc_is_thumb ? "Thumb" : "ARM");
- //fflush(stdout);
- }
- m_last_flags = flags;
- }
-#else
-#error undefined architecture
-#endif
- m_last_pc = pc;
- }
- }
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
-
- default:
- break;
- }
-}
Removed: lldb/branches/windows/tools/debugserver/source/FunctionProfiler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/FunctionProfiler.h?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/FunctionProfiler.h (original)
+++ lldb/branches/windows/tools/debugserver/source/FunctionProfiler.h (removed)
@@ -1,70 +0,0 @@
-//===-- FunctionProfiler.h --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 10/8/08.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __FunctionProfiler_h__
-#define __FunctionProfiler_h__
-
-// C Includes
-
-// C++ Includes
-#include <map>
-#include <vector>
-#include <string>
-
-// Other libraries and framework includes
-
-// Project includes
-#include "DNBDefs.h"
-#include "DNBRuntimeAction.h"
-#include "PThreadMutex.h"
-
-class DNBBreakpoint;
-class MachProcess;
-
-class FunctionProfiler : public DNBRuntimeAction
-{
-public:
- FunctionProfiler (nub_addr_t start_addr, nub_addr_t stop_addr);
- virtual ~FunctionProfiler ();
-
- //------------------------------------------------------------------
- // DNBRuntimeAction required functions
- //------------------------------------------------------------------
- virtual void Initialize(nub_process_t pid);
- virtual void ProcessStateChanged(nub_state_t state);
- virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos, nub_size_t num_image_infos) {}
-
- nub_bool_t BreakpointHit(nub_process_t pid, nub_thread_t tid, nub_break_t breakID);
- bool ShouldStepProcess() const
- {
- return m_func_entered_count > 0;
- }
-protected:
- static nub_bool_t BreakpointHitCallback (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton);
- void Clear();
- void SetBreakpoints();
-
- nub_process_t m_pid;
- nub_addr_t m_start_addr;
- nub_addr_t m_stop_addr;
- nub_break_t m_start_break_id;
- nub_break_t m_stop_break_id;
- uint32_t m_func_entered_count;
- nub_addr_t m_last_pc;
- uint32_t m_last_flags;
- uint32_t m_consecutive_opcode_count;
- uint32_t m_total_opcode_count;
-};
-
-
-#endif // __FunctionProfiler_h__
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachException.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachException.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachException.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachException.cpp Wed Apr 17 03:38:48 2013
@@ -384,7 +384,7 @@ MachException::Message::Reply(MachProces
if (state_pid != -1)
{
errno = 0;
- if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)state.thread_port, soft_signal) != 0)
+ if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)((uintptr_t)state.thread_port), soft_signal) != 0)
err.SetError(errno, DNBError::POSIX);
else
err.Clear();
@@ -480,6 +480,17 @@ MachException::Data::Dump() const
EXC_MASK_RPC_ALERT | \
EXC_MASK_MACHINE)
+// Don't listen for EXC_RESOURCE, it should really get handled by the system handler.
+
+#ifndef EXC_RESOURCE
+#define EXC_RESOURCE 11
+#endif
+
+#ifndef EXC_MASK_RESOURCE
+#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
+#endif
+
+#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
kern_return_t
MachException::PortInfo::Save (task_t task)
@@ -490,7 +501,7 @@ MachException::PortInfo::Save (task_t ta
// and back off to just what is supported on the current system
DNBError err;
- mask = EXC_MASK_ALL;
+ mask = LLDB_EXC_MASK;
count = (sizeof (ports) / sizeof (ports[0]));
err = ::task_get_exception_ports (task, mask, masks, &count, ports, behaviors, flavors);
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.cpp Wed Apr 17 03:38:48 2013
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "DNB.h"
+#include <inttypes.h>
#include <mach/mach.h>
#include <signal.h>
#include <spawn.h>
@@ -156,14 +157,20 @@ MachProcess::GetThreadAtIndex (nub_size_
return m_thread_list.ThreadIDAtIndex(thread_idx);
}
+nub_thread_t
+MachProcess::GetThreadIDForMachPortNumber (thread_t mach_port_number) const
+{
+ return m_thread_list.GetThreadIDByMachPortNumber (mach_port_number);
+}
+
nub_bool_t
MachProcess::SyncThreadState (nub_thread_t tid)
{
MachThreadSP thread_sp(m_thread_list.GetThreadByID(tid));
if (!thread_sp)
return false;
- kern_return_t kret = ::thread_abort_safely(thread_sp->ThreadID());
- DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", thread_sp->ThreadID(), kret, thread_sp->Process()->StopCount());
+ kern_return_t kret = ::thread_abort_safely(thread_sp->MachPortNumber());
+ DNBLogThreadedIf (LOG_THREAD, "thread = 0x%8.8" PRIx32 " calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", thread_sp->MachPortNumber(), kret, thread_sp->Process()->StopCount());
if (kret == KERN_SUCCESS)
return true;
@@ -179,6 +186,12 @@ MachProcess::GetCurrentThread ()
}
nub_thread_t
+MachProcess::GetCurrentThreadMachPort ()
+{
+ return m_thread_list.GetMachPortNumberByThreadID(m_thread_list.CurrentThreadID());
+}
+
+nub_thread_t
MachProcess::SetCurrentThread(nub_thread_t tid)
{
return m_thread_list.SetCurrentThread(tid);
@@ -308,15 +321,21 @@ MachProcess::StartSTDIOThread()
}
void
-MachProcess::SetAsyncEnableProfiling(bool enable, uint64_t interval_usec)
+MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec, DNBProfileDataScanType scan_type)
{
m_profile_enabled = enable;
m_profile_interval_usec = interval_usec;
+ m_profile_scan_type = scan_type;
- if (m_profile_enabled && (m_profile_thread == 0))
+ if (m_profile_enabled && (m_profile_thread == NULL))
{
StartProfileThread();
}
+ else if (!m_profile_enabled && m_profile_thread)
+ {
+ pthread_join(m_profile_thread, NULL);
+ m_profile_thread = NULL;
+ }
}
bool
@@ -350,10 +369,10 @@ MachProcess::Resume (const DNBThreadResu
}
else if (state == eStateRunning)
{
- DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x is running, ignoring...", m_task.TaskPort());
+ DNBLog("Resume() - task 0x%x is already running, ignoring...", m_task.TaskPort());
return true;
}
- DNBLogThreadedIf(LOG_PROCESS, "Resume() - task 0x%x can't continue, ignoring...", m_task.TaskPort());
+ DNBLog("Resume() - task 0x%x has state %s, can't continue...", m_task.TaskPort(), DNBStateAsString(state));
return false;
}
@@ -371,6 +390,21 @@ MachProcess::Kill (const struct timespec
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", m_pid, err.Error(), err.AsString());
m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
PrivateResume ();
+
+ // Try and reap the process without touching our m_events since
+ // we want the code above this to still get the eStateExited event
+ const uint32_t reap_timeout_usec = 1000000; // Wait 1 second and try to reap the process
+ const uint32_t reap_interval_usec = 10000; //
+ uint32_t reap_time_elapsed;
+ for (reap_time_elapsed = 0;
+ reap_time_elapsed < reap_timeout_usec;
+ reap_time_elapsed += reap_interval_usec)
+ {
+ if (GetState() == eStateExited)
+ break;
+ usleep(reap_interval_usec);
+ }
+ DNBLog ("Waited %u ms for process to be reaped (state = %s)", reap_time_elapsed/1000, DNBStateAsString(GetState()));
return true;
}
@@ -645,13 +679,18 @@ MachProcess::ReplyToAllExceptions ()
DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %u...", (uint32_t)std::distance(begin, pos));
int thread_reply_signal = 0;
- const DNBThreadResumeAction *action = m_thread_actions.GetActionForThread (pos->state.thread_port, false);
+ nub_thread_t tid = m_thread_list.GetThreadIDByMachPortNumber (pos->state.thread_port);
+ const DNBThreadResumeAction *action = NULL;
+ if (tid != INVALID_NUB_THREAD)
+ {
+ action = m_thread_actions.GetActionForThread (tid, false);
+ }
if (action)
{
thread_reply_signal = action->signal;
if (thread_reply_signal)
- m_thread_actions.SetSignalHandledForThread (pos->state.thread_port);
+ m_thread_actions.SetSignalHandledForThread (tid);
}
DNBError err (pos->Reply(this, thread_reply_signal));
@@ -1394,7 +1433,7 @@ MachProcess::ProfileThread(void *arg)
nub_state_t state = proc->GetState();
if (state == eStateRunning)
{
- std::string data = proc->Task().GetProfileData();
+ std::string data = proc->Task().GetProfileData(proc->GetProfileScanType());
if (!data.empty())
{
proc->SignalAsyncProfileData(data.c_str());
@@ -1489,7 +1528,8 @@ MachProcess::PrepareForAttach (const cha
return NULL;
const char *app_ext = strstr(path, ".app");
- if (app_ext == NULL)
+ const bool is_app = app_ext != NULL && (app_ext[4] == '\0' || app_ext[4] == '/');
+ if (!is_app)
{
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::PrepareForAttach(): path '%s' doesn't contain .app, we can't tell springboard to wait for launch...", path);
return NULL;
@@ -1634,8 +1674,22 @@ MachProcess::LaunchForDebug
case eLaunchFlavorSpringBoard:
{
- const char *app_ext = strstr(path, ".app");
- if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/'))
+ // .../whatever.app/whatever ?
+ // Or .../com.apple.whatever.app/whatever -- be careful of ".app" in "com.apple.whatever" here
+ const char *app_ext = strstr (path, ".app/");
+ if (app_ext == NULL)
+ {
+ // .../whatever.app ?
+ int len = strlen (path);
+ if (len > 5)
+ {
+ if (strcmp (path + len - 4, ".app") == 0)
+ {
+ app_ext = path + len - 4;
+ }
+ }
+ }
+ if (app_ext)
{
std::string app_bundle_path(path, app_ext + strlen(".app"));
if (SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, launch_err) != 0)
@@ -2190,19 +2244,6 @@ MachProcess::SBForkChildForPTraceDebuggi
std::string bundleID;
CFString::UTF8(bundleIDCFStr, bundleID);
- CFData argv_data(NULL);
-
- if (launch_argv.get())
- {
- if (argv_data.Serialize(launch_argv.get(), kCFPropertyListBinaryFormat_v1_0) == NULL)
- {
- DNBLogThreadedIf(LOG_PROCESS, "%s() error: failed to serialize launch arg array...", __FUNCTION__);
- return INVALID_NUB_PROCESS;
- }
- }
-
- DNBLogThreadedIf(LOG_PROCESS, "%s() serialized launch arg array", __FUNCTION__);
-
// Find SpringBoard
SBSApplicationLaunchError sbs_error = 0;
sbs_error = SBSLaunchApplicationForDebugging (bundleIDCFStr,
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachProcess.h Wed Apr 17 03:38:48 2013
@@ -148,7 +148,7 @@ public:
//----------------------------------------------------------------------
// Profile functions
//----------------------------------------------------------------------
- void SetAsyncEnableProfiling (bool enable, uint64_t internal_usec);
+ void SetEnableAsyncProfiling (bool enable, uint64_t internal_usec, DNBProfileDataScanType scan_type);
bool IsProfilingEnabled () { return m_profile_enabled; }
uint64_t ProfileInterval () { return m_profile_interval_usec; }
bool StartProfileThread ();
@@ -176,12 +176,15 @@ public:
nub_size_t GetNumThreads () const;
nub_thread_t GetThreadAtIndex (nub_size_t thread_idx) const;
nub_thread_t GetCurrentThread ();
+ nub_thread_t GetCurrentThreadMachPort ();
nub_thread_t SetCurrentThread (nub_thread_t tid);
MachThreadList & GetThreadList() { return m_thread_list; }
bool GetThreadStoppedReason(nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
void DumpThreadStoppedReason(nub_thread_t tid) const;
const char * GetThreadInfo (nub_thread_t tid) const;
+ nub_thread_t GetThreadIDForMachPortNumber (thread_t mach_port_number) const;
+
uint32_t GetCPUType ();
nub_state_t GetState ();
void SetState (nub_state_t state);
@@ -248,6 +251,9 @@ public:
}
bool ProcessUsingSpringBoard() const { return (m_flags & eMachProcessFlagsUsingSBS) != 0; }
+
+ DNBProfileDataScanType GetProfileScanType () { return m_profile_scan_type; }
+
private:
enum
{
@@ -280,6 +286,7 @@ private:
bool m_profile_enabled; // A flag to indicate if profiling is enabled
uint64_t m_profile_interval_usec; // If enable, the profiling interval in microseconds
+ DNBProfileDataScanType m_profile_scan_type; // Indicates what needs to be profiled
pthread_t m_profile_thread; // Thread ID for the thread that profiles the inferior
PThreadMutex m_profile_data_mutex; // Multithreaded protection for profile info data
std::vector<std::string> m_profile_data; // Profile data, must be protected by m_profile_data_mutex
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.cpp Wed Apr 17 03:38:48 2013
@@ -21,6 +21,7 @@
#include <mach-o/dyld_images.h>
#include <mach/mach_vm.h>
+#import <sys/sysctl.h>
// C++ Includes
#include <iomanip>
@@ -232,7 +233,7 @@ MachTask::GetMemoryRegionInfo (nub_addr_
} while (0)
// We should consider moving this into each MacThread.
-static void get_threads_profile_data(task_t task, nub_process_t pid, int &num_threads, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
+static void get_threads_profile_data(DNBProfileDataScanType scanType, task_t task, nub_process_t pid, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
{
kern_return_t kr;
thread_act_array_t threads;
@@ -242,8 +243,8 @@ static void get_threads_profile_data(tas
if (kr != KERN_SUCCESS)
return;
- num_threads = tcnt;
- for (int i = 0; i < tcnt; i++) {
+ for (int i = 0; i < tcnt; i++)
+ {
thread_identifier_info_data_t identifier_info;
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
kr = ::thread_info(threads[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifier_info, &count);
@@ -254,20 +255,26 @@ static void get_threads_profile_data(tas
kr = ::thread_info(threads[i], THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count);
if (kr != KERN_SUCCESS) continue;
- if ((basic_info.flags & TH_FLAGS_IDLE) == 0) {
- threads_id.push_back(identifier_info.thread_id);
+ if ((basic_info.flags & TH_FLAGS_IDLE) == 0)
+ {
+ nub_thread_t tid = MachThread::GetGloballyUniqueThreadIDForMachPortID (threads[i]);
+ threads_id.push_back(tid);
- if (identifier_info.thread_handle != 0) {
+ if ((scanType & eProfileThreadName) && (identifier_info.thread_handle != 0))
+ {
struct proc_threadinfo proc_threadinfo;
int len = ::proc_pidinfo(pid, PROC_PIDTHREADINFO, identifier_info.thread_handle, &proc_threadinfo, PROC_PIDTHREADINFO_SIZE);
- if (len && proc_threadinfo.pth_name[0]) {
+ if (len && proc_threadinfo.pth_name[0])
+ {
threads_name.push_back(proc_threadinfo.pth_name);
}
- else {
+ else
+ {
threads_name.push_back("");
}
}
- else {
+ else
+ {
threads_name.push_back("");
}
struct timeval tv;
@@ -287,9 +294,29 @@ static void get_threads_profile_data(tas
#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
#define DECIMAL std::dec << std::setfill(' ')
std::string
-MachTask::GetProfileData ()
+MachTask::GetProfileData (DNBProfileDataScanType scanType)
{
std::string result;
+
+ static int32_t numCPU = -1;
+ struct host_cpu_load_info host_info;
+ if (scanType & eProfileHostCPU)
+ {
+ int32_t mib[] = {CTL_HW, HW_AVAILCPU};
+ size_t len = sizeof(numCPU);
+ if (numCPU == -1)
+ {
+ if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0)
+ return result;
+ }
+
+ mach_port_t localHost = mach_host_self();
+ mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+ kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count);
+ if (kr != KERN_SUCCESS)
+ return result;
+ }
+
task_t task = TaskPort();
if (task == TASK_NULL)
return result;
@@ -303,25 +330,31 @@ MachTask::GetProfileData ()
uint64_t elapsed_usec = 0;
uint64_t task_used_usec = 0;
- int num_threads = 0;
+ if (scanType & eProfileCPU)
+ {
+ // Get current used time.
+ struct timeval current_used_time;
+ struct timeval tv;
+ TIME_VALUE_TO_TIMEVAL(&task_info.user_time, ¤t_used_time);
+ TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
+ timeradd(¤t_used_time, &tv, ¤t_used_time);
+ task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
+
+ struct timeval current_elapsed_time;
+ int res = gettimeofday(¤t_elapsed_time, NULL);
+ if (res == 0)
+ {
+ elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
+ }
+ }
+
std::vector<uint64_t> threads_id;
std::vector<std::string> threads_name;
std::vector<uint64_t> threads_used_usec;
-
- // Get current used time.
- struct timeval current_used_time;
- struct timeval tv;
- TIME_VALUE_TO_TIMEVAL(&task_info.user_time, ¤t_used_time);
- TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
- timeradd(¤t_used_time, &tv, ¤t_used_time);
- task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
- get_threads_profile_data(task, m_process->ProcessID(), num_threads, threads_id, threads_name, threads_used_usec);
-
- struct timeval current_elapsed_time;
- int res = gettimeofday(¤t_elapsed_time, NULL);
- if (res == 0)
+
+ if (scanType & eProfileThreadsCPU)
{
- elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
+ get_threads_profile_data(scanType, task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec);
}
struct vm_statistics vm_stats;
@@ -331,50 +364,84 @@ MachTask::GetProfileData ()
mach_vm_size_t vprvt = 0;
mach_vm_size_t vsize = 0;
mach_vm_size_t dirty_size = 0;
- if (m_vm_memory.GetMemoryProfile(task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size))
+ if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size))
{
std::ostringstream profile_data_stream;
- profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
- profile_data_stream << "task_used_usec:" << task_used_usec << ';';
+ if (scanType & eProfileHostCPU)
+ {
+ profile_data_stream << "num_cpu:" << numCPU << ';';
+ profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';';
+ profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';';
+ profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';';
+ }
- profile_data_stream << "threads_used_usec:" << num_threads;
- for (int i=0; i<num_threads; i++) {
- profile_data_stream << ',' << threads_id[i];
-
- profile_data_stream << ',';
- int len = threads_name[i].size();
- if (len) {
- const char *thread_name = threads_name[i].c_str();
- // Make sure that thread name doesn't interfere with our delimiter.
- profile_data_stream << RAW_HEXBASE << std::setw(2);
- const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
- for (int i=0; i<len; i++)
+ if (scanType & eProfileCPU)
+ {
+ profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
+ profile_data_stream << "task_used_usec:" << task_used_usec << ';';
+ }
+
+ if (scanType & eProfileThreadsCPU)
+ {
+ int num_threads = threads_id.size();
+ for (int i=0; i<num_threads; i++)
+ {
+ profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
+ profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
+
+ if (scanType & eProfileThreadName)
{
- profile_data_stream << (uint32_t)(ubuf8[i]);
+ profile_data_stream << "thread_used_name:";
+ int len = threads_name[i].size();
+ if (len)
+ {
+ const char *thread_name = threads_name[i].c_str();
+ // Make sure that thread name doesn't interfere with our delimiter.
+ profile_data_stream << RAW_HEXBASE << std::setw(2);
+ const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
+ for (int j=0; j<len; j++)
+ {
+ profile_data_stream << (uint32_t)(ubuf8[j]);
+ }
+ // Reset back to DECIMAL.
+ profile_data_stream << DECIMAL;
+ }
+ profile_data_stream << ';';
}
- // Reset back to DECIMAL.
- profile_data_stream << DECIMAL;
}
+ }
+
+ if (scanType & eProfileHostMemory)
+ profile_data_stream << "total:" << physical_memory << ';';
+
+ if (scanType & eProfileMemory)
+ {
+ static vm_size_t pagesize;
+ static bool calculated = false;
+ if (!calculated)
+ {
+ calculated = true;
+ pagesize = PageSize();
+ }
+
+ profile_data_stream << "wired:" << vm_stats.wire_count * pagesize << ';';
+ profile_data_stream << "active:" << vm_stats.active_count * pagesize << ';';
+ profile_data_stream << "inactive:" << vm_stats.inactive_count * pagesize << ';';
+ uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
+ profile_data_stream << "used:" << total_used_count * pagesize << ';';
+ profile_data_stream << "free:" << vm_stats.free_count * pagesize << ';';
- profile_data_stream << ',' << threads_used_usec[i];
+ profile_data_stream << "rprvt:" << rprvt << ';';
+ profile_data_stream << "rsize:" << rsize << ';';
+ profile_data_stream << "vprvt:" << vprvt << ';';
+ profile_data_stream << "vsize:" << vsize << ';';
+
+ if (scanType & eProfileMemoryDirtyPage)
+ profile_data_stream << "dirty:" << dirty_size << ';';
}
- profile_data_stream << ';';
- profile_data_stream << "wired:" << vm_stats.wire_count * vm_page_size << ';';
- profile_data_stream << "active:" << vm_stats.active_count * vm_page_size << ';';
- profile_data_stream << "inactive:" << vm_stats.inactive_count * vm_page_size << ';';
- uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
- profile_data_stream << "used:" << total_used_count * vm_page_size << ';';
- profile_data_stream << "free:" << vm_stats.free_count * vm_page_size << ';';
- profile_data_stream << "total:" << physical_memory << ';';
-
- profile_data_stream << "rprvt:" << rprvt << ';';
- profile_data_stream << "rsize:" << rsize << ';';
- profile_data_stream << "vprvt:" << vprvt << ';';
- profile_data_stream << "vsize:" << vsize << ';';
- profile_data_stream << "dirty:" << dirty_size << ';';
- profile_data_stream << "end;";
+ profile_data_stream << "--end--;";
result = profile_data_stream.str();
}
@@ -960,3 +1027,9 @@ MachTask::EnumerateMallocFrames (MachMal
*count -= 1;
return (*count > 0);
}
+
+nub_size_t
+MachTask::PageSize ()
+{
+ return m_vm_memory.PageSize (m_task);
+}
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachTask.h Wed Apr 17 03:38:48 2013
@@ -26,6 +26,7 @@
#include <string>
// Other libraries and framework includes
// Project includes
+#include "DNBDefs.h"
#include "MachException.h"
#include "MachVMMemory.h"
#include "PThreadMutex.h"
@@ -66,7 +67,7 @@ public:
nub_size_t ReadMemory (nub_addr_t addr, nub_size_t size, void *buf);
nub_size_t WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf);
int GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info);
- std::string GetProfileData ();
+ std::string GetProfileData (DNBProfileDataScanType scanType);
nub_addr_t AllocateMemory (nub_size_t size, uint32_t permissions);
nub_bool_t DeallocateMemory (nub_addr_t addr);
@@ -91,6 +92,7 @@ public:
MachProcess * Process () { return m_process; }
const MachProcess * Process () const { return m_process; }
+ nub_size_t PageSize ();
bool HasMallocLoggingEnabled ();
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.cpp Wed Apr 17 03:38:48 2013
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include <inttypes.h>
#include "MachThread.h"
#include "MachProcess.h"
#include "DNBLog.h"
@@ -23,9 +24,10 @@ GetSequenceID()
return ++g_nextID;
}
-MachThread::MachThread (MachProcess *process, thread_t tid) :
+MachThread::MachThread (MachProcess *process, uint64_t unique_thread_id, thread_t mach_port_num) :
m_process (process),
- m_tid (tid),
+ m_unique_id (unique_thread_id),
+ m_mach_port_number (mach_port_num),
m_seq_id (GetSequenceID()),
m_state (eStateUnloaded),
m_state_mutex (PTHREAD_MUTEX_RECURSIVE),
@@ -34,12 +36,10 @@ MachThread::MachThread (MachProcess *pro
m_stop_exception (),
m_arch_ap (DNBArchProtocol::Create (this)),
m_reg_sets (NULL),
- m_num_reg_sets (0)
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
- , m_ident_info(),
+ m_num_reg_sets (0),
+ m_ident_info(),
m_proc_threadinfo(),
m_dispatch_queue_name()
-#endif
{
nub_size_t num_reg_sets = 0;
m_reg_sets = m_arch_ap->GetRegisterSetInfo (&num_reg_sets);
@@ -49,12 +49,12 @@ MachThread::MachThread (MachProcess *pro
// muck with it and also so we get the suspend count correct in case it was
// already suspended
GetBasicInfo();
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::MachThread ( process = %p, tid = 0x%4.4x, seq_id = %u )", &m_process, m_tid, m_seq_id);
+ DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::MachThread ( process = %p, tid = 0x%8.8" PRIx64 ", seq_id = %u )", &m_process, m_unique_id, m_seq_id);
}
MachThread::~MachThread()
{
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::~MachThread() for tid = 0x%4.4x (%u)", m_tid, m_seq_id);
+ DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::~MachThread() for tid = 0x%8.8" PRIx64 " (%u)", m_unique_id, m_seq_id);
}
@@ -63,13 +63,13 @@ void
MachThread::Suspend()
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
- if (ThreadIDIsValid(m_tid))
+ if (MachPortNumberIsValid(m_mach_port_number))
{
- DNBError err(::thread_suspend (m_tid), DNBError::MachKernel);
+ DNBError err(::thread_suspend (m_mach_port_number), DNBError::MachKernel);
if (err.Success())
m_suspend_count++;
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
+ err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
}
}
@@ -77,7 +77,7 @@ void
MachThread::Resume(bool others_stopped)
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
- if (ThreadIDIsValid(m_tid))
+ if (MachPortNumberIsValid(m_mach_port_number))
{
SetSuspendCountBeforeResume(others_stopped);
}
@@ -88,7 +88,7 @@ MachThread::SetSuspendCountBeforeResume(
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
DNBError err;
- if (ThreadIDIsValid(m_tid) == false)
+ if (MachPortNumberIsValid(m_mach_port_number) == false)
return false;
size_t times_to_resume;
@@ -113,9 +113,9 @@ MachThread::SetSuspendCountBeforeResume(
{
while (times_to_resume > 0)
{
- err = ::thread_resume (m_tid);
+ err = ::thread_resume (m_mach_port_number);
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4x)", m_tid);
+ err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
if (err.Success())
--times_to_resume;
else
@@ -135,16 +135,16 @@ MachThread::RestoreSuspendCountAfterStop
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
DNBError err;
- if (ThreadIDIsValid(m_tid) == false)
+ if (MachPortNumberIsValid(m_mach_port_number) == false)
return false;
if (m_suspend_count > 0)
{
while (m_suspend_count > 0)
{
- err = ::thread_resume (m_tid);
+ err = ::thread_resume (m_mach_port_number);
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4x)", m_tid);
+ err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
if (err.Success())
--m_suspend_count;
else
@@ -161,12 +161,12 @@ MachThread::RestoreSuspendCountAfterStop
{
while (m_suspend_count < 0)
{
- err = ::thread_suspend (m_tid);
+ err = ::thread_suspend (m_mach_port_number);
if (err.Success())
++m_suspend_count;
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
{
- err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
+ err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
return false;
}
}
@@ -181,7 +181,7 @@ MachThread::GetBasicInfoAsString () cons
static char g_basic_info_string[1024];
struct thread_basic_info basicInfo;
- if (GetBasicInfo(m_tid, &basicInfo))
+ if (GetBasicInfo(m_mach_port_number, &basicInfo))
{
// char run_state_str[32];
@@ -197,8 +197,8 @@ MachThread::GetBasicInfoAsString () cons
// }
float user = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
float system = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
- snprintf(g_basic_info_string, sizeof(g_basic_info_string), "Thread 0x%4.4x: user=%f system=%f cpu=%d sleep_time=%d",
- InferiorThreadID(),
+ snprintf(g_basic_info_string, sizeof(g_basic_info_string), "Thread 0x%8.8" PRIx64 ": user=%f system=%f cpu=%d sleep_time=%d",
+ m_unique_id,
user,
system,
basicInfo.cpu_usage,
@@ -209,6 +209,7 @@ MachThread::GetBasicInfoAsString () cons
return NULL;
}
+// Finds the Mach port number for a given thread in the inferior process' port namespace.
thread_t
MachThread::InferiorThreadID() const
{
@@ -233,7 +234,7 @@ MachThread::InferiorThreadID() const
if (kret == KERN_SUCCESS)
{
::mach_port_deallocate (my_task, my_name);
- if (my_name == m_tid)
+ if (my_name == m_mach_port_number)
{
inferior_tid = names[i];
break;
@@ -271,7 +272,7 @@ MachThread::IsUserReady()
struct thread_basic_info *
MachThread::GetBasicInfo ()
{
- if (MachThread::GetBasicInfo(m_tid, &m_basic_info))
+ if (MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info))
return &m_basic_info;
return NULL;
}
@@ -280,7 +281,7 @@ MachThread::GetBasicInfo ()
bool
MachThread::GetBasicInfo(thread_t thread, struct thread_basic_info *basicInfoPtr)
{
- if (ThreadIDIsValid(thread))
+ if (MachPortNumberIsValid(thread))
{
unsigned int info_count = THREAD_BASIC_INFO_COUNT;
kern_return_t err = ::thread_info (thread, THREAD_BASIC_INFO, (thread_info_t) basicInfoPtr, &info_count);
@@ -293,7 +294,13 @@ MachThread::GetBasicInfo(thread_t thread
bool
-MachThread::ThreadIDIsValid(thread_t thread)
+MachThread::ThreadIDIsValid(uint64_t thread)
+{
+ return thread != 0;
+}
+
+bool
+MachThread::MachPortNumberIsValid(thread_t thread)
{
return thread != THREAD_NULL;
}
@@ -354,10 +361,10 @@ MachThread::Dump(uint32_t index)
default: thread_run_state = "???"; break;
}
- DNBLogThreaded("[%3u] #%3u tid: 0x%4.4x, pc: 0x%16.16llx, sp: 0x%16.16llx, breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
+ DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
index,
m_seq_id,
- m_tid,
+ m_unique_id,
GetPC(INVALID_NUB_ADDRESS),
GetSP(INVALID_NUB_ADDRESS),
m_break_id,
@@ -498,7 +505,7 @@ MachThread::ThreadDidStop()
RestoreSuspendCountAfterStop();
// Update the basic information for a thread
- MachThread::GetBasicInfo(m_tid, &m_basic_info);
+ MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
#if ENABLE_AUTO_STEPPING_OVER_BP
// See if we were at a breakpoint when we last resumed that we disabled,
@@ -588,7 +595,7 @@ MachThread::SetState(nub_state_t state)
{
PTHREAD_MUTEX_LOCKER (locker, m_state_mutex);
m_state = state;
- DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%4.4x", DNBStateAsString(state), m_tid);
+ DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "", DNBStateAsString(state), m_unique_id);
}
uint32_t
@@ -736,13 +743,11 @@ MachThread::NumSupportedHardwareWatchpoi
bool
MachThread::GetIdentifierInfo ()
{
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
// Don't try to get the thread info once and cache it for the life of the thread. It changes over time, for instance
// if the thread name changes, then the thread_handle also changes... So you have to refetch it every time.
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- kern_return_t kret = ::thread_info (ThreadID(), THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
+ kern_return_t kret = ::thread_info (m_mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
return kret == KERN_SUCCESS;
-#endif
return false;
}
@@ -761,3 +766,18 @@ MachThread::GetName ()
return NULL;
}
+
+uint64_t
+MachThread::GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id)
+{
+ kern_return_t kr;
+ thread_identifier_info_data_t tident;
+ mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
+ kr = thread_info (mach_port_id, THREAD_IDENTIFIER_INFO,
+ (thread_info_t) &tident, &tident_count);
+ if (kr != KERN_SUCCESS)
+ {
+ return mach_port_id;
+ }
+ return tident.thread_id;
+}
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachThread.h Wed Apr 17 03:38:48 2013
@@ -36,7 +36,7 @@ class MachThread
{
public:
- MachThread (MachProcess *process, thread_t thread = 0);
+ MachThread (MachProcess *process, uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
~MachThread ();
MachProcess * Process() { return m_process; }
@@ -44,11 +44,13 @@ public:
Process() const { return m_process; }
nub_process_t ProcessID() const;
void Dump(uint32_t index);
- thread_t ThreadID() const { return m_tid; }
+ uint64_t ThreadID() const { return m_unique_id; }
+ thread_t MachPortNumber() const { return m_mach_port_number; }
thread_t InferiorThreadID() const;
uint32_t SequenceID() const { return m_seq_id; }
- static bool ThreadIDIsValid(thread_t thread);
+ static bool ThreadIDIsValid(uint64_t thread); // The 64-bit system-wide unique thread identifier
+ static bool MachPortNumberIsValid(thread_t thread); // The mach port # for this thread in debugserver namespace
void Resume(bool others_stopped);
void Suspend();
bool SetSuspendCountBeforeResume(bool others_stopped);
@@ -106,6 +108,8 @@ public:
return m_arch_ap.get();
}
+ static uint64_t GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id);
+
protected:
static bool GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
@@ -116,7 +120,8 @@ protected:
// GetDispatchQueueName();
//
MachProcess * m_process; // The process that owns this thread
- thread_t m_tid; // The thread port for this thread
+ uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
+ thread_t m_mach_port_number; // The mach port # for this thread in debugserver namesp.
uint32_t m_seq_id; // A Sequential ID that increments with each new thread
nub_state_t m_state; // The state of our process
PThreadMutex m_state_mutex; // Multithreaded protection for m_state
@@ -128,11 +133,9 @@ protected:
std::auto_ptr<DNBArchProtocol> m_arch_ap; // Arch specific information for register state and more
const DNBRegisterSetInfo * m_reg_sets; // Register set information for this thread
nub_size_t m_num_reg_sets;
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
thread_identifier_info_data_t m_ident_info;
struct proc_threadinfo m_proc_threadinfo;
std::string m_dispatch_queue_name;
-#endif
private:
friend class MachThreadList;
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.cpp Wed Apr 17 03:38:48 2013
@@ -13,6 +13,7 @@
#include "MachThreadList.h"
+#include <inttypes.h>
#include <sys/sysctl.h>
#include "DNBLog.h"
@@ -30,7 +31,7 @@ MachThreadList::~MachThreadList()
}
nub_state_t
-MachThreadList::GetState(thread_t tid)
+MachThreadList::GetState(nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -39,7 +40,7 @@ MachThreadList::GetState(thread_t tid)
}
const char *
-MachThreadList::GetName (thread_t tid)
+MachThreadList::GetName (nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -48,7 +49,7 @@ MachThreadList::GetName (thread_t tid)
}
nub_thread_t
-MachThreadList::SetCurrentThread(thread_t tid)
+MachThreadList::SetCurrentThread(nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -72,8 +73,10 @@ MachThreadList::GetThreadStoppedReason(n
bool
MachThreadList::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
{
+ thread_t mach_port_number = GetMachPortNumberByThreadID (tid);
+
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- return ::thread_info (tid, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
+ return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
}
void
@@ -110,8 +113,57 @@ MachThreadList::GetThreadByID (nub_threa
return thread_sp;
}
+MachThreadSP
+MachThreadList::GetThreadByMachPortNumber (thread_t mach_port_number) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->MachPortNumber() == mach_port_number)
+ {
+ thread_sp = m_threads[idx];
+ break;
+ }
+ }
+ return thread_sp;
+}
+
+nub_thread_t
+MachThreadList::GetThreadIDByMachPortNumber (thread_t mach_port_number) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->MachPortNumber() == mach_port_number)
+ {
+ return m_threads[idx]->ThreadID();
+ }
+ }
+ return INVALID_NUB_THREAD;
+}
+
+thread_t
+MachThreadList::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->ThreadID() == globally_unique_id)
+ {
+ return m_threads[idx]->MachPortNumber();
+ }
+ }
+ return 0;
+}
+
bool
-MachThreadList::GetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const
+MachThreadList::GetRegisterValue (nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -121,7 +173,7 @@ MachThreadList::GetRegisterValue ( nub_t
}
bool
-MachThreadList::SetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value ) const
+MachThreadList::SetRegisterValue (nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value ) const
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -177,7 +229,7 @@ MachThreadList::CurrentThreadID ( )
bool
MachThreadList::NotifyException(MachException::Data& exc)
{
- MachThreadSP thread_sp (GetThreadByID (exc.thread_port));
+ MachThreadSP thread_sp (GetThreadByMachPortNumber (exc.thread_port));
if (thread_sp)
{
thread_sp->NotifyException(exc);
@@ -238,9 +290,10 @@ MachThreadList::UpdateThreadList(MachPro
// (add them), and which ones are not around anymore (remove them).
for (idx = 0; idx < thread_list_count; ++idx)
{
- const thread_t tid = thread_list[idx];
+ const thread_t mach_port_num = thread_list[idx];
- MachThreadSP thread_sp (GetThreadByID (tid));
+ uint64_t unique_thread_id = MachThread::GetGloballyUniqueThreadIDForMachPortID (mach_port_num);
+ MachThreadSP thread_sp (GetThreadByID (unique_thread_id));
if (thread_sp)
{
// Keep the existing thread class
@@ -249,7 +302,7 @@ MachThreadList::UpdateThreadList(MachPro
else
{
// We don't have this thread, lets add it.
- thread_sp.reset(new MachThread(process, tid));
+ thread_sp.reset(new MachThread(process, unique_thread_id, mach_port_num));
// Add the new thread regardless of its is user ready state...
// Make sure the thread is ready to be displayed and shown to users
@@ -382,7 +435,7 @@ MachThreadList::ProcessWillResume(MachPr
{
for (uint32_t idx = 0; idx < num_new_threads; ++idx)
{
- DNBLogThreadedIf (LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%4.4x, thread-is-user-ready=%i)",
+ DNBLogThreadedIf (LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
process->ProcessID(),
process->StopCount(),
new_threads[idx]->ThreadID(),
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachThreadList.h Wed Apr 17 03:38:48 2013
@@ -35,9 +35,9 @@ public:
uint32_t ProcessDidStop (MachProcess *process);
bool NotifyException (MachException::Data& exc);
bool ShouldStop (bool &step_more);
- const char * GetName (thread_t tid);
- nub_state_t GetState (thread_t tid);
- nub_thread_t SetCurrentThread (thread_t tid);
+ const char * GetName (nub_thread_t tid);
+ nub_state_t GetState (nub_thread_t tid);
+ nub_thread_t SetCurrentThread (nub_thread_t tid);
bool GetThreadStoppedReason (nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
void DumpThreadStoppedReason (nub_thread_t tid) const;
bool GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info);
@@ -56,6 +56,10 @@ public:
MachThreadSP GetThreadByID (nub_thread_t tid) const;
+ MachThreadSP GetThreadByMachPortNumber (thread_t mach_port_number) const;
+ nub_thread_t GetThreadIDByMachPortNumber (thread_t mach_port_number) const;
+ thread_t GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const;
+
protected:
typedef std::vector<MachThreadSP> collection;
typedef collection::iterator iterator;
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.cpp Wed Apr 17 03:38:48 2013
@@ -29,10 +29,29 @@ MachVMMemory::~MachVMMemory()
}
nub_size_t
-MachVMMemory::PageSize()
+MachVMMemory::PageSize(task_t task)
{
if (m_page_size == kInvalidPageSize)
{
+#if defined (TASK_VM_INFO) && TASK_VM_INFO >= 22
+ if (task != TASK_NULL)
+ {
+ kern_return_t kr;
+ mach_msg_type_number_t info_count = TASK_VM_INFO_COUNT;
+ task_vm_info_data_t vm_info;
+ kr = task_info (task, TASK_VM_INFO, (task_info_t) &vm_info, &info_count);
+ if (kr == KERN_SUCCESS)
+ {
+ DNBLogThreadedIf(LOG_TASK, "MachVMMemory::PageSize task_info returned page size of 0x%x", (int) vm_info.page_size);
+ m_page_size = vm_info.page_size;
+ return m_page_size;
+ }
+ else
+ {
+ DNBLogThreadedIf(LOG_TASK, "MachVMMemory::PageSize task_info call failed to get page size, TASK_VM_INFO %d, TASK_VM_INFO_COUNT %d, kern return %d", TASK_VM_INFO, TASK_VM_INFO_COUNT, kr);
+ }
+ }
+#endif
m_err = ::host_page_size( ::mach_host_self(), &m_page_size);
if (m_err.Fail())
m_page_size = 0;
@@ -41,9 +60,9 @@ MachVMMemory::PageSize()
}
nub_size_t
-MachVMMemory::MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count)
+MachVMMemory::MaxBytesLeftInPage(task_t task, nub_addr_t addr, nub_size_t count)
{
- const nub_size_t page_size = PageSize();
+ const nub_size_t page_size = PageSize(task);
if (page_size > 0)
{
nub_size_t page_offset = (addr % page_size);
@@ -91,7 +110,8 @@ MachVMMemory::GetMemoryRegionInfo(task_t
}
// For integrated graphics chip, this makes the accounting info for 'wired' memory more like top.
-static uint64_t GetStolenPages()
+uint64_t
+MachVMMemory::GetStolenPages(task_t task)
{
static uint64_t stolenPages = 0;
static bool calculated = false;
@@ -186,7 +206,9 @@ static uint64_t GetStolenPages()
if(stolen >= mb128)
{
stolen = (stolen & ~((128 * 1024 * 1024ULL) - 1)); // rounding down
- stolenPages = stolen/vm_page_size;
+ vm_size_t pagesize = vm_page_size;
+ pagesize = PageSize (task);
+ stolenPages = stolen/pagesize;
}
}
}
@@ -211,7 +233,8 @@ static uint64_t GetPhysicalMemory()
}
// rsize and dirty_size is not adjusted for dyld shared cache and multiple __LINKEDIT segment, as in vmmap. In practice, dirty_size doesn't differ much but rsize may. There is performance penalty for the adjustment. Right now, only use the dirty_size.
-static void GetRegionSizes(task_t task, mach_vm_size_t &rsize, mach_vm_size_t &dirty_size)
+void
+MachVMMemory::GetRegionSizes(task_t task, mach_vm_size_t &rsize, mach_vm_size_t &dirty_size)
{
mach_vm_address_t address = 0;
mach_vm_size_t size;
@@ -222,7 +245,7 @@ static void GetRegionSizes(task_t task,
while (1)
{
- mach_msg_type_number_t count;
+ mach_msg_type_number_t count;
struct vm_region_submap_info_64 info;
count = VM_REGION_SUBMAP_INFO_COUNT_64;
@@ -249,10 +272,7 @@ static void GetRegionSizes(task_t task,
// Don't count malloc stack logging data in the TOTAL VM usage lines.
if (info.user_tag == VM_MEMORY_ANALYSIS_TOOL)
should_count = false;
- // Don't count system shared library region not used by this process.
- if (address >= SHARED_REGION_BASE && address < (SHARED_REGION_BASE + SHARED_REGION_SIZE))
- should_count = false;
-
+
address = address+size;
}
@@ -263,8 +283,16 @@ static void GetRegionSizes(task_t task,
}
}
- rsize = pages_resident * vm_page_size;
- dirty_size = pages_dirtied * vm_page_size;
+ static vm_size_t pagesize;
+ static bool calculated = false;
+ if (!calculated)
+ {
+ calculated = true;
+ pagesize = PageSize (task);
+ }
+
+ rsize = pages_resident * pagesize;
+ dirty_size = pages_dirtied * pagesize;
}
// Test whether the virtual address is within the architecture's shared region.
@@ -298,16 +326,24 @@ static bool InSharedRegion(mach_vm_addre
return(addr >= base && addr < (base + size));
}
-static void GetMemorySizes(task_t task, cpu_type_t cputype, nub_process_t pid, mach_vm_size_t &rprvt, mach_vm_size_t &vprvt)
+void
+MachVMMemory::GetMemorySizes(task_t task, cpu_type_t cputype, nub_process_t pid, mach_vm_size_t &rprvt, mach_vm_size_t &vprvt)
{
// Collecting some other info cheaply but not reporting for now.
mach_vm_size_t empty = 0;
mach_vm_size_t fw_private = 0;
mach_vm_size_t aliased = 0;
- mach_vm_size_t pagesize = vm_page_size;
bool global_shared_text_data_mapped = false;
+ static vm_size_t pagesize;
+ static bool calculated = false;
+ if (!calculated)
+ {
+ calculated = true;
+ pagesize = PageSize (task);
+ }
+
for (mach_vm_address_t addr=0, size=0; ; addr += size)
{
vm_region_top_info_data_t info;
@@ -324,7 +360,7 @@ static void GetMemorySizes(task_t task,
// Check if this process has the globally shared text and data regions mapped in. If so, set global_shared_text_data_mapped to TRUE and avoid checking again.
if (global_shared_text_data_mapped == FALSE && info.share_mode == SM_EMPTY) {
- vm_region_basic_info_data_64_t b_info;
+ vm_region_basic_info_data_64_t b_info;
mach_vm_address_t b_addr = addr;
mach_vm_size_t b_size = size;
count = VM_REGION_BASIC_INFO_COUNT_64;
@@ -397,21 +433,29 @@ static void GetMemorySizes(task_t task,
}
nub_bool_t
-MachVMMemory::GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size)
+MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size)
{
- static mach_port_t localHost = mach_host_self();
- mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
- host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
- vm_stats.wire_count += GetStolenPages();
- physical_memory = GetPhysicalMemory();
-
- // This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
- GetRegionSizes(task, rsize, dirty_size);
+ if (scanType & eProfileHostMemory)
+ physical_memory = GetPhysicalMemory();
- GetMemorySizes(task, cputype, pid, rprvt, vprvt);
+ if (scanType & eProfileMemory)
+ {
+ static mach_port_t localHost = mach_host_self();
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
+ vm_stats.wire_count += GetStolenPages(task);
+
+ GetMemorySizes(task, cputype, pid, rprvt, vprvt);
- rsize = ti.resident_size;
- vsize = ti.virtual_size;
+ rsize = ti.resident_size;
+ vsize = ti.virtual_size;
+
+ if (scanType & eProfileMemoryDirtyPage)
+ {
+ // This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
+ GetRegionSizes(task, rsize, dirty_size);
+ }
+ }
return true;
}
@@ -427,7 +471,7 @@ MachVMMemory::Read(task_t task, nub_addr
uint8_t *curr_data = (uint8_t*)data;
while (total_bytes_read < data_count)
{
- mach_vm_size_t curr_size = MaxBytesLeftInPage(curr_addr, data_count - total_bytes_read);
+ mach_vm_size_t curr_size = MaxBytesLeftInPage(task, curr_addr, data_count - total_bytes_read);
mach_msg_type_number_t curr_bytes_read = 0;
vm_offset_t vm_memory = NULL;
m_err = ::mach_vm_read (task, curr_addr, curr_size, &vm_memory, &curr_bytes_read);
@@ -523,7 +567,7 @@ MachVMMemory::WriteRegion(task_t task, c
const uint8_t *curr_data = (const uint8_t*)data;
while (total_bytes_written < data_count)
{
- mach_msg_type_number_t curr_data_count = MaxBytesLeftInPage(curr_addr, data_count - total_bytes_written);
+ mach_msg_type_number_t curr_data_count = MaxBytesLeftInPage(task, curr_addr, data_count - total_bytes_written);
m_err = ::mach_vm_write (task, curr_addr, (pointer_t) curr_data, curr_data_count);
if (DNBLogCheckLogBit(LOG_MEMORY) || m_err.Fail())
m_err.LogThreaded("::mach_vm_write ( task = 0x%4.4x, addr = 0x%8.8llx, data = %8.8p, dataCnt = %u )", task, (uint64_t)curr_addr, curr_data, curr_data_count);
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/MachVMMemory.h Wed Apr 17 03:38:48 2013
@@ -26,14 +26,20 @@ public:
~MachVMMemory();
nub_size_t Read(task_t task, nub_addr_t address, void *data, nub_size_t data_count);
nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count);
- nub_size_t PageSize();
+ nub_size_t PageSize(task_t task);
nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info);
- nub_bool_t GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size);
+ nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size);
protected:
- nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count);
+ nub_size_t MaxBytesLeftInPage(task_t task, nub_addr_t addr, nub_size_t count);
+
+ uint64_t GetStolenPages(task_t task);
+ void GetRegionSizes(task_t task, mach_vm_size_t &rsize, mach_vm_size_t &dirty_size);
+ void GetMemorySizes(task_t task, cpu_type_t cputype, nub_process_t pid, mach_vm_size_t &rprvt, mach_vm_size_t &vprvt);
+
+
+ nub_size_t WriteRegion(task_t task, const nub_addr_t address, const void *data, const nub_size_t data_count);
- nub_size_t WriteRegion(task_t task, const nub_addr_t address, const void *data, const nub_size_t data_count);
vm_size_t m_page_size;
DNBError m_err;
};
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp Wed Apr 17 03:38:48 2013
@@ -188,10 +188,10 @@ DNBArchMachARM::GetGPRState(bool force)
// Read the registers from our thread
mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
uint32_t *r = &m_state.context.gpr.__r[0];
DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x",
- m_thread->ThreadID(),
+ m_thread->MachPortNumber(),
ARM_THREAD_STATE,
ARM_THREAD_STATE_COUNT,
kret,
@@ -227,12 +227,12 @@ DNBArchMachARM::GetVFPState(bool force)
// Read the registers from our thread
mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
if (DNBLogEnabledForAny (LOG_THREAD))
{
uint32_t *r = &m_state.context.vfp.__r[0];
DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
- m_thread->ThreadID(),
+ m_thread->MachPortNumber(),
ARM_THREAD_STATE,
ARM_THREAD_STATE_COUNT,
kret,
@@ -260,7 +260,7 @@ DNBArchMachARM::GetEXCState(bool force)
// Read the registers from our thread
mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -287,7 +287,7 @@ DNBArchMachARM::GetDBGState(bool force)
// Read the registers from our thread
mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -296,7 +296,7 @@ kern_return_t
DNBArchMachARM::SetGPRState()
{
int set = e_regSetGPR;
- kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -306,7 +306,7 @@ kern_return_t
DNBArchMachARM::SetVFPState()
{
int set = e_regSetVFP;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -316,7 +316,7 @@ kern_return_t
DNBArchMachARM::SetEXCState()
{
int set = e_regSetEXC;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -326,7 +326,7 @@ kern_return_t
DNBArchMachARM::SetDBGState()
{
int set = e_regSetDBG;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -346,13 +346,6 @@ DNBArchMachARM::ThreadWillResume()
DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable hardware single step");
}
}
- else
- {
- if (SetSingleStepSoftwareBreakpoints() != KERN_SUCCESS)
- {
- DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable software single step");
- }
- }
}
// Disable the triggered watchpoint temporarily before we resume.
@@ -469,13 +462,6 @@ DNBArchMachARM::ThreadDidStop()
}
m_sw_single_step_itblock_break_count = 0;
-#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
-
- // Decode instructions up to the current PC to ensure the internal decoder state is valid for the IT block
- // The decoder has to decode each instruction in the IT block even if it is not executed so that
- // the fields are correctly updated
- DecodeITBlockInstructions(m_state.context.gpr.__pc);
-#endif
}
}
@@ -520,1427 +506,45 @@ DNBArchMachARM::NotifyException(MachExce
m_watchpoint_hw_index = hw_index;
exc.exc_data[1] = addr;
// Piggyback the hw_index in the exc.data.
- exc.exc_data.push_back(hw_index);
- }
-
- return true;
- }
- break;
- }
- return false;
-}
-
-bool
-DNBArchMachARM::StepNotComplete ()
-{
- if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS)
- {
- kern_return_t kret = KERN_INVALID_ARGUMENT;
- kret = GetGPRState(false);
- if (kret == KERN_SUCCESS)
- {
- if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr)
- {
- DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr);
- return true;
- }
- }
- }
-
- m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
- return false;
-}
-
-
-#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
-
-void
-DNBArchMachARM::DecodeITBlockInstructions(nub_addr_t curr_pc)
-
-{
- uint16_t opcode16;
- uint32_t opcode32;
- nub_addr_t next_pc_in_itblock;
- nub_addr_t pc_in_itblock = m_last_decode_pc;
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);
-
- // Decode IT block instruction from the instruction following the m_last_decoded_instruction at
- // PC m_last_decode_pc upto and including the instruction at curr_pc
- if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
- {
- opcode32 = opcode16;
- pc_in_itblock += 2;
- // Check for 32 bit thumb opcode and read the upper 16 bits if needed
- if (((opcode32 & 0xE000) == 0xE000) && opcode32 & 0x1800)
- {
- // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
- // a 32 bit Thumb opcode
- // Read bits 31:16 of a 32 bit Thumb opcode
- if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
- {
- pc_in_itblock += 2;
- // 32 bit thumb opcode
- opcode32 = (opcode32 << 16) | opcode16;
- }
- else
- {
- DNBLogError("%s: Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", __FUNCTION__, (uint64_t)pc_in_itblock);
- }
- }
- }
- else
- {
- DNBLogError("%s: Error reading 16-bit Thumb instruction at pc=0x%8.8x", __FUNCTION__, pc_in_itblock);
- }
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc_in_itblock=0x%8.8x, curr_pc=0x%8.8x", __FUNCTION__, pc_in_itblock, curr_pc);
-
- next_pc_in_itblock = pc_in_itblock;
- while (next_pc_in_itblock <= curr_pc)
- {
- arm_error_t decodeError;
-
- m_last_decode_pc = pc_in_itblock;
- decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.context.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc_in_itblock);
-
- pc_in_itblock = next_pc_in_itblock;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: next_pc_in_itblock=0x%8.8x", __FUNCTION__, next_pc_in_itblock);
- }
-}
-#endif
-
-// Set the single step bit in the processor status register.
-kern_return_t
-DNBArchMachARM::EnableHardwareSingleStep (bool enable)
-{
- DNBError err;
- DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable);
-
- err = GetGPRState(false);
-
- if (err.Fail())
- {
- err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
- return err.Error();
- }
-
- err = GetDBGState(false);
-
- if (err.Fail())
- {
- err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
- return err.Error();
- }
-
- const uint32_t i = 0;
- if (enable)
- {
- m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
-
- // Save our previous state
- m_dbg_save = m_state.dbg;
- // Set a breakpoint that will stop when the PC doesn't match the current one!
- m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address
- m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH | // Stop on address mismatch
- S_USER | // Stop only in user mode
- BCR_ENABLE; // Enable this breakpoint
- if (m_state.context.gpr.__cpsr & 0x20)
- {
- // Thumb breakpoint
- if (m_state.context.gpr.__pc & 2)
- m_state.dbg.__bcr[i] |= BAS_IMVA_2_3;
- else
- m_state.dbg.__bcr[i] |= BAS_IMVA_0_1;
-
- uint16_t opcode;
- if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode))
- {
- if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800)
- {
- // 32 bit thumb opcode...
- if (m_state.context.gpr.__pc & 2)
- {
- // We can't take care of a 32 bit thumb instruction single step
- // with just IVA mismatching. We will need to chain an extra
- // hardware single step in order to complete this single step...
- m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
- }
- else
- {
- // Extend the number of bits to ignore for the mismatch
- m_state.dbg.__bcr[i] |= BAS_IMVA_ALL;
- }
- }
- }
- }
- else
- {
- // ARM breakpoint
- m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change
- }
-
- DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x BCR%u=0x%8.8x", __FUNCTION__, i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]);
-
- for (uint32_t j=i+1; j<16; ++j)
- {
- // Disable all others
- m_state.dbg.__bvr[j] = 0;
- m_state.dbg.__bcr[j] = 0;
- }
- }
- else
- {
- // Just restore the state we had before we did single stepping
- m_state.dbg = m_dbg_save;
- }
-
- return SetDBGState();
-}
-
-// return 1 if bit "BIT" is set in "value"
-static inline uint32_t bit(uint32_t value, uint32_t bit)
-{
- return (value >> bit) & 1u;
-}
-
-// return the bitfield "value[msbit:lsbit]".
-static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit)
-{
- assert(msbit >= lsbit);
- uint32_t shift_left = sizeof(value) * 8 - 1 - msbit;
- value <<= shift_left; // shift anything above the msbit off of the unsigned edge
- value >>= (shift_left + lsbit); // shift it back again down to the lsbit (including undoing any shift from above)
- return value; // return our result
-}
-
-bool
-DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr)
-{
- uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag
- uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag
- uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag
- uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag
-
- switch (condition) {
- case COND_EQ: // (0x0)
- if (cpsr_z == 1) return true;
- break;
- case COND_NE: // (0x1)
- if (cpsr_z == 0) return true;
- break;
- case COND_CS: // (0x2)
- if (cpsr_c == 1) return true;
- break;
- case COND_CC: // (0x3)
- if (cpsr_c == 0) return true;
- break;
- case COND_MI: // (0x4)
- if (cpsr_n == 1) return true;
- break;
- case COND_PL: // (0x5)
- if (cpsr_n == 0) return true;
- break;
- case COND_VS: // (0x6)
- if (cpsr_v == 1) return true;
- break;
- case COND_VC: // (0x7)
- if (cpsr_v == 0) return true;
- break;
- case COND_HI: // (0x8)
- if ((cpsr_c == 1) && (cpsr_z == 0)) return true;
- break;
- case COND_LS: // (0x9)
- if ((cpsr_c == 0) || (cpsr_z == 1)) return true;
- break;
- case COND_GE: // (0xA)
- if (cpsr_n == cpsr_v) return true;
- break;
- case COND_LT: // (0xB)
- if (cpsr_n != cpsr_v) return true;
- break;
- case COND_GT: // (0xC)
- if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true;
- break;
- case COND_LE: // (0xD)
- if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true;
- break;
- default:
- return true;
- break;
- }
-
- return false;
-}
-
-#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
-
-bool
-DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t decodedInstruction, bool currentPCIsThumb, nub_addr_t *targetPC)
-{
- nub_addr_t myTargetPC, addressWherePCLives;
- pid_t mypid;
-
- uint32_t cpsr_c = bit(m_state.context.gpr.__cpsr, 29); // Carry condition code flag
-
- uint32_t firstOperand=0, secondOperand=0, shiftAmount=0, secondOperandAfterShift=0, immediateValue=0;
- uint32_t halfwords=0, baseAddress=0, immediateOffset=0, addressOffsetFromRegister=0, addressOffsetFromRegisterAfterShift;
- uint32_t baseAddressIndex=INVALID_NUB_HW_INDEX;
- uint32_t firstOperandIndex=INVALID_NUB_HW_INDEX;
- uint32_t secondOperandIndex=INVALID_NUB_HW_INDEX;
- uint32_t addressOffsetFromRegisterIndex=INVALID_NUB_HW_INDEX;
- uint32_t shiftRegisterIndex=INVALID_NUB_HW_INDEX;
- uint16_t registerList16, registerList16NoPC;
- uint8_t registerList8;
- uint32_t numRegistersToLoad=0;
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: instruction->code=%d", __FUNCTION__, decodedInstruction.instruction->code);
-
- // Get the following in this switch statement:
- // - firstOperand, secondOperand, immediateValue, shiftAmount: For arithmetic, logical and move instructions
- // - baseAddress, immediateOffset, shiftAmount: For LDR
- // - numRegistersToLoad: For LDM and POP instructions
- switch (decodedInstruction.instruction->code)
- {
- // Arithmetic operations that can change the PC
- case ARM_INST_ADC:
- case ARM_INST_ADCS:
- case ARM_INST_ADD:
- case ARM_INST_ADDS:
- case ARM_INST_AND:
- case ARM_INST_ANDS:
- case ARM_INST_ASR:
- case ARM_INST_ASRS:
- case ARM_INST_BIC:
- case ARM_INST_BICS:
- case ARM_INST_EOR:
- case ARM_INST_EORS:
- case ARM_INST_ORR:
- case ARM_INST_ORRS:
- case ARM_INST_RSB:
- case ARM_INST_RSBS:
- case ARM_INST_RSC:
- case ARM_INST_RSCS:
- case ARM_INST_SBC:
- case ARM_INST_SBCS:
- case ARM_INST_SUB:
- case ARM_INST_SUBS:
- switch (decodedInstruction.addressMode)
- {
- case ARM_ADDR_DATA_IMM:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get firstOperand register value (at index=1)
- firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.context.gpr.__r[firstOperandIndex];
-
- // Get immediateValue (at index=2)
- immediateValue = decodedInstruction.op[2].value;
-
- break;
-
- case ARM_ADDR_DATA_REG:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get firstOperand register value (at index=1)
- firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.context.gpr.__r[firstOperandIndex];
-
- // Get secondOperand register value (at index=2)
- secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- break;
-
- case ARM_ADDR_DATA_SCALED_IMM:
- if (decodedInstruction.numOperands != 4)
- {
- DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get firstOperand register value (at index=1)
- firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.context.gpr.__r[firstOperandIndex];
-
- // Get secondOperand register value (at index=2)
- secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- // Get shiftAmount as immediate value (at index=3)
- shiftAmount = decodedInstruction.op[3].value;
-
- break;
-
-
- case ARM_ADDR_DATA_SCALED_REG:
- if (decodedInstruction.numOperands != 4)
- {
- DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get firstOperand register value (at index=1)
- firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.context.gpr.__r[firstOperandIndex];
-
- // Get secondOperand register value (at index=2)
- secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- // Get shiftAmount from register (at index=3)
- shiftRegisterIndex = decodedInstruction.op[3].value; // second operand register index
- shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
-
- break;
-
- case THUMB_ADDR_HR_HR:
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get firstOperand register value (at index=0)
- firstOperandIndex = decodedInstruction.op[0].value; // first operand register index
- firstOperand = m_state.context.gpr.__r[firstOperandIndex];
-
- // Get secondOperand register value (at index=1)
- secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- break;
-
- default:
- break;
- }
- break;
-
- // Logical shifts and move operations that can change the PC
- case ARM_INST_LSL:
- case ARM_INST_LSLS:
- case ARM_INST_LSR:
- case ARM_INST_LSRS:
- case ARM_INST_MOV:
- case ARM_INST_MOVS:
- case ARM_INST_MVN:
- case ARM_INST_MVNS:
- case ARM_INST_ROR:
- case ARM_INST_RORS:
- case ARM_INST_RRX:
- case ARM_INST_RRXS:
- // In these cases, the firstOperand is always 0, as if it does not exist
- switch (decodedInstruction.addressMode)
- {
- case ARM_ADDR_DATA_IMM:
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get immediateValue (at index=1)
- immediateValue = decodedInstruction.op[1].value;
-
- break;
-
- case ARM_ADDR_DATA_REG:
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get secondOperand register value (at index=1)
- secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- break;
-
- case ARM_ADDR_DATA_SCALED_IMM:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get secondOperand register value (at index=1)
- secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- // Get shiftAmount as immediate value (at index=2)
- shiftAmount = decodedInstruction.op[2].value;
-
- break;
-
-
- case ARM_ADDR_DATA_SCALED_REG:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get secondOperand register value (at index=1)
- secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- // Get shiftAmount from register (at index=2)
- shiftRegisterIndex = decodedInstruction.op[2].value; // second operand register index
- shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
-
- break;
-
- case THUMB_ADDR_HR_HR:
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- if (decodedInstruction.op[0].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
-
- // Get secondOperand register value (at index=1)
- secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.context.gpr.__r[secondOperandIndex];
-
- break;
-
- default:
- break;
- }
-
- break;
-
- // Simple branches, used to hop around within a routine
- case ARM_INST_B:
- *targetPC = decodedInstruction.targetPC; // Known targetPC
- return true;
- break;
-
- // Branch-and-link, used to call ARM subroutines
- case ARM_INST_BL:
- *targetPC = decodedInstruction.targetPC; // Known targetPC
- return true;
- break;
-
- // Branch-and-link with exchange, used to call opposite-mode subroutines
- case ARM_INST_BLX:
- if ((decodedInstruction.addressMode == ARM_ADDR_BRANCH_IMM) ||
- (decodedInstruction.addressMode == THUMB_ADDR_UNCOND))
- {
- *targetPC = decodedInstruction.targetPC; // Known targetPC
- return true;
- }
- else // addressMode == ARM_ADDR_BRANCH_REG
- {
- // Unknown target unless we're branching to the PC itself,
- // although this may not work properly with BLX
- if (decodedInstruction.op[REG_RD].value == PC_REG)
- {
- // this should (almost) never happen
- *targetPC = decodedInstruction.targetPC; // Known targetPC
- return true;
- }
-
- // Get the branch address and return
- if (decodedInstruction.numOperands != 1)
- {
- DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get branch address in register (at index=0)
- *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
- return true;
- }
- break;
-
- // Branch with exchange, used to hop to opposite-mode code
- // Branch to Jazelle code, used to execute Java; included here since it
- // acts just like BX unless the Jazelle unit is active and JPC is
- // already loaded into it.
- case ARM_INST_BX:
- case ARM_INST_BXJ:
- // Unknown target unless we're branching to the PC itself,
- // although this can never switch to Thumb mode and is
- // therefore pretty much useless
- if (decodedInstruction.op[REG_RD].value == PC_REG)
- {
- // this should (almost) never happen
- *targetPC = decodedInstruction.targetPC; // Known targetPC
- return true;
- }
-
- // Get the branch address and return
- if (decodedInstruction.numOperands != 1)
- {
- DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get branch address in register (at index=0)
- *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
- return true;
- break;
-
- // Compare and branch on zero/non-zero (Thumb-16 only)
- // Unusual condition check built into the instruction
- case ARM_INST_CBZ:
- case ARM_INST_CBNZ:
- // Branch address is known at compile time
- // Get the branch address and return
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get branch address as an immediate value (at index=1)
- *targetPC = decodedInstruction.op[1].value;
- return true;
- break;
-
- // Load register can be used to load PC, usually with a function pointer
- case ARM_INST_LDR:
- if (decodedInstruction.op[REG_RD].value != PC_REG)
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
- switch (decodedInstruction.addressMode)
- {
- case ARM_ADDR_LSWUB_IMM:
- case ARM_ADDR_LSWUB_IMM_PRE:
- case ARM_ADDR_LSWUB_IMM_POST:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get baseAddress from register (at index=1)
- baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.context.gpr.__r[baseAddressIndex];
-
- // Get immediateOffset (at index=2)
- immediateOffset = decodedInstruction.op[2].value;
- break;
-
- case ARM_ADDR_LSWUB_REG:
- case ARM_ADDR_LSWUB_REG_PRE:
- case ARM_ADDR_LSWUB_REG_POST:
- if (decodedInstruction.numOperands != 3)
- {
- DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get baseAddress from register (at index=1)
- baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.context.gpr.__r[baseAddressIndex];
-
- // Get immediateOffset from register (at index=2)
- addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
- addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
-
- break;
-
- case ARM_ADDR_LSWUB_SCALED:
- case ARM_ADDR_LSWUB_SCALED_PRE:
- case ARM_ADDR_LSWUB_SCALED_POST:
- if (decodedInstruction.numOperands != 4)
- {
- DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get baseAddress from register (at index=1)
- baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.context.gpr.__r[baseAddressIndex];
-
- // Get immediateOffset from register (at index=2)
- addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
- addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
-
- // Get shiftAmount (at index=3)
- shiftAmount = decodedInstruction.op[3].value;
-
- break;
-
- default:
- break;
- }
- break;
-
- // 32b load multiple operations can load the PC along with everything else,
- // usually to return from a function call
- case ARM_INST_LDMDA:
- case ARM_INST_LDMDB:
- case ARM_INST_LDMIA:
- case ARM_INST_LDMIB:
- if (decodedInstruction.op[LDM_REGLIST].value & PC_REGLIST_BIT)
- {
- if (decodedInstruction.numOperands != 2)
- {
- DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
- return false;
- }
-
- // Get baseAddress from register (at index=0)
- baseAddressIndex = decodedInstruction.op[0].value;
- baseAddress = m_state.context.gpr.__r[baseAddressIndex];
-
- // Get registerList from register (at index=1)
- registerList16 = (uint16_t)decodedInstruction.op[1].value;
-
- // Count number of registers to load in the multiple register list excluding the PC
- registerList16NoPC = registerList16&0x3FFF; // exclude the PC
- numRegistersToLoad=0;
- for (int i = 0; i < 16; i++)
- {
- if (registerList16NoPC & 0x1) numRegistersToLoad++;
- registerList16NoPC = registerList16NoPC >> 1;
- }
- }
- else
- {
- DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
- return false;
- }
- break;
-
- // Normal 16-bit LD multiple can't touch R15, but POP can
- case ARM_INST_POP: // Can also get the PC & updates SP
- // Get baseAddress from SP (at index=0)
- baseAddress = m_state.context.gpr.__sp;
-
- if (decodedInstruction.thumb16b)
- {
- // Get registerList from register (at index=0)
- registerList8 = (uint8_t)decodedInstruction.op[0].value;
-
- // Count number of registers to load in the multiple register list
- numRegistersToLoad=0;
- for (int i = 0; i < 8; i++)
- {
- if (registerList8 & 0x1) numRegistersToLoad++;
- registerList8 = registerList8 >> 1;
- }
- }
- else
- {
- // Get registerList from register (at index=0)
- registerList16 = (uint16_t)decodedInstruction.op[0].value;
-
- // Count number of registers to load in the multiple register list excluding the PC
- registerList16NoPC = registerList16&0x3FFF; // exclude the PC
- numRegistersToLoad=0;
- for (int i = 0; i < 16; i++)
- {
- if (registerList16NoPC & 0x1) numRegistersToLoad++;
- registerList16NoPC = registerList16NoPC >> 1;
- }
- }
- break;
-
- // 16b TBB and TBH instructions load a jump address from a table
- case ARM_INST_TBB:
- case ARM_INST_TBH:
- // Get baseAddress from register (at index=0)
- baseAddressIndex = decodedInstruction.op[0].value;
- baseAddress = m_state.context.gpr.__r[baseAddressIndex];
-
- // Get immediateOffset from register (at index=1)
- addressOffsetFromRegisterIndex = decodedInstruction.op[1].value;
- addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
- break;
-
- // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
- // from a special base pointer register (which is unknown at disassembly time)
- case ARM_INST_HB:
- case ARM_INST_HBP:
-// TODO: ARM_INST_HB, ARM_INST_HBP
- break;
-
- case ARM_INST_HBL:
- case ARM_INST_HBLP:
-// TODO: ARM_INST_HBL, ARM_INST_HBLP
- break;
-
- // Breakpoint and software interrupt jump to interrupt handler (always ARM)
- case ARM_INST_BKPT:
- case ARM_INST_SMC:
- case ARM_INST_SVC:
-
- // Return from exception, obviously modifies PC [interrupt only!]
- case ARM_INST_RFEDA:
- case ARM_INST_RFEDB:
- case ARM_INST_RFEIA:
- case ARM_INST_RFEIB:
-
- // Other instructions either can't change R15 or are "undefined" if you do,
- // so no sane compiler should ever generate them & we don't care here.
- // Also, R15 can only legally be used in a read-only manner for the
- // various ARM addressing mode (to get PC-relative addressing of constants),
- // but can NOT be used with any of the update modes.
- default:
- DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
- return false;
- break;
- }
-
- // Adjust PC if PC is one of the input operands
- if (baseAddressIndex == PC_REG)
- {
- if (currentPCIsThumb)
- baseAddress += 4;
- else
- baseAddress += 8;
- }
-
- if (firstOperandIndex == PC_REG)
- {
- if (currentPCIsThumb)
- firstOperand += 4;
- else
- firstOperand += 8;
- }
-
- if (secondOperandIndex == PC_REG)
- {
- if (currentPCIsThumb)
- secondOperand += 4;
- else
- secondOperand += 8;
- }
-
- if (addressOffsetFromRegisterIndex == PC_REG)
- {
- if (currentPCIsThumb)
- addressOffsetFromRegister += 4;
- else
- addressOffsetFromRegister += 8;
- }
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
- "%s: firstOperand=%8.8x, secondOperand=%8.8x, immediateValue = %d, shiftAmount = %d, baseAddress = %8.8x, addressOffsetFromRegister = %8.8x, immediateOffset = %d, numRegistersToLoad = %d",
- __FUNCTION__,
- firstOperand,
- secondOperand,
- immediateValue,
- shiftAmount,
- baseAddress,
- addressOffsetFromRegister,
- immediateOffset,
- numRegistersToLoad);
-
-
- // Calculate following values after applying shiftAmount:
- // - immediateOffsetAfterShift, secondOperandAfterShift
-
- switch (decodedInstruction.scaleMode)
- {
- case ARM_SCALE_NONE:
- addressOffsetFromRegisterAfterShift = addressOffsetFromRegister;
- secondOperandAfterShift = secondOperand;
- break;
-
- case ARM_SCALE_LSL: // Logical shift left
- addressOffsetFromRegisterAfterShift = addressOffsetFromRegister << shiftAmount;
- secondOperandAfterShift = secondOperand << shiftAmount;
- break;
-
- case ARM_SCALE_LSR: // Logical shift right
- addressOffsetFromRegisterAfterShift = addressOffsetFromRegister >> shiftAmount;
- secondOperandAfterShift = secondOperand >> shiftAmount;
- break;
-
- case ARM_SCALE_ASR: // Arithmetic shift right
- asm("mov %0, %1, asr %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
- asm("mov %0, %1, asr %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
- break;
-
- case ARM_SCALE_ROR: // Rotate right
- asm("mov %0, %1, ror %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
- asm("mov %0, %1, ror %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
- break;
-
- case ARM_SCALE_RRX: // Rotate right, pulling in carry (1-bit shift only)
- asm("mov %0, %1, rrx" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister));
- asm("mov %0, %1, rrx" : "=r" (secondOperandAfterShift) : "r" (secondOperand));
- break;
- }
-
- // Emulate instruction to calculate targetPC
- // All branches are already handled in the first switch statement. A branch should not reach this switch
- switch (decodedInstruction.instruction->code)
- {
- // Arithmetic operations that can change the PC
- case ARM_INST_ADC:
- case ARM_INST_ADCS:
- // Add with Carry
- *targetPC = firstOperand + (secondOperandAfterShift + immediateValue) + cpsr_c;
- break;
-
- case ARM_INST_ADD:
- case ARM_INST_ADDS:
- *targetPC = firstOperand + (secondOperandAfterShift + immediateValue);
- break;
-
- case ARM_INST_AND:
- case ARM_INST_ANDS:
- *targetPC = firstOperand & (secondOperandAfterShift + immediateValue);
- break;
-
- case ARM_INST_ASR:
- case ARM_INST_ASRS:
- asm("mov %0, %1, asr %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_BIC:
- case ARM_INST_BICS:
- asm("bic %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_EOR:
- case ARM_INST_EORS:
- asm("eor %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_ORR:
- case ARM_INST_ORRS:
- asm("orr %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_RSB:
- case ARM_INST_RSBS:
- asm("rsb %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_RSC:
- case ARM_INST_RSCS:
- myTargetPC = secondOperandAfterShift - (firstOperand + !cpsr_c);
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_SBC:
- case ARM_INST_SBCS:
- asm("sbc %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue + !cpsr_c));
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_SUB:
- case ARM_INST_SUBS:
- asm("sub %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
- *targetPC = myTargetPC;
- break;
-
- // Logical shifts and move operations that can change the PC
- case ARM_INST_LSL:
- case ARM_INST_LSLS:
- case ARM_INST_LSR:
- case ARM_INST_LSRS:
- case ARM_INST_MOV:
- case ARM_INST_MOVS:
- case ARM_INST_ROR:
- case ARM_INST_RORS:
- case ARM_INST_RRX:
- case ARM_INST_RRXS:
- myTargetPC = secondOperandAfterShift + immediateValue;
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_MVN:
- case ARM_INST_MVNS:
- myTargetPC = !(secondOperandAfterShift + immediateValue);
- *targetPC = myTargetPC;
- break;
-
- // Load register can be used to load PC, usually with a function pointer
- case ARM_INST_LDR:
- switch (decodedInstruction.addressMode) {
- case ARM_ADDR_LSWUB_IMM_POST:
- case ARM_ADDR_LSWUB_REG_POST:
- case ARM_ADDR_LSWUB_SCALED_POST:
- addressWherePCLives = baseAddress;
- break;
-
- case ARM_ADDR_LSWUB_IMM:
- case ARM_ADDR_LSWUB_REG:
- case ARM_ADDR_LSWUB_SCALED:
- case ARM_ADDR_LSWUB_IMM_PRE:
- case ARM_ADDR_LSWUB_REG_PRE:
- case ARM_ADDR_LSWUB_SCALED_PRE:
- addressWherePCLives = baseAddress + (addressOffsetFromRegisterAfterShift + immediateOffset);
- break;
-
- default:
- break;
- }
-
- mypid = m_thread->ProcessID();
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t))
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
- return false;
- }
-
- *targetPC = myTargetPC;
- break;
-
- // 32b load multiple operations can load the PC along with everything else,
- // usually to return from a function call
- case ARM_INST_LDMDA:
- mypid = m_thread->ProcessID();
- addressWherePCLives = baseAddress;
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t))
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
- return false;
- }
-
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_LDMDB:
- mypid = m_thread->ProcessID();
- addressWherePCLives = baseAddress - 4;
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t))
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
- return false;
- }
-
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_LDMIB:
- mypid = m_thread->ProcessID();
- addressWherePCLives = baseAddress + numRegistersToLoad*4 + 4;
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t))
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
- return false;
- }
-
- *targetPC = myTargetPC;
- break;
-
- case ARM_INST_LDMIA: // same as pop
- // Normal 16-bit LD multiple can't touch R15, but POP can
- case ARM_INST_POP: // Can also get the PC & updates SP
- mypid = m_thread->ProcessID();
- addressWherePCLives = baseAddress + numRegistersToLoad*4;
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t))
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
- return false;
- }
-
- *targetPC = myTargetPC;
- break;
-
- // 16b TBB and TBH instructions load a jump address from a table
- case ARM_INST_TBB:
- mypid = m_thread->ProcessID();
- addressWherePCLives = baseAddress + addressOffsetFromRegisterAfterShift;
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, 1, &halfwords) != 1)
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBB instruction!", addressWherePCLives);
- return false;
- }
- // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
- *targetPC = (currentPC + 4) + 2*halfwords;
- break;
-
- case ARM_INST_TBH:
- mypid = m_thread->ProcessID();
- addressWherePCLives = ((baseAddress + (addressOffsetFromRegisterAfterShift << 1)) & ~0x1);
- if (DNBProcessMemoryRead(mypid, addressWherePCLives, 2, &halfwords) != 2)
- {
- DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBH instruction!", addressWherePCLives);
- return false;
- }
- // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
- *targetPC = (currentPC + 4) + 2*halfwords;
- break;
-
- // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
- // from a special base pointer register (which is unknown at disassembly time)
- case ARM_INST_HB:
- case ARM_INST_HBP:
- // TODO: ARM_INST_HB, ARM_INST_HBP
- break;
-
- case ARM_INST_HBL:
- case ARM_INST_HBLP:
- // TODO: ARM_INST_HBL, ARM_INST_HBLP
- break;
-
- // Breakpoint and software interrupt jump to interrupt handler (always ARM)
- case ARM_INST_BKPT:
- case ARM_INST_SMC:
- case ARM_INST_SVC:
- // TODO: ARM_INST_BKPT, ARM_INST_SMC, ARM_INST_SVC
- break;
-
- // Return from exception, obviously modifies PC [interrupt only!]
- case ARM_INST_RFEDA:
- case ARM_INST_RFEDB:
- case ARM_INST_RFEIA:
- case ARM_INST_RFEIB:
- // TODO: ARM_INST_RFEDA, ARM_INST_RFEDB, ARM_INST_RFEIA, ARM_INST_RFEIB
- break;
-
- // Other instructions either can't change R15 or are "undefined" if you do,
- // so no sane compiler should ever generate them & we don't care here.
- // Also, R15 can only legally be used in a read-only manner for the
- // various ARM addressing mode (to get PC-relative addressing of constants),
- // but can NOT be used with any of the update modes.
- default:
- DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
- return false;
- break;
- }
-
- return true;
-}
-
-void
-DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, nub_addr_t *nextPC, bool *nextPCIsThumb)
-{
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup() called");
-
- nub_addr_t targetPC = INVALID_NUB_ADDRESS;
- uint32_t registerValue;
- arm_error_t decodeError;
- nub_addr_t currentPCInITBlock, nextPCInITBlock;
- int i;
- bool last_decoded_instruction_executes = true;
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: default nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");
-
- // Update *nextPC and *nextPCIsThumb for special cases
- if (m_last_decode_thumb.itBlockRemaining) // we are in an IT block
- {
- // Set the nextPC to the PC of the instruction which will execute in the IT block
- // If none of the instruction execute in the IT block based on the condition flags,
- // then point to the instruction immediately following the IT block
- const int itBlockRemaining = m_last_decode_thumb.itBlockRemaining;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%8.8x", __FUNCTION__, itBlockRemaining);
-
- // Determine the PC at which the next instruction resides
- if (m_last_decode_arm.thumb16b)
- currentPCInITBlock = currentPC + 2;
- else
- currentPCInITBlock = currentPC + 4;
-
- for (i = 0; i < itBlockRemaining; i++)
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: currentPCInITBlock=%8.8x", __FUNCTION__, currentPCInITBlock);
- decodeError = DecodeInstructionUsingDisassembler(currentPCInITBlock, cpsr, &m_last_decode_arm, &m_last_decode_thumb, &nextPCInITBlock);
-
- if (decodeError != ARM_SUCCESS)
- DNBLogError("unable to disassemble instruction at 0x%8.8llx", (uint64_t)currentPCInITBlock);
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: condition=%d", __FUNCTION__, m_last_decode_arm.condition);
- if (ConditionPassed(m_last_decode_arm.condition, cpsr))
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes matched for instruction %d", __FUNCTION__, i);
- break; // break from the for loop
- }
- else
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes DID NOT matched for instruction %d", __FUNCTION__, i);
- }
-
- // update currentPC and nextPCInITBlock
- currentPCInITBlock = nextPCInITBlock;
- }
-
- if (i == itBlockRemaining) // We came out of the IT block without executing any instructions
- last_decoded_instruction_executes = false;
-
- *nextPC = currentPCInITBlock;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: After IT block step-through: *nextPC=%8.8x", __FUNCTION__, *nextPC);
- }
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
- "%s: cpsr = %8.8x, thumb16b = %d, thumb = %d, branch = %d, conditional = %d, knownTarget = %d, links = %d, canSwitchMode = %d, doesSwitchMode = %d",
- __FUNCTION__,
- cpsr,
- m_last_decode_arm.thumb16b,
- m_last_decode_arm.thumb,
- m_last_decode_arm.branch,
- m_last_decode_arm.conditional,
- m_last_decode_arm.knownTarget,
- m_last_decode_arm.links,
- m_last_decode_arm.canSwitchMode,
- m_last_decode_arm.doesSwitchMode);
-
-
- if (last_decoded_instruction_executes && // Was this a conditional instruction that did execute?
- m_last_decode_arm.branch && // Can this instruction change the PC?
- (m_last_decode_arm.instruction->code != ARM_INST_SVC)) // If this instruction is not an SVC instruction
- {
- // Set targetPC. Compute if needed.
- if (m_last_decode_arm.knownTarget)
- {
- // Fixed, known PC-relative
- targetPC = m_last_decode_arm.targetPC;
- }
- else
- {
- // if targetPC is not known at compile time (PC-relative target), compute targetPC
- if (!ComputeNextPC(currentPC, m_last_decode_arm, currentPCIsThumb, &targetPC))
- {
- DNBLogError("%s: Unable to compute targetPC for instruction at 0x%8.8llx", __FUNCTION__, (uint64_t)currentPC);
- targetPC = INVALID_NUB_ADDRESS;
- }
- }
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: targetPC=0x%8.8x, cpsr=0x%8.8x, condition=0x%hhx", __FUNCTION__, targetPC, cpsr, m_last_decode_arm.condition);
-
- // Refine nextPC computation
- if ((m_last_decode_arm.instruction->code == ARM_INST_CBZ) ||
- (m_last_decode_arm.instruction->code == ARM_INST_CBNZ))
- {
- // Compare and branch on zero/non-zero (Thumb-16 only)
- // Unusual condition check built into the instruction
- registerValue = m_state.context.gpr.__r[m_last_decode_arm.op[REG_RD].value];
-
- if (m_last_decode_arm.instruction->code == ARM_INST_CBZ)
- {
- if (registerValue == 0)
- *nextPC = targetPC;
- }
- else
- {
- if (registerValue != 0)
- *nextPC = targetPC;
- }
- }
- else if (m_last_decode_arm.conditional) // Is the change conditional on flag results?
- {
- if (ConditionPassed(m_last_decode_arm.condition, cpsr)) // conditions match
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition matched!", __FUNCTION__);
- *nextPC = targetPC;
- }
- else
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition did not match!", __FUNCTION__);
- }
- }
- else
- {
- *nextPC = targetPC;
- }
-
- // Refine nextPCIsThumb computation
- if (m_last_decode_arm.doesSwitchMode)
- {
- *nextPCIsThumb = !currentPCIsThumb;
- }
- else if (m_last_decode_arm.canSwitchMode)
- {
- // Legal to switch ARM <--> Thumb mode with this branch
- // dependent on bit[0] of targetPC
- *nextPCIsThumb = (*nextPC & 1u) != 0;
- }
- else
- {
- *nextPCIsThumb = currentPCIsThumb;
- }
- }
-
- DNBLogThreadedIf(LOG_STEP, "%s: calculated nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");
-}
-
-
-arm_error_t
-DNBArchMachARM::DecodeInstructionUsingDisassembler(nub_addr_t curr_pc, uint32_t curr_cpsr, arm_decoded_instruction_t *decodedInstruction, thumb_static_data_t *thumbStaticData, nub_addr_t *next_pc)
-{
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc=0x%8.8x, cpsr=0x%8.8x", __FUNCTION__, curr_pc, curr_cpsr);
-
- const uint32_t isetstate_mask = MASK_CPSR_T | MASK_CPSR_J;
- const uint32_t curr_isetstate = curr_cpsr & isetstate_mask;
- uint32_t opcode32;
- nub_addr_t nextPC = curr_pc;
- arm_error_t decodeReturnCode = ARM_SUCCESS;
-
- m_last_decode_pc = curr_pc;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);
-
- switch (curr_isetstate) {
- case 0x0: // ARM Instruction
- // Read the ARM opcode
- if (m_thread->Process()->Task().ReadMemory(curr_pc, 4, &opcode32) != 4)
- {
- DNBLogError("unable to read opcode bits 31:0 for an ARM opcode at 0x%8.8llx", (uint64_t)curr_pc);
- decodeReturnCode = ARM_ERROR;
- }
- else
- {
- nextPC += 4;
- decodeReturnCode = ArmDisassembler((uint64_t)curr_pc, opcode32, false, decodedInstruction, NULL, 0, NULL, 0);
-
- if (decodeReturnCode != ARM_SUCCESS)
- DNBLogError("Unable to decode ARM instruction 0x%8.8x at 0x%8.8llx", opcode32, (uint64_t)curr_pc);
- }
- break;
-
- case 0x20: // Thumb Instruction
- uint16_t opcode16;
- // Read the a 16 bit Thumb opcode
- if (m_thread->Process()->Task().ReadMemory(curr_pc, 2, &opcode16) != 2)
- {
- DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc);
- decodeReturnCode = ARM_ERROR;
- }
- else
- {
- nextPC += 2;
- opcode32 = opcode16;
-
- decodeReturnCode = ThumbDisassembler((uint64_t)curr_pc, opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);
-
- switch (decodeReturnCode) {
- case ARM_SKIP:
- // 32 bit thumb opcode
- nextPC += 2;
- if (m_thread->Process()->Task().ReadMemory(curr_pc+2, 2, &opcode16) != 2)
- {
- DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc+2);
- }
- else
- {
- opcode32 = (opcode32 << 16) | opcode16;
-
- decodeReturnCode = ThumbDisassembler((uint64_t)(curr_pc+2), opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);
-
- if (decodeReturnCode != ARM_SUCCESS)
- DNBLogError("Unable to decode 2nd half of Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc+2);
- break;
- }
- break;
-
- case ARM_SUCCESS:
- // 16 bit thumb opcode; at this point we are done decoding the opcode
- break;
-
- default:
- DNBLogError("Unable to decode Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc);
- decodeReturnCode = ARM_ERROR;
- break;
+ exc.exc_data.push_back(hw_index);
}
- }
- break;
- default:
+ return true;
+ }
break;
}
-
- if (next_pc)
- *next_pc = nextPC;
-
- return decodeReturnCode;
+ return false;
}
-#endif
-
-nub_bool_t
-DNBArchMachARM::BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
+bool
+DNBArchMachARM::StepNotComplete ()
{
- nub_addr_t bkpt_pc = (nub_addr_t)baton;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc);
-
- DNBRegisterValue pc_value;
- DNBThreadGetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
- pc_value.value.uint32 = bkpt_pc;
- return DNBThreadSetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
+ if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS)
+ {
+ kern_return_t kret = KERN_INVALID_ARGUMENT;
+ kret = GetGPRState(false);
+ if (kret == KERN_SUCCESS)
+ {
+ if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr)
+ {
+ DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr);
+ return true;
+ }
+ }
+ }
+
+ m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
+ return false;
}
+
// Set the single step bit in the processor status register.
kern_return_t
-DNBArchMachARM::SetSingleStepSoftwareBreakpoints()
+DNBArchMachARM::EnableHardwareSingleStep (bool enable)
{
DNBError err;
+ DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable);
-#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
err = GetGPRState(false);
if (err.Fail())
@@ -1949,192 +553,164 @@ DNBArchMachARM::SetSingleStepSoftwareBre
return err.Error();
}
- nub_addr_t curr_pc = m_state.context.gpr.__pc;
- uint32_t curr_cpsr = m_state.context.gpr.__cpsr;
- nub_addr_t next_pc = curr_pc;
-
- bool curr_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0;
- bool next_pc_is_thumb = curr_pc_is_thumb;
-
- uint32_t curr_itstate = ((curr_cpsr & 0x6000000) >> 25) | ((curr_cpsr & 0xFC00) >> 8);
- bool inITBlock = (curr_itstate & 0xF) ? 1 : 0;
- bool lastInITBlock = ((curr_itstate & 0xF) == 0x8) ? 1 : 0;
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: curr_pc=0x%8.8x (%s), curr_itstate=0x%x, inITBlock=%d, lastInITBlock=%d", __FUNCTION__, curr_pc, curr_pc_is_thumb ? "Thumb" : "ARM", curr_itstate, inITBlock, lastInITBlock);
-
- // If the instruction is not in the IT block, then decode using the Disassembler and compute next_pc
- if (!inITBlock)
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Decoding an instruction NOT in the IT block", __FUNCTION__);
-
- arm_error_t decodeReturnCode = DecodeInstructionUsingDisassembler(curr_pc, curr_cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc);
+ err = GetDBGState(false);
- if (decodeReturnCode != ARM_SUCCESS)
- {
- err = KERN_INVALID_ARGUMENT;
- DNBLogError("DNBArchMachARM::SetSingleStepSoftwareBreakpoints: Unable to disassemble instruction at 0x%8.8llx", (uint64_t)curr_pc);
- }
- }
- else
+ if (err.Fail())
{
- next_pc = curr_pc + ((m_last_decode_arm.thumb16b) ? 2 : 4);
+ err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
+ return err.Error();
}
- // Instruction is NOT in the IT block OR
- if (!inITBlock)
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: normal instruction", __FUNCTION__);
- EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
- }
- else if (inITBlock && !m_last_decode_arm.setsFlags)
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that doesn't set flags", __FUNCTION__);
- EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
- }
- else if (lastInITBlock && m_last_decode_arm.branch)
- {
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction which last in the IT block and is a branch", __FUNCTION__);
- EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
- }
- else
+ const uint32_t i = 0;
+ if (enable)
{
- // Instruction is in IT block and can modify the CPSR flags
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that sets flags", __FUNCTION__);
-
- // NOTE: When this point of code is reached, the instruction at curr_pc has already been decoded
- // inside the function ThreadDidStop(). Therefore m_last_decode_arm, m_last_decode_thumb
- // reflect the decoded instruction at curr_pc
-
- // If we find an instruction inside the IT block which will set/modify the condition flags (NZCV bits in CPSR),
- // we set breakpoints at all remaining instructions inside the IT block starting from the instruction immediately
- // following this one AND a breakpoint at the instruction immediately following the IT block. We do this because
- // we cannot determine the next_pc until the instruction at which we are currently stopped executes. Hence we
- // insert (m_last_decode_thumb.itBlockRemaining+1) 16-bit Thumb breakpoints at consecutive memory locations
- // starting at addrOfNextInstructionInITBlock. We record these breakpoints in class variable m_sw_single_step_itblock_break_id[],
- // and also record the total number of IT breakpoints set in the variable 'm_sw_single_step_itblock_break_count'.
-
- // The instructions inside the IT block, which are replaced by the 16-bit Thumb breakpoints (opcode=0xDEFE)
- // instructions, can be either Thumb-16 or Thumb-32. When a Thumb-32 instruction (say, inst#1) is replaced Thumb
- // by a 16-bit breakpoint (OS only supports 16-bit breakpoints in Thumb mode and 32-bit breakpoints in ARM mode), the
- // breakpoint for the next instruction (say instr#2) is saved in the upper half of this Thumb-32 (instr#1)
- // instruction. Hence if the execution stops at Breakpoint2 corresponding to instr#2, the PC is offset by 16-bits.
- // We therefore have to keep track of PC of each instruction in the IT block that is being replaced with the 16-bit
- // Thumb breakpoint, to ensure that when the breakpoint is hit, the PC is adjusted to the correct value. We save
- // the actual PC corresponding to each instruction in the IT block by associating a call back with each breakpoint
- // we set and passing it as a baton. When the breakpoint hits and the callback routine is called, the routine
- // adjusts the PC based on the baton that is passed to it.
-
- nub_addr_t addrOfNextInstructionInITBlock, pcInITBlock, nextPCInITBlock, bpAddressInITBlock;
- uint16_t opcode16;
- uint32_t opcode32;
-
- addrOfNextInstructionInITBlock = (m_last_decode_arm.thumb16b) ? curr_pc + 2 : curr_pc + 4;
-
- pcInITBlock = addrOfNextInstructionInITBlock;
-
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%d", __FUNCTION__, m_last_decode_thumb.itBlockRemaining);
+ m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
- m_sw_single_step_itblock_break_count = 0;
- for (int i = 0; i <= m_last_decode_thumb.itBlockRemaining; i++)
+ // Save our previous state
+ m_dbg_save = m_state.dbg;
+ // Set a breakpoint that will stop when the PC doesn't match the current one!
+ m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address
+ m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH | // Stop on address mismatch
+ S_USER | // Stop only in user mode
+ BCR_ENABLE; // Enable this breakpoint
+ if (m_state.context.gpr.__cpsr & 0x20)
{
- if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
- {
- DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Array m_sw_single_step_itblock_break_id should not contain any valid breakpoint IDs at this point. But found a valid breakID=%d at index=%d", m_sw_single_step_itblock_break_id[i], i);
- }
+ // Thumb breakpoint
+ if (m_state.context.gpr.__pc & 2)
+ m_state.dbg.__bcr[i] |= BAS_IMVA_2_3;
else
+ m_state.dbg.__bcr[i] |= BAS_IMVA_0_1;
+
+ uint16_t opcode;
+ if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode))
{
- nextPCInITBlock = pcInITBlock;
- // Compute nextPCInITBlock based on opcode present at pcInITBlock
- if (m_thread->Process()->Task().ReadMemory(pcInITBlock, 2, &opcode16) == 2)
+ if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800)
{
- opcode32 = opcode16;
- nextPCInITBlock += 2;
-
- // Check for 32 bit thumb opcode and read the upper 16 bits if needed
- if (((opcode32 & 0xE000) == 0xE000) && (opcode32 & 0x1800))
+ // 32 bit thumb opcode...
+ if (m_state.context.gpr.__pc & 2)
{
- // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
- // a 32 bit Thumb opcode
- // Read bits 31:16 of a 32 bit Thumb opcode
- if (m_thread->Process()->Task().ReadMemory(pcInITBlock+2, 2, &opcode16) == 2)
- {
- // 32 bit thumb opcode
- opcode32 = (opcode32 << 16) | opcode16;
- nextPCInITBlock += 2;
- }
- else
- {
- DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", (uint64_t)nextPCInITBlock);
- }
+ // We can't take care of a 32 bit thumb instruction single step
+ // with just IVA mismatching. We will need to chain an extra
+ // hardware single step in order to complete this single step...
+ m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
+ }
+ else
+ {
+ // Extend the number of bits to ignore for the mismatch
+ m_state.dbg.__bcr[i] |= BAS_IMVA_ALL;
}
- }
- else
- {
- DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Error reading 16-bit Thumb instruction at pc=0x%8.8x", nextPCInITBlock);
- }
-
-
- // Set breakpoint and associate a callback function with it
- bpAddressInITBlock = addrOfNextInstructionInITBlock + 2*i;
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Setting IT breakpoint[%d] at address: 0x%8.8x", __FUNCTION__, i, bpAddressInITBlock);
-
- m_sw_single_step_itblock_break_id[i] = m_thread->Process()->CreateBreakpoint(bpAddressInITBlock, 2, false, m_thread->ThreadID());
- if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
- err = KERN_INVALID_ARGUMENT;
- else
- {
- DNBLogThreadedIf(LOG_STEP, "%s: Set IT breakpoint[%i]=%d set at 0x%8.8x for instruction at 0x%8.8x", __FUNCTION__, i, m_sw_single_step_itblock_break_id[i], bpAddressInITBlock, pcInITBlock);
-
- // Set the breakpoint callback for these special IT breakpoints
- // so that if one of these breakpoints gets hit, it knows to
- // update the PC to the original address of the conditional
- // IT instruction.
- DNBBreakpointSetCallback(m_thread->ProcessID(), m_sw_single_step_itblock_break_id[i], DNBArchMachARM::BreakpointHit, (void*)pcInITBlock);
- m_sw_single_step_itblock_break_count++;
}
}
-
- pcInITBlock = nextPCInITBlock;
+ }
+ else
+ {
+ // ARM breakpoint
+ m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change
}
- DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Set %u IT software single breakpoints.", __FUNCTION__, m_sw_single_step_itblock_break_count);
-
- }
-
- DNBLogThreadedIf(LOG_STEP, "%s: next_pc=0x%8.8x (%s)", __FUNCTION__, next_pc, next_pc_is_thumb ? "Thumb" : "ARM");
-
- if (next_pc & 0x1)
- {
- assert(next_pc_is_thumb);
- }
+ DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x BCR%u=0x%8.8x", __FUNCTION__, i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]);
- if (next_pc_is_thumb)
- {
- next_pc &= ~0x1;
+ for (uint32_t j=i+1; j<16; ++j)
+ {
+ // Disable all others
+ m_state.dbg.__bvr[j] = 0;
+ m_state.dbg.__bcr[j] = 0;
+ }
}
else
{
- assert((next_pc & 0x3) == 0);
+ // Just restore the state we had before we did single stepping
+ m_state.dbg = m_dbg_save;
}
- if (!inITBlock || (inITBlock && !m_last_decode_arm.setsFlags) || (lastInITBlock && m_last_decode_arm.branch))
- {
- err = KERN_SUCCESS;
+ return SetDBGState();
+}
- const DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(next_pc);
+// return 1 if bit "BIT" is set in "value"
+static inline uint32_t bit(uint32_t value, uint32_t bit)
+{
+ return (value >> bit) & 1u;
+}
- if (bp == NULL)
- {
- m_sw_single_step_break_id = m_thread->Process()->CreateBreakpoint(next_pc, next_pc_is_thumb ? 2 : 4, false, m_thread->ThreadID());
- if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id))
- err = KERN_INVALID_ARGUMENT;
- DNBLogThreadedIf(LOG_STEP, "%s: software single step breakpoint with breakID=%d set at 0x%8.8x", __FUNCTION__, m_sw_single_step_break_id, next_pc);
- }
+// return the bitfield "value[msbit:lsbit]".
+static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit)
+{
+ assert(msbit >= lsbit);
+ uint32_t shift_left = sizeof(value) * 8 - 1 - msbit;
+ value <<= shift_left; // shift anything above the msbit off of the unsigned edge
+ value >>= (shift_left + lsbit); // shift it back again down to the lsbit (including undoing any shift from above)
+ return value; // return our result
+}
+
+bool
+DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr)
+{
+ uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag
+ uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag
+ uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag
+ uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag
+
+ switch (condition) {
+ case COND_EQ: // (0x0)
+ if (cpsr_z == 1) return true;
+ break;
+ case COND_NE: // (0x1)
+ if (cpsr_z == 0) return true;
+ break;
+ case COND_CS: // (0x2)
+ if (cpsr_c == 1) return true;
+ break;
+ case COND_CC: // (0x3)
+ if (cpsr_c == 0) return true;
+ break;
+ case COND_MI: // (0x4)
+ if (cpsr_n == 1) return true;
+ break;
+ case COND_PL: // (0x5)
+ if (cpsr_n == 0) return true;
+ break;
+ case COND_VS: // (0x6)
+ if (cpsr_v == 1) return true;
+ break;
+ case COND_VC: // (0x7)
+ if (cpsr_v == 0) return true;
+ break;
+ case COND_HI: // (0x8)
+ if ((cpsr_c == 1) && (cpsr_z == 0)) return true;
+ break;
+ case COND_LS: // (0x9)
+ if ((cpsr_c == 0) || (cpsr_z == 1)) return true;
+ break;
+ case COND_GE: // (0xA)
+ if (cpsr_n == cpsr_v) return true;
+ break;
+ case COND_LT: // (0xB)
+ if (cpsr_n != cpsr_v) return true;
+ break;
+ case COND_GT: // (0xC)
+ if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true;
+ break;
+ case COND_LE: // (0xD)
+ if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true;
+ break;
+ default:
+ return true;
+ break;
}
-#else
- err.LogThreaded("%s: ARMDisassembler.framework support is disabled", __FUNCTION__);
-#endif
- return err.Error();
+
+ return false;
+}
+
+nub_bool_t
+DNBArchMachARM::BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
+{
+ nub_addr_t bkpt_pc = (nub_addr_t)baton;
+ DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc);
+
+ DNBRegisterValue pc_value;
+ DNBThreadGetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
+ pc_value.value.uint32 = bkpt_pc;
+ return DNBThreadSetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
}
uint32_t
@@ -2450,6 +1026,8 @@ DNBArchMachARM::EnableHardwareWatchpoint
(write ? WCR_STORE : 0) | // Stop on write access?
WCR_ENABLE; // Enable this watchpoint;
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]);
+
kret = SetDBGState();
//DumpDBGState(m_state.dbg);
@@ -2652,7 +1230,7 @@ DNBArchMachARM::GetWatchAddress(const DB
}
//----------------------------------------------------------------------
-// Register information defintions for 32 bit ARMV6.
+// Register information defintions for 32 bit ARMV7.
//----------------------------------------------------------------------
enum gpr_regnums
{
@@ -2677,7 +1255,7 @@ enum gpr_regnums
enum
{
- vfp_s0 = 0,
+ vfp_s0 = 17, // match the g_gdb_register_map_arm table in RNBRemote.cpp
vfp_s1,
vfp_s2,
vfp_s3,
@@ -2708,8 +1286,12 @@ enum
vfp_s28,
vfp_s29,
vfp_s30,
- vfp_s31,
- vfp_d0,
+ vfp_s31
+};
+
+enum
+{
+ vfp_d0 = 49, // match the g_gdb_register_map_arm table in RNBRemote.cpp
vfp_d1,
vfp_d2,
vfp_d3,
@@ -2740,114 +1322,63 @@ enum
vfp_d28,
vfp_d29,
vfp_d30,
- vfp_d31,
- vfp_fpscr
+ vfp_d31
};
enum
{
- exc_exception,
- exc_fsr,
- exc_far,
+ vfp_q0 = 81, // match the g_gdb_register_map_arm table in RNBRemote.cpp
+ vfp_q1,
+ vfp_q2,
+ vfp_q3,
+ vfp_q4,
+ vfp_q5,
+ vfp_q6,
+ vfp_q7,
+ vfp_q8,
+ vfp_q9,
+ vfp_q10,
+ vfp_q11,
+ vfp_q12,
+ vfp_q13,
+ vfp_q14,
+ vfp_q15,
+ vfp_fpscr
};
enum
{
- gdb_r0 = 0,
- gdb_r1,
- gdb_r2,
- gdb_r3,
- gdb_r4,
- gdb_r5,
- gdb_r6,
- gdb_r7,
- gdb_r8,
- gdb_r9,
- gdb_r10,
- gdb_r11,
- gdb_r12,
- gdb_sp,
- gdb_lr,
- gdb_pc,
- gdb_f0,
- gdb_f1,
- gdb_f2,
- gdb_f3,
- gdb_f4,
- gdb_f5,
- gdb_f6,
- gdb_f7,
- gdb_f8,
- gdb_cpsr,
- gdb_s0,
- gdb_s1,
- gdb_s2,
- gdb_s3,
- gdb_s4,
- gdb_s5,
- gdb_s6,
- gdb_s7,
- gdb_s8,
- gdb_s9,
- gdb_s10,
- gdb_s11,
- gdb_s12,
- gdb_s13,
- gdb_s14,
- gdb_s15,
- gdb_s16,
- gdb_s17,
- gdb_s18,
- gdb_s19,
- gdb_s20,
- gdb_s21,
- gdb_s22,
- gdb_s23,
- gdb_s24,
- gdb_s25,
- gdb_s26,
- gdb_s27,
- gdb_s28,
- gdb_s29,
- gdb_s30,
- gdb_s31,
- gdb_fpscr,
- gdb_d0,
- gdb_d1,
- gdb_d2,
- gdb_d3,
- gdb_d4,
- gdb_d5,
- gdb_d6,
- gdb_d7,
- gdb_d8,
- gdb_d9,
- gdb_d10,
- gdb_d11,
- gdb_d12,
- gdb_d13,
- gdb_d14,
- gdb_d15
+ exc_exception,
+ exc_fsr,
+ exc_far,
};
#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx]))
#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg))
-#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp))
-#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2))
-#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp))
+
#define EXC_OFFSET(reg) (offsetof (DNBArchMachARM::EXC, __##reg) + offsetof (DNBArchMachARM::Context, exc))
// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
-#define DEFINE_GPR_NAME(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
-//#define FLOAT_FORMAT Float
-#define FLOAT_FORMAT Hex
-#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
-//#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, gdb_d##idx }
-#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
+#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, NULL}
+#define DEFINE_GPR_NAME(reg, alt, gen, inval) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, inval}
+
+// In case we are debugging to a debug target that the ability to
+// change into the protected modes with folded registers (ABT, IRQ,
+// FIQ, SYS, USR, etc..), we should invalidate r8-r14 if the CPSR
+// gets modified.
+
+uint32_t g_invalidate_cpsr[] = {
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_sp,
+ gpr_lr,
+ INVALID_NUB_REGNUM };
// General purpose registers
const DNBRegisterInfo
@@ -2866,81 +1397,146 @@ DNBArchMachARM::g_gpr_registers[] =
DEFINE_GPR_IDX (10, r10, NULL, INVALID_NUB_REGNUM ),
DEFINE_GPR_IDX (11, r11, NULL, INVALID_NUB_REGNUM ),
DEFINE_GPR_IDX (12, r12, NULL, INVALID_NUB_REGNUM ),
- DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP ),
- DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA ),
- DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC ),
- DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS )
+ DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP, NULL),
+ DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA, NULL),
+ DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC, NULL),
+ DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS, g_invalidate_cpsr)
};
+uint32_t g_contained_q0[] {vfp_q0, INVALID_NUB_REGNUM };
+uint32_t g_contained_q1[] {vfp_q1, INVALID_NUB_REGNUM };
+uint32_t g_contained_q2[] {vfp_q2, INVALID_NUB_REGNUM };
+uint32_t g_contained_q3[] {vfp_q3, INVALID_NUB_REGNUM };
+uint32_t g_contained_q4[] {vfp_q4, INVALID_NUB_REGNUM };
+uint32_t g_contained_q5[] {vfp_q5, INVALID_NUB_REGNUM };
+uint32_t g_contained_q6[] {vfp_q6, INVALID_NUB_REGNUM };
+uint32_t g_contained_q7[] {vfp_q7, INVALID_NUB_REGNUM };
+uint32_t g_contained_q8[] {vfp_q8, INVALID_NUB_REGNUM };
+uint32_t g_contained_q9[] {vfp_q9, INVALID_NUB_REGNUM };
+uint32_t g_contained_q10[] {vfp_q10, INVALID_NUB_REGNUM };
+uint32_t g_contained_q11[] {vfp_q11, INVALID_NUB_REGNUM };
+uint32_t g_contained_q12[] {vfp_q12, INVALID_NUB_REGNUM };
+uint32_t g_contained_q13[] {vfp_q13, INVALID_NUB_REGNUM };
+uint32_t g_contained_q14[] {vfp_q14, INVALID_NUB_REGNUM };
+uint32_t g_contained_q15[] {vfp_q15, INVALID_NUB_REGNUM };
+
+uint32_t g_invalidate_q0[] {vfp_q0, vfp_d0, vfp_d1, vfp_s0, vfp_s1, vfp_s2, vfp_s3, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q1[] {vfp_q1, vfp_d2, vfp_d3, vfp_s4, vfp_s5, vfp_s6, vfp_s7, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q2[] {vfp_q2, vfp_d4, vfp_d5, vfp_s8, vfp_s9, vfp_s10, vfp_s11, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q3[] {vfp_q3, vfp_d6, vfp_d7, vfp_s12, vfp_s13, vfp_s14, vfp_s15, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q4[] {vfp_q4, vfp_d8, vfp_d9, vfp_s16, vfp_s17, vfp_s18, vfp_s19, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q5[] {vfp_q5, vfp_d10, vfp_d11, vfp_s20, vfp_s21, vfp_s22, vfp_s23, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q6[] {vfp_q6, vfp_d12, vfp_d13, vfp_s24, vfp_s25, vfp_s26, vfp_s27, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q7[] {vfp_q7, vfp_d14, vfp_d15, vfp_s28, vfp_s29, vfp_s30, vfp_s31, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q8[] {vfp_q8, vfp_d16, vfp_d17, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q9[] {vfp_q9, vfp_d18, vfp_d19, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q10[] {vfp_q10, vfp_d20, vfp_d21, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q11[] {vfp_q11, vfp_d22, vfp_d23, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q12[] {vfp_q12, vfp_d24, vfp_d25, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q13[] {vfp_q13, vfp_d26, vfp_d27, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q14[] {vfp_q14, vfp_d28, vfp_d29, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_q15[] {vfp_q15, vfp_d30, vfp_d31, INVALID_NUB_REGNUM };
+
+#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp))
+#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2))
+#define VFP_Q_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 4))
+
+#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp))
+
+#define FLOAT_FORMAT Float
+
+#define DEFINE_VFP_S_IDX(idx) e_regSetVFP, vfp_s##idx - vfp_s0, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
+#define DEFINE_VFP_D_IDX(idx) e_regSetVFP, vfp_d##idx - vfp_s0, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
+#define DEFINE_VFP_Q_IDX(idx) e_regSetVFP, vfp_q##idx - vfp_s0, "q" #idx, NULL, Vector, VectorOfUInt8, 16, VFP_Q_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_q##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM
+
// Floating point registers
const DNBRegisterInfo
DNBArchMachARM::g_vfp_registers[] =
{
- DEFINE_VFP_S_IDX ( 0),
- DEFINE_VFP_S_IDX ( 1),
- DEFINE_VFP_S_IDX ( 2),
- DEFINE_VFP_S_IDX ( 3),
- DEFINE_VFP_S_IDX ( 4),
- DEFINE_VFP_S_IDX ( 5),
- DEFINE_VFP_S_IDX ( 6),
- DEFINE_VFP_S_IDX ( 7),
- DEFINE_VFP_S_IDX ( 8),
- DEFINE_VFP_S_IDX ( 9),
- DEFINE_VFP_S_IDX (10),
- DEFINE_VFP_S_IDX (11),
- DEFINE_VFP_S_IDX (12),
- DEFINE_VFP_S_IDX (13),
- DEFINE_VFP_S_IDX (14),
- DEFINE_VFP_S_IDX (15),
- DEFINE_VFP_S_IDX (16),
- DEFINE_VFP_S_IDX (17),
- DEFINE_VFP_S_IDX (18),
- DEFINE_VFP_S_IDX (19),
- DEFINE_VFP_S_IDX (20),
- DEFINE_VFP_S_IDX (21),
- DEFINE_VFP_S_IDX (22),
- DEFINE_VFP_S_IDX (23),
- DEFINE_VFP_S_IDX (24),
- DEFINE_VFP_S_IDX (25),
- DEFINE_VFP_S_IDX (26),
- DEFINE_VFP_S_IDX (27),
- DEFINE_VFP_S_IDX (28),
- DEFINE_VFP_S_IDX (29),
- DEFINE_VFP_S_IDX (30),
- DEFINE_VFP_S_IDX (31),
- DEFINE_VFP_D_IDX (0),
- DEFINE_VFP_D_IDX (1),
- DEFINE_VFP_D_IDX (2),
- DEFINE_VFP_D_IDX (3),
- DEFINE_VFP_D_IDX (4),
- DEFINE_VFP_D_IDX (5),
- DEFINE_VFP_D_IDX (6),
- DEFINE_VFP_D_IDX (7),
- DEFINE_VFP_D_IDX (8),
- DEFINE_VFP_D_IDX (9),
- DEFINE_VFP_D_IDX (10),
- DEFINE_VFP_D_IDX (11),
- DEFINE_VFP_D_IDX (12),
- DEFINE_VFP_D_IDX (13),
- DEFINE_VFP_D_IDX (14),
- DEFINE_VFP_D_IDX (15),
- DEFINE_VFP_D_IDX (16),
- DEFINE_VFP_D_IDX (17),
- DEFINE_VFP_D_IDX (18),
- DEFINE_VFP_D_IDX (19),
- DEFINE_VFP_D_IDX (20),
- DEFINE_VFP_D_IDX (21),
- DEFINE_VFP_D_IDX (22),
- DEFINE_VFP_D_IDX (23),
- DEFINE_VFP_D_IDX (24),
- DEFINE_VFP_D_IDX (25),
- DEFINE_VFP_D_IDX (26),
- DEFINE_VFP_D_IDX (27),
- DEFINE_VFP_D_IDX (28),
- DEFINE_VFP_D_IDX (29),
- DEFINE_VFP_D_IDX (30),
- DEFINE_VFP_D_IDX (31),
- { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
+ { DEFINE_VFP_S_IDX ( 0), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_S_IDX ( 1), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_S_IDX ( 2), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_S_IDX ( 3), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_S_IDX ( 4), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_S_IDX ( 5), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_S_IDX ( 6), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_S_IDX ( 7), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_S_IDX ( 8), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_S_IDX ( 9), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_S_IDX (10), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_S_IDX (11), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_S_IDX (12), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_S_IDX (13), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_S_IDX (14), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_S_IDX (15), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_S_IDX (16), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_S_IDX (17), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_S_IDX (18), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_S_IDX (19), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_S_IDX (20), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_S_IDX (21), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_S_IDX (22), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_S_IDX (23), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_S_IDX (24), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_S_IDX (25), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_S_IDX (26), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_S_IDX (27), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_S_IDX (28), g_contained_q7, g_invalidate_q7 },
+ { DEFINE_VFP_S_IDX (29), g_contained_q7, g_invalidate_q7 },
+ { DEFINE_VFP_S_IDX (30), g_contained_q7, g_invalidate_q7 },
+ { DEFINE_VFP_S_IDX (31), g_contained_q7, g_invalidate_q7 },
+
+ { DEFINE_VFP_D_IDX (0), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_D_IDX (1), g_contained_q0, g_invalidate_q0 },
+ { DEFINE_VFP_D_IDX (2), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_D_IDX (3), g_contained_q1, g_invalidate_q1 },
+ { DEFINE_VFP_D_IDX (4), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_D_IDX (5), g_contained_q2, g_invalidate_q2 },
+ { DEFINE_VFP_D_IDX (6), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_D_IDX (7), g_contained_q3, g_invalidate_q3 },
+ { DEFINE_VFP_D_IDX (8), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_D_IDX (9), g_contained_q4, g_invalidate_q4 },
+ { DEFINE_VFP_D_IDX (10), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_D_IDX (11), g_contained_q5, g_invalidate_q5 },
+ { DEFINE_VFP_D_IDX (12), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_D_IDX (13), g_contained_q6, g_invalidate_q6 },
+ { DEFINE_VFP_D_IDX (14), g_contained_q7, g_invalidate_q7 },
+ { DEFINE_VFP_D_IDX (15), g_contained_q7, g_invalidate_q7 },
+ { DEFINE_VFP_D_IDX (16), g_contained_q8, g_invalidate_q8 },
+ { DEFINE_VFP_D_IDX (17), g_contained_q8, g_invalidate_q8 },
+ { DEFINE_VFP_D_IDX (18), g_contained_q9, g_invalidate_q9 },
+ { DEFINE_VFP_D_IDX (19), g_contained_q9, g_invalidate_q9 },
+ { DEFINE_VFP_D_IDX (20), g_contained_q10, g_invalidate_q10 },
+ { DEFINE_VFP_D_IDX (21), g_contained_q10, g_invalidate_q10 },
+ { DEFINE_VFP_D_IDX (22), g_contained_q11, g_invalidate_q11 },
+ { DEFINE_VFP_D_IDX (23), g_contained_q11, g_invalidate_q11 },
+ { DEFINE_VFP_D_IDX (24), g_contained_q12, g_invalidate_q12 },
+ { DEFINE_VFP_D_IDX (25), g_contained_q12, g_invalidate_q12 },
+ { DEFINE_VFP_D_IDX (26), g_contained_q13, g_invalidate_q13 },
+ { DEFINE_VFP_D_IDX (27), g_contained_q13, g_invalidate_q13 },
+ { DEFINE_VFP_D_IDX (28), g_contained_q14, g_invalidate_q14 },
+ { DEFINE_VFP_D_IDX (29), g_contained_q14, g_invalidate_q14 },
+ { DEFINE_VFP_D_IDX (30), g_contained_q15, g_invalidate_q15 },
+ { DEFINE_VFP_D_IDX (31), g_contained_q15, g_invalidate_q15 },
+
+ { DEFINE_VFP_Q_IDX (0), NULL, g_invalidate_q0 },
+ { DEFINE_VFP_Q_IDX (1), NULL, g_invalidate_q1 },
+ { DEFINE_VFP_Q_IDX (2), NULL, g_invalidate_q2 },
+ { DEFINE_VFP_Q_IDX (3), NULL, g_invalidate_q3 },
+ { DEFINE_VFP_Q_IDX (4), NULL, g_invalidate_q4 },
+ { DEFINE_VFP_Q_IDX (5), NULL, g_invalidate_q5 },
+ { DEFINE_VFP_Q_IDX (6), NULL, g_invalidate_q6 },
+ { DEFINE_VFP_Q_IDX (7), NULL, g_invalidate_q7 },
+ { DEFINE_VFP_Q_IDX (8), NULL, g_invalidate_q8 },
+ { DEFINE_VFP_Q_IDX (9), NULL, g_invalidate_q9 },
+ { DEFINE_VFP_Q_IDX (10), NULL, g_invalidate_q10 },
+ { DEFINE_VFP_Q_IDX (11), NULL, g_invalidate_q11 },
+ { DEFINE_VFP_Q_IDX (12), NULL, g_invalidate_q12 },
+ { DEFINE_VFP_Q_IDX (13), NULL, g_invalidate_q13 },
+ { DEFINE_VFP_Q_IDX (14), NULL, g_invalidate_q14 },
+ { DEFINE_VFP_Q_IDX (15), NULL, g_invalidate_q15 },
+
+ { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
};
// Exception registers
@@ -3038,12 +1634,16 @@ DNBArchMachARM::GetRegisterValue(int set
break;
case e_regSetVFP:
- if (reg <= vfp_s31)
+ // "reg" is an index into the floating point register set at this point.
+ // We need to translate it up so entry 0 in the fp reg set is the same as vfp_s0
+ // in the enumerated values for case statement below.
+ reg += vfp_s0;
+ if (reg >= vfp_s0 && reg <= vfp_s31)
{
- value->value.uint32 = m_state.context.vfp.__r[reg];
+ value->value.uint32 = m_state.context.vfp.__r[reg - vfp_s0];
return true;
}
- else if (reg <= vfp_d31)
+ else if (reg >= vfp_d0 && reg <= vfp_d31)
{
uint32_t d_reg_idx = reg - vfp_d0;
uint32_t s_reg_idx = d_reg_idx * 2;
@@ -3051,6 +1651,13 @@ DNBArchMachARM::GetRegisterValue(int set
value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1];
return true;
}
+ else if (reg >= vfp_q0 && reg <= vfp_q15)
+ {
+ uint32_t s_reg_idx = (reg - vfp_q0) * 4;
+ memcpy (&value->value.v_uint8, (uint8_t *) &m_state.context.vfp.__r[s_reg_idx], 16);
+ return true;
+ }
+
else if (reg == vfp_fpscr)
{
value->value.uint32 = m_state.context.vfp.__fpscr;
@@ -3125,12 +1732,17 @@ DNBArchMachARM::SetRegisterValue(int set
break;
case e_regSetVFP:
- if (reg <= vfp_s31)
+ // "reg" is an index into the floating point register set at this point.
+ // We need to translate it up so entry 0 in the fp reg set is the same as vfp_s0
+ // in the enumerated values for case statement below.
+ reg += vfp_s0;
+
+ if (reg >= vfp_s0 && reg <= vfp_s31)
{
- m_state.context.vfp.__r[reg] = value->value.uint32;
+ m_state.context.vfp.__r[reg - vfp_s0] = value->value.uint32;
success = true;
}
- else if (reg <= vfp_d31)
+ else if (reg >= vfp_d0 && reg <= vfp_d31)
{
uint32_t d_reg_idx = reg - vfp_d0;
uint32_t s_reg_idx = d_reg_idx * 2;
@@ -3138,6 +1750,12 @@ DNBArchMachARM::SetRegisterValue(int set
m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1];
success = true;
}
+ else if (reg >= vfp_q0 && reg <= vfp_q15)
+ {
+ uint32_t s_reg_idx = (reg - vfp_q0) * 4;
+ memcpy ((uint8_t *) &m_state.context.vfp.__r[s_reg_idx], &value->value.v_uint8, 16);
+ return true;
+ }
else if (reg == vfp_fpscr)
{
m_state.context.vfp.__fpscr = value->value.uint32;
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h Wed Apr 17 03:38:48 2013
@@ -17,9 +17,6 @@
#if defined (__arm__)
#include "DNBArch.h"
-#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK)
-#include <ARMDisassembler/ARMDisassembler.h>
-#endif
class MachThread;
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Wed Apr 17 03:38:48 2013
@@ -83,6 +83,26 @@ enum
gpr_es = 13,
gpr_fs = 14,
gpr_gs = 15,
+ gpr_ax ,
+ gpr_bx ,
+ gpr_cx ,
+ gpr_dx ,
+ gpr_di ,
+ gpr_si ,
+ gpr_bp ,
+ gpr_sp ,
+ gpr_ah ,
+ gpr_bh ,
+ gpr_ch ,
+ gpr_dh ,
+ gpr_al ,
+ gpr_bl ,
+ gpr_cl ,
+ gpr_dl ,
+ gpr_dil,
+ gpr_sil,
+ gpr_bpl,
+ gpr_spl,
k_num_gpr_regs
};
@@ -314,7 +334,7 @@ DNBArchImplI386::GetGPRState(bool force)
m_state.SetError(e_regSetGPR, Read, 0);
#else
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
#endif
}
return m_state.GetError(e_regSetGPR, Read);
@@ -463,17 +483,17 @@ DNBArchImplI386::GetFPUState(bool force)
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
- m_state.SetError (e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
+ m_state.SetError (e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in)) => 0x%8.8x",
- m_thread->ThreadID(), __i386_AVX_STATE, count, e_regSetWordSizeAVX,
+ m_thread->MachPortNumber(), __i386_AVX_STATE, count, e_regSetWordSizeAVX,
m_state.GetError(e_regSetFPU, Read));
}
else
{
mach_msg_type_number_t count = e_regSetWordSizeFPU;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x",
- m_thread->ThreadID(), __i386_FLOAT_STATE, count, e_regSetWordSizeFPU,
+ m_thread->MachPortNumber(), __i386_FLOAT_STATE, count, e_regSetWordSizeFPU,
m_state.GetError(e_regSetFPU, Read));
}
}
@@ -487,7 +507,7 @@ DNBArchImplI386::GetEXCState(bool force)
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -495,7 +515,7 @@ DNBArchImplI386::GetEXCState(bool force)
kern_return_t
DNBArchImplI386::SetGPRState()
{
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
return m_state.GetError(e_regSetGPR, Write);
}
@@ -510,9 +530,9 @@ DNBArchImplI386::SetFPUState()
else
{
if (CPUHasAVX() || FORCE_AVX_REGS)
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
else
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
return m_state.GetError(e_regSetFPU, Write);
}
}
@@ -520,7 +540,7 @@ DNBArchImplI386::SetFPUState()
kern_return_t
DNBArchImplI386::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
@@ -530,7 +550,7 @@ DNBArchImplI386::GetDBGState(bool force)
if (force || m_state.GetError(e_regSetDBG, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
+ m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
}
return m_state.GetError(e_regSetDBG, Read);
}
@@ -538,7 +558,7 @@ DNBArchImplI386::GetDBGState(bool force)
kern_return_t
DNBArchImplI386::SetDBGState()
{
- m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
+ m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
return m_state.GetError(e_regSetDBG, Write);
}
@@ -821,7 +841,7 @@ DNBArchImplI386::GetWatchAddress(const D
bool
DNBArchImplI386::StartTransForHWP()
{
- if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
m_2pc_dbg_checkpoint = m_state.context.dbg;
m_2pc_trans_state = Trans_Pending;
@@ -997,6 +1017,10 @@ DNBArchImplI386::EnableHardwareSingleSte
// Register information defintions
//----------------------------------------------------------------------
+#define DEFINE_GPR_PSEUDO_16(reg16,reg32) { e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, GPR_OFFSET(reg32) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8H(reg8,reg32) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg32)+1,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8L(reg8,reg32) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg32) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+
#define GPR_OFFSET(reg) (offsetof (DNBArchImplI386::GPR, __##reg))
#define FPU_OFFSET(reg) (offsetof (DNBArchImplI386::FPU, __fpu_##reg) + offsetof (DNBArchImplI386::Context, fpu.no_avx))
@@ -1022,110 +1046,148 @@ DNBArchImplI386::EnableHardwareSingleSte
// the register state structures are defined correctly and have the correct
// sizes and offsets.
+uint32_t g_contained_eax[] = { gpr_eax, INVALID_NUB_REGNUM };
+uint32_t g_contained_ebx[] = { gpr_ebx, INVALID_NUB_REGNUM };
+uint32_t g_contained_ecx[] = { gpr_ecx, INVALID_NUB_REGNUM };
+uint32_t g_contained_edx[] = { gpr_edx, INVALID_NUB_REGNUM };
+uint32_t g_contained_edi[] = { gpr_edi, INVALID_NUB_REGNUM };
+uint32_t g_contained_esi[] = { gpr_esi, INVALID_NUB_REGNUM };
+uint32_t g_contained_ebp[] = { gpr_ebp, INVALID_NUB_REGNUM };
+uint32_t g_contained_esp[] = { gpr_esp, INVALID_NUB_REGNUM };
+
+uint32_t g_invalidate_eax[] = { gpr_eax , gpr_ax , gpr_ah , gpr_al, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ebx[] = { gpr_ebx , gpr_bx , gpr_bh , gpr_bl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ecx[] = { gpr_ecx , gpr_cx , gpr_ch , gpr_cl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_edx[] = { gpr_edx , gpr_dx , gpr_dh , gpr_dl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_edi[] = { gpr_edi , gpr_di , gpr_dil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_esi[] = { gpr_esi , gpr_si , gpr_sil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ebp[] = { gpr_ebp , gpr_bp , gpr_bpl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_esp[] = { gpr_esp , gpr_sp , gpr_spl , INVALID_NUB_REGNUM };
+
// General purpose registers for 64 bit
const DNBRegisterInfo
DNBArchImplI386::g_gpr_registers[] =
{
-{ e_regSetGPR, gpr_eax, "eax" , NULL , Uint, Hex, GPR_SIZE(eax), GPR_OFFSET(eax) , gcc_eax , dwarf_eax , -1U , gdb_eax },
-{ e_regSetGPR, gpr_ebx, "ebx" , NULL , Uint, Hex, GPR_SIZE(ebx), GPR_OFFSET(ebx) , gcc_ebx , dwarf_ebx , -1U , gdb_ebx },
-{ e_regSetGPR, gpr_ecx, "ecx" , NULL , Uint, Hex, GPR_SIZE(ecx), GPR_OFFSET(ecx) , gcc_ecx , dwarf_ecx , -1U , gdb_ecx },
-{ e_regSetGPR, gpr_edx, "edx" , NULL , Uint, Hex, GPR_SIZE(edx), GPR_OFFSET(edx) , gcc_edx , dwarf_edx , -1U , gdb_edx },
-{ e_regSetGPR, gpr_edi, "edi" , NULL , Uint, Hex, GPR_SIZE(edi), GPR_OFFSET(edi) , gcc_edi , dwarf_edi , -1U , gdb_edi },
-{ e_regSetGPR, gpr_esi, "esi" , NULL , Uint, Hex, GPR_SIZE(esi), GPR_OFFSET(esi) , gcc_esi , dwarf_esi , -1U , gdb_esi },
-{ e_regSetGPR, gpr_ebp, "ebp" , "fp" , Uint, Hex, GPR_SIZE(ebp), GPR_OFFSET(ebp) , gcc_ebp , dwarf_ebp , GENERIC_REGNUM_FP , gdb_ebp },
-{ e_regSetGPR, gpr_esp, "esp" , "sp" , Uint, Hex, GPR_SIZE(esp), GPR_OFFSET(esp) , gcc_esp , dwarf_esp , GENERIC_REGNUM_SP , gdb_esp },
-{ e_regSetGPR, gpr_ss, "ss" , NULL , Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss) , -1U , -1U , -1U , gdb_ss },
-{ e_regSetGPR, gpr_eflags, "eflags", "flags" , Uint, Hex, GPR_SIZE(eflags), GPR_OFFSET(eflags) , gcc_eflags, dwarf_eflags , GENERIC_REGNUM_FLAGS , gdb_eflags},
-{ e_regSetGPR, gpr_eip, "eip" , "pc" , Uint, Hex, GPR_SIZE(eip), GPR_OFFSET(eip) , gcc_eip , dwarf_eip , GENERIC_REGNUM_PC , gdb_eip },
-{ e_regSetGPR, gpr_cs, "cs" , NULL , Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs) , -1U , -1U , -1U , gdb_cs },
-{ e_regSetGPR, gpr_ds, "ds" , NULL , Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds) , -1U , -1U , -1U , gdb_ds },
-{ e_regSetGPR, gpr_es, "es" , NULL , Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es) , -1U , -1U , -1U , gdb_es },
-{ e_regSetGPR, gpr_fs, "fs" , NULL , Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs) , -1U , -1U , -1U , gdb_fs },
-{ e_regSetGPR, gpr_gs, "gs" , NULL , Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs) , -1U , -1U , -1U , gdb_gs }
+{ e_regSetGPR, gpr_eax, "eax" , NULL , Uint, Hex, GPR_SIZE(eax), GPR_OFFSET(eax) , gcc_eax , dwarf_eax , INVALID_NUB_REGNUM , gdb_eax , NULL, g_invalidate_eax },
+{ e_regSetGPR, gpr_ebx, "ebx" , NULL , Uint, Hex, GPR_SIZE(ebx), GPR_OFFSET(ebx) , gcc_ebx , dwarf_ebx , INVALID_NUB_REGNUM , gdb_ebx , NULL, g_invalidate_ebx },
+{ e_regSetGPR, gpr_ecx, "ecx" , NULL , Uint, Hex, GPR_SIZE(ecx), GPR_OFFSET(ecx) , gcc_ecx , dwarf_ecx , INVALID_NUB_REGNUM , gdb_ecx , NULL, g_invalidate_ecx },
+{ e_regSetGPR, gpr_edx, "edx" , NULL , Uint, Hex, GPR_SIZE(edx), GPR_OFFSET(edx) , gcc_edx , dwarf_edx , INVALID_NUB_REGNUM , gdb_edx , NULL, g_invalidate_edx },
+{ e_regSetGPR, gpr_edi, "edi" , NULL , Uint, Hex, GPR_SIZE(edi), GPR_OFFSET(edi) , gcc_edi , dwarf_edi , INVALID_NUB_REGNUM , gdb_edi , NULL, g_invalidate_edi },
+{ e_regSetGPR, gpr_esi, "esi" , NULL , Uint, Hex, GPR_SIZE(esi), GPR_OFFSET(esi) , gcc_esi , dwarf_esi , INVALID_NUB_REGNUM , gdb_esi , NULL, g_invalidate_esi },
+{ e_regSetGPR, gpr_ebp, "ebp" , "fp" , Uint, Hex, GPR_SIZE(ebp), GPR_OFFSET(ebp) , gcc_ebp , dwarf_ebp , GENERIC_REGNUM_FP , gdb_ebp , NULL, g_invalidate_ebp },
+{ e_regSetGPR, gpr_esp, "esp" , "sp" , Uint, Hex, GPR_SIZE(esp), GPR_OFFSET(esp) , gcc_esp , dwarf_esp , GENERIC_REGNUM_SP , gdb_esp , NULL, g_invalidate_esp },
+{ e_regSetGPR, gpr_ss, "ss" , NULL , Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_ss , NULL, NULL},
+{ e_regSetGPR, gpr_eflags, "eflags", "flags" , Uint, Hex, GPR_SIZE(eflags), GPR_OFFSET(eflags) , gcc_eflags , dwarf_eflags , GENERIC_REGNUM_FLAGS , gdb_eflags, NULL, NULL},
+{ e_regSetGPR, gpr_eip, "eip" , "pc" , Uint, Hex, GPR_SIZE(eip), GPR_OFFSET(eip) , gcc_eip , dwarf_eip , GENERIC_REGNUM_PC , gdb_eip , NULL, NULL},
+{ e_regSetGPR, gpr_cs, "cs" , NULL , Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_cs , NULL, NULL},
+{ e_regSetGPR, gpr_ds, "ds" , NULL , Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_ds , NULL, NULL},
+{ e_regSetGPR, gpr_es, "es" , NULL , Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_es , NULL, NULL},
+{ e_regSetGPR, gpr_fs, "fs" , NULL , Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_fs , NULL, NULL},
+{ e_regSetGPR, gpr_gs, "gs" , NULL , Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_gs , NULL, NULL},
+DEFINE_GPR_PSEUDO_16 (ax , eax),
+DEFINE_GPR_PSEUDO_16 (bx , ebx),
+DEFINE_GPR_PSEUDO_16 (cx , ecx),
+DEFINE_GPR_PSEUDO_16 (dx , edx),
+DEFINE_GPR_PSEUDO_16 (di , edi),
+DEFINE_GPR_PSEUDO_16 (si , esi),
+DEFINE_GPR_PSEUDO_16 (bp , ebp),
+DEFINE_GPR_PSEUDO_16 (sp , esp),
+DEFINE_GPR_PSEUDO_8H (ah , eax),
+DEFINE_GPR_PSEUDO_8H (bh , ebx),
+DEFINE_GPR_PSEUDO_8H (ch , ecx),
+DEFINE_GPR_PSEUDO_8H (dh , edx),
+DEFINE_GPR_PSEUDO_8L (al , eax),
+DEFINE_GPR_PSEUDO_8L (bl , ebx),
+DEFINE_GPR_PSEUDO_8L (cl , ecx),
+DEFINE_GPR_PSEUDO_8L (dl , edx),
+DEFINE_GPR_PSEUDO_8L (dil, edi),
+DEFINE_GPR_PSEUDO_8L (sil, esi),
+DEFINE_GPR_PSEUDO_8L (bpl, ebp),
+DEFINE_GPR_PSEUDO_8L (spl, esp)
};
const DNBRegisterInfo
DNBArchImplI386::g_fpu_registers_no_avx[] =
{
-{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
-
-{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), -1U, dwarf_stmm0, -1U, gdb_stmm0 },
-{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), -1U, dwarf_stmm1, -1U, gdb_stmm1 },
-{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), -1U, dwarf_stmm2, -1U, gdb_stmm2 },
-{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), -1U, dwarf_stmm3, -1U, gdb_stmm3 },
-{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), -1U, dwarf_stmm4, -1U, gdb_stmm4 },
-{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), -1U, dwarf_stmm5, -1U, gdb_stmm5 },
-{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), -1U, dwarf_stmm6, -1U, gdb_stmm6 },
-{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), -1U, dwarf_stmm7, -1U, gdb_stmm7 },
-
-{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), -1U, dwarf_xmm0, -1U, gdb_xmm0 },
-{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), -1U, dwarf_xmm1, -1U, gdb_xmm1 },
-{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), -1U, dwarf_xmm2, -1U, gdb_xmm2 },
-{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), -1U, dwarf_xmm3, -1U, gdb_xmm3 },
-{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), -1U, dwarf_xmm4, -1U, gdb_xmm4 },
-{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), -1U, dwarf_xmm5, -1U, gdb_xmm5 },
-{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), -1U, dwarf_xmm6, -1U, gdb_xmm6 },
-{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), -1U, dwarf_xmm7, -1U, gdb_xmm7 }
+{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+
+{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0, INVALID_NUB_REGNUM, gdb_stmm0, NULL, NULL },
+{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1, INVALID_NUB_REGNUM, gdb_stmm1, NULL, NULL },
+{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2, INVALID_NUB_REGNUM, gdb_stmm2, NULL, NULL },
+{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3, INVALID_NUB_REGNUM, gdb_stmm3, NULL, NULL },
+{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4, INVALID_NUB_REGNUM, gdb_stmm4, NULL, NULL },
+{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5, INVALID_NUB_REGNUM, gdb_stmm5, NULL, NULL },
+{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6, INVALID_NUB_REGNUM, gdb_stmm6, NULL, NULL },
+{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7, INVALID_NUB_REGNUM, gdb_stmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), INVALID_NUB_REGNUM, dwarf_xmm0, INVALID_NUB_REGNUM, gdb_xmm0, NULL, NULL },
+{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), INVALID_NUB_REGNUM, dwarf_xmm1, INVALID_NUB_REGNUM, gdb_xmm1, NULL, NULL },
+{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), INVALID_NUB_REGNUM, dwarf_xmm2, INVALID_NUB_REGNUM, gdb_xmm2, NULL, NULL },
+{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), INVALID_NUB_REGNUM, dwarf_xmm3, INVALID_NUB_REGNUM, gdb_xmm3, NULL, NULL },
+{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), INVALID_NUB_REGNUM, dwarf_xmm4, INVALID_NUB_REGNUM, gdb_xmm4, NULL, NULL },
+{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), INVALID_NUB_REGNUM, dwarf_xmm5, INVALID_NUB_REGNUM, gdb_xmm5, NULL, NULL },
+{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), INVALID_NUB_REGNUM, dwarf_xmm6, INVALID_NUB_REGNUM, gdb_xmm6, NULL, NULL },
+{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), INVALID_NUB_REGNUM, dwarf_xmm7, INVALID_NUB_REGNUM, gdb_xmm7, NULL, NULL }
};
const DNBRegisterInfo
DNBArchImplI386::g_fpu_registers_avx[] =
{
-{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
-
-{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), -1U, dwarf_stmm0, -1U, gdb_stmm0 },
-{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), -1U, dwarf_stmm1, -1U, gdb_stmm1 },
-{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), -1U, dwarf_stmm2, -1U, gdb_stmm2 },
-{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), -1U, dwarf_stmm3, -1U, gdb_stmm3 },
-{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), -1U, dwarf_stmm4, -1U, gdb_stmm4 },
-{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), -1U, dwarf_stmm5, -1U, gdb_stmm5 },
-{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), -1U, dwarf_stmm6, -1U, gdb_stmm6 },
-{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), -1U, dwarf_stmm7, -1U, gdb_stmm7 },
-
-{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), AVX_OFFSET(xmm0), -1U, dwarf_xmm0, -1U, gdb_xmm0 },
-{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), AVX_OFFSET(xmm1), -1U, dwarf_xmm1, -1U, gdb_xmm1 },
-{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), AVX_OFFSET(xmm2), -1U, dwarf_xmm2, -1U, gdb_xmm2 },
-{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), AVX_OFFSET(xmm3), -1U, dwarf_xmm3, -1U, gdb_xmm3 },
-{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), AVX_OFFSET(xmm4), -1U, dwarf_xmm4, -1U, gdb_xmm4 },
-{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), AVX_OFFSET(xmm5), -1U, dwarf_xmm5, -1U, gdb_xmm5 },
-{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), AVX_OFFSET(xmm6), -1U, dwarf_xmm6, -1U, gdb_xmm6 },
-{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), AVX_OFFSET(xmm7), -1U, dwarf_xmm7, -1U, gdb_xmm7 },
-
-{ e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), -1U, dwarf_ymm0, -1U, gdb_ymm0 },
-{ e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), -1U, dwarf_ymm1, -1U, gdb_ymm1 },
-{ e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), -1U, dwarf_ymm2, -1U, gdb_ymm2 },
-{ e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), -1U, dwarf_ymm3, -1U, gdb_ymm3 },
-{ e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), -1U, dwarf_ymm4, -1U, gdb_ymm4 },
-{ e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), -1U, dwarf_ymm5, -1U, gdb_ymm5 },
-{ e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), -1U, dwarf_ymm6, -1U, gdb_ymm6 },
-{ e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), -1U, dwarf_ymm7, -1U, gdb_ymm7 },
+{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+
+{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0, INVALID_NUB_REGNUM, gdb_stmm0, NULL, NULL },
+{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1, INVALID_NUB_REGNUM, gdb_stmm1, NULL, NULL },
+{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2, INVALID_NUB_REGNUM, gdb_stmm2, NULL, NULL },
+{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3, INVALID_NUB_REGNUM, gdb_stmm3, NULL, NULL },
+{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4, INVALID_NUB_REGNUM, gdb_stmm4, NULL, NULL },
+{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5, INVALID_NUB_REGNUM, gdb_stmm5, NULL, NULL },
+{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6, INVALID_NUB_REGNUM, gdb_stmm6, NULL, NULL },
+{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7, INVALID_NUB_REGNUM, gdb_stmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), AVX_OFFSET(xmm0), INVALID_NUB_REGNUM, dwarf_xmm0, INVALID_NUB_REGNUM, gdb_xmm0, NULL, NULL },
+{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), AVX_OFFSET(xmm1), INVALID_NUB_REGNUM, dwarf_xmm1, INVALID_NUB_REGNUM, gdb_xmm1, NULL, NULL },
+{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), AVX_OFFSET(xmm2), INVALID_NUB_REGNUM, dwarf_xmm2, INVALID_NUB_REGNUM, gdb_xmm2, NULL, NULL },
+{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), AVX_OFFSET(xmm3), INVALID_NUB_REGNUM, dwarf_xmm3, INVALID_NUB_REGNUM, gdb_xmm3, NULL, NULL },
+{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), AVX_OFFSET(xmm4), INVALID_NUB_REGNUM, dwarf_xmm4, INVALID_NUB_REGNUM, gdb_xmm4, NULL, NULL },
+{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), AVX_OFFSET(xmm5), INVALID_NUB_REGNUM, dwarf_xmm5, INVALID_NUB_REGNUM, gdb_xmm5, NULL, NULL },
+{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), AVX_OFFSET(xmm6), INVALID_NUB_REGNUM, dwarf_xmm6, INVALID_NUB_REGNUM, gdb_xmm6, NULL, NULL },
+{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), AVX_OFFSET(xmm7), INVALID_NUB_REGNUM, dwarf_xmm7, INVALID_NUB_REGNUM, gdb_xmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), INVALID_NUB_REGNUM, dwarf_ymm0, INVALID_NUB_REGNUM, gdb_ymm0, NULL, NULL },
+{ e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), INVALID_NUB_REGNUM, dwarf_ymm1, INVALID_NUB_REGNUM, gdb_ymm1, NULL, NULL },
+{ e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), INVALID_NUB_REGNUM, dwarf_ymm2, INVALID_NUB_REGNUM, gdb_ymm2, NULL, NULL },
+{ e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), INVALID_NUB_REGNUM, dwarf_ymm3, INVALID_NUB_REGNUM, gdb_ymm3, NULL, NULL },
+{ e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), INVALID_NUB_REGNUM, dwarf_ymm4, INVALID_NUB_REGNUM, gdb_ymm4, NULL, NULL },
+{ e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), INVALID_NUB_REGNUM, dwarf_ymm5, INVALID_NUB_REGNUM, gdb_ymm5, NULL, NULL },
+{ e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), INVALID_NUB_REGNUM, dwarf_ymm6, INVALID_NUB_REGNUM, gdb_ymm6, NULL, NULL },
+{ e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), INVALID_NUB_REGNUM, dwarf_ymm7, INVALID_NUB_REGNUM, gdb_ymm7, NULL, NULL }
};
const DNBRegisterInfo
DNBArchImplI386::g_exc_registers[] =
{
-{ e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U },
-{ e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U },
-{ e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U }
+{ e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
};
// Number of registers in each register set
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp Wed Apr 17 03:38:48 2013
@@ -78,7 +78,7 @@ DNBArchMachPPC::GetGPRState(bool force)
if (force || m_state.GetError(e_regSetGPR, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count));
}
return m_state.GetError(e_regSetGPR, Read);
}
@@ -89,7 +89,7 @@ DNBArchMachPPC::GetFPRState(bool force)
if (force || m_state.GetError(e_regSetFPR, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeFPR;
- m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count));
+ m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count));
}
return m_state.GetError(e_regSetFPR, Read);
}
@@ -100,7 +100,7 @@ DNBArchMachPPC::GetEXCState(bool force)
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -111,7 +111,7 @@ DNBArchMachPPC::GetVECState(bool force)
if (force || m_state.GetError(e_regSetVEC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeVEC;
- m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, &count));
+ m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, &count));
}
return m_state.GetError(e_regSetVEC, Read);
}
@@ -119,28 +119,28 @@ DNBArchMachPPC::GetVECState(bool force)
kern_return_t
DNBArchMachPPC::SetGPRState()
{
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR));
return m_state.GetError(e_regSetGPR, Write);
}
kern_return_t
DNBArchMachPPC::SetFPRState()
{
- m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR));
+ m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR));
return m_state.GetError(e_regSetFPR, Write);
}
kern_return_t
DNBArchMachPPC::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
kern_return_t
DNBArchMachPPC::SetVECState()
{
- m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC));
+ m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC));
return m_state.GetError(e_regSetVEC, Write);
}
Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Wed Apr 17 03:38:48 2013
@@ -180,7 +180,7 @@ DNBArchImplX86_64::GetGPRState(bool forc
m_state.SetError(e_regSetGPR, Read, 0);
#else
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
@@ -188,7 +188,7 @@ DNBArchImplX86_64::GetGPRState(bool forc
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->ThreadID(), x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT,
+ m_thread->MachPortNumber(), x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT,
m_state.GetError(e_regSetGPR, Read),
m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx,
m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi,
@@ -220,7 +220,7 @@ DNBArchImplX86_64::GetGPRState(bool forc
// "\n\t cs = %16.16llx"
// "\n\t fs = %16.16llx"
// "\n\t gs = %16.16llx",
- // m_thread->ThreadID(),
+ // m_thread->MachPortNumber(),
// x86_THREAD_STATE64,
// x86_THREAD_STATE64_COUNT,
// m_state.GetError(e_regSetGPR, Read),
@@ -414,17 +414,17 @@ DNBArchImplX86_64::GetFPUState(bool forc
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in) carp) => 0x%8.8x",
- m_thread->ThreadID(), __x86_64_AVX_STATE, (uint32_t)count,
+ m_thread->MachPortNumber(), __x86_64_AVX_STATE, (uint32_t)count,
e_regSetWordSizeAVX, m_state.GetError(e_regSetFPU, Read));
}
else
{
mach_msg_type_number_t count = e_regSetWordSizeFPU;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x",
- m_thread->ThreadID(), __x86_64_FLOAT_STATE, (uint32_t)count,
+ m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (uint32_t)count,
e_regSetWordSizeFPU, m_state.GetError(e_regSetFPU, Read));
}
}
@@ -438,7 +438,7 @@ DNBArchImplX86_64::GetEXCState(bool forc
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -446,10 +446,10 @@ DNBArchImplX86_64::GetEXCState(bool forc
kern_return_t
DNBArchImplX86_64::SetGPRState()
{
- kern_return_t kret = ::thread_abort_safely(m_thread->ThreadID());
- DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount());
+ kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber());
+ DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount());
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
DNBLogThreadedIf (LOG_THREAD, "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
@@ -457,7 +457,7 @@ DNBArchImplX86_64::SetGPRState()
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->ThreadID(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
+ m_thread->MachPortNumber(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
m_state.GetError(e_regSetGPR, Write),
m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx,
m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi,
@@ -481,12 +481,12 @@ DNBArchImplX86_64::SetFPUState()
{
if (CPUHasAVX() || FORCE_AVX_REGS)
{
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
return m_state.GetError(e_regSetFPU, Write);
}
else
{
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
return m_state.GetError(e_regSetFPU, Write);
}
}
@@ -495,7 +495,7 @@ DNBArchImplX86_64::SetFPUState()
kern_return_t
DNBArchImplX86_64::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
@@ -505,7 +505,7 @@ DNBArchImplX86_64::GetDBGState(bool forc
if (force || m_state.GetError(e_regSetDBG, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
+ m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
}
return m_state.GetError(e_regSetDBG, Read);
}
@@ -513,7 +513,7 @@ DNBArchImplX86_64::GetDBGState(bool forc
kern_return_t
DNBArchImplX86_64::SetDBGState()
{
- m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
+ m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
return m_state.GetError(e_regSetDBG, Write);
}
@@ -795,7 +795,7 @@ DNBArchImplX86_64::GetWatchAddress(const
bool
DNBArchImplX86_64::StartTransForHWP()
{
- if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
m_2pc_dbg_checkpoint = m_state.context.dbg;
m_2pc_trans_state = Trans_Pending;
@@ -995,6 +995,58 @@ enum
gpr_cs,
gpr_fs,
gpr_gs,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_r8d, // Low 32 bits or r8
+ gpr_r9d, // Low 32 bits or r9
+ gpr_r10d, // Low 32 bits or r10
+ gpr_r11d, // Low 32 bits or r11
+ gpr_r12d, // Low 32 bits or r12
+ gpr_r13d, // Low 32 bits or r13
+ gpr_r14d, // Low 32 bits or r14
+ gpr_r15d, // Low 32 bits or r15
+ gpr_ax ,
+ gpr_bx ,
+ gpr_cx ,
+ gpr_dx ,
+ gpr_di ,
+ gpr_si ,
+ gpr_bp ,
+ gpr_sp ,
+ gpr_r8w, // Low 16 bits or r8
+ gpr_r9w, // Low 16 bits or r9
+ gpr_r10w, // Low 16 bits or r10
+ gpr_r11w, // Low 16 bits or r11
+ gpr_r12w, // Low 16 bits or r12
+ gpr_r13w, // Low 16 bits or r13
+ gpr_r14w, // Low 16 bits or r14
+ gpr_r15w, // Low 16 bits or r15
+ gpr_ah ,
+ gpr_bh ,
+ gpr_ch ,
+ gpr_dh ,
+ gpr_al ,
+ gpr_bl ,
+ gpr_cl ,
+ gpr_dl ,
+ gpr_dil,
+ gpr_sil,
+ gpr_bpl,
+ gpr_spl,
+ gpr_r8l, // Low 8 bits or r8
+ gpr_r9l, // Low 8 bits or r9
+ gpr_r10l, // Low 8 bits or r10
+ gpr_r11l, // Low 8 bits or r11
+ gpr_r12l, // Low 8 bits or r12
+ gpr_r13l, // Low 8 bits or r13
+ gpr_r14l, // Low 8 bits or r14
+ gpr_r15l, // Low 8 bits or r15
k_num_gpr_regs
};
@@ -1230,12 +1282,53 @@ enum gdb_regnums
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg) { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, INVALID_NUB_REGNUM, gdb_##reg }
-#define DEFINE_GPR_ALT(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg }
-#define DEFINE_GPR_ALT2(reg, alt) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_##reg }
-#define DEFINE_GPR_ALT3(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, gdb_##reg }
+#define DEFINE_GPR(reg) { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, INVALID_NUB_REGNUM, gdb_##reg, NULL, g_invalidate_##reg }
+#define DEFINE_GPR_ALT(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, g_invalidate_##reg }
+#define DEFINE_GPR_ALT2(reg, alt) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_##reg, NULL, NULL }
+#define DEFINE_GPR_ALT3(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, gdb_##reg, NULL, NULL }
+#define DEFINE_GPR_ALT4(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, NULL }
+
+#define DEFINE_GPR_PSEUDO_32(reg32,reg64) { e_regSetGPR, gpr_##reg32, #reg32, NULL, Uint, Hex, 4, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_16(reg16,reg64) { e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8H(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64)+1,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8L(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
// General purpose registers for 64 bit
+
+uint32_t g_contained_rax[] = { gpr_rax, INVALID_NUB_REGNUM };
+uint32_t g_contained_rbx[] = { gpr_rbx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rcx[] = { gpr_rcx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rdx[] = { gpr_rdx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rdi[] = { gpr_rdi, INVALID_NUB_REGNUM };
+uint32_t g_contained_rsi[] = { gpr_rsi, INVALID_NUB_REGNUM };
+uint32_t g_contained_rbp[] = { gpr_rbp, INVALID_NUB_REGNUM };
+uint32_t g_contained_rsp[] = { gpr_rsp, INVALID_NUB_REGNUM };
+uint32_t g_contained_r8[] = { gpr_r8 , INVALID_NUB_REGNUM };
+uint32_t g_contained_r9[] = { gpr_r9 , INVALID_NUB_REGNUM };
+uint32_t g_contained_r10[] = { gpr_r10, INVALID_NUB_REGNUM };
+uint32_t g_contained_r11[] = { gpr_r11, INVALID_NUB_REGNUM };
+uint32_t g_contained_r12[] = { gpr_r12, INVALID_NUB_REGNUM };
+uint32_t g_contained_r13[] = { gpr_r13, INVALID_NUB_REGNUM };
+uint32_t g_contained_r14[] = { gpr_r14, INVALID_NUB_REGNUM };
+uint32_t g_contained_r15[] = { gpr_r15, INVALID_NUB_REGNUM };
+
+uint32_t g_invalidate_rax[] = { gpr_rax, gpr_eax , gpr_ax , gpr_ah , gpr_al, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rbx[] = { gpr_rbx, gpr_ebx , gpr_bx , gpr_bh , gpr_bl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rcx[] = { gpr_rcx, gpr_ecx , gpr_cx , gpr_ch , gpr_cl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rdx[] = { gpr_rdx, gpr_edx , gpr_dx , gpr_dh , gpr_dl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rdi[] = { gpr_rdi, gpr_edi , gpr_di , gpr_dil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rsi[] = { gpr_rsi, gpr_esi , gpr_si , gpr_sil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rbp[] = { gpr_rbp, gpr_ebp , gpr_bp , gpr_bpl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rsp[] = { gpr_rsp, gpr_esp , gpr_sp , gpr_spl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r8 [] = { gpr_r8 , gpr_r8d , gpr_r8w , gpr_r8l , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r9 [] = { gpr_r9 , gpr_r9d , gpr_r9w , gpr_r9l , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r10[] = { gpr_r10, gpr_r10d, gpr_r10w, gpr_r10l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r11[] = { gpr_r11, gpr_r11d, gpr_r11w, gpr_r11l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r12[] = { gpr_r12, gpr_r12d, gpr_r12w, gpr_r12l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r13[] = { gpr_r13, gpr_r13d, gpr_r13w, gpr_r13l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r14[] = { gpr_r14, gpr_r14d, gpr_r14w, gpr_r14l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r15[] = { gpr_r15, gpr_r15d, gpr_r15w, gpr_r15l, INVALID_NUB_REGNUM };
+
const DNBRegisterInfo
DNBArchImplX86_64::g_gpr_registers[] =
{
@@ -1255,111 +1348,163 @@ DNBArchImplX86_64::g_gpr_registers[] =
DEFINE_GPR (r13),
DEFINE_GPR (r14),
DEFINE_GPR (r15),
- DEFINE_GPR_ALT (rip , "pc", GENERIC_REGNUM_PC),
+ DEFINE_GPR_ALT4 (rip , "pc", GENERIC_REGNUM_PC),
DEFINE_GPR_ALT3 (rflags, "flags", GENERIC_REGNUM_FLAGS),
DEFINE_GPR_ALT2 (cs, NULL),
DEFINE_GPR_ALT2 (fs, NULL),
DEFINE_GPR_ALT2 (gs, NULL),
+ DEFINE_GPR_PSEUDO_32 (eax, rax),
+ DEFINE_GPR_PSEUDO_32 (ebx, rbx),
+ DEFINE_GPR_PSEUDO_32 (ecx, rcx),
+ DEFINE_GPR_PSEUDO_32 (edx, rdx),
+ DEFINE_GPR_PSEUDO_32 (edi, rdi),
+ DEFINE_GPR_PSEUDO_32 (esi, rsi),
+ DEFINE_GPR_PSEUDO_32 (ebp, rbp),
+ DEFINE_GPR_PSEUDO_32 (esp, rsp),
+ DEFINE_GPR_PSEUDO_32 (r8d, r8),
+ DEFINE_GPR_PSEUDO_32 (r9d, r9),
+ DEFINE_GPR_PSEUDO_32 (r10d, r10),
+ DEFINE_GPR_PSEUDO_32 (r11d, r11),
+ DEFINE_GPR_PSEUDO_32 (r12d, r12),
+ DEFINE_GPR_PSEUDO_32 (r13d, r13),
+ DEFINE_GPR_PSEUDO_32 (r14d, r14),
+ DEFINE_GPR_PSEUDO_32 (r15d, r15),
+ DEFINE_GPR_PSEUDO_16 (ax , rax),
+ DEFINE_GPR_PSEUDO_16 (bx , rbx),
+ DEFINE_GPR_PSEUDO_16 (cx , rcx),
+ DEFINE_GPR_PSEUDO_16 (dx , rdx),
+ DEFINE_GPR_PSEUDO_16 (di , rdi),
+ DEFINE_GPR_PSEUDO_16 (si , rsi),
+ DEFINE_GPR_PSEUDO_16 (bp , rbp),
+ DEFINE_GPR_PSEUDO_16 (sp , rsp),
+ DEFINE_GPR_PSEUDO_16 (r8w, r8),
+ DEFINE_GPR_PSEUDO_16 (r9w, r9),
+ DEFINE_GPR_PSEUDO_16 (r10w, r10),
+ DEFINE_GPR_PSEUDO_16 (r11w, r11),
+ DEFINE_GPR_PSEUDO_16 (r12w, r12),
+ DEFINE_GPR_PSEUDO_16 (r13w, r13),
+ DEFINE_GPR_PSEUDO_16 (r14w, r14),
+ DEFINE_GPR_PSEUDO_16 (r15w, r15),
+ DEFINE_GPR_PSEUDO_8H (ah , rax),
+ DEFINE_GPR_PSEUDO_8H (bh , rbx),
+ DEFINE_GPR_PSEUDO_8H (ch , rcx),
+ DEFINE_GPR_PSEUDO_8H (dh , rdx),
+ DEFINE_GPR_PSEUDO_8L (al , rax),
+ DEFINE_GPR_PSEUDO_8L (bl , rbx),
+ DEFINE_GPR_PSEUDO_8L (cl , rcx),
+ DEFINE_GPR_PSEUDO_8L (dl , rdx),
+ DEFINE_GPR_PSEUDO_8L (dil, rdi),
+ DEFINE_GPR_PSEUDO_8L (sil, rsi),
+ DEFINE_GPR_PSEUDO_8L (bpl, rbp),
+ DEFINE_GPR_PSEUDO_8L (spl, rsp),
+ DEFINE_GPR_PSEUDO_8L (r8l, r8),
+ DEFINE_GPR_PSEUDO_8L (r9l, r9),
+ DEFINE_GPR_PSEUDO_8L (r10l, r10),
+ DEFINE_GPR_PSEUDO_8L (r11l, r11),
+ DEFINE_GPR_PSEUDO_8L (r12l, r12),
+ DEFINE_GPR_PSEUDO_8L (r13l, r13),
+ DEFINE_GPR_PSEUDO_8L (r14l, r14),
+ DEFINE_GPR_PSEUDO_8L (r15l, r15)
};
// Floating point registers 64 bit
const DNBRegisterInfo
DNBArchImplX86_64::g_fpu_registers_no_avx[] =
{
- { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
+ { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL },
- { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0 },
- { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1 },
- { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2 },
- { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3 },
- { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4 },
- { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5 },
- { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6 },
- { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7 },
+ { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL },
+ { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL },
+ { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL },
+ { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL },
+ { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL },
+ { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL },
+ { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL },
+ { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL },
- { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , FPU_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 },
- { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , FPU_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 },
- { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , FPU_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 },
- { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , FPU_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 },
- { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , FPU_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 },
- { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , FPU_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 },
- { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , FPU_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 },
- { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , FPU_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 },
- { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , FPU_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 },
- { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , FPU_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 },
- { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , FPU_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10 },
- { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , FPU_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11 },
- { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , FPU_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12 },
- { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , FPU_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13 },
- { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , FPU_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14 },
- { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , FPU_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15 },
+ { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , FPU_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , FPU_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , FPU_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , FPU_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , FPU_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , FPU_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , FPU_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , FPU_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , FPU_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , FPU_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , FPU_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL },
+ { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , FPU_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL },
+ { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , FPU_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL },
+ { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , FPU_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL },
+ { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , FPU_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL },
+ { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , FPU_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL },
};
const DNBRegisterInfo
DNBArchImplX86_64::g_fpu_registers_avx[] =
{
- { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
+ { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL },
- { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0 },
- { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1 },
- { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2 },
- { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3 },
- { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4 },
- { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5 },
- { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6 },
- { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7 },
+ { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL },
+ { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL },
+ { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL },
+ { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL },
+ { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL },
+ { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL },
+ { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL },
+ { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL },
- { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , AVX_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 },
- { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , AVX_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 },
- { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , AVX_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 },
- { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , AVX_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 },
- { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , AVX_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 },
- { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , AVX_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 },
- { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , AVX_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 },
- { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , AVX_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 },
- { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , AVX_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 },
- { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , AVX_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 },
- { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , AVX_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10 },
- { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , AVX_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11 },
- { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , AVX_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12 },
- { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , AVX_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13 },
- { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , AVX_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14 },
- { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , AVX_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15 },
-
- { e_regSetFPU, fpu_ymm0 , "ymm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0) , AVX_OFFSET_YMM(0) , gcc_dwarf_ymm0 , gcc_dwarf_ymm0 , -1U, gdb_ymm0 },
- { e_regSetFPU, fpu_ymm1 , "ymm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1) , AVX_OFFSET_YMM(1) , gcc_dwarf_ymm1 , gcc_dwarf_ymm1 , -1U, gdb_ymm1 },
- { e_regSetFPU, fpu_ymm2 , "ymm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2) , AVX_OFFSET_YMM(2) , gcc_dwarf_ymm2 , gcc_dwarf_ymm2 , -1U, gdb_ymm2 },
- { e_regSetFPU, fpu_ymm3 , "ymm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3) , AVX_OFFSET_YMM(3) , gcc_dwarf_ymm3 , gcc_dwarf_ymm3 , -1U, gdb_ymm3 },
- { e_regSetFPU, fpu_ymm4 , "ymm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4) , AVX_OFFSET_YMM(4) , gcc_dwarf_ymm4 , gcc_dwarf_ymm4 , -1U, gdb_ymm4 },
- { e_regSetFPU, fpu_ymm5 , "ymm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5) , AVX_OFFSET_YMM(5) , gcc_dwarf_ymm5 , gcc_dwarf_ymm5 , -1U, gdb_ymm5 },
- { e_regSetFPU, fpu_ymm6 , "ymm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6) , AVX_OFFSET_YMM(6) , gcc_dwarf_ymm6 , gcc_dwarf_ymm6 , -1U, gdb_ymm6 },
- { e_regSetFPU, fpu_ymm7 , "ymm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7) , AVX_OFFSET_YMM(7) , gcc_dwarf_ymm7 , gcc_dwarf_ymm7 , -1U, gdb_ymm7 },
- { e_regSetFPU, fpu_ymm8 , "ymm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm8) , AVX_OFFSET_YMM(8) , gcc_dwarf_ymm8 , gcc_dwarf_ymm8 , -1U, gdb_ymm8 },
- { e_regSetFPU, fpu_ymm9 , "ymm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm9) , AVX_OFFSET_YMM(9) , gcc_dwarf_ymm9 , gcc_dwarf_ymm9 , -1U, gdb_ymm9 },
- { e_regSetFPU, fpu_ymm10, "ymm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm10) , AVX_OFFSET_YMM(10), gcc_dwarf_ymm10, gcc_dwarf_ymm10, -1U, gdb_ymm10 },
- { e_regSetFPU, fpu_ymm11, "ymm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm11) , AVX_OFFSET_YMM(11), gcc_dwarf_ymm11, gcc_dwarf_ymm11, -1U, gdb_ymm11 },
- { e_regSetFPU, fpu_ymm12, "ymm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm12) , AVX_OFFSET_YMM(12), gcc_dwarf_ymm12, gcc_dwarf_ymm12, -1U, gdb_ymm12 },
- { e_regSetFPU, fpu_ymm13, "ymm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm13) , AVX_OFFSET_YMM(13), gcc_dwarf_ymm13, gcc_dwarf_ymm13, -1U, gdb_ymm13 },
- { e_regSetFPU, fpu_ymm14, "ymm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm14) , AVX_OFFSET_YMM(14), gcc_dwarf_ymm14, gcc_dwarf_ymm14, -1U, gdb_ymm14 },
- { e_regSetFPU, fpu_ymm15, "ymm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm15) , AVX_OFFSET_YMM(15), gcc_dwarf_ymm15, gcc_dwarf_ymm15, -1U, gdb_ymm15 }
+ { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , AVX_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , AVX_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , AVX_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , AVX_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , AVX_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , AVX_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , AVX_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , AVX_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , AVX_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , AVX_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , AVX_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL },
+ { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , AVX_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL },
+ { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , AVX_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL },
+ { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , AVX_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL },
+ { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , AVX_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL },
+ { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , AVX_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL },
+
+ { e_regSetFPU, fpu_ymm0 , "ymm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0) , AVX_OFFSET_YMM(0) , gcc_dwarf_ymm0 , gcc_dwarf_ymm0 , -1U, gdb_ymm0, NULL, NULL },
+ { e_regSetFPU, fpu_ymm1 , "ymm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1) , AVX_OFFSET_YMM(1) , gcc_dwarf_ymm1 , gcc_dwarf_ymm1 , -1U, gdb_ymm1, NULL, NULL },
+ { e_regSetFPU, fpu_ymm2 , "ymm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2) , AVX_OFFSET_YMM(2) , gcc_dwarf_ymm2 , gcc_dwarf_ymm2 , -1U, gdb_ymm2, NULL, NULL },
+ { e_regSetFPU, fpu_ymm3 , "ymm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3) , AVX_OFFSET_YMM(3) , gcc_dwarf_ymm3 , gcc_dwarf_ymm3 , -1U, gdb_ymm3, NULL, NULL },
+ { e_regSetFPU, fpu_ymm4 , "ymm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4) , AVX_OFFSET_YMM(4) , gcc_dwarf_ymm4 , gcc_dwarf_ymm4 , -1U, gdb_ymm4, NULL, NULL },
+ { e_regSetFPU, fpu_ymm5 , "ymm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5) , AVX_OFFSET_YMM(5) , gcc_dwarf_ymm5 , gcc_dwarf_ymm5 , -1U, gdb_ymm5, NULL, NULL },
+ { e_regSetFPU, fpu_ymm6 , "ymm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6) , AVX_OFFSET_YMM(6) , gcc_dwarf_ymm6 , gcc_dwarf_ymm6 , -1U, gdb_ymm6, NULL, NULL },
+ { e_regSetFPU, fpu_ymm7 , "ymm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7) , AVX_OFFSET_YMM(7) , gcc_dwarf_ymm7 , gcc_dwarf_ymm7 , -1U, gdb_ymm7, NULL, NULL },
+ { e_regSetFPU, fpu_ymm8 , "ymm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm8) , AVX_OFFSET_YMM(8) , gcc_dwarf_ymm8 , gcc_dwarf_ymm8 , -1U, gdb_ymm8 , NULL, NULL },
+ { e_regSetFPU, fpu_ymm9 , "ymm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm9) , AVX_OFFSET_YMM(9) , gcc_dwarf_ymm9 , gcc_dwarf_ymm9 , -1U, gdb_ymm9 , NULL, NULL },
+ { e_regSetFPU, fpu_ymm10, "ymm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm10) , AVX_OFFSET_YMM(10), gcc_dwarf_ymm10, gcc_dwarf_ymm10, -1U, gdb_ymm10, NULL, NULL },
+ { e_regSetFPU, fpu_ymm11, "ymm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm11) , AVX_OFFSET_YMM(11), gcc_dwarf_ymm11, gcc_dwarf_ymm11, -1U, gdb_ymm11, NULL, NULL },
+ { e_regSetFPU, fpu_ymm12, "ymm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm12) , AVX_OFFSET_YMM(12), gcc_dwarf_ymm12, gcc_dwarf_ymm12, -1U, gdb_ymm12, NULL, NULL },
+ { e_regSetFPU, fpu_ymm13, "ymm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm13) , AVX_OFFSET_YMM(13), gcc_dwarf_ymm13, gcc_dwarf_ymm13, -1U, gdb_ymm13, NULL, NULL },
+ { e_regSetFPU, fpu_ymm14, "ymm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm14) , AVX_OFFSET_YMM(14), gcc_dwarf_ymm14, gcc_dwarf_ymm14, -1U, gdb_ymm14, NULL, NULL },
+ { e_regSetFPU, fpu_ymm15, "ymm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm15) , AVX_OFFSET_YMM(15), gcc_dwarf_ymm15, gcc_dwarf_ymm15, -1U, gdb_ymm15, NULL, NULL }
};
// Exception registers
@@ -1367,9 +1512,9 @@ DNBArchImplX86_64::g_fpu_registers_avx[]
const DNBRegisterInfo
DNBArchImplX86_64::g_exc_registers[] =
{
- { e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U },
- { e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U },
- { e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U }
+ { e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U, NULL, NULL }
};
// Number of registers in each register set
Removed: lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.cpp?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.cpp (removed)
@@ -1,393 +0,0 @@
-//===-- ProfileObjectiveC.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 10/4/07.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProfileObjectiveC.h"
-#include "DNB.h"
-#include <objc/objc-runtime.h>
-#include <map>
-
-#if defined (__powerpc__) || defined (__ppc__)
-#define OBJC_MSG_SEND_PPC32_COMM_PAGE_ADDR ((nub_addr_t)0xfffeff00)
-#endif
-
-//----------------------------------------------------------------------
-// Constructor
-//----------------------------------------------------------------------
-ProfileObjectiveC::ProfileObjectiveC() :
- m_pid(INVALID_NUB_PROCESS),
- m_objcStats(),
- m_hit_count(0),
- m_dump_count(0xffff)
-{
- memset(&m_begin_time, 0, sizeof(m_begin_time));
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ProfileObjectiveC::~ProfileObjectiveC()
-{
-}
-
-//----------------------------------------------------------------------
-// Clear any counts that we may have had
-//----------------------------------------------------------------------
-void
-ProfileObjectiveC::Clear()
-{
- if (m_pid != INVALID_NUB_PROCESS)
- {
- DNBBreakpointClear(m_pid, m_objc_msgSend.breakID);
- DNBBreakpointClear(m_pid, m_objc_msgSendSuper.breakID);
-#if defined (__powerpc__) || defined (__ppc__)
- DNBBreakpointClear(m_pid, m_objc_msgSend_rtp.breakID);
-#endif
- }
- m_objc_msgSend.Clear();
- m_objc_msgSendSuper.Clear();
-#if defined (__powerpc__) || defined (__ppc__)
- memset(m_objc_msgSend_opcode, 0, k_opcode_size);
- m_objc_msgSend_rtp.Clear();
-#endif
- memset(&m_begin_time, 0, sizeof(m_begin_time));
- m_objcStats.clear();
-}
-
-void
-ProfileObjectiveC::Initialize(nub_process_t pid)
-{
- Clear();
- m_pid = pid;
-}
-
-
-void
-ProfileObjectiveC::ProcessStateChanged(nub_state_t state)
-{
- //printf("ProfileObjectiveC::%s(%s)\n", __FUNCTION__, DNBStateAsString(state));
- switch (state)
- {
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear();
- break;
-
- case eStateStopped:
-#if defined (__powerpc__) || defined (__ppc__)
- if (NUB_BREAK_ID_IS_VALID(m_objc_msgSend.breakID) && !NUB_BREAK_ID_IS_VALID(m_objc_msgSend_rtp.breakID))
- {
- nub_thread_t tid = DNBProcessGetCurrentThread(m_pid);
- DNBRegisterValue pc_value;
- if (DNBThreadGetRegisterValueByName(m_pid, tid, REGISTER_SET_ALL, "srr0" , &pc_value))
- {
- nub_addr_t pc = pc_value.value.uint32;
- if (pc == OBJC_MSG_SEND_PPC32_COMM_PAGE_ADDR)
- {
- // Restore previous first instruction to 0xfffeff00 in comm page
- DNBProcessMemoryWrite(m_pid, OBJC_MSG_SEND_PPC32_COMM_PAGE_ADDR, k_opcode_size, m_objc_msgSend_opcode);
- //printf("Setting breakpoint on _objc_msgSend_rtp...\n");
- m_objc_msgSend_rtp.breakID = DNBBreakpointSet(m_pid, OBJC_MSG_SEND_PPC32_COMM_PAGE_ADDR);
- if (NUB_BREAK_ID_IS_VALID(m_objc_msgSend_rtp.breakID))
- {
- DNBBreakpointSetCallback(m_pid, m_objc_msgSend_rtp.breakID, ProfileObjectiveC::MessageSendBreakpointCallback, this);
- }
- }
- }
- }
-#endif
- DumpStats(m_pid, stdout);
- break;
-
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
-
- default:
- break;
- }
-}
-
-void
-ProfileObjectiveC::SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos, nub_size_t num_image_infos)
-{
- //printf("ProfileObjectiveC::%s(%p, %u)\n", __FUNCTION__, image_infos, num_image_infos);
- if (m_objc_msgSend.IsValid() && m_objc_msgSendSuper.IsValid())
- return;
-
- if (image_infos)
- {
- nub_process_t pid = m_pid;
- nub_size_t i;
- for (i = 0; i < num_image_infos; i++)
- {
- if (strcmp(image_infos[i].name, "/usr/lib/libobjc.A.dylib") == 0)
- {
- if (!NUB_BREAK_ID_IS_VALID(m_objc_msgSend.breakID))
- {
- m_objc_msgSend.addr = DNBProcessLookupAddress(pid, "_objc_msgSend", image_infos[i].name);
-
- if (m_objc_msgSend.addr != INVALID_NUB_ADDRESS)
- {
-#if defined (__powerpc__) || defined (__ppc__)
- if (DNBProcessMemoryRead(pid, m_objc_msgSend.addr, k_opcode_size, m_objc_msgSend_opcode) != k_opcode_size)
- memset(m_objc_msgSend_opcode, 0, sizeof(m_objc_msgSend_opcode));
-#endif
- m_objc_msgSend.breakID = DNBBreakpointSet(pid, m_objc_msgSend.addr, 4, false);
- if (NUB_BREAK_ID_IS_VALID(m_objc_msgSend.breakID))
- DNBBreakpointSetCallback(pid, m_objc_msgSend.breakID, ProfileObjectiveC::MessageSendBreakpointCallback, this);
- }
- }
-
- if (!NUB_BREAK_ID_IS_VALID(m_objc_msgSendSuper.breakID))
- {
- m_objc_msgSendSuper.addr = DNBProcessLookupAddress(pid, "_objc_msgSendSuper", image_infos[i].name);
-
- if (m_objc_msgSendSuper.addr != INVALID_NUB_ADDRESS)
- {
- m_objc_msgSendSuper.breakID = DNBBreakpointSet(pid, m_objc_msgSendSuper.addr, 4, false);
- if (NUB_BREAK_ID_IS_VALID(m_objc_msgSendSuper.breakID))
- DNBBreakpointSetCallback(pid, m_objc_msgSendSuper.breakID, ProfileObjectiveC::MessageSendSuperBreakpointCallback, this);
- }
- }
- break;
- }
- }
- }
-}
-
-
-void
-ProfileObjectiveC::SetStartTime()
-{
- gettimeofday(&m_begin_time, NULL);
-}
-
-void
-ProfileObjectiveC::SelectorHit(objc_class_ptr_t isa, objc_selector_t sel)
-{
- m_objcStats[isa][sel]++;
-}
-
-nub_bool_t
-ProfileObjectiveC::MessageSendBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData)
-{
- ProfileObjectiveC *profile_objc = (ProfileObjectiveC*)userData;
- uint32_t hit_count = profile_objc->IncrementHitCount();
- if (hit_count == 1)
- profile_objc->SetStartTime();
-
- objc_class_ptr_t objc_self = 0;
- objc_selector_t objc_selector = 0;
-#if defined (__i386__)
- DNBRegisterValue esp;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "esp", &esp))
- {
- uint32_t uval32[2];
- if (DNBProcessMemoryRead(pid, esp.value.uint32 + 4, 8, &uval32) == 8)
- {
- objc_self = uval32[0];
- objc_selector = uval32[1];
- }
- }
-#elif defined (__powerpc__) || defined (__ppc__)
- DNBRegisterValue r3;
- DNBRegisterValue r4;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r3", &r3) &&
- DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r4", &r4))
- {
- objc_self = r3.value.uint32;
- objc_selector = r4.value.uint32;
- }
-#elif defined (__arm__)
- DNBRegisterValue r0;
- DNBRegisterValue r1;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r0", &r0) &&
- DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r1", &r1))
- {
- objc_self = r0.value.uint32;
- objc_selector = r1.value.uint32;
- }
-#else
-#error undefined architecture
-#endif
- if (objc_selector != 0)
- {
- uint32_t isa = 0;
- if (objc_self == 0)
- {
- profile_objc->SelectorHit(0, objc_selector);
- }
- else
- if (DNBProcessMemoryRead(pid, (nub_addr_t)objc_self, sizeof(isa), &isa) == sizeof(isa))
- {
- if (isa)
- {
- profile_objc->SelectorHit(isa, objc_selector);
- }
- else
- {
- profile_objc->SelectorHit(0, objc_selector);
- }
- }
- }
-
-
- // Dump stats if we are supposed to
- if (profile_objc->ShouldDumpStats())
- {
- profile_objc->DumpStats(pid, stdout);
- return true;
- }
-
- // Just let the target run again by returning false;
- return false;
-}
-
-nub_bool_t
-ProfileObjectiveC::MessageSendSuperBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData)
-{
- ProfileObjectiveC *profile_objc = (ProfileObjectiveC*)userData;
-
- uint32_t hit_count = profile_objc->IncrementHitCount();
- if (hit_count == 1)
- profile_objc->SetStartTime();
-
-// printf("BreakID %u hit count is = %u\n", breakID, hc);
- objc_class_ptr_t objc_super = 0;
- objc_selector_t objc_selector = 0;
-#if defined (__i386__)
- DNBRegisterValue esp;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "esp", &esp))
- {
- uint32_t uval32[2];
- if (DNBProcessMemoryRead(pid, esp.value.uint32 + 4, 8, &uval32) == 8)
- {
- objc_super = uval32[0];
- objc_selector = uval32[1];
- }
- }
-#elif defined (__powerpc__) || defined (__ppc__)
- DNBRegisterValue r3;
- DNBRegisterValue r4;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r3", &r3) &&
- DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r4", &r4))
- {
- objc_super = r3.value.uint32;
- objc_selector = r4.value.uint32;
- }
-#elif defined (__arm__)
- DNBRegisterValue r0;
- DNBRegisterValue r1;
- if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r0", &r0) &&
- DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, "r1", &r1))
- {
- objc_super = r0.value.uint32;
- objc_selector = r1.value.uint32;
- }
-#else
-#error undefined architecture
-#endif
- if (objc_selector != 0)
- {
- uint32_t isa = 0;
- if (objc_super == 0)
- {
- profile_objc->SelectorHit(0, objc_selector);
- }
- else
- if (DNBProcessMemoryRead(pid, (nub_addr_t)objc_super + 4, sizeof(isa), &isa) == sizeof(isa))
- {
- if (isa)
- {
- profile_objc->SelectorHit(isa, objc_selector);
- }
- else
- {
- profile_objc->SelectorHit(0, objc_selector);
- }
- }
- }
-
- // Dump stats if we are supposed to
- if (profile_objc->ShouldDumpStats())
- {
- profile_objc->DumpStats(pid, stdout);
- return true;
- }
-
- // Just let the target run again by returning false;
- return false;
-}
-
-void
-ProfileObjectiveC::DumpStats(nub_process_t pid, FILE *f)
-{
- if (f == NULL)
- return;
-
- if (m_hit_count == 0)
- return;
-
- ClassStatsMap::iterator class_pos;
- ClassStatsMap::iterator class_end = m_objcStats.end();
-
- struct timeval end_time;
- gettimeofday(&end_time, NULL);
- int64_t elapsed_usec = ((int64_t)(1000*1000))*((int64_t)end_time.tv_sec - (int64_t)m_begin_time.tv_sec) + ((int64_t)end_time.tv_usec - (int64_t)m_begin_time.tv_usec);
- fprintf(f, "%u probe hits for %.2f hits/sec)\n", m_hit_count, (double)m_hit_count / (((double)elapsed_usec)/(1000000.0)));
-
- for (class_pos = m_objcStats.begin(); class_pos != class_end; ++class_pos)
- {
- SelectorHitCount::iterator sel_pos;
- SelectorHitCount::iterator sel_end = class_pos->second.end();
- for (sel_pos = class_pos->second.begin(); sel_pos != sel_end; ++sel_pos)
- {
- struct objc_class objc_class;
- uint32_t isa = class_pos->first;
- uint32_t sel = sel_pos->first;
- uint32_t sel_hit_count = sel_pos->second;
-
- if (isa != 0 && DNBProcessMemoryRead(pid, isa, sizeof(objc_class), &objc_class) == sizeof(objc_class))
- {
- /* fprintf(f, "%#.8x\n isa = %p\n super_class = %p\n name = %p\n version = %lx\n info = %lx\ninstance_size = %lx\n ivars = %p\n methodLists = %p\n cache = %p\n protocols = %p\n",
- arg1.value.pointer,
- objc_class.isa,
- objc_class.super_class,
- objc_class.name,
- objc_class.version,
- objc_class.info,
- objc_class.instance_size,
- objc_class.ivars,
- objc_class.methodLists,
- objc_class.cache,
- objc_class.protocols); */
-
- // Print the class name
- fprintf(f, "%6u hits for %c[", sel_hit_count, (objc_class.super_class == objc_class.isa ? '+' : '-'));
- DNBPrintf(pid, INVALID_NUB_THREAD, (nub_addr_t)objc_class.name, f, "%s ");
- }
- else
- {
- fprintf(f, "%6u hits for [<nil> ", sel_hit_count);
- }
- DNBPrintf(pid, INVALID_NUB_THREAD, sel, f, "%s]\n");
- }
- }
-}
-
Removed: lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.h?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.h (original)
+++ lldb/branches/windows/tools/debugserver/source/ProfileObjectiveC.h (removed)
@@ -1,82 +0,0 @@
-//===-- ProfileObjectiveC.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Created by Greg Clayton on 10/4/07.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __ProfileObjectiveC_h__
-#define __ProfileObjectiveC_h__
-
-#include "DNB.h"
-#include "DNBRuntimeAction.h"
-#include <map>
-#include <sys/time.h>
-
-class ProfileObjectiveC : public DNBRuntimeAction
-{
-public:
- ProfileObjectiveC();
- virtual ~ProfileObjectiveC();
- //------------------------------------------------------------------
- // DNBRuntimeAction required functions
- //------------------------------------------------------------------
- virtual void Initialize(nub_process_t pid);
- virtual void ProcessStateChanged(nub_state_t state);
- virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos, nub_size_t num_image_infos);
-
-protected:
- typedef uint32_t objc_selector_t;
- typedef uint32_t objc_class_ptr_t;
- void Clear();
- static nub_bool_t MessageSendBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData);
- static nub_bool_t MessageSendSuperBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData);
- void DumpStats(nub_process_t pid, FILE *f);
- void SetStartTime();
- void SelectorHit(objc_class_ptr_t isa, objc_selector_t sel);
- typedef std::map<objc_selector_t, uint32_t> SelectorHitCount;
- typedef std::map<objc_class_ptr_t, SelectorHitCount> ClassStatsMap;
- typedef struct Probe
- {
- nub_addr_t addr;
- nub_break_t breakID;
- Probe() : addr(INVALID_NUB_ADDRESS), breakID(INVALID_NUB_BREAK_ID) {}
- void Clear()
- {
- addr = INVALID_NUB_ADDRESS;
- breakID = INVALID_NUB_BREAK_ID;
- }
- bool IsValid() const
- {
- return (addr != INVALID_NUB_ADDRESS) && (NUB_BREAK_ID_IS_VALID(breakID));
- }
- };
-
- uint32_t IncrementHitCount() { return ++m_hit_count; }
- bool ShouldDumpStats() const { return m_dump_count && (m_hit_count % m_dump_count) == 0; }
-
- nub_process_t m_pid;
- Probe m_objc_msgSend;
- Probe m_objc_msgSendSuper;
- uint32_t m_hit_count; // Number of times we have gotten one of our breakpoints hit
- uint32_t m_dump_count; // Dump stats every time the hit count reaches a multiple of this value
-#if defined (__powerpc__) || defined (__ppc__)
- enum
- {
- k_opcode_size = 4
- };
- uint8_t m_objc_msgSend_opcode[k_opcode_size]; // Saved copy of first opcode in objc_msgSend
- Probe m_objc_msgSend_rtp; // COMM page probe info for objc_msgSend
-#endif
- struct timeval m_begin_time;
- ClassStatsMap m_objcStats;
-};
-
-
-#endif // #ifndef __ProfileObjectiveC_h__
Modified: lldb/branches/windows/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/RNBRemote.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/RNBRemote.cpp Wed Apr 17 03:38:48 2013
@@ -30,7 +30,6 @@
#include <iomanip>
#include <sstream>
-
#include <TargetConditionals.h> // for endianness predefines
//----------------------------------------------------------------------
@@ -155,9 +154,9 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z3", "Remove read watchpoint"));
t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z4", "Insert access watchpoint"));
t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z4", "Remove access watchpoint"));
+ t.push_back (Packet (query_monitor, &RNBRemote::HandlePacket_qRcmd, NULL, "qRcmd", "Monitor command"));
t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID"));
t.push_back (Packet (query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id"));
-// t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region"));
t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)"));
t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)"));
// APPLE LOCAL: qThreadStopInfo
@@ -195,7 +194,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
t.push_back (Packet (memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address"));
t.push_back (Packet (get_profile_data, &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target."));
- t.push_back (Packet (set_enable_profiling, &RNBRemote::HandlePacket_SetAsyncEnableProfiling, NULL, "QSetAsyncEnableProfiling", "Enable or disable the profiling of current target."));
+ t.push_back (Packet (set_enable_profiling, &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target."));
t.push_back (Packet (watchpoint_support_info, &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints"));
}
@@ -879,65 +878,88 @@ g_gdb_register_map_arm[] =
{ 13, 4, "sp", {0}, NULL, 1},
{ 14, 4, "lr", {0}, NULL, 1},
{ 15, 4, "pc", {0}, NULL, 1},
- { 16, 12, "f0", {0}, k_zero_bytes, 0},
- { 17, 12, "f1", {0}, k_zero_bytes, 0},
- { 18, 12, "f2", {0}, k_zero_bytes, 0},
- { 19, 12, "f3", {0}, k_zero_bytes, 0},
- { 20, 12, "f4", {0}, k_zero_bytes, 0},
- { 21, 12, "f5", {0}, k_zero_bytes, 0},
- { 22, 12, "f6", {0}, k_zero_bytes, 0},
- { 23, 12, "f7", {0}, k_zero_bytes, 0},
- { 24, 4, "fps", {0}, k_zero_bytes, 0},
- { 25, 4,"cpsr", {0}, NULL, 1},
- { 26, 4, "s0", {0}, NULL, 0},
- { 27, 4, "s1", {0}, NULL, 0},
- { 28, 4, "s2", {0}, NULL, 0},
- { 29, 4, "s3", {0}, NULL, 0},
- { 30, 4, "s4", {0}, NULL, 0},
- { 31, 4, "s5", {0}, NULL, 0},
- { 32, 4, "s6", {0}, NULL, 0},
- { 33, 4, "s7", {0}, NULL, 0},
- { 34, 4, "s8", {0}, NULL, 0},
- { 35, 4, "s9", {0}, NULL, 0},
- { 36, 4, "s10", {0}, NULL, 0},
- { 37, 4, "s11", {0}, NULL, 0},
- { 38, 4, "s12", {0}, NULL, 0},
- { 39, 4, "s13", {0}, NULL, 0},
- { 40, 4, "s14", {0}, NULL, 0},
- { 41, 4, "s15", {0}, NULL, 0},
- { 42, 4, "s16", {0}, NULL, 0},
- { 43, 4, "s17", {0}, NULL, 0},
- { 44, 4, "s18", {0}, NULL, 0},
- { 45, 4, "s19", {0}, NULL, 0},
- { 46, 4, "s20", {0}, NULL, 0},
- { 47, 4, "s21", {0}, NULL, 0},
- { 48, 4, "s22", {0}, NULL, 0},
- { 49, 4, "s23", {0}, NULL, 0},
- { 50, 4, "s24", {0}, NULL, 0},
- { 51, 4, "s25", {0}, NULL, 0},
- { 52, 4, "s26", {0}, NULL, 0},
- { 53, 4, "s27", {0}, NULL, 0},
- { 54, 4, "s28", {0}, NULL, 0},
- { 55, 4, "s29", {0}, NULL, 0},
- { 56, 4, "s30", {0}, NULL, 0},
- { 57, 4, "s31", {0}, NULL, 0},
- { 58, 4, "fpscr", {0}, NULL, 0},
- { 59, 8, "d16", {0}, NULL, 0},
- { 60, 8, "d17", {0}, NULL, 0},
- { 61, 8, "d18", {0}, NULL, 0},
- { 62, 8, "d19", {0}, NULL, 0},
- { 63, 8, "d20", {0}, NULL, 0},
- { 64, 8, "d21", {0}, NULL, 0},
- { 65, 8, "d22", {0}, NULL, 0},
- { 66, 8, "d23", {0}, NULL, 0},
- { 67, 8, "d24", {0}, NULL, 0},
- { 68, 8, "d25", {0}, NULL, 0},
- { 69, 8, "d26", {0}, NULL, 0},
- { 70, 8, "d27", {0}, NULL, 0},
- { 71, 8, "d28", {0}, NULL, 0},
- { 72, 8, "d29", {0}, NULL, 0},
- { 73, 8, "d30", {0}, NULL, 0},
- { 74, 8, "d31", {0}, NULL, 0}
+ { 16, 4,"cpsr", {0}, NULL, 1}, // current program status register
+ { 17, 4, "s0", {0}, NULL, 0},
+ { 18, 4, "s1", {0}, NULL, 0},
+ { 19, 4, "s2", {0}, NULL, 0},
+ { 20, 4, "s3", {0}, NULL, 0},
+ { 21, 4, "s4", {0}, NULL, 0},
+ { 22, 4, "s5", {0}, NULL, 0},
+ { 23, 4, "s6", {0}, NULL, 0},
+ { 24, 4, "s7", {0}, NULL, 0},
+ { 25, 4, "s8", {0}, NULL, 0},
+ { 26, 4, "s9", {0}, NULL, 0},
+ { 27, 4, "s10", {0}, NULL, 0},
+ { 28, 4, "s11", {0}, NULL, 0},
+ { 29, 4, "s12", {0}, NULL, 0},
+ { 30, 4, "s13", {0}, NULL, 0},
+ { 31, 4, "s14", {0}, NULL, 0},
+ { 32, 4, "s15", {0}, NULL, 0},
+ { 33, 4, "s16", {0}, NULL, 0},
+ { 34, 4, "s17", {0}, NULL, 0},
+ { 35, 4, "s18", {0}, NULL, 0},
+ { 36, 4, "s19", {0}, NULL, 0},
+ { 37, 4, "s20", {0}, NULL, 0},
+ { 38, 4, "s21", {0}, NULL, 0},
+ { 39, 4, "s22", {0}, NULL, 0},
+ { 40, 4, "s23", {0}, NULL, 0},
+ { 41, 4, "s24", {0}, NULL, 0},
+ { 42, 4, "s25", {0}, NULL, 0},
+ { 43, 4, "s26", {0}, NULL, 0},
+ { 44, 4, "s27", {0}, NULL, 0},
+ { 45, 4, "s28", {0}, NULL, 0},
+ { 46, 4, "s29", {0}, NULL, 0},
+ { 47, 4, "s30", {0}, NULL, 0},
+ { 48, 4, "s31", {0}, NULL, 0},
+ { 49, 8, "d0", {0}, NULL, 0},
+ { 50, 8, "d1", {0}, NULL, 0},
+ { 51, 8, "d2", {0}, NULL, 0},
+ { 52, 8, "d3", {0}, NULL, 0},
+ { 53, 8, "d4", {0}, NULL, 0},
+ { 54, 8, "d5", {0}, NULL, 0},
+ { 55, 8, "d6", {0}, NULL, 0},
+ { 56, 8, "d7", {0}, NULL, 0},
+ { 57, 8, "d8", {0}, NULL, 0},
+ { 58, 8, "d9", {0}, NULL, 0},
+ { 59, 8, "d10", {0}, NULL, 0},
+ { 60, 8, "d11", {0}, NULL, 0},
+ { 61, 8, "d12", {0}, NULL, 0},
+ { 62, 8, "d13", {0}, NULL, 0},
+ { 63, 8, "d14", {0}, NULL, 0},
+ { 64, 8, "d15", {0}, NULL, 0},
+ { 65, 8, "d16", {0}, NULL, 0},
+ { 66, 8, "d17", {0}, NULL, 0},
+ { 67, 8, "d18", {0}, NULL, 0},
+ { 68, 8, "d19", {0}, NULL, 0},
+ { 69, 8, "d20", {0}, NULL, 0},
+ { 70, 8, "d21", {0}, NULL, 0},
+ { 71, 8, "d22", {0}, NULL, 0},
+ { 72, 8, "d23", {0}, NULL, 0},
+ { 73, 8, "d24", {0}, NULL, 0},
+ { 74, 8, "d25", {0}, NULL, 0},
+ { 75, 8, "d26", {0}, NULL, 0},
+ { 76, 8, "d27", {0}, NULL, 0},
+ { 77, 8, "d28", {0}, NULL, 0},
+ { 78, 8, "d29", {0}, NULL, 0},
+ { 79, 8, "d30", {0}, NULL, 0},
+ { 80, 8, "d31", {0}, NULL, 0},
+ { 81, 16, "q0", {0}, NULL, 0},
+ { 82, 16, "q1", {0}, NULL, 0},
+ { 83, 16, "q2", {0}, NULL, 0},
+ { 84, 16, "q3", {0}, NULL, 0},
+ { 85, 16, "q4", {0}, NULL, 0},
+ { 86, 16, "q5", {0}, NULL, 0},
+ { 87, 16, "q6", {0}, NULL, 0},
+ { 88, 16, "q7", {0}, NULL, 0},
+ { 89, 16, "q8", {0}, NULL, 0},
+ { 90, 16, "q9", {0}, NULL, 0},
+ { 91, 16, "q10", {0}, NULL, 0},
+ { 92, 16, "q11", {0}, NULL, 0},
+ { 93, 16, "q12", {0}, NULL, 0},
+ { 94, 16, "q13", {0}, NULL, 0},
+ { 95, 16, "q14", {0}, NULL, 0},
+ { 96, 16, "q15", {0}, NULL, 0},
+ { 97, 4, "fpscr", {0}, NULL, 0}
};
register_map_entry_t
@@ -1435,6 +1457,135 @@ RNBRemote::HandlePacket_qThreadExtraInfo
return SendPacket ("");
}
+
+const char *k_space_delimiters = " \t";
+static void
+skip_spaces (std::string &line)
+{
+ if (!line.empty())
+ {
+ size_t space_pos = line.find_first_not_of (k_space_delimiters);
+ if (space_pos > 0)
+ line.erase(0, space_pos);
+ }
+}
+
+static std::string
+get_identifier (std::string &line)
+{
+ std::string word;
+ skip_spaces (line);
+ const size_t line_size = line.size();
+ size_t end_pos;
+ for (end_pos = 0; end_pos < line_size; ++end_pos)
+ {
+ if (end_pos == 0)
+ {
+ if (isalpha(line[end_pos]) || line[end_pos] == '_')
+ continue;
+ }
+ else if (isalnum(line[end_pos]) || line[end_pos] == '_')
+ continue;
+ break;
+ }
+ word.assign (line, 0, end_pos);
+ line.erase(0, end_pos);
+ return word;
+}
+
+static std::string
+get_operator (std::string &line)
+{
+ std::string op;
+ skip_spaces (line);
+ if (!line.empty())
+ {
+ if (line[0] == '=')
+ {
+ op = '=';
+ line.erase(0,1);
+ }
+ }
+ return op;
+}
+
+static std::string
+get_value (std::string &line)
+{
+ std::string value;
+ skip_spaces (line);
+ if (!line.empty())
+ {
+ value.swap(line);
+ }
+ return value;
+}
+
+
+extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
+extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
+
+rnb_err_t
+RNBRemote::HandlePacket_qRcmd (const char *p)
+{
+ const char *c = p + strlen("qRcmd,");
+ std::string line;
+ while (c[0] && c[1])
+ {
+ char smallbuf[3] = { c[0], c[1], '\0' };
+ errno = 0;
+ int ch = strtoul (smallbuf, NULL, 16);
+ if (errno != 0 && ch == 0)
+ return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet");
+ line.push_back(ch);
+ c += 2;
+ }
+ if (*c == '\0')
+ {
+ std::string command = get_identifier(line);
+ if (command.compare("set") == 0)
+ {
+ std::string variable = get_identifier (line);
+ std::string op = get_operator (line);
+ std::string value = get_value (line);
+ if (variable.compare("logfile") == 0)
+ {
+ FILE *log_file = fopen(value.c_str(), "w");
+ if (log_file)
+ {
+ DNBLogSetLogCallback(FileLogCallback, log_file);
+ return SendPacket ("OK");
+ }
+ return SendPacket ("E71");
+ }
+ else if (variable.compare("logmask") == 0)
+ {
+ char *end;
+ errno = 0;
+ uint32_t logmask = strtoul (value.c_str(), &end, 0);
+ if (errno == 0 && end && *end == '\0')
+ {
+ DNBLogSetLogMask (logmask);
+ if (!DNBLogGetLogCallback())
+ DNBLogSetLogCallback(ASLLogCallback, NULL);
+ return SendPacket ("OK");
+ }
+ errno = 0;
+ logmask = strtoul (value.c_str(), &end, 16);
+ if (errno == 0 && end && *end == '\0')
+ {
+ DNBLogSetLogMask (logmask);
+ return SendPacket ("OK");
+ }
+ return SendPacket ("E72");
+ }
+ return SendPacket ("E70");
+ }
+ return SendPacket ("E69");
+ }
+ return SendPacket ("E73");
+}
+
rnb_err_t
RNBRemote::HandlePacket_qC (const char *p)
{
@@ -1552,6 +1703,30 @@ RNBRemote::HandlePacket_qRegisterInfo (c
case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break;
default: break;
}
+
+ if (reg_entry->nub_info.pseudo_regs && reg_entry->nub_info.pseudo_regs[0] != INVALID_NUB_REGNUM)
+ {
+ ostrm << "container-regs:";
+ for (unsigned i=0; reg_entry->nub_info.pseudo_regs[i] != INVALID_NUB_REGNUM; ++i)
+ {
+ if (i > 0)
+ ostrm << ',';
+ ostrm << RAW_HEXBASE << reg_entry->nub_info.pseudo_regs[i];
+ }
+ ostrm << ';';
+ }
+
+ if (reg_entry->nub_info.update_regs && reg_entry->nub_info.update_regs[0] != INVALID_NUB_REGNUM)
+ {
+ ostrm << "invalidate-regs:";
+ for (unsigned i=0; reg_entry->nub_info.update_regs[i] != INVALID_NUB_REGNUM; ++i)
+ {
+ if (i > 0)
+ ostrm << ',';
+ ostrm << RAW_HEXBASE << reg_entry->nub_info.update_regs[i];
+ }
+ ostrm << ';';
+ }
return SendPacket (ostrm.str ());
}
@@ -1582,6 +1757,16 @@ set_logging (const char *p)
{
if (*p == '|')
p++;
+
+// to regenerate the LOG_ entries (not including the LOG_RNB entries)
+// $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'`
+// do
+// echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)"
+// echo " {"
+// echo " p += sizeof (\"$logname\") - 1;"
+// echo " bitmask |= $logname;"
+// echo " }"
+// done
if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
{
p += sizeof ("LOG_VERBOSE") - 1;
@@ -1622,26 +1807,48 @@ set_logging (const char *p)
p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
bitmask |= LOG_MEMORY_DATA_LONG;
}
+ else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0)
+ {
+ p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1;
+ bitmask |= LOG_MEMORY_PROTECTIONS;
+ }
else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
{
p += sizeof ("LOG_BREAKPOINTS") - 1;
bitmask |= LOG_BREAKPOINTS;
}
- else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
- {
- p += sizeof ("LOG_ALL") - 1;
- bitmask |= LOG_ALL;
- }
else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
{
p += sizeof ("LOG_EVENTS") - 1;
bitmask |= LOG_EVENTS;
}
+ else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
+ {
+ p += sizeof ("LOG_WATCHPOINTS") - 1;
+ bitmask |= LOG_WATCHPOINTS;
+ }
+ else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0)
+ {
+ p += sizeof ("LOG_STEP") - 1;
+ bitmask |= LOG_STEP;
+ }
+ else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0)
+ {
+ p += sizeof ("LOG_TASK") - 1;
+ bitmask |= LOG_TASK;
+ }
+ else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
+ {
+ p += sizeof ("LOG_ALL") - 1;
+ bitmask |= LOG_ALL;
+ }
else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
{
p += sizeof ("LOG_DEFAULT") - 1;
bitmask |= LOG_DEFAULT;
}
+// end of auto-generated entries
+
else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
{
p += sizeof ("LOG_NONE") - 1;
@@ -3461,14 +3668,32 @@ RNBRemote::HandlePacket_MemoryRegionInfo
return SendPacket (ostrm.str());
}
+// qGetProfileData;scan_type:0xYYYYYYY
rnb_err_t
RNBRemote::HandlePacket_GetProfileData (const char *p)
{
nub_process_t pid = m_ctx.ProcessID();
if (pid == INVALID_NUB_PROCESS)
return SendPacket ("OK");
-
- std::string data = DNBProcessGetProfileData(pid);
+
+ StringExtractor packet(p += sizeof ("qGetProfileData"));
+ DNBProfileDataScanType scan_type = eProfileAll;
+ std::string name;
+ std::string value;
+ while (packet.GetNameColonValue(name, value))
+ {
+ if (name.compare ("scan_type") == 0)
+ {
+ std::istringstream iss(value);
+ uint32_t int_value = 0;
+ if (iss >> std::hex >> int_value)
+ {
+ scan_type = (DNBProfileDataScanType)int_value;
+ }
+ }
+ }
+
+ std::string data = DNBProcessGetProfileData(pid, scan_type);
if (!data.empty())
{
return SendPacket (data.c_str());
@@ -3479,18 +3704,18 @@ RNBRemote::HandlePacket_GetProfileData (
}
}
-
-// QSetAsyncEnableProfiling;enable:[0|1]:interval_usec:XXXXXX;
+// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;scan_type:0xYYYYYYY
rnb_err_t
-RNBRemote::HandlePacket_SetAsyncEnableProfiling (const char *p)
+RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
{
nub_process_t pid = m_ctx.ProcessID();
if (pid == INVALID_NUB_PROCESS)
- return SendPacket ("");
+ return SendPacket ("OK");
- StringExtractor packet(p += sizeof ("QSetAsyncEnableProfiling:") - 1);
+ StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));
bool enable = false;
uint64_t interval_usec = 0;
+ DNBProfileDataScanType scan_type = eProfileAll;
std::string name;
std::string value;
while (packet.GetNameColonValue(name, value))
@@ -3503,13 +3728,23 @@ RNBRemote::HandlePacket_SetAsyncEnablePr
{
interval_usec = strtoul(value.c_str(), NULL, 10);
}
+ else if (name.compare ("scan_type") == 0)
+ {
+ std::istringstream iss(value);
+ uint32_t int_value = 0;
+ if (iss >> std::hex >> int_value)
+ {
+ scan_type = (DNBProfileDataScanType)int_value;
+ }
+ }
}
if (interval_usec == 0)
{
enable = 0;
}
- DNBProcessSetAsyncEnableProfiling(pid, enable, interval_usec);
+
+ DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec, scan_type);
return SendPacket ("OK");
}
@@ -3601,6 +3836,7 @@ RNBRemote::HandlePacket_D (const char *p
rnb_err_t
RNBRemote::HandlePacket_k (const char *p)
{
+ DNBLog ("Got a 'k' packet, killing the inferior process.");
// No response to should be sent to the kill packet
if (m_ctx.HasValidProcessID())
DNBProcessKill (m_ctx.ProcessID());
@@ -3818,18 +4054,10 @@ RNBRemote::HandlePacket_qProcessInfo (co
}
}
- int cputype_mib[CTL_MAXNAME]={0,};
- size_t cputype_mib_len = CTL_MAXNAME;
- cpu_type_t cputype = -1;
- if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0)
- {
- cputype_mib[cputype_mib_len] = pid;
- cputype_mib_len++;
- size_t len = sizeof(cputype);
- if (::sysctl (cputype_mib, cputype_mib_len, &cputype, &len, 0, 0) == 0)
- {
- rep << "cputype:" << std::hex << cputype << ";";
- }
+ cpu_type_t cputype = DNBProcessGetCPUType (pid);
+ if (cputype != 0)
+ {
+ rep << "cputype:" << std::hex << cputype << ";";
}
uint32_t cpusubtype;
@@ -3862,10 +4090,9 @@ RNBRemote::HandlePacket_qProcessInfo (co
rep << "endian:pdp;";
#endif
- nub_thread_t thread = DNBProcessGetCurrentThread (pid);
- kern_return_t kr;
-
#if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
+ nub_thread_t thread = DNBProcessGetCurrentThreadMachPort (pid);
+ kern_return_t kr;
x86_thread_state_t gp_regs;
mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
kr = thread_get_state (thread, x86_THREAD_STATE,
Modified: lldb/branches/windows/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/RNBRemote.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/branches/windows/tools/debugserver/source/RNBRemote.h Wed Apr 17 03:38:48 2013
@@ -79,9 +79,9 @@ public:
insert_access_watch_bp, // 'Z4'
remove_access_watch_bp, // 'z4'
+ query_monitor, // 'qRcmd'
query_current_thread_id, // 'qC'
query_get_pid, // 'qGetPid'
- query_memory_crc, // 'qCRC:'
query_thread_ids_first, // 'qfThreadInfo'
query_thread_ids_subsequent, // 'qsThreadInfo'
query_thread_extra_info, // 'qThreadExtraInfo'
@@ -114,7 +114,7 @@ public:
sync_thread_state, // 'QSyncThreadState:'
memory_region_info, // 'qMemoryRegionInfo:'
get_profile_data, // 'qGetProfileData'
- set_enable_profiling, // 'QSetAsyncEnableProfiling'
+ set_enable_profiling, // 'QSetEnableAsyncProfiling'
watchpoint_support_info, // 'qWatchpointSupportInfo:'
allocate_memory, // '_M'
deallocate_memory, // '_m'
@@ -166,6 +166,7 @@ public:
rnb_err_t HandlePacket_A (const char *p);
rnb_err_t HandlePacket_H (const char *p);
rnb_err_t HandlePacket_qC (const char *p);
+ rnb_err_t HandlePacket_qRcmd (const char *p);
rnb_err_t HandlePacket_qGetPid (const char *p);
rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
rnb_err_t HandlePacket_qRegisterInfo (const char *p);
@@ -215,7 +216,7 @@ public:
rnb_err_t HandlePacket_DeallocateMemory (const char *p);
rnb_err_t HandlePacket_MemoryRegionInfo (const char *p);
rnb_err_t HandlePacket_GetProfileData(const char *p);
- rnb_err_t HandlePacket_SetAsyncEnableProfiling(const char *p);
+ rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p);
rnb_err_t HandlePacket_stop_process (const char *p);
Modified: lldb/branches/windows/tools/debugserver/source/RNBSocket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/RNBSocket.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/RNBSocket.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/RNBSocket.cpp Wed Apr 17 03:38:48 2013
@@ -31,7 +31,7 @@
This function blocks while waiting for that connection. */
rnb_err_t
-RNBSocket::Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton)
+RNBSocket::Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton, bool localhost_only)
{
//DNBLogThreadedIf(LOG_RNB_COMM, "%8u RNBSocket::%s called", (uint32_t)m_timer.ElapsedMicroSeconds(true), __FUNCTION__);
// Disconnect without saving errno
@@ -56,7 +56,14 @@ RNBSocket::Listen (in_port_t port, PortB
sa.sin_len = sizeof sa;
sa.sin_family = AF_INET;
sa.sin_port = htons (port);
- sa.sin_addr.s_addr = htonl (INADDR_ANY);
+ if (localhost_only)
+ {
+ sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ }
+ else
+ {
+ sa.sin_addr.s_addr = htonl (INADDR_ANY);
+ }
int error = ::bind (listen_fd, (struct sockaddr *) &sa, sizeof(sa));
if (error == -1)
@@ -188,15 +195,18 @@ RNBSocket::ConnectToService()
DNBLog("Connecting to com.apple.%s service...", DEBUGSERVER_PROGRAM_NAME);
// Disconnect from any previous connections
Disconnect(false);
-
- SSLContextRef ssl_ctx;
- bzero(&ssl_ctx, sizeof(ssl_ctx));
- if (::lockdown_secure_checkin (&m_fd, &ssl_ctx, NULL, NULL) != kLDESuccess)
+ if (::secure_lockdown_checkin (&m_ld_conn, NULL, NULL) != kLDESuccess)
{
- DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_secure_checkin(&m_fd, NULL, NULL, NULL) failed");
+ DNBLogThreadedIf(LOG_RNB_COMM, "::secure_lockdown_checkin(&m_fd, NULL, NULL) failed");
m_fd = -1;
return rnb_not_connected;
}
+ m_fd = ::lockdown_get_socket (m_ld_conn);
+ if (m_fd == -1)
+ {
+ DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_get_socket() failed");
+ return rnb_not_connected;
+ }
m_fd_from_lockdown = true;
return rnb_success;
}
@@ -238,7 +248,14 @@ RNBSocket::Disconnect (bool save_errno)
{
#ifdef WITH_LOCKDOWN
if (m_fd_from_lockdown)
+ {
m_fd_from_lockdown = false;
+ m_fd = -1;
+ if (lockdown_deactivate (m_ld_conn) == 0)
+ return rnb_success;
+ else
+ return rnb_err;
+ }
#endif
return ClosePort (m_fd, save_errno);
}
Modified: lldb/branches/windows/tools/debugserver/source/RNBSocket.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/RNBSocket.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/RNBSocket.h (original)
+++ lldb/branches/windows/tools/debugserver/source/RNBSocket.h Wed Apr 17 03:38:48 2013
@@ -20,6 +20,10 @@
#include <string>
#include "DNBTimer.h"
+#ifdef WITH_LOCKDOWN
+#include "lockdown.h"
+#endif
+
class RNBSocket
{
public:
@@ -29,6 +33,7 @@ public:
m_fd (-1),
#ifdef WITH_LOCKDOWN
m_fd_from_lockdown (false),
+ m_ld_conn (),
#endif
m_timer (true) // Make a thread safe timer
{
@@ -38,7 +43,7 @@ public:
Disconnect (false);
}
- rnb_err_t Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton);
+ rnb_err_t Listen (in_port_t port, PortBoundCallback callback, const void *callback_baton, bool localhost_only);
rnb_err_t Connect (const char *host, uint16_t port);
rnb_err_t useFD(int fd);
@@ -67,6 +72,7 @@ protected:
#ifdef WITH_LOCKDOWN
bool m_fd_from_lockdown;
+ lockdown_connection m_ld_conn;
#endif
DNBTimer m_timer;
Modified: lldb/branches/windows/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/debugserver.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/debugserver.cpp Wed Apr 17 03:38:48 2013
@@ -93,7 +93,7 @@ RNBRunLoopGetStartModeFromRemote (RNBRem
if (set_events & RNBContext::event_read_thread_exiting)
{
- RNBLogSTDERR ("error: packet read thread exited.");
+ RNBLogSTDERR ("error: packet read thread exited.\n");
return eRNBRunLoopModeExit;
}
@@ -108,10 +108,13 @@ RNBRunLoopGetStartModeFromRemote (RNBRem
if (type == RNBRemote::vattach || type == RNBRemote::vattachwait || type == RNBRemote::vattachorwait)
{
if (err == rnb_success)
+ {
+ RNBLogSTDOUT ("Attach succeeded, ready to debug.\n");
return eRNBRunLoopModeInferiorExecuting;
+ }
else
{
- RNBLogSTDERR ("error: attach failed.");
+ RNBLogSTDERR ("error: attach failed.\n");
return eRNBRunLoopModeExit;
}
}
@@ -127,7 +130,7 @@ RNBRunLoopGetStartModeFromRemote (RNBRem
}
else if (err == rnb_not_connected)
{
- RNBLogSTDERR ("error: connection lost.");
+ RNBLogSTDERR ("error: connection lost.\n");
return eRNBRunLoopModeExit;
}
else
@@ -568,6 +571,7 @@ RNBRunLoopInferiorExecuting (RNBRemote *
// in its current state and listen for another connection...
if (ctx.ProcessStateRunning())
{
+ DNBLog ("debugserver's event read thread is exiting, killing the inferior process.");
DNBProcessKill (ctx.ProcessID());
}
}
@@ -681,13 +685,13 @@ PortWasBoundCallback (const void *baton,
}
static int
-StartListening (RNBRemote *remote, int listen_port, const char *unix_socket_name)
+StartListening (RNBRemote *remote, int listen_port, const char *unix_socket_name, bool localhost_only)
{
if (!remote->Comm().IsConnected())
{
if (listen_port != 0)
RNBLogSTDOUT ("Listening to port %i...\n", listen_port);
- if (remote->Comm().Listen(listen_port, PortWasBoundCallback, unix_socket_name) != rnb_success)
+ if (remote->Comm().Listen(listen_port, PortWasBoundCallback, unix_socket_name, localhost_only) != rnb_success)
{
RNBLogSTDERR ("Failed to get connection from a remote gdb process.\n");
return 0;
@@ -756,7 +760,7 @@ show_usage_and_exit (int exit_code)
//----------------------------------------------------------------------
-// option descriptors for getopt_long()
+// option descriptors for getopt_long_only()
//----------------------------------------------------------------------
static struct option g_long_options[] =
{
@@ -783,6 +787,7 @@ static struct option g_long_options[] =
{ "working-dir", required_argument, NULL, 'W' }, // The working directory that the inferior process should have (only if debugserver launches the process)
{ "platform", required_argument, NULL, 'p' }, // Put this executable into a remote platform mode
{ "unix-socket", required_argument, NULL, 'u' }, // If we need to handshake with our parent process, an option will be passed down that specifies a unix socket name to use
+ { "open-connection", no_argument, NULL, 'H' }, // If debugserver is listening to a TCP port, allow connections from any host (as opposed to just "localhost" connections)
{ NULL, 0, NULL, 0 }
};
@@ -838,6 +843,7 @@ main (int argc, char *argv[])
useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec.
useconds_t waitfor_duration = 0; // Time in seconds to wait for a process by name, 0 means wait forever.
bool no_stdio = false;
+ bool localhost_only = true;
#if !defined (DNBLOG_ENABLED)
compile_options += "(no-logging) ";
@@ -874,7 +880,7 @@ main (int argc, char *argv[])
}
// NULL terminate the short option string.
short_options[short_options_idx++] = '\0';
- while ((ch = getopt_long(argc, argv, short_options, g_long_options, &long_option_index)) != -1)
+ while ((ch = getopt_long_only(argc, argv, short_options, g_long_options, &long_option_index)) != -1)
{
DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
ch, (uint8_t)ch,
@@ -1077,7 +1083,10 @@ main (int argc, char *argv[])
case 'u':
unix_socket_name.assign (optarg);
break;
-
+
+ case 'H':
+ localhost_only = false;
+ break;
}
}
@@ -1097,7 +1106,7 @@ main (int argc, char *argv[])
// fprintf(stderr, "error: no architecture was specified\n");
// exit (8);
// }
- // Skip any options we consumed with getopt_long
+ // Skip any options we consumed with getopt_long_only
argc -= optind;
argv += optind;
@@ -1283,7 +1292,7 @@ main (int argc, char *argv[])
#endif
if (listen_port != INT32_MAX)
{
- if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
+ if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
mode = eRNBRunLoopModeExit;
}
else if (str[0] == '/')
@@ -1328,6 +1337,7 @@ main (int argc, char *argv[])
ctx.SetLaunchFlavor(launch_flavor);
bool ignore_existing = false;
+ RNBLogSTDOUT ("Waiting to attach to process %s...\n", waitfor_pid_name.c_str());
nub_process_t pid = DNBProcessAttachWait (waitfor_pid_name.c_str(), launch_flavor, ignore_existing, timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
g_pid = pid;
@@ -1336,7 +1346,7 @@ main (int argc, char *argv[])
ctx.LaunchStatus().SetError(-1, DNBError::Generic);
if (err_str[0])
ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s", waitfor_pid_name.c_str(), err_str);
+ RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s\n", waitfor_pid_name.c_str(), err_str);
mode = eRNBRunLoopModeExit;
}
else
@@ -1367,6 +1377,7 @@ main (int argc, char *argv[])
timeout_ptr = &attach_timeout_abstime;
}
+ RNBLogSTDOUT ("Attaching to process %s...\n", attach_pid_name.c_str());
nub_process_t pid = DNBProcessAttachByName (attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
g_pid = pid;
if (pid == INVALID_NUB_PROCESS)
@@ -1374,7 +1385,7 @@ main (int argc, char *argv[])
ctx.LaunchStatus().SetError(-1, DNBError::Generic);
if (err_str[0])
ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s", waitfor_pid_name.c_str(), err_str);
+ RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s\n", waitfor_pid_name.c_str(), err_str);
mode = eRNBRunLoopModeExit;
}
else
@@ -1386,7 +1397,7 @@ main (int argc, char *argv[])
}
else
{
- RNBLogSTDERR ("error: asked to attach with empty name and invalid PID.");
+ RNBLogSTDERR ("error: asked to attach with empty name and invalid PID.\n");
mode = eRNBRunLoopModeExit;
}
@@ -1394,7 +1405,7 @@ main (int argc, char *argv[])
{
if (listen_port != INT32_MAX)
{
- if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
+ if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
mode = eRNBRunLoopModeExit;
}
else if (str[0] == '/')
@@ -1403,7 +1414,7 @@ main (int argc, char *argv[])
mode = eRNBRunLoopModeExit;
}
if (mode != eRNBRunLoopModeExit)
- RNBLogSTDOUT ("Got a connection, waiting for debugger instructions for process %d.\n", attach_pid);
+ RNBLogSTDOUT ("Waiting for debugger instructions for process %d.\n", attach_pid);
}
break;
@@ -1419,7 +1430,7 @@ main (int argc, char *argv[])
{
if (listen_port != INT32_MAX)
{
- if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
+ if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
mode = eRNBRunLoopModeExit;
}
else if (str[0] == '/')
@@ -1429,7 +1440,7 @@ main (int argc, char *argv[])
}
if (mode != eRNBRunLoopModeExit)
- RNBLogSTDOUT ("Got a connection, waiting for debugger instructions.\n");
+ RNBLogSTDOUT ("Got a connection, launched process %s.\n", argv_sub_zero);
}
else
{
@@ -1446,7 +1457,7 @@ main (int argc, char *argv[])
case eRNBRunLoopModePlatformMode:
if (listen_port != INT32_MAX)
{
- if (!StartListening (remote, listen_port, unix_socket_name.c_str()))
+ if (!StartListening (remote, listen_port, unix_socket_name.c_str(), localhost_only))
mode = eRNBRunLoopModeExit;
}
else if (str[0] == '/')
@@ -1468,6 +1479,7 @@ main (int argc, char *argv[])
remote->StopReadRemoteDataThread ();
remote->Context().SetProcessID(INVALID_NUB_PROCESS);
+ RNBLogSTDOUT ("Exiting.\n");
return 0;
}
Modified: lldb/branches/windows/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/CMakeLists.txt (original)
+++ lldb/branches/windows/tools/driver/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -1,105 +1,16 @@
set(LLVM_NO_RTTI 1)
-
-set( LLDB_USED_LIBS
- lldbAPI
- lldbBreakpoint
- lldbCommands
- lldbCore
- lldbExpression
- lldbHostCommon
- lldbInitAndLog
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
-
- # Plugins
- lldbPluginDisassemblerLLVM
- lldbPluginSymbolFileDWARF
- lldbPluginSymbolFileSymtab
- lldbPluginDynamicLoaderStatic
-
- lldbPluginObjectFileMachO
- lldbPluginObjectFileELF
- lldbPluginObjectContainerBSDArchive
- lldbPluginObjectContainerMachOArchive
- lldbPluginProcessGDBRemote
- lldbPluginProcessUtility
- lldbPluginPlatformGDB
- lldbPluginObjectFileMachO
- lldbPluginObjectContainerMachOArchive
- lldbPluginObjectContainerBSDArchive
- lldbPluginPlatformMacOSX
- lldbPluginDynamicLoaderMacOSXDYLD
- lldbPluginDynamicLoaderPosixDYLD
- lldbPluginUnwindAssemblyInstEmulation
- lldbPluginUnwindAssemblyX86
- lldbPluginDynamicLoaderDarwinKernel
- lldbPluginAppleObjCRuntime
- lldbPluginCXXItaniumABI
- lldbPluginABIMacOSX_arm
- lldbPluginABIMacOSX_i386
- lldbPluginABISysV_x86_64
- lldbPluginInstructionARM
-
-
- # Windows
- lldbHostWindows
- lldbPluginPlatformWindows
- lldbPluginObjectFilePECOFF
-
- # Linux
- #lldbHostLinux
-
- Ws2_32
- )
-
-set( CLANG_USED_LIBS
- clangAnalysis
- clangAST
- clangBasic
- clangCodeGen
- clangDriver
- clangEdit
- clangFrontend
- clangLex
- clangParse
- clangRewriteCore
- clangRewriteFrontend
- clangSema
- clangSerialization
- )
-
-set( LLDB_DRIVER_LIBS
- #edit
- #python2.6
- )
-
-set( LLVM_LINK_COMPONENTS
- ${LLVM_TARGETS_TO_BUILD}
- jit
- interpreter
- nativecodegen
- asmparser
- bitreader
- bitwriter
- codegen
- ipo
- selectiondag
- bitreader
- mc
- mcjit
- core
- mcdisassembler
- )
-
add_lldb_executable(lldb
Driver.cpp
- DriverEvents.cpp
- DriverOptions.cpp
- DriverPosix.cpp
+ #DriverEvents.cpp
+ #DriverOptions.cpp
+ #DriverPosix.cpp
IOChannel.cpp
)
+target_link_libraries(lldb liblldb)
+# TODO: why isn't this done by add_lldb_executable?
+#target_link_libraries(lldb ${LLDB_USED_LIBS})
+#llvm_config(lldb ${LLVM_LINK_COMPONENTS})
+
install(TARGETS lldb
RUNTIME DESTINATION bin)
Modified: lldb/branches/windows/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/Driver.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/Driver.cpp (original)
+++ lldb/branches/windows/tools/driver/Driver.cpp Wed Apr 17 03:38:48 2013
@@ -11,18 +11,20 @@
#ifdef _WIN32
#include "lldb/lldb-windows.h"
-#include "lldb/lldb-private-log.h"
-#include "lldb/Core/StreamCallback.h"
-#include "lldb/Core/Log.h"
+#else
+#include <getopt.h>
+#include <libgen.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <unistd.h>
+#include <inttypes.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>
-#ifndef _WIN32
-#include <inttypes.h>
-#endif
+#include <string>
#include "IOChannel.h"
#include "lldb/API/SBBreakpoint.h"
@@ -41,10 +43,82 @@
using namespace lldb;
static void reset_stdin_termios ();
+static bool g_old_stdin_termios_is_valid = false;
+static struct termios g_old_stdin_termios;
+
+static char *g_debugger_name = (char *) "";
+static Driver *g_driver = NULL;
+
+// In the Driver::MainLoop, we change the terminal settings. This function is
+// added as an atexit handler to make sure we clean them up.
+static void
+reset_stdin_termios ()
+{
+ if (g_old_stdin_termios_is_valid)
+ {
+ g_old_stdin_termios_is_valid = false;
+ ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
+ }
+}
+
+typedef struct
+{
+ uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
+ // then this option belongs to option set n.
+ bool required; // This option is required (in the current usage level)
+ const char * long_option; // Full name for this option.
+ int short_option; // Single character for this option.
+ int option_has_arg; // no_argument, required_argument or optional_argument
+ uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
+ lldb::CommandArgumentType argument_type; // Type of argument this option takes
+ const char * usage_text; // Full text explaining what this options does and what (if any) argument to
+ // pass it.
+} OptionDefinition;
+
+#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
+#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
+
+static OptionDefinition g_options[] =
+{
+ { LLDB_OPT_SET_1, true , "help" , 'h', no_argument , 0, eArgTypeNone,
+ "Prints out the usage information for the LLDB debugger." },
+ { LLDB_OPT_SET_2, true , "version" , 'v', no_argument , 0, eArgTypeNone,
+ "Prints out the current version number of the LLDB debugger." },
+ { LLDB_OPT_SET_3, true , "arch" , 'a', required_argument, 0, eArgTypeArchitecture,
+ "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
+ "be one of the architectures for which the program was compiled." },
+ { LLDB_OPT_SET_3, true , "file" , 'f', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to use the file <filename> as the program to be debugged." },
+ { LLDB_OPT_SET_3, false, "core" , 'c', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to use the fullpath to <path> as the core file." },
+ { LLDB_OPT_SET_4, true , "attach-name" , 'n', required_argument, 0, eArgTypeProcessName,
+ "Tells the debugger to attach to a process with the given name." },
+ { LLDB_OPT_SET_4, true , "wait-for" , 'w', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
+ { LLDB_OPT_SET_5, true , "attach-pid" , 'p', required_argument, 0, eArgTypePid,
+ "Tells the debugger to attach to a process with the given pid." },
+ { LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
+ "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
+ "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
+ "extensions have been implemented." },
+ { LLDB_3_TO_5, false, "debug" , 'd', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to print out extra information for debugging itself." },
+ { LLDB_3_TO_5, false, "source" , 's', required_argument, 0, eArgTypeFilename,
+ "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
+ { LLDB_3_TO_5, false, "editor" , 'e', no_argument , 0, eArgTypeNone,
+ "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
+ { LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
+ "Do not automatically parse any '.lldbinit' files." },
+ { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
+ "Prints out the path to the lldb.py file for this version of lldb." },
+ { 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
+};
+
+static const uint32_t last_option_set_with_args = 2;
Driver::Driver () :
SBBroadcaster ("Driver"),
- m_debugger (NULL),
+ m_debugger (SBDebugger::Create(false)),
m_editline_pty (),
m_editline_slave_fh (NULL),
m_editline_reader (),
@@ -53,10 +127,307 @@ Driver::Driver () :
m_waiting_for_command (false),
m_done(false)
{
+ // We want to be able to handle CTRL+D in the terminal to have it terminate
+ // certain input
+ m_debugger.SetCloseInputOnEOF (false);
+ g_debugger_name = (char *) m_debugger.GetInstanceName();
+ if (g_debugger_name == NULL)
+ g_debugger_name = (char *) "";
+ g_driver = this;
}
Driver::~Driver ()
{
+ g_driver = NULL;
+ g_debugger_name = NULL;
+}
+
+void
+Driver::CloseIOChannelFile ()
+{
+ // Write an End of File sequence to the file descriptor to ensure any
+ // read functions can exit.
+ char eof_str[] = "\x04";
+ ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
+
+ m_editline_pty.CloseMasterFileDescriptor();
+
+ if (m_editline_slave_fh)
+ {
+ ::fclose (m_editline_slave_fh);
+ m_editline_slave_fh = NULL;
+ }
+}
+
+// This function takes INDENT, which tells how many spaces to output at the front
+// of each line; TEXT, which is the text that is to be output. It outputs the
+// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
+// front of each line. It breaks lines on spaces, tabs or newlines, shortening
+// the line if necessary to not break in the middle of a word. It assumes that
+// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
+
+void
+OutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
+{
+ int len = strlen (text);
+ std::string text_string (text);
+
+ // Force indentation to be reasonable.
+ if (indent >= output_max_columns)
+ indent = 0;
+
+ // Will it all fit on one line?
+
+ if (len + indent < output_max_columns)
+ // Output as a single line
+ fprintf (out, "%*s%s\n", indent, "", text);
+ else
+ {
+ // We need to break it up into multiple lines.
+ int text_width = output_max_columns - indent - 1;
+ int start = 0;
+ int end = start;
+ int final_end = len;
+ int sub_len;
+
+ while (end < final_end)
+ {
+ // Dont start the 'text' on a space, since we're already outputting the indentation.
+ while ((start < final_end) && (text[start] == ' '))
+ start++;
+
+ end = start + text_width;
+ if (end > final_end)
+ end = final_end;
+ else
+ {
+ // If we're not at the end of the text, make sure we break the line on white space.
+ while (end > start
+ && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
+ end--;
+ }
+ sub_len = end - start;
+ std::string substring = text_string.substr (start, sub_len);
+ fprintf (out, "%*s%s\n", indent, "", substring.c_str());
+ start = end + 1;
+ }
+ }
+}
+
+void
+ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
+{
+ uint32_t screen_width = 80;
+ uint32_t indent_level = 0;
+ const char *name = "lldb";
+
+ fprintf (out, "\nUsage:\n\n");
+
+ indent_level += 2;
+
+
+ // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
+ // <cmd> [options-for-level-1]
+ // etc.
+
+ uint32_t num_options;
+ uint32_t num_option_sets = 0;
+
+ for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
+ {
+ uint32_t this_usage_mask = option_table[num_options].usage_mask;
+ if (this_usage_mask == LLDB_OPT_SET_ALL)
+ {
+ if (num_option_sets == 0)
+ num_option_sets = 1;
+ }
+ else
+ {
+ for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
+ {
+ if (this_usage_mask & 1 << j)
+ {
+ if (num_option_sets <= j)
+ num_option_sets = j + 1;
+ }
+ }
+ }
+ }
+
+ for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
+ {
+ uint32_t opt_set_mask;
+
+ opt_set_mask = 1 << opt_set;
+
+ if (opt_set > 0)
+ fprintf (out, "\n");
+ fprintf (out, "%*s%s", indent_level, "", name);
+ bool is_help_line = false;
+
+ for (uint32_t i = 0; i < num_options; ++i)
+ {
+ if (option_table[i].usage_mask & opt_set_mask)
+ {
+ CommandArgumentType arg_type = option_table[i].argument_type;
+ const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
+ // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
+ // so we do it by hand here.
+ if (option_table[i].short_option == 'h')
+ is_help_line = true;
+
+ if (option_table[i].required)
+ {
+ if (option_table[i].option_has_arg == required_argument)
+ fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
+ else if (option_table[i].option_has_arg == optional_argument)
+ fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
+ else
+ fprintf (out, " -%c", option_table[i].short_option);
+ }
+ else
+ {
+ if (option_table[i].option_has_arg == required_argument)
+ fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
+ else if (option_table[i].option_has_arg == optional_argument)
+ fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
+ else
+ fprintf (out, " [-%c]", option_table[i].short_option);
+ }
+ }
+ }
+ if (!is_help_line && (opt_set <= last_option_set_with_args))
+ fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
+ }
+
+ fprintf (out, "\n\n");
+
+ // Now print out all the detailed information about the various options: long form, short form and help text:
+ // -- long_name <argument>
+ // - short <argument>
+ // help text
+
+ // This variable is used to keep track of which options' info we've printed out, because some options can be in
+ // more than one usage level, but we only want to print the long form of its information once.
+
+ Driver::OptionData::OptionSet options_seen;
+ Driver::OptionData::OptionSet::iterator pos;
+
+ indent_level += 5;
+
+ for (uint32_t i = 0; i < num_options; ++i)
+ {
+ // Only print this option if we haven't already seen it.
+ pos = options_seen.find (option_table[i].short_option);
+ if (pos == options_seen.end())
+ {
+ CommandArgumentType arg_type = option_table[i].argument_type;
+ const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
+
+ options_seen.insert (option_table[i].short_option);
+ fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
+ if (arg_type != eArgTypeNone)
+ fprintf (out, "<%s>", arg_name);
+ fprintf (out, "\n");
+ fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
+ if (arg_type != eArgTypeNone)
+ fprintf (out, "<%s>", arg_name);
+ fprintf (out, "\n");
+ indent_level += 5;
+ OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
+ indent_level -= 5;
+ fprintf (out, "\n");
+ }
+ }
+
+ indent_level -= 5;
+
+ fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
+ "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
+ "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
+ indent_level, "",
+ indent_level, "",
+ name,
+ indent_level, "");
+}
+
+void
+BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
+ uint32_t num_options)
+{
+ if (num_options == 0)
+ return;
+
+ uint32_t i;
+ uint32_t j;
+ std::bitset<256> option_seen;
+
+ getopt_table.resize (num_options + 1);
+
+ for (i = 0, j = 0; i < num_options; ++i)
+ {
+ char short_opt = expanded_option_table[i].short_option;
+
+ if (option_seen.test(short_opt) == false)
+ {
+ getopt_table[j].name = expanded_option_table[i].long_option;
+ getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
+ getopt_table[j].flag = NULL;
+ getopt_table[j].val = expanded_option_table[i].short_option;
+ option_seen.set(short_opt);
+ ++j;
+ }
+ }
+
+ getopt_table[j].name = NULL;
+ getopt_table[j].has_arg = 0;
+ getopt_table[j].flag = NULL;
+ getopt_table[j].val = 0;
+
+}
+
+Driver::OptionData::OptionData () :
+ m_args(),
+ m_script_lang (lldb::eScriptLanguageDefault),
+ m_core_file (),
+ m_crash_log (),
+ m_source_command_files (),
+ m_debug_mode (false),
+ m_print_version (false),
+ m_print_python_path (false),
+ m_print_help (false),
+ m_wait_for(false),
+ m_process_name(),
+ m_process_pid(LLDB_INVALID_PROCESS_ID),
+ m_use_external_editor(false),
+ m_seen_options()
+{
+}
+
+Driver::OptionData::~OptionData ()
+{
+}
+
+void
+Driver::OptionData::Clear ()
+{
+ m_args.clear ();
+ m_script_lang = lldb::eScriptLanguageDefault;
+ m_source_command_files.clear ();
+ m_debug_mode = false;
+ m_print_help = false;
+ m_print_version = false;
+ m_print_python_path = false;
+ m_use_external_editor = false;
+ m_wait_for = false;
+ m_process_name.erase();
+ m_process_pid = LLDB_INVALID_PROCESS_ID;
+}
+
+void
+Driver::ResetOptionValues ()
+{
+ m_option_data.Clear ();
}
const char *
@@ -101,6 +472,304 @@ Driver::GetDebugMode() const
return m_option_data.m_debug_mode;
}
+
+// Check the arguments that were passed to this program to make sure they are valid and to get their
+// argument values (if any). Return a boolean value indicating whether or not to start up the full
+// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
+// if the user only wanted help or version information.
+
+SBError
+Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
+{
+ ResetOptionValues ();
+
+ SBCommandReturnObject result;
+
+ SBError error;
+ std::string option_string;
+ struct option *long_options = NULL;
+ std::vector<struct option> long_options_vector;
+ uint32_t num_options;
+
+ for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
+ /* Do Nothing. */;
+
+ if (num_options == 0)
+ {
+ if (argc > 1)
+ error.SetErrorStringWithFormat ("invalid number of options");
+ return error;
+ }
+
+ BuildGetOptTable (g_options, long_options_vector, num_options);
+
+ if (long_options_vector.empty())
+ long_options = NULL;
+ else
+ long_options = &long_options_vector.front();
+
+ if (long_options == NULL)
+ {
+ error.SetErrorStringWithFormat ("invalid long options");
+ return error;
+ }
+
+ // Build the option_string argument for call to getopt_long_only.
+
+ for (int i = 0; long_options[i].name != NULL; ++i)
+ {
+ if (long_options[i].flag == NULL)
+ {
+ option_string.push_back ((char) long_options[i].val);
+ switch (long_options[i].has_arg)
+ {
+ default:
+ case no_argument:
+ break;
+ case required_argument:
+ option_string.push_back (':');
+ break;
+ case optional_argument:
+ option_string.append ("::");
+ break;
+ }
+ }
+ }
+
+ // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
+ // know at that point whether we should read in init files yet. So we don't read them in in the
+ // Driver constructor, then set the flags back to "read them in" here, and then if we see the
+ // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
+ // main loop.
+
+ m_debugger.SkipLLDBInitFiles (false);
+ m_debugger.SkipAppInitFiles (false);
+
+ // Prepare for & make calls to getopt_long_only.
+#if __GLIBC__
+ optind = 0;
+#else
+ optreset = 1;
+ optind = 1;
+#endif
+ int val;
+ while (1)
+ {
+ int long_options_index = -1;
+ val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
+
+ if (val == -1)
+ break;
+ else if (val == '?')
+ {
+ m_option_data.m_print_help = true;
+ error.SetErrorStringWithFormat ("unknown or ambiguous option");
+ break;
+ }
+ else if (val == 0)
+ continue;
+ else
+ {
+ m_option_data.m_seen_options.insert ((char) val);
+ if (long_options_index == -1)
+ {
+ for (int i = 0;
+ long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
+ ++i)
+ {
+ if (long_options[i].val == val)
+ {
+ long_options_index = i;
+ break;
+ }
+ }
+ }
+
+ if (long_options_index >= 0)
+ {
+ const int short_option = g_options[long_options_index].short_option;
+
+ switch (short_option)
+ {
+ case 'h':
+ m_option_data.m_print_help = true;
+ break;
+
+ case 'v':
+ m_option_data.m_print_version = true;
+ break;
+
+ case 'P':
+ m_option_data.m_print_python_path = true;
+ break;
+
+ case 'c':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ {
+ m_option_data.m_core_file = optarg;
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
+ }
+ break;
+
+ case 'e':
+ m_option_data.m_use_external_editor = true;
+ break;
+
+ case 'x':
+ m_debugger.SkipLLDBInitFiles (true);
+ m_debugger.SkipAppInitFiles (true);
+ break;
+
+ case 'f':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ {
+ m_option_data.m_args.push_back (optarg);
+ }
+ else if (file.ResolveExecutableLocation())
+ {
+ char path[PATH_MAX];
+ file.GetPath (path, sizeof(path));
+ m_option_data.m_args.push_back (path);
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
+ }
+ break;
+
+ case 'a':
+ if (!m_debugger.SetDefaultArchitecture (optarg))
+ error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
+ break;
+
+ case 'l':
+ m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
+ break;
+
+ case 'd':
+ m_option_data.m_debug_mode = true;
+ break;
+
+ case 'n':
+ m_option_data.m_process_name = optarg;
+ break;
+
+ case 'w':
+ m_option_data.m_wait_for = true;
+ break;
+
+ case 'p':
+ {
+ char *remainder;
+ m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
+ if (remainder == optarg || *remainder != '\0')
+ error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
+ optarg);
+ }
+ break;
+ case 's':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ m_option_data.m_source_command_files.push_back (optarg);
+ else if (file.ResolveExecutableLocation())
+ {
+ char final_path[PATH_MAX];
+ file.GetPath (final_path, sizeof(final_path));
+ std::string path_str (final_path);
+ m_option_data.m_source_command_files.push_back (path_str);
+ }
+ else
+ error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
+ }
+ break;
+
+ default:
+ m_option_data.m_print_help = true;
+ error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
+ break;
+ }
+ }
+ else
+ {
+ error.SetErrorStringWithFormat ("invalid option with value %i", val);
+ }
+ if (error.Fail())
+ {
+ return error;
+ }
+ }
+ }
+
+ if (error.Fail() || m_option_data.m_print_help)
+ {
+ ShowUsage (out_fh, g_options, m_option_data);
+ exit = true;
+ }
+ else if (m_option_data.m_print_version)
+ {
+ ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
+ exit = true;
+ }
+ else if (m_option_data.m_print_python_path)
+ {
+ SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
+ if (python_file_spec.IsValid())
+ {
+ char python_path[PATH_MAX];
+ size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
+ if (num_chars < PATH_MAX)
+ {
+ ::fprintf (out_fh, "%s\n", python_path);
+ }
+ else
+ ::fprintf (out_fh, "<PATH TOO LONG>\n");
+ }
+ else
+ ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
+ exit = true;
+ }
+ else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
+ {
+ // Any arguments that are left over after option parsing are for
+ // the program. If a file was specified with -f then the filename
+ // is already in the m_option_data.m_args array, and any remaining args
+ // are arguments for the inferior program. If no file was specified with
+ // -f, then what is left is the program name followed by any arguments.
+
+ // Skip any options we consumed with getopt_long_only
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 0)
+ {
+ for (int arg_idx=0; arg_idx<argc; ++arg_idx)
+ {
+ const char *arg = argv[arg_idx];
+ if (arg)
+ m_option_data.m_args.push_back (arg);
+ }
+ }
+
+ }
+ else
+ {
+ // Skip any options we consumed with getopt_long_only
+ argc -= optind;
+ //argv += optind; // Commented out to keep static analyzer happy
+
+ if (argc > 0)
+ ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
+ }
+
+ return error;
+}
+
size_t
Driver::GetProcessSTDOUT ()
{
@@ -136,65 +805,233 @@ Driver::UpdateSelectedThread ()
{
using namespace lldb;
SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
- if (!process.IsValid())
- return;
+ if (process.IsValid())
+ {
+ SBThread curr_thread (process.GetSelectedThread());
+ SBThread thread;
+ StopReason curr_thread_stop_reason = eStopReasonInvalid;
+ curr_thread_stop_reason = curr_thread.GetStopReason();
+
+ if (!curr_thread.IsValid() ||
+ curr_thread_stop_reason == eStopReasonInvalid ||
+ curr_thread_stop_reason == eStopReasonNone)
+ {
+ // Prefer a thread that has just completed its plan over another thread as current thread.
+ SBThread plan_thread;
+ SBThread other_thread;
+ const size_t num_threads = process.GetNumThreads();
+ size_t i;
+ for (i = 0; i < num_threads; ++i)
+ {
+ thread = process.GetThreadAtIndex(i);
+ StopReason thread_stop_reason = thread.GetStopReason();
+ switch (thread_stop_reason)
+ {
+ case eStopReasonInvalid:
+ case eStopReasonNone:
+ break;
+
+ case eStopReasonTrace:
+ case eStopReasonBreakpoint:
+ case eStopReasonWatchpoint:
+ case eStopReasonSignal:
+ case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
+ if (!other_thread.IsValid())
+ other_thread = thread;
+ break;
+ case eStopReasonPlanComplete:
+ if (!plan_thread.IsValid())
+ plan_thread = thread;
+ break;
+ }
+ }
+ if (plan_thread.IsValid())
+ process.SetSelectedThread (plan_thread);
+ else if (other_thread.IsValid())
+ process.SetSelectedThread (other_thread);
+ else
+ {
+ if (curr_thread.IsValid())
+ thread = curr_thread;
+ else
+ thread = process.GetThreadAtIndex(0);
+
+ if (thread.IsValid())
+ process.SetSelectedThread (thread);
+ }
+ }
+ }
+}
+
+// This function handles events that were broadcast by the process.
+void
+Driver::HandleBreakpointEvent (const SBEvent &event)
+{
+ using namespace lldb;
+ const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
- SBThread curr_thread (process.GetSelectedThread());
- SBThread thread;
- StopReason curr_thread_stop_reason = eStopReasonInvalid;
- curr_thread_stop_reason = curr_thread.GetStopReason();
-
- if (!curr_thread.IsValid() ||
- curr_thread_stop_reason == eStopReasonInvalid ||
- curr_thread_stop_reason == eStopReasonNone)
- {
- // Prefer a thread that has just completed its plan over another thread as current thread.
- SBThread plan_thread;
- SBThread other_thread;
- const size_t num_threads = process.GetNumThreads();
- size_t i;
- for (i = 0; i < num_threads; ++i)
- {
- thread = process.GetThreadAtIndex(i);
- StopReason thread_stop_reason = thread.GetStopReason();
- switch (thread_stop_reason)
- {
- case eStopReasonInvalid:
- case eStopReasonNone:
- break;
-
- case eStopReasonTrace:
- case eStopReasonBreakpoint:
- case eStopReasonWatchpoint:
- case eStopReasonSignal:
- case eStopReasonException:
- case eStopReasonExec:
- case eStopReasonThreadExiting:
- if (!other_thread.IsValid())
- other_thread = thread;
- break;
- case eStopReasonPlanComplete:
- if (!plan_thread.IsValid())
- plan_thread = thread;
- break;
- }
- }
- if (plan_thread.IsValid())
- process.SetSelectedThread (plan_thread);
- else if (other_thread.IsValid())
- process.SetSelectedThread (other_thread);
- else
- {
- if (curr_thread.IsValid())
- thread = curr_thread;
- else
- thread = process.GetThreadAtIndex(0);
+ if (event_type & eBreakpointEventTypeAdded
+ || event_type & eBreakpointEventTypeRemoved
+ || event_type & eBreakpointEventTypeEnabled
+ || event_type & eBreakpointEventTypeDisabled
+ || event_type & eBreakpointEventTypeCommandChanged
+ || event_type & eBreakpointEventTypeConditionChanged
+ || event_type & eBreakpointEventTypeIgnoreChanged
+ || event_type & eBreakpointEventTypeLocationsResolved)
+ {
+ // Don't do anything about these events, since the breakpoint commands already echo these actions.
+ }
+ else if (event_type & eBreakpointEventTypeLocationsAdded)
+ {
+ char message[256];
+ uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
+ if (num_new_locations > 0)
+ {
+ SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
+ int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
+ num_new_locations,
+ num_new_locations == 1 ? "" : "s",
+ breakpoint.GetID());
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ }
+ else if (event_type & eBreakpointEventTypeLocationsRemoved)
+ {
+ // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
+ }
+ else if (event_type & eBreakpointEventTypeLocationsResolved)
+ {
+ // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
+ }
+}
+
+// This function handles events that were broadcast by the process.
+void
+Driver::HandleProcessEvent (const SBEvent &event)
+{
+ using namespace lldb;
+ const uint32_t event_type = event.GetType();
+
+ if (event_type & SBProcess::eBroadcastBitSTDOUT)
+ {
+ // The process has stdout available, get it and write it out to the
+ // appropriate place.
+ GetProcessSTDOUT ();
+ }
+ else if (event_type & SBProcess::eBroadcastBitSTDERR)
+ {
+ // The process has stderr available, get it and write it out to the
+ // appropriate place.
+ GetProcessSTDERR ();
+ }
+ else if (event_type & SBProcess::eBroadcastBitStateChanged)
+ {
+ // Drain all stout and stderr so we don't see any output come after
+ // we print our prompts
+ GetProcessSTDOUT ();
+ GetProcessSTDERR ();
+ // Something changed in the process; get the event and report the process's current status and location to
+ // the user.
+ StateType event_state = SBProcess::GetStateFromEvent (event);
+ if (event_state == eStateInvalid)
+ return;
+
+ SBProcess process (SBProcess::GetProcessFromEvent (event));
+ assert (process.IsValid());
+
+ switch (event_state)
+ {
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateStepping:
+ case eStateDetached:
+ {
+ char message[1024];
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(),
+ m_debugger.StateAsCString (event_state));
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ break;
+
+ case eStateRunning:
+ // Don't be chatty when we run...
+ break;
+
+ case eStateExited:
+ {
+ SBCommandReturnObject result;
+ m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
+ m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
+ m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
+ }
+ break;
- if (thread.IsValid())
- process.SetSelectedThread (thread);
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ // Make sure the program hasn't been auto-restarted:
+ if (SBProcess::GetRestartedFromEvent (event))
+ {
+ size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
+ if (num_reasons > 0)
+ {
+ // FIXME: Do we want to report this, or would that just be annoyingly chatty?
+ if (num_reasons == 1)
+ {
+ char message[1024];
+ const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
+ process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ else
+ {
+ char message[1024];
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
+ process.GetProcessID());
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ for (size_t i = 0; i < num_reasons; i++)
+ {
+ const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
+ int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (GetDebugger().GetSelectedTarget() == process.GetTarget())
+ {
+ SBCommandReturnObject result;
+ UpdateSelectedThread ();
+ m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
+ m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
+ m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
+ }
+ else
+ {
+ SBStream out_stream;
+ uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
+ if (target_idx != UINT32_MAX)
+ out_stream.Printf ("Target %d: (", target_idx);
+ else
+ out_stream.Printf ("Target <unknown index>: (");
+ process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
+ out_stream.Printf (") stopped.\n");
+ m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
+ }
+ }
+ break;
}
}
}
+
void
Driver::HandleThreadEvent (const SBEvent &event)
{
@@ -215,36 +1052,304 @@ Driver::HandleThreadEvent (const SBEvent
}
}
+// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
-void LogOutput(const char * msg, void *baton)
+bool
+Driver::HandleIOEvent (const SBEvent &event)
{
- puts(msg);
+ bool quit = false;
+
+ const uint32_t event_type = event.GetType();
+
+ if (event_type & IOChannel::eBroadcastBitHasUserInput)
+ {
+ // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
+ // handling.
+
+ const char *command_string = SBEvent::GetCStringFromEvent(event);
+ if (command_string == NULL)
+ command_string = "";
+ SBCommandReturnObject result;
+
+ // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
+ // output orderings and problems with the prompt.
+ m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
+
+ const bool only_if_no_immediate = true;
+
+ const size_t output_size = result.GetOutputSize();
+
+ if (output_size > 0)
+ m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
+
+ const size_t error_size = result.GetErrorSize();
+
+ if (error_size > 0)
+ m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
+
+ // We are done getting and running our command, we can now clear the
+ // m_waiting_for_command so we can get another one.
+ m_waiting_for_command = false;
+
+ // If our editline input reader is active, it means another input reader
+ // got pushed onto the input reader and caused us to become deactivated.
+ // When the input reader above us gets popped, we will get re-activated
+ // and our prompt will refresh in our callback
+ if (m_editline_reader.IsActive())
+ {
+ ReadyForCommand ();
+ }
+ }
+ else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
+ {
+ // This is here to handle control-c interrupts from the user. It has not yet really been implemented.
+ // TO BE DONE: PROPERLY HANDLE CONTROL-C FROM USER
+ //m_io_channel_ap->CancelInput();
+ // Anything else? Send Interrupt to process?
+ }
+ else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
+ (event_type & IOChannel::eBroadcastBitThreadDidExit))
+ {
+ // If the IOChannel thread is trying to go away, then it is definitely
+ // time to end the debugging session.
+ quit = true;
+ }
+
+ return quit;
}
-void Driver::Initialize()
+void
+Driver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
{
- m_debugger = SBDebugger::Create(false, LogOutput, 0);
- // We want to be able to handle CTRL+D in the terminal to have it terminate
- // certain input
- m_debugger.SetCloseInputOnEOF (false);
- InitializePseudoTerminal();
-
+ Driver *driver = (Driver*)baton;
+ driver->GetFromMaster ((const char *)src, src_len);
+}
+
+void
+Driver::GetFromMaster (const char *src, size_t src_len)
+{
+ // Echo the characters back to the Debugger's stdout, that way if you
+ // type characters while a command is running, you'll see what you've typed.
+ FILE *out_fh = m_debugger.GetOutputFileHandle();
+ if (out_fh)
+ ::fwrite (src, 1, src_len, out_fh);
+}
+
+size_t
+Driver::EditLineInputReaderCallback
+(
+ void *baton,
+ SBInputReader *reader,
+ InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len
+)
+{
+ Driver *driver = (Driver *)baton;
+
+ switch (notification)
+ {
+ case eInputReaderActivate:
+ break;
+
+ case eInputReaderReactivate:
+ driver->ReadyForCommand();
+ break;
+
+ case eInputReaderDeactivate:
+ break;
+
+ case eInputReaderAsynchronousOutputWritten:
+ if (driver->m_io_channel_ap.get() != NULL)
+ driver->m_io_channel_ap->RefreshPrompt();
+ break;
+
+ case eInputReaderInterrupt:
+ if (driver->m_io_channel_ap.get() != NULL)
+ {
+ SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
+ if (!driver->m_io_channel_ap->EditLineHasCharacters()
+ && process.IsValid()
+ && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
+ {
+ process.SendAsyncInterrupt ();
+ }
+ else
+ {
+ driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
+ // I wish I could erase the entire input line, but there's no public API for that.
+ driver->m_io_channel_ap->EraseCharsBeforeCursor();
+ driver->m_io_channel_ap->RefreshPrompt();
+ }
+ }
+ break;
+
+ case eInputReaderEndOfFile:
+ if (driver->m_io_channel_ap.get() != NULL)
+ {
+ driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
+ driver->m_io_channel_ap->RefreshPrompt ();
+ }
+ write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
+ break;
+
+ case eInputReaderGotToken:
+ write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
+ break;
+
+ case eInputReaderDone:
+ break;
+ }
+ return bytes_len;
+}
+
+void
+Driver::MainLoop ()
+{
+ char error_str[1024];
+ if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
+ {
+ ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
+ exit(1);
+ }
+ else
+ {
+ const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
+ if (driver_slave_name == NULL)
+ {
+ ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
+ exit(2);
+ }
+ else
+ {
+ m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
+ if (m_editline_slave_fh == NULL)
+ {
+ SBError error;
+ error.SetErrorToErrno();
+ ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
+ error.GetCString());
+ exit(3);
+ }
+
+ ::setbuf (m_editline_slave_fh, NULL);
+ }
+ }
+
+ lldb_utility::PseudoTerminal editline_output_pty;
+ FILE *editline_output_slave_fh = NULL;
+
+ if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
+ {
+ ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
+ exit(1);
+ }
+ else
+ {
+ const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
+ if (output_slave_name == NULL)
+ {
+ ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
+ exit(2);
+ }
+ else
+ {
+ editline_output_slave_fh = ::fopen (output_slave_name, "r+");
+ if (editline_output_slave_fh == NULL)
+ {
+ SBError error;
+ error.SetErrorToErrno();
+ ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
+ error.GetCString());
+ exit(3);
+ }
+ ::setbuf (editline_output_slave_fh, NULL);
+ }
+ }
+
+ // struct termios stdin_termios;
+
+ if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
+ {
+ g_old_stdin_termios_is_valid = true;
+ atexit (reset_stdin_termios);
+ }
+
+ ::setbuf (stdin, NULL);
+ ::setbuf (stdout, NULL);
m_debugger.SetErrorFileHandle (stderr, false);
m_debugger.SetOutputFileHandle (stdout, false);
m_debugger.SetInputFileHandle (stdin, true);
-
+
m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
- InitializeEditLineIO();
+ // You have to drain anything that comes to the master side of the PTY. master_out_comm is
+ // for that purpose. The reason you need to do this is a curious reason... editline will echo
+ // characters to the PTY when it gets characters while el_gets is not running, and then when
+ // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
+ // if there are unconsumed characters in the out buffer.
+ // However, you don't need to do anything with the characters, since editline will dump these
+ // unconsumed characters after printing the prompt again in el_gets.
+
+ SBCommunication master_out_comm("driver.editline");
+ master_out_comm.SetCloseOnEOF (false);
+ master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
+ master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
+
+ if (master_out_comm.ReadThreadStart () == false)
+ {
+ ::fprintf (stderr, "error: failed to start master out read thread");
+ exit(5);
+ }
-
SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
- m_interpreter = &sb_interpreter;
+
+ m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
+
+ SBCommunication out_comm_2("driver.editline_output");
+ out_comm_2.SetCloseOnEOF (false);
+ out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
+ out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
+
+ if (out_comm_2.ReadThreadStart () == false)
+ {
+ ::fprintf (stderr, "error: failed to start libedit output read thread");
+ exit (5);
+ }
+
+
+ struct winsize window_size;
+ if (isatty (STDIN_FILENO)
+ && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
+ {
+ if (window_size.ws_col > 0)
+ m_debugger.SetTerminalWidth (window_size.ws_col);
+ }
+
+ // Since input can be redirected by the debugger, we must insert our editline
+ // input reader in the queue so we know when our reader should be active
+ // and so we can receive bytes only when we are supposed to.
+ SBError err (m_editline_reader.Initialize (m_debugger,
+ Driver::EditLineInputReaderCallback, // callback
+ this, // baton
+ eInputReaderGranularityByte, // token_size
+ NULL, // end token - NULL means never done
+ NULL, // prompt - taken care of elsewhere
+ false)); // echo input - don't need Debugger
+ // to do this, we handle it elsewhere
+
+ if (err.Fail())
+ {
+ ::fprintf (stderr, "error: %s", err.GetCString());
+ exit (6);
+ }
+
+ m_debugger.PushInputReader (m_editline_reader);
SBListener listener(m_debugger.GetListener());
- if (!listener.IsValid())
- return;
+ if (listener.IsValid())
+ {
listener.StartListeningForEventClass(m_debugger,
SBTarget::GetBroadcasterClassName(),
@@ -253,98 +1358,250 @@ void Driver::Initialize()
SBThread::GetBroadcasterClassName(),
SBThread::eBroadcastBitStackChanged |
SBThread::eBroadcastBitThreadSelected);
- listener.StartListeningForEvents (*m_io_channel_ap,
- IOChannel::eBroadcastBitHasUserInput |
- IOChannel::eBroadcastBitUserInterrupt |
- IOChannel::eBroadcastBitThreadShouldExit |
- IOChannel::eBroadcastBitThreadDidStart |
- IOChannel::eBroadcastBitThreadDidExit);
+ listener.StartListeningForEvents (*m_io_channel_ap,
+ IOChannel::eBroadcastBitHasUserInput |
+ IOChannel::eBroadcastBitUserInterrupt |
+ IOChannel::eBroadcastBitThreadShouldExit |
+ IOChannel::eBroadcastBitThreadDidStart |
+ IOChannel::eBroadcastBitThreadDidExit);
- if (!m_io_channel_ap->Start ())
- return;
-
- iochannel_thread_exited = false;
-
- listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
- SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
- SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
- SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
+ if (m_io_channel_ap->Start ())
+ {
+ bool iochannel_thread_exited = false;
- // Before we handle any options from the command line, we parse the
- // .lldbinit file in the user's home directory.
- SBCommandReturnObject result;
- sb_interpreter.SourceInitFileInHomeDirectory(result);
+ listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
+ SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
+ SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
+ SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+ // Before we handle any options from the command line, we parse the
+ // .lldbinit file in the user's home directory.
+ SBCommandReturnObject result;
+ sb_interpreter.SourceInitFileInHomeDirectory(result);
+ if (GetDebugMode())
+ {
+ result.PutError (m_debugger.GetErrorFileHandle());
+ result.PutOutput (m_debugger.GetOutputFileHandle());
+ }
- if (GetDebugMode())
- {
- result.PutError (m_debugger.GetErrorFileHandle());
- result.PutOutput (m_debugger.GetOutputFileHandle());
- }
- HandleCommandLine(result);
+ // Now we handle options we got from the command line
+ char command_string[PATH_MAX * 2];
+ const size_t num_source_command_files = GetNumSourceCommandFiles();
+ const bool dump_stream_only_if_no_immediate = true;
+ if (num_source_command_files > 0)
+ {
+ for (size_t i=0; i < num_source_command_files; ++i)
+ {
+ const char *command_file = GetSourceCommandFileAtIndex(i);
+ ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
+ m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
+ if (GetDebugMode())
+ {
+ result.PutError (m_debugger.GetErrorFileHandle());
+ result.PutOutput (m_debugger.GetOutputFileHandle());
+ }
+
+ // if the command sourcing generated an error - dump the result object
+ if (result.Succeeded() == false)
+ {
+ const size_t output_size = result.GetOutputSize();
+ if (output_size > 0)
+ m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC);
+ const size_t error_size = result.GetErrorSize();
+ if (error_size > 0)
+ m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC);
+ }
+
+ result.Clear();
+ }
+ }
- // Now that all option parsing is done, we try and parse the .lldbinit
- // file in the current working directory
- sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
- if (GetDebugMode())
- {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
- }
- SBEvent event;
- // Make sure the IO channel is started up before we try to tell it we
- // are ready for input
- listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
- *m_io_channel_ap,
- IOChannel::eBroadcastBitThreadDidStart,
- event);
-
- // If we were asked to attach, then do that here:
- // I'm going to use the command string rather than directly
- // calling the API's because then I don't have to recode the
- // event handling here.
- if (!m_option_data.m_process_name.empty()
- || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
- {
- AttachToProcess();
- }
-
- ReadyForCommand ();
-}
+ // Was there a core file specified?
+ std::string core_file_spec("");
+ if (!m_option_data.m_core_file.empty())
+ core_file_spec.append("--core ").append(m_option_data.m_core_file);
+
+ const size_t num_args = m_option_data.m_args.size();
+ if (num_args > 0)
+ {
+ char arch_name[64];
+ if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
+ ::snprintf (command_string,
+ sizeof (command_string),
+ "target create --arch=%s %s \"%s\"",
+ arch_name,
+ core_file_spec.c_str(),
+ m_option_data.m_args[0].c_str());
+ else
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "target create %s \"%s\"",
+ core_file_spec.c_str(),
+ m_option_data.m_args[0].c_str());
+
+ m_debugger.HandleCommand (command_string);
+
+ if (num_args > 1)
+ {
+ m_debugger.HandleCommand ("settings clear target.run-args");
+ char arg_cstr[1024];
+ for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
+ {
+ ::snprintf (arg_cstr,
+ sizeof(arg_cstr),
+ "settings append target.run-args \"%s\"",
+ m_option_data.m_args[arg_idx].c_str());
+ m_debugger.HandleCommand (arg_cstr);
+ }
+ }
+ }
+ else if (!core_file_spec.empty())
+ {
+ ::snprintf (command_string,
+ sizeof(command_string),
+ "target create %s",
+ core_file_spec.c_str());
+ m_debugger.HandleCommand (command_string);;
+ }
-void
-Driver::MainLoop ()
-{
- SBEvent event;
- while (!GetIsDone())
- {
- m_listener->WaitForEvent (UINT32_MAX, event);
- if (event.IsValid())
- {
- ProcessEvent(event);
+ // Now that all option parsing is done, we try and parse the .lldbinit
+ // file in the current working directory
+ sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
+ if (GetDebugMode())
+ {
+ result.PutError(m_debugger.GetErrorFileHandle());
+ result.PutOutput(m_debugger.GetOutputFileHandle());
+ }
+
+ SBEvent event;
+
+ // Make sure the IO channel is started up before we try to tell it we
+ // are ready for input
+ listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
+ *m_io_channel_ap,
+ IOChannel::eBroadcastBitThreadDidStart,
+ event);
+ // If we were asked to attach, then do that here:
+ // I'm going to use the command string rather than directly
+ // calling the API's because then I don't have to recode the
+ // event handling here.
+ if (!m_option_data.m_process_name.empty()
+ || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
+ {
+ std::string command_str("process attach ");
+ if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
+ {
+ command_str.append("-p ");
+ char pid_buffer[32];
+ ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid);
+ command_str.append(pid_buffer);
+ }
+ else
+ {
+ command_str.append("-n \"");
+ command_str.append(m_option_data.m_process_name);
+ command_str.push_back('\"');
+ if (m_option_data.m_wait_for)
+ command_str.append(" -w");
+ }
+
+ if (m_debugger.GetOutputFileHandle())
+ ::fprintf (m_debugger.GetOutputFileHandle(),
+ "Attaching to process with:\n %s\n",
+ command_str.c_str());
+
+ // Force the attach to be synchronous:
+ bool orig_async = m_debugger.GetAsync();
+ m_debugger.SetAsync(true);
+ m_debugger.HandleCommand(command_str.c_str());
+ m_debugger.SetAsync(orig_async);
+ }
+
+ ReadyForCommand ();
+
+ while (!GetIsDone())
+ {
+ listener.WaitForEvent (UINT32_MAX, event);
+ if (event.IsValid())
+ {
+ if (event.GetBroadcaster().IsValid())
+ {
+ uint32_t event_type = event.GetType();
+ if (event.BroadcasterMatchesRef (*m_io_channel_ap))
+ {
+ if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
+ (event_type & IOChannel::eBroadcastBitThreadDidExit))
+ {
+ SetIsDone();
+ if (event_type & IOChannel::eBroadcastBitThreadDidExit)
+ iochannel_thread_exited = true;
+ }
+ else
+ {
+ if (HandleIOEvent (event))
+ SetIsDone();
+ }
+ }
+ else if (SBProcess::EventIsProcessEvent (event))
+ {
+ HandleProcessEvent (event);
+ }
+ else if (SBBreakpoint::EventIsBreakpointEvent (event))
+ {
+ HandleBreakpointEvent (event);
}
else if (SBThread::EventIsThreadEvent (event))
{
HandleThreadEvent (event);
+ }
+ else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
+ {
+ // TODO: deprecate the eBroadcastBitQuitCommandReceived event
+ // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
+ // that can take over a command
+ if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
+ {
+ SetIsDone();
+ }
+ else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
+ {
+ const char *data = SBEvent::GetCStringFromEvent (event);
+ m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
+ }
+ else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
+ {
+ const char *data = SBEvent::GetCStringFromEvent (event);
+ m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
+ }
+ }
+ }
+ }
+ }
+
+ editline_output_pty.CloseMasterFileDescriptor();
+ master_out_comm.Disconnect();
+ out_comm_2.Disconnect();
+ reset_stdin_termios();
+ fclose (stdin);
+
+ CloseIOChannelFile ();
+
+ if (!iochannel_thread_exited)
+ {
+ event.Clear();
+ listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
+ IOChannel::eBroadcastBitThreadDidExit,
+ event);
+ if (!event.IsValid())
+ {
+ // Send end EOF to the driver file descriptor
+ m_io_channel_ap->Stop();
+ }
+ }
+
+ SBDebugger::Destroy (m_debugger);
}
}
-
-
- DestroyPseudoTerminal();
- CloseIOChannelFile ();
-
- if (!iochannel_thread_exited)
- {
- event.Clear();
- m_listener->GetNextEventForBroadcasterWithType (*m_io_channel_ap,
- IOChannel::eBroadcastBitThreadDidExit,
- event);
- if (!event.IsValid())
- {
- // Send end EOF to the driver file descriptor
- m_io_channel_ap->Stop();
- }
- }
- SBDebugger::Destroy (m_debugger);
}
@@ -358,30 +1615,86 @@ Driver::ReadyForCommand ()
}
}
-// defined in DriverPosix.cpp
-void SetupPosixSignals();
+void
+Driver::ResizeWindow (unsigned short col)
+{
+ GetDebugger().SetTerminalWidth (col);
+ if (m_io_channel_ap.get() != NULL)
+ {
+ m_io_channel_ap->ElResize();
+ }
+}
+
+void
+sigwinch_handler (int signo)
+{
+ struct winsize window_size;
+ if (isatty (STDIN_FILENO)
+ && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
+ {
+ if ((window_size.ws_col > 0) && g_driver != NULL)
+ {
+ g_driver->ResizeWindow (window_size.ws_col);
+ }
+ }
+}
+
+void
+sigint_handler (int signo)
+{
+ static bool g_interrupt_sent = false;
+ if (g_driver)
+ {
+ if (!g_interrupt_sent)
+ {
+ g_interrupt_sent = true;
+ g_driver->GetDebugger().DispatchInputInterrupt();
+ g_interrupt_sent = false;
+ return;
+ }
+ }
+
+ exit (signo);
+}
+
+void
+sigtstp_handler (int signo)
+{
+ g_driver->GetDebugger().SaveInputTerminalState();
+ signal (signo, SIG_DFL);
+ kill (getpid(), signo);
+ signal (signo, sigtstp_handler);
+}
+
+void
+sigcont_handler (int signo)
+{
+ g_driver->GetDebugger().RestoreInputTerminalState();
+ signal (signo, SIG_DFL);
+ kill (getpid(), signo);
+ signal (signo, sigcont_handler);
+}
int
main (int argc, char const *argv[], const char *envp[])
{
-#if 1 // Enable for debug logging
- lldb::StreamSP logStream(new lldb_private::StreamCallback(LogOutput, 0));
- const char* logCategories[] = { 0 };
- lldb::LogSP log = lldb_private::EnableLog(logStream, 0, logCategories, 0);
- log->GetMask().Reset(LIBLLDB_LOG_ALL);
-#endif
SBDebugger::Initialize();
SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
- SetupPosixSignals();
+ signal (SIGPIPE, SIG_IGN);
+ signal (SIGWINCH, sigwinch_handler);
+ signal (SIGINT, sigint_handler);
+ signal (SIGTSTP, sigtstp_handler);
+ signal (SIGCONT, sigcont_handler);
+
// Create a scope for driver so that the driver object will destroy itself
// before SBDebugger::Terminate() is called.
{
Driver driver;
bool exit = false;
- SBError error = driver.ParseArgs (argc, argv, stdout, exit);
+ SBError error (driver.ParseArgs (argc, argv, stdout, exit));
if (error.Fail())
{
const char *error_cstr = error.GetCString ();
@@ -390,7 +1703,7 @@ main (int argc, char const *argv[], cons
}
else if (!exit)
{
- driver.Initialize();
+ driver.MainLoop ();
}
}
Modified: lldb/branches/windows/tools/driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/Driver.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/Driver.h (original)
+++ lldb/branches/windows/tools/driver/Driver.h Wed Apr 17 03:38:48 2013
@@ -10,6 +10,8 @@
#ifndef lldb_Driver_h_
#define lldb_Driver_h_
+#include "lldb/Utility/PseudoTerminal.h"
+
#include <set>
#include <bitset>
#include <string>
@@ -20,10 +22,6 @@
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBInputReader.h"
-#include "lldb/API/SBEvent.h"
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include "lldb/Utility/PseudoTerminal.h"
#define ASYNC true
#define NO_ASYNC false
@@ -35,6 +33,7 @@ namespace lldb
class SBInputReader;
}
+
class Driver : public lldb::SBBroadcaster
{
public:
@@ -49,9 +48,6 @@ public:
~Driver ();
void
- Initialize();
-
- void
MainLoop ();
void
@@ -155,12 +151,12 @@ public:
{
m_done = true;
}
+
+ void
+ ResizeWindow (unsigned short col);
private:
lldb::SBDebugger m_debugger;
- lldb::SBCommandInterpreter* m_interpreter;
- lldb::SBListener* m_listener;
-
lldb_utility::PseudoTerminal m_editline_pty;
FILE *m_editline_slave_fh;
lldb::SBInputReader m_editline_reader;
@@ -169,8 +165,6 @@ private:
bool m_waiting_for_command;
bool m_done;
- bool iochannel_thread_exited;
-
void
ResetOptionValues ();
@@ -186,24 +180,6 @@ private:
void
CloseIOChannelFile ();
- void
- InitializePseudoTerminal();
-
- void
- DestroyPseudoTerminal();
-
- void
- InitializeEditLineIO();
-
- void
- ProcessEvent(lldb::SBEvent& event);
-
- void
- AttachToProcess();
-
- void
- HandleCommandLine(lldb::SBCommandReturnObject& result);
-
static size_t
EditLineInputReaderCallback (void *baton,
lldb::SBInputReader *reader,
Modified: lldb/branches/windows/tools/driver/IOChannel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/IOChannel.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/IOChannel.cpp (original)
+++ lldb/branches/windows/tools/driver/IOChannel.cpp Wed Apr 17 03:38:48 2013
@@ -23,17 +23,6 @@
#include <string.h>
#include <limits.h>
-#ifdef _WIN32
-enum
-{
- CC_ERROR,
- CC_REDISPLAY,
- CC_REFRESH_BEEP,
-};
-#endif
-
-
-
using namespace lldb;
typedef std::map<EditLine *, std::string> PromptMap;
@@ -64,7 +53,6 @@ IOChannel::GetPrompt ()
bool
IOChannel::EditLineHasCharacters ()
{
-#ifdef __unix__
const LineInfo *line_info = el_line(m_edit_line);
if (line_info)
{
@@ -77,41 +65,42 @@ IOChannel::EditLineHasCharacters ()
return line_info->cursor != line_info->buffer;
}
else
-#endif
- return false;
+ return false;
}
void
IOChannel::EraseCharsBeforeCursor ()
{
-#ifdef __unix__
const LineInfo *line_info = el_line(m_edit_line);
el_deletestr(m_edit_line, line_info->cursor - line_info->buffer);
-#endif
}
unsigned char
IOChannel::ElCompletionFn (EditLine *e, int ch)
{
-#ifdef __unix__
IOChannel *io_channel;
if (el_get(e, EL_CLIENTDATA, &io_channel) == 0)
{
return io_channel->HandleCompletion (e, ch);
}
else
-#endif
{
return CC_ERROR;
}
}
+void
+IOChannel::ElResize()
+{
+ el_resize(m_edit_line);
+}
+
unsigned char
IOChannel::HandleCompletion (EditLine *e, int ch)
{
assert (e == m_edit_line);
-#ifdef __unix__
+
const LineInfo *line_info = el_line(m_edit_line);
SBStringList completions;
int page_size = 40;
@@ -197,8 +186,7 @@ IOChannel::HandleCompletion (EditLine *e
if (num_completions == 0)
return CC_REFRESH_BEEP;
else
-#endif
- return CC_REDISPLAY;
+ return CC_REDISPLAY;
}
IOChannel::IOChannel
@@ -219,17 +207,14 @@ IOChannel::IOChannel
m_err_file (err),
m_command_queue (),
m_completion_key ("\t"),
-#ifdef __unix__
m_edit_line (::el_init (SBHostOS::GetProgramFileSpec().GetFilename(), editline_in, editline_out, editline_out)),
m_history (history_init()),
-#endif
m_history_event(),
m_getting_command (false),
m_expecting_prompt (false),
m_prompt_str (),
m_refresh_request_pending (false)
{
-#ifdef __unix__
assert (m_edit_line);
::el_set (m_edit_line, EL_PROMPT, el_prompt);
::el_set (m_edit_line, EL_EDITOR, "emacs");
@@ -268,7 +253,7 @@ IOChannel::IOChannel
assert (error == 0);
// Initialize time that ::el_gets was last called.
-#endif
+
m_enter_elgets_time.tv_sec = 0;
m_enter_elgets_time.tv_usec = 0;
}
@@ -278,7 +263,6 @@ IOChannel::~IOChannel ()
// Save history
HistorySaveLoad (true);
-#ifdef __unix__
if (m_history != NULL)
{
::history_end (m_history);
@@ -292,7 +276,6 @@ IOChannel::~IOChannel ()
}
::pthread_mutex_destroy (&m_output_mutex);
-#endif
}
void
@@ -300,7 +283,6 @@ IOChannel::HistorySaveLoad (bool save)
{
if (m_history != NULL)
{
-#ifdef __unix__
char history_path[PATH_MAX];
::snprintf (history_path, sizeof(history_path), "~/.%s-history", SBHostOS::GetProgramFileSpec().GetFilename());
if ((size_t)SBFileSpec::ResolvePath (history_path, history_path, sizeof(history_path)) < sizeof(history_path) - 1)
@@ -311,8 +293,7 @@ IOChannel::HistorySaveLoad (bool save)
else
::history (m_history, &m_history_event, H_LOAD, path_ptr);
}
-#endif
- }
+ }
}
void
@@ -351,8 +332,7 @@ IOChannel::LibeditOutputBytesReceived (v
bool
IOChannel::LibeditGetInput (std::string &new_line)
{
- #ifdef __unix__
- if (m_edit_line != NULL)
+ if (m_edit_line != NULL)
{
int line_len = 0;
@@ -386,15 +366,13 @@ IOChannel::LibeditGetInput (std::string
return true;
}
}
-#endif
// Return false to indicate failure. This can happen when the file handle
// is closed (EOF).
new_line.clear();
return false;
-
}
-thread_result_t
+void *
IOChannel::IOReadThread (void *ptr)
{
IOChannel *myself = static_cast<IOChannel *> (ptr);
@@ -548,9 +526,8 @@ IOChannel::RefreshPrompt ()
if (m_refresh_request_pending)
return;
-#ifdef __unix__
+
::el_set (m_edit_line, EL_REFRESH);
-#endif
m_refresh_request_pending = true;
}
@@ -640,14 +617,16 @@ IOChannel::SetGettingCommand (bool new_v
m_getting_command = new_value;
}
-IOLocker::IOLocker (llvm::sys::Mutex &mutex) :
+IOLocker::IOLocker (pthread_mutex_t &mutex) :
m_mutex_ptr (&mutex)
{
- mutex.acquire();
+ if (m_mutex_ptr)
+ ::pthread_mutex_lock (m_mutex_ptr);
}
IOLocker::~IOLocker ()
{
- m_mutex_ptr->release();
+ if (m_mutex_ptr)
+ ::pthread_mutex_unlock (m_mutex_ptr);
}
Modified: lldb/branches/windows/tools/driver/IOChannel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/IOChannel.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/IOChannel.h (original)
+++ lldb/branches/windows/tools/driver/IOChannel.h Wed Apr 17 03:38:48 2013
@@ -16,29 +16,11 @@
#if defined(__FreeBSD__)
#include <readline/readline.h>
#else
-#ifndef _WIN32
#include <editline/readline.h>
#endif
-#endif
-
-#ifndef _WIN32
#include <histedit.h>
-#else
-struct EditLine;
-struct History;
-struct HistEvent {};
-#include <Winsock2.h>
-#undef GetUserName
-#endif
-
-#include "llvm/Support/Mutex.h"
-
-#ifdef _POSIX_SOURCE
#include <pthread.h>
#include <sys/time.h>
-#else
-#include <ctime>
-#endif
#include "Driver.h"
@@ -72,7 +54,7 @@ public:
bool
Stop ();
- static lldb::thread_result_t
+ static void *
IOReadThread (void *);
void
@@ -122,6 +104,9 @@ public:
static unsigned char
ElCompletionFn (EditLine *e, int ch);
+
+ void
+ ElResize();
protected:
@@ -133,7 +118,7 @@ protected:
private:
- llvm::sys::Mutex m_output_mutex;
+ pthread_mutex_t m_output_mutex;
struct timeval m_enter_elgets_time;
Driver *m_driver;
@@ -149,7 +134,7 @@ private:
HistEvent m_history_event;
bool m_getting_command;
bool m_expecting_prompt;
- std::string m_prompt_str; // for accumlating the prompt as it gets written out by editline
+ std::string m_prompt_str; // for accumlating the prompt as it gets written out by editline
bool m_refresh_request_pending;
void
@@ -163,13 +148,13 @@ class IOLocker
{
public:
- IOLocker (llvm::sys::Mutex &mutex);
+ IOLocker (pthread_mutex_t &mutex);
~IOLocker ();
protected:
- llvm::sys::Mutex *m_mutex_ptr;
+ pthread_mutex_t *m_mutex_ptr;
private:
Modified: lldb/branches/windows/tools/install-headers/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/install-headers/Makefile?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/install-headers/Makefile (original)
+++ lldb/branches/windows/tools/install-headers/Makefile Wed Apr 17 03:38:48 2013
@@ -7,7 +7,9 @@ install:
clean:
echo "clean (doing nothing)"
-TRUNCATED_VERSION = $(shell echo $(CURRENT_PROJECT_VERSION) | /usr/bin/sed -E "s/^([0-9]+)(\.[0-9]+)?$$/\1/g")
+LLDB_VERSION=`echo ${CURRENT_PROJECT_VERSION} | /usr/bin/sed -E 's/^([0-9]+).([0-9]+).([0-9]+)(.[0-9]+)?$/\1/g'`
+LLDB_REVISION=`echo ${CURRENT_PROJECT_VERSION} | /usr/bin/sed -E 's/^([0-9]+).([0-9]+).([0-9]+)(.[0-9]+)?$/\3/g'`
+LLDB_VERSION_STRING=`echo ${CURRENT_PROJECT_VERSION}`
installhdrs:
cd "${TARGET_BUILD_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Headers" ;\
@@ -15,5 +17,7 @@ installhdrs:
do \
/usr/bin/sed -i '' 's/\(#include\)[ ]*"lldb\/\(API\/\)\{0,1\}\(.*\)"/\1 <LLDB\/\3>/1' "$$file" ;\
/usr/bin/sed -i '' 's|<LLDB/Utility|<LLDB|' "$$file" ;\
- /usr/bin/sed -i '' "s|//#define LLDB_VERSION|#define LLDB_VERSION $(TRUNCATED_VERSION) |" "$$file" ;\
+ /usr/bin/sed -i '' "s|//#define LLDB_VERSION$|#define LLDB_VERSION $(LLDB_VERSION) |" "$$file" ;\
+ /usr/bin/sed -i '' "s|//#define LLDB_REVISION|#define LLDB_REVISION $(LLDB_REVISION) |" "$$file" ;\
+ /usr/bin/sed -i '' "s|//#define LLDB_VERSION_STRING|#define LLDB_VERSION_STRING \"$(LLDB_VERSION_STRING)\" |" "$$file" ;\
done
Modified: lldb/branches/windows/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/lldb-platform/lldb-platform.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/branches/windows/tools/lldb-platform/lldb-platform.cpp Wed Apr 17 03:38:48 2013
@@ -32,7 +32,7 @@ using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
-// option descriptors for getopt_long()
+// option descriptors for getopt_long_only()
//----------------------------------------------------------------------
int g_debug = 0;
@@ -117,7 +117,7 @@ main (int argc, char *argv[])
// return 3;
// }
- while ((ch = getopt_long(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
+ while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
{
// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
// ch, (uint8_t)ch,
@@ -177,7 +177,7 @@ main (int argc, char *argv[])
ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get());
}
- // Skip any options we consumed with getopt_long
+ // Skip any options we consumed with getopt_long_only
argc -= optind;
argv += optind;
Modified: lldb/branches/windows/www/architecture.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/architecture.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/architecture.html (original)
+++ lldb/branches/windows/www/architecture.html Wed Apr 17 03:38:48 2013
@@ -36,6 +36,7 @@
<li><a href="#breakpoint">Breakpoint</a></li>
<li><a href="#commands">Commands</a></li>
<li><a href="#core">Core</a></li>
+ <li><a href="#dataformatters">DataFormatters</a></li>
<li><a href="#expression">Expression</a></li>
<li><a href="#host">Host</a></li>
<li><a href="#interpreter">Interpreter</a></li>
@@ -143,6 +144,23 @@
</div>
<div class="postfooter"></div>
</div>
+ <a name="dataformatters"></a>
+ <div class="post">
+ <h1 class ="postheader">DataFormatters</h1>
+ <div class="postcontent">
+
+ <p>A collection of classes that implement the data formatters subsystem.</p>
+ <p>The main entry point for interacting with the LLDB data formatters is the DataVisualization class. It provides
+ a relatively stable front-end interface to ask questions of the data formatters regardless of the internal implementation.</p>
+ <p>For people actively maintaining the data formatters subsystem itself, however, the FormatManager class is the relevant point of entry.
+ This class is subject to more frequent changes as the formatters evolve. Currently, it provides a thin caching layer on top of a list of categories
+ that each export a group of formatters.
+ </p>
+ <p>From an end-user perspective, the "type" LLDB command is the point of access to the data formatters. A large group of generally-useful formatters
+ is provided by default and loaded upon debugger startup.
+ </div>
+ <div class="postfooter"></div>
+ </div>
<a name="expression"></a>
<div class="post">
<h1 class ="postheader">Expression</h1>
Modified: lldb/branches/windows/www/build.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/build.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/build.html (original)
+++ lldb/branches/windows/www/build.html Wed Apr 17 03:38:48 2013
@@ -17,6 +17,16 @@
<!--#include virtual="sidebar.incl"-->
<div id="middle">
+ <h1 class ="postheader">Continuous Integraton</h1>
+ <div class="postcontent">
+ <p> The following LLVM buildbots build and test LLDB trunk:
+ <ul>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-debian-clang">LLDB Linux x86_64 build with Clang (automake)</a>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-linux">LLDB Linux x86_64 build with GCC 4.6 (automake)</a>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-darwin11">LLDB Mac OS X x86_64 build with Clang (XCode)</a>
+ </ul>
+ </div>
+ <div class="postfooter"></div>
<div class="post">
<h1 class ="postheader">Building LLDB on Mac OS X</h1>
<div class="postcontent">
@@ -108,21 +118,50 @@
<br>> mkdir build
<br>> cd build
</code>
- <p>If you are using clang:</p>
+ <h2>To build with CMake</h2>
+ <p>Using CMake is documented on the <a href="http://llvm.org/docs/CMake.html">Building LLVM with CMake</a>
+ page. Building LLDB is possible using one of the following generators:
+ </p>
+ <ul>
+ <li> Ninja </li>
+ <li> Unix Makefiles </li>
+ </ul>
+ <h3>Using CMake + Ninja</h3>
+ <p>Ninja is the fastest way to build LLDB! In order to use ninja, you need to have recent versions of CMake and
+ ninja on your system. To build using ninja:
+ </p>
+ <code>
+ <br>> cmake -C .. -G Ninja
+ <br>> ninja lldb
+ <br>> ninja check-lldb
+ </code>
+ <h3>Using CMake + Unix Makefiles</h3>
+ <p>If you do not have Ninja, you can still use CMake to generate Unix Makefiles that build LLDB:</p>
+ <code>
+ <br>> cmake -C ..
+ <br>> make
+ <br>> make check-lldb
+ </code>
+ <h2>To build with autoconf</h2>
+ <p>If you do not have CMake, it is still possible to build LLDB using the autoconf build system. If you are using
+ Clang or GCC 4.7+, run:</p>
<code>
<br>> $llvm/configure --enable-cxx11
<br>> make </code>
- <p>If you are using GCC 4.6+:</p>
+ <p>Or, if you are using a version of GCC that does not support the <tt>-std=c++11</tt> option:</p>
<code>
<br>> $llvm/configure
<br>> make CXXFLAGS=-std=c++0x</code>
+ <p> To run the LLDB test suite, run:</p>
+ <code>
+ <br>> make -C tools/lldb/test</code>
<p>Note that once both LLVM and Clang have been configured and built it is not
necessary to perform a top-level <tt>make</tt> to rebuild changes made only to LLDB.
You can run <tt>make</tt> from the <tt>build/tools/lldb</tt> subdirectory as well.</p>
- <p> If you wish to build with libc++ instead of libstdc++ (the default), you should run configure with the
+ <p> If you wish to build with libc++ instead of libstdc++ (the default), run configure with the
<tt>--enable-libcpp</tt> flag.</p>
<p> If you wish to build a release version of LLDB, run configure with the <tt>--enable-optimized</tt> flag.</p>
-
+
<h2>Additional Notes</h2>
<p>LLDB has a Python scripting capability and supplies its own Python module named <tt>lldb</tt>.
If a script is run inside the command line <tt>lldb</tt> application, the Python module
Modified: lldb/branches/windows/www/lldb-gdb.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/lldb-gdb.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/lldb-gdb.html (original)
+++ lldb/branches/windows/www/lldb-gdb.html Wed Apr 17 03:38:48 2013
@@ -105,6 +105,7 @@
<td class="content">
<b>(lldb)</b> settings set target.env-vars DEBUG=1<br>
<b>(lldb)</b> set se target.env-vars DEBUG=1<br>
+ <b>(lldb)</b> env DEBUG=1<br>
</td>
</tr>
@@ -241,6 +242,16 @@
</td>
</tr>
+ <tr><td class="header" colspan="2">Return immediately from the currently selected frame, with an optional return value.</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> return <RETURN EXPRESSION><br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> thread return <RETURN EXPRESSION><br>
+ </td>
+ </tr>
+
<tr><td class="header" colspan="2">Backtrace and disassemble every time you stop.</td></tr>
<tr>
<td class="content">
@@ -341,6 +352,18 @@
</td>
</tr>
+ <tr><td class="header" colspan="2">Ensure that breakpoints by file and line work for #included .c/.cpp/.m files.</td></tr>
+
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> b foo.c:12<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> settings set target.inline-breakpoint-strategy always<br>
+ <b>(lldb)</b> br s -f foo.c -l 12<br>
+ </td>
+ </tr>
+
<tr><td class="header" colspan="2">Set a breakpoint by regular expression on source file contents.</td></tr>
<tr>
@@ -656,7 +679,18 @@
<b>(gdb)</b> p function_with_a_breakpoint()<br>
</td>
<td class="content">
- <b>(lldb)</b> expr -u 0 -- function_with_a_breakpoint()<br>
+ <b>(lldb)</b> expr -i 0 -- function_with_a_breakpoint()<br>
+ </td>
+ </tr>
+
+ <tr><td class="header" colspan="2">Calling a function that crashes, and stopping when the function crashes.</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> set unwindonsignal 0<br>
+ <b>(gdb)</b> p function_which_crashes()<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> expr -u 0 -- function_which_crashes()<br>
</td>
</tr>
Modified: lldb/branches/windows/www/python-reference.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/python-reference.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/python-reference.html (original)
+++ lldb/branches/windows/www/python-reference.html Wed Apr 17 03:38:48 2013
@@ -96,15 +96,8 @@ Python Interactive Interpreter. To exit,
<p>This drops you into the embedded python interpreter. When running under the <b>script</b> command,
lldb sets some convenience variables that give you quick access to the currently selected entities that characterize
the program and debugger state. In each case, if there is no currently selected entity of the appropriate
- type, the variable's <b>IsValid</b> method will return false.
- <p>Note also, these variables hold the values
- of the selected objects on entry to the embedded interpreter. They do not update as you use the LLDB
- API's to change, for example, the currently selected stack frame or thread.
- <p>As a corollary to this, because they get reset every time the script interpreter is entered, you should not
- use these variables in general purpose python code that you write using the lldb module. After all, lldb can
- run in a multithreaded environment, and another thread might call the "script" command, changing the value out
- from under you.</p>
- These are all global variables contained in the <b>lldb</b> python namespace :</p>
+ type, the variable's <b>IsValid</b> method will return false. These variables are:</p>
+
<table class="stats" width="620" cellspacing="0">
<tr>
<td class="hed" width="20%">Variable</td>
@@ -164,7 +157,7 @@ Python Interactive Interpreter. To exit,
Contains the currently selected thread.
The <b>lldb.SBThread</b> object manages the stack frames in that thread.
A thread is always selected in the command interpreter when a target stops.
- The <b>thread select <thread-index></b> commmand can be used to change the
+ The <b>thread select <thread-index></b> command can be used to change the
currently selected thread. So as long as you have a stopped process, there will be
some selected thread.
</td>
@@ -181,14 +174,25 @@ Python Interactive Interpreter. To exit,
The <b>lldb.SBFrame</b> object manage the stack locals and the register set for
that stack.
A stack frame is always selected in the command interpreter when a target stops.
- The <b>frame select <frame-index></b> commmand can be used to change the
+ The <b>frame select <frame-index></b> command can be used to change the
currently selected frame. So as long as you have a stopped process, there will
be some selected frame.
</td>
</tr>
</table>
- <p>Once in the embedded interpreter, these objects can be used. To get started, note that almost
+ <p>While extremely convenient, these variables have a couple caveats that you should be aware of.
+ First of all, they hold the values
+ of the selected objects on entry to the embedded interpreter. They do not update as you use the LLDB
+ API's to change, for example, the currently selected stack frame or thread.
+ <p>Moreover, they are only defined and meaningful while in the interactive Python interpreter.
+ There is no guarantee on their value in any other situation, hence you should not use them when defining
+ Python formatters, breakpoint scripts and commands (or any other Python extension point that LLDB provides).
+ As a rationale for such behavior, consider that lldb can
+ run in a multithreaded environment, and another thread might call the "script" command, changing the value out
+ from under you.</p>
+
+ <p>To get started with these objects and LLDB scripting, please note that almost
all of the <b>lldb</b> Python objects are able to briefly describe themselves when you pass them
to the Python <b>print</b> function:
<code><pre><tt>(lldb) <b>script</b>
@@ -364,10 +368,9 @@ Enter your Python command(s). Type 'DONE
<b>lldb.SBCommandReturnObject</b>
</td>
<td class="content">
- A return object where you can indicate the success or failure of your command. You can also
- provide information for the command result by printing data into it. You can also just print
- data as you normally would in a python script and the output will show up; this is useful for
- logging, but the real output for your command should go in the result object.
+ A return object which encapsulates success/failure information for the command and output text
+ that needs to be printed as a result of the command. The plain Python "print" command also works but
+ text won't go in the result by default (it is useful as a temporary logging facility).
</td>
</tr>
<tr>
@@ -383,6 +386,9 @@ Enter your Python command(s). Type 'DONE
</td>
</tr>
</table>
+ <p>As a convenience, you can treat the result object as a Python file object, and say
+ print >>result, "my command does lots of cool stuff". SBCommandReturnObject and SBStream
+ both support this file-like behavior by providing write() and flush() calls at the Python layer.</p>
<p>One other handy convenience when defining lldb command-line commands is the command
<b>command script import</b> which will import a module specified by file path - so you
don't have to change your PYTHONPATH for temporary scripts. It also has another convenience
@@ -513,6 +519,11 @@ $2 = 0x000000010010aba0 Let's Be Friends
<code><pre><tt><font color=green>#!/usr/bin/python</font>
import lldb
+import os
+
+def disassemble_instructions(insts):
+ for i in insts:
+ print i
<font color=green># Set the path to the executable to debug</font>
exe = "./a.out"
@@ -546,30 +557,30 @@ if target:
state = process.GetState ()
print process
if state == lldb.eStateStopped:
- <font color=green># Get the first thread</font>
- thread = process.GetThreadAtIndex (0)
- if thread:
- <font color=green># Print some simple thread info</font>
- print thread
- <font color=green># Get the first frame</font>
- frame = thread.GetFrameAtIndex (0)
- if frame:
- <font color=green># Print some simple frame info</font>
- print frame
- function = frame.GetFunction()
- <font color=green># See if we have debug info (a function)</font>
- if function:
- <font color=green># We do have a function, print some info for the function</font>
- print function
- <font color=green># Now get all instructions for this function and print them</font>
- insts = function.GetInstructions(target)
- disassemble_instructions (insts)
- else:
- <font color=green># See if we have a symbol in the symbol table for where we stopped</font>
- symbol = frame.GetSymbol();
- if symbol:
- <font color=green># We do have a symbol, print some info for the symbol</font>
- print symbol
+ <font color=green># Get the first thread</font>
+ thread = process.GetThreadAtIndex (0)
+ if thread:
+ <font color=green># Print some simple thread info</font>
+ print thread
+ <font color=green># Get the first frame</font>
+ frame = thread.GetFrameAtIndex (0)
+ if frame:
+ <font color=green># Print some simple frame info</font>
+ print frame
+ function = frame.GetFunction()
+ <font color=green># See if we have debug info (a function)</font>
+ if function:
+ <font color=green># We do have a function, print some info for the function</font>
+ print function
+ <font color=green># Now get all instructions for this function and print them</font>
+ insts = function.GetInstructions(target)
+ disassemble_instructions (insts)
+ else:
+ <font color=green># See if we have a symbol in the symbol table for where we stopped</font>
+ symbol = frame.GetSymbol();
+ if symbol:
+ <font color=green># We do have a symbol, print some info for the symbol</font>
+ print symbol
</tt></pre></code>
</div>
<div class="postfooter"></div>
Modified: lldb/branches/windows/www/status.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/status.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/status.html (original)
+++ lldb/branches/windows/www/status.html Wed Apr 17 03:38:48 2013
@@ -64,7 +64,7 @@
<li>module scoping
</ul>
</td>
- <td>OK except on C++ exception (catch/throw)</td>
+ <td>OK</td>
<td>OK</td>
</tr>
<tr>
Modified: lldb/branches/windows/www/tutorial.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/tutorial.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/tutorial.html (original)
+++ lldb/branches/windows/www/tutorial.html Wed Apr 17 03:38:48 2013
@@ -93,6 +93,13 @@
<br>(lldb) breakpoint set -n foo
</code>
+ <p>You can use the --name option multiple times to make a breakpoint on a set of functions as well. This is convenient
+ since it allows you to set commmon conditions or commands without having to specify them multiple times:</p>
+
+ <code>
+ (lldb) breakpoint set --name foo --name bar
+ </code>
+
<p>Setting breakpoints by name is even more specialized in LLDB as you can specify
that you want to set a breakpoint at a function by method name. To set a breakpoint
on all C++ methods named <code>foo</code> you can enter either of:</p>
@@ -117,6 +124,8 @@
<br>(lldb) breakpoint set -s foo.dylib -n foo
</code>
+ <p>The <code>--shlib</code> option can also be repeated to specify several shared libraries.</p>
+
<p>Suggestions on more interesting primitives of this sort are also very welcome.</p>
<p>Just like gdb, the lldb command interpreter does a shortest unique
Modified: lldb/branches/windows/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/varformats.html?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/www/varformats.html (original)
+++ lldb/branches/windows/www/varformats.html Wed Apr 17 03:38:48 2013
@@ -16,8 +16,7 @@
<h1 class="postheader">Variable display</h1>
<div class="postcontent">
- <p>LLDB was recently modified to allow users to define custom
- formatting options for the variables display.</p>
+ <p>LLDB has a data formatters subsystem that allows users to define custom display options for their variables.</p>
<p>Usually, when you type <code>frame variable</code> or
run some <code>expression</code> LLDB will
@@ -1076,8 +1075,7 @@ def function (valobj,internal_dict):<br/
} <br/>
</code> </p>
- <p>Currently, in LLDB <a href="http://llvm.org/svn/llvm-project/lldb/trunk/">top of tree</a>, synthetic children providers are enabled for
- <code>std::vector<T></code>, <code>std::list<T></code> and <code>std::map<K,V></code> both in the version provided by <a href="http://gcc.gnu.org/libstdc++/">libstdcpp</a> and by <a href="http://libcxx.llvm.org/">libcxx</a>.</p>
+ <p>LLDB has synthetic children providers for basic STL classes, both in the version provided by <a href="http://gcc.gnu.org/libstdc++/">libstdcpp</a> and by <a href="http://libcxx.llvm.org/">libcxx</a>. and for basic Cocoa containers (NSArray and NSDictionary).</p>
<p>Synthetic children extend summary strings by enabling a new special variable: <code>${svar</code>.<br/>
This symbol tells LLDB to refer expression paths to the
@@ -1171,17 +1169,16 @@ def function (valobj,internal_dict):<br/
<b>(lldb)</b> frame variable ns_string --dynamic-type no-run-target --show-types
</td>
</table>
- <code>(id, dynamic type: __NSCFString) ns_string = 0x00000001001183d0 @"An NSString saying hello world"<br/>
+ <code>(__NSCFString *) ns_string = 0x00000001001183d0 @"An NSString saying hello world"<br/>
</code>
<p>
Because LLDB uses a detection algorithm that does not need to invoke any functions
on the target process, <code>no-run-target</code> is enough for this to work.
As a final sidenote on this, LLDB is currently able to provide a summary string for <code>NSString</code>
that shows the content of the string, without requiring you to run code on the target
- process. This features requires you to enable the AppKit category (see below for details). The
- Python code for this formatter is at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/CFString.py">
- CFString.py</a> (the script is well commented, but intricate and might not be obvious, lacking
- working experience with Cocoa and the LLDB API).
+ process. This features requires you to enable the AppKit category (see below for details).
+ The first implementation of this feature was a Python script (still available for reference at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/CFString.py">CFString.py</a>).
+ However, this is out of sync with the current implementation of the NSString formatter (which is a C++ function compiled into the LLDB core).
</p>
</div>
</div>
More information about the llvm-branch-commits
mailing list