Added "target variable" command that allows introspection of global

variables prior to running your binary. Zero filled sections now get
section data correctly filled with zeroes when Target::ReadMemory
reads from the object file section data.

Added new option groups and option values for file lists. I still need
to hook up all of the options to "target variable" to allow more complete
introspection by file and shlib.

Added the ability for ValueObjectVariable objects to be created with
only the target as the execution context. This allows them to be read
from the object files through Target::ReadMemory(...). 

Added a "virtual Module * GetModule()" function to the ValueObject
class. By default it will look to the parent variable object and
return its module. The module is needed when we have global variables
that have file addresses (virtual addresses that are specific to
module object files) and in turn allows global variables to be displayed
prior to running.

Removed all of the unused proxy object support that bit rotted in 
lldb_private::Value.

Replaced a lot of places that used "FileSpec::Compare (lhs, rhs) == 0" code
with the more efficient "FileSpec::Equal (lhs, rhs)".

Improved logging in GDB remote plug-in.

llvm-svn: 134579
This commit is contained in:
Greg Clayton 2011-07-07 01:59:51 +00:00
parent a3c122db7e
commit 644247c1dc
39 changed files with 771 additions and 415 deletions

View File

@ -102,7 +102,7 @@ public:
/// The stream that will be used to dump the object description.
//------------------------------------------------------------------
void
Dump (Stream *s) const;
Dump (Stream *s, const char *separator_cstr = "\n") const;
//------------------------------------------------------------------
/// Find a file index.

View File

@ -156,6 +156,33 @@ public:
lldb::SymbolType symbol_type,
SymbolContextList &sc_list);
//------------------------------------------------------------------
/// Find compile units by partial or full path.
///
/// Finds all compile units that match \a path in all of the modules
/// and returns the results in \a sc_list.
///
/// @param[in] path
/// The name of the function we are looking for.
///
/// @param[in] append
/// If \b true, then append any compile units that were found
/// to \a sc_list. If \b false, then the \a sc_list is cleared
/// and the contents of \a sc_list are replaced.
///
/// @param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
///
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
uint32_t
FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list);
//------------------------------------------------------------------
/// Find functions by name.
///

View File

@ -139,6 +139,32 @@ public:
Module*
GetModulePointerAtIndex (uint32_t idx) const;
//------------------------------------------------------------------
/// Find compile units by partial or full path.
///
/// Finds all compile units that match \a path in all of the modules
/// and returns the results in \a sc_list.
///
/// @param[in] path
/// The name of the function we are looking for.
///
/// @param[in] append
/// If \b true, then append any compile units that were found
/// to \a sc_list. If \b false, then the \a sc_list is cleared
/// and the contents of \a sc_list are replaced.
///
/// @param[out] sc_list
/// A symbol context list that gets filled in with all of the
/// matches.
///
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
uint32_t
FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list);
//------------------------------------------------------------------
/// Find functions by name.
///
@ -161,7 +187,7 @@ public:
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
size_t
uint32_t
FindFunctions (const ConstString &name,
uint32_t name_type_mask,
bool include_symbols,

View File

@ -48,32 +48,16 @@ public:
eContextTypeRegisterInfo, // RegisterInfo *
eContextTypeLLDBType, // lldb_private::Type *
eContextTypeVariable, // lldb_private::Variable *
eContextTypeValue // Value * (making this a proxy value. Used when putting locals on the DWARF expression parser stack)
};
Value();
Value(const Scalar& scalar);
Value(int v);
Value(unsigned int v);
Value(long v);
Value(unsigned long v);
Value(long long v);
Value(unsigned long long v);
Value(float v);
Value(double v);
Value(long double v);
Value(const uint8_t *bytes, int len);
Value(const Value &rhs);
Value &
operator=(const Value &rhs);
Value *
CreateProxy();
Value *
GetProxyTarget();
lldb::clang_type_t
GetClangType();
@ -84,16 +68,30 @@ public:
GetValueAddressType () const;
ContextType
GetContextType() const;
GetContextType() const
{
return m_context_type;
}
void
SetValueType (ValueType value_type);
SetValueType (ValueType value_type)
{
m_value_type = value_type;
}
void
ClearContext ();
ClearContext ()
{
m_context = NULL;
m_context_type = eContextTypeInvalid;
}
void
SetContext (ContextType context_type, void *p);
SetContext (ContextType context_type, void *p)
{
m_context_type = context_type;
m_context = p;
}
RegisterInfo *
GetRegisterInfo();
@ -105,7 +103,10 @@ public:
ResolveValue (ExecutionContext *exe_ctx, clang::ASTContext *ast_context);
Scalar &
GetScalar();
GetScalar()
{
return m_value;
}
void
ResizeData(int len);
@ -126,7 +127,11 @@ public:
GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr);
Error
GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset);
GetValueAsData (ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
DataExtractor &data,
uint32_t data_offset,
Module *module); // Can be NULL
static const char *
GetValueTypeAsCString (ValueType context_type);

View File

@ -322,6 +322,16 @@ public:
virtual bool
SetValueFromCString (const char *value_str);
// Return the module associated with this value object in case the
// value is from an executable file and might have its data in
// sections of the file. This can be used for variables.
virtual Module *
GetModule()
{
if (m_parent)
return m_parent->GetModule();
return NULL;
}
//------------------------------------------------------------------
// The functions below should NOT be modified by sublasses
//------------------------------------------------------------------

View File

@ -62,6 +62,9 @@ public:
virtual bool
IsInScope ();
virtual Module*
GetModule();
protected:
virtual bool
UpdateValue ();

View File

@ -52,6 +52,9 @@ public:
virtual bool
IsInScope ();
virtual Module*
GetModule();
protected:
virtual bool
UpdateValue ();

View File

