[Lldb-commits] [lldb] r131610 - in /lldb/trunk: include/lldb/Core/RegisterValue.h include/lldb/Core/Scalar.h source/Core/ConnectionFileDescriptor.cpp source/Core/Scalar.cpp source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
Greg Clayton
gclayton at apple.com
Wed May 18 17:17:27 PDT 2011
Author: gclayton
Date: Wed May 18 19:17:26 2011
New Revision: 131610
URL: http://llvm.org/viewvc/llvm-project?rev=131610&view=rev
Log:
Added the ability to sign extend a Scalar at any bit position for integer
types.
Added the abilty to set a RegisterValue type via accessor and enum.
Added the ability to read arguments for a function for ARM if you are on the
first instruction in ABIMacOSX_arm.
Fixed an issue where a file descriptor becoming invalid could cause an
inifnite loop spin in the libedit thread.
Modified:
lldb/trunk/include/lldb/Core/RegisterValue.h
lldb/trunk/include/lldb/Core/Scalar.h
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
lldb/trunk/source/Core/Scalar.cpp
lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
Modified: lldb/trunk/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegisterValue.h?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegisterValue.h (original)
+++ lldb/trunk/include/lldb/Core/RegisterValue.h Wed May 18 19:17:26 2011
@@ -123,6 +123,12 @@
bool
CopyValue (const RegisterValue &rhs);
+ void
+ SetType (RegisterValue::Type type)
+ {
+ m_type = type;
+ }
+
RegisterValue::Type
SetType (const RegisterInfo *reg_info);
Modified: lldb/trunk/include/lldb/Core/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Scalar.h?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Scalar.h (original)
+++ lldb/trunk/include/lldb/Core/Scalar.h Wed May 18 19:17:26 2011
@@ -54,6 +54,9 @@
//Scalar(const RegisterValue& reg_value);
virtual ~Scalar();
+ bool
+ SignExtend (uint32_t bit_pos);
+
size_t
GetByteSize() const;
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Wed May 18 19:17:26 2011
@@ -229,7 +229,6 @@
status = eConnectionStatusSuccess;
return 0;
- case EBADF: // fildes is not a valid file or socket descriptor open for reading.
case EFAULT: // Buf points outside the allocated address space.
case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
case EINVAL: // The pointer associated with fildes was negative.
@@ -246,6 +245,7 @@
status = eConnectionStatusError;
break; // Break to close....
+ case EBADF: // fildes is not a valid file or socket descriptor open for reading.
case ENXIO: // An action is requested of a device that does not exist..
// A requested action cannot be performed by the device.
case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
@@ -391,6 +391,8 @@
switch (error.GetError())
{
case EBADF: // One of the descriptor sets specified an invalid descriptor.
+ return eConnectionStatusLostConnection;
+
case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
default: // Other unknown error
return eConnectionStatusError;
Modified: lldb/trunk/source/Core/Scalar.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Scalar.cpp?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Core/Scalar.cpp (original)
+++ lldb/trunk/source/Core/Scalar.cpp Wed May 18 19:17:26 2011
@@ -1922,6 +1922,74 @@
}
bool
+Scalar::SignExtend (uint32_t sign_bit_pos)
+{
+ const uint32_t max_bit_pos = GetByteSize() * 8;
+
+ if (sign_bit_pos < max_bit_pos)
+ {
+ switch (m_type)
+ {
+ default:
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ return false;
+
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ if (max_bit_pos == sign_bit_pos)
+ return true;
+ else if (sign_bit_pos < (max_bit_pos-1))
+ {
+ unsigned int sign_bit = 1u << sign_bit_pos;
+ if (m_data.uint & sign_bit)
+ {
+ const unsigned int mask = ~(sign_bit) + 1u;
+ m_data.uint |= mask;
+ }
+ return true;
+ }
+ break;
+
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ if (max_bit_pos == sign_bit_pos)
+ return true;
+ else if (sign_bit_pos < (max_bit_pos-1))
+ {
+ unsigned long sign_bit = 1ul << sign_bit_pos;
+ if (m_data.uint & sign_bit)
+ {
+ const unsigned long mask = ~(sign_bit) + 1ul;
+ m_data.uint |= mask;
+ }
+ return true;
+ }
+ break;
+
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ if (max_bit_pos == sign_bit_pos)
+ return true;
+ else if (sign_bit_pos < (max_bit_pos-1))
+ {
+ unsigned long long sign_bit = 1ull << sign_bit_pos;
+ if (m_data.uint & sign_bit)
+ {
+ const unsigned long long mask = ~(sign_bit) + 1ull;
+ m_data.uint |= mask;
+ }
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool
lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
{
// If either entry is void then we can just compare the types
Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=131610&r1=131609&r2=131610&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed May 18 19:17:26 2011
@@ -175,161 +175,118 @@
return true;
}
-
-static bool
-ReadIntegerArgument (Scalar &scalar,
- unsigned int bit_width,
- bool is_signed,
- Process &process,
- addr_t ¤t_stack_argument)
-{
-// if (bit_width > 64)
-// return false; // Scalar can't hold large integer arguments
-//
-// uint64_t arg_contents;
-// uint32_t read_data;
-// Error error;
-//
-// if (bit_width > 32)
-// {
-// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
-// return false;
-//
-// arg_contents = read_data;
-//
-// if (process.ReadMemory(current_stack_argument + 4, &read_data, sizeof(read_data), error) != sizeof(read_data))
-// return false;
-//
-// arg_contents |= ((uint64_t)read_data) << 32;
-//
-// current_stack_argument += 8;
-// }
-// else {
-// if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
-// return false;
-//
-// arg_contents = read_data;
-//
-// current_stack_argument += 4;
-// }
-//
-// if (is_signed)
-// {
-// switch (bit_width)
-// {
-// default:
-// return false;
-// case 8:
-// scalar = (int8_t)(arg_contents & 0xff);
-// break;
-// case 16:
-// scalar = (int16_t)(arg_contents & 0xffff);
-// break;
-// case 32:
-// scalar = (int32_t)(arg_contents & 0xffffffff);
-// break;
-// case 64:
-// scalar = (int64_t)arg_contents;
-// break;
-// }
-// }
-// else
-// {
-// switch (bit_width)
-// {
-// default:
-// return false;
-// case 8:
-// scalar = (uint8_t)(arg_contents & 0xff);
-// break;
-// case 16:
-// scalar = (uint16_t)(arg_contents & 0xffff);
-// break;
-// case 32:
-// scalar = (uint32_t)(arg_contents & 0xffffffff);
-// break;
-// case 64:
-// scalar = (uint64_t)arg_contents;
-// break;
-// }
-// }
-//
-// return true;
- return false;
-}
-
bool
ABIMacOSX_arm::GetArgumentValues (Thread &thread,
ValueList &values) const
{
-// unsigned int num_values = values.GetSize();
-// unsigned int value_index;
-//
-// // Extract the Clang AST context from the PC so that we can figure out type
-// // sizes
-//
-// clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
-//
-// // Get the pointer to the first stack argument so we have a place to start
-// // when reading data
-//
-// RegisterContext *reg_ctx = thread.GetRegisterContext().get();
-//
-// if (!reg_ctx)
-// return false;
-//
-// addr_t sp = reg_ctx->GetSP(0);
-//
-// if (!sp)
-// return false;
-//
-// addr_t current_stack_argument = sp + 4; // jump over return address
-//
-// for (value_index = 0;
-// value_index < num_values;
-// ++value_index)
-// {
-// Value *value = values.GetValueAtIndex(value_index);
-//
-// if (!value)
-// return false;
-//
-// // We currently only support extracting values with Clang QualTypes.
-// // Do we care about others?
-// switch (value->GetContextType())
-// {
-// default:
-// return false;
-// case Value::eContextTypeClangType:
-// {
-// void *value_type = value->GetClangType();
-// bool is_signed;
-//
-// if (ClangASTContext::IsIntegerType (value_type, is_signed))
-// {
-// size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-//
-// ReadIntegerArgument(value->GetScalar(),
-// bit_width,
-// is_signed,
-// thread.GetProcess(),
-// current_stack_argument);
-// }
-// else if (ClangASTContext::IsPointerType (value_type))
-// {
-// ReadIntegerArgument(value->GetScalar(),
-// 32,
-// false,
-// thread.GetProcess(),
-// current_stack_argument);
-// }
-// }
-// break;
-// }
-// }
-//
-// return true;
- return false;
+ uint32_t num_values = values.GetSize();
+
+
+ // For now, assume that the types in the AST values come from the Target's
+ // scratch AST.
+
+ clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+
+ // Extract the register context so we can read arguments from registers
+
+ RegisterContext *reg_ctx = thread.GetRegisterContext().get();
+
+ if (!reg_ctx)
+ return false;
+
+ bool arg_regs_exceeded = false;
+
+ addr_t sp = reg_ctx->GetSP(0);
+
+ if (!sp)
+ return false;
+
+ for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
+ {
+ // We currently only support extracting values with Clang QualTypes.
+ // Do we care about others?
+ Value *value = values.GetValueAtIndex(value_idx);
+
+ if (!value)
+ return false;
+
+ void *value_type = value->GetClangType();
+ if (value_type)
+ {
+ bool is_signed = false;
+ size_t bit_width = 0;
+ if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ {
+ bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ }
+ else if (ClangASTContext::IsPointerOrReferenceType (value_type))
+ {
+ bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ }
+ else
+ {
+ // We only handle integer, pointer and reference types currently...
+ return false;
+ }
+
+ if (bit_width <= (thread.GetProcess().GetAddressByteSize() * 8))
+ {
+ if (!arg_regs_exceeded)
+ {
+ uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+ if (arg_reg_num == LLDB_INVALID_REGNUM)
+ {
+ arg_regs_exceeded = true;
+ }
+ else
+ {
+ const RegisterInfo *arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
+ {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
+ return false;
+ continue;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+
+ const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
+ if (arg_byte_size <= sizeof(uint64_t))
+ {
+ uint8_t arg_data[sizeof(uint64_t)];
+ Error error;
+ thread.GetProcess().ReadMemory(sp, arg_data, sizeof(arg_data), error);
+ DataExtractor arg_data_extractor (arg_data, sizeof(arg_data),
+ thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(),
+ thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
+ uint32_t offset = 0;
+ if (arg_byte_size <= 4)
+ value->GetScalar() = arg_data_extractor.GetMaxU32 (&offset, arg_byte_size);
+ else if (arg_byte_size <= 8)
+ value->GetScalar() = arg_data_extractor.GetMaxU64 (&offset, arg_byte_size);
+ else
+ return false;
+
+ if (offset == 0 || offset == UINT32_MAX)
+ return false;
+
+ if (is_signed)
+ value->GetScalar().SignExtend (bit_width);
+ sp += arg_byte_size;
+ }
+ }
+ }
+ }
+ return true;
}
bool
More information about the lldb-commits
mailing list