1 //===-- RegisterContextPOSIXProcessMonitor_x86.h ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===---------------------------------------------------------------------===//
10 #include "lldb/Target/Thread.h"
11 #include "lldb/Core/RegisterValue.h"
13 #include "ProcessPOSIX.h"
14 #include "RegisterContextPOSIXProcessMonitor_x86.h"
15 #include "ProcessMonitor.h"
17 using namespace lldb_private;
20 // Support ptrace extensions even when compiled without required kernel support
22 #define NT_X86_XSTATE 0x202
25 #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
28 size_and_rw_bits(size_t size, bool read, bool write)
33 rw = 0x3; // READ or READ/WRITE
37 assert(0 && "read and write cannot both be false");
44 return (0x1 << 2) | rw;
46 return (0x3 << 2) | rw;
48 return (0x2 << 2) | rw;
50 assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
54 RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread,
55 uint32_t concrete_frame_idx,
56 RegisterInfoInterface *register_info)
57 : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info)
62 RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor()
64 ProcessSP base = CalculateProcess();
65 ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
66 return process->GetMonitor();
70 RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR()
72 ProcessMonitor &monitor = GetMonitor();
73 return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
77 RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR()
79 ProcessMonitor &monitor = GetMonitor();
80 if (GetFPRType() == eFXSAVE)
81 return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
83 if (GetFPRType() == eXSAVE)
84 return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
89 RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR()
91 ProcessMonitor &monitor = GetMonitor();
92 return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
96 RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR()
98 ProcessMonitor &monitor = GetMonitor();
99 if (GetFPRType() == eFXSAVE)
100 return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
102 if (GetFPRType() == eXSAVE)
103 return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
108 RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const unsigned reg,
109 RegisterValue &value)
111 ProcessMonitor &monitor = GetMonitor();
113 #if defined(__FreeBSD__)
114 if (reg >= m_reg_info.first_dr)
115 return monitor.ReadDebugRegisterValue(m_thread.GetID(),
116 GetRegisterOffset(reg),
117 GetRegisterName(reg),
118 GetRegisterSize(reg),
121 return monitor.ReadRegisterValue(m_thread.GetID(),
122 GetRegisterOffset(reg),
123 GetRegisterName(reg),
124 GetRegisterSize(reg),
129 RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const unsigned reg,
130 const RegisterValue &value)
132 unsigned reg_to_write = reg;
133 RegisterValue value_to_write = value;
135 // Check if this is a subregister of a full register.
136 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
137 if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
139 RegisterValue full_value;
140 uint32_t full_reg = reg_info->invalidate_regs[0];
141 const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
143 // Read the full register.
144 if (ReadRegister(full_reg_info, full_value))
147 ByteOrder byte_order = GetByteOrder();
148 uint8_t dst[RegisterValue::kMaxRegisterByteSize];
150 // Get the bytes for the full register.
151 const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
156 if (error.Success() && dest_size)
158 uint8_t src[RegisterValue::kMaxRegisterByteSize];
160 // Get the bytes for the source data.
161 const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
162 if (error.Success() && src_size && (src_size < dest_size))
164 // Copy the src bytes to the destination.
165 memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
166 // Set this full register as the value to write.
167 value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
168 value_to_write.SetType(full_reg_info);
169 reg_to_write = full_reg;
175 ProcessMonitor &monitor = GetMonitor();
176 #if defined(__FreeBSD__)
177 if (reg >= m_reg_info.first_dr)
178 return monitor.WriteDebugRegisterValue(m_thread.GetID(),
179 GetRegisterOffset(reg_to_write),
180 GetRegisterName(reg_to_write),
183 return monitor.WriteRegisterValue(m_thread.GetID(),
184 GetRegisterOffset(reg_to_write),
185 GetRegisterName(reg_to_write),
190 RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
195 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
197 if (IsFPR(reg, GetFPRType()))
204 uint32_t full_reg = reg;
205 bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
209 // Read the full aligned 64-bit register.
210 full_reg = reg_info->invalidate_regs[0];
213 bool success = ReadRegister(full_reg, value);
217 // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
218 if (is_subreg && (reg_info->byte_offset & 0x1))
219 value.SetUInt64(value.GetAsUInt64() >> 8);
221 // If our return byte size was greater than the return value reg size, then
222 // use the type specified by reg_info rather than the uint64_t default
223 if (value.GetByteSize() > reg_info->byte_size)
224 value.SetType(reg_info);
229 if (reg_info->encoding == eEncodingVector)
231 ByteOrder byte_order = GetByteOrder();
233 if (byte_order != ByteOrder::eByteOrderInvalid)
235 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
236 value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
237 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
238 value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
239 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
240 value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
241 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
243 // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
244 if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
245 value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
249 return value.GetType() == RegisterValue::eTypeBytes;
254 // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
255 assert (reg_info->byte_offset < sizeof(m_fpr));
256 uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
257 switch (reg_info->byte_size)
260 value.SetUInt16(*(uint16_t *)src);
263 value.SetUInt32(*(uint32_t *)src);
266 value.SetUInt64(*(uint64_t *)src);
269 assert(false && "Unhandled data size.");
275 RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
277 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
280 return WriteRegister(reg, value);
282 if (IsFPR(reg, GetFPRType()))
284 if (reg_info->encoding == eEncodingVector)
286 if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
287 ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, value.GetBytes(), value.GetByteSize());
289 if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
290 ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, value.GetBytes(), value.GetByteSize());
292 if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
293 ::memcpy (m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, value.GetBytes(), value.GetByteSize());
295 if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
297 if (GetFPRType() != eXSAVE)
298 return false; // the target processor does not support AVX
300 // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
301 ::memcpy (m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, value.GetBytes(), value.GetByteSize());
302 if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
308 // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
309 assert (reg_info->byte_offset < sizeof(m_fpr));
310 uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
311 switch (reg_info->byte_size)
314 *(uint16_t *)dst = value.GetAsUInt16();
317 *(uint32_t *)dst = value.GetAsUInt32();
320 *(uint64_t *)dst = value.GetAsUInt64();
323 assert(false && "Unhandled data size.");
331 return CopyYMMtoXSTATE(reg, GetByteOrder());
339 RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
341 bool success = false;
342 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
343 if (data_sp && ReadGPR () && ReadFPR ())
345 uint8_t *dst = data_sp->GetBytes();
350 ::memcpy (dst, &m_gpr_x86_64, GetGPRSize());
353 if (GetFPRType() == eFXSAVE)
354 ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
356 if (GetFPRType() == eXSAVE)
358 ByteOrder byte_order = GetByteOrder();
360 // Assemble the YMM register content from the register halves.
361 for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
362 success = CopyXSTATEtoYMM(reg, byte_order);
366 // Copy the extended register state including the assembled ymm registers.
367 ::memcpy (dst, &m_fpr, sizeof(m_fpr));
375 RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
377 bool success = false;
378 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
380 uint8_t *src = data_sp->GetBytes();
383 ::memcpy (&m_gpr_x86_64, src, GetGPRSize());
388 if (GetFPRType() == eFXSAVE)
389 ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
390 if (GetFPRType() == eXSAVE)
391 ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
393 success = WriteFPR();
396 if (GetFPRType() == eXSAVE)
398 ByteOrder byte_order = GetByteOrder();
400 // Parse the YMM register content from the register halves.
401 for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
402 success = CopyYMMtoXSTATE(reg, byte_order);
412 RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(addr_t addr, size_t size,
413 bool read, bool write)
415 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
418 for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
420 if (IsWatchpointVacant(hw_index))
421 return SetHardwareWatchpointWithIndex(addr, size,
426 return LLDB_INVALID_INDEX32;
430 RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
432 if (hw_index < NumSupportedHardwareWatchpoints())
434 RegisterValue current_dr7_bits;
436 if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
438 uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
440 if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
449 RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable)
451 enum { TRACE_BIT = 0x100 };
454 if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
459 if (rflags & TRACE_BIT)
466 if (!(rflags & TRACE_BIT))
469 rflags &= ~TRACE_BIT;
472 return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
476 RegisterContextPOSIXProcessMonitor_x86_64::UpdateAfterBreakpoint()
478 // PC points one byte past the int3 responsible for the breakpoint.
481 if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
489 RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(unsigned offset)
492 for (reg = 0; reg < m_reg_info.num_registers; reg++)
494 if (GetRegisterInfo()[reg].byte_offset == offset)
497 assert(reg < m_reg_info.num_registers && "Invalid register offset.");
502 RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
506 if (m_watchpoints_initialized == false)
508 // Reset the debug status and debug control registers
509 RegisterValue zero_bits = RegisterValue(uint64_t(0));
510 if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
511 assert(false && "Could not initialize watchpoint registers");
512 m_watchpoints_initialized = true;
515 if (hw_index < NumSupportedHardwareWatchpoints())
519 if (ReadRegister(m_reg_info.first_dr + 6, value))
521 uint64_t val = value.GetAsUInt64();
522 is_hit = val & (1 << hw_index);
530 RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits()
532 return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
536 RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
538 addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
540 if (hw_index < NumSupportedHardwareWatchpoints())
542 if (!IsWatchpointVacant(hw_index))
546 if (ReadRegister(m_reg_info.first_dr + hw_index, value))
547 wp_monitor_addr = value.GetAsUInt64();
551 return wp_monitor_addr;
555 RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
557 bool is_vacant = false;
560 assert(hw_index < NumSupportedHardwareWatchpoints());
562 if (m_watchpoints_initialized == false)
564 // Reset the debug status and debug control registers
565 RegisterValue zero_bits = RegisterValue(uint64_t(0));
566 if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
567 assert(false && "Could not initialize watchpoint registers");
568 m_watchpoints_initialized = true;
571 if (ReadRegister(m_reg_info.first_dr + 7, value))
573 uint64_t val = value.GetAsUInt64();
574 is_vacant = (val & (3 << 2*hw_index)) == 0;
581 RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
582 bool read, bool write,
585 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
587 if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
590 if (!(size == 1 || size == 2 || size == 4 || size == 8))
593 if (read == false && write == false)
596 if (!IsWatchpointVacant(hw_index))
599 // Set both dr7 (debug control register) and dri (debug address register).
601 // dr7{7-0} encodes the local/global enable bits:
602 // global enable --. .-- local enable
610 // dr7{31-16} encodes the rw/len bits:
611 // b_x+3, b_x+2, b_x+1, b_x
612 // where bits{x+1, x} => rw
613 // 0b00: execute, 0b01: write, 0b11: read-or-write,
614 // 0b10: io read-or-write (unused)
615 // and bits{x+3, x+2} => len
616 // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
618 // dr0 -> bits{19-16}
619 // dr1 -> bits{23-20}
620 // dr2 -> bits{27-24}
621 // dr3 -> bits{31-28}
622 if (hw_index < num_hw_watchpoints)
624 RegisterValue current_dr7_bits;
626 if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
628 uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
630 size_and_rw_bits(size, read, write) <<
633 if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
634 WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
643 RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints()
645 // Available debug address registers: dr0, dr1, dr2, dr3