@ -19,6 +19,7 @@
// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/UUID.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Host/FileSpec.h"
namespace lldb_private {
@ -28,6 +29,7 @@ namespace lldb_private {
class OptionValueUInt64;
class OptionValueString;
class OptionValueFileSpec;
class OptionValueFileSpecList;
class OptionValueFormat;
class OptionValueUUID;
class OptionValueArray;
@ -46,6 +48,7 @@ namespace lldb_private {
eTypeDictionary,
eTypeEnum,
eTypeFileSpec,
eTypeFileSpecList,
eTypeFormat,
eTypeSInt64,
eTypeUInt64,
@ -108,6 +111,9 @@ namespace lldb_private {
OptionValueFileSpec *
GetAsFileSpec ();
OptionValueFileSpecList *
GetAsFileSpecList ();
OptionValueFormat *
GetAsFormat ();
@ -644,7 +650,79 @@ namespace lldb_private {
FileSpec m_current_value;
FileSpec m_default_value;
};
//---------------------------------------------------------------------
// OptionValueFileSpecList
//---------------------------------------------------------------------
class OptionValueFileSpecList : public OptionValue
{
public:
OptionValueFileSpecList () :
m_current_value ()
{
}
OptionValueFileSpecList (const FileSpecList &current_value) :
m_current_value (current_value)
{
}
virtual
~OptionValueFileSpecList()
{
}
//---------------------------------------------------------------------
// Virtual subclass pure virtual overrides
//---------------------------------------------------------------------
virtual OptionValue::Type
GetType ()
{
return eTypeFileSpecList;
}
virtual void
DumpValue (Stream &strm);
virtual Error
SetValueFromCString (const char *value);
virtual bool
Clear ()
{
m_current_value.Clear();
m_value_was_set = false;
return true;
}
//---------------------------------------------------------------------
// Subclass specific functions
//---------------------------------------------------------------------
FileSpecList &
GetCurrentValue()
{
return m_current_value;
}
const FileSpecList &
GetCurrentValue() const
{
return m_current_value;
}
void
SetCurrentValue (const FileSpecList &value)
{
m_current_value = value;
}
protected:
FileSpecList m_current_value;
};
//---------------------------------------------------------------------
// OptionValueFormat
//---------------------------------------------------------------------

View File

@ -18,6 +18,7 @@
#include "lldb/Interpreter/NamedOptionValue.h"
namespace lldb_private {
//-------------------------------------------------------------------------
// OptionGroupFile
//-------------------------------------------------------------------------
@ -76,6 +77,65 @@ protected:
};
//-------------------------------------------------------------------------
// OptionGroupFileList
//-------------------------------------------------------------------------
class OptionGroupFileList : public OptionGroup
{
public:
OptionGroupFileList (uint32_t usage_mask,
bool required,
const char *long_option,
char short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text);
virtual
~OptionGroupFileList ();
virtual uint32_t
GetNumDefinitions ()
{
return 1;
}
virtual const OptionDefinition*
GetDefinitions ()
{
return &m_option_definition;
}
virtual Error
SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_value);
virtual void
OptionParsingStarting (CommandInterpreter &interpreter);
OptionValueFileSpecList &
GetOptionValue ()
{
return m_file_list;
}
const OptionValueFileSpecList &
GetOptionValue () const
{
return m_file_list;
}
protected:
OptionValueFileSpecList m_file_list;
OptionDefinition m_option_definition;
};
} // namespace lldb_private
#endif // liblldb_OptionGroupFile_h_

View File

@ -53,6 +53,12 @@ public:
const ConstString&
GetName() const;
SymbolContextScope *
GetSymbolContextScope() const
{
return m_owner_scope;
}
// Since a variable can have a basename "i" and also a mangled
// named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name
// "(anonymous namespace)::i", this function will allow a generic match

View File

@ -80,6 +80,9 @@ public:
ExecutionContextScope *
GetBestExecutionContextScope () const;
Process *
GetProcess () const;
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------

View File

@ -89,6 +89,16 @@
ReferencedContainer = "container:lldb.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "/Volumes/work/gclayton/Documents/src/args/a.out"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "/private/tmp/a.out"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR"

View File

@ -692,7 +692,6 @@ public:
}
protected:
// CommandOptions m_options;
OptionGroupOptions m_option_group;
OptionGroupFormat m_format_options;
OptionGroupReadMemory m_memory_options;
@ -701,26 +700,6 @@ protected:
};
//OptionDefinition
//CommandObjectMemoryRead::CommandOptions::g_option_table[] =
//{
//{ LLDB_OPT_SET_1, false, "format" ,'f', required_argument, NULL, 0, eArgTypeFormat ,"The format that will be used to display the memory. Defaults to bytes with ASCII (--format=Y)."},
//{ LLDB_OPT_SET_1, false, "size" ,'s', required_argument, NULL, 0, eArgTypeByteSize ,"The size in bytes to use when displaying with the selected format."},
//{ LLDB_OPT_SET_1, false, "num-per-line" ,'l', required_argument, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
//{ LLDB_OPT_SET_1|
// LLDB_OPT_SET_2|
// LLDB_OPT_SET_3, false, "count" ,'c', required_argument, NULL, 0, eArgTypeCount ,"The number of total items to display."},
//{ LLDB_OPT_SET_1|
// LLDB_OPT_SET_2|
// LLDB_OPT_SET_3, false, "outfile" ,'o', required_argument, NULL, 0, eArgTypeFilename ,"Dump memory read results into a file."},
//{ LLDB_OPT_SET_1|
// LLDB_OPT_SET_2|
// LLDB_OPT_SET_3, false, "append" ,'a', no_argument , NULL, 0, eArgTypeNone ,"Append memory read results to 'outfile'."},
//{ LLDB_OPT_SET_2, false, "binary" ,'b', no_argument , NULL, 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 , "view-as" ,'t', required_argument, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."},
//{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
//};
//----------------------------------------------------------------------
// Write memory to the inferior process
//----------------------------------------------------------------------

