bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info,
                                                   RegisterValue &value) {
  const uint8_t *src;
  size_t offset;
  const size_t fxsave_offset = reg_info->byte_offset - GetFXSAVEOffset();
  // make the offset relative to the beginning of the FXSAVE structure
  // because this is the data that we have (not the entire UserArea)

  if (m_gpregset && reg_info->byte_offset < GetGPRSize()) {
    src = m_gpregset.get();
    offset = reg_info->byte_offset;
  } else if (m_fpregset && fxsave_offset < sizeof(FXSAVE)) {
    src = m_fpregset.get();
    offset = fxsave_offset;
  } else {
    return false;
  }

  Error error;
  value.SetFromMemoryData(reg_info, src + offset, reg_info->byte_size,
                          lldb::eByteOrderLittle, error);

  return error.Success();
}
示例#2
0
Error
RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
                                              lldb::addr_t src_addr, 
                                              uint32_t src_len, 
                                              RegisterValue &reg_value)
{
    Error error;
    if (reg_info == nullptr)
    {
        error.SetErrorString ("invalid register info argument.");
        return error;
    }

    // Moving from addr into a register
    //
    // Case 1: src_len == dst_len
    //
    //   |AABBCCDD| Address contents
    //   |AABBCCDD| Register contents
    //
    // Case 2: src_len > dst_len
    //
    //   Error!  (The register should always be big enough to hold the data)
    //
    // Case 3: src_len < dst_len
    //
    //   |AABB| Address contents
    //   |AABB0000| Register contents [on little-endian hardware]
    //   |0000AABB| Register contents [on big-endian hardware]
    if (src_len > RegisterValue::kMaxRegisterByteSize)
    {
        error.SetErrorString ("register too small to receive memory data");
        return error;
    }
    
    const uint32_t dst_len = reg_info->byte_size;
    
    if (src_len > dst_len)
    {
        error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len);
        return error;
    }
    
    ProcessSP process_sp (m_thread.GetProcess());
    if (process_sp)
    {
        uint8_t src[RegisterValue::kMaxRegisterByteSize];
       
        // Read the memory
        const uint32_t bytes_read = process_sp->ReadMemory (src_addr, src, src_len, error);

        // Make sure the memory read succeeded...
        if (bytes_read != src_len)
        {
            if (error.Success())
            {
                // This might happen if we read _some_ bytes but not all
                error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len);
            }
            return error;
        }
        
        // We now have a memory buffer that contains the part or all of the register
        // value. Set the register value using this memory data.
        // TODO: we might need to add a parameter to this function in case the byte
        // order of the memory data doesn't match the process. For now we are assuming
        // they are the same.
        reg_value.SetFromMemoryData (reg_info, 
                                     src, 
                                     src_len, 
                                     process_sp->GetByteOrder(), 
                                     error);
    }
    else
        error.SetErrorString("invalid process");

    return error;
}