svn commit: r317959 - in vendor/lldb/dist: include/lldb/API include/lldb/Core include/lldb/Expression include/lldb/Host include/lldb/Host/common include/lldb/Target include/lldb/Utility packages/Py...

Dimitry Andric dim at FreeBSD.org
Mon May 8 17:13:58 UTC 2017


Author: dim
Date: Mon May  8 17:13:54 2017
New Revision: 317959
URL: https://svnweb.freebsd.org/changeset/base/317959

Log:
  Vendor import of lldb trunk r302418:
  https://llvm.org/svn/llvm-project/lldb/trunk@302418

Added:
  vendor/lldb/dist/unittests/Host/MainLoopTest.cpp   (contents, props changed)
Modified:
  vendor/lldb/dist/include/lldb/API/SBAddress.h
  vendor/lldb/dist/include/lldb/API/SBInstruction.h
  vendor/lldb/dist/include/lldb/API/SBInstructionList.h
  vendor/lldb/dist/include/lldb/Core/Disassembler.h
  vendor/lldb/dist/include/lldb/Expression/Expression.h
  vendor/lldb/dist/include/lldb/Host/MainLoop.h
  vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h
  vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h
  vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h
  vendor/lldb/dist/include/lldb/Utility/TaskPool.h
  vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py
  vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py
  vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
  vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py
  vendor/lldb/dist/scripts/interface/SBInstruction.i
  vendor/lldb/dist/scripts/interface/SBInstructionList.i
  vendor/lldb/dist/source/API/SBAddress.cpp
  vendor/lldb/dist/source/API/SBInstruction.cpp
  vendor/lldb/dist/source/API/SBInstructionList.cpp
  vendor/lldb/dist/source/API/SBProcess.cpp
  vendor/lldb/dist/source/Core/Disassembler.cpp
  vendor/lldb/dist/source/Host/common/Editline.cpp
  vendor/lldb/dist/source/Host/common/MainLoop.cpp
  vendor/lldb/dist/source/Host/common/UDPSocket.cpp
  vendor/lldb/dist/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
  vendor/lldb/dist/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
  vendor/lldb/dist/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  vendor/lldb/dist/source/Target/ThreadPlanCallUserExpression.cpp
  vendor/lldb/dist/source/Utility/TaskPool.cpp
  vendor/lldb/dist/unittests/Host/CMakeLists.txt
  vendor/lldb/dist/unittests/Utility/TaskPoolTest.cpp
  vendor/lldb/dist/www/lldb-gdb.html

Modified: vendor/lldb/dist/include/lldb/API/SBAddress.h
==============================================================================
--- vendor/lldb/dist/include/lldb/API/SBAddress.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/API/SBAddress.h	Mon May  8 17:13:54 2017	(r317959)
@@ -103,6 +103,8 @@ protected:
 
   const lldb_private::Address *operator->() const;
 
+  friend bool operator==(const SBAddress &lhs, const SBAddress &rhs);
+
   lldb_private::Address *get();
 
   lldb_private::Address &ref();
@@ -117,6 +119,8 @@ private:
   std::unique_ptr<lldb_private::Address> m_opaque_ap;
 };
 
+bool operator==(const SBAddress &lhs, const SBAddress &rhs);
+
 } // namespace lldb
 
 #endif // LLDB_SBAddress_h_

Modified: vendor/lldb/dist/include/lldb/API/SBInstruction.h
==============================================================================
--- vendor/lldb/dist/include/lldb/API/SBInstruction.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/API/SBInstruction.h	Mon May  8 17:13:54 2017	(r317959)
@@ -53,6 +53,8 @@ public:
 
   bool HasDelaySlot();
 
+  bool CanSetBreakpoint();
+
   void Print(FILE *out);
 
   bool GetDescription(lldb::SBStream &description);

Modified: vendor/lldb/dist/include/lldb/API/SBInstructionList.h
==============================================================================
--- vendor/lldb/dist/include/lldb/API/SBInstructionList.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/API/SBInstructionList.h	Mon May  8 17:13:54 2017	(r317959)
@@ -32,6 +32,15 @@ public:
 
   lldb::SBInstruction GetInstructionAtIndex(uint32_t idx);
 
+  // ----------------------------------------------------------------------
+  // Returns the number of instructions between the start and end address.
+  // If canSetBreakpoint is true then the count will be the number of 
+  // instructions on which a breakpoint can be set.
+  // ----------------------------------------------------------------------
+  size_t GetInstructionsCount(const SBAddress &start,
+                              const SBAddress &end,
+                              bool canSetBreakpoint = false);                                   
+
   void Clear();
 
   void AppendInstruction(lldb::SBInstruction inst);

Modified: vendor/lldb/dist/include/lldb/Core/Disassembler.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Core/Disassembler.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Core/Disassembler.h	Mon May  8 17:13:54 2017	(r317959)
@@ -173,6 +173,8 @@ public:
 
   virtual bool HasDelaySlot();
 