View File

@ -21,18 +21,22 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
@ -141,7 +145,7 @@ public:
"Create a target using the argument as the main executable.",
NULL),
m_option_group (interpreter),
m_file_options (),
m_arch_option (),
m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
{
CommandArgumentEntry arg;
@ -157,7 +161,7 @@ public:
// Push the data for the first argument into the m_arguments vector.
m_arguments.push_back (arg);
m_option_group.Append (&m_file_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
}
@ -199,12 +203,12 @@ public:
}
ArchSpec file_arch;
const char *arch_cstr = m_file_options.GetArchitectureName();
const char *arch_cstr = m_arch_option.GetArchitectureName();
if (arch_cstr)
{
if (!platform_sp)
platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
if (!m_file_options.GetArchitecture(platform_sp.get(), file_arch))
if (!m_arch_option.GetArchitecture(platform_sp.get(), file_arch))
{
result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
result.SetStatus (eReturnStatusFailed);
@ -269,7 +273,7 @@ public:
}
private:
OptionGroupOptions m_option_group;
OptionGroupArchitecture m_file_options;
OptionGroupArchitecture m_arch_option;
OptionGroupPlatform m_platform_options;
};
@ -397,6 +401,133 @@ public:
};
#pragma mark CommandObjectTargetVariable
//----------------------------------------------------------------------
// "target variable"
//----------------------------------------------------------------------
class CommandObjectTargetVariable : public CommandObject
{
public:
CommandObjectTargetVariable (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"target select",
"Select a target as the current target by target index.",
NULL,
0),
m_option_group (interpreter),
m_format_options (eFormatDefault, 0, false),
m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypePath, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
m_varobj_options()
{
m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_format_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
}
virtual
~CommandObjectTargetVariable ()
{
}
virtual bool
Execute (Args& args, CommandReturnObject &result)
{
ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
if (exe_ctx.target)
{
const size_t argc = args.GetArgumentCount();
if (argc > 0)
{
for (size_t idx = 0; idx < argc; ++idx)
{
VariableList global_var_list;
const char *global_var_name = args.GetArgumentAtIndex(idx);
const uint32_t matches = exe_ctx.target->GetImages().FindGlobalVariables (global_var_name,
true,
UINT32_MAX,
global_var_list);
if (matches == 0)
{
result.GetErrorStream().Printf ("error: can't find global variable '%s'\n",
global_var_name);
}
else
{
for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
{
VariableSP var_sp (global_var_list.GetVariableAtIndex(global_idx));
if (var_sp)
{
ValueObjectSP valobj_sp(ValueObjectVariable::Create (exe_ctx.target, var_sp));
if (valobj_sp)
{
const Format format = m_format_options.GetFormat ();
if (format != eFormatDefault)
valobj_sp->SetFormat (format);
// if (m_format_options.show_decl && var_sp->GetDeclaration ().GetFile())
// {
// var_sp->GetDeclaration ().DumpStopContext (&s, false);
// s.PutCString (": ");
// }
ValueObject::DumpValueObject (result.GetOutputStream(),
valobj_sp.get(),
global_var_name,
m_varobj_options.ptr_depth,
0,
m_varobj_options.max_depth,
m_varobj_options.show_types,
m_varobj_options.show_location,
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
false,
m_varobj_options.flat_output);
}
}
}
}
}
}
else
{
result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
result.SetStatus (eReturnStatusFailed);
}
}
else
{
result.AppendError ("invalid target, create a debug target using the 'target create' command");
result.SetStatus (eReturnStatusFailed);
return false;
}
return result.Succeeded();
}
Options *
GetOptions ()
{
return &m_option_group;
}
protected:
OptionGroupOptions m_option_group;
OptionGroupFormat m_format_options;
OptionGroupFileList m_option_compile_units;
OptionGroupFileList m_option_shared_libraries;
OptionGroupValueObjectDisplay m_varobj_options;
};
#pragma mark CommandObjectTargetModulesSearchPathsAdd
class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
@ -1137,14 +1268,11 @@ LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *m
}
static uint32_t
LookupTypeInModule
(
CommandInterpreter &interpreter,
Stream &strm,
Module *module,
const char *name_cstr,
bool name_is_regex
)
LookupTypeInModule (CommandInterpreter &interpreter,
Stream &strm,
Module *module,
const char *name_cstr,
bool name_is_regex)
{
if (module && name_cstr && name_cstr[0])
{
@ -3565,6 +3693,7 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &
LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
}
CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()

View File

@ -239,13 +239,6 @@ Broadcaster::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
if (hijacking_listener)
{
// FIXME: REMOVE THIS EXTRA LOGGING
LogSP log_process(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log_process)
log_process->Printf ("Hijacking event delivery for Broadcaster(\"%s\") to Listener(\"%s\").",
m_broadcaster_name.AsCString(""),
hijacking_listener->GetName());
if (unique && hijacking_listener->PeekAtNextEventForBroadcasterWithType (this, event_type))
return;
hijacking_listener->AddEvent (event_sp);

View File

@ -368,7 +368,10 @@ Communication::ReadThread (void *p)
case eConnectionStatusError: // Check GetError() for details
case eConnectionStatusTimedOut: // Request timed out
if (log)
error.LogIfError(log.get(), "%p Communication::ReadFromConnection () => status = %i", p, status);
error.LogIfError(log.get(),
"%p Communication::ReadFromConnection () => status = %s",
p,
Communication::ConnectionStatusAsCString (status));
break;
}
}

View File

@ -88,9 +88,15 @@ FileSpecList::Clear()
// Dumps the file list to the supplied stream pointer "s".
//------------------------------------------------------------------
void
FileSpecList::Dump(Stream *s) const
FileSpecList::Dump(Stream *s, const char *separator_cstr) const
{
for_each (m_files.begin(), m_files.end(), bind2nd(mem_fun_ref(&FileSpec::Dump),s));
collection::const_iterator pos, end = m_files.end();
for (pos = m_files.begin(); pos != end; ++pos)
{
pos->Dump(s);
if (separator_cstr)
s->PutCString(separator_cstr);
}
}
//------------------------------------------------------------------

