summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source')
-rw-r--r--lldb/tools/debugserver/source/ARM_DWARF_Registers.h190
-rw-r--r--lldb/tools/debugserver/source/ARM_GCC_Registers.h35
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp12
-rw-r--r--lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp543
-rw-r--r--lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h33
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp33
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h1
-rw-r--r--lldb/tools/debugserver/source/RNBServices.cpp1
-rw-r--r--lldb/tools/debugserver/source/debugserver.cpp2
9 files changed, 674 insertions, 176 deletions
diff --git a/lldb/tools/debugserver/source/ARM_DWARF_Registers.h b/lldb/tools/debugserver/source/ARM_DWARF_Registers.h
new file mode 100644
index 00000000000..c94579d1648
--- /dev/null
+++ b/lldb/tools/debugserver/source/ARM_DWARF_Registers.h
@@ -0,0 +1,190 @@
+//===-- ARM_DWARF_Registers.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM_DWARF_Registers_h_
+#define utility_ARM_DWARF_Registers_h_
+
+enum
+{
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_sp,
+ dwarf_lr,
+ dwarf_pc,
+ dwarf_cpsr,
+
+ dwarf_s0 = 64,
+ dwarf_s1,
+ dwarf_s2,
+ dwarf_s3,
+ dwarf_s4,
+ dwarf_s5,
+ dwarf_s6,
+ dwarf_s7,
+ dwarf_s8,
+ dwarf_s9,
+ dwarf_s10,
+ dwarf_s11,
+ dwarf_s12,
+ dwarf_s13,
+ dwarf_s14,
+ dwarf_s15,
+ dwarf_s16,
+ dwarf_s17,
+ dwarf_s18,
+ dwarf_s19,
+ dwarf_s20,
+ dwarf_s21,
+ dwarf_s22,
+ dwarf_s23,
+ dwarf_s24,
+ dwarf_s25,
+ dwarf_s26,
+ dwarf_s27,
+ dwarf_s28,
+ dwarf_s29,
+ dwarf_s30,
+ dwarf_s31,
+
+ // FPA Registers 0-7
+ dwarf_f0 = 96,
+ dwarf_f1,
+ dwarf_f2,
+ dwarf_f3,
+ dwarf_f4,
+ dwarf_f5,
+ dwarf_f6,
+ dwarf_f7,
+
+ // Intel wireless MMX general purpose registers 0–7
+ dwarf_wCGR0 = 104,
+ dwarf_wCGR1,
+ dwarf_wCGR2,
+ dwarf_wCGR3,
+ dwarf_wCGR4,
+ dwarf_wCGR5,
+ dwarf_wCGR6,
+ dwarf_wCGR7,
+
+ // XScale accumulator register 0–7 (they do overlap with wCGR0 - wCGR7)
+ dwarf_ACC0 = 104,
+ dwarf_ACC1,
+ dwarf_ACC2,
+ dwarf_ACC3,
+ dwarf_ACC4,
+ dwarf_ACC5,
+ dwarf_ACC6,
+ dwarf_ACC7,
+
+ // Intel wireless MMX data registers 0–15
+ dwarf_wR0 = 112,
+ dwarf_wR1,
+ dwarf_wR2,
+ dwarf_wR3,
+ dwarf_wR4,
+ dwarf_wR5,
+ dwarf_wR6,
+ dwarf_wR7,
+ dwarf_wR8,
+ dwarf_wR9,
+ dwarf_wR10,
+ dwarf_wR11,
+ dwarf_wR12,
+ dwarf_wR13,
+ dwarf_wR14,
+ dwarf_wR15,
+
+ dwarf_spsr = 128,
+ dwarf_spsr_fiq,
+ dwarf_spsr_irq,
+ dwarf_spsr_abt,
+ dwarf_spsr_und,
+ dwarf_spsr_svc,
+
+ dwarf_r8_usr = 144,
+ dwarf_r9_usr,
+ dwarf_r10_usr,
+ dwarf_r11_usr,
+ dwarf_r12_usr,
+ dwarf_r13_usr,
+ dwarf_r14_usr,
+ dwarf_r8_fiq,
+ dwarf_r9_fiq,
+ dwarf_r10_fiq,
+ dwarf_r11_fiq,
+ dwarf_r12_fiq,
+ dwarf_r13_fiq,
+ dwarf_r14_fiq,
+ dwarf_r13_irq,
+ dwarf_r14_irq,
+ dwarf_r13_abt,
+ dwarf_r14_abt,
+ dwarf_r13_und,
+ dwarf_r14_und,
+ dwarf_r13_svc,
+ dwarf_r14_svc,
+
+ // Intel wireless MMX control register in co-processor 0–7
+ dwarf_wC0 = 192,
+ dwarf_wC1,
+ dwarf_wC2,
+ dwarf_wC3,
+ dwarf_wC4,
+ dwarf_wC5,
+ dwarf_wC6,
+ dwarf_wC7,
+
+ // VFP-v3/Neon
+ dwarf_d0 = 256,
+ dwarf_d1,
+ dwarf_d2,
+ dwarf_d3,
+ dwarf_d4,
+ dwarf_d5,
+ dwarf_d6,
+ dwarf_d7,
+ dwarf_d8,
+ dwarf_d9,
+ dwarf_d10,
+ dwarf_d11,
+ dwarf_d12,
+ dwarf_d13,
+ dwarf_d14,
+ dwarf_d15,
+ dwarf_d16,
+ dwarf_d17,
+ dwarf_d18,
+ dwarf_d19,
+ dwarf_d20,
+ dwarf_d21,
+ dwarf_d22,
+ dwarf_d23,
+ dwarf_d24,
+ dwarf_d25,
+ dwarf_d26,
+ dwarf_d27,
+ dwarf_d28,
+ dwarf_d29,
+ dwarf_d30,
+ dwarf_d31
+};
+
+#endif // utility_ARM_DWARF_Registers_h_
+
diff --git a/lldb/tools/debugserver/source/ARM_GCC_Registers.h b/lldb/tools/debugserver/source/ARM_GCC_Registers.h
new file mode 100644
index 00000000000..e315b69bb27
--- /dev/null
+++ b/lldb/tools/debugserver/source/ARM_GCC_Registers.h
@@ -0,0 +1,35 @@
+//===-- ARM_GCC_Registers.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM_GCC_Registers_h_
+#define utility_ARM_GCC_Registers_h_
+
+enum
+{
+ gcc_r0 = 0,
+ gcc_r1,
+ gcc_r2,
+ gcc_r3,
+ gcc_r4,
+ gcc_r5,
+ gcc_r6,
+ gcc_r7,
+ gcc_r8,
+ gcc_r9,
+ gcc_r10,
+ gcc_r11,
+ gcc_r12,
+ gcc_sp,
+ gcc_lr,
+ gcc_pc,
+ gcc_cpsr
+};
+
+#endif // utility_ARM_GCC_Registers_h_
+
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index 2eb371faa77..582d29b93f9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -1778,7 +1778,17 @@ MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const
char const *arg;
for (i=0; (arg = argv[i]) != NULL; i++)
m_args.push_back(arg);
- m_task.StartExceptionThread();
+ m_task.StartExceptionThread(launch_err);
+
+ if (launch_err.Fail())
+ {
+ if (launch_err.AsString() == NULL)
+ launch_err.SetErrorString("unable to start the exception thread");
+ ::ptrace (PT_KILL, m_pid, 0, 0);
+ m_pid = INVALID_NUB_PROCESS;
+ return INVALID_NUB_PROCESS;
+ }
+
StartSTDIOThread();
SetState (eStateAttaching);
int err = ptrace (PT_ATTACHEXC, m_pid, 0, 0);
diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
index 6eec80cfd7a..d0572c393ea 100644
--- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
@@ -20,6 +20,8 @@
#include "DNBLog.h"
#include "DNBRegisterInfo.h"
#include "DNB.h"
+#include "ARM_GCC_Registers.h"
+#include "ARM_DWARF_Registers.h"
#include <sys/sysctl.h>
@@ -113,7 +115,7 @@ DNBArchMachARM::GetPC(uint64_t failValue)
{
// Get program counter
if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.gpr.__pc;
+ return m_state.context.gpr.__pc;
return failValue;
}
@@ -124,7 +126,7 @@ DNBArchMachARM::SetPC(uint64_t value)
kern_return_t err = GetGPRState(false);
if (err == KERN_SUCCESS)
{
- m_state.gpr.__pc = value;
+ m_state.context.gpr.__pc = value;
err = SetGPRState();
}
return err == KERN_SUCCESS;
@@ -135,7 +137,7 @@ DNBArchMachARM::GetSP(uint64_t failValue)
{
// Get stack pointer
if (GetGPRState(false) == KERN_SUCCESS)
- return m_state.gpr.__sp;
+ return m_state.context.gpr.__sp;
return failValue;
}
@@ -149,8 +151,8 @@ 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.gpr, &count);
- uint32_t *r = &m_state.gpr.__r[0];
+ kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), 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 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(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT, kret,
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15], r[16]);
m_state.SetError(set, Read, kret);
@@ -167,7 +169,7 @@ 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.vfp, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -182,7 +184,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.exc, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -217,7 +219,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.gpr, ARM_THREAD_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), 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
@@ -227,7 +229,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.vfp, ARM_VFP_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), 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
@@ -237,7 +239,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.exc, ARM_EXCEPTION_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), 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
@@ -302,16 +304,16 @@ DNBArchMachARM::ThreadDidStop()
{
uint32_t sw_step_next_pc = m_sw_single_step_next_pc & 0xFFFFFFFEu;
bool sw_step_next_pc_is_thumb = (m_sw_single_step_next_pc & 1) != 0;
- bool actual_next_pc_is_thumb = (m_state.gpr.__cpsr & 0x20) != 0;
- if (m_state.gpr.__pc != sw_step_next_pc)
+ bool actual_next_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0;
+ if (m_state.context.gpr.__pc != sw_step_next_pc)
{
- DNBLogError("curr pc = 0x%8.8x - calculated single step target PC was incorrect: 0x%8.8x != 0x%8.8x", m_state.gpr.__pc, sw_step_next_pc, m_state.gpr.__pc);
+ DNBLogError("curr pc = 0x%8.8x - calculated single step target PC was incorrect: 0x%8.8x != 0x%8.8x", m_state.context.gpr.__pc, sw_step_next_pc, m_state.context.gpr.__pc);
exit(1);
}
if (actual_next_pc_is_thumb != sw_step_next_pc_is_thumb)
{
DNBLogError("curr pc = 0x%8.8x - calculated single step calculated mode mismatch: sw single mode = %s != %s",
- m_state.gpr.__pc,
+ m_state.context.gpr.__pc,
actual_next_pc_is_thumb ? "Thumb" : "ARM",
sw_step_next_pc_is_thumb ? "Thumb" : "ARM");
exit(1);
@@ -336,7 +338,7 @@ DNBArchMachARM::ThreadDidStop()
if (m_sw_single_step_itblock_break_count > 0)
{
// See if we hit one of our Thumb IT breakpoints?
- DNBBreakpoint *step_bp = m_thread->Process()->Breakpoints().FindByAddress(m_state.gpr.__pc);
+ DNBBreakpoint *step_bp = m_thread->Process()->Breakpoints().FindByAddress(m_state.context.gpr.__pc);
if (step_bp)
{
@@ -362,7 +364,7 @@ DNBArchMachARM::ThreadDidStop()
// 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.gpr.__pc);
+ DecodeITBlockInstructions(m_state.context.gpr.__pc);
}
}
@@ -389,7 +391,7 @@ DNBArchMachARM::StepNotComplete ()
kret = GetGPRState(false);
if (kret == KERN_SUCCESS)
{
- if (m_state.gpr.__pc == m_hw_single_chained_step_addr)
+ 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;
@@ -450,7 +452,7 @@ DNBArchMachARM::DecodeITBlockInstructions(nub_addr_t curr_pc)
arm_error_t decodeError;
m_last_decode_pc = pc_in_itblock;
- decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_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);
@@ -489,30 +491,30 @@ DNBArchMachARM::EnableHardwareSingleStep (bool enable)
// 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.gpr.__pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address
+ 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.gpr.__cpsr & 0x20)
+ if (m_state.context.gpr.__cpsr & 0x20)
{
// Thumb breakpoint
- if (m_state.gpr.__pc & 2)
+ 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.gpr.__pc, sizeof(opcode), &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.gpr.__pc & 2)
+ 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.gpr.__pc + 2;
+ m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
}
else
{
@@ -627,7 +629,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
nub_addr_t myTargetPC, addressWherePCLives;
pid_t mypid;
- uint32_t cpsr_c = bit(m_state.gpr.__cpsr, 29); // Carry condition code flag
+ 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;
@@ -688,7 +690,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get firstOperand register value (at index=1)
firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.gpr.__r[firstOperandIndex];
+ firstOperand = m_state.context.gpr.__r[firstOperandIndex];
// Get immediateValue (at index=2)
immediateValue = decodedInstruction.op[2].value;
@@ -710,11 +712,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get firstOperand register value (at index=1)
firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.gpr.__r[firstOperandIndex];
+ 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.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
break;
@@ -733,11 +735,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get firstOperand register value (at index=1)
firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.gpr.__r[firstOperandIndex];
+ 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.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
// Get shiftAmount as immediate value (at index=3)
shiftAmount = decodedInstruction.op[3].value;
@@ -760,15 +762,15 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get firstOperand register value (at index=1)
firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
- firstOperand = m_state.gpr.__r[firstOperandIndex];
+ 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.gpr.__r[secondOperandIndex];
+ 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.gpr.__r[shiftRegisterIndex];
+ shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
break;
@@ -787,11 +789,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get firstOperand register value (at index=0)
firstOperandIndex = decodedInstruction.op[0].value; // first operand register index
- firstOperand = m_state.gpr.__r[firstOperandIndex];
+ 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.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
break;
@@ -849,7 +851,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get secondOperand register value (at index=1)
secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
break;
@@ -868,7 +870,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get secondOperand register value (at index=1)
secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
- secondOperand = m_state.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
// Get shiftAmount as immediate value (at index=2)
shiftAmount = decodedInstruction.op[2].value;
@@ -891,11 +893,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get secondOperand register value (at index=1)
secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.gpr.__r[secondOperandIndex];
+ 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.gpr.__r[shiftRegisterIndex];
+ shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];
break;
@@ -914,7 +916,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get secondOperand register value (at index=1)
secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
- secondOperand = m_state.gpr.__r[secondOperandIndex];
+ secondOperand = m_state.context.gpr.__r[secondOperandIndex];
break;
@@ -963,7 +965,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
}
// Get branch address in register (at index=0)
- *targetPC = m_state.gpr.__r[decodedInstruction.op[0].value];
+ *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
return true;
}
break;
@@ -992,7 +994,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
}
// Get branch address in register (at index=0)
- *targetPC = m_state.gpr.__r[decodedInstruction.op[0].value];
+ *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
return true;
break;
@@ -1033,7 +1035,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get baseAddress from register (at index=1)
baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.gpr.__r[baseAddressIndex];
+ baseAddress = m_state.context.gpr.__r[baseAddressIndex];
// Get immediateOffset (at index=2)
immediateOffset = decodedInstruction.op[2].value;
@@ -1050,11 +1052,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get baseAddress from register (at index=1)
baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.gpr.__r[baseAddressIndex];
+ baseAddress = m_state.context.gpr.__r[baseAddressIndex];
// Get immediateOffset from register (at index=2)
addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
- addressOffsetFromRegister = m_state.gpr.__r[addressOffsetFromRegisterIndex];
+ addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
break;
@@ -1069,11 +1071,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get baseAddress from register (at index=1)
baseAddressIndex = decodedInstruction.op[1].value;
- baseAddress = m_state.gpr.__r[baseAddressIndex];
+ baseAddress = m_state.context.gpr.__r[baseAddressIndex];
// Get immediateOffset from register (at index=2)
addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
- addressOffsetFromRegister = m_state.gpr.__r[addressOffsetFromRegisterIndex];
+ addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
// Get shiftAmount (at index=3)
shiftAmount = decodedInstruction.op[3].value;
@@ -1101,7 +1103,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// Get baseAddress from register (at index=0)
baseAddressIndex = decodedInstruction.op[0].value;
- baseAddress = m_state.gpr.__r[baseAddressIndex];
+ baseAddress = m_state.context.gpr.__r[baseAddressIndex];
// Get registerList from register (at index=1)
registerList16 = (uint16_t)decodedInstruction.op[1].value;
@@ -1125,7 +1127,7 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
// 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.gpr.__sp;
+ baseAddress = m_state.context.gpr.__sp;
if (decodedInstruction.thumb16b)
{
@@ -1161,11 +1163,11 @@ DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t de
case ARM_INST_TBH:
// Get baseAddress from register (at index=0)
baseAddressIndex = decodedInstruction.op[0].value;
- baseAddress = m_state.gpr.__r[baseAddressIndex];
+ baseAddress = m_state.context.gpr.__r[baseAddressIndex];
// Get immediateOffset from register (at index=1)
addressOffsetFromRegisterIndex = decodedInstruction.op[1].value;
- addressOffsetFromRegister = m_state.gpr.__r[addressOffsetFromRegisterIndex];
+ addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
break;
// ThumbEE branch-to-handler instructions: Jump to handlers at some offset
@@ -1625,7 +1627,7 @@ DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t cur
{
// Compare and branch on zero/non-zero (Thumb-16 only)
// Unusual condition check built into the instruction
- registerValue = m_state.gpr.__r[m_last_decode_arm.op[REG_RD].value];
+ registerValue = m_state.context.gpr.__r[m_last_decode_arm.op[REG_RD].value];
if (m_last_decode_arm.instruction->code == ARM_INST_CBZ)
{
@@ -1767,11 +1769,15 @@ DNBArchMachARM::DecodeInstructionUsingDisassembler(nub_addr_t curr_pc, uint32_t
}
nub_bool_t
-DNBArchMachARM::BreakpointHit(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
+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);
- return DNBThreadSetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, 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);
}
// Set the single step bit in the processor status register.
@@ -1787,11 +1793,11 @@ DNBArchMachARM::SetSingleStepSoftwareBreakpoints()
return err.Error();
}
- nub_addr_t curr_pc = m_state.gpr.__pc;
- uint32_t curr_cpsr = m_state.gpr.__cpsr;
+ 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.gpr.__cpsr & 0x20) != 0;
+ 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);
@@ -1822,17 +1828,17 @@ DNBArchMachARM::SetSingleStepSoftwareBreakpoints()
if (!inITBlock)
{
DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: normal instruction", __FUNCTION__);
- EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
+ 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.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
+ 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.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
+ EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
}
else
{
@@ -2279,119 +2285,294 @@ DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index)
//----------------------------------------------------------------------
enum gpr_regnums
{
- e_regNumGPR_r0 = 0,
- e_regNumGPR_r1,
- e_regNumGPR_r2,
- e_regNumGPR_r3,
- e_regNumGPR_r4,
- e_regNumGPR_r5,
- e_regNumGPR_r6,
- e_regNumGPR_r7,
- e_regNumGPR_r8,
- e_regNumGPR_r9,
- e_regNumGPR_r10,
- e_regNumGPR_r11,
- e_regNumGPR_r12,
- e_regNumGPR_sp,
- e_regNumGPR_lr,
- e_regNumGPR_pc,
- e_regNumGPR_cpsr
+ gpr_r0 = 0,
+ gpr_r1,
+ gpr_r2,
+ gpr_r3,
+ gpr_r4,
+ gpr_r5,
+ gpr_r6,
+ gpr_r7,
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_sp,
+ gpr_lr,
+ gpr_pc,
+ gpr_cpsr
};
+enum
+{
+ vfp_s0 = 0,
+ vfp_s1,
+ vfp_s2,
+ vfp_s3,
+ vfp_s4,
+ vfp_s5,
+ vfp_s6,
+ vfp_s7,
+ vfp_s8,
+ vfp_s9,
+ vfp_s10,
+ vfp_s11,
+ vfp_s12,
+ vfp_s13,
+ vfp_s14,
+ vfp_s15,
+ vfp_s16,
+ vfp_s17,
+ vfp_s18,
+ vfp_s19,
+ vfp_s20,
+ vfp_s21,
+ vfp_s22,
+ vfp_s23,
+ vfp_s24,
+ vfp_s25,
+ vfp_s26,
+ vfp_s27,
+ vfp_s28,
+ vfp_s29,
+ vfp_s30,
+ vfp_s31,
+ vfp_d16,
+ vfp_d17,
+ vfp_d18,
+ vfp_d19,
+ vfp_d20,
+ vfp_d21,
+ vfp_d22,
+ vfp_d23,
+ vfp_d24,
+ vfp_d25,
+ vfp_d26,
+ vfp_d27,
+ vfp_d28,
+ vfp_d29,
+ vfp_d30,
+ vfp_d31,
+ vfp_fpscr
+};
+
+enum
+{
+ exc_exception,
+ exc_fsr,
+ exc_far,
+};
+
+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
+};
+
+#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 (32) + (((idx) - 16) * 8))
+#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 DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, 4, Float, 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, 8, Float, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
+
// General purpose registers
-static DNBRegisterInfo g_gpr_registers[] =
+const DNBRegisterInfo
+DNBArchMachARM::g_gpr_registers[] =
{
- { "r0" , Uint, 4, Hex },
- { "r1" , Uint, 4, Hex },
- { "r2" , Uint, 4, Hex },
- { "r3" , Uint, 4, Hex },
- { "r4" , Uint, 4, Hex },
- { "r5" , Uint, 4, Hex },
- { "r6" , Uint, 4, Hex },
- { "r7" , Uint, 4, Hex },
- { "r8" , Uint, 4, Hex },
- { "r9" , Uint, 4, Hex },
- { "r10" , Uint, 4, Hex },
- { "r11" , Uint, 4, Hex },
- { "r12" , Uint, 4, Hex },
- { "sp" , Uint, 4, Hex },
- { "lr" , Uint, 4, Hex },
- { "pc" , Uint, 4, Hex },
- { "cpsr" , Uint, 4, Hex },
+ DEFINE_GPR_IDX ( 0, r0, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 1, r1, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 2, r2, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 3, r3, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 4, r4, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 5, r5, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 6, r6, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 7, r7, NULL, GENERIC_REGNUM_FP ),
+ DEFINE_GPR_IDX ( 8, r8, NULL, INVALID_NUB_REGNUM ),
+ DEFINE_GPR_IDX ( 9, r9, NULL, INVALID_NUB_REGNUM ),
+ 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, NULL, GENERIC_REGNUM_FLAGS )
};
// Floating point registers
-static DNBRegisterInfo g_vfp_registers[] =
+const DNBRegisterInfo
+DNBArchMachARM::g_vfp_registers[] =
{
- { "s0" , IEEE754, 4, Float },
- { "s1" , IEEE754, 4, Float },
- { "s2" , IEEE754, 4, Float },
- { "s3" , IEEE754, 4, Float },
- { "s4" , IEEE754, 4, Float },
- { "s5" , IEEE754, 4, Float },
- { "s6" , IEEE754, 4, Float },
- { "s7" , IEEE754, 4, Float },
- { "s8" , IEEE754, 4, Float },
- { "s9" , IEEE754, 4, Float },
- { "s10" , IEEE754, 4, Float },
- { "s11" , IEEE754, 4, Float },
- { "s12" , IEEE754, 4, Float },
- { "s13" , IEEE754, 4, Float },
- { "s14" , IEEE754, 4, Float },
- { "s15" , IEEE754, 4, Float },
- { "s16" , IEEE754, 4, Float },
- { "s17" , IEEE754, 4, Float },
- { "s18" , IEEE754, 4, Float },
- { "s19" , IEEE754, 4, Float },
- { "s20" , IEEE754, 4, Float },
- { "s21" , IEEE754, 4, Float },
- { "s22" , IEEE754, 4, Float },
- { "s23" , IEEE754, 4, Float },
- { "s24" , IEEE754, 4, Float },
- { "s25" , IEEE754, 4, Float },
- { "s26" , IEEE754, 4, Float },
- { "s27" , IEEE754, 4, Float },
- { "s28" , IEEE754, 4, Float },
- { "s29" , IEEE754, 4, Float },
- { "s30" , IEEE754, 4, Float },
- { "s31" , IEEE754, 4, Float },
- { "fpscr" , Uint, 4, Hex }
+ 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 (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, 4, Hex, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
};
// Exception registers
-static DNBRegisterInfo g_exc_registers[] =
+const DNBRegisterInfo
+DNBArchMachARM::g_exc_registers[] =
{
- { "dar" , Uint, 4, Hex },
- { "dsisr" , Uint, 4, Hex },
- { "exception" , Uint, 4, Hex }
+ { e_regSetVFP, exc_exception , "exception" , NULL, Uint, 4, Hex, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
+ { e_regSetVFP, exc_fsr , "fsr" , NULL, Uint, 4, Hex, EXC_OFFSET(fsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
+ { e_regSetVFP, exc_far , "far" , NULL, Uint, 4, Hex, EXC_OFFSET(far) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
};
// Number of registers in each register set
-const size_t k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
-const size_t k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo);
-const size_t k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
-// Total number of registers for this architecture
-const size_t k_num_armv6_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers;
+const size_t DNBArchMachARM::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
+const size_t DNBArchMachARM::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers;
//----------------------------------------------------------------------
// Register set definitions. The first definitions at register set index
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
-static const DNBRegisterSetInfo g_reg_sets[] =
+const DNBRegisterSetInfo
+DNBArchMachARM::g_reg_sets[] =
{
- { "ARMV6 Registers", NULL, k_num_armv6_registers },
+ { "ARM Registers", NULL, k_num_all_registers },
{ "General Purpose Registers", g_gpr_registers, k_num_gpr_registers },
{ "Floating Point Registers", g_vfp_registers, k_num_vfp_registers },
{ "Exception State Registers", g_exc_registers, k_num_exc_registers }
};
// Total number of register sets for this architecture
-const size_t k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
+const size_t DNBArchMachARM::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
const DNBRegisterSetInfo *
-DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets) const
+DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
*num_reg_sets = k_num_register_sets;
return g_reg_sets;
@@ -2406,27 +2587,27 @@ DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
{
case GENERIC_REGNUM_PC: // Program Counter
set = e_regSetGPR;
- reg = e_regNumGPR_pc;
+ reg = gpr_pc;
break;
case GENERIC_REGNUM_SP: // Stack Pointer
set = e_regSetGPR;
- reg = e_regNumGPR_sp;
+ reg = gpr_sp;
break;
case GENERIC_REGNUM_FP: // Frame Pointer
set = e_regSetGPR;
- reg = e_regNumGPR_r7; // is this the right reg?
+ reg = gpr_r7; // is this the right reg?
break;
case GENERIC_REGNUM_RA: // Return Address
set = e_regSetGPR;
- reg = e_regNumGPR_lr;
+ reg = gpr_lr;
break;
case GENERIC_REGNUM_FLAGS: // Processor flags register
set = e_regSetGPR;
- reg = e_regNumGPR_cpsr;
+ reg = gpr_cpsr;
break;
default:
@@ -2446,7 +2627,7 @@ DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
case e_regSetGPR:
if (reg < k_num_gpr_registers)
{
- value->value.uint32 = m_state.gpr.__r[reg];
+ value->value.uint32 = m_state.context.gpr.__r[reg];
return true;
}
break;
@@ -2454,12 +2635,12 @@ DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
case e_regSetVFP:
if (reg < 32)
{
- value->value.uint32 = m_state.vfp.__r[reg];
+ value->value.uint32 = m_state.context.vfp.__r[reg];
return true;
}
else if (reg == 32)
{
- value->value.uint32 = m_state.vfp.__fpscr;
+ value->value.uint32 = m_state.context.vfp.__fpscr;
return true;
}
break;
@@ -2467,7 +2648,7 @@ DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
case e_regSetEXC:
if (reg < k_num_exc_registers)
{
- value->value.uint32 = (&m_state.exc.__exception)[reg];
+ value->value.uint32 = (&m_state.context.exc.__exception)[reg];
return true;
}
break;
@@ -2485,27 +2666,27 @@ DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value
{
case GENERIC_REGNUM_PC: // Program Counter
set = e_regSetGPR;
- reg = e_regNumGPR_pc;
+ reg = gpr_pc;
break;
case GENERIC_REGNUM_SP: // Stack Pointer
set = e_regSetGPR;
- reg = e_regNumGPR_sp;
+ reg = gpr_sp;
break;
case GENERIC_REGNUM_FP: // Frame Pointer
set = e_regSetGPR;
- reg = e_regNumGPR_r7;
+ reg = gpr_r7;
break;
case GENERIC_REGNUM_RA: // Return Address
set = e_regSetGPR;
- reg = e_regNumGPR_lr;
+ reg = gpr_lr;
break;
case GENERIC_REGNUM_FLAGS: // Processor flags register
set = e_regSetGPR;
- reg = e_regNumGPR_cpsr;
+ reg = gpr_cpsr;
break;
default:
@@ -2525,7 +2706,7 @@ DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value
case e_regSetGPR:
if (reg < k_num_gpr_registers)
{
- m_state.gpr.__r[reg] = value->value.uint32;
+ m_state.context.gpr.__r[reg] = value->value.uint32;
success = true;
}
break;
@@ -2533,12 +2714,12 @@ DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value
case e_regSetVFP:
if (reg < 32)
{
- m_state.vfp.__r[reg] = value->value.float64;
+ m_state.context.vfp.__r[reg] = value->value.float64;
success = true;
}
else if (reg == 32)
{
- m_state.vfp.__fpscr = value->value.uint32;
+ m_state.context.vfp.__fpscr = value->value.uint32;
success = true;
}
break;
@@ -2546,7 +2727,7 @@ DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value
case e_regSetEXC:
if (reg < k_num_exc_registers)
{
- (&m_state.exc.__exception)[reg] = value->value.uint32;
+ (&m_state.context.exc.__exception)[reg] = value->value.uint32;
success = true;
}
break;
@@ -2606,5 +2787,47 @@ DNBArchMachARM::RegisterSetStateIsValid (int set) const
}
+nub_size_t
+DNBArchMachARM::GetRegisterContext (void *buf, nub_size_t buf_len)
+{
+ nub_size_t size = sizeof (m_state.context);
+
+ if (buf && buf_len)
+ {
+ if (size > buf_len)
+ size = buf_len;
+
+ bool force = false;
+ if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force))
+ return 0;
+ ::memcpy (buf, &m_state.context, size);
+ }
+ DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::GetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
+ // Return the size of the register context even if NULL was passed in
+ return size;
+}
+
+nub_size_t
+DNBArchMachARM::SetRegisterContext (const void *buf, nub_size_t buf_len)
+{
+ nub_size_t size = sizeof (m_state.context);
+ if (buf == NULL || buf_len == 0)
+ size = 0;
+
+ if (size)
+ {
+ if (size > buf_len)
+ size = buf_len;
+
+ ::memcpy (&m_state.context, buf, size);
+ SetGPRState();
+ SetVFPState();
+ SetEXCState();
+ }
+ DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
+ return size;
+}
+
+
#endif // #if defined (__arm__)
diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
index f40c891ce98..f012caa1828 100644
--- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
+++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
@@ -45,10 +45,13 @@ public:
{
}
- virtual const DNBRegisterSetInfo *
- GetRegisterSetInfo(nub_size_t *num_reg_sets) const;
+ static const DNBRegisterSetInfo *
+ GetRegisterSetInfo(nub_size_t *num_reg_sets);
+
virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value);
virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value);
+ virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
+ virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len);
virtual kern_return_t GetRegisterState (int set, bool force);
virtual kern_return_t SetRegisterState (int set);
@@ -100,12 +103,32 @@ protected:
Write = 1,
kNumErrors = 2
};
+
+ typedef arm_thread_state_t GPR;
+ typedef arm_vfp_state_t FPU;
+ typedef arm_exception_state_t EXC;
+
+ static const DNBRegisterInfo g_gpr_registers[];
+ static const DNBRegisterInfo g_vfp_registers[];
+ static const DNBRegisterInfo g_exc_registers[];
+ static const DNBRegisterSetInfo g_reg_sets[];
+
+ static const size_t k_num_gpr_registers;
+ static const size_t k_num_vfp_registers;
+ static const size_t k_num_exc_registers;
+ static const size_t k_num_all_registers;
+ static const size_t k_num_register_sets;
+
+ struct Context
+ {
+ GPR gpr;
+ FPU vfp;
+ EXC exc;
+ };
struct State
{
- arm_thread_state_t gpr;
- arm_vfp_state_t vfp;
- arm_exception_state_t exc;
+ Context context;
arm_debug_state_t dbg;
kern_return_t gpr_errs[2]; // Read/Write errors
kern_return_t vfp_errs[2]; // Read/Write errors
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index b4d5d7841fe..986cb4f5035 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -171,6 +171,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_Q , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_Q , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_Q , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
+ t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_Q , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
@@ -826,14 +827,14 @@ 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", NULL, k_zero_bytes, 0},
- { 17, 12, "f1", NULL, k_zero_bytes, 0},
- { 18, 12, "f2", NULL, k_zero_bytes, 0},
- { 19, 12, "f3", NULL, k_zero_bytes, 0},
- { 20, 12, "f4", NULL, k_zero_bytes, 0},
- { 21, 12, "f5", NULL, k_zero_bytes, 0},
- { 22, 12, "f6", NULL, k_zero_bytes, 0},
- { 23, 12, "f7", NULL, k_zero_bytes, 0},
+ { 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}, NULL, 0},
{ 25, 4,"cpsr", {0}, NULL, 1},
{ 26, 4, "s0", {0}, NULL, 0},
@@ -1751,6 +1752,20 @@ RNBRemote::HandlePacket_Q (const char *p)
return SendPacket ("E35");
}
+ if (strncmp (p, "QSetDisableASLR:", sizeof ("QSetDisableASLR:") - 1) == 0)
+ {
+ extern int g_disable_aslr;
+ p += sizeof ("QSetDisableASLR:") - 1;
+ switch (*p)
+ {
+ case '0': g_disable_aslr = 0; break;
+ case '1': g_disable_aslr = 1; break;
+ default:
+ return SendPacket ("E56");
+ }
+ return SendPacket ("OK");
+ }
+
/* The number of characters in a packet payload that gdb is
prepared to accept. The packet-start char, packet-end char,
2 checksum chars and terminating null character are not included
@@ -1933,7 +1948,7 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
{
if (thread_ident_info.dispatch_qaddr != 0)
- ostrm << std::hex << "dispatchqaddr:" << thread_ident_info.dispatch_qaddr << ';';
+ ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
}
DNBRegisterValue reg_value;
for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index bec9d1812d0..bd3703c74e7 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -96,6 +96,7 @@ public:
set_max_packet_size, // 'QSetMaxPacketSize:'
set_max_payload_size, // 'QSetMaxPayloadSize:'
set_environment_variable, // 'QEnvironment:'
+ set_disable_aslr, // 'QSetDisableASLR:'
allocate_memory, // '_M'
deallocate_memory, // '_m'
diff --git a/lldb/tools/debugserver/source/RNBServices.cpp b/lldb/tools/debugserver/source/RNBServices.cpp
index 1fe791d37be..846c469faa2 100644
--- a/lldb/tools/debugserver/source/RNBServices.cpp
+++ b/lldb/tools/debugserver/source/RNBServices.cpp
@@ -16,6 +16,7 @@
#import <CoreFoundation/CoreFoundation.h>
#import <unistd.h>
#import "DNBLog.h"
+#include "MacOSX/CFUtils.h"
#if defined (__arm__)
#import <SpringBoardServices/SpringBoardServices.h>
diff --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp
index 17918da2290..dc50b63bb0d 100644
--- a/lldb/tools/debugserver/source/debugserver.cpp
+++ b/lldb/tools/debugserver/source/debugserver.cpp
@@ -53,7 +53,7 @@ RNBRemoteSP g_remoteSP;
static int g_lockdown_opt = 0;
static int g_applist_opt = 0;
static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault;
-static int g_disable_aslr = 0;
+int g_disable_aslr = 0;
int g_isatty = 0;
OpenPOWER on IntegriCloud