Add a way to load an image using a library name and list of paths.

This provides an efficient (at least on Posix platforms) way to offload to the
target process the search & loading of a library when all we have are the 
library name and a set of potential candidate locations.

<rdar://problem/40905971>

llvm-svn: 335912
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index f98670e..4d5ddc8 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -1187,6 +1187,57 @@
   return LLDB_INVALID_IMAGE_TOKEN;
 }
 
+uint32_t SBProcess::LoadImageUsingPaths(const lldb::SBFileSpec &image_spec,
+                                        SBStringList &paths,
+                                        lldb::SBFileSpec &loaded_path, 
+                                        lldb::SBError &error) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+  ProcessSP process_sp(GetSP());
+  if (process_sp) {
+    Process::StopLocker stop_locker;
+    if (stop_locker.TryLock(&process_sp->GetRunLock())) {
+      if (log)
+        log->Printf("SBProcess(%p)::LoadImageUsingPaths() => "
+                    "calling Platform::LoadImageUsingPaths for: %s",
+                    static_cast<void *>(process_sp.get()),
+                    image_spec.GetFilename());
+
+      std::lock_guard<std::recursive_mutex> guard(
+        process_sp->GetTarget().GetAPIMutex());
+      PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
+      size_t num_paths = paths.GetSize();
+      std::vector<std::string> paths_vec;
+      paths_vec.reserve(num_paths);
+      for (size_t i = 0; i < num_paths; i++)
+        paths_vec.push_back(paths.GetStringAtIndex(i));
+      FileSpec loaded_spec;
+      
+      uint32_t token = platform_sp->LoadImageUsingPaths(process_sp.get(),
+                                                        *image_spec, 
+                                                        paths_vec, 
+                                                        error.ref(), 
+                                                        &loaded_spec);
+       if (token != LLDB_INVALID_IMAGE_TOKEN)
+          loaded_path = loaded_spec;
+       return token;
+    } else {
+      if (log)
+        log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: "
+                    "process is running",
+                    static_cast<void *>(process_sp.get()));
+      error.SetErrorString("process is running");
+    }
+  } else { 
+    if (log)
+      log->Printf("SBProcess(%p)::LoadImageUsingPaths() => error: "
+                   "called with invalid process",
+                    static_cast<void *>(process_sp.get()));
+    error.SetErrorString("process is invalid");
+  }
+  
+  return LLDB_INVALID_IMAGE_TOKEN;
+}
+
 lldb::SBError SBProcess::UnloadImage(uint32_t image_token) {
   lldb::SBError sb_error;
   ProcessSP process_sp(GetSP());