View File

@ -193,16 +193,6 @@ Module::GetCompileUnitAtIndex (uint32_t index)
return cu_sp;
}
//CompUnitSP
//Module::FindCompUnit(lldb::user_id_t uid)
//{
// CompUnitSP cu_sp;
// SymbolVendor *symbols = GetSymbolVendor ();
// if (symbols)
// cu_sp = symbols->FindCompUnit(uid);
// return cu_sp;
//}
bool
Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
{
@ -322,6 +312,28 @@ Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_
return 0;
}
uint32_t
Module::FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list)
{
if (!append)
sc_list.Clear();
const uint32_t start_size = sc_list.GetSize();
const uint32_t num_compile_units = GetNumCompileUnits();
SymbolContext sc;
sc.module_sp = GetSP();
const bool compare_directory = path.GetDirectory();
for (uint32_t i=0; i<num_compile_units; ++i)
{
sc.comp_unit = GetCompileUnitAtIndex(i).get();
if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
sc_list.Append(sc);
}
return sc_list.GetSize() - start_size;
}
uint32_t
Module::FindFunctions (const ConstString &name,
uint32_t name_type_mask,

View File

@ -150,7 +150,7 @@ ModuleList::GetModuleAtIndex(uint32_t idx)
return module_sp;
}
size_t
uint32_t
ModuleList::FindFunctions (const ConstString &name,
uint32_t name_type_mask,
bool include_symbols,
@ -170,6 +170,24 @@ ModuleList::FindFunctions (const ConstString &name,
return sc_list.GetSize();
}
uint32_t
ModuleList::FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list)
{
if (!append)
sc_list.Clear();
Mutex::Locker locker(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
(*pos)->FindCompileUnits (path, true, sc_list);
}
return sc_list.GetSize();
}
uint32_t
ModuleList::FindGlobalVariables (const ConstString &name,
bool append,

View File

@ -326,7 +326,7 @@ SearchFilterByModule::~SearchFilterByModule()
bool
SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
{
if (module_sp && FileSpec::Compare (module_sp->GetFileSpec(), m_module_spec, false) == 0)
if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false))
return true;
else
return false;

View File

@ -331,8 +331,25 @@ Section::ReadSectionDataFromObjectFile (const ObjectFile* objfile, off_t section
if (file)
{
off_t section_file_offset = GetFileOffset() + objfile->GetOffset() + section_offset;
return file.ReadFileContents (section_file_offset, dst, dst_len);
size_t bytes_left = dst_len;
size_t bytes_read = 0;
const uint64_t file_size = GetFileSize();
if (section_offset < file_size)
{
off_t section_file_offset = objfile->GetOffset() + GetFileOffset() + section_offset;
bytes_read = file.ReadFileContents (section_file_offset, dst, dst_len);
if (bytes_read >= dst_len)
return bytes_read;
bytes_left -= bytes_read;
}
const uint64_t byte_size = GetByteSize();
if (section_offset + bytes_read < byte_size)
{
memset ((uint8_t*)dst + bytes_read, 0, bytes_left);
bytes_read += bytes_left;
}
return bytes_read;
}
}
return 0;

View File

@ -279,7 +279,7 @@ SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before,
bool
SourceManager::File::FileSpecMatches (const FileSpec &file_spec)
{
return FileSpec::Compare (m_file_spec, file_spec, false) == 0;
return FileSpec::Equal (m_file_spec, file_spec, false);
}

View File

