]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
Vendor import of lldb trunk r338150:
[FreeBSD/FreeBSD.git] / source / Plugins / Platform / OpenBSD / PlatformOpenBSD.cpp
1 //===-- PlatformOpenBSD.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "PlatformOpenBSD.h"
11 #include "lldb/Host/Config.h"
12
13 // C Includes
14 #include <stdio.h>
15 #ifndef LLDB_DISABLE_POSIX
16 #include <sys/utsname.h>
17 #endif
18
19 // C++ Includes
20 // Other libraries and framework includes
21 // Project includes
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Host/HostInfo.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Utility/FileSpec.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/Status.h"
31 #include "lldb/Utility/StreamString.h"
32
33 // Define these constants from OpenBSD mman.h for use when targeting remote
34 // openbsd systems even when host has different values.
35 #define MAP_PRIVATE 0x0002
36 #define MAP_ANON 0x1000
37
38 using namespace lldb;
39 using namespace lldb_private;
40 using namespace lldb_private::platform_openbsd;
41
42 static uint32_t g_initialize_count = 0;
43
44 //------------------------------------------------------------------
45
46 PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
47   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
48   LLDB_LOG(log, "force = {0}, arch=({1}, {2})", force,
49            arch ? arch->GetArchitectureName() : "<null>",
50            arch ? arch->GetTriple().getTriple() : "<null>");
51
52   bool create = force;
53   if (create == false && arch && arch->IsValid()) {
54     const llvm::Triple &triple = arch->GetTriple();
55     switch (triple.getOS()) {
56     case llvm::Triple::OpenBSD:
57       create = true;
58       break;
59
60 #if defined(__OpenBSD__)
61     // Only accept "unknown" for the OS if the host is BSD and it "unknown"
62     // wasn't specified (it was just returned because it was NOT specified)
63     case llvm::Triple::OSType::UnknownOS:
64       create = !arch->TripleOSWasSpecified();
65       break;
66 #endif
67     default:
68       break;
69     }
70   }
71   LLDB_LOG(log, "create = {0}", create);
72   if (create) {
73     return PlatformSP(new PlatformOpenBSD(false));
74   }
75   return PlatformSP();
76 }
77
78 ConstString PlatformOpenBSD::GetPluginNameStatic(bool is_host) {
79   if (is_host) {
80     static ConstString g_host_name(Platform::GetHostPlatformName());
81     return g_host_name;
82   } else {
83     static ConstString g_remote_name("remote-openbsd");
84     return g_remote_name;
85   }
86 }
87
88 const char *PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) {
89   if (is_host)
90     return "Local OpenBSD user platform plug-in.";
91   else
92     return "Remote OpenBSD user platform plug-in.";
93 }
94
95 ConstString PlatformOpenBSD::GetPluginName() {
96   return GetPluginNameStatic(IsHost());
97 }
98
99 void PlatformOpenBSD::Initialize() {
100   Platform::Initialize();
101
102   if (g_initialize_count++ == 0) {
103 #if defined(__OpenBSD__)
104     PlatformSP default_platform_sp(new PlatformOpenBSD(true));
105     default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
106     Platform::SetHostPlatform(default_platform_sp);
107 #endif
108     PluginManager::RegisterPlugin(
109         PlatformOpenBSD::GetPluginNameStatic(false),
110         PlatformOpenBSD::GetPluginDescriptionStatic(false),
111         PlatformOpenBSD::CreateInstance, nullptr);
112   }
113 }
114
115 void PlatformOpenBSD::Terminate() {
116   if (g_initialize_count > 0) {
117     if (--g_initialize_count == 0) {
118       PluginManager::UnregisterPlugin(PlatformOpenBSD::CreateInstance);
119     }
120   }
121
122   PlatformPOSIX::Terminate();
123 }
124
125 //------------------------------------------------------------------
126 /// Default Constructor
127 //------------------------------------------------------------------
128 PlatformOpenBSD::PlatformOpenBSD(bool is_host)
129     : PlatformPOSIX(is_host) // This is the local host platform
130 {}
131
132 PlatformOpenBSD::~PlatformOpenBSD() = default;
133
134 bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx,
135                                                       ArchSpec &arch) {
136   if (IsHost()) {
137     ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
138     if (hostArch.GetTriple().isOSOpenBSD()) {
139       if (idx == 0) {
140         arch = hostArch;
141         return arch.IsValid();
142       }
143     }
144   } else {
145     if (m_remote_platform_sp)
146       return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch);
147
148     llvm::Triple triple;
149     // Set the OS to OpenBSD
150     triple.setOS(llvm::Triple::OpenBSD);
151     // Set the architecture
152     switch (idx) {
153     case 0:
154       triple.setArchName("x86_64");
155       break;
156     case 1:
157       triple.setArchName("i386");
158       break;
159     case 2:
160       triple.setArchName("aarch64");
161       break;
162     case 3:
163       triple.setArchName("arm");
164       break;
165     default:
166       return false;
167     }
168     // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the
169     // vendor by calling triple.SetVendorName("unknown") so that it is a
170     // "unspecified unknown". This means when someone calls
171     // triple.GetVendorName() it will return an empty string which indicates
172     // that the vendor can be set when two architectures are merged
173
174     // Now set the triple into "arch" and return true
175     arch.SetTriple(triple);
176     return true;
177   }
178   return false;
179 }
180
181 void PlatformOpenBSD::GetStatus(Stream &strm) {
182   Platform::GetStatus(strm);
183
184 #ifndef LLDB_DISABLE_POSIX
185   // Display local kernel information only when we are running in host mode.
186   // Otherwise, we would end up printing non-OpenBSD information (when running
187   // on Mac OS for example).
188   if (IsHost()) {
189     struct utsname un;
190
191     if (uname(&un))
192       return;
193
194     strm.Printf("    Kernel: %s\n", un.sysname);
195     strm.Printf("   Release: %s\n", un.release);
196     strm.Printf("   Version: %s\n", un.version);
197   }
198 #endif
199 }
200
201 // OpenBSD processes cannot yet be launched by spawning and attaching.
202 bool PlatformOpenBSD::CanDebugProcess() {
203   return false;
204 }
205
206 void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() {
207   m_trap_handlers.push_back(ConstString("_sigtramp"));
208 }
209
210 MmapArgList PlatformOpenBSD::GetMmapArgumentList(const ArchSpec &arch,
211                                                  addr_t addr, addr_t length,
212                                                  unsigned prot, unsigned flags,
213                                                  addr_t fd, addr_t offset) {
214   uint64_t flags_platform = 0;
215
216   if (flags & eMmapFlagsPrivate)
217     flags_platform |= MAP_PRIVATE;
218   if (flags & eMmapFlagsAnon)
219     flags_platform |= MAP_ANON;
220
221   MmapArgList args({addr, length, prot, flags_platform, fd, offset});
222   return args;
223 }