uint32_t
GetNumSupportedHardwareWatchpoints (lldb::SBError &error) const;
+ //------------------------------------------------------------------
+ /// Load a shared library into this process.
+ ///
+ /// @param[in] remote_image_spec
+ /// The path for the shared library on the target what you want
+ /// to load.
+ ///
+ /// @param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying to load the shared library.
+ ///
+ /// @return
+ /// A token that represents the shared library that can be
+ /// later used to unload the shared library. A value of
+ /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+ /// library can't be opened.
+ //------------------------------------------------------------------
+ uint32_t
+ LoadImage (lldb::SBFileSpec &remote_image_spec, lldb::SBError &error);
+
+ //------------------------------------------------------------------
+ /// Load a shared library into this process.
+ ///
+ /// @param[in] local_image_spec
+ /// The file spec that points to the shared library that you
+ /// want to load if the library is located on the host. The
+ /// library will be copied over to the location specified by
+ /// remote_image_spec or into the current working directory with
+ /// the same filename if the remote_image_spec isn't specified.
+ ///
+ /// @param[in] remote_image_spec
+ /// If local_image_spec is specified then the location where the
+ /// library should be copied over from the host. If
+ /// local_image_spec isn't specified, then the path for the
+ /// shared library on the target what you want to load.
+ ///
+ /// @param[out] error
+ /// An error object that gets filled in with any errors that
+ /// might occur when trying to load the shared library.
+ ///
+ /// @return
+ /// A token that represents the shared library that can be
+ /// later used to unload the shared library. A value of
+ /// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+ /// library can't be opened.
+ //------------------------------------------------------------------
uint32_t
- LoadImage (lldb::SBFileSpec &image_spec, lldb::SBError &error);
+ LoadImage (const lldb::SBFileSpec &local_image_spec,
+ const lldb::SBFileSpec &remote_image_spec,
+ lldb::SBError &error);
lldb::SBError
UnloadImage (uint32_t image_token);
/// @param[in] process
/// The process to load the image.
///
- /// @param[in] image_spec
- /// The image file spec that points to the shared library that
- /// you want to load.
+ /// @param[in] local_file
+ /// The file spec that points to the shared library that you want
+ /// to load if the library is located on the host. The library will
+ /// be copied over to the location specified by remote_file or into
+ /// the current working directory with the same filename if the
+ /// remote_file isn't specified.
+ ///
+ /// @param[in] remote_file
+ /// If local_file is specified then the location where the library
+ /// should be copied over from the host. If local_file isn't
+ /// specified, then the path for the shared library on the target
+ /// what you want to load.
///
/// @param[out] error
/// An error object that gets filled in with any errors that
/// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
/// library can't be opened.
//------------------------------------------------------------------
- virtual uint32_t
+ uint32_t
LoadImage (lldb_private::Process* process,
- const lldb_private::FileSpec& image_spec,
+ const lldb_private::FileSpec& local_file,
+ const lldb_private::FileSpec& remote_file,
lldb_private::Error& error);
+ virtual uint32_t
+ DoLoadImage (lldb_private::Process* process,
+ const lldb_private::FileSpec& remote_file,
+ lldb_private::Error& error);
+
virtual Error
UnloadImage (lldb_private::Process* process, uint32_t image_token);
else:
dylibName = 'libloadunload_a.so'
- if lldb.remote_platform:
- # Don't use os.path.join as we have to use the path separator for the target
- dylibPath = shlib_dir + '/' + dylibName
- else:
- dylibPath = dylibName
-
# Make sure that a_function does not exist at this point.
self.expect("image lookup -n a_function", "a_function should not exist yet",
error=True, matching=False, patterns = ["1 match found"])
# Use lldb 'process load' to load the dylib.
- self.expect("process load %s" % dylibPath, "%s loaded correctly" % dylibPath,
- patterns = ['Loading "%s".*ok' % dylibPath,
+ self.expect("process load %s --install" % dylibName, "%s loaded correctly" % dylibName,
+ patterns = ['Loading "%s".*ok' % dylibName,
'Image [0-9]+ loaded'])
# Search for and match the "Image ([0-9]+) loaded" pattern.
}
uint32_t
-SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error)
+SBProcess::LoadImage (lldb::SBFileSpec &sb_remote_image_spec, lldb::SBError &sb_error)
+{
+ return LoadImage(SBFileSpec(), sb_remote_image_spec, sb_error);
+}
+
+uint32_t
+SBProcess::LoadImage (const lldb::SBFileSpec &sb_local_image_spec,
+ const lldb::SBFileSpec &sb_remote_image_spec,
+ lldb::SBError &sb_error)
{
ProcessSP process_sp(GetSP());
if (process_sp)
{
Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
- return platform_sp->LoadImage (process_sp.get(), *sb_image_spec, sb_error.ref());
+ return platform_sp->LoadImage (process_sp.get(),
+ *sb_local_image_spec,
+ *sb_remote_image_spec,
+ sb_error.ref());
}
else
{
class CommandObjectProcessLoad : public CommandObjectParsed
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options(interpreter)
+ {
+ // Keep default values of all options in one place: OptionParsingStarting ()
+ OptionParsingStarting ();
+ }
+
+ ~CommandOptions () override = default;
+
+ Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg) override
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option)
+ {
+ case 'i':
+ do_install = true;
+ if (option_arg && option_arg[0])
+ install_path.SetFile(option_arg, false);
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+ break;
+ }
+ return error;
+ }
+
+ void
+ OptionParsingStarting () override
+ {
+ do_install = false;
+ install_path.Clear();
+ }
+
+ const OptionDefinition*
+ GetDefinitions () override
+ {
+ 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.
+ bool do_install;
+ FileSpec install_path;
+ };
CommandObjectProcessLoad (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
eCommandRequiresProcess |
eCommandTryTargetAPILock |
eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ eCommandProcessMustBePaused ),
+ m_options (interpreter)
{
}
- ~CommandObjectProcessLoad () override
+ ~CommandObjectProcessLoad () override = default;
+
+ Options *
+ GetOptions () override
{
+ return &m_options;
}
protected:
Process *process = m_exe_ctx.GetProcessPtr();
const size_t argc = command.GetArgumentCount();
-
for (uint32_t i=0; i<argc; ++i)
{
Error error;
- const char *image_path = command.GetArgumentAtIndex(i);
- FileSpec image_spec (image_path, false);
PlatformSP platform = process->GetTarget().GetPlatform();
- platform->ResolveRemotePath(image_spec, image_spec);
- uint32_t image_token = platform->LoadImage(process, image_spec, error);
+ const char *image_path = command.GetArgumentAtIndex(i);
+ uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
+
+ if (!m_options.do_install)
+ {
+ FileSpec image_spec (image_path, false);
+ platform->ResolveRemotePath(image_spec, image_spec);
+ image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
+ }
+ else if (m_options.install_path)
+ {
+ FileSpec image_spec (image_path, true);
+ platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
+ image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
+ }
+ else
+ {
+ FileSpec image_spec (image_path, true);
+ image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
+ }
+
if (image_token != LLDB_INVALID_IMAGE_TOKEN)
{
- result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
+ result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
}
return result.Succeeded();
}
+
+ CommandOptions m_options;
};
+OptionDefinition
+CommandObjectProcessLoad::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory."},
+ { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+};
//-------------------------------------------------------------------------
// CommandObjectProcessUnload
}
uint32_t
-PlatformPOSIX::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error)
+PlatformPOSIX::DoLoadImage(lldb_private::Process* process,
+ const lldb_private::FileSpec& remote_file,
+ lldb_private::Error& error)
{
char path[PATH_MAX];
- image_spec.GetPath(path, sizeof(path));
+ remote_file.GetPath(path, sizeof(path));
StreamString expr;
expr.Printf(R"(
DisconnectRemote () override;
uint32_t
- LoadImage (lldb_private::Process* process,
- const lldb_private::FileSpec& image_spec,
- lldb_private::Error& error) override;
+ DoLoadImage (lldb_private::Process* process,
+ const lldb_private::FileSpec& remote_file,
+ lldb_private::Error& error) override;
lldb_private::Error
UnloadImage (lldb_private::Process* process, uint32_t image_token) override;
}
uint32_t
-Platform::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error)
+Platform::LoadImage(lldb_private::Process* process,
+ const lldb_private::FileSpec& local_file,
+ const lldb_private::FileSpec& remote_file,
+ lldb_private::Error& error)
+{
+ if (local_file && remote_file)
+ {
+ // Both local and remote file was specified. Install the local file to the given location.
+ if (IsRemote() || local_file != remote_file)
+ {
+ error = Install(local_file, remote_file);
+ if (error.Fail())
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+ return DoLoadImage(process, remote_file, error);
+ }
+
+ if (local_file)
+ {
+ // Only local file was specified. Install it to the current working directory.
+ FileSpec target_file = GetWorkingDirectory();
+ target_file.AppendPathComponent(local_file.GetFilename().AsCString());
+ if (IsRemote() || local_file != target_file)
+ {
+ error = Install(local_file, target_file);
+ if (error.Fail())
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+ return DoLoadImage(process, target_file, error);
+ }
+
+ if (remote_file)
+ {
+ // Only remote file was specified so we don't have to do any copying
+ return DoLoadImage(process, remote_file, error);
+ }
+
+ error.SetErrorString("Neither local nor remote file was specified");
+ return LLDB_INVALID_IMAGE_TOKEN;
+}
+
+uint32_t
+Platform::DoLoadImage (lldb_private::Process* process,
+ const lldb_private::FileSpec& remote_file,
+ lldb_private::Error& error)
{
error.SetErrorString("LoadImage is not supported on the current platform");
return LLDB_INVALID_IMAGE_TOKEN;
Error
Platform::UnloadImage(lldb_private::Process* process, uint32_t image_token)
{
- return Error("UnLoadImage is not supported on the current platform");
+ return Error("UnloadImage is not supported on the current platform");
}