@ -31,98 +31,30 @@ using namespace lldb;
using namespace lldb_private;
Value::Value() :
m_value(),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
m_value (),
m_value_type (eValueTypeScalar),
m_context (NULL),
m_context_type (eContextTypeInvalid),
m_data_buffer ()
{
}
Value::Value(const Scalar& scalar) :
m_value(scalar),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
m_value (scalar),
m_value_type (eValueTypeScalar),
m_context (NULL),
m_context_type (eContextTypeInvalid),
m_data_buffer ()
{
}
Value::Value(int v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(unsigned int v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(long v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(unsigned long v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(long long v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(unsigned long long v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(float v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(double v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(long double v) :
m_value(v),
m_value_type(eValueTypeScalar),
m_context(NULL),
m_context_type(eContextTypeInvalid)
{
}
Value::Value(const uint8_t *bytes, int len) :
m_value(),
m_value_type(eValueTypeHostAddress),
m_context(NULL),
m_context_type(eContextTypeInvalid)
m_value (),
m_value_type (eValueTypeHostAddress),
m_context (NULL),
m_context_type (eContextTypeInvalid),
m_data_buffer ()
{
m_data_buffer.CopyData(bytes, len);
m_value = (uintptr_t)m_data_buffer.GetBytes();
@ -163,35 +95,9 @@ Value::operator=(const Value &rhs)
return *this;
}
Value *
Value::CreateProxy()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->CreateProxy ();
Value *ret = new Value;
ret->SetContext(eContextTypeValue, this);
return ret;
}
Value *
Value::GetProxyTarget()
{
if (m_context_type == eContextTypeValue)
return (Value*)m_context;
else
return NULL;
}
void
Value::Dump (Stream* strm)
{
if (m_context_type == eContextTypeValue)
{
((Value*)m_context)->Dump (strm);
return;
}
m_value.GetValue (strm, true);
strm->Printf(", value_type = %s, context = %p, context_type = %s",
Value::GetValueTypeAsCString(m_value_type),
@ -202,18 +108,12 @@ Value::Dump (Stream* strm)
Value::ValueType
Value::GetValueType() const
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetValueType ();
return m_value_type;
}
AddressType
Value::GetValueAddressType () const
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetValueAddressType ();
switch (m_value_type)
{
default:
@ -226,60 +126,9 @@ Value::GetValueAddressType () const
return eAddressTypeInvalid;
}
Value::ContextType
Value::GetContextType() const
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetContextType ();
return m_context_type;
}
void
Value::SetValueType (Value::ValueType value_type)
{
if (m_context_type == eContextTypeValue)
{
((Value*)m_context)->SetValueType(value_type);
return;
}
m_value_type = value_type;
}
void
Value::ClearContext ()
{
if (m_context_type == eContextTypeValue)
{
((Value*)m_context)->ClearContext();
return;
}
m_context = NULL;
m_context_type = eContextTypeInvalid;
}
void
Value::SetContext (Value::ContextType context_type, void *p)
{
if (m_context_type == eContextTypeValue)
{
((Value*)m_context)->SetContext(context_type, p);
return;
}
m_context_type = context_type;
m_context = p;
}
RegisterInfo *
Value::GetRegisterInfo()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetRegisterInfo();
if (m_context_type == eContextTypeRegisterInfo)
return static_cast<RegisterInfo *> (m_context);
return NULL;
@ -288,32 +137,14 @@ Value::GetRegisterInfo()
Type *
Value::GetType()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetType();
if (m_context_type == eContextTypeLLDBType)
return static_cast<Type *> (m_context);
return NULL;
}
Scalar &
Value::GetScalar()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetScalar();
return m_value;
}
void
Value::ResizeData(int len)
{
if (m_context_type == eContextTypeValue)
{
((Value*)m_context)->ResizeData(len);
return;
}
m_value_type = eValueTypeHostAddress;
m_data_buffer.SetByteSize(len);
m_value = (uintptr_t)m_data_buffer.GetBytes();
@ -322,19 +153,16 @@ Value::ResizeData(int len)
bool
Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->ValueOf(exe_ctx, ast_context);
switch (m_context_type)
{
default:
case eContextTypeInvalid:
case eContextTypeClangType: // clang::Type *
case eContextTypeRegisterInfo: // RegisterInfo *
case eContextTypeLLDBType: // Type *
case eContextTypeClangType: // clang::Type *
case eContextTypeRegisterInfo: // RegisterInfo *
case eContextTypeLLDBType: // Type *
break;
case eContextTypeVariable: // Variable *
case eContextTypeVariable: // Variable *
ResolveValue(exe_ctx, ast_context);
return true;
}
@ -344,9 +172,6 @@ Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
size_t
Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetValueByteSize(ast_context, error_ptr);
size_t byte_size = 0;
switch (m_context_type)
@ -412,9 +237,6 @@ Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
clang_type_t
Value::GetClangType ()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetClangType();
switch (m_context_type)
{
default:
@ -444,9 +266,6 @@ Value::GetClangType ()
lldb::Format
Value::GetValueDefaultFormat ()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetValueDefaultFormat();
switch (m_context_type)
{
default:
@ -506,11 +325,12 @@ Value::GetData (DataExtractor &data)
}
Error
Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset)
Value::GetValueAsData (ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
DataExtractor &data,
uint32_t data_offset,
Module *module)
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetValueAsData(exe_ctx, ast_context, data, data_offset);
data.Clear();
Error error;
@ -544,16 +364,20 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
{
error.SetErrorString ("can't read load address (no execution context)");
}
else if (exe_ctx->process == NULL)
else
{
error.SetErrorString ("can't read load address (invalid process)");
}
else
{
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
address_type = eAddressTypeLoad;
data.SetByteOrder(exe_ctx->process->GetTarget().GetArchitecture().GetByteOrder());
data.SetAddressByteSize(exe_ctx->process->GetTarget().GetArchitecture().GetAddressByteSize());
Process *process = exe_ctx->GetProcess();
if (process == NULL)
{
error.SetErrorString ("can't read load address (invalid process)");
}
else
{
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
address_type = eAddressTypeLoad;
data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
}
}
break;
@ -568,71 +392,91 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
}
else
{
// The only thing we can currently lock down to a module so that
// we can resolve a file address, is a variable.
Variable *variable = GetVariable();
if (GetVariable())
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
if (address == LLDB_INVALID_ADDRESS)
{
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
if (address != LLDB_INVALID_ADDRESS)
error.SetErrorString ("invalid file address");
}
else
{
if (module == NULL)
{
// The only thing we can currently lock down to a module so that
// we can resolve a file address, is a variable.
Variable *variable = GetVariable();
if (variable)
{
SymbolContext var_sc;
variable->CalculateSymbolContext(&var_sc);
module = var_sc.module_sp.get();
}
}
if (module)
{
bool resolved = false;
SymbolContext var_sc;
variable->CalculateSymbolContext(&var_sc);
if (var_sc.module_sp)
ObjectFile *objfile = module->GetObjectFile();
if (objfile)
{
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
if (objfile)
Address so_addr(address, objfile->GetSectionList());
addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
if (load_address != LLDB_INVALID_ADDRESS)
{
Address so_addr(address, objfile->GetSectionList());
addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
if (load_address != LLDB_INVALID_ADDRESS)
resolved = true;
address = load_address;
address_type = eAddressTypeLoad;
data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
}
else
{
if (so_addr.IsSectionOffset())
{
resolved = true;
address = load_address;
address_type = eAddressTypeLoad;
data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
}
else
{
if (so_addr.IsSectionOffset())
{
resolved = true;
file_so_addr = so_addr;
data.SetByteOrder(objfile->GetByteOrder());
data.SetAddressByteSize(objfile->GetAddressByteSize());
}
file_so_addr = so_addr;
data.SetByteOrder(objfile->GetByteOrder());
data.SetAddressByteSize(objfile->GetAddressByteSize());
}
}
}
if (!resolved)
{
if (var_sc.module_sp)
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
address,
variable->GetName().AsCString(""),
var_sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
var_sc.module_sp->GetFileSpec().GetDirectory() ? "/" : "",
var_sc.module_sp->GetFileSpec().GetFilename().GetCString());
Variable *variable = GetVariable();
if (module)
{
if (variable)
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
address,
variable->GetName().AsCString(""),
module->GetFileSpec().GetDirectory().GetCString(),
module->GetFileSpec().GetDirectory() ? "/" : "",
module->GetFileSpec().GetFilename().GetCString());
else
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s",
address,
module->GetFileSpec().GetDirectory().GetCString(),
module->GetFileSpec().GetDirectory() ? "/" : "",
module->GetFileSpec().GetFilename().GetCString());
}
else
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
address,
variable->GetName().AsCString(""));
{
if (variable)
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
address,
variable->GetName().AsCString(""));
else
error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
}
}
}
else
{
error.SetErrorString ("invalid file address");
// Can't convert a file address to anything valid without more
// context (which Module it came from)
error.SetErrorString ("can't read memory from file address without more context");
}
}
else
{
// Can't convert a file address to anything valid without more
// context (which Module it came from)
error.SetErrorString ("can't read memory from file address without more context");
}
}
break;
@ -695,9 +539,24 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
}
else
{
if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
// The execution context might have a NULL process, but it
// might have a valid process in the exe_ctx->target, so use
// the ExecutionContext::GetProcess accessor to ensure we
// get the process if there is one.
Process *process = exe_ctx->GetProcess();
if (process)
{
error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
if (bytes_read != byte_size)
error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)",
(uint64_t)address,
(uint32_t)bytes_read,
(uint32_t)byte_size);
}
else
{
error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);
}
}
}
@ -717,30 +576,9 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
Scalar &
Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{
Scalar scalar;
if (m_context_type == eContextTypeValue)
void *opaque_clang_qual_type = GetClangType();
if (opaque_clang_qual_type)
{
// Resolve the proxy
Value * rhs = (Value*)m_context;
m_value = rhs->m_value;
m_value_type = rhs->m_value_type;
m_context = rhs->m_context;
m_context_type = rhs->m_context_type;
if ((uintptr_t)rhs->m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs->m_data_buffer.GetBytes())
{
m_data_buffer.CopyData(rhs->m_data_buffer.GetBytes(),
rhs->m_data_buffer.GetByteSize());
m_value = (uintptr_t)m_data_buffer.GetBytes();
}
}
if (m_context_type == eContextTypeClangType)
{
void *opaque_clang_qual_type = GetClangType();
switch (m_value_type)
{
case eValueTypeScalar: // raw scalar value
@ -759,6 +597,7 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
DataExtractor data;
if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
{
Scalar scalar;
if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
{
m_value = scalar;
@ -784,8 +623,6 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
}
break;
}
}
return m_value;
}
@ -793,16 +630,11 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
Variable *
Value::GetVariable()
{
if (m_context_type == eContextTypeValue)
return ((Value*)m_context)->GetVariable();
if (m_context_type == eContextTypeVariable)
return static_cast<Variable *> (m_context);
return NULL;
}
const char *
Value::GetValueTypeAsCString (ValueType value_type)
{
@ -821,12 +653,11 @@ Value::GetContextTypeAsCString (ContextType context_type)
{
switch (context_type)
{
case eContextTypeInvalid: return "invalid";
case eContextTypeClangType: return "clang::Type *";
case eContextTypeRegisterInfo: return "RegisterInfo *";
case eContextTypeLLDBType: return "Type *";
case eContextTypeVariable: return "Variable *";
case eContextTypeValue: return "Value"; // TODO: Sean, more description here?
case eContextTypeInvalid: return "invalid";
case eContextTypeClangType: return "clang::Type *";
case eContextTypeRegisterInfo: return "RegisterInfo *";
case eContextTypeLLDBType: return "Type *";
case eContextTypeVariable: return "Variable *";
};
return "???";
}

View File

@ -973,7 +973,7 @@ ValueObject::SetValueFromCString (const char *value_str)
unsigned long long ull_val = strtoull(value_str, &end, 0);
if (end && *end != '\0')
return false;
m_value = ull_val;
m_value.GetScalar() = ull_val;
// Limit the bytes in our m_data appropriately.
m_value.GetScalar().GetData (m_data, byte_size);
}
@ -989,7 +989,7 @@ ValueObject::SetValueFromCString (const char *value_str)
long long sll_val = strtoll(value_str, &end, 0);
if (end && *end != '\0')
return false;
m_value = sll_val;
m_value.GetScalar() = sll_val;
// Limit the bytes in our m_data appropriately.
m_value.GetScalar().GetData (m_data, byte_size);
}
@ -1612,7 +1612,7 @@ ValueObject::CreateConstantValue (const ConstString &name)
data.SetByteOrder (m_data.GetByteOrder());
data.SetAddressByteSize(m_data.GetAddressByteSize());
m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0, GetModule());
valobj_sp = ValueObjectConstResult::Create (exe_scope,
ast,

View File

@ -169,7 +169,7 @@ ValueObjectChild::UpdateValue ()
if (m_error.Success())
{
ExecutionContext exe_ctx (GetExecutionContextScope());
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0, GetModule());
}
}
else

