Ejemplo n.º 1
0
static bool
IsPointerValue (const CompilerType &type)
{
    Flags type_flags(type.GetTypeInfo());
    if (type_flags.AnySet(eTypeIsPointer))
        return type_flags.AllClear(eTypeIsBuiltIn);
    return false;
}
Ejemplo n.º 2
0
ValueObjectSP
ABISysV_i386::GetReturnValueObjectSimple (Thread &thread,
                                          CompilerType &return_clang_type) const
{
    ValueObjectSP return_valobj_sp;
    Value value;

    if (!return_clang_type)
        return return_valobj_sp;

    value.SetCompilerType (return_clang_type);

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;

    const uint32_t type_flags = return_clang_type.GetTypeInfo ();

    unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
    unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];


    // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
    // The terminology 'Fundamental Data Types' used here is adopted from
    // Table 2.1 of the reference document (specified on top of this file)

    if (type_flags & eTypeIsPointer)     // 'Pointer'
    {
        uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
        value.SetValueType(Value::eValueTypeScalar);
        value.GetScalar() = ptr;
        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                           value,
                                                           ConstString(""));
    }

    else if ((type_flags & eTypeIsScalar) || (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
    {
        value.SetValueType(Value::eValueTypeScalar);
        const size_t byte_size = return_clang_type.GetByteSize(nullptr);
        bool success = false;

        if (type_flags & eTypeIsInteger)    // 'Integral' except enum
        {
            const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
            raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;

            switch (byte_size)
            {
                default:
                   break;

                case 16:
                   // For clang::BuiltinType::UInt128 & Int128
                   // ToDo: Need to decide how to handle it
                   break ;

                case 8:
                    if (is_signed)
                        value.GetScalar() = (int64_t)(raw_value);
                    else
                        value.GetScalar() = (uint64_t)(raw_value);
                    success = true;
                    break;

                case 4:
                    if (is_signed)
                        value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
                    else
                        value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
                    success = true;
                    break;

                case 2:
                    if (is_signed)
                        value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
                    else
                        value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
                    success = true;
                    break;

                case 1:
                    if (is_signed)
                        value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
                    else
                        value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
                    success = true;
                    break;
             }

             if (success)
                 return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                                    value,
                                                                    ConstString(""));
        }

        else if (type_flags & eTypeIsEnumeration)     // handles enum
        {
            uint32_t enm = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff ;
            value.SetValueType(Value::eValueTypeScalar);
            value.GetScalar() = enm;
            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                               value,
                                                               ConstString(""));
        }

        else if (type_flags & eTypeIsFloat)  // 'Floating Point'
        {
            if (byte_size <= 12)      // handles float, double, long double, __float80
            {
                const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
                RegisterValue st0_value;

                if (reg_ctx->ReadRegister (st0_info, st0_value))
                {
                    DataExtractor data;
                    if (st0_value.GetData(data))
                    {
                        lldb::offset_t offset = 0;
                        long double value_long_double = data.GetLongDouble(&offset);

                        if (byte_size == 4)    // float is 4 bytes
                        {
                            float value_float = (float)value_long_double;
                            value.GetScalar() = value_float;
                            success = true;
                        }
                        else if (byte_size == 8)   // double is 8 bytes
                        {
                            // On Android Platform: long double is also 8 bytes
                            // It will be handled here only.
                            double value_double = (double)value_long_double;
                            value.GetScalar() =  value_double;
                            success = true;
                        }
                        else if (byte_size == 12) // long double and __float80 are 12 bytes on i386
                        {
                            value.GetScalar() = value_long_double;
                            success = true;
                        }
                    }
                }

                if (success)
                    return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                                       value,
                                                                       ConstString(""));
            }
            else if(byte_size == 16)   // handles __float128
            {
                lldb::addr_t storage_addr = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
                return_valobj_sp = ValueObjectMemory::Create (&thread,
                                                               "",
                                                              Address (storage_addr, nullptr),
                                                              return_clang_type);
            }
        }

        else  // Neither 'Integral' nor 'Floating Point'
        {
            // If flow reaches here then check type_flags
            // This type_flags is unhandled
        }
    }

    else if (type_flags & eTypeIsComplex)    // 'Complex Floating Point'
    {
       // ToDo: Yet to be implemented
    }

    else if (type_flags & eTypeIsVector)    // 'Packed'
    {
        const size_t byte_size = return_clang_type.GetByteSize(nullptr);
        if (byte_size > 0)
        {
            const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
            if (vec_reg == nullptr)
                vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);

            if (vec_reg)
            {
                if (byte_size <= vec_reg->byte_size)
                {
                    ProcessSP process_sp (thread.GetProcess());
                    if (process_sp)
                    {
                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
                        const ByteOrder byte_order = process_sp->GetByteOrder();
                        RegisterValue reg_value;
                        if (reg_ctx->ReadRegister(vec_reg, reg_value))
                        {
                            Error error;
                            if (reg_value.GetAsMemoryData (vec_reg,
                                                           heap_data_ap->GetBytes(),
                                                           heap_data_ap->GetByteSize(),
                                                           byte_order,
                                                           error))
                            {
                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
                                                    byte_order,
                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
                                                                                   return_clang_type,
                                                                                   ConstString(""),
                                                                                   data);
                            }
                        }
                    }
                }
                else if (byte_size <= vec_reg->byte_size*2)
                {
                    const RegisterInfo *vec_reg2 = reg_ctx->GetRegisterInfoByName("xmm1", 0);
                    if (vec_reg2)
                    {
                        ProcessSP process_sp (thread.GetProcess());
                        if (process_sp)
                        {
                            std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
                            const ByteOrder byte_order = process_sp->GetByteOrder();
                            RegisterValue reg_value;
                            RegisterValue reg_value2;
                            if (reg_ctx->ReadRegister(vec_reg, reg_value) && reg_ctx->ReadRegister(vec_reg2, reg_value2))
                            {

                                Error error;
                                if (reg_value.GetAsMemoryData (vec_reg,
                                                               heap_data_ap->GetBytes(),
                                                               vec_reg->byte_size,
                                                               byte_order,
                                                               error) &&
                                    reg_value2.GetAsMemoryData (vec_reg2,
                                                                heap_data_ap->GetBytes() + vec_reg->byte_size,
                                                                heap_data_ap->GetByteSize() - vec_reg->byte_size,
                                                                byte_order,
                                                                error))
                                {
                                    DataExtractor data (DataBufferSP (heap_data_ap.release()),
                                                        byte_order,
                                                        process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
                                    return_valobj_sp = ValueObjectConstResult::Create (&thread,
                                                                                       return_clang_type,
                                                                                       ConstString(""),
                                                                                       data);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    else    // 'Decimal Floating Point'
    {
       //ToDo: Yet to be implemented
    }
    return return_valobj_sp;
}
Ejemplo n.º 3
0
ValueObjectSP ABISysV_ppc64::GetReturnValueObjectSimple(
    Thread &thread, CompilerType &return_compiler_type) const {
  ValueObjectSP return_valobj_sp;
  Value value;

  if (!return_compiler_type)
    return return_valobj_sp;

  // value.SetContext (Value::eContextTypeClangType, return_value_type);
  value.SetCompilerType(return_compiler_type);

  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
  if (!reg_ctx)
    return return_valobj_sp;

  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
  if (type_flags & eTypeIsScalar) {
    value.SetValueType(Value::eValueTypeScalar);

    bool success = false;
    if (type_flags & eTypeIsInteger) {
      // Extract the register context so we can read arguments from registers

      const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
      uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
          reg_ctx->GetRegisterInfoByName("r3", 0), 0);
      const bool is_signed = (type_flags & eTypeIsSigned) != 0;
      switch (byte_size) {
      default:
        break;

      case sizeof(uint64_t):
        if (is_signed)
          value.GetScalar() = (int64_t)(raw_value);
        else
          value.GetScalar() = (uint64_t)(raw_value);
        success = true;
        break;

      case sizeof(uint32_t):
        if (is_signed)
          value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
        else
          value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
        success = true;
        break;

      case sizeof(uint16_t):
        if (is_signed)
          value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
        else
          value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
        success = true;
        break;

      case sizeof(uint8_t):
        if (is_signed)
          value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
        else
          value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
        success = true;
        break;
      }
    } else if (type_flags & eTypeIsFloat) {
      if (type_flags & eTypeIsComplex) {
        // Don't handle complex yet.
      } else {
        const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
        if (byte_size <= sizeof(long double)) {
          const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
          RegisterValue f1_value;
          if (reg_ctx->ReadRegister(f1_info, f1_value)) {
            DataExtractor data;
            if (f1_value.GetData(data)) {
              lldb::offset_t offset = 0;
              if (byte_size == sizeof(float)) {
                value.GetScalar() = (float)data.GetFloat(&offset);
                success = true;
              } else if (byte_size == sizeof(double)) {
                value.GetScalar() = (double)data.GetDouble(&offset);
                success = true;
              }
            }
          }
        }
      }
    }

    if (success)
      return_valobj_sp = ValueObjectConstResult::Create(
          thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
  } else if (type_flags & eTypeIsPointer) {
    unsigned r3_id =
        reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
    value.GetScalar() =
        (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
    value.SetValueType(Value::eValueTypeScalar);
    return_valobj_sp = ValueObjectConstResult::Create(
        thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
  } else if (type_flags & eTypeIsVector) {
    const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
    if (byte_size > 0) {
      const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
      if (altivec_reg) {
        if (byte_size <= altivec_reg->byte_size) {
          ProcessSP process_sp(thread.GetProcess());
          if (process_sp) {
            std::unique_ptr<DataBufferHeap> heap_data_ap(
                new DataBufferHeap(byte_size, 0));
            const ByteOrder byte_order = process_sp->GetByteOrder();
            RegisterValue reg_value;
            if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
              Status error;
              if (reg_value.GetAsMemoryData(
                      altivec_reg, heap_data_ap->GetBytes(),
                      heap_data_ap->GetByteSize(), byte_order, error)) {
                DataExtractor data(DataBufferSP(heap_data_ap.release()),
                                   byte_order, process_sp->GetTarget()
                                                   .GetArchitecture()
                                                   .GetAddressByteSize());
                return_valobj_sp = ValueObjectConstResult::Create(
                    &thread, return_compiler_type, ConstString(""), data);
              }
            }
          }
        }
      }
    }
  }

  return return_valobj_sp;
}
Ejemplo n.º 4
0
ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
    Thread &thread, CompilerType &return_compiler_type) const {
  ValueObjectSP return_valobj_sp;
  Value value;

  if (!return_compiler_type)
    return return_valobj_sp;

  // value.SetContext (Value::eContextTypeClangType, return_value_type);
  value.SetCompilerType(return_compiler_type);

  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
  if (!reg_ctx)
    return return_valobj_sp;

  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
  if (type_flags & eTypeIsScalar) {
    value.SetValueType(Value::eValueTypeScalar);

    bool success = false;
    if (type_flags & eTypeIsInteger) {
      // Extract the register context so we can read arguments from registers.
      llvm::Optional<uint64_t> byte_size =
          return_compiler_type.GetByteSize(nullptr);
      if (!byte_size)
        return return_valobj_sp;
      uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
          reg_ctx->GetRegisterInfoByName("r2", 0), 0);
      const bool is_signed = (type_flags & eTypeIsSigned) != 0;
      switch (*byte_size) {
      default:
        break;

      case sizeof(uint64_t):
        if (is_signed)
          value.GetScalar() = (int64_t)(raw_value);
        else
          value.GetScalar() = (uint64_t)(raw_value);
        success = true;
        break;

      case sizeof(uint32_t):
        if (is_signed)
          value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
        else
          value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
        success = true;
        break;

      case sizeof(uint16_t):
        if (is_signed)
          value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
        else
          value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
        success = true;
        break;

      case sizeof(uint8_t):
        if (is_signed)
          value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
        else
          value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
        success = true;
        break;
      }
    } else if (type_flags & eTypeIsFloat) {
      if (type_flags & eTypeIsComplex) {
        // Don't handle complex yet.
      } else {
        llvm::Optional<uint64_t> byte_size =
            return_compiler_type.GetByteSize(nullptr);
        if (byte_size && *byte_size <= sizeof(long double)) {
          const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
          RegisterValue f0_value;
          if (reg_ctx->ReadRegister(f0_info, f0_value)) {
            DataExtractor data;
            if (f0_value.GetData(data)) {
              lldb::offset_t offset = 0;
              if (*byte_size == sizeof(float)) {
                value.GetScalar() = (float)data.GetFloat(&offset);
                success = true;
              } else if (*byte_size == sizeof(double)) {
                value.GetScalar() = (double)data.GetDouble(&offset);
                success = true;
              } else if (*byte_size == sizeof(long double)) {
                // Don't handle long double yet.
              }
            }
          }
        }
      }
    }

    if (success)
      return_valobj_sp = ValueObjectConstResult::Create(
          thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
  } else if (type_flags & eTypeIsPointer) {
    unsigned r2_id =
        reg_ctx->GetRegisterInfoByName("r2", 0)->kinds[eRegisterKindLLDB];
    value.GetScalar() =
        (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_id, 0);
    value.SetValueType(Value::eValueTypeScalar);
    return_valobj_sp = ValueObjectConstResult::Create(
        thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
  }

  return return_valobj_sp;
}