summaryrefslogtreecommitdiff
path: root/source/Commands/CommandObjectMemory.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
commit5f29bb8a675e8f96452b632e7129113f7dec850e (patch)
tree3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Commands/CommandObjectMemory.cpp
parent88c643b6fec27eec436c8d138fee6346e92337d6 (diff)
Notes
Diffstat (limited to 'source/Commands/CommandObjectMemory.cpp')
-rw-r--r--source/Commands/CommandObjectMemory.cpp130
1 files changed, 73 insertions, 57 deletions
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index b1edb1afa5d2c..1afcac71318df 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -1,24 +1,19 @@
//===-- CommandObjectMemory.cpp ---------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#include <inttypes.h>
-
-#include "clang/AST/Decl.h"
-
#include "CommandObjectMemory.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -26,15 +21,17 @@
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupOutputFile.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
+#include "lldb/Interpreter/OptionValueLanguage.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/Options.h"
-#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -43,6 +40,9 @@
#include "lldb/lldb-private.h"
+#include <cinttypes>
+#include <memory>
+
using namespace lldb;
using namespace lldb_private;
@@ -51,7 +51,9 @@ static constexpr OptionDefinition g_read_memory_options[] = {
{LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." },
{LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that "
"uses the format, size, count and number per line settings." },
- {LLDB_OPT_SET_3, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The name of a type to view memory as." },
+ {LLDB_OPT_SET_3 |
+ LLDB_OPT_SET_4, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "The name of a type to view memory as." },
+ {LLDB_OPT_SET_4, false, "language", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "The language of the type to view memory as."},
{LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." },
{LLDB_OPT_SET_1 |
LLDB_OPT_SET_2 |
@@ -63,7 +65,7 @@ class OptionGroupReadMemory : public OptionGroup {
public:
OptionGroupReadMemory()
: m_num_per_line(1, 1), m_output_as_binary(false), m_view_as_type(),
- m_offset(0, 0) {}
+ m_offset(0, 0), m_language_for_type(eLanguageTypeUnknown) {}
~OptionGroupReadMemory() override = default;
@@ -97,6 +99,10 @@ public:
m_force = true;
break;
+ case 'x':
+ error = m_language_for_type.SetValueFromString(option_value);
+ break;
+
case 'E':
error = m_offset.SetValueFromString(option_value);
break;
@@ -115,6 +121,7 @@ public:
m_view_as_type.Clear();
m_force = false;
m_offset.Clear();
+ m_language_for_type.Clear();
}
Status FinalizeSettings(Target *target, OptionGroupFormat &format_options) {
@@ -277,7 +284,8 @@ public:
bool AnyOptionWasSet() const {
return m_num_per_line.OptionWasSet() || m_output_as_binary ||
- m_view_as_type.OptionWasSet() || m_offset.OptionWasSet();
+ m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
+ m_language_for_type.OptionWasSet();
}
OptionValueUInt64 m_num_per_line;
@@ -285,11 +293,10 @@ public:
OptionValueString m_view_as_type;
bool m_force;
OptionValueUInt64 m_offset;
+ OptionValueLanguage m_language_for_type;
};
-//----------------------------------------------------------------------
// Read memory from the inferior process
-//----------------------------------------------------------------------
class CommandObjectMemoryRead : public CommandObjectParsed {
public:
CommandObjectMemoryRead(CommandInterpreter &interpreter)
@@ -374,7 +381,7 @@ protected:
return false;
}
- CompilerType clang_ast_type;
+ CompilerType compiler_type;
Status error;
const char *view_as_type_cstr =
@@ -474,26 +481,43 @@ protected:
exact_match, 1, searched_symbol_files,
type_list);
- if (type_list.GetSize() == 0 && lookup_type_name.GetCString() &&
- *lookup_type_name.GetCString() == '$') {
- if (ClangPersistentVariables *persistent_vars =
- llvm::dyn_cast_or_null<ClangPersistentVariables>(
- target->GetPersistentExpressionStateForLanguage(
- lldb::eLanguageTypeC))) {
- clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(
- persistent_vars->GetPersistentDecl(
- ConstString(lookup_type_name)));
-
- if (tdecl) {
- clang_ast_type.SetCompilerType(
- ClangASTContext::GetASTContext(&tdecl->getASTContext()),
- reinterpret_cast<lldb::opaque_compiler_type_t>(
- const_cast<clang::Type *>(tdecl->getTypeForDecl())));
+ if (type_list.GetSize() == 0 && lookup_type_name.GetCString()) {
+ LanguageType language_for_type =
+ m_memory_options.m_language_for_type.GetCurrentValue();
+ std::set<LanguageType> languages_to_check;
+ if (language_for_type != eLanguageTypeUnknown) {
+ languages_to_check.insert(language_for_type);
+ } else {
+ languages_to_check = Language::GetSupportedLanguages();
+ }
+
+ std::set<CompilerType> user_defined_types;
+ for (auto lang : languages_to_check) {
+ if (auto *persistent_vars =
+ target->GetPersistentExpressionStateForLanguage(lang)) {
+ if (llvm::Optional<CompilerType> type =
+ persistent_vars->GetCompilerTypeFromPersistentDecl(
+ lookup_type_name)) {
+ user_defined_types.emplace(*type);
+ }
}
}
+
+ if (user_defined_types.size() > 1) {
+ result.AppendErrorWithFormat(
+ "Mutiple types found matching raw type '%s', please disambiguate "
+ "by specifying the language with -x",
+ lookup_type_name.GetCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (user_defined_types.size() == 1) {
+ compiler_type = *user_defined_types.begin();
+ }
}
- if (!clang_ast_type.IsValid()) {
+ if (!compiler_type.IsValid()) {
if (type_list.GetSize() == 0) {
result.AppendErrorWithFormat("unable to find any types that match "
"the raw type '%s' for full type '%s'\n",
@@ -503,14 +527,14 @@ protected:
return false;
} else {
TypeSP type_sp(type_list.GetTypeAtIndex(0));
- clang_ast_type = type_sp->GetFullCompilerType();
+ compiler_type = type_sp->GetFullCompilerType();
}
}
while (pointer_count > 0) {
- CompilerType pointer_type = clang_ast_type.GetPointerType();
+ CompilerType pointer_type = compiler_type.GetPointerType();
if (pointer_type.IsValid())
- clang_ast_type = pointer_type;
+ compiler_type = pointer_type;
else {
result.AppendError("unable make a pointer type\n");
result.SetStatus(eReturnStatusFailed);
@@ -519,7 +543,7 @@ protected:
--pointer_count;
}
- llvm::Optional<uint64_t> size = clang_ast_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
if (!size) {
result.AppendErrorWithFormat(
"unable to get the byte size of the type '%s'\n",
@@ -549,7 +573,7 @@ protected:
// options have been set
addr = m_next_addr;
total_byte_size = m_prev_byte_size;
- clang_ast_type = m_prev_clang_ast_type;
+ compiler_type = m_prev_compiler_type;
if (!m_format_options.AnyOptionWasSet() &&
!m_memory_options.AnyOptionWasSet() &&
!m_outfile_options.AnyOptionWasSet() &&
@@ -636,13 +660,13 @@ protected:
DataBufferSP data_sp;
size_t bytes_read = 0;
- if (clang_ast_type.GetOpaqueQualType()) {
+ if (compiler_type.GetOpaqueQualType()) {
// Make sure we don't display our type as ASCII bytes like the default
// memory read
if (!m_format_options.GetFormatValue().OptionWasSet())
m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
- llvm::Optional<uint64_t> size = clang_ast_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
if (!size) {
result.AppendError("can't get size of type");
return false;
@@ -653,7 +677,7 @@ protected:
addr = addr + (*size * m_memory_options.m_offset.GetCurrentValue());
} else if (m_format_options.GetFormatValue().GetCurrentValue() !=
eFormatCString) {
- data_sp.reset(new DataBufferHeap(total_byte_size, '\0'));
+ data_sp = std::make_shared<DataBufferHeap>(total_byte_size, '\0');
if (data_sp->GetBytes() == nullptr) {
result.AppendErrorWithFormat(
"can't allocate 0x%" PRIx32
@@ -693,8 +717,9 @@ protected:
item_byte_size = target->GetMaximumSizeOfStringSummary();
if (!m_format_options.GetCountValue().OptionWasSet())
item_count = 1;
- data_sp.reset(new DataBufferHeap((item_byte_size + 1) * item_count,
- '\0')); // account for NULLs as necessary
+ data_sp = std::make_shared<DataBufferHeap>(
+ (item_byte_size + 1) * item_count,
+ '\0'); // account for NULLs as necessary
if (data_sp->GetBytes() == nullptr) {
result.AppendErrorWithFormat(
"can't allocate 0x%" PRIx64
@@ -741,7 +766,8 @@ protected:
if (break_on_no_NULL)
break;
}
- data_sp.reset(new DataBufferHeap(data_sp->GetBytes(), bytes_read + 1));
+ data_sp =
+ std::make_shared<DataBufferHeap>(data_sp->GetBytes(), bytes_read + 1);
}
m_next_addr = addr + bytes_read;
@@ -750,7 +776,7 @@ protected:
m_prev_memory_options = m_memory_options;
m_prev_outfile_options = m_outfile_options;
m_prev_varobj_options = m_varobj_options;
- m_prev_clang_ast_type = clang_ast_type;
+ m_prev_compiler_type = compiler_type;
StreamFile outfile_stream;
Stream *output_stream = nullptr;
@@ -800,14 +826,14 @@ protected:
}
ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
- if (clang_ast_type.GetOpaqueQualType()) {
+ if (compiler_type.GetOpaqueQualType()) {
for (uint32_t i = 0; i < item_count; ++i) {
addr_t item_addr = addr + (i * item_byte_size);
Address address(item_addr);
StreamString name_strm;
name_strm.Printf("0x%" PRIx64, item_addr);
ValueObjectSP valobj_sp(ValueObjectMemory::Create(
- exe_scope, name_strm.GetString(), address, clang_ast_type));
+ exe_scope, name_strm.GetString(), address, compiler_type));
if (valobj_sp) {
Format format = m_format_options.GetFormat();
if (format != eFormatDefault)
@@ -877,7 +903,7 @@ protected:
OptionGroupReadMemory m_prev_memory_options;
OptionGroupOutputFile m_prev_outfile_options;
OptionGroupValueObjectDisplay m_prev_varobj_options;
- CompilerType m_prev_clang_ast_type;
+ CompilerType m_prev_compiler_type;
};
static constexpr OptionDefinition g_memory_find_option_table[] = {
@@ -889,9 +915,7 @@ static constexpr OptionDefinition g_memory_find_option_table[] = {
// clang-format on
};
-//----------------------------------------------------------------------
// Find the specified data in memory
-//----------------------------------------------------------------------
class CommandObjectMemoryFind : public CommandObjectParsed {
public:
class OptionGroupFindMemory : public OptionGroup {
@@ -1186,9 +1210,7 @@ static constexpr OptionDefinition g_memory_write_option_table[] = {
// clang-format on
};
-//----------------------------------------------------------------------
// Write memory to the inferior process
-//----------------------------------------------------------------------
class CommandObjectMemoryWrite : public CommandObjectParsed {
public:
class OptionGroupWriteMemory : public OptionGroup {
@@ -1595,9 +1617,7 @@ protected:
OptionGroupWriteMemory m_memory_options;
};
-//----------------------------------------------------------------------
// Get malloc/free history of a memory address.
-//----------------------------------------------------------------------
class CommandObjectMemoryHistory : public CommandObjectParsed {
public:
CommandObjectMemoryHistory(CommandInterpreter &interpreter)
@@ -1677,9 +1697,7 @@ protected:
}
};
-//-------------------------------------------------------------------------
// CommandObjectMemoryRegion
-//-------------------------------------------------------------------------
#pragma mark CommandObjectMemoryRegion
class CommandObjectMemoryRegion : public CommandObjectParsed {
@@ -1770,9 +1788,7 @@ protected:
lldb::addr_t m_prev_end_addr;
};
-//-------------------------------------------------------------------------
// CommandObjectMemory
-//-------------------------------------------------------------------------
CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter)
: CommandObjectMultiword(