View File

@ -177,7 +177,7 @@ ValueObjectDynamicValue::UpdateValue ()
if (m_type_sp)
SetValueDidChange(true);
m_value = m_parent->GetValue();
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
return m_error.Success();
}
@ -225,7 +225,7 @@ ValueObjectDynamicValue::UpdateValue ()
{
// The variable value is in the Scalar value inside the m_value.
// We can point our m_data right to it.
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
if (m_error.Success())
{
if (ClangASTContext::IsAggregateType (GetClangType()))

View File

@ -205,7 +205,7 @@ ValueObjectMemory::UpdateValue ()
case Value::eValueTypeScalar:
// The variable value is in the Scalar value inside the m_value.
// We can point our m_data right to it.
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
break;
case Value::eValueTypeFileAddress:
@ -247,7 +247,7 @@ ValueObjectMemory::UpdateValue ()
else
value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule());
}
break;
}
@ -267,3 +267,11 @@ ValueObjectMemory::IsInScope ()
return true;
}
Module *
ValueObjectMemory::GetModule()
{
return m_address.GetModule();
}

View File

@ -20,6 +20,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
@ -154,7 +155,7 @@ ValueObjectVariable::UpdateValue ()
case Value::eValueTypeScalar:
// The variable value is in the Scalar value inside the m_value.
// We can point our m_data right to it.
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule());
break;
case Value::eValueTypeFileAddress:
@ -206,7 +207,7 @@ ValueObjectVariable::UpdateValue ()
// so it can extract read its value into m_data appropriately
Value value(m_value);
value.SetContext(Value::eContextTypeVariable, variable);
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule());
}
break;
}
@ -233,3 +234,20 @@ ValueObjectVariable::IsInScope ()
return m_variable_sp->IsInScope (frame);
}
Module *
ValueObjectVariable::GetModule()
{
if (m_variable_sp)
{
SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
if (sc_scope)
{
SymbolContext sc;
sc_scope->CalculateSymbolContext (&sc);
return sc.module_sp.get();
}
}
return NULL;
}

