diff options
author | Greg Clayton <gclayton@apple.com> | 2011-05-22 22:46:53 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2011-05-22 22:46:53 +0000 |
commit | f3ef3d2af95e8cd20bb9bd9aeceb24b4bf8107ca (patch) | |
tree | 1614e0a38827a33bfae37302a3567c9cec8a391b | |
parent | 5c51177981f6e482dbf2a99700fa8bc801f53401 (diff) | |
download | bcm5719-llvm-f3ef3d2af95e8cd20bb9bd9aeceb24b4bf8107ca.tar.gz bcm5719-llvm-f3ef3d2af95e8cd20bb9bd9aeceb24b4bf8107ca.zip |
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
21 files changed, 458 insertions, 560 deletions
diff --git a/lldb/include/lldb/Core/Scalar.h b/lldb/include/lldb/Core/Scalar.h index 3c22ce04379..1b6a6e710af 100644 --- a/lldb/include/lldb/Core/Scalar.h +++ b/lldb/include/lldb/Core/Scalar.h @@ -63,12 +63,18 @@ public: static size_t GetMaxByteSize() { - return std::max (sizeof(long double), sizeof (unsigned long long)); + return sizeof(ValueData); } bool GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const; + uint32_t + GetAsMemoryData (void *dst, + uint32_t dst_len, + lldb::ByteOrder dst_byte_order, + Error &error) const; + bool IsZero() const; diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 2e82f422bf0..bd7c9c444d8 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -2083,6 +2083,9 @@ public: /// @param[in] byte_size /// The size in byte of the integer to read. /// + /// @param[in] fail_value + /// The value to return if we fail to read an integer. + /// /// @param[out] error /// An error that indicates the success or failure of this /// operation. If error indicates success (error.Success()), @@ -2098,9 +2101,20 @@ public: /// order. //------------------------------------------------------------------ uint64_t - ReadUnsignedInteger (lldb::addr_t load_addr, - size_t byte_size, - Error &error); + ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr, + size_t byte_size, + uint64_t fail_value, + Error &error); + + lldb::addr_t + ReadPointerFromMemory (lldb::addr_t vm_addr, + Error &error); + + bool + WritePointerToMemory (lldb::addr_t vm_addr, + lldb::addr_t ptr_value, + Error &error); + //------------------------------------------------------------------ /// Actually do the writing of memory to a process. /// @@ -2115,6 +2129,9 @@ public: /// @param[in] size /// The number of bytes to write. /// + /// @param[out] error + /// An error value in case the memory write fails. + /// /// @return /// The number of bytes that were actually written. //------------------------------------------------------------------ @@ -2122,6 +2139,51 @@ public: DoWriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) = 0; //------------------------------------------------------------------ + /// Write all or part of a scalar value to memory. + /// + /// The value contained in \a scalar will be swapped to match the + /// byte order of the process that is being debugged. If \a size is + /// less than the size of scalar, the least significate \a size bytes + /// from scalar will be written. If \a size is larger than the byte + /// size of scalar, then the extra space will be padded with zeros + /// and the scalar value will be placed in the least significant + /// bytes in memory. + /// + /// @param[in] vm_addr + /// A virtual load address that indicates where to start writing + /// memory to. + /// + /// @param[in] scalar + /// The scalar to write to the debugged process. + /// + /// @param[in] size + /// This value can be smaller or larger than the scalar value + /// itself. If \a size is smaller than the size of \a scalar, + /// the least significant bytes in \a scalar will be used. If + /// \a size is larger than the byte size of \a scalar, then + /// the extra space will be padded with zeros. If \a size is + /// set to UINT32_MAX, then the size of \a scalar will be used. + /// + /// @param[out] error + /// An error value in case the memory write fails. + /// + /// @return + /// The number of bytes that were actually written. + //------------------------------------------------------------------ + size_t + WriteScalarToMemory (lldb::addr_t vm_addr, + const Scalar &scalar, + uint32_t size, + Error &error); + + size_t + ReadScalarIntegerFromMemory (lldb::addr_t addr, + uint32_t byte_size, + bool is_signed, + Scalar &scalar, + Error &error); + + //------------------------------------------------------------------ /// Write memory to a process. /// /// This function will write memory to the current process's diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 316eb1d0061..5a670808a23 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -280,6 +280,36 @@ public: void ModulesDidUnload (ModuleList &module_list); + + //------------------------------------------------------------------ + /// Get \a load_addr as a callable code load address for this target + /// + /// Take \a load_addr and potentially add any address bits that are + /// needed to make the address callable. For ARM this can set bit + /// zero (if it already isn't) if \a load_addr is a thumb function. + /// If \a addr_class is set to eAddressClassInvalid, then the address + /// adjustment will always happen. If it is set to an address class + /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be + /// returned. + //------------------------------------------------------------------ + lldb::addr_t + GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class = lldb_private::eAddressClassInvalid) const; + + //------------------------------------------------------------------ + /// Get \a load_addr as an opcode for this target. + /// + /// Take \a load_addr and potentially strip any address bits that are + /// needed to make the address point to an opcode. For ARM this can + /// clear bit zero (if it already isn't) if \a load_addr is a + /// thumb function and load_addr is in code. + /// If \a addr_class is set to eAddressClassInvalid, then the address + /// adjustment will always happen. If it is set to an address class + /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be + /// returned. + //------------------------------------------------------------------ + lldb::addr_t + GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class = lldb_private::eAddressClassInvalid) const; + protected: void ModuleAdded (lldb::ModuleSP &module_sp); diff --git a/lldb/include/lldb/Target/ThreadPlanRunToAddress.h b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h index bb6f1bc647c..7559f15e9f0 100644 --- a/lldb/include/lldb/Target/ThreadPlanRunToAddress.h +++ b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h @@ -33,7 +33,7 @@ public: bool stop_others); ThreadPlanRunToAddress (Thread &thread, - std::vector<lldb::addr_t> &addresses, + const std::vector<lldb::addr_t> &addresses, bool stop_others); diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp index 388da6bdf6c..5f5a8fab44e 100644 --- a/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -36,7 +36,7 @@ BreakpointLocation::BreakpointLocation lldb::tid_t tid, bool hardware ) : - StoppointLocation (loc_id, addr.GetLoadAddress(&owner.GetTarget()), hardware), + StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware), m_address (addr), m_owner (owner), m_options_ap (), @@ -53,7 +53,7 @@ BreakpointLocation::~BreakpointLocation() lldb::addr_t BreakpointLocation::GetLoadAddress () const { - return m_address.GetLoadAddress(&m_owner.GetTarget()); + return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); } Address & @@ -290,7 +290,7 @@ BreakpointLocation::ResolveBreakpointSite () LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); if (log) log->Warning ("Tried to add breakpoint site at 0x%llx but it was already present.\n", - m_address.GetLoadAddress(&m_owner.GetTarget())); + m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); return false; } @@ -438,7 +438,7 @@ BreakpointLocation::Dump(Stream *s) const "hw_index = %i hit_count = %-4u ignore_count = %-4u", GetID(), GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), - (uint64_t) m_address.GetLoadAddress (&m_owner.GetTarget()), + (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", IsHardware() ? "hardware" : "software", GetHardwareIndex(), diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index d4b80923029..49d38ad5c61 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -300,37 +300,9 @@ addr_t Address::GetCallableLoadAddress (Target *target) const { addr_t code_addr = GetLoadAddress (target); - - // Make sure we have section, otherwise the call to GetAddressClass() will - // fail because it uses the section to get to the module. - if (m_section && code_addr != LLDB_INVALID_ADDRESS) - { - switch (target->GetArchitecture().GetMachine()) - { - case llvm::Triple::arm: - case llvm::Triple::thumb: - // Check if bit zero it no set? - if ((code_addr & 1ull) == 0) - { - // Bit zero isn't set, check if the address is a multiple of 2? - if (code_addr & 2ull) - { - // The address is a multiple of 2 so it must be thumb, set bit zero - code_addr |= 1ull; - } - else if (GetAddressClass() == eAddressClassCodeAlternateISA) - { - // We checked the address and the address claims to be the alternate ISA - // which means thumb, so set bit zero. - code_addr |= 1ull; - } - } - break; - - default: - break; - } - } + + if (target) + return target->GetCallableLoadAddress (code_addr, GetAddressClass()); return code_addr; } @@ -339,57 +311,19 @@ Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target) { if (SetLoadAddress (load_addr, target)) { - switch (target->GetArchitecture().GetMachine()) - { - case llvm::Triple::arm: - case llvm::Triple::thumb: - // Check if bit zero it no set? - if ((m_offset & 1ull) == 0) - { - // Bit zero isn't set, check if the address is a multiple of 2? - if (m_offset & 2ull) - { - // The address is a multiple of 2 so it must be thumb, set bit zero - m_offset |= 1ull; - } - else if (GetAddressClass() == eAddressClassCodeAlternateISA) - { - // We checked the address and the address claims to be the alternate ISA - // which means thumb, so set bit zero. - m_offset |= 1ull; - } - } - break; - - default: - break; - } + if (target) + m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass()); return true; } return false; } - - addr_t Address::GetOpcodeLoadAddress (Target *target) const { addr_t code_addr = GetLoadAddress (target); - if (code_addr != LLDB_INVALID_ADDRESS) - { - switch (target->GetArchitecture().GetMachine()) - { - case llvm::Triple::arm: - case llvm::Triple::thumb: - // Strip bit zero to make sure we end up on an opcode boundary - return code_addr & ~(1ull); - break; - - default: - break; - } - } + code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass()); return code_addr; } @@ -398,17 +332,8 @@ Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target) { if (SetLoadAddress (load_addr, target)) { - switch (target->GetArchitecture().GetMachine()) - { - case llvm::Triple::arm: - case llvm::Triple::thumb: - // Make sure bit zero is clear - m_offset &= ~(1ull); - break; - - default: - break; - } + if (target) + m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass()); return true; } return false; diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 9c07dc9c9fc..8ce7b8f3224 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -1063,7 +1063,7 @@ DataExtractor::CopyByteOrderedData (uint32_t src_offset, const uint8_t* src = (const uint8_t *)PeekData (src_offset, src_len); if (src) { - if (src_len >= dst_len) + if (dst_len >= src_len) { // We are copying the entire value from src into dst. // Calculate how many, if any, zeroes we need for the most diff --git a/lldb/source/Core/Scalar.cpp b/lldb/source/Core/Scalar.cpp index ee5c941540f..fb5769f55ff 100644 --- a/lldb/source/Core/Scalar.cpp +++ b/lldb/source/Core/Scalar.cpp @@ -1989,6 +1989,34 @@ Scalar::SignExtend (uint32_t sign_bit_pos) return false; } +uint32_t +Scalar::GetAsMemoryData (void *dst, + uint32_t dst_len, + lldb::ByteOrder dst_byte_order, + Error &error) const +{ + // Get a data extractor that points to the native scalar data + DataExtractor data; + if (!GetData(data)) + { + error.SetErrorString ("invalid scalar value"); + return 0; + } + + const size_t src_len = data.GetByteSize(); + + // Prepare a memory buffer that contains some or all of the register value + const uint32_t bytes_copied = data.CopyByteOrderedData (0, // src offset + src_len, // src length + dst, // dst buffer + dst_len, // dst length + dst_byte_order); // dst byte order + if (bytes_copied == 0) + error.SetErrorString ("failed to copy data"); + + return bytes_copied; +} + bool lldb_private::operator== (const Scalar& lhs, const Scalar& rhs) { diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 7131abf69ff..e89942566cb 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -680,7 +680,6 @@ ClangExpressionDeclMap::GetObjectPointer { lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize(); - lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder(); if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8) @@ -689,22 +688,13 @@ ClangExpressionDeclMap::GetObjectPointer return false; } - DataBufferHeap data; - data.SetByteSize(address_byte_size); Error read_error; - - if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size) + object_ptr = exe_ctx.process->ReadPointerFromMemory (value_addr, read_error); + if (read_error.Fail() || object_ptr == LLDB_INVALID_ADDRESS) { err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString()); return false; - } - - DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size); - - uint32_t offset = 0; - - object_ptr = extractor.GetPointer(&offset); - + } return true; } case Value::eValueTypeScalar: @@ -812,16 +802,18 @@ ClangExpressionDeclMap::DumpMaterializedStruct return false; } - lldb::DataBufferSP data(new DataBufferHeap(m_struct_vars->m_struct_size, 0)); + lldb::DataBufferSP data_sp(new DataBufferHeap(m_struct_vars->m_struct_size, 0)); Error error; - if (exe_ctx.process->ReadMemory (m_material_vars->m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize()) + if (exe_ctx.process->ReadMemory (m_material_vars->m_materialized_location, + data_sp->GetBytes(), + data_sp->GetByteSize(), error) != data_sp->GetByteSize()) { err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString()); return false; } - DataExtractor extractor(data, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize()); + DataExtractor extractor(data_sp, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize()); for (size_t member_idx = 0, num_members = m_struct_members.GetSize(); member_idx < num_members; @@ -1000,63 +992,6 @@ ClangExpressionDeclMap::DoMaterialize return true; } -static bool WriteAddressInto -( - ExecutionContext &exe_ctx, - lldb::addr_t target, - lldb::addr_t address, - Error &err -) -{ - size_t pointer_byte_size = exe_ctx.process->GetAddressByteSize(); - - StreamString str (0 | Stream::eBinary, - pointer_byte_size, - exe_ctx.process->GetByteOrder()); - - switch (pointer_byte_size) - { - default: - assert(!"Unhandled byte size"); - case 4: - { - uint32_t address32 = address & 0xffffffffll; - str.PutRawBytes(&address32, sizeof(address32), endian::InlHostByteOrder(), eByteOrderInvalid); - } - break; - case 8: - { - uint64_t address64 = address; - str.PutRawBytes(&address64, sizeof(address64), endian::InlHostByteOrder(), eByteOrderInvalid); - } - break; - } - - return (exe_ctx.process->WriteMemory (target, str.GetData(), pointer_byte_size, err) == pointer_byte_size); -} - -static lldb::addr_t ReadAddressFrom -( - ExecutionContext &exe_ctx, - lldb::addr_t source, - Error &err -) -{ - size_t pointer_byte_size = exe_ctx.process->GetAddressByteSize(); - - DataBufferHeap *buf = new DataBufferHeap(pointer_byte_size, 0); - DataBufferSP buf_sp(buf); - - if (exe_ctx.process->ReadMemory (source, buf->GetBytes(), pointer_byte_size, err) != pointer_byte_size) - return LLDB_INVALID_ADDRESS; - - DataExtractor extractor (buf_sp, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize()); - - uint32_t offset = 0; - - return (lldb::addr_t)extractor.GetPointer(&offset); -} - bool ClangExpressionDeclMap::DoMaterializeOnePersistentVariable ( @@ -1098,7 +1033,7 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable // Get the location of the target out of the struct. Error read_error; - mem = ReadAddressFrom(exe_ctx, addr, read_error); + mem = exe_ctx.process->ReadPointerFromMemory (addr, read_error); if (mem == LLDB_INVALID_ADDRESS) { @@ -1243,19 +1178,19 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable if ((var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && var_sp->m_live_sp) || var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) { - mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong(); - // Now write the location of the area into the struct. - Error write_error; - if (!WriteAddressInto(exe_ctx, addr, mem, write_error)) + if (!exe_ctx.process->WriteScalarToMemory (addr, + var_sp->m_live_sp->GetValue().GetScalar(), + exe_ctx.process->GetAddressByteSize(), + write_error)) { err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString()); return false; } if (log) - log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), (uint64_t)mem); + log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), var_sp->m_live_sp->GetValue().GetScalar().ULongLong()); } else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) { @@ -1308,7 +1243,8 @@ ClangExpressionDeclMap::DoMaterializeOneVariable if (!GetSymbolAddress(*exe_ctx.target, name, location_load_addr)) { if (log) - err.SetErrorStringWithFormat("Couldn't find value for global symbol %s", name.GetCString()); + err.SetErrorStringWithFormat ("Couldn't find value for global symbol %s", + name.GetCString()); } location_value->SetValueType(Value::eValueTypeLoadAddress); @@ -1316,7 +1252,8 @@ ClangExpressionDeclMap::DoMaterializeOneVariable } else { - err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString()); + err.SetErrorStringWithFormat ("Couldn't find %s with appropriate type", + name.GetCString()); return false; } @@ -1328,7 +1265,10 @@ ClangExpressionDeclMap::DoMaterializeOneVariable type.GetOpaqueQualType(), &my_stream_string); - log->Printf("%s %s with type %s", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), my_stream_string.GetString().c_str()); + log->Printf ("%s %s with type %s", + dematerialize ? "Dematerializing" : "Materializing", + name.GetCString(), + my_stream_string.GetString().c_str()); } if (!location_value.get()) @@ -1352,7 +1292,9 @@ ClangExpressionDeclMap::DoMaterializeOneVariable location_value->Dump(&ss); - err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str()); + err.SetErrorStringWithFormat ("%s has a value of unhandled type: %s", + name.GetCString(), + ss.GetString().c_str()); return false; } break; @@ -1360,16 +1302,16 @@ ClangExpressionDeclMap::DoMaterializeOneVariable { if (!dematerialize) { - lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); - - Error error; + Error write_error; - if (!WriteAddressInto(exe_ctx, - addr, - value_addr, - error)) + if (!exe_ctx.process->WriteScalarToMemory (addr, + location_value->GetScalar(), + exe_ctx.process->GetAddressByteSize(), + write_error)) { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString()); + err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", + name.GetCString(), + write_error.AsCString()); return false; } } @@ -1382,17 +1324,18 @@ ClangExpressionDeclMap::DoMaterializeOneVariable StreamString ss; location_value->Dump(&ss); - err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str()); + err.SetErrorStringWithFormat ("%s is a scalar of unhandled type: %s", + name.GetCString(), + ss.GetString().c_str()); return false; } - lldb::addr_t reg_addr = LLDB_INVALID_ADDRESS; // The address of a spare memory area aused to hold the variable. - RegisterInfo *reg_info = location_value->GetRegisterInfo(); if (!reg_info) { - err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString()); + err.SetErrorStringWithFormat ("Couldn't get the register information for %s", + name.GetCString()); return false; } @@ -1402,7 +1345,9 @@ ClangExpressionDeclMap::DoMaterializeOneVariable if (!reg_ctx) { - err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), reg_info->name); + err.SetErrorStringWithFormat ("Couldn't read register context to read %s from %s", + name.GetCString(), + reg_info->name); return false; } @@ -1424,25 +1369,32 @@ ClangExpressionDeclMap::DoMaterializeOneVariable return false; } - reg_addr = expr_var->m_live_sp->GetValue().GetScalar().ULongLong(); + Scalar ®_addr = expr_var->m_live_sp->GetValue().GetScalar(); - err = reg_ctx->ReadRegisterValueFromMemory (reg_info, reg_addr, value_byte_size, reg_value); + err = reg_ctx->ReadRegisterValueFromMemory (reg_info, + reg_addr.ULongLong(), + value_byte_size, + reg_value); if (err.Fail()) return false; if (!reg_ctx->WriteRegister (reg_info, reg_value)) { - err.SetErrorStringWithFormat("Couldn't write %s to register %s", name.GetCString(), reg_info->name); + err.SetErrorStringWithFormat ("Couldn't write %s to register %s", + name.GetCString(), + reg_info->name); return false; } // Deallocate the spare area and clear the variable's live data. - Error deallocate_error = exe_ctx.process->DeallocateMemory(reg_addr); + Error deallocate_error = exe_ctx.process->DeallocateMemory(reg_addr.ULongLong()); if (!deallocate_error.Success()) { - err.SetErrorStringWithFormat("Couldn't deallocate spare memory area for %s: %s", name.GetCString(), deallocate_error.AsCString()); + err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s", + name.GetCString(), + deallocate_error.AsCString()); return false; } @@ -1455,13 +1407,15 @@ ClangExpressionDeclMap::DoMaterializeOneVariable Error allocate_error; - reg_addr = exe_ctx.process->AllocateMemory (value_byte_size, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - allocate_error); + Scalar reg_addr (exe_ctx.process->AllocateMemory (value_byte_size, + lldb::ePermissionsReadable | lldb::ePermissionsWritable, + allocate_error)); - if (reg_addr == LLDB_INVALID_ADDRESS) + if (reg_addr.ULongLong() == LLDB_INVALID_ADDRESS) { - err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", name.GetCString(), allocate_error.AsCString()); + err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s", + name.GetCString(), + allocate_error.AsCString()); return false; } @@ -1471,66 +1425,47 @@ ClangExpressionDeclMap::DoMaterializeOneVariable type.GetASTContext(), type.GetOpaqueQualType(), name, - reg_addr, + reg_addr.ULongLong(), eAddressTypeLoad, value_byte_size); // Now write the location of the area into the struct. Error write_error; - if (!WriteAddressInto(exe_ctx, addr, reg_addr, write_error)) + + if (!exe_ctx.process->WriteScalarToMemory (addr, + reg_addr, + exe_ctx.process->GetAddressByteSize(), + write_error)) { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), write_error.AsCString()); + err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", + name.GetCString(), + write_error.AsCString()); return false; } - // Moving from a register into addr - // - // Case 1: addr_byte_size and register_byte_size are the same - // - // |AABBCCDD| Register contents - // |AABBCCDD| Address contents - // - // Case 2: addr_byte_size is bigger than register_byte_size - // - // Error! (The register should always be big enough to hold the data) - // - // Case 3: register_byte_size is bigger than addr_byte_size - // - // |AABBCCDD| Register contents - // |AABB| Address contents on little-endian hardware - // |CCDD| Address contents on big-endian hardware - if (value_byte_size > register_byte_size) { - err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), reg_info->name); + err.SetErrorStringWithFormat ("%s is too big to store in %s", + name.GetCString(), + reg_info->name); return false; } - - uint32_t register_offset; - - switch (exe_ctx.process->GetByteOrder()) - { - default: - err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString()); - return false; - case lldb::eByteOrderLittle: - register_offset = 0; - break; - case lldb::eByteOrderBig: - register_offset = register_byte_size - value_byte_size; - break; - } RegisterValue reg_value; if (!reg_ctx->ReadRegister (reg_info, reg_value)) { - err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), reg_info->name); + err.SetErrorStringWithFormat ("Couldn't read %s from %s", + name.GetCString(), + reg_info->name); return false; } - err = reg_ctx->WriteRegisterValueToMemory(reg_info, reg_addr, value_byte_size, reg_value); + err = reg_ctx->WriteRegisterValueToMemory (reg_info, + reg_addr.ULongLong(), + value_byte_size, + reg_value); if (err.Fail()) return false; } diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index 0c07bcb6a50..1ce39e87cdc 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -654,7 +654,7 @@ ClangExpressionParser::MakeJIT (lldb::addr_t &func_allocation_addr, if (exc_context.process->WriteMemory(cursor, (void *) lstart, size, write_error) != size) { err.SetErrorToGenericError(); - err.SetErrorStringWithFormat("Couldn't copy JITted function into the target: %s", write_error.AsCString("unknown error")); + err.SetErrorStringWithFormat("Couldn't copy JIT code for function into the target: %s", write_error.AsCString("unknown error")); return err; } diff --git a/lldb/source/Expression/ClangFunction.cpp b/lldb/source/Expression/ClangFunction.cpp index 935ff95ce4f..0d8fbf4f1fb 100644 --- a/lldb/source/Expression/ClangFunction.cpp +++ b/lldb/source/Expression/ClangFunction.cpp @@ -314,12 +314,10 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, } } - // FIXME: This is fake, and just assumes that it matches that architecture. - // Make a data extractor and put the address into the right byte order & size. - - uint64_t fun_addr = function_address.GetLoadAddress(exe_ctx.target); + // TODO: verify fun_addr needs to be a callable address + Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.target)); int first_offset = m_member_offsets[0]; - process->WriteMemory(args_addr_ref + first_offset, &fun_addr, 8, error); + process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error); // FIXME: We will need to extend this for Variadic functions. @@ -350,13 +348,8 @@ ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx, m_clang_ast_context->getASTContext()); - int byte_size = arg_scalar.GetByteSize(); - std::vector<uint8_t> buffer; - buffer.resize(byte_size); - DataExtractor value_data; - arg_scalar.GetData (value_data); - value_data.ExtractBytes(0, byte_size, process->GetByteOrder(), &buffer.front()); - process->WriteMemory(args_addr_ref + offset, &buffer.front(), byte_size, error); + if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error)) + return false; } return true; @@ -420,8 +413,6 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg // Read the return value - it is the last field in the struct: // FIXME: How does clang tell us there's no return value? We need to handle that case. - std::vector<uint8_t> data_buffer; - data_buffer.resize(m_return_size); Process *process = exe_ctx.process; if (process == NULL) @@ -430,25 +421,13 @@ ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t arg return false; Error error; - size_t bytes_read = process->ReadMemory(args_addr + m_return_offset, &data_buffer.front(), m_return_size, error); - - if (bytes_read == 0) - { - return false; - } + ret_value.GetScalar() = process->ReadUnsignedIntegerFromMemory (args_addr + m_return_offset, m_return_size, 0, error); - if (bytes_read < m_return_size) + if (error.Fail()) return false; - DataExtractor data(&data_buffer.front(), m_return_size, process->GetByteOrder(), process->GetAddressByteSize()); - // FIXME: Assuming an integer scalar for now: - - uint32_t offset = 0; - uint64_t return_integer = data.GetMaxU64(&offset, m_return_size); - ret_value.SetContext (Value::eContextTypeClangType, m_function_return_qual_type); ret_value.SetValueType(Value::eValueTypeScalar); - ret_value.GetScalar() = return_integer; return true; } diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index d7a609166d1..09be5fda016 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -269,29 +269,11 @@ ABIMacOSX_arm::GetArgumentValues (Thread &thread, { // Arguments 5 on up are on the stack 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; + Error error; + if (!thread.GetProcess().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error)) + return false; - if (is_signed) - value->GetScalar().SignExtend (bit_width); - sp += arg_byte_size; - } + sp += arg_byte_size; } } } diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index fb4675ca57b..ee39a41cf74 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -397,84 +397,22 @@ ABIMacOSX_i386::PrepareNormalCall (Thread &thread, return true; } -static bool ReadIntegerArgument(Scalar &scalar, - unsigned int bit_width, - bool is_signed, - Process &process, - addr_t ¤t_stack_argument) +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; + uint32_t byte_size = (bit_width + (8-1))/8; Error error; - - if (bit_width > 32) + if (process.ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error)) { - 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; + current_stack_argument += byte_size; + return true; } - - 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 diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index fee09935842..7063ca8b157 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -194,69 +194,24 @@ static bool ReadIntegerArgument(Scalar &scalar, if (bit_width > 64) return false; // Scalar can't hold large integer arguments - uint64_t arg_contents; - if (current_argument_register < 6) { - arg_contents = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0); + scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0); current_argument_register++; + if (is_signed) + scalar.SignExtend (bit_width); } else { - uint8_t arg_data[sizeof(arg_contents)]; + uint32_t byte_size = (bit_width + (8-1))/8; Error error; - thread.GetProcess().ReadMemory(current_stack_argument, arg_data, sizeof(arg_contents), error); - DataExtractor arg_data_extractor (arg_data, sizeof(arg_contents), - thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(), - thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize()); - uint32_t offset = 0; - arg_contents = arg_data_extractor.GetMaxU64(&offset, bit_width / 8); - if (!offset) - return false; - current_stack_argument += (bit_width / 8); - } - - 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) + if (thread.GetProcess().ReadScalarIntegerFromMemory(current_stack_argument, byte_size, is_signed, scalar, error)) { - default: - return false; - case 8: - scalar = (uint8_t)(arg_contents & 0xffu); - break; - case 16: - scalar = (uint16_t)(arg_contents & 0xffffu); - break; - case 32: - scalar = (uint32_t)(arg_contents & 0xffffffffu); - break; - case 64: - scalar = (uint64_t)arg_contents; - break; + current_stack_argument += byte_size; + return true; } + return false; } - return true; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index 0d9d0bcf6a3..0dca2eab032 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -64,7 +64,7 @@ AppleObjCRuntime::GetObjectDescription (Stream &str, ValueObject &object) } bool -AppleObjCRuntime::GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) +AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope) { if (!m_read_objc_library) return false; @@ -88,7 +88,7 @@ AppleObjCRuntime::GetObjectDescription (Stream &str, Value &value, ExecutionCont clang::QualType value_type = clang::QualType::getFromOpaquePtr (value.GetClangType()); if (!value_type->isObjCObjectPointerType()) { - str.Printf ("Value doesn't point to an ObjC object.\n"); + strm.Printf ("Value doesn't point to an ObjC object.\n"); return false; } } @@ -138,35 +138,22 @@ AppleObjCRuntime::GetObjectDescription (Stream &str, Value &value, ExecutionCont ret); if (results != eExecutionCompleted) { - str.Printf("Error evaluating Print Object function: %d.\n", results); + strm.Printf("Error evaluating Print Object function: %d.\n", results); return false; } addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - // FIXME: poor man's strcpy - we should have a "read memory as string interface... - - Error error; - std::vector<char> desc; - while (1) + char buf[512]; + size_t cstr_len = 0; + size_t curr_len = sizeof(buf); + while (curr_len == sizeof(buf)) { - char byte = '\0'; - if (exe_ctx.process->ReadMemory(result_ptr + desc.size(), &byte, 1, error) != 1) - break; - - desc.push_back(byte); - - if (byte == '\0') - break; + curr_len = exe_ctx.process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf)); + strm.Write (buf, curr_len); + cstr_len += curr_len; } - - if (!desc.empty()) - { - str.PutCString(&desc.front()); - return true; - } - return false; - + return cstr_len > 0; } Address * diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 4d315f5c186..fb05f118d04 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -220,9 +220,9 @@ AppleObjCRuntimeV2::RunFunctionToFindClassName(lldb::addr_t object_addr, Thread bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, - lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, - Address &address) + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address) { // The Runtime is attached to a particular process, you shouldn't pass in a value from another process. assert (in_value.GetUpdatePoint().GetProcess() == m_process); @@ -244,9 +244,11 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, Target *target = m_process->CalculateTarget(); char memory_buffer[16]; - DataExtractor data(memory_buffer, sizeof(memory_buffer), - m_process->GetByteOrder(), - m_process->GetAddressByteSize()); + DataExtractor data (memory_buffer, + sizeof(memory_buffer), + m_process->GetByteOrder(), + m_process->GetAddressByteSize()); + size_t address_byte_size = m_process->GetAddressByteSize(); Error error; size_t bytes_read = m_process->ReadMemory (original_ptr, @@ -258,10 +260,10 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, return false; } - uint32_t offset_ptr = 0; - lldb::addr_t isa_addr = data.GetAddress (&offset_ptr); + uint32_t offset = 0; + lldb::addr_t isa_addr = data.GetAddress (&offset); - if (offset_ptr == 0) + if (offset == 0) return false; // Make sure the class address is readable, otherwise this is not a good object: diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index 8d402cfff42..c5b1ddbacd4 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -340,8 +340,8 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols () if (m_objc_module_sp) { ConstString trampoline_name ("gdb_objc_trampolines"); - const Symbol *trampoline_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType(trampoline_name, - eSymbolTypeData); + const Symbol *trampoline_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (trampoline_name, + eSymbolTypeData); if (trampoline_symbol != NULL) { if (!trampoline_symbol->GetValue().IsValid()) @@ -353,18 +353,17 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols () // Next look up the "changed" symbol and set a breakpoint on that... ConstString changed_name ("gdb_objc_trampolines_changed"); - const Symbol *changed_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType(changed_name, - eSymbolTypeCode); + const Symbol *changed_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (changed_name, + eSymbolTypeCode); if (changed_symbol != NULL) { if (!changed_symbol->GetValue().IsValid()) return false; - lldb::addr_t changed_addr = changed_symbol->GetValue().GetLoadAddress(&target); + lldb::addr_t changed_addr = changed_symbol->GetValue().GetOpcodeLoadAddress (&target); if (changed_addr != LLDB_INVALID_ADDRESS) { - BreakpointSP trampolines_changed_bp_sp = target.CreateBreakpoint (changed_addr, - true); + BreakpointSP trampolines_changed_bp_sp = target.CreateBreakpoint (changed_addr, true); if (trampolines_changed_bp_sp != NULL) { m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID(); @@ -427,18 +426,11 @@ AppleObjCTrampolineHandler::AppleObjCVTables::ReadRegions () m_regions.clear(); if (!InitializeVTableSymbols()) return false; - char memory_buffer[8]; - DataExtractor data(memory_buffer, sizeof(memory_buffer), - m_process_sp->GetByteOrder(), - m_process_sp->GetAddressByteSize()); Error error; - size_t bytes_read = m_process_sp->ReadMemory (m_trampoline_header, memory_buffer, m_process_sp->GetAddressByteSize(), error); - if (bytes_read != m_process_sp->GetAddressByteSize()) - return false; - - uint32_t offset_ptr = 0; - lldb::addr_t region_addr = data.GetPointer(&offset_ptr); - return ReadRegions (region_addr); + lldb::addr_t region_addr = m_process_sp->ReadPointerFromMemory (m_trampoline_header, error); + if (error.Success()) + return ReadRegions (region_addr); + return false; } bool @@ -535,13 +527,13 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (ProcessSP process_sp, Mo const Symbol *msg_forward_stret = m_objc_module_sp->FindFirstSymbolWithNameAndType (msg_forward_stret_name, eSymbolTypeCode); if (class_getMethodImplementation) - m_impl_fn_addr = class_getMethodImplementation->GetValue().GetLoadAddress(target); + m_impl_fn_addr = class_getMethodImplementation->GetValue().GetOpcodeLoadAddress (target); if (class_getMethodImplementation_stret) - m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetValue().GetLoadAddress(target); + m_impl_stret_fn_addr = class_getMethodImplementation_stret->GetValue().GetOpcodeLoadAddress (target); if (msg_forward) - m_msg_forward_addr = msg_forward->GetValue().GetLoadAddress(target); + m_msg_forward_addr = msg_forward->GetValue().GetOpcodeLoadAddress(target); if (msg_forward_stret) - m_msg_forward_stret_addr = msg_forward_stret->GetValue().GetLoadAddress(target); + m_msg_forward_stret_addr = msg_forward_stret->GetValue().GetOpcodeLoadAddress(target); // FIXME: Do some kind of logging here. if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 9a7e2c65a49..7acb87e5080 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1708,29 +1708,36 @@ Process::ReadMemoryFromInferior (addr_t addr, void *buf, size_t size, Error &err } uint64_t -Process::ReadUnsignedInteger (lldb::addr_t vm_addr, size_t integer_byte_size, Error &error) +Process::ReadUnsignedIntegerFromMemory (lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, Error &error) { - if (integer_byte_size > sizeof(uint64_t)) - { - error.SetErrorString ("unsupported integer size"); - } + Scalar scalar; + if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, error)) + return scalar.ULongLong(fail_value); + return fail_value; +} + +addr_t +Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error) +{ + Scalar scalar; + if (ReadScalarIntegerFromMemory(vm_addr, GetAddressByteSize(), false, scalar, error)) + return scalar.ULongLong(LLDB_INVALID_ADDRESS); + return LLDB_INVALID_ADDRESS; +} + + +bool +Process::WritePointerToMemory (lldb::addr_t vm_addr, + lldb::addr_t ptr_value, + Error &error) +{ + Scalar scalar; + const uint32_t addr_byte_size = GetAddressByteSize(); + if (addr_byte_size <= 4) + scalar = (uint32_t)ptr_value; else - { - uint8_t tmp[sizeof(uint64_t)]; - DataExtractor data (tmp, - integer_byte_size, - m_target.GetArchitecture().GetByteOrder(), - m_target.GetArchitecture().GetAddressByteSize()); - if (ReadMemory (vm_addr, tmp, integer_byte_size, error) == integer_byte_size) - { - uint32_t offset = 0; - return data.GetMaxU64 (&offset, integer_byte_size); - } - } - // Any plug-in that doesn't return success a memory read with the number - // of bytes that were requested should be setting the error - assert (error.Fail()); - return 0; + scalar = ptr_value; + return WriteScalarToMemory(vm_addr, scalar, addr_byte_size, error) == addr_byte_size; } size_t @@ -1831,6 +1838,61 @@ Process::WriteMemory (addr_t addr, const void *buf, size_t size, Error &error) return bytes_written; } + +size_t +Process::WriteScalarToMemory (addr_t addr, const Scalar &scalar, uint32_t byte_size, Error &error) +{ + if (byte_size == UINT32_MAX) + byte_size = scalar.GetByteSize(); + if (byte_size > 0) + { + uint8_t buf[32]; + const size_t mem_size = scalar.GetAsMemoryData (buf, byte_size, GetByteOrder(), error); + if (mem_size > 0) + return WriteMemory(addr, buf, mem_size, error); + else + error.SetErrorString ("failed to get scalar as memory data"); + } + else + { + error.SetErrorString ("invalid scalar value"); + } + return 0; +} + +size_t +Process::ReadScalarIntegerFromMemory (addr_t addr, + uint32_t byte_size, + bool is_signed, + Scalar &scalar, + Error &error) +{ + uint64_t uval; + + if (byte_size <= sizeof(uval)) + { + size_t bytes_read = ReadMemory (addr, &uval, byte_size, error); + if (bytes_read == byte_size) + { + DataExtractor data (&uval, sizeof(uval), GetByteOrder(), GetAddressByteSize()); + uint32_t offset = 0; + if (byte_size <= 4) + scalar = data.GetMaxU32 (&offset, byte_size); + else + scalar = data.GetMaxU64 (&offset, byte_size); + + if (is_signed) + scalar.SignExtend(byte_size * 8); + return bytes_read; + } + } + else + { + error.SetErrorStringWithFormat ("byte size of %u is too large for integer scalar type", byte_size); + } + return 0; +} + #define USE_ALLOCATE_MEMORY_CACHE 1 addr_t Process::AllocateMemory(size_t size, uint32_t permissions, Error &error) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 387a3363113..56b798bed08 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1014,6 +1014,81 @@ Target::EvaluateExpression return execution_results; } +lldb::addr_t +Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const +{ + addr_t code_addr = load_addr; + switch (m_arch.GetMachine()) + { + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (addr_class) + { + case eAddressClassData: + case eAddressClassDebug: + return LLDB_INVALID_ADDRESS; + + case eAddressClassUnknown: + case eAddressClassInvalid: + case eAddressClassCode: + case eAddressClassCodeAlternateISA: + case eAddressClassRuntime: + // Check if bit zero it no set? + if ((code_addr & 1ull) == 0) + { + // Bit zero isn't set, check if the address is a multiple of 2? + if (code_addr & 2ull) + { + // The address is a multiple of 2 so it must be thumb, set bit zero + code_addr |= 1ull; + } + else if (addr_class == eAddressClassCodeAlternateISA) + { + // We checked the address and the address claims to be the alternate ISA + // which means thumb, so set bit zero. + code_addr |= 1ull; + } + } + break; + } + break; + + default: + break; + } + return code_addr; +} + +lldb::addr_t +Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const +{ + addr_t opcode_addr = load_addr; + switch (m_arch.GetMachine()) + { + case llvm::Triple::arm: + case llvm::Triple::thumb: + switch (addr_class) + { + case eAddressClassData: + case eAddressClassDebug: + return LLDB_INVALID_ADDRESS; + + case eAddressClassInvalid: + case eAddressClassUnknown: + case eAddressClassCode: + case eAddressClassCodeAlternateISA: + case eAddressClassRuntime: + opcode_addr &= ~(1ull); + break; + } + break; + + default: + break; + } + return opcode_addr; +} + lldb::user_id_t Target::AddStopHook (Target::StopHookSP &new_hook_sp) { diff --git a/lldb/source/Target/ThreadPlanRunToAddress.cpp b/lldb/source/Target/ThreadPlanRunToAddress.cpp index 23945453f00..0779a1fd322 100644 --- a/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -39,7 +39,7 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress m_addresses (), m_break_ids () { - m_addresses.push_back (address.GetLoadAddress(&m_thread.GetProcess().GetTarget())); + m_addresses.push_back (address.GetOpcodeLoadAddress (&m_thread.GetProcess().GetTarget())); SetInitialBreakpoints(); } @@ -54,14 +54,14 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress m_addresses (), m_break_ids () { - m_addresses.push_back(address); + m_addresses.push_back(m_thread.GetProcess().GetTarget().GetOpcodeLoadAddress(address)); SetInitialBreakpoints(); } ThreadPlanRunToAddress::ThreadPlanRunToAddress ( Thread &thread, - std::vector<lldb::addr_t> &addresses, + const std::vector<lldb::addr_t> &addresses, bool stop_others ) : ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion), @@ -69,6 +69,13 @@ ThreadPlanRunToAddress::ThreadPlanRunToAddress m_addresses (addresses), m_break_ids () { + // Convert all addressses into opcode addresses to make sure we set + // breakpoints at the correct address. + Target &target = thread.GetProcess().GetTarget(); + std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end(); + for (pos = m_addresses.begin(); pos != end; ++pos) + *pos = target.GetOpcodeLoadAddress (*pos); + SetInitialBreakpoints(); } diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp index 386ba2317eb..0fe65b6927a 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp @@ -698,70 +698,3 @@ MachThread::GetName () return NULL; } - -// -//const char * -//MachThread::GetDispatchQueueName() -//{ -// if (GetIdentifierInfo ()) -// { -// if (m_ident_info.dispatch_qaddr == 0) -// return NULL; -// -// uint8_t memory_buffer[8]; -// DNBDataRef data(memory_buffer, sizeof(memory_buffer), false); -// ModuleSP module_sp(GetProcess()->GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib"))); -// if (module_sp.get() == NULL) -// return NULL; -// -// lldb::addr_t dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; -// const Symbol *dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (ConstString("dispatch_queue_offsets"), eSymbolTypeData); -// if (dispatch_queue_offsets_symbol) -// dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetValue().GetLoadAddress(GetProcess()); -// -// if (dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) -// return NULL; -// -// // Excerpt from src/queue_private.h -// struct dispatch_queue_offsets_s -// { -// uint16_t dqo_version; -// uint16_t dqo_label; -// uint16_t dqo_label_size; -// } dispatch_queue_offsets; -// -// -// if (GetProcess()->ReadMemory (dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets)) == sizeof(dispatch_queue_offsets)) -// { -// uint32_t data_offset = 0; -// if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t))) -// { -// if (GetProcess()->ReadMemory (m_ident_info.dispatch_qaddr, &memory_buffer, data.GetAddressByteSize()) == data.GetAddressByteSize()) -// { -// data_offset = 0; -// lldb::addr_t queue_addr = data.GetAddress(&data_offset); -// lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label; -// const size_t chunk_size = 32; -// uint32_t label_pos = 0; -// m_dispatch_queue_name.resize(chunk_size, '\0'); -// while (1) -// { -// size_t bytes_read = GetProcess()->ReadMemory (label_addr + label_pos, &m_dispatch_queue_name[label_pos], chunk_size); -// -// if (bytes_read <= 0) -// break; -// -// if (m_dispatch_queue_name.find('\0', label_pos) != std::string::npos) -// break; -// label_pos += bytes_read; -// } -// m_dispatch_queue_name.erase(m_dispatch_queue_name.find('\0')); -// } -// } -// } -// } -// -// if (m_dispatch_queue_name.empty()) -// return NULL; -// return m_dispatch_queue_name.c_str(); -//} |