Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make sense by default so that subclasses can check: int PlatformSubclass::Foo () { if (IsHost()) return Platform::Foo (); // Let the platform base class do the host specific stuff // Platform subclass specific code... int result = ... return result; } Added new functions to the platform: virtual const char *Platform::GetUserName (uint32_t uid); virtual const char *Platform::GetGroupName (uint32_t gid); The user and group names are cached locally so that remote platforms can avoid sending packets multiple times to resolve this information. Added the parent process ID to the ProcessInfo class. Added a new ProcessInfoMatch class which helps us to match processes up and changed the Host layer over to using this new class. The new class allows us to search for processs: 1 - by name (equal to, starts with, ends with, contains, and regex) 2 - by pid 3 - And further check for parent pid == value, uid == value, gid == value, euid == value, egid == value, arch == value, parent == value. This is all hookup up to the "platform process list" command which required adding dumping routines to dump process information. If the Host class implements the process lookup routines, you can now lists processes on your local machine: machine1.foo.com % lldb (lldb) platform process list PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME ====== ====== ========== ========== ========== ========== ======================== ============================ 99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge 94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker 94852 244 username usergroup username usergroup x86_64-apple-darwin Safari 94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode 92742 92710 username usergroup username usergroup i386-apple-darwin debugserver This of course also works remotely with the lldb-platform: machine1.foo.com % lldb-platform --listen 1234 machine2.foo.com % lldb (lldb) platform create remote-macosx Platform: remote-macosx Connected: no (lldb) platform connect connect://localhost:1444 Platform: remote-macosx Triple: x86_64-apple-darwin OS Version: 10.6.7 (10J869) Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 Hostname: machine1.foo.com Connected: yes (lldb) platform process list PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME ====== ====== ========== ========== ========== ========== ======================== ============================ 99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation 99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb 99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge 94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker 94852 244 username usergroup username usergroup x86_64-apple-darwin Safari The lldb-platform implements everything with the Host:: layer, so this should "just work" for linux. I will probably be adding more stuff to the Host layer for launching processes and attaching to processes so that this support should eventually just work as well. Modified the target to be able to be created with an architecture that differs from the main executable. This is needed for iOS debugging since we can have an "armv6" binary which can run on an "armv7" machine, so we want to be able to do: % lldb (lldb) platform create remote-ios (lldb) file --arch armv7 a.out Where "a.out" is an armv6 executable. The platform then can correctly decide to open all "armv7" images for all dependent shared libraries. Modified the disassembly to show the current PC value. Example output: (lldb) disassemble --frame a.out`main: 0x1eb7: pushl %ebp 0x1eb8: movl %esp, %ebp 0x1eba: pushl %ebx 0x1ebb: subl $20, %esp 0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18 0x1ec3: popl %ebx -> 0x1ec4: calll 0x1f12 ; getpid 0x1ec9: movl %eax, 4(%esp) 0x1ecd: leal 199(%ebx), %eax 0x1ed3: movl %eax, (%esp) 0x1ed6: calll 0x1f18 ; printf 0x1edb: leal 213(%ebx), %eax 0x1ee1: movl %eax, (%esp) 0x1ee4: calll 0x1f1e ; puts 0x1ee9: calll 0x1f0c ; getchar 0x1eee: movl $20, (%esp) 0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6 0x1efa: movl $12, %eax 0x1eff: addl $20, %esp 0x1f02: popl %ebx 0x1f03: leave 0x1f04: ret This can be handy when dealing with the new --line options that was recently added: (lldb) disassemble --line a.out`main + 13 at test.c:19 18 { -> 19 printf("Process: %i\n\n", getpid()); 20 puts("Press any key to continue..."); getchar(); -> 0x1ec4: calll 0x1f12 ; getpid 0x1ec9: movl %eax, 4(%esp) 0x1ecd: leal 199(%ebx), %eax 0x1ed3: movl %eax, (%esp) 0x1ed6: calll 0x1f18 ; printf Modified the ModuleList to have a lookup based solely on a UUID. Since the UUID is typically the MD5 checksum of a binary image, there is no need to give the path and architecture when searching for a pre-existing image in an image list. Now that we support remote debugging a bit better, our lldb_private::Module needs to be able to track what the original path for file was as the platform knows it, as well as where the file is locally. The module has the two following functions to retrieve both paths: const FileSpec &Module::GetFileSpec () const; const FileSpec &Module::GetPlatformFileSpec () const; llvm-svn: 128563
This commit is contained in:
parent
ae917a3740
commit
32e0a7509c
|
@ -27,7 +27,8 @@ namespace lldb_private {
|
|||
class Instruction
|
||||
{
|
||||
public:
|
||||
Instruction (const Address &address, AddressClass addr_class);
|
||||
Instruction (const Address &address,
|
||||
AddressClass addr_class = eAddressClassInvalid);
|
||||
|
||||
virtual
|
||||
~Instruction();
|
||||
|
@ -202,7 +203,6 @@ public:
|
|||
Debugger &debugger,
|
||||
const ArchSpec &arch,
|
||||
const ExecutionContext &exe_ctx,
|
||||
const Address &start_addr,
|
||||
uint32_t num_instructions,
|
||||
uint32_t num_mixed_context_lines,
|
||||
bool show_bytes,
|
||||
|
|
|
@ -320,12 +320,47 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
/// Get const accessor for the module file specification.
|
||||
///
|
||||
/// This function returns the file for the module on the host system
|
||||
/// that is running LLDB. This can differ from the path on the
|
||||
/// platform since we might be doing remote debugging.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
//------------------------------------------------------------------
|
||||
const FileSpec &
|
||||
GetFileSpec () const;
|
||||
GetFileSpec () const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor for the module platform file specification.
|
||||
///
|
||||
/// Platform file refers to the path of the module as it is known on
|
||||
/// the remote system on which it is being debugged. For local
|
||||
/// debugging this is always the same as Module::GetFileSpec(). But
|
||||
/// remote debugging might mention a file "/usr/lib/liba.dylib"
|
||||
/// which might be locally downloaded and cached. In this case the
|
||||
/// platform file could be something like:
|
||||
/// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib"
|
||||
/// The file could also be cached in a local developer kit directory.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
//------------------------------------------------------------------
|
||||
const FileSpec &
|
||||
GetPlatformFileSpec () const
|
||||
{
|
||||
if (m_platform_file)
|
||||
return m_platform_file;
|
||||
return m_file;
|
||||
}
|
||||
|
||||
void
|
||||
SetPlatformFileSpec (const FileSpec &file)
|
||||
{
|
||||
m_platform_file = file;
|
||||
}
|
||||
|
||||
const TimeValue &
|
||||
GetModificationTime () const;
|
||||
|
@ -561,6 +596,7 @@ protected:
|
|||
ArchSpec m_arch; ///< The architecture for this module.
|
||||
lldb_private::UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols.
|
||||
FileSpec m_file; ///< The file representation on disk for this module (if there is one).
|
||||
FileSpec m_platform_file;///< The path to the module on the platform on which it is being debugged
|
||||
ConstString m_object_name; ///< The name an object within this module that is selected, or empty of the module is represented by \a m_file.
|
||||
std::auto_ptr<ObjectFile> m_objfile_ap; ///< A pointer to the object file parser for this module.
|
||||
std::auto_ptr<SymbolVendor> m_symfile_ap; ///< A pointer to the symbol vendor for this module.
|
||||
|
|
|
@ -266,9 +266,25 @@ public:
|
|||
lldb::ModuleSP
|
||||
FindModule (const Module *module_ptr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Find a module by UUID
|
||||
//
|
||||
// The UUID value for a module is extracted from the ObjectFile and
|
||||
// is the MD5 checksum, or a smarter object file equivalent, so
|
||||
// finding modules by UUID values is very efficient and accurate.
|
||||
//------------------------------------------------------------------
|
||||
lldb::ModuleSP
|
||||
FindModule (const UUID &uuid);
|
||||
|
||||
lldb::ModuleSP
|
||||
FindFirstModuleForFileSpec (const FileSpec &file_spec,
|
||||
const ConstString *object_name = NULL);
|
||||
const ArchSpec *arch_ptr,
|
||||
const ConstString *object_name);
|
||||
|
||||
lldb::ModuleSP
|
||||
FindFirstModuleForPlatormFileSpec (const FileSpec &platform_file_spec,
|
||||
const ArchSpec *arch_ptr,
|
||||
const ConstString *object_name);
|
||||
|
||||
size_t
|
||||
FindSymbolsWithNameAndType (const ConstString &name,
|
||||
|
|
|
@ -110,6 +110,12 @@ public:
|
|||
static bool
|
||||
GetHostname (std::string &s);
|
||||
|
||||
static const char *
|
||||
GetUserName (uint32_t uid, std::string &user_name);
|
||||
|
||||
static const char *
|
||||
GetGroupName (uint32_t gid, std::string &group_name);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Gets the host architecture.
|
||||
///
|
||||
|
@ -337,9 +343,8 @@ public:
|
|||
SetCrashDescription (const char *description);
|
||||
|
||||
static uint32_t
|
||||
FindProcessesByName (const char *name,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &proc_infos);
|
||||
FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &proc_infos);
|
||||
|
||||
static bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
|
||||
|
|
|
@ -167,8 +167,13 @@ public:
|
|||
virtual const OptionDefinition*
|
||||
GetDefinitions () { return NULL; }
|
||||
|
||||
virtual void
|
||||
ResetOptionValues ();
|
||||
// Call this prior to parsing any options. This call will call the
|
||||
// subclass ResetOptionValues() and will avoid the need for all
|
||||
// ResetOptionValues() function instances from having to call the
|
||||
// Option::ResetOptionValues() like they did before. This was error
|
||||
// prone and subclasses shouldn't have to do it.
|
||||
void
|
||||
Reset ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the value of an option.
|
||||
|
@ -313,6 +318,12 @@ protected:
|
|||
|
||||
void
|
||||
OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set);
|
||||
|
||||
// Subclasses must reset their option values prior to starting a new
|
||||
// option parse. Each subclass must override this function and revert
|
||||
// all option settings to default values.
|
||||
virtual void
|
||||
ResetOptionValues () = 0;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -19,6 +20,7 @@
|
|||
// Project includes
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
|
@ -121,7 +123,7 @@ namespace lldb_private {
|
|||
bool
|
||||
GetOSKernelDescription (std::string &s);
|
||||
|
||||
const char *
|
||||
virtual const char *
|
||||
GetHostname ();
|
||||
|
||||
virtual const char *
|
||||
|
@ -172,13 +174,11 @@ namespace lldb_private {
|
|||
return ArchSpec(); // Return an invalid architecture
|
||||
}
|
||||
|
||||
// Remote subclasses should override this and return a valid instance
|
||||
// name if connected.
|
||||
virtual const char *
|
||||
GetRemoteHostname ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
GetUserName (uint32_t uid);
|
||||
|
||||
virtual const char *
|
||||
GetGroupName (uint32_t gid);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Locate a file for a platform.
|
||||
|
@ -189,6 +189,15 @@ namespace lldb_private {
|
|||
/// @param[in] platform_file
|
||||
/// The platform file path to locate and cache locally.
|
||||
///
|
||||
/// @param[in] uuid_ptr
|
||||
/// If we know the exact UUID of the file we are looking for, it
|
||||
/// can be specified. If it is not specified, we might now know
|
||||
/// the exact file. The UUID is usually some sort of MD5 checksum
|
||||
/// for the file and is sometimes known by dynamic linkers/loaders.
|
||||
/// If the UUID is known, it is best to supply it to platform
|
||||
/// file queries to ensure we are finding the correct file, not
|
||||
/// just a file at the correct path.
|
||||
///
|
||||
/// @param[out] local_file
|
||||
/// A locally cached version of the platform file. For platforms
|
||||
/// that describe the current host computer, this will just be
|
||||
|
@ -204,6 +213,16 @@ namespace lldb_private {
|
|||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
|
||||
virtual Error
|
||||
GetSharedModule (const FileSpec &platform_file,
|
||||
const ArchSpec &arch,
|
||||
const UUID *uuid_ptr,
|
||||
const ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
lldb::ModuleSP &module_sp,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr);
|
||||
|
||||
virtual Error
|
||||
ConnectRemote (Args& args);
|
||||
|
||||
|
@ -333,13 +352,16 @@ namespace lldb_private {
|
|||
// bool wait_for_launch,
|
||||
// Error &error) = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// The base class Platform will take care of the host platform.
|
||||
// Subclasses will need to fill in the remote case.
|
||||
//------------------------------------------------------------------
|
||||
virtual uint32_t
|
||||
FindProcessesByName (const char *name,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &proc_infos) = 0;
|
||||
FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &proc_infos);
|
||||
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info) = 0;
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
|
||||
|
||||
const std::string &
|
||||
GetRemoteURL () const
|
||||
|
@ -377,6 +399,18 @@ namespace lldb_private {
|
|||
m_os_version_set_while_connected = m_system_arch.IsValid();
|
||||
}
|
||||
|
||||
// Used for column widths
|
||||
uint32_t
|
||||
GetMaxUserIDNameLength() const
|
||||
{
|
||||
return m_max_uid_name_len;
|
||||
}
|
||||
// Used for column widths
|
||||
uint32_t
|
||||
GetMaxGroupIDNameLength() const
|
||||
{
|
||||
return m_max_gid_name_len;
|
||||
}
|
||||
protected:
|
||||
bool m_is_host;
|
||||
// Set to true when we are able to actually set the OS version while
|
||||
|
@ -392,6 +426,99 @@ namespace lldb_private {
|
|||
uint32_t m_minor_os_version;
|
||||
uint32_t m_update_os_version;
|
||||
ArchSpec m_system_arch; // The architecture of the kernel or the remote platform
|
||||
typedef std::map<uint32_t, ConstString> IDToNameMap;
|
||||
Mutex m_uid_map_mutex;
|
||||
Mutex m_gid_map_mutex;
|
||||
IDToNameMap m_uid_map;
|
||||
IDToNameMap m_gid_map;
|
||||
uint32_t m_max_uid_name_len;
|
||||
uint32_t m_max_gid_name_len;
|
||||
|
||||
const char *
|
||||
GetCachedUserName (uint32_t uid)
|
||||
{
|
||||
Mutex::Locker locker (m_uid_map_mutex);
|
||||
IDToNameMap::iterator pos = m_uid_map.find (uid);
|
||||
if (pos != m_uid_map.end())
|
||||
{
|
||||
// return the empty string if our string is NULL
|
||||
// so we can tell when things were in the negative
|
||||
// cached (didn't find a valid user name, don't keep
|
||||
// trying)
|
||||
return pos->second.AsCString("");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
SetCachedUserName (uint32_t uid, const char *name, size_t name_len)
|
||||
{
|
||||
Mutex::Locker locker (m_uid_map_mutex);
|
||||
ConstString const_name (name);
|
||||
m_uid_map[uid] = const_name;
|
||||
if (m_max_uid_name_len < name_len)
|
||||
m_max_uid_name_len = name_len;
|
||||
// Const strings lives forever in our const string pool, so we can return the const char *
|
||||
return const_name.GetCString();
|
||||
}
|
||||
|
||||
void
|
||||
SetUserNameNotFound (uint32_t uid)
|
||||
{
|
||||
Mutex::Locker locker (m_uid_map_mutex);
|
||||
m_uid_map[uid] = ConstString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClearCachedUserNames ()
|
||||
{
|
||||
Mutex::Locker locker (m_uid_map_mutex);
|
||||
m_uid_map.clear();
|
||||
}
|
||||
|
||||
const char *
|
||||
GetCachedGroupName (uint32_t gid)
|
||||
{
|
||||
Mutex::Locker locker (m_gid_map_mutex);
|
||||
IDToNameMap::iterator pos = m_gid_map.find (gid);
|
||||
if (pos != m_gid_map.end())
|
||||
{
|
||||
// return the empty string if our string is NULL
|
||||
// so we can tell when things were in the negative
|
||||
// cached (didn't find a valid group name, don't keep
|
||||
// trying)
|
||||
return pos->second.AsCString("");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
SetCachedGroupName (uint32_t gid, const char *name, size_t name_len)
|
||||
{
|
||||
Mutex::Locker locker (m_gid_map_mutex);
|
||||
ConstString const_name (name);
|
||||
m_gid_map[gid] = const_name;
|
||||
if (m_max_gid_name_len < name_len)
|
||||
m_max_gid_name_len = name_len;
|
||||
// Const strings lives forever in our const string pool, so we can return the const char *
|
||||
return const_name.GetCString();
|
||||
}
|
||||
|
||||
void
|
||||
SetGroupNameNotFound (uint32_t gid)
|
||||
{
|
||||
Mutex::Locker locker (m_gid_map_mutex);
|
||||
m_gid_map[gid] = ConstString();
|
||||
}
|
||||
|
||||
void
|
||||
ClearCachedGroupNames ()
|
||||
{
|
||||
Mutex::Locker locker (m_gid_map_mutex);
|
||||
m_gid_map.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (Platform);
|
||||
};
|
||||
|
|
|
@ -233,7 +233,8 @@ public:
|
|||
m_effective_uid (UINT32_MAX),
|
||||
m_effective_gid (UINT32_MAX),
|
||||
m_arch(),
|
||||
m_pid (LLDB_INVALID_PROCESS_ID)
|
||||
m_pid (LLDB_INVALID_PROCESS_ID),
|
||||
m_parent_pid (LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -246,7 +247,8 @@ public:
|
|||
m_effective_uid (UINT32_MAX),
|
||||
m_effective_gid (UINT32_MAX),
|
||||
m_arch (arch),
|
||||
m_pid (pid)
|
||||
m_pid (pid),
|
||||
m_parent_pid (LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -260,11 +262,14 @@ public:
|
|||
m_effective_gid = UINT32_MAX;
|
||||
m_arch.Clear();
|
||||
m_pid = LLDB_INVALID_PROCESS_ID;
|
||||
m_parent_pid = LLDB_INVALID_PROCESS_ID;
|
||||
}
|
||||
|
||||
const char *
|
||||
GetName() const
|
||||
{
|
||||
if (m_name.empty())
|
||||
return NULL;
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
|
@ -283,12 +288,18 @@ public:
|
|||
m_name.clear();
|
||||
}
|
||||
|
||||
void
|
||||
SwapName (std::string &name)
|
||||
{
|
||||
m_name.swap (name);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetRealUserID() const
|
||||
{
|
||||
return m_real_uid;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
GetRealGroupID() const
|
||||
{
|
||||
|
@ -306,6 +317,30 @@ public:
|
|||
{
|
||||
return m_effective_gid;
|
||||
}
|
||||
|
||||
bool
|
||||
RealUserIDIsValid () const
|
||||
{
|
||||
return m_real_uid != UINT32_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
RealGroupIDIsValid () const
|
||||
{
|
||||
return m_real_gid != UINT32_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
EffectiveUserIDIsValid () const
|
||||
{
|
||||
return m_effective_uid != UINT32_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
EffectiveGroupIDIsValid () const
|
||||
{
|
||||
return m_effective_gid != UINT32_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
SetRealUserID (uint32_t uid)
|
||||
|
@ -378,6 +413,15 @@ public:
|
|||
{
|
||||
return m_parent_pid != LLDB_INVALID_PROCESS_ID;
|
||||
}
|
||||
|
||||
void
|
||||
Dump (Stream &s, Platform *platform) const;
|
||||
|
||||
static void
|
||||
DumpTableHeader (Stream &s, Platform *platform);
|
||||
|
||||
void
|
||||
DumpAsTableRow (Stream &s, Platform *platform) const;
|
||||
|
||||
protected:
|
||||
std::string m_name;
|
||||
|
@ -390,6 +434,78 @@ protected:
|
|||
lldb::pid_t m_parent_pid;
|
||||
};
|
||||
|
||||
class ProcessInfoMatch
|
||||
{
|
||||
public:
|
||||
ProcessInfoMatch () :
|
||||
m_match_info (),
|
||||
m_name_match_type (lldb_private::eNameMatchIgnore),
|
||||
m_match_all_users (false)
|
||||
{
|
||||
}
|
||||
|
||||
ProcessInfoMatch (const char *process_name,
|
||||
lldb_private::NameMatchType process_name_match_type) :
|
||||
m_match_info (),
|
||||
m_name_match_type (process_name_match_type),
|
||||
m_match_all_users (false)
|
||||
{
|
||||
m_match_info.SetName (process_name);
|
||||
}
|
||||
|
||||
ProcessInfo &
|
||||
GetProcessInfo ()
|
||||
{
|
||||
return m_match_info;
|
||||
}
|
||||
|
||||
const ProcessInfo &
|
||||
GetProcessInfo () const
|
||||
{
|
||||
return m_match_info;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMatchAllUsers () const
|
||||
{
|
||||
return m_match_all_users;
|
||||
}
|
||||
|
||||
void
|
||||
SetMatchAllUsers (bool b)
|
||||
{
|
||||
m_match_all_users = b;
|
||||
}
|
||||
|
||||
lldb_private::NameMatchType
|
||||
GetNameMatchType () const
|
||||
{
|
||||
return m_name_match_type;
|
||||
}
|
||||
|
||||
void
|
||||
SetNameMatchType (lldb_private::NameMatchType name_match_type)
|
||||
{
|
||||
m_name_match_type = name_match_type;
|
||||
}
|
||||
|
||||
bool
|
||||
NameMatches (const char *process_name) const;
|
||||
|
||||
bool
|
||||
Matches (const ProcessInfo &proc_info) const;
|
||||
|
||||
bool
|
||||
MatchAllProcesses () const;
|
||||
void
|
||||
Clear ();
|
||||
|
||||
protected:
|
||||
ProcessInfo m_match_info;
|
||||
lldb_private::NameMatchType m_name_match_type;
|
||||
bool m_match_all_users;
|
||||
};
|
||||
|
||||
class ProcessInfoList
|
||||
{
|
||||
public:
|
||||
|
@ -451,6 +567,14 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
// You must ensure "idx" is valid before calling this function
|
||||
const ProcessInfo &
|
||||
GetProcessInfoAtIndex (uint32_t idx) const
|
||||
{
|
||||
assert (idx < m_infos.size());
|
||||
return m_infos[idx];
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::vector<ProcessInfo> collection;
|
||||
collection m_infos;
|
||||
|
|
|
@ -135,7 +135,9 @@ private:
|
|||
///
|
||||
/// @see TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
|
||||
//------------------------------------------------------------------
|
||||
Target(Debugger &debugger, const lldb::PlatformSP &platform_sp);
|
||||
Target (Debugger &debugger,
|
||||
const ArchSpec &target_arch,
|
||||
const lldb::PlatformSP &platform_sp);
|
||||
|
||||
public:
|
||||
~Target();
|
||||
|
@ -345,13 +347,13 @@ public:
|
|||
ArchSpec &
|
||||
GetArchitecture ()
|
||||
{
|
||||
return m_arch_spec;
|
||||
return m_arch;
|
||||
}
|
||||
|
||||
const ArchSpec &
|
||||
GetArchitecture () const
|
||||
{
|
||||
return m_arch_spec;
|
||||
return m_arch;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -662,7 +664,7 @@ protected:
|
|||
Debugger & m_debugger;
|
||||
lldb::PlatformSP m_platform_sp; ///< The platform for this target.
|
||||
Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
|
||||
ArchSpec m_arch_spec;
|
||||
ArchSpec m_arch;
|
||||
ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded).
|
||||
SectionLoadList m_section_load_list;
|
||||
BreakpointList m_breakpoint_list;
|
||||
|
|
|
@ -103,6 +103,7 @@ class Platform;
|
|||
class Process;
|
||||
class ProcessInfo;
|
||||
class ProcessInfoList;
|
||||
class ProcessInfoMatch;
|
||||
class RegisterContext;
|
||||
class RegisterLocation;
|
||||
class RegisterLocationList;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
version = "1.3">
|
||||
version = "1.5">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
|
@ -77,7 +77,8 @@
|
|||
displayScaleIsEnabled = "NO"
|
||||
displayScale = "1.00"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
useCustomWorkingDirectory = "YES"
|
||||
customWorkingDirectory = "/Volumes/work/gclayton/Documents/src/lldb/build/Debug"
|
||||
buildConfiguration = "Debug">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
|
@ -88,6 +89,12 @@
|
|||
ReferencedContainer = "container:lldb.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "/Volumes/work/gclayton/Documents/src/a.out"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR"
|
||||
|
@ -189,4 +196,7 @@
|
|||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
<InstallAction
|
||||
buildConfiguration = "Debug">
|
||||
</InstallAction>
|
||||
</Scheme>
|
||||
|
|
|
@ -743,7 +743,7 @@ SBTarget::FindModule (const SBFileSpec &sb_file_spec)
|
|||
if (m_opaque_sp && sb_file_spec.IsValid())
|
||||
{
|
||||
// The module list is thread safe, no need to lock
|
||||
sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
|
||||
sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL, NULL));
|
||||
}
|
||||
return sb_module;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@ CommandObjectArgs::CommandOptions::SetOptionValue (int option_idx, const char *o
|
|||
void
|
||||
CommandObjectArgs::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
|
|
|
@ -235,8 +235,6 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
|
|||
void
|
||||
CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_filename.clear();
|
||||
m_line_num = 0;
|
||||
m_column = 0;
|
||||
|
@ -706,8 +704,6 @@ CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, con
|
|||
void
|
||||
CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_level = lldb::eDescriptionLevelBrief;
|
||||
m_internal = false;
|
||||
}
|
||||
|
@ -1105,8 +1101,6 @@ CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, co
|
|||
void
|
||||
CommandObjectBreakpointClear::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_filename.clear();
|
||||
m_line_num = 0;
|
||||
}
|
||||
|
@ -1485,8 +1479,6 @@ CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, c
|
|||
void
|
||||
CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_ignore_count = 0;
|
||||
m_thread_id = LLDB_INVALID_THREAD_ID;
|
||||
m_thread_id_passed = false;
|
||||
|
|
|
@ -135,8 +135,6 @@ CommandObjectBreakpointCommandAdd::CommandOptions::SetOptionValue
|
|||
void
|
||||
CommandObjectBreakpointCommandAdd::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_use_commands = true;
|
||||
m_use_script_language = false;
|
||||
m_script_language = eScriptLanguageNone;
|
||||
|
|
|
@ -69,8 +69,6 @@ private:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
m_stop_on_error = true;
|
||||
m_stop_on_continue = true;
|
||||
}
|
||||
|
@ -358,7 +356,7 @@ public:
|
|||
if (options)
|
||||
{
|
||||
// See if any options were specified as part of the alias; if so, handle them appropriately
|
||||
options->ResetOptionValues ();
|
||||
options->Reset ();
|
||||
Args tmp_args (raw_command_string.c_str());
|
||||
args.Unshift ("dummy_arg");
|
||||
args.ParseAliasOptions (*options, result, option_arg_vector, raw_command_string);
|
||||
|
@ -489,7 +487,7 @@ public:
|
|||
options = sub_cmd_obj->GetOptions();
|
||||
else
|
||||
options = cmd_obj->GetOptions();
|
||||
options->ResetOptionValues ();
|
||||
options->Reset ();
|
||||
std::string empty_string;
|
||||
args.Unshift ("dummy_arg");
|
||||
args.ParseAliasOptions (*options, result, option_arg_vector, empty_string);
|
||||
|
|
|
@ -36,12 +36,13 @@ CommandObjectDisassemble::CommandOptions::CommandOptions () :
|
|||
Options(),
|
||||
num_lines_context(0),
|
||||
num_instructions (0),
|
||||
m_func_name(),
|
||||
m_start_addr(),
|
||||
m_end_addr (),
|
||||
m_at_pc (false),
|
||||
m_plugin_name (),
|
||||
m_arch()
|
||||
func_name(),
|
||||
start_addr(),
|
||||
end_addr (),
|
||||
at_pc (false),
|
||||
frame_line (false),
|
||||
plugin_name (),
|
||||
arch()
|
||||
{
|
||||
ResetOptionValues();
|
||||
}
|
||||
|
@ -82,32 +83,39 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
|
|||
break;
|
||||
|
||||
case 's':
|
||||
m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
|
||||
if (m_start_addr == LLDB_INVALID_ADDRESS)
|
||||
m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
|
||||
start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
|
||||
if (start_addr == LLDB_INVALID_ADDRESS)
|
||||
start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
|
||||
|
||||
if (m_start_addr == LLDB_INVALID_ADDRESS)
|
||||
if (start_addr == LLDB_INVALID_ADDRESS)
|
||||
error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", option_arg);
|
||||
break;
|
||||
case 'e':
|
||||
m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
|
||||
if (m_end_addr == LLDB_INVALID_ADDRESS)
|
||||
m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
|
||||
end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
|
||||
if (end_addr == LLDB_INVALID_ADDRESS)
|
||||
end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
|
||||
|
||||
if (m_end_addr == LLDB_INVALID_ADDRESS)
|
||||
if (end_addr == LLDB_INVALID_ADDRESS)
|
||||
error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", option_arg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
m_func_name.assign (option_arg);
|
||||
func_name.assign (option_arg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
m_at_pc = true;
|
||||
at_pc = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
frame_line = true;
|
||||
// Disassemble the current source line kind of implies showing mixed
|
||||
// source code context.
|
||||
show_mixed = true;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
m_plugin_name.assign (option_arg);
|
||||
plugin_name.assign (option_arg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
|
@ -120,7 +128,7 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
|
|||
break;
|
||||
|
||||
case 'a':
|
||||
m_arch.SetTriple (option_arg);
|
||||
arch.SetTriple (option_arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -134,18 +142,18 @@ CommandObjectDisassemble::CommandOptions::SetOptionValue (int option_idx, const
|
|||
void
|
||||
CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
show_mixed = false;
|
||||
show_bytes = false;
|
||||
num_lines_context = 0;
|
||||
num_instructions = 0;
|
||||
m_func_name.clear();
|
||||
m_at_pc = false;
|
||||
m_start_addr = LLDB_INVALID_ADDRESS;
|
||||
m_end_addr = LLDB_INVALID_ADDRESS;
|
||||
func_name.clear();
|
||||
at_pc = false;
|
||||
frame_line = false;
|
||||
start_addr = LLDB_INVALID_ADDRESS;
|
||||
end_addr = LLDB_INVALID_ADDRESS;
|
||||
raw = false;
|
||||
m_plugin_name.clear();
|
||||
m_arch.Clear();
|
||||
plugin_name.clear();
|
||||
arch.Clear();
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
|
@ -172,7 +180,8 @@ CommandObjectDisassemble::CommandOptions::g_option_table[] =
|
|||
LLDB_OPT_SET_5 , false , "count", 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
|
||||
{ LLDB_OPT_SET_3 , true , "name", 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
|
||||
{ LLDB_OPT_SET_4 , true , "frame", 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
|
||||
{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the current pc."},
|
||||
{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble around the current pc."},
|
||||
{ LLDB_OPT_SET_6 , true , "line", 'l', no_argument , NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there debug line table information, else disasemble around the pc."},
|
||||
{ 0 , false , NULL, 0, 0 , NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
@ -208,10 +217,10 @@ CommandObjectDisassemble::Execute
|
|||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
if (!m_options.m_arch.IsValid())
|
||||
m_options.m_arch = target->GetArchitecture();
|
||||
if (!m_options.arch.IsValid())
|
||||
m_options.arch = target->GetArchitecture();
|
||||
|
||||
if (!m_options.m_arch.IsValid())
|
||||
if (!m_options.arch.IsValid())
|
||||
{
|
||||
result.AppendError ("use the --arch option or set the target architecure to disassemble");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
|
@ -219,17 +228,17 @@ CommandObjectDisassemble::Execute
|
|||
}
|
||||
|
||||
const char *plugin_name = m_options.GetPluginName ();
|
||||
Disassembler *disassembler = Disassembler::FindPlugin(m_options.m_arch, plugin_name);
|
||||
Disassembler *disassembler = Disassembler::FindPlugin(m_options.arch, plugin_name);
|
||||
|
||||
if (disassembler == NULL)
|
||||
{
|
||||
if (plugin_name)
|
||||
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
|
||||
plugin_name,
|
||||
m_options.m_arch.GetArchitectureName());
|
||||
m_options.arch.GetArchitectureName());
|
||||
else
|
||||
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
|
||||
m_options.m_arch.GetArchitectureName());
|
||||
m_options.arch.GetArchitectureName());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
|
@ -252,12 +261,12 @@ CommandObjectDisassemble::Execute
|
|||
|
||||
ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
|
||||
|
||||
if (!m_options.m_func_name.empty())
|
||||
if (!m_options.func_name.empty())
|
||||
{
|
||||
ConstString name(m_options.m_func_name.c_str());
|
||||
ConstString name(m_options.func_name.c_str());
|
||||
|
||||
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
|
||||
m_options.m_arch,
|
||||
m_options.arch,
|
||||
plugin_name,
|
||||
exe_ctx,
|
||||
name,
|
||||
|
@ -278,59 +287,76 @@ CommandObjectDisassemble::Execute
|
|||
}
|
||||
else
|
||||
{
|
||||
Address start_addr;
|
||||
lldb::addr_t range_byte_size = DEFAULT_DISASM_BYTE_SIZE;
|
||||
|
||||
if (m_options.m_at_pc)
|
||||
AddressRange range;
|
||||
if (m_options.frame_line)
|
||||
{
|
||||
if (exe_ctx.frame == NULL)
|
||||
LineEntry pc_line_entry (exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
|
||||
if (pc_line_entry.IsValid())
|
||||
{
|
||||
result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
range = pc_line_entry.range;
|
||||
}
|
||||
start_addr = exe_ctx.frame->GetFrameCodeAddress();
|
||||
if (m_options.num_instructions == 0)
|
||||
else
|
||||
{
|
||||
// Disassembling at the PC always disassembles some number of instructions (not the whole function).
|
||||
m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
|
||||
m_options.at_pc = true; // No line entry, so just disassemble around the current pc
|
||||
m_options.show_mixed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Did the "m_options.frame_line" find a valid range already? If so
|
||||
// skip the rest...
|
||||
if (range.GetByteSize() == 0)
|
||||
{
|
||||
start_addr.SetOffset (m_options.m_start_addr);
|
||||
if (start_addr.IsValid())
|
||||
if (m_options.at_pc)
|
||||
{
|
||||
if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
|
||||
if (exe_ctx.frame == NULL)
|
||||
{
|
||||
if (m_options.m_end_addr < m_options.m_start_addr)
|
||||
result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
|
||||
if (m_options.num_instructions == 0)
|
||||
{
|
||||
// Disassembling at the PC always disassembles some number of instructions (not the whole function).
|
||||
m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
range.GetBaseAddress().SetOffset (m_options.start_addr);
|
||||
if (range.GetBaseAddress().IsValid())
|
||||
{
|
||||
if (m_options.end_addr != LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
result.AppendErrorWithFormat ("End address before start address.\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
if (m_options.end_addr <= m_options.start_addr)
|
||||
{
|
||||
result.AppendErrorWithFormat ("End address before start address.\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
range.SetByteSize (m_options.end_addr - m_options.start_addr);
|
||||
}
|
||||
range_byte_size = m_options.m_end_addr - m_options.m_start_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_options.num_instructions != 0)
|
||||
{
|
||||
if (!start_addr.IsValid())
|
||||
if (!range.GetBaseAddress().IsValid())
|
||||
{
|
||||
// The default action is to disassemble the current frame function.
|
||||
if (exe_ctx.frame)
|
||||
{
|
||||
SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
|
||||
if (sc.function)
|
||||
start_addr = sc.function->GetAddressRange().GetBaseAddress();
|
||||
range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
|
||||
else if (sc.symbol && sc.symbol->GetAddressRangePtr())
|
||||
start_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
|
||||
range.GetBaseAddress() = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
|
||||
else
|
||||
start_addr = exe_ctx.frame->GetFrameCodeAddress();
|
||||
range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
|
||||
}
|
||||
|
||||
if (!start_addr.IsValid())
|
||||
if (!range.GetBaseAddress().IsValid())
|
||||
{
|
||||
result.AppendError ("invalid frame");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
|
@ -339,10 +365,10 @@ CommandObjectDisassemble::Execute
|
|||
}
|
||||
|
||||
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
|
||||
m_options.m_arch,
|
||||
m_options.arch,
|
||||
plugin_name,
|
||||
exe_ctx,
|
||||
start_addr,
|
||||
range.GetBaseAddress(),
|
||||
m_options.num_instructions,
|
||||
m_options.show_mixed ? m_options.num_lines_context : 0,
|
||||
m_options.show_bytes,
|
||||
|
@ -353,19 +379,13 @@ CommandObjectDisassemble::Execute
|
|||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
|
||||
result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddressRange range;
|
||||
if (start_addr.IsValid())
|
||||
{
|
||||
range.GetBaseAddress() = start_addr;
|
||||
range.SetByteSize (range_byte_size);
|
||||
}
|
||||
else
|
||||
if (!range.GetBaseAddress().IsValid())
|
||||
{
|
||||
// The default action is to disassemble the current frame function.
|
||||
if (exe_ctx.frame)
|
||||
|
@ -389,7 +409,7 @@ CommandObjectDisassemble::Execute
|
|||
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
|
||||
|
||||
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
|
||||
m_options.m_arch,
|
||||
m_options.arch,
|
||||
plugin_name,
|
||||
exe_ctx,
|
||||
range,
|
||||
|
@ -403,7 +423,7 @@ CommandObjectDisassemble::Execute
|
|||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
|
||||
result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ public:
|
|||
const char *
|
||||
GetPluginName ()
|
||||
{
|
||||
if (m_plugin_name.empty())
|
||||
if (plugin_name.empty())
|
||||
return NULL;
|
||||
return m_plugin_name.c_str();
|
||||
return plugin_name.c_str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,12 +58,13 @@ public:
|
|||
uint32_t num_lines_context;
|
||||
uint32_t num_instructions;
|
||||
bool raw;
|
||||
std::string m_func_name;
|
||||
lldb::addr_t m_start_addr;
|
||||
lldb::addr_t m_end_addr;
|
||||
bool m_at_pc;
|
||||
std::string m_plugin_name;
|
||||
ArchSpec m_arch;
|
||||
std::string func_name;
|
||||
lldb::addr_t start_addr;
|
||||
lldb::addr_t end_addr;
|
||||
bool at_pc;
|
||||
bool frame_line;
|
||||
std::string plugin_name;
|
||||
ArchSpec arch;
|
||||
static OptionDefinition g_option_table[];
|
||||
};
|
||||
|
||||
|
|
|
@ -95,7 +95,6 @@ CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const c
|
|||
void
|
||||
CommandObjectExpression::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
//language.Clear();
|
||||
debug = false;
|
||||
format = eFormatDefault;
|
||||
|
@ -298,7 +297,7 @@ CommandObjectExpression::ExecuteRawCommandString
|
|||
{
|
||||
m_exe_ctx = m_interpreter.GetDebugger().GetExecutionContext();
|
||||
|
||||
m_options.ResetOptionValues();
|
||||
m_options.Reset();
|
||||
|
||||
const char * expr = NULL;
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@ CommandObjectFile::CommandOptions::SetOptionValue (int option_idx, const char *o
|
|||
void
|
||||
CommandObjectFile::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_arch.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -135,7 +135,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
relative_frame_offset = INT32_MIN;
|
||||
}
|
||||
|
||||
|
@ -352,8 +351,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
use_objc = false;
|
||||
use_regex = false;
|
||||
show_args = true;
|
||||
|
|
|
@ -763,7 +763,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_sort_order = eSortOrderNone;
|
||||
}
|
||||
|
||||
|
@ -1167,7 +1166,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_format_array.clear();
|
||||
}
|
||||
|
||||
|
@ -1429,7 +1427,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_type = eLookupTypeInvalid;
|
||||
m_str.clear();
|
||||
m_file.Clear();
|
||||
|
|
|
@ -208,7 +208,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
log_file.clear();
|
||||
log_options = 0;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_format = eFormatBytesWithASCII;
|
||||
m_byte_size = 0;
|
||||
m_count = 0;
|
||||
|
@ -493,7 +492,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_format = eFormatBytes;
|
||||
m_byte_size = 1;
|
||||
m_infile.Clear();
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("command not implemented\n");
|
||||
result.AppendError ("platform create takes a platform name as an argument\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
return result.Succeeded();
|
||||
|
@ -409,6 +409,308 @@ public:
|
|||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// "platform process list"
|
||||
//----------------------------------------------------------------------
|
||||
class CommandObjectPlatformProcessList : public CommandObject
|
||||
{
|
||||
public:
|
||||
CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
|
||||
CommandObject (interpreter,
|
||||
"platform process list",
|
||||
"List processes on a remote platform by name, pid, or many other matching attributes.",
|
||||
"platform process list",
|
||||
0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~CommandObjectPlatformProcessList ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Execute (Args& args, CommandReturnObject &result)
|
||||
{
|
||||
PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
|
||||
|
||||
if (platform_sp)
|
||||
{
|
||||
Error error;
|
||||
if (args.GetArgumentCount() == 0)
|
||||
{
|
||||
|
||||
if (platform_sp)
|
||||
{
|
||||
lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
|
||||
if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
ProcessInfo proc_info;
|
||||
if (platform_sp->GetProcessInfo (pid, proc_info))
|
||||
{
|
||||
proc_info.Dump (result.GetOutputStream(), platform_sp.get());
|
||||
result.SetStatus (eReturnStatusSuccessFinishResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("no process found with pid = %i\n", pid);
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessInfoList proc_infos;
|
||||
const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
|
||||
if (matches == 0)
|
||||
{
|
||||
const char *match_desc = NULL;
|
||||
const char *match_name = m_options.match_info.GetProcessInfo().GetName();
|
||||
if (match_name && match_name[0])
|
||||
{
|
||||
switch (m_options.match_info.GetNameMatchType())
|
||||
{
|
||||
case eNameMatchIgnore: break;
|
||||
case eNameMatchEquals: match_desc = "match"; break;
|
||||
case eNameMatchContains: match_desc = "contains"; break;
|
||||
case eNameMatchStartsWith: match_desc = "starts with"; break;
|
||||
case eNameMatchEndsWith: match_desc = "end with"; break;
|
||||
case eNameMatchRegularExpression: match_desc = "match the regular expression"; break;
|
||||
}
|
||||
}
|
||||
if (match_desc)
|
||||
result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
|
||||
match_desc,
|
||||
match_name,
|
||||
platform_sp->GetShortPluginName());
|
||||
else
|
||||
result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream &ostrm = result.GetOutputStream();
|
||||
|
||||
ProcessInfo::DumpTableHeader (ostrm, platform_sp.get());
|
||||
for (uint32_t i=0; i<matches; ++i)
|
||||
{
|
||||
proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("invalid args: process list takes only options\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("no platform is selected\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
virtual Options *
|
||||
GetOptions ()
|
||||
{
|
||||
return &m_options;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
class CommandOptions : public Options
|
||||
{
|
||||
public:
|
||||
|
||||
CommandOptions () :
|
||||
match_info ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~CommandOptions ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Error
|
||||
SetOptionValue (int option_idx, const char *option_arg)
|
||||
{
|
||||
Error error;
|
||||
char short_option = (char) m_getopt_table[option_idx].val;
|
||||
bool success = false;
|
||||
|
||||
switch (short_option)
|
||||
{
|
||||
case 'p':
|
||||
match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
|
||||
if (!success)
|
||||
error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
match_info.GetProcessInfo().SetName (option_arg);
|
||||
if (match_info.GetNameMatchType() == eNameMatchIgnore)
|
||||
match_info.SetNameMatchType (eNameMatchEquals);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
match_info.SetNameMatchType (eNameMatchEndsWith);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
match_info.SetNameMatchType (eNameMatchStartsWith);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
match_info.SetNameMatchType (eNameMatchContains);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
match_info.SetNameMatchType (eNameMatchRegularExpression);
|
||||
break;
|
||||
|
||||
default:
|
||||
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
match_info.Clear();
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
GetDefinitions ()
|
||||
{
|
||||
return g_option_table;
|
||||
}
|
||||
|
||||
// Options table: Required for subclasses of Options.
|
||||
|
||||
static OptionDefinition g_option_table[];
|
||||
|
||||
// Instance variables to hold the values for command options.
|
||||
|
||||
ProcessInfoMatch match_info;
|
||||
};
|
||||
CommandOptions m_options;
|
||||
};
|
||||
|
||||
OptionDefinition
|
||||
CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
|
||||
{
|
||||
{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes that match the supplied name." },
|
||||
{ LLDB_OPT_SET_2, false, "ends-with" , 'e', no_argument , NULL, 0, eArgTypeNone , "Process names must end with the name supplied with the --name option." },
|
||||
{ LLDB_OPT_SET_3, false, "starts-with" , 's', no_argument , NULL, 0, eArgTypeNone , "Process names must start with the name supplied with the --name option." },
|
||||
{ LLDB_OPT_SET_4, false, "contains" , 'c', no_argument , NULL, 0, eArgTypeNone , "Process names must contain the name supplied with the --name option." },
|
||||
{ LLDB_OPT_SET_5, false, "regex" , 'r', no_argument , NULL, 0, eArgTypeNone , "Process names must match name supplied with the --name option as a regular expression." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
|
||||
{ LLDB_OPT_SET_2|
|
||||
LLDB_OPT_SET_3|
|
||||
LLDB_OPT_SET_4|
|
||||
LLDB_OPT_SET_5|
|
||||
LLDB_OPT_SET_6, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
|
||||
{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
|
||||
};
|
||||
|
||||
class CommandObjectPlatformProcess : public CommandObjectMultiword
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
|
||||
CommandObjectMultiword (interpreter,
|
||||
"platform process",
|
||||
"A set of commands to query, launch and attach to platform processes",
|
||||
"platform process [attach|launch|list] ...")
|
||||
{
|
||||
// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
|
||||
// LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
|
||||
LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
|
||||
|
||||
}
|
||||
|
||||
virtual
|
||||
~CommandObjectPlatformProcess ()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For CommandObjectPlatform only
|
||||
//------------------------------------------------------------------
|
||||
DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// CommandObjectPlatform constructor
|
||||
|
@ -425,6 +727,7 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
|
|||
LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
|
||||
LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
|
||||
LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
|
||||
LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -82,7 +82,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
stop_at_entry = false;
|
||||
in_new_tty = false;
|
||||
tty_name.clear();
|
||||
|
@ -483,7 +482,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
pid = LLDB_INVALID_PROCESS_ID;
|
||||
name.clear();
|
||||
waitfor = false;
|
||||
|
@ -527,7 +525,13 @@ public:
|
|||
if (platform_sp)
|
||||
{
|
||||
ProcessInfoList process_infos;
|
||||
platform_sp->FindProcessesByName (partial_name, partial_name ? eNameMatchStartsWith : eNameMatchIgnore, process_infos);
|
||||
ProcessInfoMatch match_info;
|
||||
if (partial_name)
|
||||
{
|
||||
match_info.GetProcessInfo().SetName(partial_name);
|
||||
match_info.SetNameMatchType(eNameMatchStartsWith);
|
||||
}
|
||||
platform_sp->FindProcesses (match_info, process_infos);
|
||||
const uint32_t num_matches = process_infos.GetSize();
|
||||
if (num_matches > 0)
|
||||
{
|
||||
|
@ -706,7 +710,8 @@ public:
|
|||
PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ());
|
||||
if (platform_sp)
|
||||
{
|
||||
platform_sp->FindProcessesByName (wait_name, eNameMatchEquals, process_infos);
|
||||
ProcessInfoMatch match_info (wait_name, eNameMatchEquals);
|
||||
platform_sp->FindProcesses (match_info, process_infos);
|
||||
}
|
||||
if (process_infos.GetSize() > 1)
|
||||
{
|
||||
|
@ -1011,7 +1016,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
plugin_name.clear();
|
||||
}
|
||||
|
||||
|
@ -1601,7 +1605,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
stop.clear();
|
||||
notify.clear();
|
||||
pass.clear();
|
||||
|
|
|
@ -58,6 +58,12 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
Options *
|
||||
GetOptions ()
|
||||
{
|
||||
return &m_options;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Execute
|
||||
(
|
||||
|
@ -143,8 +149,77 @@ public:
|
|||
}
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
protected:
|
||||
class CommandOptions : public Options
|
||||
{
|
||||
public:
|
||||
CommandOptions () :
|
||||
Options()
|
||||
{
|
||||
ResetOptionValues();
|
||||
}
|
||||
|
||||
virtual
|
||||
~CommandOptions ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Error
|
||||
SetOptionValue (int option_idx, const char *option_arg)
|
||||
{
|
||||
Error error;
|
||||
char short_option = (char) m_getopt_table[option_idx].val;
|
||||
switch (short_option)
|
||||
{
|
||||
case 'f':
|
||||
error = Args::StringToFormat (option_arg, m_format);
|
||||
break;
|
||||
|
||||
default:
|
||||
error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
m_format = eFormatBytes;
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
GetDefinitions ()
|
||||
{
|
||||
return g_option_table;
|
||||
}
|
||||
|
||||
// Options table: Required for subclasses of Options.
|
||||
|
||||
static OptionDefinition g_option_table[];
|
||||
|
||||
// Instance variables to hold the values for command options.
|
||||
lldb::Format m_format;
|
||||
};
|
||||
|
||||
CommandOptions m_options;
|
||||
};
|
||||
|
||||
OptionDefinition
|
||||
CommandObjectRegisterRead::CommandOptions::g_option_table[] =
|
||||
{
|
||||
//{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
|
||||
//{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
|
||||
{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the expression output should use."},
|
||||
{ LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
|
||||
{ LLDB_OPT_SET_ALL, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
|
||||
{ LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
|
||||
{ LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, eArgTypeNone, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."},
|
||||
{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// "register write"
|
||||
|
|
|
@ -287,8 +287,6 @@ CommandObjectSettingsSet::CommandOptions::SetOptionValue (int option_idx, const
|
|||
void
|
||||
CommandObjectSettingsSet::CommandOptions::ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues ();
|
||||
|
||||
m_override = true;
|
||||
m_reset = false;
|
||||
}
|
||||
|
|
|
@ -74,8 +74,6 @@ class CommandObjectSourceInfo : public CommandObject
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
file_spec.Clear();
|
||||
file_name.clear();
|
||||
start_line = 0;
|
||||
|
@ -200,8 +198,6 @@ class CommandObjectSourceList : public CommandObject
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
|
||||
file_spec.Clear();
|
||||
file_name.clear();
|
||||
symbol_name.clear();
|
||||
|
|
|
@ -300,7 +300,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_count = -1;
|
||||
m_start = 0;
|
||||
}
|
||||
|
@ -545,7 +544,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_avoid_no_debug = true;
|
||||
m_run_mode = eOnlyDuringStepping;
|
||||
m_avoid_regexp.clear();
|
||||
|
@ -1044,7 +1042,6 @@ public:
|
|||
void
|
||||
ResetOptionValues ()
|
||||
{
|
||||
Options::ResetOptionValues();
|
||||
m_thread_idx = LLDB_INVALID_THREAD_ID;
|
||||
m_frame_idx = 0;
|
||||
m_stop_others = false;
|
||||
|
|
|
@ -261,7 +261,6 @@ Disassembler::Disassemble
|
|||
debugger,
|
||||
arch,
|
||||
exe_ctx,
|
||||
disasm_range.GetBaseAddress(),
|
||||
num_instructions,
|
||||
num_mixed_context_lines,
|
||||
show_bytes,
|
||||
|
@ -302,7 +301,6 @@ Disassembler::Disassemble
|
|||
debugger,
|
||||
arch,
|
||||
exe_ctx,
|
||||
addr,
|
||||
num_instructions,
|
||||
num_mixed_context_lines,
|
||||
show_bytes,
|
||||
|
@ -320,7 +318,6 @@ Disassembler::PrintInstructions
|
|||
Debugger &debugger,
|
||||
const ArchSpec &arch,
|
||||
const ExecutionContext &exe_ctx,
|
||||
const Address &start_addr,
|
||||
uint32_t num_instructions,
|
||||
uint32_t num_mixed_context_lines,
|
||||
bool show_bytes,
|
||||
|
@ -339,41 +336,53 @@ Disassembler::PrintInstructions
|
|||
SymbolContext sc;
|
||||
SymbolContext prev_sc;
|
||||
AddressRange sc_range;
|
||||
Address addr (start_addr);
|
||||
|
||||
if (num_mixed_context_lines)
|
||||
strm.IndentMore ();
|
||||
|
||||
// We extract the section to make sure we don't transition out
|
||||
// of the current section when disassembling
|
||||
const Section *addr_section = addr.GetSection();
|
||||
Module *range_module = addr.GetModule();
|
||||
Address *pc_addr_ptr = NULL;
|
||||
if (exe_ctx.frame)
|
||||
pc_addr_ptr = &exe_ctx.frame->GetFrameCodeAddress();
|
||||
|
||||
for (size_t i=0; i<num_instructions_found; ++i)
|
||||
{
|
||||
Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
|
||||
if (inst)
|
||||
{
|
||||
addr_t file_addr = addr.GetFileAddress();
|
||||
if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
|
||||
{
|
||||
if (range_module)
|
||||
range_module->ResolveFileAddress (file_addr, addr);
|
||||
else if (exe_ctx.target)
|
||||
exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
|
||||
|
||||
addr_section = addr.GetSection();
|
||||
}
|
||||
const Address &addr = inst->GetAddress();
|
||||
const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
|
||||
|
||||
prev_sc = sc;
|
||||
|
||||
if (addr_section)
|
||||
Module *module = addr.GetModule();
|
||||
if (module)
|
||||
{
|
||||
Module *module = addr_section->GetModule();
|
||||
uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
|
||||
if (resolved_mask)
|
||||
{
|
||||
if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
|
||||
if (num_mixed_context_lines)
|
||||
{
|
||||
if (!sc_range.ContainsFileAddress (addr))
|
||||
{
|
||||
sc.GetAddressRange (eSymbolContextEverything, sc_range);
|
||||
|
||||
if (sc != prev_sc)
|
||||
{
|
||||
if (offset != 0)
|
||||
strm.EOL();
|
||||
|
||||
sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
|
||||
strm.EOL();
|
||||
|
||||
if (sc.comp_unit && sc.line_entry.IsValid())
|
||||
{
|
||||
debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
|
||||
sc.line_entry.line,
|
||||
num_mixed_context_lines,
|
||||
num_mixed_context_lines,
|
||||
num_mixed_context_lines ? "->" : "",
|
||||
&strm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(prev_sc.function == sc.function || prev_sc.symbol == sc.symbol))
|
||||
{
|
||||
if (prev_sc.function || prev_sc.symbol)
|
||||
strm.EOL();
|
||||
|
@ -386,54 +395,28 @@ Disassembler::PrintInstructions
|
|||
strm << '`' << sc.symbol->GetMangled().GetName();
|
||||
strm << ":\n";
|
||||
}
|
||||
|
||||
if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
|
||||
{
|
||||
sc.GetAddressRange (eSymbolContextEverything, sc_range);
|
||||
|
||||
if (sc != prev_sc)
|
||||
{
|
||||
if (offset != 0)
|
||||
strm.EOL();
|
||||
|
||||
sc.DumpStopContext(&strm, exe_ctx.process, addr, false, true, false);
|
||||
strm.EOL();
|
||||
|
||||
if (sc.comp_unit && sc.line_entry.IsValid())
|
||||
{
|
||||
debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
|
||||
sc.line_entry.line,
|
||||
num_mixed_context_lines,
|
||||
num_mixed_context_lines,
|
||||
num_mixed_context_lines ? "->" : "",
|
||||
&strm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.Clear();
|
||||
}
|
||||
}
|
||||
if (num_mixed_context_lines)
|
||||
strm.IndentMore ();
|
||||
strm.Indent();
|
||||
inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
|
||||
strm.EOL();
|
||||
|
||||
addr.Slide(inst->GetOpcode().GetByteSize());
|
||||
|
||||
if (num_mixed_context_lines)
|
||||
strm.IndentLess ();
|
||||
if (pc_addr_ptr)
|
||||
{
|
||||
if (inst_is_at_pc)
|
||||
strm.PutCString("-> ");
|
||||
else
|
||||
strm.PutCString(" ");
|
||||
}
|
||||
inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, raw);
|
||||
strm.EOL();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num_mixed_context_lines)
|
||||
strm.IndentLess ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstStrin
|
|||
m_arch (arch),
|
||||
m_uuid (),
|
||||
m_file (file_spec),
|
||||
m_platform_file(),
|
||||
m_object_name (),
|
||||
m_objfile_ap (),
|
||||
m_symfile_ap (),
|
||||
|
@ -448,12 +449,6 @@ Module::GetSymbolVendor (bool can_create)
|
|||
return m_symfile_ap.get();
|
||||
}
|
||||
|
||||
const FileSpec &
|
||||
Module::GetFileSpec () const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
void
|
||||
Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
|
||||
{
|
||||
|
|
|
@ -216,14 +216,20 @@ public:
|
|||
ModuleMatches (const FileSpec *file_spec_ptr,
|
||||
const ArchSpec *arch_ptr,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
const ConstString *object_name) :
|
||||
const ConstString *object_name,
|
||||
bool file_spec_is_platform) :
|
||||
m_file_spec_ptr (file_spec_ptr),
|
||||
m_arch_ptr (arch_ptr),
|
||||
m_uuid_ptr (uuid_ptr),
|
||||
m_object_name (object_name)
|
||||
m_object_name (object_name),
|
||||
m_file_spec_compare_basename_only (false),
|
||||
m_file_spec_is_platform (file_spec_is_platform)
|
||||
{
|
||||
if (file_spec_ptr)
|
||||
m_file_spec_compare_basename_only = file_spec_ptr->GetDirectory();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// Unary predicate function object callback.
|
||||
//--------------------------------------------------------------
|
||||
|
@ -232,8 +238,21 @@ public:
|
|||
{
|
||||
if (m_file_spec_ptr)
|
||||
{
|
||||
if (!FileSpec::Equal (*m_file_spec_ptr, module_sp->GetFileSpec(), m_file_spec_ptr->GetDirectory()))
|
||||
return false;
|
||||
if (m_file_spec_is_platform)
|
||||
{
|
||||
if (!FileSpec::Equal (*m_file_spec_ptr,
|
||||
module_sp->GetPlatformFileSpec(),
|
||||
m_file_spec_compare_basename_only))
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!FileSpec::Equal (*m_file_spec_ptr,
|
||||
module_sp->GetFileSpec(),
|
||||
m_file_spec_compare_basename_only))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_arch_ptr && m_arch_ptr->IsValid())
|
||||
|
@ -264,6 +283,8 @@ private:
|
|||
const ArchSpec * m_arch_ptr;
|
||||
const lldb_private::UUID * m_uuid_ptr;
|
||||
const ConstString * m_object_name;
|
||||
bool m_file_spec_compare_basename_only;
|
||||
bool m_file_spec_is_platform;
|
||||
};
|
||||
|
||||
size_t
|
||||
|
@ -277,7 +298,7 @@ ModuleList::FindModules
|
|||
) const
|
||||
{
|
||||
size_t existing_matches = matching_module_list.GetSize();
|
||||
ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name);
|
||||
ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name, false);
|
||||
|
||||
Mutex::Locker locker(m_modules_mutex);
|
||||
collection::const_iterator end = m_modules.end();
|
||||
|
@ -316,6 +337,28 @@ ModuleList::FindModule (const Module *module_ptr)
|
|||
|
||||
}
|
||||
|
||||
ModuleSP
|
||||
ModuleList::FindModule (const UUID &uuid)
|
||||
{
|
||||
ModuleSP module_sp;
|
||||
|
||||
if (uuid.IsValid())
|
||||
{
|
||||
Mutex::Locker locker(m_modules_mutex);
|
||||
collection::const_iterator pos, end = m_modules.end();
|
||||
|
||||
for (pos = m_modules.begin(); pos != end; ++pos)
|
||||
{
|
||||
if ((*pos)->GetUUID() == uuid)
|
||||
{
|
||||
module_sp = (*pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return module_sp;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
|
||||
|
@ -340,10 +383,16 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool ap
|
|||
|
||||
|
||||
ModuleSP
|
||||
ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec, const ConstString *object_name)
|
||||
ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec,
|
||||
const ArchSpec *arch_ptr,
|
||||
const ConstString *object_name)
|
||||
{
|
||||
ModuleSP module_sp;
|
||||
ModuleMatches matcher (&file_spec, NULL, NULL, NULL);
|
||||
ModuleMatches matcher (&file_spec,
|
||||
arch_ptr,
|
||||
NULL,
|
||||
object_name,
|
||||
false);
|
||||
|
||||
// Scope for "locker"
|
||||
{
|
||||
|
@ -359,6 +408,32 @@ ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec, const ConstSt
|
|||
|
||||
}
|
||||
|
||||
ModuleSP
|
||||
ModuleList::FindFirstModuleForPlatormFileSpec (const FileSpec &file_spec,
|
||||
const ArchSpec *arch_ptr,
|
||||
const ConstString *object_name)
|
||||
{
|
||||
ModuleSP module_sp;
|
||||
ModuleMatches matcher (&file_spec,
|
||||
arch_ptr,
|
||||
NULL,
|
||||
object_name,
|
||||
true);
|
||||
|
||||
// Scope for "locker"
|
||||
{
|
||||
Mutex::Locker locker(m_modules_mutex);
|
||||
collection::const_iterator end = m_modules.end();
|
||||
collection::const_iterator pos = m_modules.begin();
|
||||
|
||||
pos = std::find_if (pos, end, matcher);
|
||||
if (pos != end)
|
||||
module_sp = (*pos);
|
||||
}
|
||||
return module_sp;
|
||||
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
ModuleList::GetSize() const
|
||||
|
|
|
@ -119,7 +119,7 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile
|
|||
break;
|
||||
}
|
||||
|
||||
s->Printf("%4u %2.2s\t", curr_line, curr_line == line ? current_line_cstr : "");
|
||||
s->Printf("%2.2s %-4u\t", curr_line == line ? current_line_cstr : "", curr_line);
|
||||
if (m_last_file_sp->DisplaySourceLines (curr_line, 0, 0, s) == 0)
|
||||
{
|
||||
m_last_file_line = UINT32_MAX;
|
||||
|
|
|
@ -24,7 +24,11 @@
|
|||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#if defined (__APPLE__)
|
||||
|
||||
|
@ -33,6 +37,7 @@
|
|||
#include <mach-o/dyld.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
|
||||
#elif defined (__linux__)
|
||||
|
||||
#include <sys/wait.h>
|
||||
|
@ -1055,6 +1060,66 @@ Host::GetHostname (std::string &s)
|
|||
return false;
|
||||
}
|
||||
|
||||
const char *
|
||||
Host::GetUserName (uint32_t uid, std::string &user_name)
|
||||
{
|
||||
struct passwd user_info;
|
||||
struct passwd *user_info_ptr = &user_info;
|
||||
char user_buffer[PATH_MAX];
|
||||
size_t user_buffer_size = sizeof(user_buffer);
|
||||
if (::getpwuid_r (uid,
|
||||
&user_info,
|
||||
user_buffer,
|
||||
user_buffer_size,
|
||||
&user_info_ptr) == 0)
|
||||
{
|
||||
if (user_info_ptr)
|
||||
{
|
||||
user_name.assign (user_info_ptr->pw_name);
|
||||
return user_name.c_str();
|
||||
}
|
||||
}
|
||||
user_name.clear();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
Host::GetGroupName (uint32_t gid, std::string &group_name)
|
||||
{
|
||||
char group_buffer[PATH_MAX];
|
||||
size_t group_buffer_size = sizeof(group_buffer);
|
||||
struct group group_info;
|
||||
struct group *group_info_ptr = &group_info;
|
||||
// Try the threadsafe version first
|
||||
if (::getgrgid_r (gid,
|
||||
&group_info,
|
||||
group_buffer,
|
||||
group_buffer_size,
|
||||
&group_info_ptr) == 0)
|
||||
{
|
||||
if (group_info_ptr)
|
||||
{
|
||||
group_name.assign (group_info_ptr->gr_name);
|
||||
return group_name.c_str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The threadsafe version isn't currently working
|
||||
// for me on darwin, but the non-threadsafe version
|
||||
// is, so I am calling it below.
|
||||
group_info_ptr = ::getgrgid (gid);
|
||||
if (group_info_ptr)
|
||||
{
|
||||
group_name.assign (group_info_ptr->gr_name);
|
||||
return group_name.c_str();
|
||||
}
|
||||
}
|
||||
group_name.clear();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#if !defined (__APPLE__) // see macosx/Host.mm
|
||||
|
||||
bool
|
||||
|
@ -1072,7 +1137,7 @@ Host::GetOSKernelDescription (std::string &s)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
Host::FindProcessesByName (const char *name, NameMatchType name_match_type, ProcessInfoList &process_infos)
|
||||
Host::FindProcesses (const ProcessInfoMatch &match_info, ProcessInfoList &process_infos)
|
||||
{
|
||||
process_infos.Clear();
|
||||
return process_infos.GetSize();
|
||||
|
|
|
@ -912,8 +912,7 @@ Host::GetOSVersion
|
|||
}
|
||||
|
||||
static bool
|
||||
GetMacOSXProcessName (NameMatchType name_match_type,
|
||||
const char *name_match,
|
||||
GetMacOSXProcessName (const ProcessInfoMatch *match_info_ptr,
|
||||
ProcessInfo &process_info)
|
||||
{
|
||||
if (process_info.ProcessIDIsValid())
|
||||
|
@ -923,7 +922,9 @@ GetMacOSXProcessName (NameMatchType name_match_type,
|
|||
if (name_len == 0)
|
||||
return false;
|
||||
|
||||
if (NameMatches(process_name, name_match_type, name_match))
|
||||
if (match_info_ptr == NULL || NameMatches(process_name,
|
||||
match_info_ptr->GetNameMatchType(),
|
||||
match_info_ptr->GetProcessInfo().GetName()))
|
||||
{
|
||||
process_info.SetName (process_name);
|
||||
return true;
|
||||
|
@ -966,56 +967,6 @@ GetMacOSXProcessCPUType (ProcessInfo &process_info)
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: move this into the platform
|
||||
static bool
|
||||
GetGroupName (uint32_t gid, std::string &group_name)
|
||||
{
|
||||
char group_buffer[PATH_MAX];
|
||||
size_t group_buffer_size = sizeof(group_buffer);
|
||||
struct group group_info;
|
||||
struct group *group_info_ptr = &group_info;
|
||||
// User the real user ID here, not the effective user ID
|
||||
if (::getgrgid_r (gid,
|
||||
&group_info,
|
||||
group_buffer,
|
||||
group_buffer_size,
|
||||
&group_info_ptr) == 0)
|
||||
{
|
||||
if (group_info_ptr)
|
||||
{
|
||||
group_name.assign (group_info_ptr->gr_name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
group_name.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: move this into the platform
|
||||
static bool
|
||||
GetUserName (uint32_t uid, std::string &user_name)
|
||||
{
|
||||
struct passwd user_info;
|
||||
struct passwd *user_info_ptr = &user_info;
|
||||
char user_buffer[PATH_MAX];
|
||||
size_t user_buffer_size = sizeof(user_buffer);
|
||||
if (::getpwuid_r (uid,
|
||||
&user_info,
|
||||
user_buffer,
|
||||
user_buffer_size,
|
||||
&user_info_ptr) == 0)
|
||||
{
|
||||
if (user_info_ptr)
|
||||
{
|
||||
user_name.assign (user_info_ptr->pw_name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
user_name.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
GetMacOSXProcessUserAndGroup (ProcessInfo &process_info)
|
||||
{
|
||||
|
@ -1055,7 +1006,7 @@ GetMacOSXProcessUserAndGroup (ProcessInfo &process_info)
|
|||
|
||||
|
||||
uint32_t
|
||||
Host::FindProcessesByName (const char *name, NameMatchType name_match_type, ProcessInfoList &process_infos)
|
||||
Host::FindProcesses (const ProcessInfoMatch &match_info, ProcessInfoList &process_infos)
|
||||
{
|
||||
int num_pids;
|
||||
int size_of_pids;
|
||||
|
@ -1091,11 +1042,12 @@ Host::FindProcessesByName (const char *name, NameMatchType name_match_type, Proc
|
|||
|
||||
ProcessInfo process_info;
|
||||
process_info.SetProcessID (bsd_info.pbi_pid);
|
||||
if (GetMacOSXProcessName (name_match_type, name, process_info))
|
||||
if (GetMacOSXProcessName (&match_info, process_info))
|
||||
{
|
||||
GetMacOSXProcessCPUType (process_info);
|
||||
GetMacOSXProcessUserAndGroup (process_info);
|
||||
process_infos.Append (process_info);
|
||||
if (match_info.Matches (process_info))
|
||||
process_infos.Append (process_info);
|
||||
}
|
||||
}
|
||||
return process_infos.GetSize();
|
||||
|
@ -1105,7 +1057,7 @@ bool
|
|||
Host::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
process_info.SetProcessID(pid);
|
||||
if (GetMacOSXProcessName (eNameMatchIgnore, NULL, process_info))
|
||||
if (GetMacOSXProcessName (NULL, process_info))
|
||||
{
|
||||
GetMacOSXProcessCPUType (process_info);
|
||||
GetMacOSXProcessUserAndGroup (process_info);
|
||||
|
|
|
@ -177,7 +177,7 @@ CommandObject::ParseOptions
|
|||
if (options != NULL)
|
||||
{
|
||||
Error error;
|
||||
options->ResetOptionValues();
|
||||
options->Reset();
|
||||
|
||||
// ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
|
||||
// so we need to push a dummy value into position zero.
|
||||
|
|
|
@ -39,11 +39,12 @@ Options::~Options ()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Options::ResetOptionValues ()
|
||||
Options::Reset ()
|
||||
{
|
||||
m_seen_options.clear();
|
||||
// Let the subclass reset its option values
|
||||
ResetOptionValues ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace llvm::MachO;
|
||||
|
||||
/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
|
||||
/// I am putting it here so I can invoke it in the Trampoline code here, but
|
||||
|
@ -42,16 +41,37 @@ using namespace llvm::MachO;
|
|||
|
||||
|
||||
DynamicLoaderMacOSXDYLD::DYLDImageInfo *
|
||||
DynamicLoaderMacOSXDYLD::GetImageInfo (const FileSpec &file_spec, const lldb_private::UUID &uuid)
|
||||
DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
|
||||
{
|
||||
const UUID &module_uuid = module->GetUUID();
|
||||
DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
|
||||
|
||||
// First try just by UUID as it is the safest.
|
||||
if (module_uuid.IsValid())
|
||||
{
|
||||
for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
|
||||
{
|
||||
if (pos->uuid == module_uuid)
|
||||
return &(*pos);
|
||||
}
|
||||
|
||||
if (m_dyld.uuid == module_uuid)
|
||||
return &m_dyld;
|
||||
}
|
||||
|
||||
// Next try by platform path only for things that don't have a valid UUID
|
||||
// since if a file has a valid UUID in real life it should also in the
|
||||
// dyld info. This is the next safest because the paths in the dyld info
|
||||
// are platform paths, not local paths. For local debugging platform == local
|
||||
// paths.
|
||||
const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
|
||||
for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
|
||||
{
|
||||
if (pos->uuid == uuid && pos->file_spec == file_spec)
|
||||
if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
|
||||
return &(*pos);
|
||||
}
|
||||
|
||||
if (m_dyld.uuid == uuid && m_dyld.file_spec == file_spec)
|
||||
if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
|
||||
return &m_dyld;
|
||||
|
||||
return NULL;
|
||||
|
@ -205,6 +225,35 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
|
|||
return false;
|
||||
}
|
||||
|
||||
ModuleSP
|
||||
DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
|
||||
{
|
||||
if (did_create_ptr)
|
||||
*did_create_ptr = false;
|
||||
ModuleSP module_sp;
|
||||
ModuleList &target_images = m_process->GetTarget().GetImages();
|
||||
const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
|
||||
if (image_info_uuid_is_valid)
|
||||
module_sp = target_images.FindModule(image_info.uuid);
|
||||
|
||||
if (!module_sp)
|
||||
{
|
||||
ArchSpec arch(image_info.GetArchitecture ());
|
||||
|
||||
module_sp = target_images.FindFirstModuleForFileSpec (image_info.file_spec, &arch, NULL);
|
||||
|
||||
if (can_create && !module_sp)
|
||||
{
|
||||
module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec,
|
||||
arch,
|
||||
image_info_uuid_is_valid ? &image_info.uuid : NULL);
|
||||
if (did_create_ptr)
|
||||
*did_create_ptr = module_sp;
|
||||
}
|
||||
}
|
||||
return module_sp;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Assume that dyld is in memory at ADDR and try to parse it's load
|
||||
// commands
|
||||
|
@ -215,7 +264,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
|
|||
DataExtractor data; // Load command data
|
||||
if (ReadMachHeader (addr, &m_dyld.header, &data))
|
||||
{
|
||||
if (m_dyld.header.filetype == HeaderFileTypeDynamicLinkEditor)
|
||||
if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
|
||||
{
|
||||
m_dyld.address = addr;
|
||||
ModuleSP dyld_module_sp;
|
||||
|
@ -223,17 +272,10 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
|
|||
{
|
||||
if (m_dyld.file_spec)
|
||||
{
|
||||
ArchSpec dyld_arch(eArchTypeMachO, m_dyld.header.cputype, m_dyld.header.cpusubtype);
|
||||
dyld_module_sp = m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld.file_spec);
|
||||
dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
|
||||
|
||||
if (dyld_module_sp.get() == NULL || dyld_module_sp->GetArchitecture() != dyld_arch)
|
||||
{
|
||||
dyld_module_sp = m_process->GetTarget().GetSharedModule (m_dyld.file_spec,
|
||||
dyld_arch,
|
||||
&m_dyld.uuid);
|
||||
}
|
||||
|
||||
UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
|
||||
if (dyld_module_sp)
|
||||
UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +349,7 @@ DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
|
|||
// updated INFO that is passed in.
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, struct DYLDImageInfo& info)
|
||||
DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
|
||||
{
|
||||
bool changed = false;
|
||||
if (module)
|
||||
|
@ -379,7 +421,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, struct DYLDImag
|
|||
// updated INFO that is passed in.
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, struct DYLDImageInfo& info)
|
||||
DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
|
||||
{
|
||||
bool changed = false;
|
||||
if (module)
|
||||
|
@ -551,6 +593,8 @@ uint32_t
|
|||
DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
|
||||
ModuleList& target_images = m_process->GetTarget().GetImages();
|
||||
|
||||
if (ReadAllImageInfosStructure ())
|
||||
{
|
||||
Mutex::Locker locker(m_mutex);
|
||||
|
@ -627,13 +671,12 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
|||
// we might have shared libraries that got loaded from
|
||||
// elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
|
||||
// environment variables...
|
||||
ModuleList& images = m_process->GetTarget().GetImages();
|
||||
const size_t num_images = images.GetSize();
|
||||
const size_t num_images = target_images.GetSize();
|
||||
for (idx = 0; idx < num_images; ++idx)
|
||||
{
|
||||
ModuleSP module_sp (images.GetModuleAtIndex (idx));
|
||||
ModuleSP module_sp (target_images.GetModuleAtIndex (idx));
|
||||
|
||||
if (GetImageInfo (module_sp->GetFileSpec(), module_sp->GetUUID()) == NULL)
|
||||
if (GetImageInfo (module_sp.get()) == NULL)
|
||||
unloaded_module_list.AppendIfNeeded (module_sp);
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +701,7 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
|||
{
|
||||
if (log)
|
||||
old_dyld_all_image_infos[old_idx].PutToLog (log.get());
|
||||
ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[old_idx].file_spec));
|
||||
ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL));
|
||||
if (unload_image_module_sp.get())
|
||||
{
|
||||
if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
|
||||
|
@ -696,18 +739,11 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
|||
ModuleList loaded_module_list;
|
||||
for (uint32_t idx = 0; idx<num_dylibs; ++idx)
|
||||
{
|
||||
ArchSpec arch_spec(eArchTypeMachO, m_dyld_image_infos[idx].header.cputype, m_dyld_image_infos[idx].header.cpusubtype);
|
||||
ModuleSP image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld_image_infos[idx].file_spec));
|
||||
if (image_module_sp.get() == NULL || image_module_sp->GetArchitecture() != arch_spec)
|
||||
{
|
||||
image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
|
||||
arch_spec,
|
||||
&m_dyld_image_infos[idx].uuid);
|
||||
}
|
||||
ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL));
|
||||
|
||||
if (image_module_sp)
|
||||
{
|
||||
if (m_dyld_image_infos[idx].header.filetype == HeaderFileTypeDynamicLinkEditor)
|
||||
if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
|
||||
image_module_sp->SetIsDynamicLinkEditor (true);
|
||||
|
||||
ObjectFile *objfile = image_module_sp->GetObjectFile ();
|
||||
|
@ -720,17 +756,19 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
|||
Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
|
||||
if (commpage_section)
|
||||
{
|
||||
FileSpec objfile_file_spec(objfile->GetFileSpec());
|
||||
ModuleSP commpage_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (objfile_file_spec, &commpage_dbstr));
|
||||
if (commpage_image_module_sp.get() == NULL)
|
||||
const FileSpec objfile_file_spec = objfile->GetFileSpec();
|
||||
ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ());
|
||||
ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr));
|
||||
if (!commpage_image_module_sp)
|
||||
{
|
||||
commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
|
||||
arch_spec,
|
||||
arch,
|
||||
&m_dyld_image_infos[idx].uuid,
|
||||
&commpage_dbstr,
|
||||
objfile->GetOffset() + commpage_section->GetOffset());
|
||||
UpdateCommPageLoadAddress(commpage_image_module_sp.get());
|
||||
}
|
||||
if (commpage_image_module_sp)
|
||||
UpdateCommPageLoadAddress (commpage_image_module_sp.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,15 +819,15 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
|
|||
// Returns true if we succeed, false if we fail for any reason.
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header, DataExtractor *load_command_data)
|
||||
DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
|
||||
{
|
||||
DataBufferHeap header_bytes(sizeof(mach_header), 0);
|
||||
DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
|
||||
Error error;
|
||||
size_t bytes_read = m_process->ReadMemory (addr,
|
||||
header_bytes.GetBytes(),
|
||||
header_bytes.GetByteSize(),
|
||||
error);
|
||||
if (bytes_read == sizeof(mach_header))
|
||||
if (bytes_read == sizeof(llvm::MachO::mach_header))
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
::memset (header, 0, sizeof(header));
|
||||
|
@ -804,13 +842,13 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header,
|
|||
case llvm::MachO::HeaderMagic32:
|
||||
case llvm::MachO::HeaderMagic32Swapped:
|
||||
data.SetAddressByteSize(4);
|
||||
load_cmd_addr += sizeof(mach_header);
|
||||
load_cmd_addr += sizeof(llvm::MachO::mach_header);
|
||||
break;
|
||||
|
||||
case llvm::MachO::HeaderMagic64:
|
||||
case llvm::MachO::HeaderMagic64Swapped:
|
||||
data.SetAddressByteSize(8);
|
||||
load_cmd_addr += sizeof(mach_header_64);
|
||||
load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -818,7 +856,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header,
|
|||
}
|
||||
|
||||
// Read the rest of dyld's mach header
|
||||
if (data.GetU32(&offset, &header->cputype, (sizeof(mach_header)/sizeof(uint32_t)) - 1))
|
||||
if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
|
||||
{
|
||||
if (load_command_data == NULL)
|
||||
return true; // We were able to read the mach_header and weren't asked to read the load command bytes
|
||||
|
@ -851,7 +889,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header,
|
|||
// Parse the load commands for an image
|
||||
//----------------------------------------------------------------------
|
||||
uint32_t
|
||||
DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
|
||||
DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
uint32_t cmd_idx;
|
||||
|
@ -863,15 +901,15 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DY
|
|||
// Clear out any load command specific data from DYLIB_INFO since
|
||||
// we are about to read it.
|
||||
|
||||
if (data.ValidOffsetForDataOfSize (offset, sizeof(load_command)))
|
||||
if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
|
||||
{
|
||||
load_command load_cmd;
|
||||
llvm::MachO::load_command load_cmd;
|
||||
uint32_t load_cmd_offset = offset;
|
||||
load_cmd.cmd = data.GetU32 (&offset);
|
||||
load_cmd.cmdsize = data.GetU32 (&offset);
|
||||
switch (load_cmd.cmd)
|
||||
{
|
||||
case LoadCommandSegment32:
|
||||
case llvm::MachO::LoadCommandSegment32:
|
||||
{
|
||||
segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
|
||||
segment.addr = data.GetU32 (&offset);
|
||||
|
@ -880,7 +918,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DY
|
|||
}
|
||||
break;
|
||||
|
||||
case LoadCommandSegment64:
|
||||
case llvm::MachO::LoadCommandSegment64:
|
||||
{
|
||||
segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
|
||||
segment.addr = data.GetU64 (&offset);
|
||||
|
@ -889,7 +927,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DY
|
|||
}
|
||||
break;
|
||||
|
||||
case LoadCommandDynamicLinkerIdent:
|
||||
case llvm::MachO::LoadCommandDynamicLinkerIdent:
|
||||
if (lc_id_dylinker)
|
||||
{
|
||||
uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
|
||||
|
@ -898,7 +936,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DY
|
|||
}
|
||||
break;
|
||||
|
||||
case LoadCommandUUID:
|
||||
case llvm::MachO::LoadCommandUUID:
|
||||
dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
|
||||
break;
|
||||
|
||||
|
@ -920,6 +958,7 @@ void
|
|||
DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
|
||||
{
|
||||
uint32_t exe_idx = UINT32_MAX;
|
||||
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
|
||||
// Read any UUID values that we can get
|
||||
for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
|
||||
{
|
||||
|
@ -931,37 +970,35 @@ DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
|
|||
|
||||
ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
|
||||
|
||||
if (m_dyld_image_infos[i].header.filetype == HeaderFileTypeExecutable)
|
||||
if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
|
||||
exe_idx = i;
|
||||
|
||||
if (log)
|
||||
m_dyld_image_infos[i].PutToLog (log.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (exe_idx < m_dyld_image_infos.size())
|
||||
{
|
||||
bool set_executable = false;
|
||||
ArchSpec dyld_exe_arch_spec(eArchTypeMachO, m_dyld_image_infos[exe_idx].header.cputype, m_dyld_image_infos[exe_idx].header.cpusubtype);
|
||||
ModuleSP exe_module_sp(m_process->GetTarget().GetExecutableModule());
|
||||
if (exe_module_sp.get())
|
||||
{
|
||||
if (exe_module_sp->GetFileSpec() != m_dyld_image_infos[exe_idx].file_spec ||
|
||||
exe_module_sp->GetArchitecture() != dyld_exe_arch_spec)
|
||||
set_executable = true;
|
||||
}
|
||||
else
|
||||
set_executable = true;
|
||||
ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL));
|
||||
|
||||
if (set_executable)
|
||||
if (!exe_module_sp)
|
||||
{
|
||||
ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ());
|
||||
exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
|
||||
dyld_exe_arch_spec,
|
||||
exe_arch_spec,
|
||||
&m_dyld_image_infos[exe_idx].uuid);
|
||||
if (exe_module_sp.get())
|
||||
}
|
||||
|
||||
if (exe_module_sp)
|
||||
{
|
||||
if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModule().get())
|
||||
{
|
||||
// If we found the file where it purported to be, then it should
|
||||
// be safe to load dependent images.
|
||||
bool get_dependent_images = exe_module_sp->GetFileSpec() == m_dyld_image_infos[exe_idx].file_spec;
|
||||
|
||||
m_process->GetTarget().SetExecutableModule (exe_module_sp, get_dependent_images);
|
||||
// Don't load dependent images since we are in dyld where we will know
|
||||
// and find out about all images that are loaded
|
||||
bool get_dependent_images = false;
|
||||
m_process->GetTarget().SetExecutableModule (exe_module_sp,
|
||||
get_dependent_images);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,6 +278,12 @@ protected:
|
|||
return lldb::endian::InlHostByteOrder();
|
||||
}
|
||||
|
||||
lldb_private::ArchSpec
|
||||
GetArchitecture () const
|
||||
{
|
||||
return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
|
||||
}
|
||||
|
||||
const Segment *
|
||||
FindSegment (const lldb_private::ConstString &name) const;
|
||||
|
||||
|
@ -337,20 +343,24 @@ protected:
|
|||
|
||||
uint32_t
|
||||
ParseLoadCommands (const lldb_private::DataExtractor& data,
|
||||
struct DYLDImageInfo& dylib_info,
|
||||
DYLDImageInfo& dylib_info,
|
||||
lldb_private::FileSpec *lc_id_dylinker);
|
||||
|
||||
bool
|
||||
UpdateImageLoadAddress(lldb_private::Module *module,
|
||||
struct DYLDImageInfo& info);
|
||||
DYLDImageInfo& info);
|
||||
|
||||
bool
|
||||
UnloadImageLoadAddress (lldb_private::Module *module,
|
||||
struct DYLDImageInfo& info);
|
||||
DYLDImageInfo& info);
|
||||
|
||||
lldb::ModuleSP
|
||||
FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info,
|
||||
bool can_create,
|
||||
bool *did_create_ptr);
|
||||
|
||||
DYLDImageInfo *
|
||||
GetImageInfo (const lldb_private::FileSpec &file_spec,
|
||||
const lldb_private::UUID &uuid);
|
||||
GetImageInfo (lldb_private::Module *module);
|
||||
|
||||
bool
|
||||
NeedToLocateDYLD () const;
|
||||
|
|
|
@ -10105,7 +10105,7 @@ EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding
|
|||
// {
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
EmulateInstructionARM::ARMOpcode*
|
||||
|
|
|
@ -238,8 +238,11 @@ PlatformDarwin::GetRemoteSystemArchitecture ()
|
|||
|
||||
|
||||
const char *
|
||||
PlatformDarwin::GetRemoteHostname ()
|
||||
PlatformDarwin::GetHostname ()
|
||||
{
|
||||
if (IsHost())
|
||||
return Platform::GetHostname();
|
||||
|
||||
if (m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetHostname ();
|
||||
return NULL;
|
||||
|
@ -311,3 +314,67 @@ PlatformDarwin::DisconnectRemote ()
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
bool sucess = false;
|
||||
if (IsHost())
|
||||
{
|
||||
sucess = Platform::GetProcessInfo (pid, process_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_remote_platform_sp)
|
||||
sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
|
||||
}
|
||||
return sucess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t
|
||||
PlatformDarwin::FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
uint32_t match_count = 0;
|
||||
if (IsHost())
|
||||
{
|
||||
// Let the base class figure out the host details
|
||||
match_count = Platform::FindProcesses (match_info, process_infos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we are remote, we can only return results if we are connected
|
||||
if (m_remote_platform_sp)
|
||||
match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
|
||||
}
|
||||
return match_count;
|
||||
}
|
||||
|
||||
const char *
|
||||
PlatformDarwin::GetUserName (uint32_t uid)
|
||||
{
|
||||
// Check the cache in Platform in case we have already looked this uid up
|
||||
const char *user_name = Platform::GetUserName(uid);
|
||||
if (user_name)
|
||||
return user_name;
|
||||
|
||||
if (IsRemote() && m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetUserName(uid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
PlatformDarwin::GetGroupName (uint32_t gid)
|
||||
{
|
||||
const char *group_name = Platform::GetGroupName(gid);
|
||||
if (group_name)
|
||||
return group_name;
|
||||
|
||||
if (IsRemote() && m_remote_platform_sp)
|
||||
return m_remote_platform_sp->GetGroupName(gid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,61 +16,71 @@
|
|||
// Project includes
|
||||
#include "lldb/Target/Platform.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class PlatformDarwin : public lldb_private::Platform
|
||||
{
|
||||
public:
|
||||
PlatformDarwin (bool is_host);
|
||||
|
||||
class PlatformDarwin : public Platform
|
||||
{
|
||||
public:
|
||||
PlatformDarwin (bool is_host);
|
||||
virtual
|
||||
~PlatformDarwin();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual lldb_private::Error
|
||||
ResolveExecutable (const lldb_private::FileSpec &exe_file,
|
||||
const lldb_private::ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
|
||||
virtual
|
||||
~PlatformDarwin();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual Error
|
||||
ResolveExecutable (const FileSpec &exe_file,
|
||||
const ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
virtual size_t
|
||||
GetSoftwareBreakpointTrapOpcode (lldb_private::Target &target,
|
||||
lldb_private::BreakpointSite *bp_site);
|
||||
|
||||
virtual size_t
|
||||
GetSoftwareBreakpointTrapOpcode (Target &target,
|
||||
BreakpointSite *bp_site);
|
||||
virtual bool
|
||||
GetRemoteOSVersion ();
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSVersion ();
|
||||
virtual bool
|
||||
GetRemoteOSBuildString (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSKernelDescription (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSBuildString (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSKernelDescription (std::string &s);
|
||||
// Remote Platform subclasses need to override this function
|
||||
virtual lldb_private::ArchSpec
|
||||
GetRemoteSystemArchitecture ();
|
||||
|
||||
// Remote Platform subclasses need to override this function
|
||||
virtual ArchSpec
|
||||
GetRemoteSystemArchitecture ();
|
||||
virtual bool
|
||||
IsConnected () const;
|
||||
|
||||
virtual bool
|
||||
IsConnected () const;
|
||||
virtual lldb_private::Error
|
||||
ConnectRemote (lldb_private::Args& args);
|
||||
|
||||
virtual Error
|
||||
ConnectRemote (Args& args);
|
||||
virtual lldb_private::Error
|
||||
DisconnectRemote ();
|
||||
|
||||
virtual Error
|
||||
DisconnectRemote ();
|
||||
virtual const char *
|
||||
GetHostname ();
|
||||
|
||||
virtual const char *
|
||||
GetRemoteHostname ();
|
||||
virtual const char *
|
||||
GetUserName (uint32_t uid);
|
||||
|
||||
virtual const char *
|
||||
GetGroupName (uint32_t gid);
|
||||
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid,
|
||||
lldb_private::ProcessInfo &proc_info);
|
||||
|
||||
virtual uint32_t
|
||||
FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
|
||||
lldb_private::ProcessInfoList &process_infos);
|
||||
|
||||
protected:
|
||||
lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS
|
||||
|
||||
protected:
|
||||
lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformDarwin);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformDarwin);
|
||||
|
||||
};
|
||||
} // namespace lldb_private
|
||||
};
|
||||
|
||||
#endif // liblldb_PlatformDarwin_h_
|
||||
|
|
|
@ -128,39 +128,51 @@ PlatformMacOSX::GetFile (const FileSpec &platform_file,
|
|||
return Error();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PlatformMacOSX::FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos)
|
||||
Error
|
||||
PlatformMacOSX::GetSharedModule (const FileSpec &platform_file,
|
||||
const ArchSpec &arch,
|
||||
const UUID *uuid_ptr,
|
||||
const ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
ModuleSP &module_sp,
|
||||
ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr)
|
||||
{
|
||||
uint32_t match_count = 0;
|
||||
if (IsHost())
|
||||
{
|
||||
match_count = Host::FindProcessesByName (name_match, name_match_type, process_infos);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_remote_platform_sp)
|
||||
match_count = m_remote_platform_sp->FindProcessesByName (name_match, name_match_type, process_infos);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Error error;
|
||||
module_sp.reset();
|
||||
|
||||
bool
|
||||
PlatformMacOSX::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
bool sucess = false;
|
||||
if (IsHost())
|
||||
{
|
||||
sucess = Host::GetProcessInfo (pid, process_info);
|
||||
}
|
||||
else
|
||||
if (IsRemote())
|
||||
{
|
||||
// If we have a remote platform always, let it try and locate
|
||||
// the shared module first.
|
||||
if (m_remote_platform_sp)
|
||||
sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
|
||||
{
|
||||
error = m_remote_platform_sp->GetSharedModule (platform_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
}
|
||||
}
|
||||
return sucess;
|
||||
|
||||
if (!module_sp)
|
||||
{
|
||||
// Fall back to the local platform and find the file locally
|
||||
error = Platform::GetSharedModule(platform_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
}
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
return error;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -187,3 +199,4 @@ PlatformMacOSX::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,88 +16,88 @@
|
|||
// Project includes
|
||||
#include "PlatformDarwin.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class PlatformMacOSX : public PlatformDarwin
|
||||
{
|
||||
public:
|
||||
|
||||
class PlatformMacOSX : public PlatformDarwin
|
||||
//------------------------------------------------------------
|
||||
// Class functions
|
||||
//------------------------------------------------------------
|
||||
static lldb_private::Platform*
|
||||
CreateInstance ();
|
||||
|
||||
static void
|
||||
Initialize ();
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static const char *
|
||||
GetPluginNameStatic ();
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic(bool is_host);
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic(bool is_host);
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------
|
||||
PlatformMacOSX (bool is_host);
|
||||
|
||||
virtual
|
||||
~PlatformMacOSX();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
public:
|
||||
return GetPluginNameStatic ();
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic (IsHost());
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetDescription ()
|
||||
{
|
||||
return GetDescriptionStatic (IsHost());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class functions
|
||||
//------------------------------------------------------------
|
||||
static Platform*
|
||||
CreateInstance ();
|
||||
virtual lldb_private::Error
|
||||
GetFile (const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
static void
|
||||
Initialize ();
|
||||
lldb_private::Error
|
||||
GetSharedModule (const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::ArchSpec &arch,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
const lldb_private::ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
lldb::ModuleSP &module_sp,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr);
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static const char *
|
||||
GetPluginNameStatic ();
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx,
|
||||
lldb_private::ArchSpec &arch);
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic(bool is_host);
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformMacOSX);
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic(bool is_host);
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------
|
||||
PlatformMacOSX (bool is_host);
|
||||
|
||||
virtual
|
||||
~PlatformMacOSX();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
return GetPluginNameStatic ();
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic (IsHost());
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetDescription ()
|
||||
{
|
||||
return GetDescriptionStatic (IsHost());
|
||||
}
|
||||
|
||||
virtual Error
|
||||
GetFile (const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
|
||||
virtual uint32_t
|
||||
FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos);
|
||||
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
|
||||
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformMacOSX);
|
||||
|
||||
};
|
||||
} // namespace lldb_private
|
||||
};
|
||||
|
||||
#endif // liblldb_PlatformMacOSX_h_
|
||||
|
|
|
@ -151,56 +151,47 @@ PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
|
|||
NULL,
|
||||
NULL);
|
||||
|
||||
if (exe_module_sp->GetObjectFile() == NULL)
|
||||
{
|
||||
exe_module_sp.reset();
|
||||
error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s",
|
||||
exe_file.GetDirectory().AsCString(""),
|
||||
exe_file.GetDirectory() ? "/" : "",
|
||||
exe_file.GetFilename().AsCString(""),
|
||||
exe_arch.GetArchitectureName());
|
||||
}
|
||||
if (exe_module_sp->GetObjectFile())
|
||||
return error;
|
||||
exe_module_sp.reset();
|
||||
}
|
||||
else
|
||||
// No valid architecture was specified or the exact ARM slice wasn't
|
||||
// found so ask the platform for the architectures that we should be
|
||||
// using (in the correct order) and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
ArchSpec platform_arch;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
|
||||
{
|
||||
// No valid architecture was specified, ask the platform for
|
||||
// the architectures that we should be using (in the correct order)
|
||||
// and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
ArchSpec platform_arch;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
|
||||
error = ModuleList::GetSharedModule (resolved_exe_file,
|
||||
platform_arch,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
exe_module_sp,
|
||||
NULL,
|
||||
NULL);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success())
|
||||
{
|
||||
error = ModuleList::GetSharedModule (resolved_exe_file,
|
||||
platform_arch,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
exe_module_sp,
|
||||
NULL,
|
||||
NULL);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success())
|
||||
{
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
arch_names.PutCString (", ");
|
||||
arch_names.PutCString (platform_arch.GetArchitectureName());
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp)
|
||||
{
|
||||
error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
|
||||
exe_file.GetDirectory().AsCString(""),
|
||||
exe_file.GetDirectory() ? "/" : "",
|
||||
exe_file.GetFilename().AsCString(""),
|
||||
GetShortPluginName(),
|
||||
arch_names.GetString().c_str());
|
||||
}
|
||||
if (idx > 0)
|
||||
arch_names.PutCString (", ");
|
||||
arch_names.PutCString (platform_arch.GetArchitectureName());
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp)
|
||||
{
|
||||
error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
|
||||
exe_file.GetDirectory().AsCString(""),
|
||||
exe_file.GetDirectory() ? "/" : "",
|
||||
exe_file.GetFilename().AsCString(""),
|
||||
GetShortPluginName(),
|
||||
arch_names.GetString().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -418,10 +409,46 @@ PlatformRemoteiOS::GetFile (const FileSpec &platform_file,
|
|||
return error;
|
||||
}
|
||||
|
||||
Error
|
||||
PlatformRemoteiOS::GetSharedModule (const FileSpec &platform_file,
|
||||
const ArchSpec &arch,
|
||||
const UUID *uuid_ptr,
|
||||
const ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
ModuleSP &module_sp,
|
||||
ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr)
|
||||
{
|
||||
// For iOS, the SDK files are all cached locally on the host
|
||||
// system. So first we ask for the file in the cached SDK,
|
||||
// then we attempt to get a shared module for the right architecture
|
||||
// with the right UUID.
|
||||
Error error;
|
||||
FileSpec local_file;
|
||||
error = GetFile (platform_file, uuid_ptr, local_file);
|
||||
if (error.Success())
|
||||
{
|
||||
const bool always_create = false;
|
||||
error = ModuleList::GetSharedModule (local_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr,
|
||||
always_create);
|
||||
}
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
PlatformRemoteiOS::FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos)
|
||||
PlatformRemoteiOS::FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
// TODO: if connected, send a packet to get the remote process infos by name
|
||||
process_infos.Clear();
|
||||
|
|
|
@ -16,111 +16,119 @@
|
|||
// Project includes
|
||||
#include "PlatformDarwin.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class PlatformRemoteiOS : public PlatformDarwin
|
||||
{
|
||||
public:
|
||||
|
||||
class PlatformRemoteiOS : public PlatformDarwin
|
||||
//------------------------------------------------------------
|
||||
// Class Functions
|
||||
//------------------------------------------------------------
|
||||
static lldb_private::Platform*
|
||||
CreateInstance ();
|
||||
|
||||
static void
|
||||
Initialize ();
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static const char *
|
||||
GetPluginNameStatic ();
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic();
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------
|
||||
PlatformRemoteiOS ();
|
||||
|
||||
virtual
|
||||
~PlatformRemoteiOS();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
public:
|
||||
return GetPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Functions
|
||||
//------------------------------------------------------------
|
||||
static Platform*
|
||||
CreateInstance ();
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual lldb_private::Error
|
||||
ResolveExecutable (const lldb_private::FileSpec &exe_file,
|
||||
const lldb_private::ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
|
||||
static void
|
||||
Initialize ();
|
||||
virtual const char *
|
||||
GetDescription ()
|
||||
{
|
||||
return GetDescriptionStatic();
|
||||
}
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static const char *
|
||||
GetPluginNameStatic ();
|
||||
virtual void
|
||||
GetStatus (lldb_private::Stream &strm);
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic();
|
||||
virtual lldb_private::Error
|
||||
GetFile (const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------
|
||||
PlatformRemoteiOS ();
|
||||
lldb_private::Error
|
||||
GetSharedModule (const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::ArchSpec &arch,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
const lldb_private::ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
lldb::ModuleSP &module_sp,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr);
|
||||
|
||||
virtual
|
||||
~PlatformRemoteiOS();
|
||||
virtual uint32_t
|
||||
FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
|
||||
lldb_private::ProcessInfoList &process_infos);
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
return GetPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid,
|
||||
lldb_private::ProcessInfo &proc_info);
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual Error
|
||||
ResolveExecutable (const FileSpec &exe_file,
|
||||
const ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx,
|
||||
lldb_private::ArchSpec &arch);
|
||||
|
||||
virtual const char *
|
||||
GetDescription ()
|
||||
{
|
||||
return GetDescriptionStatic();
|
||||
}
|
||||
protected:
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
//std::vector<FileSpec> m_device_support_os_dirs;
|
||||
|
||||
const char *
|
||||
GetDeviceSupportDirectory();
|
||||
|
||||
virtual void
|
||||
GetStatus (Stream &strm);
|
||||
const char *
|
||||
GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
virtual Error
|
||||
GetFile (const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteiOS);
|
||||
|
||||
virtual uint32_t
|
||||
FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos);
|
||||
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
|
||||
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);
|
||||
|
||||
protected:
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
//std::vector<FileSpec> m_device_support_os_dirs;
|
||||
|
||||
const char *
|
||||
GetDeviceSupportDirectory();
|
||||
|
||||
const char *
|
||||
GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteiOS);
|
||||
|
||||
};
|
||||
} // namespace lldb_private
|
||||
};
|
||||
|
||||
#endif // liblldb_PlatformRemoteiOS_h_
|
||||
|
|
|
@ -126,20 +126,6 @@ PlatformRemoteGDBServer::~PlatformRemoteGDBServer()
|
|||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PlatformRemoteGDBServer::FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
|
||||
{
|
||||
|
@ -240,7 +226,7 @@ PlatformRemoteGDBServer::DisconnectRemote ()
|
|||
}
|
||||
|
||||
const char *
|
||||
PlatformRemoteGDBServer::GetRemoteHostname ()
|
||||
PlatformRemoteGDBServer::GetHostname ()
|
||||
{
|
||||
m_gdb_client.GetHostname (m_name);
|
||||
if (m_name.empty())
|
||||
|
@ -248,3 +234,47 @@ PlatformRemoteGDBServer::GetRemoteHostname ()
|
|||
return m_name.c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
PlatformRemoteGDBServer::GetUserName (uint32_t uid)
|
||||
{
|
||||
// Try and get a cache user name first
|
||||
const char *cached_user_name = Platform::GetUserName(uid);
|
||||
if (cached_user_name)
|
||||
return cached_user_name;
|
||||
std::string name;
|
||||
if (m_gdb_client.GetUserName(uid, name))
|
||||
return SetCachedUserName(uid, name.c_str(), name.size());
|
||||
|
||||
SetUserNameNotFound(uid); // Negative cache so we don't keep sending packets
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
PlatformRemoteGDBServer::GetGroupName (uint32_t gid)
|
||||
{
|
||||
const char *cached_group_name = Platform::GetGroupName(gid);
|
||||
if (cached_group_name)
|
||||
return cached_group_name;
|
||||
std::string name;
|
||||
if (m_gdb_client.GetGroupName(gid, name))
|
||||
return SetCachedGroupName(gid, name.c_str(), name.size());
|
||||
|
||||
SetGroupNameNotFound(gid); // Negative cache so we don't keep sending packets
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PlatformRemoteGDBServer::FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
return m_gdb_client.FindProcesses (match_info, process_infos);
|
||||
}
|
||||
|
||||
bool
|
||||
PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
return m_gdb_client.GetProcessInfo (pid, process_info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,121 +19,123 @@
|
|||
#include "lldb/Target/Platform.h"
|
||||
#include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class PlatformRemoteGDBServer : public lldb_private::Platform
|
||||
{
|
||||
public:
|
||||
|
||||
class PlatformRemoteGDBServer : public Platform
|
||||
static void
|
||||
Initialize ();
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static lldb_private::Platform*
|
||||
CreateInstance ();
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic();
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic();
|
||||
|
||||
|
||||
PlatformRemoteGDBServer ();
|
||||
|
||||
virtual
|
||||
~PlatformRemoteGDBServer();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
public:
|
||||
|
||||
static void
|
||||
Initialize ();
|
||||
|
||||
static void
|
||||
Terminate ();
|
||||
|
||||
static Platform*
|
||||
CreateInstance ();
|
||||
|
||||
static const char *
|
||||
GetShortPluginNameStatic();
|
||||
|
||||
static const char *
|
||||
GetDescriptionStatic();
|
||||
return "PlatformRemoteGDBServer";
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
PlatformRemoteGDBServer ();
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual lldb_private::Error
|
||||
ResolveExecutable (const lldb_private::FileSpec &exe_file,
|
||||
const lldb_private::ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
|
||||
virtual
|
||||
~PlatformRemoteGDBServer();
|
||||
virtual const char *
|
||||
GetDescription ();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
virtual const char *
|
||||
GetPluginName()
|
||||
{
|
||||
return "PlatformRemoteGDBServer";
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetShortPluginName()
|
||||
{
|
||||
return GetShortPluginNameStatic();
|
||||
}
|
||||
|
||||
virtual uint32_t
|
||||
GetPluginVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual lldb_private::Error
|
||||
GetFile (const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
virtual Error
|
||||
ResolveExecutable (const FileSpec &exe_file,
|
||||
const ArchSpec &arch,
|
||||
lldb::ModuleSP &module_sp);
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid, lldb_private::ProcessInfo &proc_info);
|
||||
|
||||
virtual uint32_t
|
||||
FindProcesses (const lldb_private::ProcessInfoMatch &match_info,
|
||||
lldb_private::ProcessInfoList &process_infos);
|
||||
|
||||
virtual const char *
|
||||
GetDescription ();
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
|
||||
|
||||
virtual Error
|
||||
GetFile (const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file);
|
||||
virtual size_t
|
||||
GetSoftwareBreakpointTrapOpcode (lldb_private::Target &target,
|
||||
lldb_private::BreakpointSite *bp_site);
|
||||
|
||||
virtual uint32_t
|
||||
FindProcessesByName (const char *name_match,
|
||||
NameMatchType name_match_type,
|
||||
ProcessInfoList &process_infos);
|
||||
virtual bool
|
||||
GetRemoteOSVersion ();
|
||||
|
||||
virtual bool
|
||||
GetProcessInfo (lldb::pid_t pid, ProcessInfo &proc_info);
|
||||
virtual bool
|
||||
GetRemoteOSBuildString (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSKernelDescription (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);
|
||||
// Remote Platform subclasses need to override this function
|
||||
virtual lldb_private::ArchSpec
|
||||
GetRemoteSystemArchitecture ();
|
||||
|
||||
virtual size_t
|
||||
GetSoftwareBreakpointTrapOpcode (Target &target,
|
||||
BreakpointSite *bp_site);
|
||||
// Remote subclasses should override this and return a valid instance
|
||||
// name if connected.
|
||||
virtual const char *
|
||||
GetHostname ();
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSVersion ();
|
||||
virtual const char *
|
||||
GetUserName (uint32_t uid);
|
||||
|
||||
virtual const char *
|
||||
GetGroupName (uint32_t gid);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSBuildString (std::string &s);
|
||||
|
||||
virtual bool
|
||||
GetRemoteOSKernelDescription (std::string &s);
|
||||
virtual bool
|
||||
IsConnected () const;
|
||||
|
||||
// Remote Platform subclasses need to override this function
|
||||
virtual ArchSpec
|
||||
GetRemoteSystemArchitecture ();
|
||||
virtual lldb_private::Error
|
||||
ConnectRemote (lldb_private::Args& args);
|
||||
|
||||
// Remote subclasses should override this and return a valid instance
|
||||
// name if connected.
|
||||
virtual const char *
|
||||
GetRemoteHostname ();
|
||||
virtual lldb_private::Error
|
||||
DisconnectRemote ();
|
||||
|
||||
virtual bool
|
||||
IsConnected () const;
|
||||
protected:
|
||||
GDBRemoteCommunicationClient m_gdb_client;
|
||||
std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
|
||||
|
||||
virtual Error
|
||||
ConnectRemote (Args& args);
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
|
||||
|
||||
virtual Error
|
||||
DisconnectRemote ();
|
||||
|
||||
protected:
|
||||
GDBRemoteCommunicationClient m_gdb_client;
|
||||
std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
|
||||
|
||||
};
|
||||
} // namespace lldb_private
|
||||
};
|
||||
|
||||
#endif // liblldb_PlatformRemoteGDBServer_h_
|
||||
|
|
|
@ -112,13 +112,13 @@ ThreadMacOSX::GetDispatchQueueName()
|
|||
m_process.GetTarget().GetArchitecture().GetAddressByteSize());
|
||||
static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
|
||||
const Symbol *dispatch_queue_offsets_symbol = NULL;
|
||||
ModuleSP module_sp(m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
|
||||
ModuleSP module_sp(m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false), NULL, NULL));
|
||||
if (module_sp)
|
||||
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
|
||||
|
||||
if (dispatch_queue_offsets_symbol == NULL)
|
||||
{
|
||||
module_sp = m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
|
||||
module_sp = m_process.GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false), NULL, NULL);
|
||||
if (module_sp)
|
||||
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
|
||||
}
|
||||
|
|
|
@ -161,8 +161,8 @@ StopInfoMachException::GetDescription ()
|
|||
case llvm::Triple::x86_64:
|
||||
switch (m_exc_code)
|
||||
{
|
||||
case 1: subcode_desc = "EXC_I386_SGL"; break;
|
||||
case 2: subcode_desc = "EXC_I386_BPT"; break;
|
||||
case 1: code_desc = "EXC_I386_SGL"; break;
|
||||
case 2: code_desc = "EXC_I386_BPT"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -170,14 +170,14 @@ StopInfoMachException::GetDescription ()
|
|||
case llvm::Triple::ppc64:
|
||||
switch (m_exc_code)
|
||||
{
|
||||
case 1: subcode_desc = "EXC_PPC_BREAKPOINT"; break;
|
||||
case 1: code_desc = "EXC_PPC_BREAKPOINT"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case llvm::Triple::arm:
|
||||
switch (m_exc_code)
|
||||
{
|
||||
case 1: subcode_desc = "EXC_ARM_BREAKPOINT"; break;
|
||||
case 1: code_desc = "EXC_ARM_BREAKPOINT"; break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -332,7 +332,10 @@ StopInfoMachException::CreateStopReasonWithMachException
|
|||
else
|
||||
return StopInfoSP();
|
||||
}
|
||||
|
||||
else if (cpu == llvm::Triple::arm)
|
||||
{
|
||||
return StopInfo::CreateStopReasonToTrace (thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -30,7 +30,7 @@ using namespace lldb_private;
|
|||
//----------------------------------------------------------------------
|
||||
GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) :
|
||||
Communication(comm_name),
|
||||
m_packet_timeout (1),
|
||||
m_packet_timeout (60),
|
||||
m_rx_packet_listener (listener_name),
|
||||
m_sequence_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_public_is_running (false),
|
||||
|
@ -57,7 +57,6 @@ GDBRemoteCommunication::~GDBRemoteCommunication()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
|
||||
{
|
||||
|
@ -80,7 +79,7 @@ GDBRemoteCommunication::SendAck ()
|
|||
log->Printf ("send packet: +");
|
||||
ConnectionStatus status = eConnectionStatusSuccess;
|
||||
char ack_char = '+';
|
||||
return Write (&ack_char, 1, status, NULL) == 1;
|
||||
return Write (&ack_char, 1, status, NULL);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -91,7 +90,15 @@ GDBRemoteCommunication::SendNack ()
|
|||
log->Printf ("send packet: -");
|
||||
ConnectionStatus status = eConnectionStatusSuccess;
|
||||
char nack_char = '-';
|
||||
return Write (&nack_char, 1, status, NULL) == 1;
|
||||
return Write (&nack_char, 1, status, NULL);
|
||||
}
|
||||
|
||||
size_t
|
||||
GDBRemoteCommunication::SendPacket (lldb_private::StreamString &payload)
|
||||
{
|
||||
Mutex::Locker locker(m_sequence_mutex);
|
||||
const std::string &p (payload.GetString());
|
||||
return SendPacketNoLock (p.c_str(), p.size());
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
SendPacket (const char *payload,
|
||||
size_t payload_length);
|
||||
|
||||
size_t
|
||||
SendPacket (lldb_private::StreamString &response);
|
||||
|
||||
// Wait for a packet within 'nsec' seconds
|
||||
size_t
|
||||
WaitForPacket (StringExtractorGDBRemote &response,
|
||||
|
|
|
@ -38,13 +38,17 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
|
|||
GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
|
||||
m_supports_not_sending_acks (eLazyBoolCalculate),
|
||||
m_supports_thread_suffix (eLazyBoolCalculate),
|
||||
m_supports_qHostInfo (eLazyBoolCalculate),
|
||||
m_supports_vCont_all (eLazyBoolCalculate),
|
||||
m_supports_vCont_any (eLazyBoolCalculate),
|
||||
m_supports_vCont_c (eLazyBoolCalculate),
|
||||
m_supports_vCont_C (eLazyBoolCalculate),
|
||||
m_supports_vCont_s (eLazyBoolCalculate),
|
||||
m_supports_vCont_S (eLazyBoolCalculate),
|
||||
m_qHostInfo_is_valid (eLazyBoolCalculate),
|
||||
m_supports_qProcessInfoPID (true),
|
||||
m_supports_qfProcessInfo (true),
|
||||
m_supports_qUserName (true),
|
||||
m_supports_qGroupName (true),
|
||||
m_async_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_async_packet_predicate (false),
|
||||
m_async_packet (),
|
||||
|
@ -113,11 +117,15 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
|
|||
{
|
||||
m_supports_not_sending_acks = eLazyBoolCalculate;
|
||||
m_supports_thread_suffix = eLazyBoolCalculate;
|
||||
m_supports_qHostInfo = eLazyBoolCalculate;
|
||||
m_supports_vCont_c = eLazyBoolCalculate;
|
||||
m_supports_vCont_C = eLazyBoolCalculate;
|
||||
m_supports_vCont_s = eLazyBoolCalculate;
|
||||
m_supports_vCont_S = eLazyBoolCalculate;
|
||||
m_qHostInfo_is_valid = eLazyBoolCalculate;
|
||||
m_supports_qProcessInfoPID = true;
|
||||
m_supports_qfProcessInfo = true;
|
||||
m_supports_qUserName = true;
|
||||
m_supports_qGroupName = true;
|
||||
m_host_arch.Clear();
|
||||
}
|
||||
|
||||
|
@ -759,107 +767,159 @@ GDBRemoteCommunicationClient::GetSystemArchitecture ()
|
|||
bool
|
||||
GDBRemoteCommunicationClient::GetHostInfo ()
|
||||
{
|
||||
if (m_supports_qHostInfo == eLazyBoolCalculate)
|
||||
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
|
||||
{
|
||||
m_supports_qHostInfo = eLazyBoolNo;
|
||||
|
||||
m_qHostInfo_is_valid = eLazyBoolNo;
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
|
||||
{
|
||||
if (response.IsUnsupportedResponse())
|
||||
{
|
||||
return false;
|
||||
|
||||
m_supports_qHostInfo = eLazyBoolYes;
|
||||
|
||||
std::string name;
|
||||
std::string value;
|
||||
uint32_t cpu = LLDB_INVALID_CPUTYPE;
|
||||
uint32_t sub = 0;
|
||||
std::string arch_name;
|
||||
std::string os_name;
|
||||
std::string vendor_name;
|
||||
std::string triple;
|
||||
uint32_t pointer_byte_size = 0;
|
||||
StringExtractor extractor;
|
||||
ByteOrder byte_order = eByteOrderInvalid;
|
||||
while (response.GetNameColonValue(name, value))
|
||||
{
|
||||
if (name.compare("cputype") == 0)
|
||||
{
|
||||
// exception type in big endian hex
|
||||
cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
|
||||
}
|
||||
else if (name.compare("cpusubtype") == 0)
|
||||
{
|
||||
// exception count in big endian hex
|
||||
sub = Args::StringToUInt32 (value.c_str(), 0, 0);
|
||||
}
|
||||
else if (name.compare("arch") == 0)
|
||||
{
|
||||
arch_name.swap (value);
|
||||
}
|
||||
else if (name.compare("triple") == 0)
|
||||
{
|
||||
// The triple comes as ASCII hex bytes since it contains '-' chars
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (triple);
|
||||
}
|
||||
else if (name.compare("os_build") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_os_build);
|
||||
}
|
||||
else if (name.compare("hostname") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_hostname);
|
||||
}
|
||||
else if (name.compare("os_kernel") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_os_kernel);
|
||||
}
|
||||
else if (name.compare("ostype") == 0)
|
||||
{
|
||||
os_name.swap (value);
|
||||
}
|
||||
else if (name.compare("vendor") == 0)
|
||||
{
|
||||
vendor_name.swap(value);
|
||||
}
|
||||
else if (name.compare("endian") == 0)
|
||||
{
|
||||
if (value.compare("little") == 0)
|
||||
byte_order = eByteOrderLittle;
|
||||
else if (value.compare("big") == 0)
|
||||
byte_order = eByteOrderBig;
|
||||
else if (value.compare("pdp") == 0)
|
||||
byte_order = eByteOrderPDP;
|
||||
}
|
||||
else if (name.compare("ptrsize") == 0)
|
||||
{
|
||||
pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
|
||||
}
|
||||
else if (name.compare("os_version") == 0)
|
||||
{
|
||||
Args::StringToVersion (value.c_str(),
|
||||
m_os_version_major,
|
||||
m_os_version_minor,
|
||||
m_os_version_update);
|
||||
}
|
||||
}
|
||||
|
||||
if (triple.empty())
|
||||
else if (response.IsNormalResponse())
|
||||
{
|
||||
if (arch_name.empty())
|
||||
std::string name;
|
||||
std::string value;
|
||||
uint32_t cpu = LLDB_INVALID_CPUTYPE;
|
||||
uint32_t sub = 0;
|
||||
std::string arch_name;
|
||||
std::string os_name;
|
||||
std::string vendor_name;
|
||||
std::string triple;
|
||||
uint32_t pointer_byte_size = 0;
|
||||
StringExtractor extractor;
|
||||
ByteOrder byte_order = eByteOrderInvalid;
|
||||
uint32_t num_keys_decoded = 0;
|
||||
while (response.GetNameColonValue(name, value))
|
||||
{
|
||||
if (cpu != LLDB_INVALID_CPUTYPE)
|
||||
if (name.compare("cputype") == 0)
|
||||
{
|
||||
m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
|
||||
// exception type in big endian hex
|
||||
cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
|
||||
if (cpu != LLDB_INVALID_CPUTYPE)
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("cpusubtype") == 0)
|
||||
{
|
||||
// exception count in big endian hex
|
||||
sub = Args::StringToUInt32 (value.c_str(), 0, 0);
|
||||
if (sub != 0)
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("arch") == 0)
|
||||
{
|
||||
arch_name.swap (value);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("triple") == 0)
|
||||
{
|
||||
// The triple comes as ASCII hex bytes since it contains '-' chars
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (triple);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("os_build") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_os_build);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("hostname") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_hostname);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("os_kernel") == 0)
|
||||
{
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (m_os_kernel);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("ostype") == 0)
|
||||
{
|
||||
os_name.swap (value);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("vendor") == 0)
|
||||
{
|
||||
vendor_name.swap(value);
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("endian") == 0)
|
||||
{
|
||||
++num_keys_decoded;
|
||||
if (value.compare("little") == 0)
|
||||
byte_order = eByteOrderLittle;
|
||||
else if (value.compare("big") == 0)
|
||||
byte_order = eByteOrderBig;
|
||||
else if (value.compare("pdp") == 0)
|
||||
byte_order = eByteOrderPDP;
|
||||
else
|
||||
--num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("ptrsize") == 0)
|
||||
{
|
||||
pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
|
||||
if (pointer_byte_size != 0)
|
||||
++num_keys_decoded;
|
||||
}
|
||||
else if (name.compare("os_version") == 0)
|
||||
{
|
||||
Args::StringToVersion (value.c_str(),
|
||||
m_os_version_major,
|
||||
m_os_version_minor,
|
||||
m_os_version_update);
|
||||
if (m_os_version_major != UINT32_MAX)
|
||||
++num_keys_decoded;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_keys_decoded > 0)
|
||||
m_qHostInfo_is_valid = eLazyBoolYes;
|
||||
|
||||
if (triple.empty())
|
||||
{
|
||||
if (arch_name.empty())
|
||||
{
|
||||
if (cpu != LLDB_INVALID_CPUTYPE)
|
||||
{
|
||||
m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
|
||||
if (pointer_byte_size)
|
||||
{
|
||||
assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
|
||||
}
|
||||
if (byte_order != eByteOrderInvalid)
|
||||
{
|
||||
assert (byte_order == m_host_arch.GetByteOrder());
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
|
||||
if (!os_name.empty())
|
||||
m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string triple;
|
||||
triple += arch_name;
|
||||
triple += '-';
|
||||
if (vendor_name.empty())
|
||||
triple += "unknown";
|
||||
else
|
||||
triple += vendor_name;
|
||||
triple += '-';
|
||||
if (os_name.empty())
|
||||
triple += "unknown";
|
||||
else
|
||||
triple += os_name;
|
||||
m_host_arch.SetTriple (triple.c_str());
|
||||
if (pointer_byte_size)
|
||||
{
|
||||
assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
|
||||
|
@ -868,27 +928,11 @@ GDBRemoteCommunicationClient::GetHostInfo ()
|
|||
{
|
||||
assert (byte_order == m_host_arch.GetByteOrder());
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
|
||||
if (!os_name.empty())
|
||||
m_host_arch.GetTriple().setVendorName (llvm::StringRef (os_name));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string triple;
|
||||
triple += arch_name;
|
||||
triple += '-';
|
||||
if (vendor_name.empty())
|
||||
triple += "unknown";
|
||||
else
|
||||
triple += vendor_name;
|
||||
triple += '-';
|
||||
if (os_name.empty())
|
||||
triple += "unknown";
|
||||
else
|
||||
triple += os_name;
|
||||
m_host_arch.SetTriple (triple.c_str());
|
||||
if (pointer_byte_size)
|
||||
{
|
||||
|
@ -898,24 +942,11 @@ GDBRemoteCommunicationClient::GetHostInfo ()
|
|||
{
|
||||
assert (byte_order == m_host_arch.GetByteOrder());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_arch.SetTriple (triple.c_str());
|
||||
if (pointer_byte_size)
|
||||
{
|
||||
assert (pointer_byte_size == m_host_arch.GetAddressByteSize());
|
||||
}
|
||||
if (byte_order != eByteOrderInvalid)
|
||||
{
|
||||
assert (byte_order == m_host_arch.GetByteOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_supports_qHostInfo == eLazyBoolYes;
|
||||
return m_qHostInfo_is_valid == eLazyBoolYes;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -927,10 +958,10 @@ GDBRemoteCommunicationClient::SendAttach
|
|||
{
|
||||
if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
StreamString packet;
|
||||
packet.Printf("vAttach;%x", pid);
|
||||
|
||||
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
|
||||
char packet[64];
|
||||
const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%x", pid);
|
||||
assert (packet_len < sizeof(packet));
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsErrorResponse())
|
||||
return response.GetError();
|
||||
|
@ -943,7 +974,7 @@ GDBRemoteCommunicationClient::SendAttach
|
|||
const lldb_private::ArchSpec &
|
||||
GDBRemoteCommunicationClient::GetHostArchitecture ()
|
||||
{
|
||||
if (m_supports_qHostInfo == eLazyBoolCalculate)
|
||||
if (m_qHostInfo_is_valid == eLazyBoolCalculate)
|
||||
GetHostInfo ();
|
||||
return m_host_arch;
|
||||
}
|
||||
|
@ -952,12 +983,13 @@ addr_t
|
|||
GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
|
||||
{
|
||||
char packet[64];
|
||||
::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
|
||||
permissions & lldb::ePermissionsReadable ? "r" : "",
|
||||
permissions & lldb::ePermissionsWritable ? "w" : "",
|
||||
permissions & lldb::ePermissionsExecutable ? "x" : "");
|
||||
const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
|
||||
permissions & lldb::ePermissionsReadable ? "r" : "",
|
||||
permissions & lldb::ePermissionsWritable ? "w" : "",
|
||||
permissions & lldb::ePermissionsExecutable ? "x" : "");
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet, response, false))
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (!response.IsErrorResponse())
|
||||
return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
|
||||
|
@ -969,9 +1001,10 @@ bool
|
|||
GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
|
||||
{
|
||||
char packet[64];
|
||||
snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
|
||||
const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet, response, false))
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsOKResponse())
|
||||
return true;
|
||||
|
@ -1070,11 +1103,11 @@ GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
|
|||
int
|
||||
GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
|
||||
{
|
||||
StreamString packet;
|
||||
packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
|
||||
|
||||
char packet[32];
|
||||
const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsOKResponse())
|
||||
return 0;
|
||||
|
@ -1084,3 +1117,251 @@ GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInfo &process_info)
|
||||
{
|
||||
if (response.IsNormalResponse())
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
StringExtractor extractor;
|
||||
|
||||
while (response.GetNameColonValue(name, value))
|
||||
{
|
||||
if (name.compare("pid") == 0)
|
||||
{
|
||||
process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
|
||||
}
|
||||
else if (name.compare("ppid") == 0)
|
||||
{
|
||||
process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
|
||||
}
|
||||
else if (name.compare("uid") == 0)
|
||||
{
|
||||
process_info.SetRealUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
|
||||
}
|
||||
else if (name.compare("euid") == 0)
|
||||
{
|
||||
process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
|
||||
}
|
||||
else if (name.compare("gid") == 0)
|
||||
{
|
||||
process_info.SetRealGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
|
||||
}
|
||||
else if (name.compare("egid") == 0)
|
||||
{
|
||||
process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0));
|
||||
}
|
||||
else if (name.compare("triple") == 0)
|
||||
{
|
||||
// The triple comes as ASCII hex bytes since it contains '-' chars
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (value);
|
||||
process_info.GetArchitecture ().SetTriple (value.c_str());
|
||||
}
|
||||
else if (name.compare("name") == 0)
|
||||
{
|
||||
StringExtractor extractor;
|
||||
// The the process name from ASCII hex bytes since we can't
|
||||
// control the characters in a process name
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.SetFilePos(0);
|
||||
extractor.GetHexByteString (value);
|
||||
process_info.SwapName (value);
|
||||
}
|
||||
}
|
||||
|
||||
if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
process_info.Clear();
|
||||
|
||||
if (m_supports_qProcessInfoPID)
|
||||
{
|
||||
char packet[32];
|
||||
const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%i", pid);
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsUnsupportedResponse())
|
||||
{
|
||||
m_supports_qProcessInfoPID = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return DecodeProcessInfoResponse (response, process_info);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GDBRemoteCommunicationClient::FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
process_infos.Clear();
|
||||
|
||||
if (m_supports_qfProcessInfo)
|
||||
{
|
||||
StreamString packet;
|
||||
packet.PutCString ("qfProcessInfo");
|
||||
if (!match_info.MatchAllProcesses())
|
||||
{
|
||||
packet.PutChar (':');
|
||||
const char *name = match_info.GetProcessInfo().GetName();
|
||||
bool has_name_match = false;
|
||||
if (name && name[0])
|
||||
{
|
||||
has_name_match = true;
|
||||
NameMatchType name_match_type = match_info.GetNameMatchType();
|
||||
switch (name_match_type)
|
||||
{
|
||||
case eNameMatchIgnore:
|
||||
has_name_match = false;
|
||||
break;
|
||||
|
||||
case eNameMatchEquals:
|
||||
packet.PutCString ("name_match:equals;");
|
||||
break;
|
||||
|
||||
case eNameMatchContains:
|
||||
packet.PutCString ("name_match:contains;");
|
||||
break;
|
||||
|
||||
case eNameMatchStartsWith:
|
||||
packet.PutCString ("name_match:starts_with;");
|
||||
break;
|
||||
|
||||
case eNameMatchEndsWith:
|
||||
packet.PutCString ("name_match:ends_with;");
|
||||
break;
|
||||
|
||||
case eNameMatchRegularExpression:
|
||||
packet.PutCString ("name_match:regex;");
|
||||
break;
|
||||
}
|
||||
if (has_name_match)
|
||||
{
|
||||
packet.PutCString ("name:");
|
||||
packet.PutBytesAsRawHex8(name, ::strlen(name));
|
||||
packet.PutChar (';');
|
||||
}
|
||||
}
|
||||
|
||||
if (match_info.GetProcessInfo().ProcessIDIsValid())
|
||||
packet.Printf("pid:%u;",match_info.GetProcessInfo().GetProcessID());
|
||||
if (match_info.GetProcessInfo().ParentProcessIDIsValid())
|
||||
packet.Printf("parent_pid:%u;",match_info.GetProcessInfo().GetParentProcessID());
|
||||
if (match_info.GetProcessInfo().RealUserIDIsValid())
|
||||
packet.Printf("uid:%u;",match_info.GetProcessInfo().GetRealUserID());
|
||||
if (match_info.GetProcessInfo().RealGroupIDIsValid())
|
||||
packet.Printf("gid:%u;",match_info.GetProcessInfo().GetRealGroupID());
|
||||
if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
|
||||
packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID());
|
||||
if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
|
||||
packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID());
|
||||
if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
|
||||
packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0);
|
||||
if (match_info.GetProcessInfo().GetArchitecture().IsValid())
|
||||
{
|
||||
const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();
|
||||
const llvm::Triple &triple = match_arch.GetTriple();
|
||||
packet.PutCString("triple:");
|
||||
packet.PutCStringAsRawHex8(triple.getTriple().c_str());
|
||||
packet.PutChar (';');
|
||||
}
|
||||
}
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
|
||||
{
|
||||
if (response.IsUnsupportedResponse())
|
||||
{
|
||||
m_supports_qfProcessInfo = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
ProcessInfo process_info;
|
||||
if (!DecodeProcessInfoResponse (response, process_info))
|
||||
break;
|
||||
process_infos.Append(process_info);
|
||||
response.GetStringRef().clear();
|
||||
response.SetFilePos(0);
|
||||
} while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
|
||||
}
|
||||
}
|
||||
return process_infos.GetSize();
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
|
||||
{
|
||||
if (m_supports_qUserName)
|
||||
{
|
||||
char packet[32];
|
||||
const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsUnsupportedResponse())
|
||||
{
|
||||
m_supports_qUserName = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.IsNormalResponse())
|
||||
{
|
||||
// Make sure we parsed the right number of characters. The response is
|
||||
// the hex encoded user name and should make up the entire packet.
|
||||
// If there are any non-hex ASCII bytes, the length won't match below..
|
||||
if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
|
||||
{
|
||||
if (m_supports_qGroupName)
|
||||
{
|
||||
char packet[32];
|
||||
const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
|
||||
assert (packet_len < sizeof(packet));
|
||||
StringExtractorGDBRemote response;
|
||||
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
|
||||
{
|
||||
if (response.IsUnsupportedResponse())
|
||||
{
|
||||
m_supports_qGroupName = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.IsNormalResponse())
|
||||
{
|
||||
// Make sure we parsed the right number of characters. The response is
|
||||
// the hex encoded group name and should make up the entire packet.
|
||||
// If there are any non-hex ASCII bytes, the length won't match below..
|
||||
if (response.GetHexByteString (name) * 2 == response.GetStringRef().size())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
|
|
@ -212,6 +212,20 @@ public:
|
|||
bool
|
||||
GetSupportsThreadSuffix ();
|
||||
|
||||
bool
|
||||
GetProcessInfo (lldb::pid_t pid,
|
||||
lldb_private::ProcessInfo &process_info);
|
||||
|
||||
uint32_t
|
||||
FindProcesses (const lldb_private::ProcessInfoMatch &process_match_info,
|
||||
lldb_private::ProcessInfoList &process_infos);
|
||||
|
||||
bool
|
||||
GetUserName (uint32_t uid, std::string &name);
|
||||
|
||||
bool
|
||||
GetGroupName (uint32_t gid, std::string &name);
|
||||
|
||||
bool
|
||||
HasFullVContSupport ()
|
||||
{
|
||||
|
@ -239,13 +253,17 @@ protected:
|
|||
//------------------------------------------------------------------
|
||||
lldb_private::LazyBool m_supports_not_sending_acks;
|
||||
lldb_private::LazyBool m_supports_thread_suffix;
|
||||
lldb_private::LazyBool m_supports_qHostInfo;
|
||||
lldb_private::LazyBool m_supports_vCont_all;
|
||||
lldb_private::LazyBool m_supports_vCont_any;
|
||||
lldb_private::LazyBool m_supports_vCont_c;
|
||||
lldb_private::LazyBool m_supports_vCont_C;
|
||||
lldb_private::LazyBool m_supports_vCont_s;
|
||||
lldb_private::LazyBool m_supports_vCont_S;
|
||||
lldb_private::LazyBool m_qHostInfo_is_valid;
|
||||
bool m_supports_qProcessInfoPID;
|
||||
bool m_supports_qfProcessInfo;
|
||||
bool m_supports_qUserName;
|
||||
bool m_supports_qGroupName;
|
||||
|
||||
// If we need to send a packet while the target is running, the m_async_XXX
|
||||
// member variables take care of making this happen.
|
||||
|
@ -263,6 +281,9 @@ protected:
|
|||
std::string m_os_kernel;
|
||||
std::string m_hostname;
|
||||
|
||||
bool
|
||||
DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
|
||||
lldb_private::ProcessInfo &process_info);
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
// For GDBRemoteCommunicationClient only
|
||||
|
|
|
@ -97,13 +97,28 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
|
|||
break;
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_unimplemented:
|
||||
return SendUnimplementedResponse () > 0;
|
||||
return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
|
||||
return Handle_qHostInfo ();
|
||||
|
||||
return Handle_qHostInfo (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
|
||||
return Handle_qProcessInfoPID (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
|
||||
return Handle_qfProcessInfo (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
|
||||
return Handle_qsProcessInfo (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qUserName:
|
||||
return Handle_qUserName (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_qGroupName:
|
||||
return Handle_qGroupName (packet);
|
||||
|
||||
case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
|
||||
return Handle_QStartNoAckMode ();
|
||||
return Handle_QStartNoAckMode (packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -119,11 +134,22 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout
|
|||
}
|
||||
|
||||
size_t
|
||||
GDBRemoteCommunicationServer::SendUnimplementedResponse ()
|
||||
GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
|
||||
{
|
||||
// TODO: Log the packet we aren't handling...
|
||||
return SendPacket ("");
|
||||
}
|
||||
|
||||
size_t
|
||||
GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
|
||||
{
|
||||
char packet[16];
|
||||
int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
|
||||
assert (packet_len < sizeof(packet));
|
||||
return SendPacket (packet, packet_len);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
GDBRemoteCommunicationServer::SendOKResponse ()
|
||||
{
|
||||
|
@ -139,7 +165,7 @@ GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
|
|||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_qHostInfo ()
|
||||
GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
StreamString response;
|
||||
|
||||
|
@ -204,13 +230,208 @@ GDBRemoteCommunicationServer::Handle_qHostInfo ()
|
|||
response.PutChar(';');
|
||||
}
|
||||
|
||||
return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
|
||||
return SendPacket (response) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
CreateProcessInfoResponse (const ProcessInfo &proc_info, StreamString &response)
|
||||
{
|
||||
response.Printf ("pid:%i;ppid:%i;uid:%i;gid:%i;euid:%i;egid:%i;",
|
||||
proc_info.GetProcessID(),
|
||||
proc_info.GetParentProcessID(),
|
||||
proc_info.GetRealUserID(),
|
||||
proc_info.GetRealGroupID(),
|
||||
proc_info.GetEffectiveUserID(),
|
||||
proc_info.GetEffectiveGroupID());
|
||||
response.PutCString ("name:");
|
||||
response.PutCStringAsRawHex8(proc_info.GetName());
|
||||
response.PutChar(';');
|
||||
const ArchSpec &proc_arch = proc_info.GetArchitecture();
|
||||
if (proc_arch.IsValid())
|
||||
{
|
||||
const llvm::Triple &proc_triple = proc_arch.GetTriple();
|
||||
response.PutCString("triple:");
|
||||
response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
|
||||
response.PutChar(';');
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_QStartNoAckMode ()
|
||||
GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// Packet format: "qProcessInfoPID:%i" where %i is the pid
|
||||
packet.SetFilePos(strlen ("qProcessInfoPID:"));
|
||||
lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
|
||||
if (pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
ProcessInfo proc_info;
|
||||
if (Host::GetProcessInfo(pid, proc_info))
|
||||
{
|
||||
StreamString response;
|
||||
CreateProcessInfoResponse (proc_info, response);
|
||||
return SendPacket (response);
|
||||
}
|
||||
}
|
||||
return SendErrorResponse (1);
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
m_proc_infos_index = 0;
|
||||
m_proc_infos.Clear();
|
||||
|
||||
ProcessInfoMatch match_info;
|
||||
packet.SetFilePos(strlen ("qfProcessInfo"));
|
||||
if (packet.GetChar() == ':')
|
||||
{
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
while (packet.GetNameColonValue(key, value))
|
||||
{
|
||||
bool success = true;
|
||||
if (key.compare("name") == 0)
|
||||
{
|
||||
StringExtractor extractor;
|
||||
extractor.GetStringRef().swap(value);
|
||||
extractor.GetHexByteString (value);
|
||||
match_info.GetProcessInfo().SetName (value.c_str());
|
||||
}
|
||||
else if (key.compare("name_match") == 0)
|
||||
{
|
||||
if (value.compare("equals") == 0)
|
||||
{
|
||||
match_info.SetNameMatchType (eNameMatchEquals);
|
||||
}
|
||||
else if (value.compare("starts_with") == 0)
|
||||
{
|
||||
match_info.SetNameMatchType (eNameMatchStartsWith);
|
||||
}
|
||||
else if (value.compare("ends_with") == 0)
|
||||
{
|
||||
match_info.SetNameMatchType (eNameMatchEndsWith);
|
||||
}
|
||||
else if (value.compare("contains") == 0)
|
||||
{
|
||||
match_info.SetNameMatchType (eNameMatchContains);
|
||||
}
|
||||
else if (value.compare("regex") == 0)
|
||||
{
|
||||
match_info.SetNameMatchType (eNameMatchRegularExpression);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (key.compare("pid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
|
||||
}
|
||||
else if (key.compare("parent_pid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success));
|
||||
}
|
||||
else if (key.compare("uid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
|
||||
}
|
||||
else if (key.compare("gid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
|
||||
}
|
||||
else if (key.compare("euid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
|
||||
}
|
||||
else if (key.compare("egid") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success));
|
||||
}
|
||||
else if (key.compare("all_users") == 0)
|
||||
{
|
||||
match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success));
|
||||
}
|
||||
else if (key.compare("triple") == 0)
|
||||
{
|
||||
match_info.GetProcessInfo().GetArchitecture().SetTriple(value.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
return SendErrorResponse (2);
|
||||
}
|
||||
}
|
||||
|
||||
if (Host::FindProcesses (match_info, m_proc_infos))
|
||||
{
|
||||
// We found something, return the first item by calling the get
|
||||
// subsequent process info packet handler...
|
||||
return Handle_qsProcessInfo (packet);
|
||||
}
|
||||
return SendErrorResponse (3);
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
if (m_proc_infos_index < m_proc_infos.GetSize())
|
||||
{
|
||||
StreamString response;
|
||||
CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
|
||||
++m_proc_infos_index;
|
||||
return SendPacket (response);
|
||||
}
|
||||
return SendErrorResponse (4);
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// Packet format: "qUserName:%i" where %i is the uid
|
||||
packet.SetFilePos(strlen ("qUserName:"));
|
||||
uint32_t uid = packet.GetU32 (UINT32_MAX);
|
||||
if (uid != UINT32_MAX)
|
||||
{
|
||||
std::string name;
|
||||
if (Host::GetUserName (uid, name))
|
||||
{
|
||||
StreamString response;
|
||||
response.PutCStringAsRawHex8 (name.c_str());
|
||||
return SendPacket (response);
|
||||
}
|
||||
}
|
||||
return SendErrorResponse (5);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// Packet format: "qGroupName:%i" where %i is the gid
|
||||
packet.SetFilePos(strlen ("qGroupName:"));
|
||||
uint32_t gid = packet.GetU32 (UINT32_MAX);
|
||||
if (gid != UINT32_MAX)
|
||||
{
|
||||
std::string name;
|
||||
if (Host::GetGroupName (gid, name))
|
||||
{
|
||||
StreamString response;
|
||||
response.PutCStringAsRawHex8 (name.c_str());
|
||||
return SendPacket (response);
|
||||
}
|
||||
}
|
||||
return SendErrorResponse (6);
|
||||
}
|
||||
|
||||
bool
|
||||
GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// Send response first before changing m_send_acks to we ack this packet
|
||||
SendOKResponse ();
|
||||
m_send_acks = false;
|
||||
return true;
|
||||
|
|
|
@ -14,9 +14,12 @@
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Target/Process.h"
|
||||
|
||||
#include "GDBRemoteCommunication.h"
|
||||
|
||||
class ProcessGDBRemote;
|
||||
class StringExtractorGDBRemote;
|
||||
|
||||
class GDBRemoteCommunicationServer : public GDBRemoteCommunication
|
||||
{
|
||||
|
@ -52,18 +55,38 @@ public:
|
|||
|
||||
protected:
|
||||
lldb::thread_t m_async_thread;
|
||||
lldb_private::ProcessInfoList m_proc_infos;
|
||||
uint32_t m_proc_infos_index;
|
||||
|
||||
size_t
|
||||
SendUnimplementedResponse ();
|
||||
SendUnimplementedResponse (const char *packet);
|
||||
|
||||
size_t
|
||||
SendErrorResponse (uint8_t error);
|
||||
|
||||
size_t
|
||||
SendOKResponse ();
|
||||
|
||||
bool
|
||||
Handle_qHostInfo ();
|
||||
Handle_qHostInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_qUserName (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_qGroupName (StringExtractorGDBRemote &packet);
|
||||
|
||||
bool
|
||||
Handle_QStartNoAckMode ();
|
||||
Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
|
||||
|
||||
private:
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -495,15 +495,15 @@ GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters()
|
|||
{ "sp", "r13", 4, 52, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 13 }},
|
||||
{ "lr", "r14", 4, 56, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 14 }},
|
||||
{ "pc", "r15", 4, 60, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 15 }},
|
||||
{ NULL, NULL, 12, 64, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 16 }},
|
||||
{ NULL, NULL, 12, 76, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 17 }},
|
||||
{ NULL, NULL, 12, 88, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 18 }},
|
||||
{ NULL, NULL, 12, 100, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 19 }},
|
||||
{ NULL, NULL, 12, 112, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 20 }},
|
||||
{ NULL, NULL, 12, 124, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 21 }},
|
||||
{ NULL, NULL, 12, 136, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 22 }},
|
||||
{ NULL, NULL, 12, 148, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 23 }},
|
||||
{ NULL, NULL, 12, 160, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 24 }},
|
||||
// { NULL, NULL, 12, 64, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 16 }},
|
||||
// { NULL, NULL, 12, 76, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 17 }},
|
||||
// { NULL, NULL, 12, 88, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 18 }},
|
||||
// { NULL, NULL, 12, 100, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 19 }},
|
||||
// { NULL, NULL, 12, 112, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 20 }},
|
||||
// { NULL, NULL, 12, 124, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 21 }},
|
||||
// { NULL, NULL, 12, 136, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 22 }},
|
||||
// { NULL, NULL, 12, 148, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 23 }},
|
||||
// { NULL, NULL, 12, 160, eEncodingIEEE754, eFormatFloat, { LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 24 }},
|
||||
{ "cpsr", "psr", 4, 172, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 25 }},
|
||||
{ "s0", NULL, 4, 176, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 26 }},
|
||||
{ "s1", NULL, 4, 180, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 27 }},
|
||||
|
|
|
@ -312,6 +312,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
|
|||
else
|
||||
{
|
||||
response_type = StringExtractorGDBRemote::eError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,6 +378,7 @@ ProcessGDBRemote::DoConnectRemote (const char *remote_url)
|
|||
{
|
||||
// We have a valid process
|
||||
SetID (pid);
|
||||
UpdateThreadListIfNeeded ();
|
||||
StringExtractorGDBRemote response;
|
||||
if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, false))
|
||||
{
|
||||
|
@ -601,23 +603,28 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
|
|||
return error;
|
||||
}
|
||||
|
||||
if (m_gdb_comm.StartReadThread(&error))
|
||||
// We always seem to be able to open a connection to a local port
|
||||
// so we need to make sure we can then send data to it. If we can't
|
||||
// then we aren't actually connected to anything, so try and do the
|
||||
// handshake with the remote GDB server and make sure that goes
|
||||
// alright.
|
||||
if (!m_gdb_comm.HandshakeWithServer (NULL))
|
||||
{
|
||||
// Send an initial ack
|
||||
m_gdb_comm.SendAck();
|
||||
|
||||
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
|
||||
m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
|
||||
this,
|
||||
m_debugserver_pid,
|
||||
false);
|
||||
|
||||
m_gdb_comm.ResetDiscoverableSettings();
|
||||
m_gdb_comm.GetSendAcks ();
|
||||
m_gdb_comm.GetThreadSuffixSupported ();
|
||||
m_gdb_comm.GetHostInfo ();
|
||||
m_gdb_comm.GetVContSupported ('c');
|
||||
m_gdb_comm.Disconnect();
|
||||
if (error.Success())
|
||||
error.SetErrorString("not connected to remote gdb server");
|
||||
return error;
|
||||
}
|
||||
if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
|
||||
m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
|
||||
this,
|
||||
m_debugserver_pid,
|
||||
false);
|
||||
m_gdb_comm.ResetDiscoverableSettings();
|
||||
m_gdb_comm.QueryNoAckModeSupported ();
|
||||
m_gdb_comm.GetThreadSuffixSupported ();
|
||||
m_gdb_comm.GetHostInfo ();
|
||||
m_gdb_comm.GetVContSupported ('c');
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -633,9 +640,6 @@ ProcessGDBRemote::DidLaunchOrAttach ()
|
|||
|
||||
BuildDynamicRegisterInfo (false);
|
||||
|
||||
|
||||
StreamString strm;
|
||||
|
||||
// See if the GDB server supports the qHostInfo information
|
||||
|
||||
const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
|
||||
|
@ -2364,13 +2368,13 @@ ProcessGDBRemote::GetDispatchQueueNameForThread
|
|||
{
|
||||
static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets");
|
||||
const Symbol *dispatch_queue_offsets_symbol = NULL;
|
||||
ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false)));
|
||||
ModuleSP module_sp(GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libSystem.B.dylib", false), NULL, NULL));
|
||||
if (module_sp)
|
||||
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
|
||||
|
||||
if (dispatch_queue_offsets_symbol == NULL)
|
||||
{
|
||||
module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false));
|
||||
module_sp = GetTarget().GetImages().FindFirstModuleForFileSpec (FileSpec("libdispatch.dylib", false), NULL, NULL);
|
||||
if (module_sp)
|
||||
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
|
||||
}
|
||||
|
|
|
@ -474,9 +474,9 @@ SymbolContextSpecifier::AddSpecification (const char *spec_string, Specification
|
|||
break;
|
||||
case eModuleSpecified:
|
||||
{
|
||||
// See if we can find the Module, if so stick it in the SymbolContext.
|
||||
FileSpec module_spec(spec_string, true);
|
||||
lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec);
|
||||
// See if we can find the Module, if so stick it in the SymbolContext.
|
||||
FileSpec module_spec(spec_string, false);
|
||||
lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL);
|
||||
m_type |= eModuleSpecified;
|
||||
if (module_sp)
|
||||
m_module_sp = module_sp;
|
||||
|
@ -487,7 +487,7 @@ SymbolContextSpecifier::AddSpecification (const char *spec_string, Specification
|
|||
case eFileSpecified:
|
||||
// CompUnits can't necessarily be resolved here, since an inlined function might show up in
|
||||
// a number of CompUnits. Instead we just convert to a FileSpec and store it away.
|
||||
m_file_spec_ap.reset (new FileSpec (spec_string, true));
|
||||
m_file_spec_ap.reset (new FileSpec (spec_string, false));
|
||||
m_type |= eFileSpecified;
|
||||
break;
|
||||
case eLineStartSpecified:
|
||||
|
|
|
@ -78,6 +78,35 @@ Platform::GetFile (const FileSpec &platform_file,
|
|||
return Error();
|
||||
}
|
||||
|
||||
Error
|
||||
Platform::GetSharedModule (const FileSpec &platform_file,
|
||||
const ArchSpec &arch,
|
||||
const UUID *uuid_ptr,
|
||||
const ConstString *object_name_ptr,
|
||||
off_t object_offset,
|
||||
ModuleSP &module_sp,
|
||||
ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr)
|
||||
{
|
||||
// Don't do any path remapping for the default implementation
|
||||
// of the platform GetSharedModule function, just call through
|
||||
// to our static ModuleList function. Platform subclasses that
|
||||
// implement remote debugging, might have a developer kits
|
||||
// installed that have cached versions of the files for the
|
||||
// remote target, or might implement a download and cache
|
||||
// locally implementation.
|
||||
const bool always_create = false;
|
||||
return ModuleList::GetSharedModule (platform_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr,
|
||||
always_create);
|
||||
}
|
||||
|
||||
|
||||
PlatformSP
|
||||
Platform::Create (const char *platform_name, Error &error)
|
||||
|
@ -127,7 +156,14 @@ Platform::Platform (bool is_host) :
|
|||
m_name (),
|
||||
m_major_os_version (UINT32_MAX),
|
||||
m_minor_os_version (UINT32_MAX),
|
||||
m_update_os_version (UINT32_MAX)
|
||||
m_update_os_version (UINT32_MAX),
|
||||
m_system_arch(),
|
||||
m_uid_map_mutex (Mutex::eMutexTypeNormal),
|
||||
m_gid_map_mutex (Mutex::eMutexTypeNormal),
|
||||
m_uid_map(),
|
||||
m_gid_map(),
|
||||
m_max_uid_name_len (0),
|
||||
m_max_gid_name_len (0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -148,18 +184,18 @@ Platform::GetStatus (Stream &strm)
|
|||
uint32_t minor = UINT32_MAX;
|
||||
uint32_t update = UINT32_MAX;
|
||||
std::string s;
|
||||
strm.Printf ("Platform: %s\n", GetShortPluginName());
|
||||
strm.Printf (" Platform: %s\n", GetShortPluginName());
|
||||
|
||||
ArchSpec arch (GetSystemArchitecture());
|
||||
if (arch.IsValid())
|
||||
{
|
||||
if (!arch.GetTriple().str().empty())
|
||||
strm.Printf("Triple: %s\n", arch.GetTriple().str().c_str());
|
||||
strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
|
||||
}
|
||||
|
||||
if (GetOSVersion(major, minor, update))
|
||||
{
|
||||
strm.Printf("OS: %u", major);
|
||||
strm.Printf("OS Version: %u", major);
|
||||
if (minor != UINT32_MAX)
|
||||
strm.Printf(".%u", minor);
|
||||
if (update != UINT32_MAX)
|
||||
|
@ -172,18 +208,18 @@ Platform::GetStatus (Stream &strm)
|
|||
}
|
||||
|
||||
if (GetOSKernelDescription (s))
|
||||
strm.Printf("Kernel: %s\n", s.c_str());
|
||||
strm.Printf(" Kernel: %s\n", s.c_str());
|
||||
|
||||
if (IsHost())
|
||||
{
|
||||
strm.Printf("Hostname: %s\n", GetHostname());
|
||||
strm.Printf(" Hostname: %s\n", GetHostname());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsConnected())
|
||||
strm.Printf("Remote hostname: %s\n", GetHostname());
|
||||
else
|
||||
strm.PutCString("Not connected to a remote platform.\n");
|
||||
const bool is_connected = IsConnected();
|
||||
if (is_connected)
|
||||
strm.Printf(" Hostname: %s\n", GetHostname());
|
||||
strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,33 +302,46 @@ Platform::GetOSKernelDescription (std::string &s)
|
|||
const char *
|
||||
Platform::GetHostname ()
|
||||
{
|
||||
if (m_name.empty())
|
||||
if (IsHost() && m_name.empty())
|
||||
{
|
||||
if (IsHost())
|
||||
{
|
||||
if (!Host::GetHostname(m_name))
|
||||
return "localhost";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsConnected())
|
||||
{
|
||||
const char *instance_name = GetRemoteHostname ();
|
||||
if (instance_name)
|
||||
m_name.assign (instance_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "remote";
|
||||
}
|
||||
}
|
||||
if (!Host::GetHostname(m_name))
|
||||
return "localhost";
|
||||
}
|
||||
|
||||
if (m_name.empty())
|
||||
return NULL;
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
Platform::GetUserName (uint32_t uid)
|
||||
{
|
||||
const char *user_name = GetCachedUserName(uid);
|
||||
if (user_name)
|
||||
return user_name;
|
||||
if (IsHost())
|
||||
{
|
||||
std::string name;
|
||||
if (Host::GetUserName(uid, name))
|
||||
return SetCachedUserName (uid, name.c_str(), name.size());
|
||||
}
|
||||
if (!m_name.empty())
|
||||
return m_name.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
Platform::GetGroupName (uint32_t gid)
|
||||
{
|
||||
const char *group_name = GetCachedGroupName(gid);
|
||||
if (group_name)
|
||||
return group_name;
|
||||
if (IsHost())
|
||||
{
|
||||
std::string name;
|
||||
if (Host::GetGroupName(gid, name))
|
||||
return SetCachedGroupName (gid, name.c_str(), name.size());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
Platform::SetOSVersion (uint32_t major,
|
||||
|
@ -447,3 +496,23 @@ Platform::DisconnectRemote ()
|
|||
error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
|
||||
return error;
|
||||
}
|
||||
|
||||
bool
|
||||
Platform::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info)
|
||||
{
|
||||
// Take care of the host case so that each subclass can just
|
||||
// call Platform::GetProcessInfo (pid, process_info)
|
||||
if (IsHost())
|
||||
return Host::GetProcessInfo (pid, process_info);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Platform::FindProcesses (const ProcessInfoMatch &match_info,
|
||||
ProcessInfoList &process_infos)
|
||||
{
|
||||
uint32_t match_count = 0;
|
||||
if (IsHost())
|
||||
match_count = Host::FindProcesses (match_info, process_infos);
|
||||
return match_count;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,172 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
void
|
||||
ProcessInfo::Dump (Stream &s, Platform *platform) const
|
||||
{
|
||||
const char *cstr;
|
||||
if (m_pid != LLDB_INVALID_PROCESS_ID) s.Printf (" pid = %i\n", m_pid);
|
||||
if (!m_name.empty()) s.Printf (" name = \"%s\"\n", m_name.c_str());
|
||||
if (m_arch.IsValid()) s.Printf (" arch = %s\n", m_arch.GetTriple().str().c_str());
|
||||
if (m_parent_pid != LLDB_INVALID_PROCESS_ID)s.Printf ("parent = %i\n", m_parent_pid);
|
||||
if (m_real_uid != UINT32_MAX)
|
||||
{
|
||||
cstr = platform->GetUserName (m_real_uid);
|
||||
s.Printf (" uid = %u %s\n", m_real_uid, cstr ? cstr : "");
|
||||
}
|
||||
if (m_real_gid != UINT32_MAX)
|
||||
{
|
||||
cstr = platform->GetGroupName (m_real_gid);
|
||||
s.Printf (" gid = %u %s\n", m_real_gid, cstr ? cstr : "");
|
||||
}
|
||||
if (m_effective_uid != UINT32_MAX)
|
||||
{
|
||||
cstr = platform->GetUserName (m_effective_uid);
|
||||
s.Printf (" euid = %u %s\n", m_effective_uid, cstr ? cstr : "");
|
||||
}
|
||||
if (m_effective_gid != UINT32_MAX)
|
||||
{
|
||||
cstr = platform->GetGroupName (m_effective_gid);
|
||||
s.Printf (" egid = %u %s\n", m_effective_gid, cstr ? cstr : "");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessInfo::DumpTableHeader (Stream &s, Platform *platform)
|
||||
{
|
||||
// s.PutCString ("PID PARENT UID GID EUID EGID TRIPLE NAME\n");
|
||||
// s.PutCString ("====== ====== ===== ===== ===== ===== ======================== ============================\n");
|
||||
s.PutCString ("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME\n");
|
||||
s.PutCString ("====== ====== ========== ========== ========== ========== ======================== ============================\n");
|
||||
}
|
||||
|
||||
void
|
||||
ProcessInfo::DumpAsTableRow (Stream &s, Platform *platform) const
|
||||
{
|
||||
if (m_pid != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
const char *cstr;
|
||||
s.Printf ("%-6u %-6u ", m_pid, m_parent_pid);
|
||||
|
||||
cstr = platform->GetUserName (m_real_uid);
|
||||
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
|
||||
s.Printf ("%-10s ", cstr);
|
||||
else
|
||||
s.Printf ("%-10u ", m_real_uid);
|
||||
|
||||
cstr = platform->GetGroupName (m_real_gid);
|
||||
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
|
||||
s.Printf ("%-10s ", cstr);
|
||||
else
|
||||
s.Printf ("%-10u ", m_real_gid);
|
||||
|
||||
cstr = platform->GetUserName (m_effective_uid);
|
||||
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
|
||||
s.Printf ("%-10s ", cstr);
|
||||
else
|
||||
s.Printf ("%-10u ", m_effective_uid);
|
||||
|
||||
cstr = platform->GetGroupName (m_effective_gid);
|
||||
if (cstr && cstr[0]) // Watch for empty string that indicates lookup failed
|
||||
s.Printf ("%-10s ", cstr);
|
||||
else
|
||||
s.Printf ("%-10u ", m_effective_gid);
|
||||
|
||||
s.Printf ("%-24s %s\n",
|
||||
m_arch.IsValid() ? m_arch.GetTriple().str().c_str() : "",
|
||||
m_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessInfoMatch::NameMatches (const char *process_name) const
|
||||
{
|
||||
if (m_name_match_type == eNameMatchIgnore || process_name == NULL)
|
||||
return true;
|
||||
const char *match_name = m_match_info.GetName();
|
||||
if (!match_name)
|
||||
return true;
|
||||
|
||||
return lldb_private::NameMatches (process_name, m_name_match_type, match_name);
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessInfoMatch::Matches (const ProcessInfo &proc_info) const
|
||||
{
|
||||
if (!NameMatches (proc_info.GetName()))
|
||||
return false;
|
||||
|
||||
if (m_match_info.ProcessIDIsValid() &&
|
||||
m_match_info.GetProcessID() != proc_info.GetProcessID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.ParentProcessIDIsValid() &&
|
||||
m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.RealUserIDIsValid () &&
|
||||
m_match_info.GetRealUserID() != proc_info.GetRealUserID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.RealGroupIDIsValid () &&
|
||||
m_match_info.GetRealGroupID() != proc_info.GetRealGroupID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.EffectiveUserIDIsValid () &&
|
||||
m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.EffectiveGroupIDIsValid () &&
|
||||
m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
|
||||
return false;
|
||||
|
||||
if (m_match_info.GetArchitecture().IsValid() &&
|
||||
m_match_info.GetArchitecture() != proc_info.GetArchitecture())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessInfoMatch::MatchAllProcesses () const
|
||||
{
|
||||
if (m_name_match_type != eNameMatchIgnore)
|
||||
return false;
|
||||
|
||||
if (m_match_info.ProcessIDIsValid())
|
||||
return false;
|
||||
|
||||
if (m_match_info.ParentProcessIDIsValid())
|
||||
return false;
|
||||
|
||||
if (m_match_info.RealUserIDIsValid ())
|
||||
return false;
|
||||
|
||||
if (m_match_info.RealGroupIDIsValid ())
|
||||
return false;
|
||||
|
||||
if (m_match_info.EffectiveUserIDIsValid ())
|
||||
return false;
|
||||
|
||||
if (m_match_info.EffectiveGroupIDIsValid ())
|
||||
return false;
|
||||
|
||||
if (m_match_info.GetArchitecture().IsValid())
|
||||
return false;
|
||||
|
||||
if (m_match_all_users)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ProcessInfoMatch::Clear()
|
||||
{
|
||||
m_match_info.Clear();
|
||||
m_name_match_type = eNameMatchIgnore;
|
||||
m_match_all_users = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// MemoryCache constructor
|
||||
|
@ -1727,7 +1893,10 @@ Process::Attach (const char *process_name, bool wait_for_launch)
|
|||
PlatformSP platform_sp (m_target.GetDebugger().GetPlatformList().GetSelectedPlatform ());
|
||||
if (platform_sp)
|
||||
{
|
||||
platform_sp->FindProcessesByName (process_name, eNameMatchEquals, process_infos);
|
||||
ProcessInfoMatch match_info;
|
||||
match_info.GetProcessInfo().SetName(process_name);
|
||||
match_info.SetNameMatchType (eNameMatchEquals);
|
||||
platform_sp->FindProcesses (match_info, process_infos);
|
||||
if (process_infos.GetSize() > 1)
|
||||
{
|
||||
error.SetErrorStringWithFormat ("More than one process named %s\n", process_name);
|
||||
|
@ -1829,13 +1998,28 @@ Process::ConnectRemote (const char *remote_url)
|
|||
Error error (DoConnectRemote (remote_url));
|
||||
if (error.Success())
|
||||
{
|
||||
StartPrivateStateThread();
|
||||
// If we attached and actually have a process on the other end, then
|
||||
// this ended up being the equivalent of an attach.
|
||||
if (GetID() != LLDB_INVALID_PROCESS_ID)
|
||||
{
|
||||
CompleteAttach ();
|
||||
EventSP event_sp;
|
||||
StateType state = WaitForProcessStopPrivate(NULL, event_sp);
|
||||
|
||||
if (state == eStateStopped || state == eStateCrashed)
|
||||
{
|
||||
// If we attached and actually have a process on the other end, then
|
||||
// this ended up being the equivalent of an attach.
|
||||
CompleteAttach ();
|
||||
|
||||
// This delays passing the stopped event to listeners till
|
||||
// CompleteAttach gets a chance to complete...
|
||||
HandlePrivateEvent (event_sp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (PrivateStateThreadIsValid ())
|
||||
ResumePrivateStateThread ();
|
||||
else
|
||||
StartPrivateStateThread ();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -39,22 +39,25 @@ using namespace lldb_private;
|
|||
//----------------------------------------------------------------------
|
||||
// Target constructor
|
||||
//----------------------------------------------------------------------
|
||||
Target::Target(Debugger &debugger, const lldb::PlatformSP &platform_sp) :
|
||||
Broadcaster("lldb.target"),
|
||||
m_platform_sp (platform_sp),
|
||||
Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp) :
|
||||
Broadcaster ("lldb.target"),
|
||||
ExecutionContextScope (),
|
||||
TargetInstanceSettings (*GetSettingsController()),
|
||||
m_debugger (debugger),
|
||||
m_platform_sp (platform_sp),
|
||||
m_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_images(),
|
||||
m_arch (target_arch),
|
||||
m_images (),
|
||||
m_section_load_list (),
|
||||
m_breakpoint_list (false),
|
||||
m_internal_breakpoint_list (true),
|
||||
m_process_sp(),
|
||||
m_search_filter_sp(),
|
||||
m_process_sp (),
|
||||
m_search_filter_sp (),
|
||||
m_image_search_paths (ImageSearchPathsChanged, this),
|
||||
m_scratch_ast_context_ap (NULL),
|
||||
m_persistent_variables (),
|
||||
m_stop_hook_next_id(0)
|
||||
m_stop_hooks (),
|
||||
m_stop_hook_next_id (0)
|
||||
{
|
||||
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
|
||||
SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
|
||||
|
@ -412,10 +415,9 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
|
||||
m_images.Append(executable_sp); // The first image is our exectuable file
|
||||
|
||||
ArchSpec exe_arch = executable_sp->GetArchitecture();
|
||||
// If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
|
||||
if (!m_arch_spec.IsValid())
|
||||
m_arch_spec = exe_arch;
|
||||
if (!m_arch.IsValid())
|
||||
m_arch = executable_sp->GetArchitecture();
|
||||
|
||||
FileSpecList dependent_files;
|
||||
ObjectFile *executable_objfile = executable_sp->GetObjectFile();
|
||||
|
@ -433,7 +435,7 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
platform_dependent_file_spec = dependent_file_spec;
|
||||
|
||||
ModuleSP image_module_sp(GetSharedModule (platform_dependent_file_spec,
|
||||
exe_arch));
|
||||
m_arch));
|
||||
if (image_module_sp.get())
|
||||
{
|
||||
//image_module_sp->Dump(&s);// REMOVE THIS, DEBUG ONLY
|
||||
|
@ -445,9 +447,9 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
}
|
||||
|
||||
// Now see if we know the target triple, and if so, create our scratch AST context:
|
||||
if (m_arch_spec.IsValid())
|
||||
if (m_arch.IsValid())
|
||||
{
|
||||
m_scratch_ast_context_ap.reset (new ClangASTContext(m_arch_spec.GetTriple().str().c_str()));
|
||||
m_scratch_ast_context_ap.reset (new ClangASTContext(m_arch.GetTriple().str().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,22 +460,22 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
bool
|
||||
Target::SetArchitecture (const ArchSpec &arch_spec)
|
||||
{
|
||||
if (m_arch_spec == arch_spec)
|
||||
if (m_arch == arch_spec)
|
||||
{
|
||||
// If we're setting the architecture to our current architecture, we
|
||||
// don't need to do anything.
|
||||
return true;
|
||||
}
|
||||
else if (!m_arch_spec.IsValid())
|
||||
else if (!m_arch.IsValid())
|
||||
{
|
||||
// If we haven't got a valid arch spec, then we just need to set it.
|
||||
m_arch_spec = arch_spec;
|
||||
m_arch = arch_spec;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we have an executable file, try to reset the executable to the desired architecture
|
||||
m_arch_spec = arch_spec;
|
||||
m_arch = arch_spec;
|
||||
ModuleSP executable_sp = GetExecutableModule ();
|
||||
m_images.Clear();
|
||||
m_scratch_ast_context_ap.reset();
|
||||
|
@ -668,10 +670,9 @@ Target::GetSharedModule
|
|||
bool did_create_module = false;
|
||||
ModuleSP module_sp;
|
||||
|
||||
// If there are image search path entries, try to use them first to acquire a suitable image.
|
||||
|
||||
Error error;
|
||||
|
||||
// If there are image search path entries, try to use them first to acquire a suitable image.
|
||||
if (m_image_search_paths.GetSize())
|
||||
{
|
||||
FileSpec transformed_spec;
|
||||
|
@ -682,13 +683,26 @@ Target::GetSharedModule
|
|||
}
|
||||
}
|
||||
|
||||
// If a module hasn't been found yet, use the unmodified path.
|
||||
|
||||
if (!module_sp)
|
||||
// The platform is responsible for finding and caching an appropriate
|
||||
// module in the shared module cache.
|
||||
if (m_platform_sp)
|
||||
{
|
||||
error = (ModuleList::GetSharedModule (file_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module));
|
||||
FileSpec platform_file_spec;
|
||||
error = m_platform_sp->GetSharedModule (file_spec,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name,
|
||||
object_offset,
|
||||
module_sp,
|
||||
&old_module_sp,
|
||||
&did_create_module);
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString("no platform is currently set");
|
||||
}
|
||||
|
||||
// If a module hasn't been found yet, use the unmodified path.
|
||||
if (module_sp)
|
||||
{
|
||||
m_images.Append (module_sp);
|
||||
|
@ -1130,17 +1144,17 @@ Target::RunStopHooks ()
|
|||
bool echo_commands = false;
|
||||
bool print_results = true;
|
||||
GetDebugger().GetCommandInterpreter().HandleCommands (cur_hook_sp->GetCommands(),
|
||||
&exc_ctx_with_reasons[i],
|
||||
stop_on_continue,
|
||||
stop_on_error,
|
||||
echo_commands,
|
||||
print_results,
|
||||
result);
|
||||
&exc_ctx_with_reasons[i],
|
||||
stop_on_continue,
|
||||
stop_on_error,
|
||||
echo_commands,
|
||||
print_results,
|
||||
result);
|
||||
|
||||
// If the command started the target going again, we should bag out of
|
||||
// running the stop hooks.
|
||||
if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
|
||||
|| (result.GetStatus() == eReturnStatusSuccessContinuingResult))
|
||||
if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
|
||||
(result.GetStatus() == eReturnStatusSuccessContinuingResult))
|
||||
{
|
||||
result.AppendMessageWithFormat ("Aborting stop hooks, hook %d set the program running.", cur_hook_sp->GetID());
|
||||
keep_going = false;
|
||||
|
|
|
@ -68,7 +68,6 @@ TargetList::CreateTarget
|
|||
{
|
||||
ModuleSP exe_module_sp;
|
||||
FileSpec resolved_file(file);
|
||||
ArchSpec platform_arch;
|
||||
|
||||
if (platform_sp)
|
||||
error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
|
||||
|
@ -94,7 +93,7 @@ TargetList::CreateTarget
|
|||
}
|
||||
return error;
|
||||
}
|
||||
target_sp.reset(new Target(debugger, platform_sp));
|
||||
target_sp.reset(new Target(debugger, arch, platform_sp));
|
||||
target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
|
||||
}
|
||||
}
|
||||
|
@ -102,9 +101,7 @@ TargetList::CreateTarget
|
|||
{
|
||||
// No file was specified, just create an empty target with any arch
|
||||
// if a valid arch was specified
|
||||
target_sp.reset(new Target(debugger, platform_sp));
|
||||
if (arch.IsValid())
|
||||
target_sp->SetArchitecture(arch);
|
||||
target_sp.reset(new Target(debugger, arch, platform_sp));
|
||||
}
|
||||
|
||||
if (target_sp)
|
||||
|
|
|
@ -156,6 +156,26 @@ StringExtractor::GetHexU8 (uint8_t fail_value)
|
|||
return fail_value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
StringExtractor::GetU32 (uint32_t fail_value, int base)
|
||||
{
|
||||
if (m_index < m_packet.size())
|
||||
{
|
||||
char *end = NULL;
|
||||
const char *start = m_packet.c_str();
|
||||
const char *uint_cstr = start + m_index;
|
||||
uint32_t result = ::strtoul (uint_cstr, &end, base);
|
||||
|
||||
if (end && end != uint_cstr)
|
||||
{
|
||||
m_index = end - start;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
|
||||
{
|
||||
|
|
|
@ -98,6 +98,9 @@ public:
|
|||
bool
|
||||
GetNameColonValue (std::string &name, std::string &value);
|
||||
|
||||
uint32_t
|
||||
GetU32 (uint32_t fail_value, int base = 0);
|
||||
|
||||
uint32_t
|
||||
GetHexMaxU32 (bool little_endian, uint32_t fail_value);
|
||||
|
||||
|
|
|
@ -81,8 +81,18 @@ StringExtractorGDBRemote::GetServerPacketType () const
|
|||
break;
|
||||
|
||||
case 'q':
|
||||
if (strcmp (packet_cstr, "qHostInfo") == 0)
|
||||
if (packet_cstr[1] == 'H' && 0 == ::strcmp (packet_cstr, "qHostInfo"))
|
||||
return eServerPacketType_qHostInfo;
|
||||
else if (packet_cstr[1] == 'P' && 0 == ::strncmp(packet_cstr, "qProcessInfoPID:", strlen("qProcessInfoPID:")))
|
||||
return eServerPacketType_qProcessInfoPID;
|
||||
else if (packet_cstr[1] == 'f' && 0 == ::strncmp(packet_cstr, "qfProcessInfo", strlen("qfProcessInfo")))
|
||||
return eServerPacketType_qfProcessInfo;
|
||||
else if (packet_cstr[1] == 'U' && 0 == ::strncmp(packet_cstr, "qUserName:", strlen("qUserName:")))
|
||||
return eServerPacketType_qUserName;
|
||||
else if (packet_cstr[1] == 'G' && 0 == ::strncmp(packet_cstr, "qGroupName:", strlen("qGroupName:")))
|
||||
return eServerPacketType_qGroupName;
|
||||
else if (packet_cstr[1] == 's' && 0 == ::strcmp (packet_cstr, "qsProcessInfo"))
|
||||
return eServerPacketType_qsProcessInfo;
|
||||
break;
|
||||
}
|
||||
return eServerPacketType_unimplemented;
|
||||
|
|
|
@ -47,6 +47,11 @@ public:
|
|||
eServerPacketType_unimplemented,
|
||||
eServerPacketType_interrupt, // CTRL+c packet or "\x03"
|
||||
eServerPacketType_qHostInfo,
|
||||
eServerPacketType_qProcessInfoPID,
|
||||
eServerPacketType_qfProcessInfo,
|
||||
eServerPacketType_qsProcessInfo,
|
||||
eServerPacketType_qUserName,
|
||||
eServerPacketType_qGroupName,
|
||||
eServerPacketType_QStartNoAckMode
|
||||
};
|
||||
|
||||
|
|
|
@ -465,8 +465,11 @@
|
|||
);
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 131;
|
||||
"GCC_VERSION[sdk=iphoneos*][arch=*]" = 4.2;
|
||||
"GCC_VERSION[sdk=macosx*][arch=*]" = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SDKROOT = "";
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
VALID_ARCHS = "armv4t armv5 armv6 armv7 i386 ppc ppc64 ppc7400 ppc970 x86_64";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
@ -486,6 +489,7 @@
|
|||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SDKROOT = "";
|
||||
STRIPFLAGS = "-x";
|
||||
STRIP_STYLE = debugging;
|
||||
VALID_ARCHS = "armv4t armv5 armv6 armv7 i386 ppc ppc64 ppc7400 ppc970 x86_64";
|
||||
|
@ -506,6 +510,7 @@
|
|||
DEAD_CODE_STRIPPING = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SDKROOT = "";
|
||||
STRIPFLAGS = "-x";
|
||||
STRIP_STYLE = debugging;
|
||||
VALID_ARCHS = "armv4t armv5 armv6 armv7 i386 ppc ppc64 ppc7400 ppc970 x86_64";
|
||||
|
|
|
@ -90,6 +90,13 @@ DNBLogEnabled ()
|
|||
return g_log_callback != NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
DNBLogEnabledForAny (uint32_t mask)
|
||||
{
|
||||
if (g_log_callback)
|
||||
return (g_log_bits & mask) != 0;
|
||||
return false;
|
||||
}
|
||||
static inline void
|
||||
_DNBLogVAPrintf(uint32_t flags, const char *format, va_list args)
|
||||
{
|
||||
|
|
|
@ -51,6 +51,7 @@ uint32_t DNBLogSetLogMask (uint32_t mask) DNB_EXPORT;
|
|||
uint32_t DNBLogGetLogMask () DNB_EXPORT;
|
||||
void DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) DNB_EXPORT;
|
||||
bool DNBLogEnabled () DNB_EXPORT;
|
||||
bool DNBLogEnabledForAny (uint32_t mask) DNB_EXPORT;
|
||||
int DNBLogGetDebug () DNB_EXPORT;
|
||||
void DNBLogSetDebug (int g) DNB_EXPORT;
|
||||
int DNBLogGetVerbose () DNB_EXPORT;
|
||||
|
@ -60,7 +61,7 @@ void DNBLogSetVerbose (int g) DNB_EXPORT;
|
|||
#define DNBLogDebug(fmt, ...) do { if (DNBLogEnabled()) { _DNBLogDebug(fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogDebugVerbose(fmt, ...) do { if (DNBLogEnabled()) { _DNBLogDebugVerbose(fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogThreaded(fmt, ...) do { if (DNBLogEnabled()) { _DNBLogThreaded(fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogThreadedIf(mask, fmt, ...) do { if (DNBLogEnabled()) { _DNBLogThreadedIf(mask, fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogThreadedIf(mask, fmt, ...) do { if (DNBLogEnabledForAny(mask)) { _DNBLogThreaded(fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogError(fmt, ...) do { if (DNBLogEnabled()) { _DNBLogError(fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogFatalError(err, fmt, ...) do { if (DNBLogEnabled()) { _DNBLogFatalError(err, fmt, ## __VA_ARGS__); } } while (0)
|
||||
#define DNBLogVerbose(fmt, ...) do { if (DNBLogEnabled()) { _DNBLogVerbose(fmt, ## __VA_ARGS__); } } while (0)
|
||||
|
|
|
@ -93,6 +93,29 @@ static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
|
|||
#define MNEMONIC_STRING_SIZE 32
|
||||
#define OPERAND_STRING_SIZE 128
|
||||
|
||||
|
||||
void
|
||||
DNBArchMachARM::Initialize()
|
||||
{
|
||||
DNBArchPluginInfo arch_plugin_info =
|
||||
{
|
||||
CPU_TYPE_ARM,
|
||||
DNBArchMachARM::Create,
|
||||
DNBArchMachARM::GetRegisterSetInfo,
|
||||
DNBArchMachARM::SoftwareBreakpointOpcode
|
||||
};
|
||||
|
||||
// Register this arch plug-in with the main protocol class
|
||||
DNBArchProtocol::RegisterArchPlugin (arch_plugin_info);
|
||||
}
|
||||
|
||||
|
||||
DNBArchProtocol *
|
||||
DNBArchMachARM::Create (MachThread *thread)
|
||||
{
|
||||
return new DNBArchMachARM (thread);
|
||||
}
|
||||
|
||||
const uint8_t * const
|
||||
DNBArchMachARM::SoftwareBreakpointOpcode (nub_size_t byte_size)
|
||||
{
|
||||
|
@ -153,8 +176,29 @@ DNBArchMachARM::GetGPRState(bool force)
|
|||
mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT;
|
||||
kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
|
||||
uint32_t *r = &m_state.context.gpr.__r[0];
|
||||
DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x", m_thread->ThreadID(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT, kret,
|
||||
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15], r[16]);
|
||||
DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x",
|
||||
m_thread->ThreadID(),
|
||||
ARM_THREAD_STATE,
|
||||
ARM_THREAD_STATE_COUNT,
|
||||
kret,
|
||||
count,
|
||||
r[0],
|
||||
r[1],
|
||||
r[2],
|
||||
r[3],
|
||||
r[4],
|
||||
r[5],
|
||||
r[6],
|
||||
r[7],
|
||||
r[8],
|
||||
r[9],
|
||||
r[10],
|
||||
r[11],
|
||||
r[12],
|
||||
r[13],
|
||||
r[14],
|
||||
r[15],
|
||||
r[16]);
|
||||
m_state.SetError(set, Read, kret);
|
||||
return kret;
|
||||
}
|
||||
|
@ -170,6 +214,24 @@ DNBArchMachARM::GetVFPState(bool force)
|
|||
// Read the registers from our thread
|
||||
mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
|
||||
kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
|
||||
if (DNBLogEnabledForAny (LOG_THREAD))
|
||||
{
|
||||
uint32_t *r = &m_state.context.vfp.__r[0];
|
||||
DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
|
||||
m_thread->ThreadID(),
|
||||
ARM_THREAD_STATE,
|
||||
ARM_THREAD_STATE_COUNT,
|
||||
kret,
|
||||
count);
|
||||
DNBLogThreaded(" s0=%8.8x s1=%8.8x s2=%8.8x s3=%8.8x s4=%8.8x s5=%8.8x s6=%8.8x s7=%8.8x",r[ 0],r[ 1],r[ 2],r[ 3],r[ 4],r[ 5],r[ 6],r[ 7]);
|
||||
DNBLogThreaded(" s8=%8.8x s9=%8.8x s10=%8.8x s11=%8.8x s12=%8.8x s13=%8.8x s14=%8.8x s15=%8.8x",r[ 8],r[ 9],r[10],r[11],r[12],r[13],r[14],r[15]);
|
||||
DNBLogThreaded(" s16=%8.8x s17=%8.8x s18=%8.8x s19=%8.8x s20=%8.8x s21=%8.8x s22=%8.8x s23=%8.8x",r[16],r[17],r[18],r[19],r[20],r[21],r[22],r[23]);
|
||||
DNBLogThreaded(" s24=%8.8x s25=%8.8x s26=%8.8x s27=%8.8x s28=%8.8x s29=%8.8x s30=%8.8x s31=%8.8x",r[24],r[25],r[26],r[27],r[28],r[29],r[30],r[31]);
|
||||
DNBLogThreaded(" s32=%8.8x s33=%8.8x s34=%8.8x s35=%8.8x s36=%8.8x s37=%8.8x s38=%8.8x s39=%8.8x",r[32],r[33],r[34],r[35],r[36],r[37],r[38],r[39]);
|
||||
DNBLogThreaded(" s40=%8.8x s41=%8.8x s42=%8.8x s43=%8.8x s44=%8.8x s45=%8.8x s46=%8.8x s47=%8.8x",r[40],r[41],r[42],r[43],r[44],r[45],r[46],r[47]);
|
||||
DNBLogThreaded(" s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x s53=%8.8x s54=%8.8x s55=%8.8x",r[48],r[49],r[50],r[51],r[52],r[53],r[54],r[55]);
|
||||
DNBLogThreaded(" s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",r[56],r[57],r[58],r[59],r[60],r[61],r[62],r[63],r[64]);
|
||||
}
|
||||
m_state.SetError(set, Read, kret);
|
||||
return kret;
|
||||
}
|
||||
|
@ -2338,6 +2400,22 @@ enum
|
|||
vfp_s29,
|
||||
vfp_s30,
|
||||
vfp_s31,
|
||||
vfp_d0,
|
||||
vfp_d1,
|
||||
vfp_d2,
|
||||
vfp_d3,
|
||||
vfp_d4,
|
||||
vfp_d5,
|
||||
vfp_d6,
|
||||
vfp_d7,
|
||||
vfp_d8,
|
||||
vfp_d9,
|
||||
vfp_d10,
|
||||
vfp_d11,
|
||||
vfp_d12,
|
||||
vfp_d13,
|
||||
vfp_d14,
|
||||
vfp_d15,
|
||||
vfp_d16,
|
||||
vfp_d17,
|
||||
vfp_d18,
|
||||
|
@ -2445,8 +2523,8 @@ enum
|
|||
|
||||
#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx]))
|
||||
#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg))
|
||||
#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[idx]) + offsetof (DNBArchMachARM::Context, vfp))
|
||||
#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX (32) + (((idx) - 16) * 8))
|
||||
#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp))
|
||||
#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2))
|
||||
#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp))
|
||||
#define EXC_OFFSET(reg) (offsetof (DNBArchMachARM::EXC, __##reg) + offsetof (DNBArchMachARM::Context, exc))
|
||||
|
||||
|
@ -2456,9 +2534,11 @@ enum
|
|||
// sizes and offsets.
|
||||
#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
|
||||
#define DEFINE_GPR_NAME(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
|
||||
|
||||
#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, 4, Float, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
|
||||
#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, 8, Float, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
|
||||
//#define FLOAT_FORMAT Float
|
||||
#define FLOAT_FORMAT Hex
|
||||
#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
|
||||
//#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, gdb_d##idx }
|
||||
#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
|
||||
|
||||
// General purpose registers
|
||||
const DNBRegisterInfo
|
||||
|
@ -2519,6 +2599,22 @@ DNBArchMachARM::g_vfp_registers[] =
|
|||
DEFINE_VFP_S_IDX (29),
|
||||
DEFINE_VFP_S_IDX (30),
|
||||
DEFINE_VFP_S_IDX (31),
|
||||
DEFINE_VFP_D_IDX (0),
|
||||
DEFINE_VFP_D_IDX (1),
|
||||
DEFINE_VFP_D_IDX (2),
|
||||
DEFINE_VFP_D_IDX (3),
|
||||
DEFINE_VFP_D_IDX (4),
|
||||
DEFINE_VFP_D_IDX (5),
|
||||
DEFINE_VFP_D_IDX (6),
|
||||
DEFINE_VFP_D_IDX (7),
|
||||
DEFINE_VFP_D_IDX (8),
|
||||
DEFINE_VFP_D_IDX (9),
|
||||
DEFINE_VFP_D_IDX (10),
|
||||
DEFINE_VFP_D_IDX (11),
|
||||
DEFINE_VFP_D_IDX (12),
|
||||
DEFINE_VFP_D_IDX (13),
|
||||
DEFINE_VFP_D_IDX (14),
|
||||
DEFINE_VFP_D_IDX (15),
|
||||
DEFINE_VFP_D_IDX (16),
|
||||
DEFINE_VFP_D_IDX (17),
|
||||
DEFINE_VFP_D_IDX (18),
|
||||
|
@ -2535,7 +2631,7 @@ DNBArchMachARM::g_vfp_registers[] =
|
|||
DEFINE_VFP_D_IDX (29),
|
||||
DEFINE_VFP_D_IDX (30),
|
||||
DEFINE_VFP_D_IDX (31),
|
||||
{ e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, 4, Hex, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
|
||||
{ e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
|
||||
};
|
||||
|
||||
// Exception registers
|
||||
|
@ -2543,9 +2639,9 @@ DNBArchMachARM::g_vfp_registers[] =
|
|||
const DNBRegisterInfo
|
||||
DNBArchMachARM::g_exc_registers[] =
|
||||
{
|
||||
{ e_regSetVFP, exc_exception , "exception" , NULL, Uint, 4, Hex, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
|
||||
{ e_regSetVFP, exc_fsr , "fsr" , NULL, Uint, 4, Hex, EXC_OFFSET(fsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
|
||||
{ e_regSetVFP, exc_far , "far" , NULL, Uint, 4, Hex, EXC_OFFSET(far) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
|
||||
{ e_regSetVFP, exc_exception , "exception" , NULL, Uint, Hex, 4, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
|
||||
{ e_regSetVFP, exc_fsr , "fsr" , NULL, Uint, Hex, 4, EXC_OFFSET(fsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
|
||||
{ e_regSetVFP, exc_far , "far" , NULL, Uint, Hex, 4, EXC_OFFSET(far) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
|
||||
};
|
||||
|
||||
// Number of registers in each register set
|
||||
|
@ -2633,12 +2729,20 @@ DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
|
|||
break;
|
||||
|
||||
case e_regSetVFP:
|
||||
if (reg < 32)
|
||||
if (reg <= vfp_s31)
|
||||
{
|
||||
value->value.uint32 = m_state.context.vfp.__r[reg];
|
||||
return true;
|
||||
}
|
||||
else if (reg == 32)
|
||||
else if (reg <= vfp_d31)
|
||||
{
|
||||
uint32_t d_reg_idx = reg - vfp_d0;
|
||||
uint32_t s_reg_idx = d_reg_idx * 2;
|
||||
value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0];
|
||||
value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1];
|
||||
return true;
|
||||
}
|
||||
else if (reg == vfp_fpscr)
|
||||
{
|
||||
value->value.uint32 = m_state.context.vfp.__fpscr;
|
||||
return true;
|
||||
|
@ -2712,12 +2816,20 @@ DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value
|
|||
break;
|
||||
|
||||
case e_regSetVFP:
|
||||
if (reg < 32)
|
||||
if (reg <= vfp_s31)
|
||||
{
|
||||
m_state.context.vfp.__r[reg] = value->value.float64;
|
||||
m_state.context.vfp.__r[reg] = value->value.uint32;
|
||||
success = true;
|
||||
}
|
||||
else if (reg == 32)
|
||||
else if (reg <= vfp_d31)
|
||||
{
|
||||
uint32_t d_reg_idx = reg - vfp_d0;
|
||||
uint32_t s_reg_idx = d_reg_idx * 2;
|
||||
m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0];
|
||||
m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1];
|
||||
success = true;
|
||||
}
|
||||
else if (reg == vfp_fpscr)
|
||||
{
|
||||
m_state.context.vfp.__fpscr = value->value.uint32;
|
||||
success = true;
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
static void Initialize();
|
||||
static const DNBRegisterSetInfo *
|
||||
GetRegisterSetInfo(nub_size_t *num_reg_sets);
|
||||
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
virtual void ThreadWillResume();
|
||||
virtual bool ThreadDidStop();
|
||||
|
||||
static DNBArchProtocol *Create (MachThread *thread);
|
||||
static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size);
|
||||
static uint32_t GetCPUType();
|
||||
|
||||
|
|
|
@ -842,7 +842,7 @@ g_gdb_register_map_arm[] =
|
|||
{ 21, 12, "f5", {0}, k_zero_bytes, 0},
|
||||
{ 22, 12, "f6", {0}, k_zero_bytes, 0},
|
||||
{ 23, 12, "f7", {0}, k_zero_bytes, 0},
|
||||
{ 24, 4, "fps", {0}, NULL, 0},
|
||||
{ 24, 4, "fps", {0}, k_zero_bytes, 0},
|
||||
{ 25, 4,"cpsr", {0}, NULL, 1},
|
||||
{ 26, 4, "s0", {0}, NULL, 0},
|
||||
{ 27, 4, "s1", {0}, NULL, 0},
|
||||
|
@ -3351,30 +3351,3 @@ RNBRemote::HandlePacket_qHostInfo (const char *p)
|
|||
strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
|
||||
return SendPacket (strm.str());
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_qProcessInfo (const char *p)
|
||||
{
|
||||
return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_qfProcessInfoAll (const char *p)
|
||||
{
|
||||
return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_qfProcessInfoName (const char *p)
|
||||
{
|
||||
return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
|
||||
}
|
||||
|
||||
rnb_err_t
|
||||
RNBRemote::HandlePacket_qsProcessInfo (const char *p)
|
||||
{
|
||||
return RNBRemote::HandlePacket_UNIMPLEMENTED (p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -91,10 +91,6 @@ public:
|
|||
query_shlib_notify_info_addr, // 'qShlibInfoAddr'
|
||||
query_step_packet_supported, // 'qStepPacketSupported'
|
||||
query_host_info, // 'qHostInfo'
|
||||
platform_proc_info_for_pid, // 'qProcessInfo:<PID>' -- get process info for process by ID
|
||||
platform_proc_info_first_all, // 'qfProcessInfoAll' -- list all processes
|
||||
platform_proc_info_first_name, // 'qfProcessInfoName:<HEXNAME>' -- list all processes that match "name"
|
||||
platform_proc_info_subsequent, // 'qsProcessInfo' -- get subsequent matches for 'qfProcessInfo*' queries
|
||||
pass_signals_to_inferior, // 'QPassSignals'
|
||||
start_noack_mode, // 'QStartNoAckMode'
|
||||
prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
|
||||
|
@ -165,10 +161,6 @@ public:
|
|||
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
|
||||
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
|
||||
rnb_err_t HandlePacket_qHostInfo (const char *p);
|
||||
rnb_err_t HandlePacket_qProcessInfo (const char *p);
|
||||
rnb_err_t HandlePacket_qfProcessInfoAll (const char *p);
|
||||
rnb_err_t HandlePacket_qfProcessInfoName (const char *p);
|
||||
rnb_err_t HandlePacket_qsProcessInfo (const char *p);
|
||||
rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
|
||||
rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
|
||||
rnb_err_t HandlePacket_QSetLogging (const char *p);
|
||||
|
|
Loading…
Reference in New Issue