+  bool CanSetBreakpoint ();
+
   virtual size_t Decode(const Disassembler &disassembler,
                         const DataExtractor &data,
                         lldb::offset_t data_offset) = 0;

Modified: vendor/lldb/dist/include/lldb/Expression/Expression.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Expression/Expression.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Expression/Expression.h	Mon May  8 17:13:54 2017	(r317959)
@@ -99,6 +99,16 @@ public:
   //------------------------------------------------------------------
   lldb::addr_t StartAddress() { return m_jit_start_addr; }
 
+  //------------------------------------------------------------------
+  /// Called to notify the expression that it is about to be executed.
+  //------------------------------------------------------------------
+  virtual void WillStartExecuting() {}
+
+  //------------------------------------------------------------------
+  /// Called to notify the expression that its execution has finished.
+  //------------------------------------------------------------------
+  virtual void DidFinishExecuting() {}
+
   virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; }
 
 protected:

Modified: vendor/lldb/dist/include/lldb/Host/MainLoop.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Host/MainLoop.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Host/MainLoop.h	Mon May  8 17:13:54 2017	(r317959)
@@ -42,6 +42,7 @@ private:
 public:
   typedef std::unique_ptr<SignalHandle> SignalHandleUP;
 
+  MainLoop();
   ~MainLoop() override;
 
   ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
@@ -71,6 +72,9 @@ protected:
   void UnregisterSignal(int signo);
 
 private:
+  void ProcessReadObject(IOObject::WaitableHandle handle);
+  void ProcessSignal(int signo);
+
   class SignalHandle {
   public:
     ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); }
@@ -97,6 +101,9 @@ private:
 
   llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
   llvm::DenseMap<int, SignalInfo> m_signals;
+#if HAVE_SYS_EVENT_H
+  int m_kqueue;
+#endif
   bool m_terminate_request : 1;
 };
 

Modified: vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Host/common/UDPSocket.h	Mon May  8 17:13:54 2017	(r317959)
@@ -21,15 +21,13 @@ public:
                        Socket *&socket);
 
 private:
-  UDPSocket(NativeSocket socket, const UDPSocket &listen_socket);
+  UDPSocket(NativeSocket socket);
 
   size_t Send(const void *buf, const size_t num_bytes) override;
   Error Connect(llvm::StringRef name) override;
   Error Listen(llvm::StringRef name, int backlog) override;
   Error Accept(Socket *&socket) override;
 
-  Error CreateSocket();
-
   SocketAddress m_sockaddr;
 };
 }

Modified: vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Target/ThreadPlanCallFunction.h	Mon May  8 17:13:54 2017	(r317959)
@@ -117,7 +117,7 @@ protected:
                         lldb::addr_t &start_load_addr,
                         lldb::addr_t &function_load_addr);
 
-  void DoTakedown(bool success);
+  virtual void DoTakedown(bool success);
 
   void SetBreakpoints();
 

Modified: vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Target/ThreadPlanCallUserExpression.h	Mon May  8 17:13:54 2017	(r317959)
@@ -35,6 +35,8 @@ public:
 
   void GetDescription(Stream *s, lldb::DescriptionLevel level) override;
 
+  void DidPush() override;
+
   void WillPop() override;
 
   lldb::StopInfoSP GetRealStopInfo() override;
@@ -48,6 +50,7 @@ public:
   }
 
 protected:
+  void DoTakedown(bool success) override;
 private:
   lldb::UserExpressionSP
       m_user_expression_sp; // This is currently just used to ensure the

Modified: vendor/lldb/dist/include/lldb/Utility/TaskPool.h
==============================================================================
--- vendor/lldb/dist/include/lldb/Utility/TaskPool.h	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/include/lldb/Utility/TaskPool.h	Mon May  8 17:13:54 2017	(r317959)
@@ -53,50 +53,6 @@ private:
   static void AddTaskImpl(std::function<void()> &&task_fn);
 };
 
-// Wrapper class around the global TaskPool implementation to make it possible
-// to create a set of
-// tasks and then wait for the tasks to be completed by the
-// WaitForNextCompletedTask call. This
-// class should be used when WaitForNextCompletedTask is needed because this
-// class add no other
-// extra functionality to the TaskPool class and it have a very minor
-// performance overhead.
-template <typename T> // The return type of the tasks what will be added to this
-                      // task runner
-                      class TaskRunner {
-public:
-  // Add a task to the task runner what will also add the task to the global
-  // TaskPool. The
-  // function doesn't return the std::future for the task because it will be
-  // supplied by the
-  // WaitForNextCompletedTask after the task is completed.
-  template <typename F, typename... Args> void AddTask(F &&f, Args &&... args);
-
-  // Wait for the next task in this task runner to finish and then return the
-  // std::future what
-  // belongs to the finished task. If there is no task in this task runner
-  // (neither pending nor
-  // comleted) then this function will return an invalid future. Usually this
-  // function should be
-  // called in a loop processing the results of the tasks until it returns an
-  // invalid std::future
-  // what means that all task in this task runner is completed.
-  std::future<T> WaitForNextCompletedTask();
-
-  // Convenience method to wait for all task in this TaskRunner to finish. Do
-  // NOT use this class
-  // just because of this method. Use TaskPool instead and wait for each
-  // std::future returned by
-  // AddTask in a loop.
-  void WaitForAllTasks();
-
-private:
-  std::list<std::future<T>> m_ready;
-  std::list<std::future<T>> m_pending;
-  std::mutex m_mutex;
-  std::condition_variable m_cv;
-};
-
 template <typename F, typename... Args>
 std::future<typename std::result_of<F(Args...)>::type>
 TaskPool::AddTask(F &&f, Args &&... args) {
@@ -126,64 +82,10 @@ template <> struct TaskPool::RunTaskImpl
   static void Run() {}
 };
 
-template <typename T>
-template <typename F, typename... Args>
-void TaskRunner<T>::AddTask(F &&f, Args &&... args) {
-  std::unique_lock<std::mutex> lock(m_mutex);
-  auto it = m_pending.emplace(m_pending.end());
-  *it = std::move(TaskPool::AddTask(
-      [this, it](F f, Args... args) {
-        T &&r = f(std::forward<Args>(args)...);
-
-        std::unique_lock<std::mutex> lock(this->m_mutex);
-        this->m_ready.splice(this->m_ready.end(), this->m_pending, it);
-        lock.unlock();
-
-        this->m_cv.notify_one();
-        return r;
-      },
-      std::forward<F>(f), std::forward<Args>(args)...));
-}
-
-template <>
-template <typename F, typename... Args>
-void TaskRunner<void>::AddTask(F &&f, Args &&... args) {
-  std::unique_lock<std::mutex> lock(m_mutex);
-  auto it = m_pending.emplace(m_pending.end());
-  *it = std::move(TaskPool::AddTask(
-      [this, it](F f, Args... args) {
-        f(std::forward<Args>(args)...);
-
-        std::unique_lock<std::mutex> lock(this->m_mutex);
-        this->m_ready.emplace_back(std::move(*it));
-        this->m_pending.erase(it);
-        lock.unlock();
-
-        this->m_cv.notify_one();
-      },
-      std::forward<F>(f), std::forward<Args>(args)...));
-}
-
-template <typename T> std::future<T> TaskRunner<T>::WaitForNextCompletedTask() {
-  std::unique_lock<std::mutex> lock(m_mutex);
-  if (m_ready.empty() && m_pending.empty())
-    return std::future<T>(); // No more tasks
-
-  if (m_ready.empty())
-    m_cv.wait(lock, [this]() { return !this->m_ready.empty(); });
-
-  std::future<T> res = std::move(m_ready.front());
-  m_ready.pop_front();
-
-  lock.unlock();
-  res.wait();
-
-  return std::move(res);
-}
-
-template <typename T> void TaskRunner<T>::WaitForAllTasks() {
-  while (WaitForNextCompletedTask().valid())
-    ;
-}
+// Run 'func' on every value from begin .. end-1.  Each worker will grab
+// 'batch_size' numbers at a time to work on, so for very fast functions, batch
+// should be large enough to avoid too much cache line contention.
+void TaskMapOverInt(size_t begin, size_t end,
+                    std::function<void(size_t)> const &func);
 
 #endif // #ifndef utility_TaskPool_h_

Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py
==============================================================================
--- vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/packages/Python/lldbsuite/test/expression_command/multiline/TestMultilineExpressions.py	Mon May  8 17:13:54 2017	(r317959)
@@ -12,6 +12,7 @@ from lldbsuite.test import lldbutil
 class MultilineExpressionsTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
 
     def setUp(self):
         # Call super's setUp().
@@ -60,3 +61,30 @@ class MultilineExpressionsTestCase(TestB
         child.expect_exact(prompt)
         self.expect(child.before, exe=False,
                     patterns=['= 5'])
+
+    @skipIfRemote
+    @expectedFailureAll(
+        oslist=["windows"],
+        bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+    def test_empty_list(self):
+        """Test printing an empty list of expressions"""
+        import pexpect
+        prompt = "(lldb) "
+
+        # So that the child gets torn down after the test
+        self.child = pexpect.spawn(
+                "%s %s" %
+                (lldbtest_config.lldbExec, self.lldbOption))
+        child = self.child
+
+        # Turn on logging for what the child sends back.
+        if self.TraceOn():
+            child.logfile_read = sys.stdout
+
+        # We expect a prompt, then send "print" to start a list of expressions,
+        # then an empty line. We expect a prompt back.
+        child.expect_exact(prompt)
+        child.sendline("print")
+        child.expect_exact('1:')
+        child.sendline("")
+        child.expect_exact(prompt)

Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py
==============================================================================
--- vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py	Mon May  8 17:13:54 2017	(r317959)
@@ -62,12 +62,11 @@ class StepOverBreakpointsTestCase(TestBa
         instructions = function.GetInstructions(self.target)
         addr_1 = self.breakpoint1.GetLocationAtIndex(0).GetAddress()
         addr_4 = self.breakpoint4.GetLocationAtIndex(0).GetAddress()
-        for i in range(instructions.GetSize()) :
-            addr = instructions.GetInstructionAtIndex(i).GetAddress()
-            if (addr == addr_1) : index_1 = i
-            if (addr == addr_4) : index_4 = i 
 
-        steps_expected = index_4 - index_1
+        # if third argument is true then the count will be the number of
+        # instructions on which a breakpoint can be set.
+        # start = addr_1, end = addr_4, canSetBreakpoint = True
+        steps_expected = instructions.GetInstructionsCount(addr_1, addr_4, True)
         step_count = 0
         # Step from breakpoint_1 to breakpoint_4
         while True:

Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
==============================================================================
--- vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py	Mon May  8 17:13:54 2017	(r317959)
@@ -171,17 +171,45 @@ class ReturnValueTestCase(TestBase):
         #self.return_and_test_struct_value ("return_one_int_one_double_packed")
         self.return_and_test_struct_value("return_one_int_one_long")
 
-        # icc and gcc don't support this extension.
-        if self.getCompiler().endswith('clang'):
-            self.return_and_test_struct_value("return_vector_size_float32_8")
-            self.return_and_test_struct_value("return_vector_size_float32_16")
-            self.return_and_test_struct_value("return_vector_size_float32_32")
-            self.return_and_test_struct_value(
-                "return_ext_vector_size_float32_2")
-            self.return_and_test_struct_value(
-                "return_ext_vector_size_float32_4")
-            self.return_and_test_struct_value(
-                "return_ext_vector_size_float32_8")
+    @expectedFailureAll(oslist=["freebsd"], archs=["i386"])
+    @expectedFailureAll(oslist=["macosx"], archs=["i386"], bugnumber="<rdar://problem/28719652>")
+    @expectedFailureAll(
+        oslist=["linux"],
+        compiler="clang",
+        compiler_version=[
+            "<=",
+            "3.6"],
+        archs=["i386"])
+    @expectedFailureAll(
+        bugnumber="llvm.org/pr25785",
+        hostoslist=["windows"],
+        compiler="gcc",
+        archs=["i386"],
+        triple='.*-android')
+    @expectedFailureAll(compiler=["gcc"], archs=["x86_64", "i386"])
+    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778")
+    def test_vector_values(self):
+        self.build()
+        exe = os.path.join(os.getcwd(), "a.out")
+        error = lldb.SBError()
+
+        self.target = self.dbg.CreateTarget(exe)
+        self.assertTrue(self.target, VALID_TARGET)
+
+        main_bktp = self.target.BreakpointCreateByName("main", exe)
+        self.assertTrue(main_bktp, VALID_BREAKPOINT)
+
+        self.process = self.target.LaunchSimple(
+            None, None, self.get_process_working_directory())
+        self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(
+            self.process, main_bktp)), 1)
+
+        self.return_and_test_struct_value("return_vector_size_float32_8")
+        self.return_and_test_struct_value("return_vector_size_float32_16")
+        self.return_and_test_struct_value("return_vector_size_float32_32")
+        self.return_and_test_struct_value("return_ext_vector_size_float32_2")
+        self.return_and_test_struct_value("return_ext_vector_size_float32_4")
+        self.return_and_test_struct_value("return_ext_vector_size_float32_8")
 
     def return_and_test_struct_value(self, func_name):
         """Pass in the name of the function to return from - takes in value, returns value."""

Modified: vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py
==============================================================================
--- vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteHostInfo.py	Mon May  8 17:13:54 2017	(r317959)
@@ -14,6 +14,7 @@ class TestGdbRemoteHostInfo(GdbRemoteTes
     mydir = TestBase.compute_mydir(__file__)
 
     KNOWN_HOST_INFO_KEYS = set([
+        "arch",
         "cputype",
         "cpusubtype",
         "distribution_id",

Modified: vendor/lldb/dist/scripts/interface/SBInstruction.i
==============================================================================
--- vendor/lldb/dist/scripts/interface/SBInstruction.i	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/scripts/interface/SBInstruction.i	Mon May  8 17:13:54 2017	(r317959)
@@ -54,6 +54,9 @@ public:
     bool
     HasDelaySlot ();
 
+    bool
+    CanSetBreakpoint ();
+
     void
     Print (FILE *out);
 

Modified: vendor/lldb/dist/scripts/interface/SBInstructionList.i
==============================================================================
--- vendor/lldb/dist/scripts/interface/SBInstructionList.i	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/scripts/interface/SBInstructionList.i	Mon May  8 17:13:54 2017	(r317959)
@@ -44,6 +44,9 @@ public:
     lldb::SBInstruction
     GetInstructionAtIndex (uint32_t idx);
 
+    size_t GetInstructionsCount(const SBAddress &start, const SBAddress &end,
+                                bool canSetBreakpoint);
+
     void
     Clear ();
 

Modified: vendor/lldb/dist/source/API/SBAddress.cpp
==============================================================================
--- vendor/lldb/dist/source/API/SBAddress.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/API/SBAddress.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -55,6 +55,12 @@ const SBAddress &SBAddress::operator=(co
   return *this;
 }
 
+bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) {
+  if (lhs.IsValid() && rhs.IsValid())
+    return lhs.ref() == rhs.ref();
+  return false;
+}
+
 bool SBAddress::IsValid() const {
   return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
 }

Modified: vendor/lldb/dist/source/API/SBInstruction.cpp
==============================================================================
--- vendor/lldb/dist/source/API/SBInstruction.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/API/SBInstruction.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -176,6 +176,13 @@ bool SBInstruction::HasDelaySlot() {
   return false;
 }
 
+bool SBInstruction::CanSetBreakpoint () {
+  lldb::InstructionSP inst_sp(GetOpaque());
+  if (inst_sp)
+    return inst_sp->CanSetBreakpoint();
+  return false;
+}
+
 lldb::InstructionSP SBInstruction::GetOpaque() {
   if (m_opaque_sp)
     return m_opaque_sp->GetSP();

Modified: vendor/lldb/dist/source/API/SBInstructionList.cpp
==============================================================================
--- vendor/lldb/dist/source/API/SBInstructionList.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/API/SBInstructionList.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -9,6 +9,7 @@
 
 #include "lldb/API/SBInstructionList.h"
 #include "lldb/API/SBInstruction.h"
+#include "lldb/API/SBAddress.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Module.h"
@@ -49,6 +50,31 @@ SBInstruction SBInstructionList::GetInst
   return inst;
 }
 
+size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,
+                                              const SBAddress &end, 
+                                              bool canSetBreakpoint) {
+  size_t num_instructions = GetSize();
+  size_t i = 0;
+  SBAddress addr;
+  size_t lower_index = 0;
+  size_t upper_index = 0;
+  size_t instructions_to_skip = 0;
+  for (i = 0; i < num_instructions; ++i) {
+    addr = GetInstructionAtIndex(i).GetAddress();
+    if (start == addr)
+      lower_index = i;
+    if (end == addr)
+      upper_index = i;
+  }
+  if (canSetBreakpoint)
+    for (i = lower_index; i <= upper_index; ++i) {
+      SBInstruction insn = GetInstructionAtIndex(i);
+      if (!insn.CanSetBreakpoint())
+        ++instructions_to_skip;
+    }
+  return upper_index - lower_index - instructions_to_skip;
+}
+
 void SBInstructionList::Clear() { m_opaque_sp.reset(); }
 
 void SBInstructionList::AppendInstruction(SBInstruction insn) {}

Modified: vendor/lldb/dist/source/API/SBProcess.cpp
==============================================================================
--- vendor/lldb/dist/source/API/SBProcess.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/API/SBProcess.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -1157,22 +1157,34 @@ uint32_t SBProcess::LoadImage(lldb::SBFi
 uint32_t SBProcess::LoadImage(const lldb::SBFileSpec &sb_local_image_spec,
                               const lldb::SBFileSpec &sb_remote_image_spec,
                               lldb::SBError &sb_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)::LoadImage() => calling Platform::LoadImage"
+                    "for: %s",
+                    static_cast<void *>(process_sp.get()),
+                    sb_local_image_spec.GetFilename());
+
       std::lock_guard<std::recursive_mutex> guard(
-          process_sp->GetTarget().GetAPIMutex());
+        process_sp->GetTarget().GetAPIMutex());
       PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
       return platform_sp->LoadImage(process_sp.get(), *sb_local_image_spec,
                                     *sb_remote_image_spec, sb_error.ref());
     } else {
-      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
       if (log)
         log->Printf("SBProcess(%p)::LoadImage() => error: process is running",
                     static_cast<void *>(process_sp.get()));
       sb_error.SetErrorString("process is running");
     }
+  } else { 
+    if (log)
+      log->Printf("SBProcess(%p)::LoadImage() => error: called with invalid"
+                    " process",
+                    static_cast<void *>(process_sp.get()));
+    sb_error.SetErrorString("process is invalid");
   }
   return LLDB_INVALID_IMAGE_TOKEN;
 }

Modified: vendor/lldb/dist/source/Core/Disassembler.cpp
==============================================================================
--- vendor/lldb/dist/source/Core/Disassembler.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/Core/Disassembler.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -759,6 +759,10 @@ bool Instruction::DumpEmulation(const Ar
   return false;
 }
 
+bool Instruction::CanSetBreakpoint () {
+  return !HasDelaySlot();
+}
+
 bool Instruction::HasDelaySlot() {
   // Default is false.
   return false;

Modified: vendor/lldb/dist/source/Host/common/Editline.cpp
==============================================================================
--- vendor/lldb/dist/source/Host/common/Editline.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/Host/common/Editline.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -367,7 +367,7 @@ void Editline::MoveCursor(CursorLocation
   if (to == CursorLocation::EditingCursor) {
     toColumn =
         editline_cursor_position - (editline_cursor_row * m_terminal_width) + 1;
-  } else if (to == CursorLocation::BlockEnd) {
+  } else if (to == CursorLocation::BlockEnd && !m_input_lines.empty()) {
     toColumn =
         ((m_input_lines[m_input_lines.size() - 1].length() + GetPromptWidth()) %
          80) +

Modified: vendor/lldb/dist/source/Host/common/MainLoop.cpp
==============================================================================
--- vendor/lldb/dist/source/Host/common/MainLoop.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/Host/common/MainLoop.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -18,6 +18,11 @@
 #include <vector>
 #include <time.h>
 
+// Multiplexing is implemented using kqueue on systems that support it (BSD
+// variants including OSX). On linux we use ppoll, while android uses pselect
+// (ppoll is present but not implemented properly). On windows we use WSApoll
+// (which does not support signals).
+
 #if HAVE_SYS_EVENT_H
 #include <sys/event.h>
 #elif defined(LLVM_ON_WIN32)
@@ -65,92 +70,72 @@ static void SignalHandler(int signo, sig
 
 class MainLoop::RunImpl {
 public:
-  // TODO: Use llvm::Expected<T>
-  static std::unique_ptr<RunImpl> Create(MainLoop &loop, Error &error);
-  ~RunImpl();
+  RunImpl(MainLoop &loop);
+  ~RunImpl() = default;
 
   Error Poll();
-
-  template <typename F> void ForEachReadFD(F &&f);
-  template <typename F> void ForEachSignal(F &&f);
+  void ProcessEvents();
 
 private:
   MainLoop &loop;
 
 #if HAVE_SYS_EVENT_H
-  int queue_id;
   std::vector<struct kevent> in_events;
   struct kevent out_events[4];
   int num_events = -1;
 
-  RunImpl(MainLoop &loop, int queue_id) : loop(loop), queue_id(queue_id) {
-    in_events.reserve(loop.m_read_fds.size() + loop.m_signals.size());
-  }
 #else
-  std::vector<int> signals;
 #ifdef FORCE_PSELECT
   fd_set read_fd_set;
 #else
   std::vector<struct pollfd> read_fds;
 #endif
 
-  RunImpl(MainLoop &loop) : loop(loop) {
-    signals.reserve(loop.m_signals.size());
-  }
-
   sigset_t get_sigmask();
 #endif
 };
 
 #if HAVE_SYS_EVENT_H
-MainLoop::RunImpl::~RunImpl() {
-  int r = close(queue_id);
-  assert(r == 0);
-  (void)r;
-}
-std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
-{
-  error.Clear();
-  int queue_id = kqueue();
-  if(queue_id < 0) {
-    error = Error(errno, eErrorTypePOSIX);
-    return nullptr;
-  }
-  return std::unique_ptr<RunImpl>(new RunImpl(loop, queue_id));
+MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
+  in_events.reserve(loop.m_read_fds.size());
 }
 
 Error MainLoop::RunImpl::Poll() {
-  in_events.resize(loop.m_read_fds.size() + loop.m_signals.size());
+  in_events.resize(loop.m_read_fds.size());
   unsigned i = 0;
   for (auto &fd : loop.m_read_fds)
     EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
 
-  for (const auto &sig : loop.m_signals)
-    EV_SET(&in_events[i++], sig.first, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
-
-  num_events = kevent(queue_id, in_events.data(), in_events.size(), out_events,
-                      llvm::array_lengthof(out_events), nullptr);
+  num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
+                      out_events, llvm::array_lengthof(out_events), nullptr);
 
   if (num_events < 0)
     return Error("kevent() failed with error %d\n", num_events);
   return Error();
 }
 
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+void MainLoop::RunImpl::ProcessEvents() {
   assert(num_events >= 0);
   for (int i = 0; i < num_events; ++i) {
-    f(out_events[i].ident);
     if (loop.m_terminate_request)
       return;
+    switch (out_events[i].filter) {
+    case EVFILT_READ:
+      loop.ProcessReadObject(out_events[i].ident);
+      break;
+    case EVFILT_SIGNAL:
+      loop.ProcessSignal(out_events[i].ident);
+      break;
+    default:
+      llvm_unreachable("Unknown event");
+    }
   }
 }
-template <typename F> void MainLoop::RunImpl::ForEachSignal(F && f) {}
 #else
-MainLoop::RunImpl::~RunImpl() {}
-std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
-{
-  error.Clear();
-  return std::unique_ptr<RunImpl>(new RunImpl(loop));
+MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
+#ifndef FORCE_PSELECT
+  read_fds.reserve(loop.m_read_fds.size());
+#endif
 }
 
 sigset_t MainLoop::RunImpl::get_sigmask() {
@@ -162,18 +147,14 @@ sigset_t MainLoop::RunImpl::get_sigmask(
   assert(ret == 0);
   (void) ret;
 
-  for (const auto &sig : loop.m_signals) {
-    signals.push_back(sig.first);
+  for (const auto &sig : loop.m_signals)
     sigdelset(&sigmask, sig.first);
-  }
   return sigmask;
 #endif
 }
 
 #ifdef FORCE_PSELECT
 Error MainLoop::RunImpl::Poll() {
-  signals.clear();
-
   FD_ZERO(&read_fd_set);
   int nfds = 0;
   for (const auto &fd : loop.m_read_fds) {
@@ -188,20 +169,8 @@ Error MainLoop::RunImpl::Poll() {
 
   return Error();
 }
-
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
-  for (const auto &fd : loop.m_read_fds) {
-    if(!FD_ISSET(fd.first, &read_fd_set))
-      continue;
-
-    f(fd.first);
-    if (loop.m_terminate_request)
-      return;
-  }
-}
 #else
 Error MainLoop::RunImpl::Poll() {
-  signals.clear();
   read_fds.clear();
 
   sigset_t sigmask = get_sigmask();
@@ -220,33 +189,47 @@ Error MainLoop::RunImpl::Poll() {
 
   return Error();
 }
+#endif
 
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+void MainLoop::RunImpl::ProcessEvents() {
+#ifdef FORCE_PSELECT
+  for (const auto &fd : loop.m_read_fds) {
+    if (!FD_ISSET(fd.first, &read_fd_set))
+      continue;
+    IOObject::WaitableHandle handle = fd.first;
+#else
   for (const auto &fd : read_fds) {
     if ((fd.revents & POLLIN) == 0)
       continue;
-
-    f(fd.fd);
+    IOObject::WaitableHandle handle = fd.fd;
+#endif
     if (loop.m_terminate_request)
       return;
-  }
-}
-#endif
 
-template <typename F> void MainLoop::RunImpl::ForEachSignal(F &&f) {
-  for (int sig : signals) {
-    if (g_signal_flags[sig] == 0)
-      continue; // No signal
-    g_signal_flags[sig] = 0;
-    f(sig);
+    loop.ProcessReadObject(handle);
+  }
 
+  for (const auto &entry : loop.m_signals) {
     if (loop.m_terminate_request)
       return;
+    if (g_signal_flags[entry.first] == 0)
+      continue; // No signal
+    g_signal_flags[entry.first] = 0;
+    loop.ProcessSignal(entry.first);
   }
 }
 #endif
 
+MainLoop::MainLoop() {
+#if HAVE_SYS_EVENT_H
+  m_kqueue = kqueue();
+  assert(m_kqueue >= 0);
+#endif
+}
 MainLoop::~MainLoop() {
+#if HAVE_SYS_EVENT_H
+  close(m_kqueue);
+#endif
   assert(m_read_fds.size() == 0);
   assert(m_signals.size() == 0);
 }
@@ -298,24 +281,30 @@ MainLoop::RegisterSignal(int signo, cons
   new_action.sa_flags = SA_SIGINFO;
   sigemptyset(&new_action.sa_mask);
   sigaddset(&new_action.sa_mask, signo);
-
   sigset_t old_set;
-  if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) {
-    error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n",
-                                   ret);
-    return nullptr;
-  }
 
-  info.was_blocked = sigismember(&old_set, signo);
-  if (sigaction(signo, &new_action, &info.old_action) == -1) {
-    error.SetErrorToErrno();
-    if (!info.was_blocked)
-      pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr);
-    return nullptr;
-  }
+  g_signal_flags[signo] = 0;
+
+  // Even if using kqueue, the signal handler will still be invoked, so it's
+  // important to replace it with our "bening" handler.
+  int ret = sigaction(signo, &new_action, &info.old_action);
+  assert(ret == 0 && "sigaction failed");
+
+#if HAVE_SYS_EVENT_H
+  struct kevent ev;
+  EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
+  ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
+  assert(ret == 0);
+#endif
 
+  // If we're using kqueue, the signal needs to be unblocked in order to recieve
+  // it. If using pselect/ppoll, we need to block it, and later unblock it as a
+  // part of the system call.
+  ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
+                        &new_action.sa_mask, &old_set);
+  assert(ret == 0 && "pthread_sigmask failed");
+  info.was_blocked = sigismember(&old_set, signo);
   m_signals.insert({signo, info});
-  g_signal_flags[signo] = 0;
 
   return SignalHandleUP(new SignalHandle(*this, signo));
 #endif
@@ -331,7 +320,6 @@ void MainLoop::UnregisterSignal(int sign
 #if SIGNAL_POLLING_UNSUPPORTED
   Error("Signal polling is not supported on this platform.");
 #else
-  // We undo the actions of RegisterSignal on a best-effort basis.
   auto it = m_signals.find(signo);
   assert(it != m_signals.end());
 
@@ -340,8 +328,17 @@ void MainLoop::UnregisterSignal(int sign
   sigset_t set;
   sigemptyset(&set);
   sigaddset(&set, signo);
-  pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set,
-                  nullptr);
+  int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
+                            &set, nullptr);
+  assert(ret == 0);
+  (void)ret;
+
+#if HAVE_SYS_EVENT_H
+  struct kevent ev;
+  EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0);
+  ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
+  assert(ret == 0);
+#endif
 
   m_signals.erase(it);
 #endif
@@ -351,32 +348,31 @@ Error MainLoop::Run() {
   m_terminate_request = false;
   
   Error error;
-  auto impl = RunImpl::Create(*this, error);
-  if (!impl)
-    return error;
+  RunImpl impl(*this);
 
   // run until termination or until we run out of things to listen to
   while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
 
-    error = impl->Poll();
+    error = impl.Poll();
     if (error.Fail())
       return error;
 
-    impl->ForEachSignal([&](int sig) {
-      auto it = m_signals.find(sig);
-      if (it != m_signals.end())
-        it->second.callback(*this); // Do the work
-    });
-    if (m_terminate_request)
-      return Error();
+    impl.ProcessEvents();
 
-    impl->ForEachReadFD([&](int fd) {
-      auto it = m_read_fds.find(fd);
-      if (it != m_read_fds.end())
-        it->second(*this); // Do the work
-    });
     if (m_terminate_request)
       return Error();
   }
   return Error();
 }
+
+void MainLoop::ProcessSignal(int signo) {
+  auto it = m_signals.find(signo);
+  if (it != m_signals.end())
+    it->second.callback(*this); // Do the work
+}
+
+void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) {
+  auto it = m_read_fds.find(handle);
+  if (it != m_read_fds.end())
+    it->second(*this); // Do the work
+}

Modified: vendor/lldb/dist/source/Host/common/UDPSocket.cpp
==============================================================================
--- vendor/lldb/dist/source/Host/common/UDPSocket.cpp	Mon May  8 17:13:50 2017	(r317958)
+++ vendor/lldb/dist/source/Host/common/UDPSocket.cpp	Mon May  8 17:13:54 2017	(r317959)
@@ -28,31 +28,41 @@ const int kDomain = AF_INET;
 const int kType = SOCK_DGRAM;
 
 static const char *g_not_supported_error = "Not supported";
-} // namespace
-
-UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit)
-    : Socket(ProtocolUdp, should_close, child_processes_inherit) {}
+}
 
-UDPSocket::UDPSocket(NativeSocket socket, const UDPSocket &listen_socket)
-    : Socket(ProtocolUdp, listen_socket.m_should_close_fd,
-             listen_socket.m_child_processes_inherit) {
+UDPSocket::UDPSocket(NativeSocket socket) : Socket(ProtocolUdp, true, true) {
   m_socket = socket;
 }
 
+UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit)
+    : Socket(ProtocolUdp, should_close, child_processes_inherit) {}
+
 size_t UDPSocket::Send(const void *buf, const size_t num_bytes) {
   return ::sendto(m_socket, static_cast<const char *>(buf), num_bytes, 0,
                   m_sockaddr, m_sockaddr.GetLength());
 }
 
 Error UDPSocket::Connect(llvm::StringRef name) {
+  return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Listen(llvm::StringRef name, int backlog) {
+  return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Accept(Socket *&socket) {
+  return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
+                         Socket *&socket) {
+  std::unique_ptr<UDPSocket> final_socket;
+
   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
   if (log)
     log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
 
   Error error;
-  if (error.Fail())
-    return error;
-
   std::string host_str;
   std::string port_str;
   int32_t port = INT32_MIN;
@@ -84,11 +94,12 @@ Error UDPSocket::Connect(llvm::StringRef
   for (struct addrinfo *service_info_ptr = service_info_list;
        service_info_ptr != nullptr;
        service_info_ptr = service_info_ptr->ai_next) {
-    m_socket = Socket::CreateSocket(
+    auto send_fd = CreateSocket(
         service_info_ptr->ai_family, service_info_ptr->ai_socktype,
-        service_info_ptr->ai_protocol, m_child_processes_inherit, error);
+        service_info_ptr->ai_protocol, child_processes_inherit, error);
     if (error.Success()) {
-      m_sockaddr = service_info_ptr;
+      final_socket.reset(new UDPSocket(send_fd));
+      final_socket->m_sockaddr = service_info_ptr;
       break;
     } else
       continue;
@@ -96,17 +107,16 @@ Error UDPSocket::Connect(llvm::StringRef
 
   ::freeaddrinfo(service_info_list);
 
-  if (IsValid())
+  if (!final_socket)
     return error;
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list