2011-01-21 22:02:52 +00:00
|
|
|
//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
|
|
|
|
|
//
|
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
|
//
|
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2011-02-05 02:56:16 +00:00
|
|
|
#include "lldb/Core/EmulateInstruction.h"
|
2011-01-21 22:02:52 +00:00
|
|
|
|
2016-03-03 00:51:40 +00:00
|
|
|
// C Includes
|
|
|
|
|
// C++ Includes
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
// Other libraries and framework includes
|
|
|
|
|
// Project includes
|
2011-04-26 04:39:08 +00:00
|
|
|
#include "lldb/Core/Address.h"
|
2011-01-21 22:02:52 +00:00
|
|
|
#include "lldb/Core/DataExtractor.h"
|
2011-04-05 18:46:00 +00:00
|
|
|
#include "lldb/Core/Error.h"
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
#include "lldb/Core/PluginManager.h"
|
2011-05-09 20:18:18 +00:00
|
|
|
#include "lldb/Core/RegisterValue.h"
|
|
|
|
|
#include "lldb/Core/StreamFile.h"
|
2011-01-21 22:02:52 +00:00
|
|
|
#include "lldb/Core/StreamString.h"
|
2011-02-01 01:31:41 +00:00
|
|
|
#include "lldb/Host/Endian.h"
|
2011-04-26 23:48:45 +00:00
|
|
|
#include "lldb/Symbol/UnwindPlan.h"
|
2011-04-05 18:46:00 +00:00
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
|
#include "lldb/Target/RegisterContext.h"
|
2011-04-26 04:39:08 +00:00
|
|
|
#include "lldb/Target/Target.h"
|
2011-04-05 18:46:00 +00:00
|
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
|
|
2011-01-21 22:02:52 +00:00
|
|
|
using namespace lldb;
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
EmulateInstruction*
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
EmulateInstructionCreateInstance create_callback = nullptr;
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
if (plugin_name)
|
|
|
|
|
{
|
2013-05-10 21:47:16 +00:00
|
|
|
ConstString const_plugin_name (plugin_name);
|
|
|
|
|
create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
if (create_callback)
|
|
|
|
|
{
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
|
2011-04-05 18:46:00 +00:00
|
|
|
if (emulate_insn_ptr)
|
|
|
|
|
return emulate_insn_ptr;
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx)
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
{
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
|
2011-04-05 18:46:00 +00:00
|
|
|
if (emulate_insn_ptr)
|
|
|
|
|
return emulate_insn_ptr;
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
2016-03-03 00:51:40 +00:00
|
|
|
return nullptr;
|
Modified the PluginManager to be ready for loading plug-ins from a system
LLDB plugin directory and a user LLDB plugin directory. We currently still
need to work out at what layer the plug-ins will be, but at least we are
prepared for plug-ins. Plug-ins will attempt to be loaded from the
"/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Plugins"
folder, and from the "~/Library/Application Support/LLDB/Plugins" folder on
MacOSX. Each plugin will be scanned for:
extern "C" bool LLDBPluginInitialize(void);
extern "C" void LLDBPluginTerminate(void);
If at least LLDBPluginInitialize is found, the plug-in will be loaded. The
LLDBPluginInitialize function returns a bool that indicates if the plug-in
should stay loaded or not (plug-ins might check the current OS, current
hardware, or anything else and determine they don't want to run on the current
host). The plug-in is uniqued by path and added to a static loaded plug-in
map. The plug-in scanning happens during "lldb_private::Initialize()" which
calls to the PluginManager::Initialize() function. Likewise with termination
lldb_private::Terminate() calls PluginManager::Terminate(). The paths for the
plug-in directories is fetched through new Host calls:
bool Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec);
bool Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec);
This way linux and other systems can define their own appropriate locations
for plug-ins to be loaded.
To allow dynamic shared library loading, the Host layer has also been modified
to include shared library open, close and get symbol:
static void *
Host::DynamicLibraryOpen (const FileSpec &file_spec,
Error &error);
static Error
Host::DynamicLibraryClose (void *dynamic_library_handle);
static void *
Host::DynamicLibraryGetSymbol (void *dynamic_library_handle,
const char *symbol_name,
Error &error);
lldb_private::FileSpec also has been modified to support directory enumeration
in an attempt to abstract the directory enumeration into one spot in the code.
The directory enumertion function is static and takes a callback:
typedef enum EnumerateDirectoryResult
{
eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory
eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not
eEnumerateDirectoryResultExit, // Exit from the current directory at the current level.
eEnumerateDirectoryResultQuit // Stop directory enumerations at any level
};
typedef FileSpec::EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton,
FileSpec::FileType file_type,
const FileSpec &spec);
static FileSpec::EnumerateDirectoryResult
FileSpec::EnumerateDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
This allow clients to specify the directory to search, and specifies if only
files, directories or other (pipe, symlink, fifo, etc) files will cause the
callback to be called. The callback also gets to return with the action that
should be performed after this directory entry. eEnumerateDirectoryResultNext
specifies to continue enumerating through a directory with the next entry.
eEnumerateDirectoryResultEnter specifies to recurse down into a directory
entry, or if the file is not a directory or symlink/alias to a directory, then
just iterate to the next entry. eEnumerateDirectoryResultExit specifies to
exit the current directory and skip any entries that might be remaining, yet
continue enumerating to the next entry in the parent directory. And finally
eEnumerateDirectoryResultQuit means to abort all directory enumerations at
all levels.
Modified the Declaration class to not include column information currently
since we don't have any compilers that currently support column based
declaration information. Columns support can be re-enabled with the
additions of a #define.
Added the ability to find an EmulateInstruction plug-in given a target triple
and optional plug-in name in the plug-in manager.
Fixed a few cases where opendir/readdir was being used, but yet not closedir
was being used. Soon these will be deprecated in favor of the new directory
enumeration call that was added to the FileSpec class.
llvm-svn: 124716
2011-02-02 02:24:04 +00:00
|
|
|
}
|
2011-01-21 22:02:52 +00:00
|
|
|
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
|
2016-03-03 00:51:40 +00:00
|
|
|
m_arch(arch),
|
|
|
|
|
m_baton(nullptr),
|
|
|
|
|
m_read_mem_callback(&ReadMemoryDefault),
|
|
|
|
|
m_write_mem_callback(&WriteMemoryDefault),
|
|
|
|
|
m_read_reg_callback(&ReadRegisterDefault),
|
|
|
|
|
m_write_reg_callback(&WriteRegisterDefault),
|
|
|
|
|
m_addr(LLDB_INVALID_ADDRESS)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
::memset (&m_opcode, 0, sizeof (m_opcode));
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-09 20:18:18 +00:00
|
|
|
bool
|
|
|
|
|
EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
|
|
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (m_read_reg_callback != nullptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
return m_read_reg_callback (this, m_baton, reg_info, reg_value);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2014-07-02 09:51:28 +00:00
|
|
|
EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
|
2011-04-26 23:48:45 +00:00
|
|
|
{
|
|
|
|
|
RegisterInfo reg_info;
|
|
|
|
|
if (GetRegisterInfo(reg_kind, reg_num, reg_info))
|
2011-05-09 20:18:18 +00:00
|
|
|
return ReadRegister (®_info, reg_value);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t
|
2014-07-02 09:51:28 +00:00
|
|
|
EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
|
2011-05-09 20:18:18 +00:00
|
|
|
uint32_t reg_num,
|
|
|
|
|
uint64_t fail_value,
|
|
|
|
|
bool *success_ptr)
|
|
|
|
|
{
|
|
|
|
|
RegisterValue reg_value;
|
|
|
|
|
if (ReadRegister (reg_kind, reg_num, reg_value))
|
|
|
|
|
return reg_value.GetAsUInt64(fail_value, success_ptr);
|
2011-04-26 23:48:45 +00:00
|
|
|
if (success_ptr)
|
|
|
|
|
*success_ptr = false;
|
|
|
|
|
return fail_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
|
|
|
|
|
uint64_t fail_value,
|
|
|
|
|
bool *success_ptr)
|
2011-01-21 22:02:52 +00:00
|
|
|
{
|
2011-05-09 20:18:18 +00:00
|
|
|
RegisterValue reg_value;
|
|
|
|
|
if (ReadRegister (reg_info, reg_value))
|
|
|
|
|
return reg_value.GetAsUInt64(fail_value, success_ptr);
|
2011-01-21 22:02:52 +00:00
|
|
|
if (success_ptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
*success_ptr = false;
|
|
|
|
|
return fail_value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
EmulateInstruction::WriteRegister (const Context &context,
|
|
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
const RegisterValue& reg_value)
|
|
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (m_write_reg_callback != nullptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
EmulateInstruction::WriteRegister (const Context &context,
|
2014-07-02 09:51:28 +00:00
|
|
|
lldb::RegisterKind reg_kind,
|
2011-05-09 20:18:18 +00:00
|
|
|
uint32_t reg_num,
|
|
|
|
|
const RegisterValue& reg_value)
|
|
|
|
|
{
|
|
|
|
|
RegisterInfo reg_info;
|
|
|
|
|
if (GetRegisterInfo(reg_kind, reg_num, reg_info))
|
|
|
|
|
return WriteRegister (context, ®_info, reg_value);
|
|
|
|
|
return false;
|
2011-01-21 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::WriteRegisterUnsigned (const Context &context,
|
2014-07-02 09:51:28 +00:00
|
|
|
lldb::RegisterKind reg_kind,
|
2011-05-09 20:18:18 +00:00
|
|
|
uint32_t reg_num,
|
|
|
|
|
uint64_t uint_value)
|
2011-01-21 22:02:52 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
RegisterInfo reg_info;
|
|
|
|
|
if (GetRegisterInfo(reg_kind, reg_num, reg_info))
|
2011-05-09 20:18:18 +00:00
|
|
|
{
|
|
|
|
|
RegisterValue reg_value;
|
|
|
|
|
if (reg_value.SetUInt(uint_value, reg_info.byte_size))
|
|
|
|
|
return WriteRegister (context, ®_info, reg_value);
|
|
|
|
|
}
|
2011-04-26 23:48:45 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::WriteRegisterUnsigned (const Context &context,
|
|
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
uint64_t uint_value)
|
|
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (reg_info != nullptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
{
|
|
|
|
|
RegisterValue reg_value;
|
|
|
|
|
if (reg_value.SetUInt(uint_value, reg_info->byte_size))
|
|
|
|
|
return WriteRegister (context, reg_info, reg_value);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
|
EmulateInstruction::ReadMemory (const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
void *dst,
|
|
|
|
|
size_t dst_len)
|
2011-04-26 23:48:45 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (m_read_mem_callback != nullptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
|
|
|
|
|
return false;
|
2011-01-21 22:02:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
|
|
|
|
|
{
|
|
|
|
|
uint64_t uval64 = 0;
|
|
|
|
|
bool success = false;
|
|
|
|
|
if (byte_size <= 8)
|
|
|
|
|
{
|
|
|
|
|
uint8_t buf[sizeof(uint64_t)];
|
2011-04-26 04:39:08 +00:00
|
|
|
size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
|
2011-01-21 22:02:52 +00:00
|
|
|
if (bytes_read == byte_size)
|
|
|
|
|
{
|
2013-01-25 18:06:21 +00:00
|
|
|
lldb::offset_t offset = 0;
|
2011-04-26 04:39:08 +00:00
|
|
|
DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
|
2011-01-21 22:02:52 +00:00
|
|
|
uval64 = data.GetMaxU64 (&offset, byte_size);
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success_ptr)
|
|
|
|
|
*success_ptr = success;
|
|
|
|
|
|
|
|
|
|
if (!success)
|
|
|
|
|
uval64 = fail_value;
|
|
|
|
|
return uval64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
EmulateInstruction::WriteMemoryUnsigned (const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
uint64_t uval,
|
|
|
|
|
size_t uval_byte_size)
|
|
|
|
|
{
|
|
|
|
|
StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
|
|
|
|
|
strm.PutMaxHex64 (uval, uval_byte_size);
|
|
|
|
|
|
2011-04-26 04:39:08 +00:00
|
|
|
size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
|
2016-03-03 00:51:40 +00:00
|
|
|
return (bytes_written == uval_byte_size);
|
2011-01-21 22:02:52 +00:00
|
|
|
}
|
2011-04-05 18:46:00 +00:00
|
|
|
|
2011-05-09 20:18:18 +00:00
|
|
|
bool
|
|
|
|
|
EmulateInstruction::WriteMemory (const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
const void *src,
|
|
|
|
|
size_t src_len)
|
|
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (m_write_mem_callback != nullptr)
|
2011-05-09 20:18:18 +00:00
|
|
|
return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-05 18:46:00 +00:00
|
|
|
void
|
|
|
|
|
EmulateInstruction::SetBaton (void *baton)
|
|
|
|
|
{
|
|
|
|
|
m_baton = baton;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
|
|
|
|
|
WriteMemoryCallback write_mem_callback,
|
|
|
|
|
ReadRegisterCallback read_reg_callback,
|
|
|
|
|
WriteRegisterCallback write_reg_callback)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
m_read_mem_callback = read_mem_callback;
|
|
|
|
|
m_write_mem_callback = write_mem_callback;
|
|
|
|
|
m_read_reg_callback = read_reg_callback;
|
|
|
|
|
m_write_reg_callback = write_reg_callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
m_read_mem_callback = read_mem_callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
m_write_mem_callback = write_mem_callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
m_read_reg_callback = read_reg_callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
m_write_reg_callback = write_reg_callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Read & Write Memory and Registers callback functions.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
size_t
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 20:18:48 +00:00
|
|
|
const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
void *dst,
|
2012-02-18 05:35:26 +00:00
|
|
|
size_t dst_len)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (baton == nullptr || dst == nullptr || dst_len == 0)
|
2011-04-05 18:46:00 +00:00
|
|
|
return 0;
|
2012-02-18 05:35:26 +00:00
|
|
|
|
2013-11-04 09:33:30 +00:00
|
|
|
StackFrame *frame = (StackFrame *) baton;
|
2011-04-05 20:18:48 +00:00
|
|
|
|
2012-02-18 05:35:26 +00:00
|
|
|
ProcessSP process_sp (frame->CalculateProcess());
|
|
|
|
|
if (process_sp)
|
|
|
|
|
{
|
|
|
|
|
Error error;
|
|
|
|
|
return process_sp->ReadMemory (addr, dst, dst_len, error);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 20:18:48 +00:00
|
|
|
const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
2012-02-18 05:35:26 +00:00
|
|
|
const void *src,
|
|
|
|
|
size_t src_len)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (baton == nullptr || src == nullptr || src_len == 0)
|
2011-04-05 18:46:00 +00:00
|
|
|
return 0;
|
|
|
|
|
|
2013-11-04 09:33:30 +00:00
|
|
|
StackFrame *frame = (StackFrame *) baton;
|
2011-04-05 20:18:48 +00:00
|
|
|
|
2012-02-18 05:35:26 +00:00
|
|
|
ProcessSP process_sp (frame->CalculateProcess());
|
|
|
|
|
if (process_sp)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2012-02-18 05:35:26 +00:00
|
|
|
Error error;
|
|
|
|
|
return process_sp->WriteMemory (addr, src, src_len, error);
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-05-09 20:18:18 +00:00
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
RegisterValue ®_value)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (baton == nullptr)
|
2011-04-05 18:46:00 +00:00
|
|
|
return false;
|
|
|
|
|
|
2013-11-04 09:33:30 +00:00
|
|
|
StackFrame *frame = (StackFrame *) baton;
|
2011-05-09 20:18:18 +00:00
|
|
|
return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 20:18:48 +00:00
|
|
|
const Context &context,
|
2011-05-09 20:18:18 +00:00
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
const RegisterValue ®_value)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (baton == nullptr)
|
2011-04-05 20:18:48 +00:00
|
|
|
return false;
|
|
|
|
|
|
2013-11-04 09:33:30 +00:00
|
|
|
StackFrame *frame = (StackFrame *) baton;
|
2011-05-09 20:18:18 +00:00
|
|
|
return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 18:46:00 +00:00
|
|
|
const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
void *dst,
|
|
|
|
|
size_t length)
|
|
|
|
|
{
|
2011-05-11 18:39:18 +00:00
|
|
|
StreamFile strm (stdout, false);
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
|
2011-05-11 18:39:18 +00:00
|
|
|
context.Dump (strm, instruction);
|
|
|
|
|
strm.EOL();
|
2011-04-05 18:46:00 +00:00
|
|
|
*((uint64_t *) dst) = 0xdeadbeef;
|
|
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 18:46:00 +00:00
|
|
|
const Context &context,
|
|
|
|
|
lldb::addr_t addr,
|
|
|
|
|
const void *dst,
|
|
|
|
|
size_t length)
|
|
|
|
|
{
|
2011-05-11 18:39:18 +00:00
|
|
|
StreamFile strm (stdout, false);
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
|
2011-05-11 18:39:18 +00:00
|
|
|
context.Dump (strm, instruction);
|
|
|
|
|
strm.EOL();
|
2011-04-05 18:46:00 +00:00
|
|
|
return length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-05-09 20:18:18 +00:00
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
RegisterValue ®_value)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-05-11 18:39:18 +00:00
|
|
|
StreamFile strm (stdout, false);
|
|
|
|
|
strm.Printf (" Read Register (%s)\n", reg_info->name);
|
2014-07-02 09:51:28 +00:00
|
|
|
lldb::RegisterKind reg_kind;
|
|
|
|
|
uint32_t reg_num;
|
2011-04-26 23:48:45 +00:00
|
|
|
if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
|
2011-05-09 20:18:18 +00:00
|
|
|
reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
|
2011-04-26 23:48:45 +00:00
|
|
|
else
|
2011-05-09 20:18:18 +00:00
|
|
|
reg_value.SetUInt64(0);
|
2011-04-26 23:48:45 +00:00
|
|
|
|
2011-04-05 18:46:00 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2011-04-26 04:39:08 +00:00
|
|
|
EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
|
|
|
|
|
void *baton,
|
2011-04-05 18:46:00 +00:00
|
|
|
const Context &context,
|
2011-05-09 20:18:18 +00:00
|
|
|
const RegisterInfo *reg_info,
|
|
|
|
|
const RegisterValue ®_value)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-05-09 20:18:18 +00:00
|
|
|
StreamFile strm (stdout, false);
|
|
|
|
|
strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
|
2011-05-15 04:12:07 +00:00
|
|
|
reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
|
2011-05-09 20:18:18 +00:00
|
|
|
strm.PutCString (", context = ");
|
2011-05-11 18:39:18 +00:00
|
|
|
context.Dump (strm, instruction);
|
|
|
|
|
strm.EOL();
|
2011-04-05 18:46:00 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-05-11 18:39:18 +00:00
|
|
|
EmulateInstruction::Context::Dump (Stream &strm,
|
2011-04-26 23:48:45 +00:00
|
|
|
EmulateInstruction *instruction) const
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
switch (type)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
|
|
|
|
case eContextReadOpcode:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("reading opcode");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextImmediate:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("immediate");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextPushRegisterOnStack:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("push register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextPopRegisterOffStack:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("pop register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextAdjustStackPointer:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("adjust sp");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
2011-06-04 01:26:29 +00:00
|
|
|
case eContextSetFramePointer:
|
|
|
|
|
strm.PutCString ("set frame pointer");
|
|
|
|
|
break;
|
|
|
|
|
|
2011-04-05 18:46:00 +00:00
|
|
|
case eContextAdjustBaseRegister:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("adjusting (writing value back to) a base register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextRegisterPlusOffset:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("register + offset");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextRegisterStore:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("store register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextRegisterLoad:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("load register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextRelativeBranchImmediate:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("relative branch immediate");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextAbsoluteBranchRegister:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("absolute branch register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextSupervisorCall:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("supervisor call");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextTableBranchReadMemory:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("table branch read memory");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextWriteRegisterRandomBits:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("write random bits to a register");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextWriteMemoryRandomBits:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("write random bits to a memory address");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
2011-04-26 23:48:45 +00:00
|
|
|
case eContextArithmetic:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("arithmetic");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eContextReturnFromException:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("return from exception");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.PutCString ("unrecognized context.");
|
2011-04-05 18:46:00 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-26 23:48:45 +00:00
|
|
|
switch (info_type)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
case eInfoTypeRegisterPlusOffset:
|
2016-03-03 00:51:40 +00:00
|
|
|
strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
|
|
|
|
|
info.RegisterPlusOffset.reg.name,
|
|
|
|
|
info.RegisterPlusOffset.signed_offset);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeRegisterPlusIndirectOffset:
|
2016-03-03 00:51:40 +00:00
|
|
|
strm.Printf(" (reg_plus_reg = %s + %s)",
|
|
|
|
|
info.RegisterPlusIndirectOffset.base_reg.name,
|
|
|
|
|
info.RegisterPlusIndirectOffset.offset_reg.name);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
2011-04-05 18:46:00 +00:00
|
|
|
|
2011-04-26 23:48:45 +00:00
|
|
|
case eInfoTypeRegisterToRegisterPlusOffset:
|
2016-03-03 00:51:40 +00:00
|
|
|
strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
|
|
|
|
|
info.RegisterToRegisterPlusOffset.base_reg.name,
|
|
|
|
|
info.RegisterToRegisterPlusOffset.offset,
|
|
|
|
|
info.RegisterToRegisterPlusOffset.data_reg.name);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeRegisterToRegisterPlusIndirectOffset:
|
2016-03-03 00:51:40 +00:00
|
|
|
strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
|
|
|
|
|
info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
|
|
|
|
|
info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
|
|
|
|
|
info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeRegisterRegisterOperands:
|
2016-03-03 00:51:40 +00:00
|
|
|
strm.Printf(" (register to register binary op: %s and %s)",
|
|
|
|
|
info.RegisterRegisterOperands.operand1.name,
|
|
|
|
|
info.RegisterRegisterOperands.operand2.name);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
2011-04-05 18:46:00 +00:00
|
|
|
|
2011-04-26 23:48:45 +00:00
|
|
|
case eInfoTypeOffset:
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeRegister:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.Printf (" (reg = %s)", info.reg.name);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeImmediate:
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
|
2011-05-11 18:39:18 +00:00
|
|
|
info.unsigned_immediate,
|
|
|
|
|
info.unsigned_immediate);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeImmediateSigned:
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
|
2011-05-11 18:39:18 +00:00
|
|
|
info.signed_immediate,
|
|
|
|
|
info.signed_immediate);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeAddress:
|
2012-11-29 21:49:15 +00:00
|
|
|
strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeISAAndImmediate:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
|
|
|
|
|
info.ISAAndImmediate.isa,
|
|
|
|
|
info.ISAAndImmediate.unsigned_data32,
|
|
|
|
|
info.ISAAndImmediate.unsigned_data32);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeISAAndImmediateSigned:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
|
|
|
|
|
info.ISAAndImmediateSigned.isa,
|
|
|
|
|
info.ISAAndImmediateSigned.signed_data32,
|
|
|
|
|
info.ISAAndImmediateSigned.signed_data32);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeISA:
|
2011-05-11 18:39:18 +00:00
|
|
|
strm.Printf (" (isa = %u)", info.isa);
|
2011-04-26 23:48:45 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case eInfoTypeNoArgs:
|
|
|
|
|
break;
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-26 04:39:08 +00:00
|
|
|
bool
|
|
|
|
|
EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-04-26 04:39:08 +00:00
|
|
|
m_opcode = opcode;
|
2011-04-29 22:50:31 +00:00
|
|
|
m_addr = LLDB_INVALID_ADDRESS;
|
2011-04-26 04:39:08 +00:00
|
|
|
if (inst_addr.IsValid())
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2016-03-03 00:51:40 +00:00
|
|
|
if (target != nullptr)
|
2011-04-29 22:50:31 +00:00
|
|
|
m_addr = inst_addr.GetLoadAddress (target);
|
|
|
|
|
if (m_addr == LLDB_INVALID_ADDRESS)
|
|
|
|
|
m_addr = inst_addr.GetFileAddress ();
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
2011-04-26 04:39:08 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-26 23:48:45 +00:00
|
|
|
bool
|
2011-05-09 20:18:18 +00:00
|
|
|
EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
|
2014-07-02 09:51:28 +00:00
|
|
|
lldb::RegisterKind ®_kind,
|
2011-04-26 23:48:45 +00:00
|
|
|
uint32_t ®_num)
|
2011-04-26 04:39:08 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
// Generic and DWARF should be the two most popular register kinds when
|
|
|
|
|
// emulating instructions since they are the most platform agnostic...
|
2011-05-09 20:18:18 +00:00
|
|
|
reg_num = reg_info->kinds[eRegisterKindGeneric];
|
2011-04-26 23:48:45 +00:00
|
|
|
if (reg_num != LLDB_INVALID_REGNUM)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
reg_kind = eRegisterKindGeneric;
|
|
|
|
|
return true;
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
2011-04-26 04:39:08 +00:00
|
|
|
|
2011-05-09 20:18:18 +00:00
|
|
|
reg_num = reg_info->kinds[eRegisterKindDWARF];
|
2011-04-26 23:48:45 +00:00
|
|
|
if (reg_num != LLDB_INVALID_REGNUM)
|
2011-04-05 18:46:00 +00:00
|
|
|
{
|
2011-04-26 23:48:45 +00:00
|
|
|
reg_kind = eRegisterKindDWARF;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2011-04-26 04:39:08 +00:00
|
|
|
|
2011-05-09 20:18:18 +00:00
|
|
|
reg_num = reg_info->kinds[eRegisterKindLLDB];
|
2011-04-26 23:48:45 +00:00
|
|
|
if (reg_num != LLDB_INVALID_REGNUM)
|
|
|
|
|
{
|
|
|
|
|
reg_kind = eRegisterKindLLDB;
|
|
|
|
|
return true;
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|
2011-04-26 23:48:45 +00:00
|
|
|
|
2015-08-15 01:21:01 +00:00
|
|
|
reg_num = reg_info->kinds[eRegisterKindEHFrame];
|
2011-04-26 23:48:45 +00:00
|
|
|
if (reg_num != LLDB_INVALID_REGNUM)
|
|
|
|
|
{
|
2015-08-15 01:21:01 +00:00
|
|
|
reg_kind = eRegisterKindEHFrame;
|
2011-04-26 23:48:45 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-15 23:20:34 +00:00
|
|
|
reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
|
2011-04-26 23:48:45 +00:00
|
|
|
if (reg_num != LLDB_INVALID_REGNUM)
|
|
|
|
|
{
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-15 23:20:34 +00:00
|
|
|
reg_kind = eRegisterKindProcessPlugin;
|
2011-04-26 23:48:45 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
|
EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info)
|
|
|
|
|
{
|
2014-07-02 09:51:28 +00:00
|
|
|
lldb::RegisterKind reg_kind;
|
|
|
|
|
uint32_t reg_num;
|
2011-05-09 20:18:18 +00:00
|
|
|
if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num))
|
2011-04-26 23:48:45 +00:00
|
|
|
return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
|
|
|
|
|
return LLDB_INVALID_REGNUM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
|
|
|
|
|
{
|
|
|
|
|
unwind_plan.Clear();
|
|
|
|
|
return false;
|
2011-04-05 18:46:00 +00:00
|
|
|
}
|