1//===-- PlatformAIX.cpp -------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "PlatformAIX.h"
10#include "lldb/Host/Config.h"
11#include <cstdio>
12#if LLDB_ENABLE_POSIX
13#include <sys/utsname.h>
14#endif
15#include "Utility/ARM64_DWARF_Registers.h"
16#include "lldb/Core/Debugger.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Host/HostInfo.h"
19#include "lldb/Symbol/UnwindPlan.h"
20#include "lldb/Target/Process.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Utility/FileSpec.h"
23#include "lldb/Utility/LLDBLog.h"
24#include "lldb/Utility/Log.h"
25#include "lldb/Utility/State.h"
26#include "lldb/Utility/Status.h"
27#include "lldb/Utility/StreamString.h"
28
29// Use defined constants from AIX mman.h for use when targeting remote aix
30// systems even when host has different values.
31
32// For remotely cross debugging aix
33constexpr int MapVariable = 0x0;
34constexpr int MapPrivate = 0x2;
35constexpr int MapAnonymous = 0x10;
36#if defined(_AIX)
37#include <sys/mman.h>
38static_assert(MapVariable == MAP_VARIABLE);
39static_assert(MapPrivate == MAP_PRIVATE);
40static_assert(MapAnonymous == MAP_ANONYMOUS);
41#endif
42
43using namespace lldb;
44using namespace lldb_private;
45using namespace lldb_private::platform_aix;
46
47LLDB_PLUGIN_DEFINE(PlatformAIX)
48
49static uint32_t g_initialize_count = 0;
50
51PlatformSP PlatformAIX::CreateInstance(bool force, const ArchSpec *arch) {
52 Log *log = GetLog(mask: LLDBLog::Platform);
53 LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
54 arch ? arch->GetArchitectureName() : "<null>",
55 arch ? arch->GetTriple().getTriple() : "<null>");
56
57 bool create = force || (arch && arch->IsValid() &&
58 arch->GetTriple().getOS() == llvm::Triple::AIX);
59 LLDB_LOG(log, "create = {0}", create);
60 if (create) {
61 return PlatformSP(new PlatformAIX(false));
62 }
63 return PlatformSP();
64}
65
66llvm::StringRef PlatformAIX::GetPluginDescriptionStatic(bool is_host) {
67 if (is_host)
68 return "Local AIX user platform plug-in.";
69 return "Remote AIX user platform plug-in.";
70}
71
72void PlatformAIX::Initialize() {
73 PlatformPOSIX::Initialize();
74
75 if (g_initialize_count++ == 0) {
76#ifdef _AIX
77 PlatformSP default_platform_sp(new PlatformAIX(true));
78 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
79 Platform::SetHostPlatform(default_platform_sp);
80#endif
81 PluginManager::RegisterPlugin(
82 name: PlatformAIX::GetPluginNameStatic(is_host: false),
83 description: PlatformAIX::GetPluginDescriptionStatic(is_host: false),
84 create_callback: PlatformAIX::CreateInstance, debugger_init_callback: nullptr);
85 }
86}
87
88void PlatformAIX::Terminate() {
89 if (g_initialize_count > 0)
90 if (--g_initialize_count == 0)
91 PluginManager::UnregisterPlugin(create_callback: PlatformAIX::CreateInstance);
92
93 PlatformPOSIX::Terminate();
94}
95
96PlatformAIX::PlatformAIX(bool is_host) : PlatformPOSIX(is_host) {
97 if (is_host) {
98 ArchSpec hostArch = HostInfo::GetArchitecture(arch_kind: HostInfo::eArchKindDefault);
99 m_supported_architectures.push_back(x: hostArch);
100 } else {
101 m_supported_architectures =
102 CreateArchList(archs: {llvm::Triple::ppc64}, os: llvm::Triple::AIX);
103 }
104}
105
106std::vector<ArchSpec>
107PlatformAIX::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
108 if (m_remote_platform_sp)
109 return m_remote_platform_sp->GetSupportedArchitectures(process_host_arch);
110 return m_supported_architectures;
111}
112
113void PlatformAIX::GetStatus(Stream &strm) {
114 Platform::GetStatus(strm);
115
116#if LLDB_ENABLE_POSIX
117 // Display local kernel information only when we are running in host mode.
118 // Otherwise, we would end up printing non-AIX information (when running on
119 // Mac OS for example).
120 if (IsHost()) {
121 struct utsname un;
122
123 if (uname(name: &un))
124 return;
125
126 strm.Printf(format: " Kernel: %s\n", un.sysname);
127 strm.Printf(format: " Release: %s\n", un.release);
128 strm.Printf(format: " Version: %s\n", un.version);
129 }
130#endif
131}
132
133void PlatformAIX::CalculateTrapHandlerSymbolNames() {}
134
135lldb::UnwindPlanSP
136PlatformAIX::GetTrapHandlerUnwindPlan(const llvm::Triple &triple,
137 ConstString name) {
138 return {};
139}
140
141MmapArgList PlatformAIX::GetMmapArgumentList(const ArchSpec &arch, addr_t addr,
142 addr_t length, unsigned prot,
143 unsigned flags, addr_t fd,
144 addr_t offset) {
145 unsigned flags_platform = MapVariable;
146
147 if (flags & eMmapFlagsPrivate)
148 flags_platform |= MapPrivate;
149 if (flags & eMmapFlagsAnon)
150 flags_platform |= MapAnonymous;
151
152 MmapArgList args({addr, length, prot, flags_platform, fd, offset});
153 return args;
154}
155
156CompilerType PlatformAIX::GetSiginfoType(const llvm::Triple &triple) {
157 return CompilerType();
158}
159

source code of lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp