[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)

2024-12-28 Thread Hu Jialun via lldb-commits

https://github.com/SuibianP updated 
https://github.com/llvm/llvm-project/pull/121269

>From b980d11a234138a2c5a3f1509ee9d0dee51ccae0 Mon Sep 17 00:00:00 2001
From: Hu Jialun 
Date: Sat, 28 Dec 2024 22:39:33 +0800
Subject: [PATCH] [lldb-dap] Implement runInTerminal for Windows

Currently, the named pipe is passed by name and a transient ofstream is
constructed at each I/O request. This assumes,
  - Blocking semantics: FIFO I/O waits for the other side to connect.
  - Buffered semantics: Closing one side does not discard existing data.

The former can be replaced by WaitNamedPipe/ConnectNamedPipe on Win32,
but the second cannot be easily worked around. It is also impossible to
have another "keep-alive" pipe server instance, as server-client pairs
are fixed on connection on Win32 and the client may get connected to it
instead of the real one.

Refactor FifoFile[IO] to use an open file handles rather than file name.
---
 lldb/tools/lldb-dap/FifoFiles.cpp | 110 +-
 lldb/tools/lldb-dap/FifoFiles.h   |  31 
 lldb/tools/lldb-dap/RunInTerminal.cpp |  27 +--
 lldb/tools/lldb-dap/RunInTerminal.h   |   4 +-
 lldb/tools/lldb-dap/lldb-dap.cpp  |  13 ++-
 5 files changed, 138 insertions(+), 47 deletions(-)

diff --git a/lldb/tools/lldb-dap/FifoFiles.cpp 
b/lldb/tools/lldb-dap/FifoFiles.cpp
index 1f1bba80bd3b11..f2544cfe974a54 100644
--- a/lldb/tools/lldb-dap/FifoFiles.cpp
+++ b/lldb/tools/lldb-dap/FifoFiles.cpp
@@ -9,7 +9,13 @@
 #include "FifoFiles.h"
 #include "JSONUtils.h"
 
-#if !defined(_WIN32)
+#include "llvm/Support/FileSystem.h"
+
+#if defined(_WIN32)
+#include 
+#include 
+#include 
+#else
 #include 
 #include 
 #include 