View File

@ -896,7 +896,7 @@ DWARFExpression::Evaluate
// address and whose size is the size of an address on the target machine.
//----------------------------------------------------------------------
case DW_OP_addr:
stack.push_back(opcodes.GetAddress(&offset));
stack.push_back(Scalar(opcodes.GetAddress(&offset)));
stack.back().SetValueType (Value::eValueTypeFileAddress);
break;
@ -1157,16 +1157,16 @@ DWARFExpression::Evaluate
// DW_OP_constu unsigned LEB128 integer constant
// DW_OP_consts signed LEB128 integer constant
//----------------------------------------------------------------------
case DW_OP_const1u : stack.push_back(( uint8_t)opcodes.GetU8(&offset)); break;
case DW_OP_const1s : stack.push_back(( int8_t)opcodes.GetU8(&offset)); break;
case DW_OP_const2u : stack.push_back((uint16_t)opcodes.GetU16(&offset)); break;
case DW_OP_const2s : stack.push_back(( int16_t)opcodes.GetU16(&offset)); break;
case DW_OP_const4u : stack.push_back((uint32_t)opcodes.GetU32(&offset)); break;
case DW_OP_const4s : stack.push_back(( int32_t)opcodes.GetU32(&offset)); break;
case DW_OP_const8u : stack.push_back((uint64_t)opcodes.GetU64(&offset)); break;
case DW_OP_const8s : stack.push_back(( int64_t)opcodes.GetU64(&offset)); break;
case DW_OP_constu : stack.push_back(opcodes.GetULEB128(&offset)); break;
case DW_OP_consts : stack.push_back(opcodes.GetSLEB128(&offset)); break;
case DW_OP_const1u : stack.push_back(Scalar(( uint8_t)opcodes.GetU8 (&offset))); break;
case DW_OP_const1s : stack.push_back(Scalar(( int8_t)opcodes.GetU8 (&offset))); break;
case DW_OP_const2u : stack.push_back(Scalar((uint16_t)opcodes.GetU16 (&offset))); break;
case DW_OP_const2s : stack.push_back(Scalar(( int16_t)opcodes.GetU16 (&offset))); break;
case DW_OP_const4u : stack.push_back(Scalar((uint32_t)opcodes.GetU32 (&offset))); break;
case DW_OP_const4s : stack.push_back(Scalar(( int32_t)opcodes.GetU32 (&offset))); break;
case DW_OP_const8u : stack.push_back(Scalar((uint64_t)opcodes.GetU64 (&offset))); break;
case DW_OP_const8s : stack.push_back(Scalar(( int64_t)opcodes.GetU64 (&offset))); break;
case DW_OP_constu : stack.push_back(Scalar(opcodes.GetULEB128 (&offset))); break;
case DW_OP_consts : stack.push_back(Scalar(opcodes.GetSLEB128 (&offset))); break;
//----------------------------------------------------------------------
// OPCODE: DW_OP_dup
@ -1877,7 +1877,7 @@ DWARFExpression::Evaluate
case DW_OP_lit29:
case DW_OP_lit30:
case DW_OP_lit31:
stack.push_back(op - DW_OP_lit0);
stack.push_back(Scalar(op - DW_OP_lit0));
break;
//----------------------------------------------------------------------
@ -2567,6 +2567,10 @@ DWARFExpression::Evaluate
error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_expr_local(%u) with invalid index %u.\n", idx, idx);
return false;
}
// The proxy code has been removed. If it is ever re-added, please
// use shared pointers or return by value to avoid possible memory
// leak (there is no leak here, but in general, no returning pointers
// that must be manually freed please.
Value *proxy = expr_local_variable->CreateProxy();
stack.push_back(*proxy);
delete proxy;
@ -2598,6 +2602,10 @@ DWARFExpression::Evaluate
error_ptr->SetErrorStringWithFormat ("DW_OP_APPLE_extern(%u) with invalid index %u.\n", idx, idx);
return false;
}
// The proxy code has been removed. If it is ever re-added, please
// use shared pointers or return by value to avoid possible memory
// leak (there is no leak here, but in general, no returning pointers
// that must be manually freed please.
Value *proxy = extern_var->CreateProxy();
stack.push_back(*proxy);
delete proxy;

View File

