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 34 // remote 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 62 // it "unknown" wasn't specified (it was just returned because it 63 // was NOT specified) 64 case llvm::Triple::OSType::UnknownOS: 65 create = !arch->TripleOSWasSpecified(); 66 break; 67 #endif 68 default: 69 break; 70 } 71 } 72 LLDB_LOG(log, "create = {0}", create); 73 if (create) { 74 return PlatformSP(new PlatformOpenBSD(false)); 75 } 76 return PlatformSP(); 77 } 78 79 ConstString PlatformOpenBSD::GetPluginNameStatic(bool is_host) { 80 if (is_host) { 81 static ConstString g_host_name(Platform::GetHostPlatformName()); 82 return g_host_name; 83 } else { 84 static ConstString g_remote_name("remote-openbsd"); 85 return g_remote_name; 86 } 87 } 88 89 const char *PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) { 90 if (is_host) 91 return "Local OpenBSD user platform plug-in."; 92 else 93 return "Remote OpenBSD user platform plug-in."; 94 } 95 96 ConstString PlatformOpenBSD::GetPluginName() { 97 return GetPluginNameStatic(IsHost()); 98 } 99 100 void PlatformOpenBSD::Initialize() { 101 Platform::Initialize(); 102 103 if (g_initialize_count++ == 0) { 104 #if defined(__OpenBSD__) 105 PlatformSP default_platform_sp(new PlatformOpenBSD(true)); 106 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 107 Platform::SetHostPlatform(default_platform_sp); 108 #endif 109 PluginManager::RegisterPlugin( 110 PlatformOpenBSD::GetPluginNameStatic(false), 111 PlatformOpenBSD::GetPluginDescriptionStatic(false), 112 PlatformOpenBSD::CreateInstance, nullptr); 113 } 114 } 115 116 void PlatformOpenBSD::Terminate() { 117 if (g_initialize_count > 0) { 118 if (--g_initialize_count == 0) { 119 PluginManager::UnregisterPlugin(PlatformOpenBSD::CreateInstance); 120 } 121 } 122 123 PlatformPOSIX::Terminate(); 124 } 125 126 //------------------------------------------------------------------ 127 /// Default Constructor 128 //------------------------------------------------------------------ 129 PlatformOpenBSD::PlatformOpenBSD(bool is_host) 130 : PlatformPOSIX(is_host) // This is the local host platform 131 {} 132 133 PlatformOpenBSD::~PlatformOpenBSD() = default; 134 135 bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx, 136 ArchSpec &arch) { 137 if (IsHost()) { 138 ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 139 if (hostArch.GetTriple().isOSOpenBSD()) { 140 if (idx == 0) { 141 arch = hostArch; 142 return arch.IsValid(); 143 } 144 } 145 } else { 146 if (m_remote_platform_sp) 147 return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); 148 149 llvm::Triple triple; 150 // Set the OS to OpenBSD 151 triple.setOS(llvm::Triple::OpenBSD); 152 // Set the architecture 153 switch (idx) { 154 case 0: 155 triple.setArchName("x86_64"); 156 break; 157 case 1: 158 triple.setArchName("i386"); 159 break; 160 case 2: 161 triple.setArchName("aarch64"); 162 break; 163 case 3: 164 triple.setArchName("arm"); 165 break; 166 default: 167 return false; 168 } 169 // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the 170 // vendor by 171 // calling triple.SetVendorName("unknown") so that it is a "unspecified 172 // unknown". 173 // This means when someone calls triple.GetVendorName() it will return an 174 // empty string 175 // which indicates that the vendor can be set when two architectures are 176 // merged 177 178 // Now set the triple into "arch" and return true 179 arch.SetTriple(triple); 180 return true; 181 } 182 return false; 183 } 184 185 void PlatformOpenBSD::GetStatus(Stream &strm) { 186 Platform::GetStatus(strm); 187 188 #ifndef LLDB_DISABLE_POSIX 189 // Display local kernel information only when we are running in host mode. 190 // Otherwise, we would end up printing non-OpenBSD information (when running 191 // on Mac OS for example). 192 if (IsHost()) { 193 struct utsname un; 194 195 if (uname(&un)) 196 return; 197 198 strm.Printf(" Kernel: %s\n", un.sysname); 199 strm.Printf(" Release: %s\n", un.release); 200 strm.Printf(" Version: %s\n", un.version); 201 } 202 #endif 203 } 204 205 // OpenBSD processes cannot yet be launched by spawning and attaching. 206 bool PlatformOpenBSD::CanDebugProcess() { 207 return false; 208 } 209 210 void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() { 211 m_trap_handlers.push_back(ConstString("_sigtramp")); 212 } 213 214 uint64_t PlatformOpenBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch, 215 unsigned flags) { 216 uint64_t flags_platform = 0; 217 218 if (flags & eMmapFlagsPrivate) 219 flags_platform |= MAP_PRIVATE; 220 if (flags & eMmapFlagsAnon) 221 flags_platform |= MAP_ANON; 222 return flags_platform; 223 } 224