@@ -24,26 +30,65 @@ using namespace llvm;
 
 namespace lldb_dap {
 
-FifoFile::FifoFile(StringRef path) : m_path(path) {}
+std::error_code EC;
 
+FifoFile::FifoFile(StringRef path)
+: m_path(path), m_file(fopen(path.data(), "r+")) {
+  if (m_file == nullptr) {
+EC = std::error_code(errno, std::generic_category());
+llvm::errs() << "Failed to open fifo file: " << path << EC.message()
+ << "\n";
+return;
+  }
+  if (setvbuf(m_file, NULL, _IONBF, 0))
+llvm::errs() << "Error setting unbuffered mode on C FILE\n";
+}
+FifoFile::FifoFile(StringRef path, FILE *f) : m_path(path), m_file(f) {}
 FifoFile::~FifoFile() {
+  fclose(m_file);
 #if !defined(_WIN32)
   unlink(m_path.c_str());
 #endif
+  // Unreferenced named pipes are deleted automatically on Win32
 }
 
-Expected> CreateFifoFile(StringRef path) {
-#if defined(_WIN32)
-  return createStringError(inconvertibleErrorCode(), "Unimplemented");
+// This probably belongs to llvm::sys::fs as another FSEntity type
+std::error_code createNamedPipe(const Twine &Prefix, StringRef Suffix,
+int &ResultFd,
+SmallVectorImpl &ResultPath) {
+  const char *Middle = Suffix.empty() ? "-%%" : "-%%.";
+  auto EC = sys::fs::getPotentiallyUniqueFileName(
+#ifdef _WIN32
+  ".\\pipe\\LOCAL\\"
+#else
+  "/tmp/"
+#endif
+  + Prefix + Middle + Suffix,
+  ResultPath);
+  if (EC)
+return EC;
+  ResultPath.push_back(0);
+  const char *path = ResultPath.data();
+#ifdef _WIN32
+  HANDLE h = ::CreateNamedPipeA(
+  path, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
+  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 0, NULL);
+  if (h == INVALID_HANDLE_VALUE)
+return std::error_code(::GetLastError(), std::system_category());
+  ResultFd = _open_osfhandle((intptr_t)h, _O_TEXT | _O_RDWR);
+  if (ResultFd == -1)
+return std::error_code(::GetLastError(), std::system_category());
 #else
-  if (int err = mkfifo(path.data(), 0600))
-return createStringError(std::error_code(err, std::generic_category()),
- "Couldn't create fifo file: %s", path.data());
-  return std::make_shared(path);
+  if (mkfifo(path, 0600) == -1)
+return std::error_code(errno, std::generic_category());
+  EC = openFileForWrite(ResultPath, ResultFd, sys::fs::CD_OpenExisting, 
sys::fs::OF_None, 0600);
+  if (EC)
+return EC;
 #endif
+  return std::error_code();
 }
 
-FifoFileIO::FifoFileIO(StringRef fifo_file, StringRef other_endpoint_name)
+FifoFileIO::FifoFileIO(FifoFile fifo_file, StringRef other_endpoint_name)
 : m_fifo_file(fifo_file), m_other_endpoint_name(other_endpoint_name) {}
 
 Expected FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {
@@ -52,13 +97,20 @@ Expected 
FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {
   std::optional line;
   std::future *future =
   new std::future(std::async(std::launch::async, [&]() {
-std::ifstream reader(m_fifo_file, std::ifstream::in);
-std::string buffer;
-std::getline(reader, buffer);
-if (!buffer.empty())
-  line = buffer;
+rewind(m_fifo_file.m_file);
+constexpr size_t buffer_size = 2048;
+char buffer[buffer_size];
+cha

[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)

2024-12-28 Thread Hu Jialun via lldb-commits

https://github.com/SuibianP created 
https://github.com/llvm/llvm-project/pull/121269

Currently, the named pipe is passed by name and a transient `ofstream` is 
constructed at each I/O request. This assumes,
  - Blocking semantics: FIFO I/O waits for the other side to connect.
  - Buffered semantics: Closing one side does not discard existing data.

The former can be replaced by `WaitNamedPipe`/`ConnectNamedPipe` on Win32, but 
the second cannot be easily worked around. It is also impossible to have 
another "keep-alive" pipe server instance, as server-client pairs are fixed on 
connection on Win32 and the client may get connected to it instead of the real 
one.

Refactor `FifoFile[IO]` to use an open file handles rather than file name.

>From 4c8c18c8c54308b945d6c78e2c71ebabf29cb554 Mon Sep 17 00:00:00 2001
From: Hu Jialun 
Date: Sat, 28 Dec 2024 22:39:33 +0800
Subject: [PATCH] [lldb-dap] Implement runInTerminal for Windows

Currently, the named pipe is passed by name and a transient ofstream is
constructed at each I/O request. This assumes,
  - Blocking semantics: FIFO I/O waits for the other side to connect.
  - Buffered semantics: Closing one side does not discard existing data.

The former can be replaced by WaitNamedPipe/ConnectNamedPipe on Win32,
but the second cannot be easily worked around. It is also impossible to
have another "keep-alive" pipe server instance, as server-client pairs
are fixed on connection on Win32 and the client may get connected to it
instead of the real one.

Refactor FifoFile[IO] to use an open file handles rather than file name.
---
 lldb/tools/lldb-dap/FifoFiles.cpp | 110 +-
 lldb/tools/lldb-dap/FifoFiles.h   |  31 
 lldb/tools/lldb-dap/RunInTerminal.cpp |  27 +--
 lldb/tools/lldb-dap/RunInTerminal.h   |   4 +-
 lldb/tools/lldb-dap/lldb-dap.cpp  |  13 ++-
 5 files changed, 138 insertions(+), 47 deletions(-)

diff --git a/lldb/tools/lldb-dap/FifoFiles.cpp 
b/lldb/tools/lldb-dap/FifoFiles.cpp
index 1f1bba80bd3b11..80e358532ecee4 100644
--- a/lldb/tools/lldb-dap/FifoFiles.cpp
+++ b/lldb/tools/lldb-dap/FifoFiles.cpp
@@ -9,7 +9,13 @@
 #include "FifoFiles.h"
 #include "JSONUtils.h"
 
-#if !defined(_WIN32)
+#include "llvm/Support/FileSystem.h"
+
+#if defined(_WIN32)
+#include 
+#include 
+#include 
+#else
 #include 
 #include 
 #include 
@@ -24,26 +30,65 @@ using namespace llvm;
 
 namespace lldb_dap {
 
-FifoFile::FifoFile(StringRef path) : m_path(path) {}
+std::error_code EC;
 
+FifoFile::FifoFile(StringRef path)
+: m_path(path), m_file(fopen(path.data(), "r+")) {
+  if (m_file == nullptr) {
+EC = std::error_code(errno, std::generic_category());
+llvm::errs() << "Failed to open fifo file: " << path << EC.message()
+ << "\n";
+return;
+  }
+  if (setvbuf(m_file, NULL, _IONBF, 0))
+llvm::errs() << "Error setting unbuffered mode on C FILE\n";
+}
+FifoFile::FifoFile(StringRef path, FILE *f) : m_path(path), m_file(f) {}
 FifoFile::~FifoFile() {
+  fclose(m_file);
 #if !defined(_WIN32)
   unlink(m_path.c_str());
 #endif
+  // Unreferenced named pipes are deleted automatically on Win32
 }
 
-Expected> CreateFifoFile(StringRef path) {
-#if defined(_WIN32)
-  return createStringError(inconvertibleErrorCode(), "Unimplemented");
+// This probably belongs to llvm::sys::fs as another FSEntity type
+std::error_code createNamedPipe(const Twine &Prefix, StringRef Suffix,
+int &ResultFd,
+SmallVectorImpl &ResultPath) {
+  const char *Middle = Suffix.empty() ? "-%%" : "-%%.";
+  auto EC = sys::fs::getPotentiallyUniqueFileName(
+#ifdef _WIN32
+  ".\\pipe\\LOCAL\\"
+#else
+  "/tmp/"
+#endif
+  + Prefix + Middle + Suffix,
+  ResultPath);
+  if (EC)
+return EC;
+  ResultPath.push_back(0);
+  const char *path = ResultPath.data();
+#ifdef _WIN32
+  HANDLE h = ::CreateNamedPipeA(
+  path, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
+  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 0, NULL);
+  if (h == INVALID_HANDLE_VALUE)
+return std::error_code(::GetLastError(), std::system_category());
+  ResultFd = _open_osfhandle((intptr_t)h, _O_TEXT | _O_RDWR);
+  if (ResultFd == -1)
+return std::error_code(::GetLastError(), std::system_category());
 #else
-  if (int err = mkfifo(path.data(), 0600))
-return createStringError(std::error_code(err, std::generic_category()),
- "Couldn't create fifo file: %s", path.data());
-  return std::make_shared(path);
+  if (mkfifo(path, 0600) == -1)
+return std::error_code(errno, std::generic_category());
+  EC = openFileForWrite(ResultPath, ResultFd, CD_OpenExisting, OF_None, 0600);
+  if (EC)
+return EC;
 #endif
+  return std::error_code();
 }
 
-FifoFileIO::FifoFileIO(StringRef fifo_file, StringRef other_endpoint_name)
+FifoFileIO::FifoFileIO(FifoFile fifo_file, StringRef other_endpoint_name)
 : m_fifo_file(

[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)

2024-12-28 Thread via lldb-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/121269
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb-dap] Implement `runInTerminal` for Windows (PR #121269)

2024-12-28 Thread Hu Jialun via lldb-commits

SuibianP wrote:

The patch currently suffers from a critical issue that I cannot diagnose. Help 
is much appreciated.

When the debug adapter attempts to attach to the launcher,

https://github.com/llvm/llvm-project/blob/4c8c18c8c54308b945d6c78e2c71ebabf29cb554/lldb/tools/lldb-dap/lldb-dap.cpp#L2039

it blocks at

https://github.com/llvm/llvm-project/blob/4c8c18c8c54308b945d6c78e2c71ebabf29cb554/lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp#L580-L581

although adding the following snippet at the front of 
`RunInTerminalLauncherCommChannel::WaitUntilDebugAdaptorAttaches` indicates 
that the launcher process does get paused and never resumed.

```cpp
for (int i = 0; !::IsDebuggerPresent(); ++i)
  LLVM_LOGV(log, "Waiting to be attached... {0}", i);
LLVM_LOGV(log, "Attached");
```

https://github.com/llvm/llvm-project/pull/121269
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][AIX] Added PlatformAIX plugin (PR #121273)

2024-12-28 Thread Dhruv Srivastava via lldb-commits

https://github.com/DhruvSrivastavaX created 
https://github.com/llvm/llvm-project/pull/121273

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
2. https://github.com/llvm/llvm-project/issues/101657
The complete changes for porting are present in this draft PR:
https://github.com/llvm/llvm-project/pull/102601

Details:
--
Adding PlatformAIX plugin for a basic lldb build support. The 1st commit is the 
original version as in the draft PR which is a PlatformLinux copy. I have 
removed some of the code in the next commits. 
Please let me know all the other changes required to push the PlatformAIX 
changes and avoid any duplication.


Review Request: @labath @DavidSpickett

>From 16107a423e30cc339b7529db35a75c3c26924146 Mon Sep 17 00:00:00 2001
From: Dhruv-Srivastava 
Date: Sat, 28 Dec 2024 13:19:21 -0600
Subject: [PATCH 1/3] Introducing PlatformAIX from PlatformLinux

---
 .../Plugins/Platform/AIX/CMakeLists.txt   |  13 +
 .../Plugins/Platform/AIX/PlatformAIX.cpp  | 471 ++
 .../source/Plugins/Platform/AIX/PlatformAIX.h |  74 +++
 lldb/source/Plugins/Platform/CMakeLists.txt   |   1 +
 4 files changed, 559 insertions(+)
 create mode 100644 lldb/source/Plugins/Platform/AIX/CMakeLists.txt
 create mode 100644 lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp
 create mode 100644 lldb/source/Plugins/Platform/AIX/PlatformAIX.h

diff --git a/lldb/source/Plugins/Platform/AIX/CMakeLists.txt 
b/lldb/source/Plugins/Platform/AIX/CMakeLists.txt
new file mode 100644
index 00..85ff0a315eabd5
--- /dev/null
+++ b/lldb/source/Plugins/Platform/AIX/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_definitions("-D_ALL_SOURCE")
+
+add_lldb_library(lldbPluginPlatformAIX PLUGIN
+  PlatformAIX.cpp
+
+   LINK_LIBS
+lldbBreakpoint
+lldbCore
+lldbHost
+lldbInterpreter
+lldbTarget
+lldbPluginPlatformPOSIX
+  )
diff --git a/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp 
b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp
new file mode 100644
index 00..5c944770029789
--- /dev/null
+++ b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp
@@ -0,0 +1,471 @@
+//===-- PlatformAIX.cpp -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "PlatformAIX.h"
+#include "lldb/Host/Config.h"
+
+#include 
+#if LLDB_ENABLE_POSIX
+#include 
+#endif
+
+#include "Utility/ARM64_DWARF_Registers.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StreamString.h"
+
+// Define these constants from AIX mman.h for use when targeting remote aix
+// systems even when host has different values.
+
+#if defined(_AIX)
+#include 
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::platform_aix;
+
+LLDB_PLUGIN_DEFINE(PlatformAIX)
+
+static uint32_t g_initialize_count = 0;
+
+
+PlatformSP PlatformAIX::CreateInstance(bool force, const ArchSpec *arch) {
+  Log *log = GetLog(LLDBLog::Platform);
+  LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
+   arch ? arch->GetArchitectureName() : "",
+   arch ? arch->GetTriple().getTriple() : "");
+
+  bool create = force;
+  if (!create && arch && arch->IsValid()) {
+const llvm::Triple &triple = arch->GetTriple();
+switch (triple.getOS()) {
+case llvm::Triple::AIX:
+  create = true;
+  break;
+
+default:
+  break;
+}
+  }
+
+  LLDB_LOG(log, "create = {0}", create);
+  if (create) {
+return PlatformSP(new PlatformAIX(false));
+  }
+  return PlatformSP();
+}
+
+llvm::StringRef PlatformAIX::GetPluginDescriptionStatic(bool is_host) {
+  if (is_host)
+return "Local AIX user platform plug-in.";
+  return "Remote AIX user platform plug-in.";
+}
+
+void PlatformAIX::Initialize() {
+  PlatformPOSIX::Initialize();
+
+  if (g_initialize_count++ == 0) {
+#if defined(_AIX)
+PlatformSP default_platform_sp(new PlatformAIX(true));
+default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+Platform::SetHostPlatform(default_platform_sp);
+#endif
+PluginManager::RegisterPlugin(
+PlatformAIX::GetPluginNameStatic(false),
+PlatformAIX::GetPluginDescriptionStatic(false),
+PlatformAIX::CreateInstance, nullptr);
+  }
+}
+
+void PlatformAIX::Terminate() {
+  if (g_initialize_count > 0

[Lldb-commits] [lldb] [lldb][AIX] Added PlatformAIX plugin (PR #121273)

2024-12-28 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Dhruv Srivastava (DhruvSrivastavaX)


Changes

This PR is in reference to porting LLDB on AIX.

Link to discussions on llvm discourse and github:

1. https://discourse.llvm.org/t/port-lldb-to-ibm-aix/80640
2. https://github.com/llvm/llvm-project/issues/101657
The complete changes for porting are present in this draft PR:
https://github.com/llvm/llvm-project/pull/102601

Details:
--
Adding PlatformAIX plugin for a basic lldb build support. The 1st commit is the 
original version as in the draft PR which is a PlatformLinux copy. I have 
removed some of the code in the next commits. 
Please let me know all the other changes required to push the PlatformAIX 
changes and avoid any duplication.


Review Request: @labath @DavidSpickett

---
Full diff: https://github.com/llvm/llvm-project/pull/121273.diff


4 Files Affected:

- (added) lldb/source/Plugins/Platform/AIX/CMakeLists.txt (+13) 
- (added) lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp (+368) 
- (added) lldb/source/Plugins/Platform/AIX/PlatformAIX.h (+74) 
- (modified) lldb/source/Plugins/Platform/CMakeLists.txt (+1) 


``diff
diff --git a/lldb/source/Plugins/Platform/AIX/CMakeLists.txt 
b/lldb/source/Plugins/Platform/AIX/CMakeLists.txt
new file mode 100644
index 00..85ff0a315eabd5
--- /dev/null
+++ b/lldb/source/Plugins/Platform/AIX/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_definitions("-D_ALL_SOURCE")
+
+add_lldb_library(lldbPluginPlatformAIX PLUGIN
+  PlatformAIX.cpp
+
+   LINK_LIBS
+lldbBreakpoint
+lldbCore
+lldbHost
+lldbInterpreter
+lldbTarget
+lldbPluginPlatformPOSIX
+  )
diff --git a/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp 
b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp
new file mode 100644
index 00..36d02be5642293
--- /dev/null
+++ b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp
@@ -0,0 +1,368 @@
+//===-- PlatformAIX.cpp -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "PlatformAIX.h"
+#include "lldb/Host/Config.h"
+#include 
+#if LLDB_ENABLE_POSIX
+#include 
+#endif
+#include "Utility/ARM64_DWARF_Registers.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StreamString.h"
+
+// Use defined constants from AIX mman.h for use when targeting remote aix
+// systems even when host has different values.
+
+#if defined(_AIX)
+#include 
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::platform_aix;
+
+LLDB_PLUGIN_DEFINE(PlatformAIX)
+
+static uint32_t g_initialize_count = 0;
+
+PlatformSP PlatformAIX::CreateInstance(bool force, const ArchSpec *arch) {
+  Log *log = GetLog(LLDBLog::Platform);
+  LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
+   arch ? arch->GetArchitectureName() : "",
+   arch ? arch->GetTriple().getTriple() : "");
+
+  bool create = force;
+  if (!create && arch && arch->IsValid()) {
+const llvm::Triple &triple = arch->GetTriple();
+switch (triple.getOS()) {
+case llvm::Triple::AIX:
+  create = true;
+  break;
+
+default:
+  break;
+}
+  }
+
+  LLDB_LOG(log, "create = {0}", create);
+  if (create) {
+return PlatformSP(new PlatformAIX(false));
+  }
+  return PlatformSP();
+}
+
+llvm::StringRef PlatformAIX::GetPluginDescriptionStatic(bool is_host) {
+  if (is_host)
+return "Local AIX user platform plug-in.";
+  return "Remote AIX user platform plug-in.";
+}
+
+void PlatformAIX::Initialize() {
+  PlatformPOSIX::Initialize();
+
+  if (g_initialize_count++ == 0) {
+PlatformSP default_platform_sp(new PlatformAIX(true));
+default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
+Platform::SetHostPlatform(default_platform_sp);
+PluginManager::RegisterPlugin(
+PlatformAIX::GetPluginNameStatic(false),
+PlatformAIX::GetPluginDescriptionStatic(false),
+PlatformAIX::CreateInstance, nullptr);
+  }
+}
+
+void PlatformAIX::Terminate() {
+  if (g_initialize_count > 0) {
+if (--g_initialize_count == 0) {
+  PluginManager::UnregisterPlugin(PlatformAIX::CreateInstance);
+}
+  }
+
+  PlatformPOSIX::Terminate();
+}
+
+/// Default Constructor
+PlatformAIX::PlatformAIX(bool is_host)
+: PlatformPOSIX(is_host) // This is the local host platform
+{
+  if (is_host) {
+ArchSpec hostArch = HostInfo