@ -315,6 +315,27 @@ OptionValueFileSpec::SetValueFromCString (const char *value_cstr)
return Error();
}
//-------------------------------------------------------------------------
// OptionValueFileSpecList
//-------------------------------------------------------------------------
void
OptionValueFileSpecList::DumpValue (Stream &strm)
{
m_current_value.Dump(&strm, "\n");
}
Error
OptionValueFileSpecList::SetValueFromCString (const char *value_cstr)
{
if (value_cstr && value_cstr[0])
{
FileSpec file (value_cstr, false);
m_current_value.Append(file);
}
m_value_was_set = true;
return Error();
}
//-------------------------------------------------------------------------
// OptionValueUUID

View File

@ -55,3 +55,43 @@ OptionGroupFile::OptionParsingStarting (CommandInterpreter &interpreter)
{
m_file.Clear();
}
OptionGroupFileList::OptionGroupFileList (uint32_t usage_mask,
bool required,
const char *long_option,
char short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text) :
m_file_list ()
{
m_option_definition.usage_mask = usage_mask;
m_option_definition.required = required;
m_option_definition.long_option = long_option;
m_option_definition.short_option = short_option;
m_option_definition.option_has_arg = required_argument;
m_option_definition.enum_values = NULL;
m_option_definition.completion_type = completion_type;
m_option_definition.argument_type = argument_type;
m_option_definition.usage_text = usage_text;
}
OptionGroupFileList::~OptionGroupFileList ()
{
}
Error
OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter,
uint32_t option_idx,
const char *option_arg)
{
Error error (m_file_list.SetValueFromCString (option_arg));
return error;
}
void
OptionGroupFileList::OptionParsingStarting (CommandInterpreter &interpreter)
{
m_file_list.Clear();
}

View File

@ -407,7 +407,11 @@ AppleObjCTrampolineHandler::AppleObjCVTables::RefreshTrampolines (void *baton,
// Now get a pointer value from the zeroth argument.
Error error;
DataExtractor data;
error = argument_values.GetValueAtIndex(0)->GetValueAsData(&(context->exe_ctx), clang_ast_context->getASTContext(), data, 0);
error = argument_values.GetValueAtIndex(0)->GetValueAsData (&(context->exe_ctx),
clang_ast_context->getASTContext(),
data,
0,
NULL);
uint32_t offset_ptr = 0;
lldb::addr_t region_addr = data.GetPointer(&offset_ptr);

View File

@ -190,6 +190,8 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac
uint8_t buffer[8192];
Error error;
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
// Check for a packet from our cache first without trying any reading...
if (CheckForPacket (NULL, 0, packet))
return packet.GetStringRef().size();
@ -199,6 +201,15 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac
{
lldb::ConnectionStatus status;
size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
if (log)
log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu",
__PRETTY_FUNCTION__,
timeout_usec,
Communication::ConnectionStatusAsCString (status),
error.AsCString(),
bytes_read);
if (bytes_read > 0)
{
if (CheckForPacket (buffer, bytes_read, packet))

View File

@ -237,11 +237,16 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
{
Mutex::Locker locker;
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
size_t response_len = 0;
if (GetSequenceMutex (locker))
{
if (SendPacketNoLock (payload, payload_length))
return WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
else
{
if (log)
log->Printf("error: failed to send '%*s'", payload_length, payload);
}
}
else
{
@ -266,12 +271,15 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
if (log)
log->Printf ("async: sent interrupt");
if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
{
if (log)
log->Printf ("async: got response");
response = m_async_response;
return response.GetStringRef().size();
// Swap the response buffer to avoid malloc and string copy
response.GetStringRef().swap (m_async_response.GetStringRef());
response_len = response.GetStringRef().size();
}
else
{
@ -289,7 +297,9 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
else
{
// We had a racy condition where we went to send the interrupt
// yet we were able to get the loc
// yet we were able to get the lock
if (log)
log->Printf ("async: got lock but failed to send interrupt");
}
}
else
@ -301,10 +311,15 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
else
{
if (log)
log->Printf ("mutex taken and send_async == false, aborting packet");
log->Printf("error: packet mutex taken and send_async == false, not sending packet '%*s'", payload_length, payload);
}
}
return 0;
if (response_len == 0)
{
if (log)
log->Printf("error: failed to get response for '%*s'", payload_length, payload);
}
return response_len;
}
//template<typename _Tp>

View File

@ -3381,8 +3381,6 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
clang_type = m_forward_decl_die_to_clang_type.lookup (die);
if (clang_type == NULL)
{
if (die->GetOffset() == 0x1c436)
printf("REMOVE THIS!!!\n");
enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
DW_ATE_signed,
byte_size * 8);

View File

@ -285,7 +285,7 @@ CompileUnit::ResolveSymbolContext
// "file_spec" has an empty directory, then only compare the basenames
// when finding file indexes
std::vector<uint32_t> file_indexes;
bool file_spec_matches_cu_file_spec = FileSpec::Compare(file_spec, this, !file_spec.GetDirectory().IsEmpty()) == 0;
bool file_spec_matches_cu_file_spec = FileSpec::Equal(file_spec, this, !file_spec.GetDirectory().IsEmpty());
// If we are not looking for inlined functions and our file spec doesn't
// match then we are done...

View File

@ -99,3 +99,13 @@ ExecutionContext::GetBestExecutionContextScope () const
return process;
return target;
}
Process *
ExecutionContext::GetProcess () const
{
if (process)
return process;
if (target)
return target->GetProcessSP().get();
return NULL;
}

View File

@ -444,7 +444,6 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
m_arch));
if (image_module_sp.get())
{
//image_module_sp->Dump(&s);// REMOVE THIS, DEBUG ONLY
ObjectFile *objfile = image_module_sp->GetObjectFile();
if (objfile)
objfile->GetDependentModules(dependent_files);

View File

@ -211,6 +211,11 @@ main (int argc, char *argv[])
if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done))
break;
}
if (error.Fail())
{
fprintf(stderr, "error: %s\n", error.AsCString());
}
}
else
{