1254721Semaste//===-- Host.cpp ------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste// C includes
13254721Semaste#include <dlfcn.h>
14254721Semaste#include <errno.h>
15254721Semaste#include <grp.h>
16254721Semaste#include <limits.h>
17254721Semaste#include <netdb.h>
18254721Semaste#include <pwd.h>
19254721Semaste#include <sys/types.h>
20254721Semaste#include <sys/sysctl.h>
21254721Semaste#include <unistd.h>
22254721Semaste
23254721Semaste#if defined (__APPLE__)
24254721Semaste
25254721Semaste#include <dispatch/dispatch.h>
26254721Semaste#include <libproc.h>
27254721Semaste#include <mach-o/dyld.h>
28254721Semaste#include <mach/mach_port.h>
29254721Semaste
30254721Semaste#endif
31254721Semaste
32254721Semaste#if defined (__linux__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
33254721Semaste#include <sys/wait.h>
34254721Semaste#include <sys/syscall.h>
35254721Semaste#endif
36254721Semaste
37254721Semaste#if defined (__FreeBSD__)
38254721Semaste#include <pthread_np.h>
39254721Semaste#endif
40254721Semaste
41254721Semaste#include "lldb/Host/Host.h"
42254721Semaste#include "lldb/Core/ArchSpec.h"
43254721Semaste#include "lldb/Core/ConstString.h"
44254721Semaste#include "lldb/Core/Debugger.h"
45254721Semaste#include "lldb/Core/Error.h"
46254721Semaste#include "lldb/Core/Log.h"
47254721Semaste#include "lldb/Core/StreamString.h"
48254721Semaste#include "lldb/Core/ThreadSafeSTLMap.h"
49254721Semaste#include "lldb/Host/Config.h"
50254721Semaste#include "lldb/Host/Endian.h"
51254721Semaste#include "lldb/Host/FileSpec.h"
52254721Semaste#include "lldb/Host/Mutex.h"
53254721Semaste#include "lldb/Target/Process.h"
54254721Semaste#include "lldb/Target/TargetList.h"
55254721Semaste
56254721Semaste#include "llvm/ADT/SmallString.h"
57254721Semaste#include "llvm/Support/Host.h"
58254721Semaste#include "llvm/Support/MachO.h"
59254721Semaste#include "llvm/Support/raw_ostream.h"
60254721Semaste
61254721Semaste
62254721Semaste
63254721Semaste
64254721Semaste
65254721Semasteusing namespace lldb;
66254721Semasteusing namespace lldb_private;
67254721Semaste
68254721Semaste
69254721Semaste#if !defined (__APPLE__)
70254721Semastestruct MonitorInfo
71254721Semaste{
72254721Semaste    lldb::pid_t pid;                            // The process ID to monitor
73254721Semaste    Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
74254721Semaste    void *callback_baton;                       // The callback baton for the callback function
75254721Semaste    bool monitor_signals;                       // If true, call the callback when "pid" gets signaled.
76254721Semaste};
77254721Semaste
78254721Semastestatic void *
79254721SemasteMonitorChildProcessThreadFunction (void *arg);
80254721Semaste
81254721Semastelldb::thread_t
82254721SemasteHost::StartMonitoringChildProcess
83254721Semaste(
84254721Semaste    Host::MonitorChildProcessCallback callback,
85254721Semaste    void *callback_baton,
86254721Semaste    lldb::pid_t pid,
87254721Semaste    bool monitor_signals
88254721Semaste)
89254721Semaste{
90254721Semaste    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
91254721Semaste    MonitorInfo * info_ptr = new MonitorInfo();
92254721Semaste
93254721Semaste    info_ptr->pid = pid;
94254721Semaste    info_ptr->callback = callback;
95254721Semaste    info_ptr->callback_baton = callback_baton;
96254721Semaste    info_ptr->monitor_signals = monitor_signals;
97254721Semaste
98254721Semaste    char thread_name[256];
99254721Semaste    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
100254721Semaste    thread = ThreadCreate (thread_name,
101254721Semaste                           MonitorChildProcessThreadFunction,
102254721Semaste                           info_ptr,
103254721Semaste                           NULL);
104254721Semaste
105254721Semaste    return thread;
106254721Semaste}
107254721Semaste
108254721Semaste//------------------------------------------------------------------
109254721Semaste// Scoped class that will disable thread canceling when it is
110254721Semaste// constructed, and exception safely restore the previous value it
111254721Semaste// when it goes out of scope.
112254721Semaste//------------------------------------------------------------------
113254721Semasteclass ScopedPThreadCancelDisabler
114254721Semaste{
115254721Semastepublic:
116254721Semaste    ScopedPThreadCancelDisabler()
117254721Semaste    {
118254721Semaste        // Disable the ability for this thread to be cancelled
119254721Semaste        int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
120254721Semaste        if (err != 0)
121254721Semaste            m_old_state = -1;
122254721Semaste
123254721Semaste    }
124254721Semaste
125254721Semaste    ~ScopedPThreadCancelDisabler()
126254721Semaste    {
127254721Semaste        // Restore the ability for this thread to be cancelled to what it
128254721Semaste        // previously was.
129254721Semaste        if (m_old_state != -1)
130254721Semaste            ::pthread_setcancelstate (m_old_state, 0);
131254721Semaste    }
132254721Semasteprivate:
133254721Semaste    int m_old_state;    // Save the old cancelability state.
134254721Semaste};
135254721Semaste
136254721Semastestatic void *
137254721SemasteMonitorChildProcessThreadFunction (void *arg)
138254721Semaste{
139254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
140254721Semaste    const char *function = __FUNCTION__;
141254721Semaste    if (log)
142254721Semaste        log->Printf ("%s (arg = %p) thread starting...", function, arg);
143254721Semaste
144254721Semaste    MonitorInfo *info = (MonitorInfo *)arg;
145254721Semaste
146254721Semaste    const Host::MonitorChildProcessCallback callback = info->callback;
147254721Semaste    void * const callback_baton = info->callback_baton;
148254721Semaste    const lldb::pid_t pid = info->pid;
149254721Semaste    const bool monitor_signals = info->monitor_signals;
150254721Semaste
151254721Semaste    delete info;
152254721Semaste
153254721Semaste    int status = -1;
154254721Semaste#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
155254721Semaste    #define __WALL 0
156254721Semaste#endif
157254721Semaste    const int options = __WALL;
158254721Semaste
159254721Semaste    while (1)
160254721Semaste    {
161254721Semaste        log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
162254721Semaste        if (log)
163254721Semaste            log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
164254721Semaste
165254721Semaste        // Wait for all child processes
166254721Semaste        ::pthread_testcancel ();
167254721Semaste        // Get signals from all children with same process group of pid
168254721Semaste        const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
169254721Semaste        ::pthread_testcancel ();
170254721Semaste
171254721Semaste        if (wait_pid == -1)
172254721Semaste        {
173254721Semaste            if (errno == EINTR)
174254721Semaste                continue;
175254721Semaste            else
176254721Semaste            {
177254721Semaste                if (log)
178254721Semaste                    log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno));
179254721Semaste                break;
180254721Semaste            }
181254721Semaste        }
182254721Semaste        else if (wait_pid > 0)
183254721Semaste        {
184254721Semaste            bool exited = false;
185254721Semaste            int signal = 0;
186254721Semaste            int exit_status = 0;
187254721Semaste            const char *status_cstr = NULL;
188254721Semaste            if (WIFSTOPPED(status))
189254721Semaste            {
190254721Semaste                signal = WSTOPSIG(status);
191254721Semaste                status_cstr = "STOPPED";
192254721Semaste            }
193254721Semaste            else if (WIFEXITED(status))
194254721Semaste            {
195254721Semaste                exit_status = WEXITSTATUS(status);
196254721Semaste                status_cstr = "EXITED";
197254721Semaste                exited = true;
198254721Semaste            }
199254721Semaste            else if (WIFSIGNALED(status))
200254721Semaste            {
201254721Semaste                signal = WTERMSIG(status);
202254721Semaste                status_cstr = "SIGNALED";
203254721Semaste                if (wait_pid == pid) {
204254721Semaste                    exited = true;
205254721Semaste                    exit_status = -1;
206254721Semaste                }
207254721Semaste            }
208254721Semaste            else
209254721Semaste            {
210254721Semaste                status_cstr = "(\?\?\?)";
211254721Semaste            }
212254721Semaste
213254721Semaste            // Scope for pthread_cancel_disabler
214254721Semaste            {
215254721Semaste                ScopedPThreadCancelDisabler pthread_cancel_disabler;
216254721Semaste
217254721Semaste                log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
218254721Semaste                if (log)
219254721Semaste                    log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
220254721Semaste                                 function,
221254721Semaste                                 wait_pid,
222254721Semaste                                 options,
223254721Semaste                                 pid,
224254721Semaste                                 status,
225254721Semaste                                 status_cstr,
226254721Semaste                                 signal,
227254721Semaste                                 exit_status);
228254721Semaste
229254721Semaste                if (exited || (signal != 0 && monitor_signals))
230254721Semaste                {
231254721Semaste                    bool callback_return = false;
232254721Semaste                    if (callback)
233254721Semaste                        callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
234254721Semaste
235254721Semaste                    // If our process exited, then this thread should exit
236254721Semaste                    if (exited && wait_pid == pid)
237254721Semaste                    {
238254721Semaste                        if (log)
239254721Semaste                            log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
240254721Semaste                        break;
241254721Semaste                    }
242254721Semaste                    // If the callback returns true, it means this process should
243254721Semaste                    // exit
244254721Semaste                    if (callback_return)
245254721Semaste                    {
246254721Semaste                        if (log)
247254721Semaste                            log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
248254721Semaste                        break;
249254721Semaste                    }
250254721Semaste                }
251254721Semaste            }
252254721Semaste        }
253254721Semaste    }
254254721Semaste
255254721Semaste    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
256254721Semaste    if (log)
257254721Semaste        log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
258254721Semaste
259254721Semaste    return NULL;
260254721Semaste}
261254721Semaste
262254721Semaste
263254721Semastevoid
264254721SemasteHost::SystemLog (SystemLogType type, const char *format, va_list args)
265254721Semaste{
266254721Semaste    vfprintf (stderr, format, args);
267254721Semaste}
268254721Semaste
269254721Semaste#endif // #if !defined (__APPLE__)
270254721Semaste
271254721Semastevoid
272254721SemasteHost::SystemLog (SystemLogType type, const char *format, ...)
273254721Semaste{
274254721Semaste    va_list args;
275254721Semaste    va_start (args, format);
276254721Semaste    SystemLog (type, format, args);
277254721Semaste    va_end (args);
278254721Semaste}
279254721Semaste
280254721Semastesize_t
281254721SemasteHost::GetPageSize()
282254721Semaste{
283254721Semaste    return ::getpagesize();
284254721Semaste}
285254721Semaste
286254721Semasteconst ArchSpec &
287254721SemasteHost::GetArchitecture (SystemDefaultArchitecture arch_kind)
288254721Semaste{
289254721Semaste    static bool g_supports_32 = false;
290254721Semaste    static bool g_supports_64 = false;
291254721Semaste    static ArchSpec g_host_arch_32;
292254721Semaste    static ArchSpec g_host_arch_64;
293254721Semaste
294254721Semaste#if defined (__APPLE__)
295254721Semaste
296254721Semaste    // Apple is different in that it can support both 32 and 64 bit executables
297254721Semaste    // in the same operating system running concurrently. Here we detect the
298254721Semaste    // correct host architectures for both 32 and 64 bit including if 64 bit
299254721Semaste    // executables are supported on the system.
300254721Semaste
301254721Semaste    if (g_supports_32 == false && g_supports_64 == false)
302254721Semaste    {
303254721Semaste        // All apple systems support 32 bit execution.
304254721Semaste        g_supports_32 = true;
305254721Semaste        uint32_t cputype, cpusubtype;
306254721Semaste        uint32_t is_64_bit_capable = false;
307254721Semaste        size_t len = sizeof(cputype);
308254721Semaste        ArchSpec host_arch;
309254721Semaste        // These will tell us about the kernel architecture, which even on a 64
310254721Semaste        // bit machine can be 32 bit...
311254721Semaste        if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
312254721Semaste        {
313254721Semaste            len = sizeof (cpusubtype);
314254721Semaste            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
315254721Semaste                cpusubtype = CPU_TYPE_ANY;
316254721Semaste
317254721Semaste            len = sizeof (is_64_bit_capable);
318254721Semaste            if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
319254721Semaste            {
320254721Semaste                if (is_64_bit_capable)
321254721Semaste                    g_supports_64 = true;
322254721Semaste            }
323254721Semaste
324254721Semaste            if (is_64_bit_capable)
325254721Semaste            {
326254721Semaste#if defined (__i386__) || defined (__x86_64__)
327254721Semaste                if (cpusubtype == CPU_SUBTYPE_486)
328254721Semaste                    cpusubtype = CPU_SUBTYPE_I386_ALL;
329254721Semaste#endif
330254721Semaste                if (cputype & CPU_ARCH_ABI64)
331254721Semaste                {
332254721Semaste                    // We have a 64 bit kernel on a 64 bit system
333254721Semaste                    g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
334254721Semaste                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
335254721Semaste                }
336254721Semaste                else
337254721Semaste                {
338254721Semaste                    // We have a 32 bit kernel on a 64 bit system
339254721Semaste                    g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
340254721Semaste                    cputype |= CPU_ARCH_ABI64;
341254721Semaste                    g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
342254721Semaste                }
343254721Semaste            }
344254721Semaste            else
345254721Semaste            {
346254721Semaste                g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
347254721Semaste                g_host_arch_64.Clear();
348254721Semaste            }
349254721Semaste        }
350254721Semaste    }
351254721Semaste
352254721Semaste#else // #if defined (__APPLE__)
353254721Semaste
354254721Semaste    if (g_supports_32 == false && g_supports_64 == false)
355254721Semaste    {
356254721Semaste        llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
357254721Semaste
358254721Semaste        g_host_arch_32.Clear();
359254721Semaste        g_host_arch_64.Clear();
360254721Semaste
361254721Semaste        // If the OS is Linux, "unknown" in the vendor slot isn't what we want
362254721Semaste        // for the default triple.  It's probably an artifact of config.guess.
363254721Semaste        if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
364254721Semaste            triple.setVendorName("");
365254721Semaste
366254721Semaste        switch (triple.getArch())
367254721Semaste        {
368254721Semaste        default:
369254721Semaste            g_host_arch_32.SetTriple(triple);
370254721Semaste            g_supports_32 = true;
371254721Semaste            break;
372254721Semaste
373254721Semaste        case llvm::Triple::x86_64:
374254721Semaste            g_host_arch_64.SetTriple(triple);
375254721Semaste            g_supports_64 = true;
376254721Semaste            g_host_arch_32.SetTriple(triple.get32BitArchVariant());
377254721Semaste            g_supports_32 = true;
378254721Semaste            break;
379254721Semaste
380254721Semaste        case llvm::Triple::sparcv9:
381254721Semaste        case llvm::Triple::ppc64:
382254721Semaste            g_host_arch_64.SetTriple(triple);
383254721Semaste            g_supports_64 = true;
384254721Semaste            break;
385254721Semaste        }
386254721Semaste
387254721Semaste        g_supports_32 = g_host_arch_32.IsValid();
388254721Semaste        g_supports_64 = g_host_arch_64.IsValid();
389254721Semaste    }
390254721Semaste
391254721Semaste#endif // #else for #if defined (__APPLE__)
392254721Semaste
393254721Semaste    if (arch_kind == eSystemDefaultArchitecture32)
394254721Semaste        return g_host_arch_32;
395254721Semaste    else if (arch_kind == eSystemDefaultArchitecture64)
396254721Semaste        return g_host_arch_64;
397254721Semaste
398254721Semaste    if (g_supports_64)
399254721Semaste        return g_host_arch_64;
400254721Semaste
401254721Semaste    return g_host_arch_32;
402254721Semaste}
403254721Semaste
404254721Semasteconst ConstString &
405254721SemasteHost::GetVendorString()
406254721Semaste{
407254721Semaste    static ConstString g_vendor;
408254721Semaste    if (!g_vendor)
409254721Semaste    {
410254721Semaste        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
411254721Semaste        const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
412254721Semaste        g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size());
413254721Semaste    }
414254721Semaste    return g_vendor;
415254721Semaste}
416254721Semaste
417254721Semasteconst ConstString &
418254721SemasteHost::GetOSString()
419254721Semaste{
420254721Semaste    static ConstString g_os_string;
421254721Semaste    if (!g_os_string)
422254721Semaste    {
423254721Semaste        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
424254721Semaste        const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
425254721Semaste        g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size());
426254721Semaste    }
427254721Semaste    return g_os_string;
428254721Semaste}
429254721Semaste
430254721Semasteconst ConstString &
431254721SemasteHost::GetTargetTriple()
432254721Semaste{
433254721Semaste    static ConstString g_host_triple;
434254721Semaste    if (!(g_host_triple))
435254721Semaste    {
436254721Semaste        const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
437254721Semaste        g_host_triple.SetCString(host_arch.GetTriple().getTriple().c_str());
438254721Semaste    }
439254721Semaste    return g_host_triple;
440254721Semaste}
441254721Semaste
442254721Semastelldb::pid_t
443254721SemasteHost::GetCurrentProcessID()
444254721Semaste{
445254721Semaste    return ::getpid();
446254721Semaste}
447254721Semaste
448254721Semastelldb::tid_t
449254721SemasteHost::GetCurrentThreadID()
450254721Semaste{
451254721Semaste#if defined (__APPLE__)
452254721Semaste    // Calling "mach_port_deallocate()" bumps the reference count on the thread
453254721Semaste    // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
454254721Semaste    // count.
455254721Semaste    thread_port_t thread_self = mach_thread_self();
456254721Semaste    mach_port_deallocate(mach_task_self(), thread_self);
457254721Semaste    return thread_self;
458254721Semaste#elif defined(__FreeBSD__)
459254721Semaste    return lldb::tid_t(pthread_getthreadid_np());
460254721Semaste#elif defined(__linux__)
461254721Semaste    return lldb::tid_t(syscall(SYS_gettid));
462254721Semaste#else
463254721Semaste    return lldb::tid_t(pthread_self());
464254721Semaste#endif
465254721Semaste}
466254721Semaste
467254721Semastelldb::thread_t
468254721SemasteHost::GetCurrentThread ()
469254721Semaste{
470254721Semaste    return lldb::thread_t(pthread_self());
471254721Semaste}
472254721Semaste
473254721Semasteconst char *
474254721SemasteHost::GetSignalAsCString (int signo)
475254721Semaste{
476254721Semaste    switch (signo)
477254721Semaste    {
478254721Semaste    case SIGHUP:    return "SIGHUP";    // 1    hangup
479254721Semaste    case SIGINT:    return "SIGINT";    // 2    interrupt
480254721Semaste    case SIGQUIT:   return "SIGQUIT";   // 3    quit
481254721Semaste    case SIGILL:    return "SIGILL";    // 4    illegal instruction (not reset when caught)
482254721Semaste    case SIGTRAP:   return "SIGTRAP";   // 5    trace trap (not reset when caught)
483254721Semaste    case SIGABRT:   return "SIGABRT";   // 6    abort()
484254721Semaste#if  (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
485254721Semaste    case SIGPOLL:   return "SIGPOLL";   // 7    pollable event ([XSR] generated, not supported)
486254721Semaste#endif
487254721Semaste#if  !defined(_POSIX_C_SOURCE)
488254721Semaste    case SIGEMT:    return "SIGEMT";    // 7    EMT instruction
489254721Semaste#endif
490254721Semaste    case SIGFPE:    return "SIGFPE";    // 8    floating point exception
491254721Semaste    case SIGKILL:   return "SIGKILL";   // 9    kill (cannot be caught or ignored)
492254721Semaste    case SIGBUS:    return "SIGBUS";    // 10    bus error
493254721Semaste    case SIGSEGV:   return "SIGSEGV";   // 11    segmentation violation
494254721Semaste    case SIGSYS:    return "SIGSYS";    // 12    bad argument to system call
495254721Semaste    case SIGPIPE:   return "SIGPIPE";   // 13    write on a pipe with no one to read it
496254721Semaste    case SIGALRM:   return "SIGALRM";   // 14    alarm clock
497254721Semaste    case SIGTERM:   return "SIGTERM";   // 15    software termination signal from kill
498254721Semaste    case SIGURG:    return "SIGURG";    // 16    urgent condition on IO channel
499254721Semaste    case SIGSTOP:   return "SIGSTOP";   // 17    sendable stop signal not from tty
500254721Semaste    case SIGTSTP:   return "SIGTSTP";   // 18    stop signal from tty
501254721Semaste    case SIGCONT:   return "SIGCONT";   // 19    continue a stopped process
502254721Semaste    case SIGCHLD:   return "SIGCHLD";   // 20    to parent on child stop or exit
503254721Semaste    case SIGTTIN:   return "SIGTTIN";   // 21    to readers pgrp upon background tty read
504254721Semaste    case SIGTTOU:   return "SIGTTOU";   // 22    like TTIN for output if (tp->t_local&LTOSTOP)
505254721Semaste#if  !defined(_POSIX_C_SOURCE)
506254721Semaste    case SIGIO:     return "SIGIO";     // 23    input/output possible signal
507254721Semaste#endif
508254721Semaste    case SIGXCPU:   return "SIGXCPU";   // 24    exceeded CPU time limit
509254721Semaste    case SIGXFSZ:   return "SIGXFSZ";   // 25    exceeded file size limit
510254721Semaste    case SIGVTALRM: return "SIGVTALRM"; // 26    virtual time alarm
511254721Semaste    case SIGPROF:   return "SIGPROF";   // 27    profiling time alarm
512254721Semaste#if  !defined(_POSIX_C_SOURCE)
513254721Semaste    case SIGWINCH:  return "SIGWINCH";  // 28    window size changes
514254721Semaste    case SIGINFO:   return "SIGINFO";   // 29    information request
515254721Semaste#endif
516254721Semaste    case SIGUSR1:   return "SIGUSR1";   // 30    user defined signal 1
517254721Semaste    case SIGUSR2:   return "SIGUSR2";   // 31    user defined signal 2
518254721Semaste    default:
519254721Semaste        break;
520254721Semaste    }
521254721Semaste    return NULL;
522254721Semaste}
523254721Semaste
524254721Semastevoid
525254721SemasteHost::WillTerminate ()
526254721Semaste{
527254721Semaste}
528254721Semaste
529254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__) // see macosx/Host.mm
530254721Semaste
531254721Semastevoid
532254721SemasteHost::ThreadCreated (const char *thread_name)
533254721Semaste{
534254721Semaste}
535254721Semaste
536254721Semastevoid
537254721SemasteHost::Backtrace (Stream &strm, uint32_t max_frames)
538254721Semaste{
539254721Semaste    // TODO: Is there a way to backtrace the current process on other systems?
540254721Semaste}
541254721Semaste
542254721Semastesize_t
543254721SemasteHost::GetEnvironment (StringList &env)
544254721Semaste{
545254721Semaste    // TODO: Is there a way to the host environment for this process on other systems?
546254721Semaste    return 0;
547254721Semaste}
548254721Semaste
549254721Semaste#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__)
550254721Semaste
551254721Semastestruct HostThreadCreateInfo
552254721Semaste{
553254721Semaste    std::string thread_name;
554254721Semaste    thread_func_t thread_fptr;
555254721Semaste    thread_arg_t thread_arg;
556254721Semaste
557254721Semaste    HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
558254721Semaste        thread_name (name ? name : ""),
559254721Semaste        thread_fptr (fptr),
560254721Semaste        thread_arg (arg)
561254721Semaste    {
562254721Semaste    }
563254721Semaste};
564254721Semaste
565254721Semastestatic thread_result_t
566254721SemasteThreadCreateTrampoline (thread_arg_t arg)
567254721Semaste{
568254721Semaste    HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
569254721Semaste    Host::ThreadCreated (info->thread_name.c_str());
570254721Semaste    thread_func_t thread_fptr = info->thread_fptr;
571254721Semaste    thread_arg_t thread_arg = info->thread_arg;
572254721Semaste
573254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
574254721Semaste    if (log)
575254721Semaste        log->Printf("thread created");
576254721Semaste
577254721Semaste    delete info;
578254721Semaste    return thread_fptr (thread_arg);
579254721Semaste}
580254721Semaste
581254721Semastelldb::thread_t
582254721SemasteHost::ThreadCreate
583254721Semaste(
584254721Semaste    const char *thread_name,
585254721Semaste    thread_func_t thread_fptr,
586254721Semaste    thread_arg_t thread_arg,
587254721Semaste    Error *error
588254721Semaste)
589254721Semaste{
590254721Semaste    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
591254721Semaste
592254721Semaste    // Host::ThreadCreateTrampoline will delete this pointer for us.
593254721Semaste    HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
594254721Semaste
595254721Semaste    int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
596254721Semaste    if (err == 0)
597254721Semaste    {
598254721Semaste        if (error)
599254721Semaste            error->Clear();
600254721Semaste        return thread;
601254721Semaste    }
602254721Semaste
603254721Semaste    if (error)
604254721Semaste        error->SetError (err, eErrorTypePOSIX);
605254721Semaste
606254721Semaste    return LLDB_INVALID_HOST_THREAD;
607254721Semaste}
608254721Semaste
609254721Semastebool
610254721SemasteHost::ThreadCancel (lldb::thread_t thread, Error *error)
611254721Semaste{
612254721Semaste    int err = ::pthread_cancel (thread);
613254721Semaste    if (error)
614254721Semaste        error->SetError(err, eErrorTypePOSIX);
615254721Semaste    return err == 0;
616254721Semaste}
617254721Semaste
618254721Semastebool
619254721SemasteHost::ThreadDetach (lldb::thread_t thread, Error *error)
620254721Semaste{
621254721Semaste    int err = ::pthread_detach (thread);
622254721Semaste    if (error)
623254721Semaste        error->SetError(err, eErrorTypePOSIX);
624254721Semaste    return err == 0;
625254721Semaste}
626254721Semaste
627254721Semastebool
628254721SemasteHost::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
629254721Semaste{
630254721Semaste    int err = ::pthread_join (thread, thread_result_ptr);
631254721Semaste    if (error)
632254721Semaste        error->SetError(err, eErrorTypePOSIX);
633254721Semaste    return err == 0;
634254721Semaste}
635254721Semaste
636254721Semastebool
637254721SemasteHost::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
638254721Semaste{
639254721Semaste#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
640254721Semaste    lldb::pid_t curr_pid = Host::GetCurrentProcessID();
641254721Semaste    lldb::tid_t curr_tid = Host::GetCurrentThreadID();
642254721Semaste    if (pid == LLDB_INVALID_PROCESS_ID)
643254721Semaste        pid = curr_pid;
644254721Semaste
645254721Semaste    if (tid == LLDB_INVALID_THREAD_ID)
646254721Semaste        tid = curr_tid;
647254721Semaste
648254721Semaste    // Set the pthread name if possible
649254721Semaste    if (pid == curr_pid && tid == curr_tid)
650254721Semaste    {
651254721Semaste        if (::pthread_setname_np (name) == 0)
652254721Semaste            return true;
653254721Semaste    }
654254721Semaste    return false;
655254721Semaste#elif defined (__FreeBSD__)
656254721Semaste    lldb::pid_t curr_pid = Host::GetCurrentProcessID();
657254721Semaste    lldb::tid_t curr_tid = Host::GetCurrentThreadID();
658254721Semaste    if (pid == LLDB_INVALID_PROCESS_ID)
659254721Semaste        pid = curr_pid;
660254721Semaste
661254721Semaste    if (tid == LLDB_INVALID_THREAD_ID)
662254721Semaste        tid = curr_tid;
663254721Semaste
664254721Semaste    // Set the pthread name if possible
665254721Semaste    if (pid == curr_pid && tid == curr_tid)
666254721Semaste    {
667254721Semaste        ::pthread_set_name_np (::pthread_self(), name);
668254721Semaste        return true;
669254721Semaste    }
670254721Semaste    return false;
671254721Semaste#elif defined (__linux__) || defined (__GLIBC__)
672254721Semaste    void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
673254721Semaste    if (fn)
674254721Semaste    {
675254721Semaste        lldb::pid_t curr_pid = Host::GetCurrentProcessID();
676254721Semaste        lldb::tid_t curr_tid = Host::GetCurrentThreadID();
677254721Semaste        if (pid == LLDB_INVALID_PROCESS_ID)
678254721Semaste            pid = curr_pid;
679254721Semaste
680254721Semaste        if (tid == LLDB_INVALID_THREAD_ID)
681254721Semaste            tid = curr_tid;
682254721Semaste
683254721Semaste        if (pid == curr_pid && tid == curr_tid)
684254721Semaste        {
685254721Semaste            int (*pthread_setname_np_func)(pthread_t thread, const char *name);
686254721Semaste            *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
687254721Semaste
688254721Semaste            if (pthread_setname_np_func (::pthread_self(), name) == 0)
689254721Semaste                return true;
690254721Semaste        }
691254721Semaste    }
692254721Semaste    return false;
693254721Semaste#else
694254721Semaste    return false;
695254721Semaste#endif
696254721Semaste}
697254721Semaste
698254721Semastebool
699254721SemasteHost::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid,
700254721Semaste                          const char *thread_name, size_t len)
701254721Semaste{
702254721Semaste    char *namebuf = (char *)::malloc (len + 1);
703254721Semaste
704254721Semaste    // Thread names are coming in like '<lldb.comm.debugger.edit>' and
705254721Semaste    // '<lldb.comm.debugger.editline>'.  So just chopping the end of the string
706254721Semaste    // off leads to a lot of similar named threads.  Go through the thread name
707254721Semaste    // and search for the last dot and use that.
708254721Semaste    const char *lastdot = ::strrchr (thread_name, '.');
709254721Semaste
710254721Semaste    if (lastdot && lastdot != thread_name)
711254721Semaste        thread_name = lastdot + 1;
712254721Semaste    ::strncpy (namebuf, thread_name, len);
713254721Semaste    namebuf[len] = 0;
714254721Semaste
715254721Semaste    int namebuflen = strlen(namebuf);
716254721Semaste    if (namebuflen > 0)
717254721Semaste    {
718254721Semaste        if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>')
719254721Semaste        {
720254721Semaste            // Trim off trailing '(' and '>' characters for a bit more cleanup.
721254721Semaste            namebuflen--;
722254721Semaste            namebuf[namebuflen] = 0;
723254721Semaste        }
724254721Semaste        return Host::SetThreadName (pid, tid, namebuf);
725254721Semaste    }
726254721Semaste    return false;
727254721Semaste}
728254721Semaste
729254721SemasteFileSpec
730254721SemasteHost::GetProgramFileSpec ()
731254721Semaste{
732254721Semaste    static FileSpec g_program_filespec;
733254721Semaste    if (!g_program_filespec)
734254721Semaste    {
735254721Semaste#if defined (__APPLE__)
736254721Semaste        char program_fullpath[PATH_MAX];
737254721Semaste        // If DST is NULL, then return the number of bytes needed.
738254721Semaste        uint32_t len = sizeof(program_fullpath);
739254721Semaste        int err = _NSGetExecutablePath (program_fullpath, &len);
740254721Semaste        if (err == 0)
741254721Semaste            g_program_filespec.SetFile (program_fullpath, false);
742254721Semaste        else if (err == -1)
743254721Semaste        {
744254721Semaste            char *large_program_fullpath = (char *)::malloc (len + 1);
745254721Semaste
746254721Semaste            err = _NSGetExecutablePath (large_program_fullpath, &len);
747254721Semaste            if (err == 0)
748254721Semaste                g_program_filespec.SetFile (large_program_fullpath, false);
749254721Semaste
750254721Semaste            ::free (large_program_fullpath);
751254721Semaste        }
752254721Semaste#elif defined (__linux__)
753254721Semaste        char exe_path[PATH_MAX];
754254721Semaste        ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
755254721Semaste        if (len > 0) {
756254721Semaste            exe_path[len] = 0;
757254721Semaste            g_program_filespec.SetFile(exe_path, false);
758254721Semaste        }
759254721Semaste#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
760254721Semaste        int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
761254721Semaste        size_t exe_path_size;
762254721Semaste        if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
763254721Semaste        {
764254721Semaste            char *exe_path = new char[exe_path_size];
765254721Semaste            if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
766254721Semaste                g_program_filespec.SetFile(exe_path, false);
767254721Semaste            delete[] exe_path;
768254721Semaste        }
769254721Semaste#endif
770254721Semaste    }
771254721Semaste    return g_program_filespec;
772254721Semaste}
773254721Semaste
774254721SemasteFileSpec
775254721SemasteHost::GetModuleFileSpecForHostAddress (const void *host_addr)
776254721Semaste{
777254721Semaste    FileSpec module_filespec;
778254721Semaste    Dl_info info;
779254721Semaste    if (::dladdr (host_addr, &info))
780254721Semaste    {
781254721Semaste        if (info.dli_fname)
782254721Semaste            module_filespec.SetFile(info.dli_fname, true);
783254721Semaste    }
784254721Semaste    return module_filespec;
785254721Semaste}
786254721Semaste
787254721Semaste#if !defined (__APPLE__) // see Host.mm
788254721Semaste
789254721Semastebool
790254721SemasteHost::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
791254721Semaste{
792254721Semaste    bundle.Clear();
793254721Semaste    return false;
794254721Semaste}
795254721Semaste
796254721Semastebool
797254721SemasteHost::ResolveExecutableInBundle (FileSpec &file)
798254721Semaste{
799254721Semaste    return false;
800254721Semaste}
801254721Semaste#endif
802254721Semaste
803254721Semaste// Opaque info that tracks a dynamic library that was loaded
804254721Semastestruct DynamicLibraryInfo
805254721Semaste{
806254721Semaste    DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
807254721Semaste        file_spec (fs),
808254721Semaste        open_options (o),
809254721Semaste        handle (h)
810254721Semaste    {
811254721Semaste    }
812254721Semaste
813254721Semaste    const FileSpec file_spec;
814254721Semaste    uint32_t open_options;
815254721Semaste    void * handle;
816254721Semaste};
817254721Semaste
818254721Semastevoid *
819254721SemasteHost::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
820254721Semaste{
821254721Semaste    char path[PATH_MAX];
822254721Semaste    if (file_spec.GetPath(path, sizeof(path)))
823254721Semaste    {
824254721Semaste        int mode = 0;
825254721Semaste
826254721Semaste        if (options & eDynamicLibraryOpenOptionLazy)
827254721Semaste            mode |= RTLD_LAZY;
828254721Semaste        else
829254721Semaste            mode |= RTLD_NOW;
830254721Semaste
831254721Semaste
832254721Semaste        if (options & eDynamicLibraryOpenOptionLocal)
833254721Semaste            mode |= RTLD_LOCAL;
834254721Semaste        else
835254721Semaste            mode |= RTLD_GLOBAL;
836254721Semaste
837254721Semaste#ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
838254721Semaste        if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
839254721Semaste            mode |= RTLD_FIRST;
840254721Semaste#endif
841254721Semaste
842254721Semaste        void * opaque = ::dlopen (path, mode);
843254721Semaste
844254721Semaste        if (opaque)
845254721Semaste        {
846254721Semaste            error.Clear();
847254721Semaste            return new DynamicLibraryInfo (file_spec, options, opaque);
848254721Semaste        }
849254721Semaste        else
850254721Semaste        {
851254721Semaste            error.SetErrorString(::dlerror());
852254721Semaste        }
853254721Semaste    }
854254721Semaste    else
855254721Semaste    {
856254721Semaste        error.SetErrorString("failed to extract path");
857254721Semaste    }
858254721Semaste    return NULL;
859254721Semaste}
860254721Semaste
861254721SemasteError
862254721SemasteHost::DynamicLibraryClose (void *opaque)
863254721Semaste{
864254721Semaste    Error error;
865254721Semaste    if (opaque == NULL)
866254721Semaste    {
867254721Semaste        error.SetErrorString ("invalid dynamic library handle");
868254721Semaste    }
869254721Semaste    else
870254721Semaste    {
871254721Semaste        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
872254721Semaste        if (::dlclose (dylib_info->handle) != 0)
873254721Semaste        {
874254721Semaste            error.SetErrorString(::dlerror());
875254721Semaste        }
876254721Semaste
877254721Semaste        dylib_info->open_options = 0;
878254721Semaste        dylib_info->handle = 0;
879254721Semaste        delete dylib_info;
880254721Semaste    }
881254721Semaste    return error;
882254721Semaste}
883254721Semaste
884254721Semastevoid *
885254721SemasteHost::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
886254721Semaste{
887254721Semaste    if (opaque == NULL)
888254721Semaste    {
889254721Semaste        error.SetErrorString ("invalid dynamic library handle");
890254721Semaste    }
891254721Semaste    else
892254721Semaste    {
893254721Semaste        DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
894254721Semaste
895254721Semaste        void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
896254721Semaste        if (symbol_addr)
897254721Semaste        {
898254721Semaste#ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
899254721Semaste            // This host doesn't support limiting searches to this shared library
900254721Semaste            // so we need to verify that the match came from this shared library
901254721Semaste            // if it was requested in the Host::DynamicLibraryOpen() function.
902254721Semaste            if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
903254721Semaste            {
904254721Semaste                FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
905254721Semaste                if (match_dylib_spec != dylib_info->file_spec)
906254721Semaste                {
907254721Semaste                    char dylib_path[PATH_MAX];
908254721Semaste                    if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
909254721Semaste                        error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
910254721Semaste                    else
911254721Semaste                        error.SetErrorString ("symbol not found");
912254721Semaste                    return NULL;
913254721Semaste                }
914254721Semaste            }
915254721Semaste#endif
916254721Semaste            error.Clear();
917254721Semaste            return symbol_addr;
918254721Semaste        }
919254721Semaste        else
920254721Semaste        {
921254721Semaste            error.SetErrorString(::dlerror());
922254721Semaste        }
923254721Semaste    }
924254721Semaste    return NULL;
925254721Semaste}
926254721Semaste
927254721Semastebool
928254721SemasteHost::GetLLDBPath (PathType path_type, FileSpec &file_spec)
929254721Semaste{
930254721Semaste    // To get paths related to LLDB we get the path to the executable that
931254721Semaste    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
932254721Semaste    // on linux this is assumed to be the "lldb" main executable. If LLDB on
933254721Semaste    // linux is actually in a shared library (liblldb.so) then this function will
934254721Semaste    // need to be modified to "do the right thing".
935254721Semaste
936254721Semaste    switch (path_type)
937254721Semaste    {
938254721Semaste    case ePathTypeLLDBShlibDir:
939254721Semaste        {
940254721Semaste            static ConstString g_lldb_so_dir;
941254721Semaste            if (!g_lldb_so_dir)
942254721Semaste            {
943254721Semaste                FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
944254721Semaste                g_lldb_so_dir = lldb_file_spec.GetDirectory();
945254721Semaste            }
946254721Semaste            file_spec.GetDirectory() = g_lldb_so_dir;
947254721Semaste            return file_spec.GetDirectory();
948254721Semaste        }
949254721Semaste        break;
950254721Semaste
951254721Semaste    case ePathTypeSupportExecutableDir:
952254721Semaste        {
953254721Semaste            static ConstString g_lldb_support_exe_dir;
954254721Semaste            if (!g_lldb_support_exe_dir)
955254721Semaste            {
956254721Semaste                FileSpec lldb_file_spec;
957254721Semaste                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
958254721Semaste                {
959254721Semaste                    char raw_path[PATH_MAX];
960254721Semaste                    char resolved_path[PATH_MAX];
961254721Semaste                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
962254721Semaste
963254721Semaste#if defined (__APPLE__)
964254721Semaste                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
965254721Semaste                    if (framework_pos)
966254721Semaste                    {
967254721Semaste                        framework_pos += strlen("LLDB.framework");
968254721Semaste#if !defined (__arm__)
969254721Semaste                        ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
970254721Semaste#endif
971254721Semaste                    }
972254721Semaste#endif
973254721Semaste                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
974254721Semaste                    g_lldb_support_exe_dir.SetCString(resolved_path);
975254721Semaste                }
976254721Semaste            }
977254721Semaste            file_spec.GetDirectory() = g_lldb_support_exe_dir;
978254721Semaste            return file_spec.GetDirectory();
979254721Semaste        }
980254721Semaste        break;
981254721Semaste
982254721Semaste    case ePathTypeHeaderDir:
983254721Semaste        {
984254721Semaste            static ConstString g_lldb_headers_dir;
985254721Semaste            if (!g_lldb_headers_dir)
986254721Semaste            {
987254721Semaste#if defined (__APPLE__)
988254721Semaste                FileSpec lldb_file_spec;
989254721Semaste                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
990254721Semaste                {
991254721Semaste                    char raw_path[PATH_MAX];
992254721Semaste                    char resolved_path[PATH_MAX];
993254721Semaste                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
994254721Semaste
995254721Semaste                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
996254721Semaste                    if (framework_pos)
997254721Semaste                    {
998254721Semaste                        framework_pos += strlen("LLDB.framework");
999254721Semaste                        ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
1000254721Semaste                    }
1001254721Semaste                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1002254721Semaste                    g_lldb_headers_dir.SetCString(resolved_path);
1003254721Semaste                }
1004254721Semaste#else
1005254721Semaste                // TODO: Anyone know how we can determine this for linux? Other systems??
1006254721Semaste                g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
1007254721Semaste#endif
1008254721Semaste            }
1009254721Semaste            file_spec.GetDirectory() = g_lldb_headers_dir;
1010254721Semaste            return file_spec.GetDirectory();
1011254721Semaste        }
1012254721Semaste        break;
1013254721Semaste
1014254721Semaste#ifndef LLDB_DISABLE_PYTHON
1015254721Semaste    case ePathTypePythonDir:
1016254721Semaste        {
1017254721Semaste            static ConstString g_lldb_python_dir;
1018254721Semaste            if (!g_lldb_python_dir)
1019254721Semaste            {
1020254721Semaste                FileSpec lldb_file_spec;
1021254721Semaste                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1022254721Semaste                {
1023254721Semaste                    char raw_path[PATH_MAX];
1024254721Semaste                    char resolved_path[PATH_MAX];
1025254721Semaste                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1026254721Semaste
1027254721Semaste#if defined (__APPLE__)
1028254721Semaste                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1029254721Semaste                    if (framework_pos)
1030254721Semaste                    {
1031254721Semaste                        framework_pos += strlen("LLDB.framework");
1032254721Semaste                        ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1033254721Semaste                    }
1034254721Semaste#else
1035254721Semaste                    llvm::SmallString<256> python_version_dir;
1036254721Semaste                    llvm::raw_svector_ostream os(python_version_dir);
1037254721Semaste                    os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages";
1038254721Semaste                    os.flush();
1039254721Semaste
1040254721Semaste                    // We may get our string truncated. Should we protect
1041254721Semaste                    // this with an assert?
1042254721Semaste
1043254721Semaste                    ::strncat(raw_path, python_version_dir.c_str(),
1044254721Semaste                              sizeof(raw_path) - strlen(raw_path) - 1);
1045254721Semaste
1046254721Semaste#endif
1047254721Semaste                    FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1048254721Semaste                    g_lldb_python_dir.SetCString(resolved_path);
1049254721Semaste                }
1050254721Semaste            }
1051254721Semaste            file_spec.GetDirectory() = g_lldb_python_dir;
1052254721Semaste            return file_spec.GetDirectory();
1053254721Semaste        }
1054254721Semaste        break;
1055254721Semaste#endif
1056254721Semaste
1057254721Semaste    case ePathTypeLLDBSystemPlugins:    // System plug-ins directory
1058254721Semaste        {
1059254721Semaste#if defined (__APPLE__) || defined(__linux__)
1060254721Semaste            static ConstString g_lldb_system_plugin_dir;
1061254721Semaste            static bool g_lldb_system_plugin_dir_located = false;
1062254721Semaste            if (!g_lldb_system_plugin_dir_located)
1063254721Semaste            {
1064254721Semaste                g_lldb_system_plugin_dir_located = true;
1065254721Semaste#if defined (__APPLE__)
1066254721Semaste                FileSpec lldb_file_spec;
1067254721Semaste                if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1068254721Semaste                {
1069254721Semaste                    char raw_path[PATH_MAX];
1070254721Semaste                    char resolved_path[PATH_MAX];
1071254721Semaste                    lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1072254721Semaste
1073254721Semaste                    char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1074254721Semaste                    if (framework_pos)
1075254721Semaste                    {
1076254721Semaste                        framework_pos += strlen("LLDB.framework");
1077254721Semaste                        ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
1078254721Semaste                        FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1079254721Semaste                        g_lldb_system_plugin_dir.SetCString(resolved_path);
1080254721Semaste                    }
1081254721Semaste                    return false;
1082254721Semaste                }
1083254721Semaste#elif defined (__linux__)
1084254721Semaste                FileSpec lldb_file_spec("/usr/lib/lldb", true);
1085254721Semaste                if (lldb_file_spec.Exists())
1086254721Semaste                {
1087254721Semaste                    g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1088254721Semaste                }
1089254721Semaste#endif // __APPLE__ || __linux__
1090254721Semaste            }
1091254721Semaste
1092254721Semaste            if (g_lldb_system_plugin_dir)
1093254721Semaste            {
1094254721Semaste                file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1095254721Semaste                return true;
1096254721Semaste            }
1097254721Semaste#else
1098254721Semaste            // TODO: where would system LLDB plug-ins be located on other systems?
1099254721Semaste            return false;
1100254721Semaste#endif
1101254721Semaste        }
1102254721Semaste        break;
1103254721Semaste
1104254721Semaste    case ePathTypeLLDBUserPlugins:      // User plug-ins directory
1105254721Semaste        {
1106254721Semaste#if defined (__APPLE__)
1107254721Semaste            static ConstString g_lldb_user_plugin_dir;
1108254721Semaste            if (!g_lldb_user_plugin_dir)
1109254721Semaste            {
1110254721Semaste                char user_plugin_path[PATH_MAX];
1111254721Semaste                if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1112254721Semaste                                       user_plugin_path,
1113254721Semaste                                       sizeof(user_plugin_path)))
1114254721Semaste                {
1115254721Semaste                    g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1116254721Semaste                }
1117254721Semaste            }
1118254721Semaste            file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1119254721Semaste            return file_spec.GetDirectory();
1120254721Semaste#elif defined (__linux__)
1121254721Semaste            static ConstString g_lldb_user_plugin_dir;
1122254721Semaste            if (!g_lldb_user_plugin_dir)
1123254721Semaste            {
1124254721Semaste                // XDG Base Directory Specification
1125254721Semaste                // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
1126254721Semaste                // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
1127254721Semaste                FileSpec lldb_file_spec;
1128254721Semaste                const char *xdg_data_home = getenv("XDG_DATA_HOME");
1129254721Semaste                if (xdg_data_home && xdg_data_home[0])
1130254721Semaste                {
1131254721Semaste                    std::string user_plugin_dir (xdg_data_home);
1132254721Semaste                    user_plugin_dir += "/lldb";
1133254721Semaste                    lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1134254721Semaste                }
1135254721Semaste                else
1136254721Semaste                {
1137254721Semaste                    const char *home_dir = getenv("HOME");
1138254721Semaste                    if (home_dir && home_dir[0])
1139254721Semaste                    {
1140254721Semaste                        std::string user_plugin_dir (home_dir);
1141254721Semaste                        user_plugin_dir += "/.local/share/lldb";
1142254721Semaste                        lldb_file_spec.SetFile (user_plugin_dir.c_str(), true);
1143254721Semaste                    }
1144254721Semaste                }
1145254721Semaste
1146254721Semaste                if (lldb_file_spec.Exists())
1147254721Semaste                    g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str());
1148254721Semaste            }
1149254721Semaste            file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1150254721Semaste            return file_spec.GetDirectory();
1151254721Semaste#endif
1152254721Semaste            // TODO: where would user LLDB plug-ins be located on other systems?
1153254721Semaste            return false;
1154254721Semaste        }
1155254721Semaste    }
1156254721Semaste
1157254721Semaste    return false;
1158254721Semaste}
1159254721Semaste
1160254721Semaste
1161254721Semastebool
1162254721SemasteHost::GetHostname (std::string &s)
1163254721Semaste{
1164254721Semaste    char hostname[PATH_MAX];
1165254721Semaste    hostname[sizeof(hostname) - 1] = '\0';
1166254721Semaste    if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1167254721Semaste    {
1168254721Semaste        struct hostent* h = ::gethostbyname (hostname);
1169254721Semaste        if (h)
1170254721Semaste            s.assign (h->h_name);
1171254721Semaste        else
1172254721Semaste            s.assign (hostname);
1173254721Semaste        return true;
1174254721Semaste    }
1175254721Semaste    return false;
1176254721Semaste}
1177254721Semaste
1178254721Semasteconst char *
1179254721SemasteHost::GetUserName (uint32_t uid, std::string &user_name)
1180254721Semaste{
1181254721Semaste    struct passwd user_info;
1182254721Semaste    struct passwd *user_info_ptr = &user_info;
1183254721Semaste    char user_buffer[PATH_MAX];
1184254721Semaste    size_t user_buffer_size = sizeof(user_buffer);
1185254721Semaste    if (::getpwuid_r (uid,
1186254721Semaste                      &user_info,
1187254721Semaste                      user_buffer,
1188254721Semaste                      user_buffer_size,
1189254721Semaste                      &user_info_ptr) == 0)
1190254721Semaste    {
1191254721Semaste        if (user_info_ptr)
1192254721Semaste        {
1193254721Semaste            user_name.assign (user_info_ptr->pw_name);
1194254721Semaste            return user_name.c_str();
1195254721Semaste        }
1196254721Semaste    }
1197254721Semaste    user_name.clear();
1198254721Semaste    return NULL;
1199254721Semaste}
1200254721Semaste
1201254721Semasteconst char *
1202254721SemasteHost::GetGroupName (uint32_t gid, std::string &group_name)
1203254721Semaste{
1204254721Semaste    char group_buffer[PATH_MAX];
1205254721Semaste    size_t group_buffer_size = sizeof(group_buffer);
1206254721Semaste    struct group group_info;
1207254721Semaste    struct group *group_info_ptr = &group_info;
1208254721Semaste    // Try the threadsafe version first
1209254721Semaste    if (::getgrgid_r (gid,
1210254721Semaste                      &group_info,
1211254721Semaste                      group_buffer,
1212254721Semaste                      group_buffer_size,
1213254721Semaste                      &group_info_ptr) == 0)
1214254721Semaste    {
1215254721Semaste        if (group_info_ptr)
1216254721Semaste        {
1217254721Semaste            group_name.assign (group_info_ptr->gr_name);
1218254721Semaste            return group_name.c_str();
1219254721Semaste        }
1220254721Semaste    }
1221254721Semaste    else
1222254721Semaste    {
1223254721Semaste        // The threadsafe version isn't currently working
1224254721Semaste        // for me on darwin, but the non-threadsafe version
1225254721Semaste        // is, so I am calling it below.
1226254721Semaste        group_info_ptr = ::getgrgid (gid);
1227254721Semaste        if (group_info_ptr)
1228254721Semaste        {
1229254721Semaste            group_name.assign (group_info_ptr->gr_name);
1230254721Semaste            return group_name.c_str();
1231254721Semaste        }
1232254721Semaste    }
1233254721Semaste    group_name.clear();
1234254721Semaste    return NULL;
1235254721Semaste}
1236254721Semaste
1237254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) // see macosx/Host.mm
1238254721Semastebool
1239254721SemasteHost::GetOSBuildString (std::string &s)
1240254721Semaste{
1241254721Semaste    s.clear();
1242254721Semaste    return false;
1243254721Semaste}
1244254721Semaste
1245254721Semastebool
1246254721SemasteHost::GetOSKernelDescription (std::string &s)
1247254721Semaste{
1248254721Semaste    s.clear();
1249254721Semaste    return false;
1250254721Semaste}
1251254721Semaste#endif
1252254721Semaste
1253254721Semasteuint32_t
1254254721SemasteHost::GetUserID ()
1255254721Semaste{
1256254721Semaste    return getuid();
1257254721Semaste}
1258254721Semaste
1259254721Semasteuint32_t
1260254721SemasteHost::GetGroupID ()
1261254721Semaste{
1262254721Semaste    return getgid();
1263254721Semaste}
1264254721Semaste
1265254721Semasteuint32_t
1266254721SemasteHost::GetEffectiveUserID ()
1267254721Semaste{
1268254721Semaste    return geteuid();
1269254721Semaste}
1270254721Semaste
1271254721Semasteuint32_t
1272254721SemasteHost::GetEffectiveGroupID ()
1273254721Semaste{
1274254721Semaste    return getegid();
1275254721Semaste}
1276254721Semaste
1277254721Semaste#if !defined (__APPLE__) && !defined(__linux__)
1278254721Semasteuint32_t
1279254721SemasteHost::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
1280254721Semaste{
1281254721Semaste    process_infos.Clear();
1282254721Semaste    return process_infos.GetSize();
1283254721Semaste}
1284254721Semaste#endif // #if !defined (__APPLE__) && !defined(__linux__)
1285254721Semaste
1286254721Semaste#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined(__linux__)
1287254721Semastebool
1288254721SemasteHost::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1289254721Semaste{
1290254721Semaste    process_info.Clear();
1291254721Semaste    return false;
1292254721Semaste}
1293254721Semaste#endif
1294254721Semaste
1295254721Semaste#if !defined(__linux__)
1296254721Semastebool
1297254721SemasteHost::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
1298254721Semaste{
1299254721Semaste    return false;
1300254721Semaste}
1301254721Semaste#endif
1302254721Semaste
1303254721Semastelldb::TargetSP
1304254721SemasteHost::GetDummyTarget (lldb_private::Debugger &debugger)
1305254721Semaste{
1306254721Semaste    static TargetSP g_dummy_target_sp;
1307254721Semaste
1308254721Semaste    // FIXME: Maybe the dummy target should be per-Debugger
1309254721Semaste    if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
1310254721Semaste    {
1311254721Semaste        ArchSpec arch(Target::GetDefaultArchitecture());
1312254721Semaste        if (!arch.IsValid())
1313254721Semaste            arch = Host::GetArchitecture ();
1314254721Semaste        Error err = debugger.GetTargetList().CreateTarget(debugger,
1315254721Semaste                                                          NULL,
1316254721Semaste                                                          arch.GetTriple().getTriple().c_str(),
1317254721Semaste                                                          false,
1318254721Semaste                                                          NULL,
1319254721Semaste                                                          g_dummy_target_sp);
1320254721Semaste    }
1321254721Semaste
1322254721Semaste    return g_dummy_target_sp;
1323254721Semaste}
1324254721Semaste
1325254721Semastestruct ShellInfo
1326254721Semaste{
1327254721Semaste    ShellInfo () :
1328254721Semaste        process_reaped (false),
1329254721Semaste        can_delete (false),
1330254721Semaste        pid (LLDB_INVALID_PROCESS_ID),
1331254721Semaste        signo(-1),
1332254721Semaste        status(-1)
1333254721Semaste    {
1334254721Semaste    }
1335254721Semaste
1336254721Semaste    lldb_private::Predicate<bool> process_reaped;
1337254721Semaste    lldb_private::Predicate<bool> can_delete;
1338254721Semaste    lldb::pid_t pid;
1339254721Semaste    int signo;
1340254721Semaste    int status;
1341254721Semaste};
1342254721Semaste
1343254721Semastestatic bool
1344254721SemasteMonitorShellCommand (void *callback_baton,
1345254721Semaste                     lldb::pid_t pid,
1346254721Semaste                     bool exited,       // True if the process did exit
1347254721Semaste                     int signo,         // Zero for no signal
1348254721Semaste                     int status)   // Exit value of process if signal is zero
1349254721Semaste{
1350254721Semaste    ShellInfo *shell_info = (ShellInfo *)callback_baton;
1351254721Semaste    shell_info->pid = pid;
1352254721Semaste    shell_info->signo = signo;
1353254721Semaste    shell_info->status = status;
1354254721Semaste    // Let the thread running Host::RunShellCommand() know that the process
1355254721Semaste    // exited and that ShellInfo has been filled in by broadcasting to it
1356254721Semaste    shell_info->process_reaped.SetValue(1, eBroadcastAlways);
1357254721Semaste    // Now wait for a handshake back from that thread running Host::RunShellCommand
1358254721Semaste    // so we know that we can delete shell_info_ptr
1359254721Semaste    shell_info->can_delete.WaitForValueEqualTo(true);
1360254721Semaste    // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
1361254721Semaste    usleep(1000);
1362254721Semaste    // Now delete the shell info that was passed into this function
1363254721Semaste    delete shell_info;
1364254721Semaste    return true;
1365254721Semaste}
1366254721Semaste
1367254721SemasteError
1368254721SemasteHost::RunShellCommand (const char *command,
1369254721Semaste                       const char *working_dir,
1370254721Semaste                       int *status_ptr,
1371254721Semaste                       int *signo_ptr,
1372254721Semaste                       std::string *command_output_ptr,
1373254721Semaste                       uint32_t timeout_sec,
1374254721Semaste                       const char *shell)
1375254721Semaste{
1376254721Semaste    Error error;
1377254721Semaste    ProcessLaunchInfo launch_info;
1378254721Semaste    if (shell && shell[0])
1379254721Semaste    {
1380254721Semaste        // Run the command in a shell
1381254721Semaste        launch_info.SetShell(shell);
1382254721Semaste        launch_info.GetArguments().AppendArgument(command);
1383254721Semaste        const bool localhost = true;
1384254721Semaste        const bool will_debug = false;
1385254721Semaste        const bool first_arg_is_full_shell_command = true;
1386254721Semaste        launch_info.ConvertArgumentsForLaunchingInShell (error,
1387254721Semaste                                                         localhost,
1388254721Semaste                                                         will_debug,
1389254721Semaste                                                         first_arg_is_full_shell_command);
1390254721Semaste    }
1391254721Semaste    else
1392254721Semaste    {
1393254721Semaste        // No shell, just run it
1394254721Semaste        Args args (command);
1395254721Semaste        const bool first_arg_is_executable = true;
1396254721Semaste        launch_info.SetArguments(args, first_arg_is_executable);
1397254721Semaste    }
1398254721Semaste
1399254721Semaste    if (working_dir)
1400254721Semaste        launch_info.SetWorkingDirectory(working_dir);
1401254721Semaste    char output_file_path_buffer[L_tmpnam];
1402254721Semaste    const char *output_file_path = NULL;
1403254721Semaste    if (command_output_ptr)
1404254721Semaste    {
1405254721Semaste        // Create a temporary file to get the stdout/stderr and redirect the
1406254721Semaste        // output of the command into this file. We will later read this file
1407254721Semaste        // if all goes well and fill the data into "command_output_ptr"
1408254721Semaste        output_file_path = ::tmpnam(output_file_path_buffer);
1409254721Semaste        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1410254721Semaste        launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
1411254721Semaste        launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
1412254721Semaste    }
1413254721Semaste    else
1414254721Semaste    {
1415254721Semaste        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
1416254721Semaste        launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
1417254721Semaste        launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
1418254721Semaste    }
1419254721Semaste
1420254721Semaste    // The process monitor callback will delete the 'shell_info_ptr' below...
1421254721Semaste    std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
1422254721Semaste
1423254721Semaste    const bool monitor_signals = false;
1424254721Semaste    launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
1425254721Semaste
1426254721Semaste    error = LaunchProcess (launch_info);
1427254721Semaste    const lldb::pid_t pid = launch_info.GetProcessID();
1428254721Semaste    if (pid != LLDB_INVALID_PROCESS_ID)
1429254721Semaste    {
1430254721Semaste        // The process successfully launched, so we can defer ownership of
1431254721Semaste        // "shell_info" to the MonitorShellCommand callback function that will
1432254721Semaste        // get called when the process dies. We release the unique pointer as it
1433254721Semaste        // doesn't need to delete the ShellInfo anymore.
1434254721Semaste        ShellInfo *shell_info = shell_info_ap.release();
1435254721Semaste        TimeValue timeout_time(TimeValue::Now());
1436254721Semaste        timeout_time.OffsetWithSeconds(timeout_sec);
1437254721Semaste        bool timed_out = false;
1438254721Semaste        shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1439254721Semaste        if (timed_out)
1440254721Semaste        {
1441254721Semaste            error.SetErrorString("timed out waiting for shell command to complete");
1442254721Semaste
1443254721Semaste            // Kill the process since it didn't complete withint the timeout specified
1444254721Semaste            ::kill (pid, SIGKILL);
1445254721Semaste            // Wait for the monitor callback to get the message
1446254721Semaste            timeout_time = TimeValue::Now();
1447254721Semaste            timeout_time.OffsetWithSeconds(1);
1448254721Semaste            timed_out = false;
1449254721Semaste            shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
1450254721Semaste        }
1451254721Semaste        else
1452254721Semaste        {
1453254721Semaste            if (status_ptr)
1454254721Semaste                *status_ptr = shell_info->status;
1455254721Semaste
1456254721Semaste            if (signo_ptr)
1457254721Semaste                *signo_ptr = shell_info->signo;
1458254721Semaste
1459254721Semaste            if (command_output_ptr)
1460254721Semaste            {
1461254721Semaste                command_output_ptr->clear();
1462254721Semaste                FileSpec file_spec(output_file_path, File::eOpenOptionRead);
1463254721Semaste                uint64_t file_size = file_spec.GetByteSize();
1464254721Semaste                if (file_size > 0)
1465254721Semaste                {
1466254721Semaste                    if (file_size > command_output_ptr->max_size())
1467254721Semaste                    {
1468254721Semaste                        error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
1469254721Semaste                    }
1470254721Semaste                    else
1471254721Semaste                    {
1472254721Semaste                        command_output_ptr->resize(file_size);
1473254721Semaste                        file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
1474254721Semaste                    }
1475254721Semaste                }
1476254721Semaste            }
1477254721Semaste        }
1478254721Semaste        shell_info->can_delete.SetValue(true, eBroadcastAlways);
1479254721Semaste    }
1480254721Semaste    else
1481254721Semaste    {
1482254721Semaste        error.SetErrorString("failed to get process ID");
1483254721Semaste    }
1484254721Semaste
1485254721Semaste    if (output_file_path)
1486254721Semaste        ::unlink (output_file_path);
1487254721Semaste    // Handshake with the monitor thread, or just let it know in advance that
1488254721Semaste    // it can delete "shell_info" in case we timed out and were not able to kill
1489254721Semaste    // the process...
1490254721Semaste    return error;
1491254721Semaste}
1492254721Semaste
1493254721Semaste
1494254721Semasteuint32_t
1495254721SemasteHost::GetNumberCPUS ()
1496254721Semaste{
1497254721Semaste    static uint32_t g_num_cores = UINT32_MAX;
1498254721Semaste    if (g_num_cores == UINT32_MAX)
1499254721Semaste    {
1500254721Semaste#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__) or defined (__FreeBSD_kernel__)
1501254721Semaste
1502254721Semaste        g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
1503254721Semaste
1504254721Semaste#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
1505254721Semaste
1506254721Semaste        // Header file for this might need to be included at the top of this file
1507254721Semaste        SYSTEM_INFO system_info;
1508254721Semaste        ::GetSystemInfo (&system_info);
1509254721Semaste        g_num_cores = system_info.dwNumberOfProcessors;
1510254721Semaste
1511254721Semaste#else
1512254721Semaste
1513254721Semaste        // Assume POSIX support if a host specific case has not been supplied above
1514254721Semaste        g_num_cores = 0;
1515254721Semaste        int num_cores = 0;
1516254721Semaste        size_t num_cores_len = sizeof(num_cores);
1517254721Semaste#ifdef HW_AVAILCPU
1518254721Semaste        int mib[] = { CTL_HW, HW_AVAILCPU };
1519254721Semaste#else
1520254721Semaste        int mib[] = { CTL_HW, HW_NCPU };
1521254721Semaste#endif
1522254721Semaste
1523254721Semaste        /* get the number of CPUs from the system */
1524254721Semaste        if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1525254721Semaste        {
1526254721Semaste            g_num_cores = num_cores;
1527254721Semaste        }
1528254721Semaste        else
1529254721Semaste        {
1530254721Semaste            mib[1] = HW_NCPU;
1531254721Semaste            num_cores_len = sizeof(num_cores);
1532254721Semaste            if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
1533254721Semaste            {
1534254721Semaste                if (num_cores > 0)
1535254721Semaste                    g_num_cores = num_cores;
1536254721Semaste            }
1537254721Semaste        }
1538254721Semaste#endif
1539254721Semaste    }
1540254721Semaste    return g_num_cores;
1541254721Semaste}
1542254721Semaste
1543254721Semaste
1544254721Semaste
1545254721Semaste#if !defined (__APPLE__)
1546254721Semastebool
1547254721SemasteHost::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1548254721Semaste{
1549254721Semaste    return false;
1550254721Semaste}
1551254721Semaste
1552254721Semastevoid
1553254721SemasteHost::SetCrashDescriptionWithFormat (const char *format, ...)
1554254721Semaste{
1555254721Semaste}
1556254721Semaste
1557254721Semastevoid
1558254721SemasteHost::SetCrashDescription (const char *description)
1559254721Semaste{
1560254721Semaste}
1561254721Semaste
1562254721Semastelldb::pid_t
1563254721SemasteLaunchApplication (const FileSpec &app_file_spec)
1564254721Semaste{
1565254721Semaste    return LLDB_INVALID_PROCESS_ID;
1566254721Semaste}
1567254721Semaste
1568254721Semaste#endif
1569