1 //===-- Host.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 "lldb/Host/Host.h"
11 #include "lldb/Core/ArchSpec.h"
12 #include "lldb/Core/ConstString.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Error.h"
15 #include "lldb/Core/Log.h"
16 #include "lldb/Core/StreamString.h"
17 #include "lldb/Host/Config.h"
18 #include "lldb/Host/Endian.h"
19 #include "lldb/Host/FileSpec.h"
20 #include "lldb/Host/Mutex.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/TargetList.h"
23 
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/MachO.h"
26 
27 #include <dlfcn.h>
28 #include <errno.h>
29 #include <grp.h>
30 #include <limits.h>
31 #include <netdb.h>
32 #include <pwd.h>
33 #include <sys/types.h>
34 
35 
36 #if defined (__APPLE__)
37 
38 #include <dispatch/dispatch.h>
39 #include <libproc.h>
40 #include <mach-o/dyld.h>
41 #include <sys/sysctl.h>
42 
43 
44 #elif defined (__linux__)
45 
46 #include <sys/wait.h>
47 
48 #elif defined (__FreeBSD__)
49 
50 #include <sys/wait.h>
51 #include <sys/sysctl.h>
52 #include <pthread_np.h>
53 
54 #endif
55 
56 using namespace lldb;
57 using namespace lldb_private;
58 
59 
60 #if !defined (__APPLE__)
61 struct MonitorInfo
62 {
63     lldb::pid_t pid;                            // The process ID to monitor
64     Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
65     void *callback_baton;                       // The callback baton for the callback function
66     bool monitor_signals;                       // If true, call the callback when "pid" gets signaled.
67 };
68 
69 static void *
70 MonitorChildProcessThreadFunction (void *arg);
71 
72 lldb::thread_t
73 Host::StartMonitoringChildProcess
74 (
75     Host::MonitorChildProcessCallback callback,
76     void *callback_baton,
77     lldb::pid_t pid,
78     bool monitor_signals
79 )
80 {
81     lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
82     MonitorInfo * info_ptr = new MonitorInfo();
83 
84     info_ptr->pid = pid;
85     info_ptr->callback = callback;
86     info_ptr->callback_baton = callback_baton;
87     info_ptr->monitor_signals = monitor_signals;
88 
89     char thread_name[256];
90     ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
91     thread = ThreadCreate (thread_name,
92                            MonitorChildProcessThreadFunction,
93                            info_ptr,
94                            NULL);
95 
96     return thread;
97 }
98 
99 //------------------------------------------------------------------
100 // Scoped class that will disable thread canceling when it is
101 // constructed, and exception safely restore the previous value it
102 // when it goes out of scope.
103 //------------------------------------------------------------------
104 class ScopedPThreadCancelDisabler
105 {
106 public:
107     ScopedPThreadCancelDisabler()
108     {
109         // Disable the ability for this thread to be cancelled
110         int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &m_old_state);
111         if (err != 0)
112             m_old_state = -1;
113 
114     }
115 
116     ~ScopedPThreadCancelDisabler()
117     {
118         // Restore the ability for this thread to be cancelled to what it
119         // previously was.
120         if (m_old_state != -1)
121             ::pthread_setcancelstate (m_old_state, 0);
122     }
123 private:
124     int m_old_state;    // Save the old cancelability state.
125 };
126 
127 static void *
128 MonitorChildProcessThreadFunction (void *arg)
129 {
130     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
131     const char *function = __FUNCTION__;
132     if (log)
133         log->Printf ("%s (arg = %p) thread starting...", function, arg);
134 
135     MonitorInfo *info = (MonitorInfo *)arg;
136 
137     const Host::MonitorChildProcessCallback callback = info->callback;
138     void * const callback_baton = info->callback_baton;
139     const lldb::pid_t pid = info->pid;
140     const bool monitor_signals = info->monitor_signals;
141 
142     delete info;
143 
144     int status = -1;
145     const int options = 0;
146     while (1)
147     {
148         log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
149         if (log)
150             log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options);
151 
152         // Wait for all child processes
153         ::pthread_testcancel ();
154         const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
155         ::pthread_testcancel ();
156 
157         if (wait_pid == -1)
158         {
159             if (errno == EINTR)
160                 continue;
161             else
162                 break;
163         }
164         else if (wait_pid == pid)
165         {
166             bool exited = false;
167             int signal = 0;
168             int exit_status = 0;
169             const char *status_cstr = NULL;
170             if (WIFSTOPPED(status))
171             {
172                 signal = WSTOPSIG(status);
173                 status_cstr = "STOPPED";
174             }
175             else if (WIFEXITED(status))
176             {
177                 exit_status = WEXITSTATUS(status);
178                 status_cstr = "EXITED";
179                 exited = true;
180             }
181             else if (WIFSIGNALED(status))
182             {
183                 signal = WTERMSIG(status);
184                 status_cstr = "SIGNALED";
185                 exited = true;
186                 exit_status = -1;
187             }
188             else
189             {
190                 status_cstr = "(\?\?\?)";
191             }
192 
193             // Scope for pthread_cancel_disabler
194             {
195                 ScopedPThreadCancelDisabler pthread_cancel_disabler;
196 
197                 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
198                 if (log)
199                     log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
200                                  function,
201                                  wait_pid,
202                                  options,
203                                  pid,
204                                  status,
205                                  status_cstr,
206                                  signal,
207                                  exit_status);
208 
209                 if (exited || (signal != 0 && monitor_signals))
210                 {
211                     bool callback_return = false;
212                     if (callback)
213                         callback_return = callback (callback_baton, pid, exited, signal, exit_status);
214 
215                     // If our process exited, then this thread should exit
216                     if (exited)
217                         break;
218                     // If the callback returns true, it means this process should
219                     // exit
220                     if (callback_return)
221                         break;
222                 }
223             }
224         }
225     }
226 
227     log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
228     if (log)
229         log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
230 
231     return NULL;
232 }
233 
234 
235 void
236 Host::SystemLog (SystemLogType type, const char *format, va_list args)
237 {
238     vfprintf (stderr, format, args);
239 }
240 
241 #endif // #if !defined (__APPLE__)
242 
243 void
244 Host::SystemLog (SystemLogType type, const char *format, ...)
245 {
246     va_list args;
247     va_start (args, format);
248     SystemLog (type, format, args);
249     va_end (args);
250 }
251 
252 size_t
253 Host::GetPageSize()
254 {
255     return ::getpagesize();
256 }
257 
258 const ArchSpec &
259 Host::GetArchitecture (SystemDefaultArchitecture arch_kind)
260 {
261     static bool g_supports_32 = false;
262     static bool g_supports_64 = false;
263     static ArchSpec g_host_arch_32;
264     static ArchSpec g_host_arch_64;
265 
266 #if defined (__APPLE__)
267 
268     // Apple is different in that it can support both 32 and 64 bit executables
269     // in the same operating system running concurrently. Here we detect the
270     // correct host architectures for both 32 and 64 bit including if 64 bit
271     // executables are supported on the system.
272 
273     if (g_supports_32 == false && g_supports_64 == false)
274     {
275         // All apple systems support 32 bit execution.
276         g_supports_32 = true;
277         uint32_t cputype, cpusubtype;
278         uint32_t is_64_bit_capable = false;
279         size_t len = sizeof(cputype);
280         ArchSpec host_arch;
281         // These will tell us about the kernel architecture, which even on a 64
282         // bit machine can be 32 bit...
283         if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
284         {
285             len = sizeof (cpusubtype);
286             if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
287                 cpusubtype = CPU_TYPE_ANY;
288 
289             len = sizeof (is_64_bit_capable);
290             if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
291             {
292                 if (is_64_bit_capable)
293                     g_supports_64 = true;
294             }
295 
296             if (is_64_bit_capable)
297             {
298 #if defined (__i386__) || defined (__x86_64__)
299                 if (cpusubtype == CPU_SUBTYPE_486)
300                     cpusubtype = CPU_SUBTYPE_I386_ALL;
301 #endif
302                 if (cputype & CPU_ARCH_ABI64)
303                 {
304                     // We have a 64 bit kernel on a 64 bit system
305                     g_host_arch_32.SetArchitecture (eArchTypeMachO, ~(CPU_ARCH_MASK) & cputype, cpusubtype);
306                     g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
307                 }
308                 else
309                 {
310                     // We have a 32 bit kernel on a 64 bit system
311                     g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
312                     cputype |= CPU_ARCH_ABI64;
313                     g_host_arch_64.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
314                 }
315             }
316             else
317             {
318                 g_host_arch_32.SetArchitecture (eArchTypeMachO, cputype, cpusubtype);
319                 g_host_arch_64.Clear();
320             }
321         }
322     }
323 
324 #else // #if defined (__APPLE__)
325 
326     if (g_supports_32 == false && g_supports_64 == false)
327     {
328         llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
329 
330         g_host_arch_32.Clear();
331         g_host_arch_64.Clear();
332 
333         switch (triple.getArch())
334         {
335         default:
336             g_host_arch_32.SetTriple(triple);
337             g_supports_32 = true;
338             break;
339 
340         case llvm::Triple::x86_64:
341         case llvm::Triple::sparcv9:
342         case llvm::Triple::ppc64:
343         case llvm::Triple::cellspu:
344             g_host_arch_64.SetTriple(triple);
345             g_supports_64 = true;
346             break;
347         }
348 
349         g_supports_32 = g_host_arch_32.IsValid();
350         g_supports_64 = g_host_arch_64.IsValid();
351     }
352 
353 #endif // #else for #if defined (__APPLE__)
354 
355     if (arch_kind == eSystemDefaultArchitecture32)
356         return g_host_arch_32;
357     else if (arch_kind == eSystemDefaultArchitecture64)
358         return g_host_arch_64;
359 
360     if (g_supports_64)
361         return g_host_arch_64;
362 
363     return g_host_arch_32;
364 }
365 
366 const ConstString &
367 Host::GetVendorString()
368 {
369     static ConstString g_vendor;
370     if (!g_vendor)
371     {
372 #if defined (__APPLE__)
373         char ostype[64];
374         size_t len = sizeof(ostype);
375         if (::sysctlbyname("kern.ostype", &ostype, &len, NULL, 0) == 0)
376             g_vendor.SetCString (ostype);
377         else
378             g_vendor.SetCString("apple");
379 #elif defined (__linux__)
380         g_vendor.SetCString("gnu");
381 #elif defined (__FreeBSD__)
382         g_vendor.SetCString("freebsd");
383 #endif
384     }
385     return g_vendor;
386 }
387 
388 const ConstString &
389 Host::GetOSString()
390 {
391     static ConstString g_os_string;
392     if (!g_os_string)
393     {
394 #if defined (__APPLE__)
395         g_os_string.SetCString("darwin");
396 #elif defined (__linux__)
397         g_os_string.SetCString("linux");
398 #elif defined (__FreeBSD__)
399         g_os_string.SetCString("freebsd");
400 #endif
401     }
402     return g_os_string;
403 }
404 
405 const ConstString &
406 Host::GetTargetTriple()
407 {
408     static ConstString g_host_triple;
409     if (!(g_host_triple))
410     {
411         StreamString triple;
412         triple.Printf("%s-%s-%s",
413                       GetArchitecture().GetArchitectureName(),
414                       GetVendorString().AsCString(),
415                       GetOSString().AsCString());
416 
417         std::transform (triple.GetString().begin(),
418                         triple.GetString().end(),
419                         triple.GetString().begin(),
420                         ::tolower);
421 
422         g_host_triple.SetCString(triple.GetString().c_str());
423     }
424     return g_host_triple;
425 }
426 
427 lldb::pid_t
428 Host::GetCurrentProcessID()
429 {
430     return ::getpid();
431 }
432 
433 lldb::tid_t
434 Host::GetCurrentThreadID()
435 {
436 #if defined (__APPLE__)
437     return ::mach_thread_self();
438 #elif defined(__FreeBSD__)
439     return lldb::tid_t(pthread_getthreadid_np());
440 #else
441     return lldb::tid_t(pthread_self());
442 #endif
443 }
444 
445 const char *
446 Host::GetSignalAsCString (int signo)
447 {
448     switch (signo)
449     {
450     case SIGHUP:    return "SIGHUP";    // 1    hangup
451     case SIGINT:    return "SIGINT";    // 2    interrupt
452     case SIGQUIT:   return "SIGQUIT";   // 3    quit
453     case SIGILL:    return "SIGILL";    // 4    illegal instruction (not reset when caught)
454     case SIGTRAP:   return "SIGTRAP";   // 5    trace trap (not reset when caught)
455     case SIGABRT:   return "SIGABRT";   // 6    abort()
456 #if  (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE))
457     case SIGPOLL:   return "SIGPOLL";   // 7    pollable event ([XSR] generated, not supported)
458 #endif
459 #if  !defined(_POSIX_C_SOURCE)
460     case SIGEMT:    return "SIGEMT";    // 7    EMT instruction
461 #endif
462     case SIGFPE:    return "SIGFPE";    // 8    floating point exception
463     case SIGKILL:   return "SIGKILL";   // 9    kill (cannot be caught or ignored)
464     case SIGBUS:    return "SIGBUS";    // 10    bus error
465     case SIGSEGV:   return "SIGSEGV";   // 11    segmentation violation
466     case SIGSYS:    return "SIGSYS";    // 12    bad argument to system call
467     case SIGPIPE:   return "SIGPIPE";   // 13    write on a pipe with no one to read it
468     case SIGALRM:   return "SIGALRM";   // 14    alarm clock
469     case SIGTERM:   return "SIGTERM";   // 15    software termination signal from kill
470     case SIGURG:    return "SIGURG";    // 16    urgent condition on IO channel
471     case SIGSTOP:   return "SIGSTOP";   // 17    sendable stop signal not from tty
472     case SIGTSTP:   return "SIGTSTP";   // 18    stop signal from tty
473     case SIGCONT:   return "SIGCONT";   // 19    continue a stopped process
474     case SIGCHLD:   return "SIGCHLD";   // 20    to parent on child stop or exit
475     case SIGTTIN:   return "SIGTTIN";   // 21    to readers pgrp upon background tty read
476     case SIGTTOU:   return "SIGTTOU";   // 22    like TTIN for output if (tp->t_local&LTOSTOP)
477 #if  !defined(_POSIX_C_SOURCE)
478     case SIGIO:     return "SIGIO";     // 23    input/output possible signal
479 #endif
480     case SIGXCPU:   return "SIGXCPU";   // 24    exceeded CPU time limit
481     case SIGXFSZ:   return "SIGXFSZ";   // 25    exceeded file size limit
482     case SIGVTALRM: return "SIGVTALRM"; // 26    virtual time alarm
483     case SIGPROF:   return "SIGPROF";   // 27    profiling time alarm
484 #if  !defined(_POSIX_C_SOURCE)
485     case SIGWINCH:  return "SIGWINCH";  // 28    window size changes
486     case SIGINFO:   return "SIGINFO";   // 29    information request
487 #endif
488     case SIGUSR1:   return "SIGUSR1";   // 30    user defined signal 1
489     case SIGUSR2:   return "SIGUSR2";   // 31    user defined signal 2
490     default:
491         break;
492     }
493     return NULL;
494 }
495 
496 void
497 Host::WillTerminate ()
498 {
499 }
500 
501 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
502 void
503 Host::ThreadCreated (const char *thread_name)
504 {
505 }
506 
507 void
508 Host::Backtrace (Stream &strm, uint32_t max_frames)
509 {
510     // TODO: Is there a way to backtrace the current process on linux? Other systems?
511 }
512 
513 size_t
514 Host::GetEnvironment (StringList &env)
515 {
516     // TODO: Is there a way to the host environment for this process on linux? Other systems?
517     return 0;
518 }
519 
520 #endif
521 
522 struct HostThreadCreateInfo
523 {
524     std::string thread_name;
525     thread_func_t thread_fptr;
526     thread_arg_t thread_arg;
527 
528     HostThreadCreateInfo (const char *name, thread_func_t fptr, thread_arg_t arg) :
529         thread_name (name ? name : ""),
530         thread_fptr (fptr),
531         thread_arg (arg)
532     {
533     }
534 };
535 
536 static thread_result_t
537 ThreadCreateTrampoline (thread_arg_t arg)
538 {
539     HostThreadCreateInfo *info = (HostThreadCreateInfo *)arg;
540     Host::ThreadCreated (info->thread_name.c_str());
541     thread_func_t thread_fptr = info->thread_fptr;
542     thread_arg_t thread_arg = info->thread_arg;
543 
544     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
545     if (log)
546         log->Printf("thread created");
547 
548     delete info;
549     return thread_fptr (thread_arg);
550 }
551 
552 lldb::thread_t
553 Host::ThreadCreate
554 (
555     const char *thread_name,
556     thread_func_t thread_fptr,
557     thread_arg_t thread_arg,
558     Error *error
559 )
560 {
561     lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
562 
563     // Host::ThreadCreateTrampoline will delete this pointer for us.
564     HostThreadCreateInfo *info_ptr = new HostThreadCreateInfo (thread_name, thread_fptr, thread_arg);
565 
566     int err = ::pthread_create (&thread, NULL, ThreadCreateTrampoline, info_ptr);
567     if (err == 0)
568     {
569         if (error)
570             error->Clear();
571         return thread;
572     }
573 
574     if (error)
575         error->SetError (err, eErrorTypePOSIX);
576 
577     return LLDB_INVALID_HOST_THREAD;
578 }
579 
580 bool
581 Host::ThreadCancel (lldb::thread_t thread, Error *error)
582 {
583     int err = ::pthread_cancel (thread);
584     if (error)
585         error->SetError(err, eErrorTypePOSIX);
586     return err == 0;
587 }
588 
589 bool
590 Host::ThreadDetach (lldb::thread_t thread, Error *error)
591 {
592     int err = ::pthread_detach (thread);
593     if (error)
594         error->SetError(err, eErrorTypePOSIX);
595     return err == 0;
596 }
597 
598 bool
599 Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Error *error)
600 {
601     int err = ::pthread_join (thread, thread_result_ptr);
602     if (error)
603         error->SetError(err, eErrorTypePOSIX);
604     return err == 0;
605 }
606 
607 //------------------------------------------------------------------
608 // Control access to a static file thread name map using a single
609 // static function to avoid a static constructor.
610 //------------------------------------------------------------------
611 static const char *
612 ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
613 {
614     uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
615 
616     static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
617     Mutex::Locker locker(&g_mutex);
618 
619     typedef std::map<uint64_t, std::string> thread_name_map;
620     // rdar://problem/8153284
621     // Fixed a crasher where during shutdown, loggings attempted to access the
622     // thread name but the static map instance had already been destructed.
623     // Another approach is to introduce a static guard object which monitors its
624     // own destruction and raises a flag, but this incurs more overhead.
625     static thread_name_map *g_thread_names_ptr = new thread_name_map();
626     thread_name_map &g_thread_names = *g_thread_names_ptr;
627 
628     if (get)
629     {
630         // See if the thread name exists in our thread name pool
631         thread_name_map::iterator pos = g_thread_names.find(pid_tid);
632         if (pos != g_thread_names.end())
633             return pos->second.c_str();
634     }
635     else
636     {
637         // Set the thread name
638         g_thread_names[pid_tid] = name;
639     }
640     return NULL;
641 }
642 
643 const char *
644 Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
645 {
646     const char *name = ThreadNameAccessor (true, pid, tid, NULL);
647     if (name == NULL)
648     {
649 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
650         // We currently can only get the name of a thread in the current process.
651         if (pid == Host::GetCurrentProcessID())
652         {
653             char pthread_name[1024];
654             if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
655             {
656                 if (pthread_name[0])
657                 {
658                     // Set the thread in our string pool
659                     ThreadNameAccessor (false, pid, tid, pthread_name);
660                     // Get our copy of the thread name string
661                     name = ThreadNameAccessor (true, pid, tid, NULL);
662                 }
663             }
664 
665             if (name == NULL)
666             {
667                 dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
668                 if (current_queue != NULL)
669                     name = dispatch_queue_get_label (current_queue);
670             }
671         }
672 #endif
673     }
674     return name;
675 }
676 
677 void
678 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
679 {
680     lldb::pid_t curr_pid = Host::GetCurrentProcessID();
681     lldb::tid_t curr_tid = Host::GetCurrentThreadID();
682     if (pid == LLDB_INVALID_PROCESS_ID)
683         pid = curr_pid;
684 
685     if (tid == LLDB_INVALID_THREAD_ID)
686         tid = curr_tid;
687 
688 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
689     // Set the pthread name if possible
690     if (pid == curr_pid && tid == curr_tid)
691     {
692         ::pthread_setname_np (name);
693     }
694 #endif
695     ThreadNameAccessor (false, pid, tid, name);
696 }
697 
698 FileSpec
699 Host::GetProgramFileSpec ()
700 {
701     static FileSpec g_program_filespec;
702     if (!g_program_filespec)
703     {
704 #if defined (__APPLE__)
705         char program_fullpath[PATH_MAX];
706         // If DST is NULL, then return the number of bytes needed.
707         uint32_t len = sizeof(program_fullpath);
708         int err = _NSGetExecutablePath (program_fullpath, &len);
709         if (err == 0)
710             g_program_filespec.SetFile (program_fullpath, false);
711         else if (err == -1)
712         {
713             char *large_program_fullpath = (char *)::malloc (len + 1);
714 
715             err = _NSGetExecutablePath (large_program_fullpath, &len);
716             if (err == 0)
717                 g_program_filespec.SetFile (large_program_fullpath, false);
718 
719             ::free (large_program_fullpath);
720         }
721 #elif defined (__linux__)
722         char exe_path[PATH_MAX];
723         ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
724         if (len > 0) {
725             exe_path[len] = 0;
726             g_program_filespec.SetFile(exe_path, false);
727         }
728 #elif defined (__FreeBSD__)
729         int exe_path_mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid() };
730         size_t exe_path_size;
731         if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0)
732         {
733             char *exe_path = new char[exe_path_size];
734             if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
735                 g_program_filespec.SetFile(exe_path, false);
736             delete[] exe_path;
737         }
738 #endif
739     }
740     return g_program_filespec;
741 }
742 
743 FileSpec
744 Host::GetModuleFileSpecForHostAddress (const void *host_addr)
745 {
746     FileSpec module_filespec;
747     Dl_info info;
748     if (::dladdr (host_addr, &info))
749     {
750         if (info.dli_fname)
751             module_filespec.SetFile(info.dli_fname, true);
752     }
753     return module_filespec;
754 }
755 
756 #if !defined (__APPLE__) // see Host.mm
757 
758 bool
759 Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
760 {
761     bundle.Clear();
762     return false;
763 }
764 
765 bool
766 Host::ResolveExecutableInBundle (FileSpec &file)
767 {
768     return false;
769 }
770 #endif
771 
772 // Opaque info that tracks a dynamic library that was loaded
773 struct DynamicLibraryInfo
774 {
775     DynamicLibraryInfo (const FileSpec &fs, int o, void *h) :
776         file_spec (fs),
777         open_options (o),
778         handle (h)
779     {
780     }
781 
782     const FileSpec file_spec;
783     uint32_t open_options;
784     void * handle;
785 };
786 
787 void *
788 Host::DynamicLibraryOpen (const FileSpec &file_spec, uint32_t options, Error &error)
789 {
790     char path[PATH_MAX];
791     if (file_spec.GetPath(path, sizeof(path)))
792     {
793         int mode = 0;
794 
795         if (options & eDynamicLibraryOpenOptionLazy)
796             mode |= RTLD_LAZY;
797         else
798             mode |= RTLD_NOW;
799 
800 
801         if (options & eDynamicLibraryOpenOptionLocal)
802             mode |= RTLD_LOCAL;
803         else
804             mode |= RTLD_GLOBAL;
805 
806 #ifdef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
807         if (options & eDynamicLibraryOpenOptionLimitGetSymbol)
808             mode |= RTLD_FIRST;
809 #endif
810 
811         void * opaque = ::dlopen (path, mode);
812 
813         if (opaque)
814         {
815             error.Clear();
816             return new DynamicLibraryInfo (file_spec, options, opaque);
817         }
818         else
819         {
820             error.SetErrorString(::dlerror());
821         }
822     }
823     else
824     {
825         error.SetErrorString("failed to extract path");
826     }
827     return NULL;
828 }
829 
830 Error
831 Host::DynamicLibraryClose (void *opaque)
832 {
833     Error error;
834     if (opaque == NULL)
835     {
836         error.SetErrorString ("invalid dynamic library handle");
837     }
838     else
839     {
840         DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
841         if (::dlclose (dylib_info->handle) != 0)
842         {
843             error.SetErrorString(::dlerror());
844         }
845 
846         dylib_info->open_options = 0;
847         dylib_info->handle = 0;
848         delete dylib_info;
849     }
850     return error;
851 }
852 
853 void *
854 Host::DynamicLibraryGetSymbol (void *opaque, const char *symbol_name, Error &error)
855 {
856     if (opaque == NULL)
857     {
858         error.SetErrorString ("invalid dynamic library handle");
859     }
860     else
861     {
862         DynamicLibraryInfo *dylib_info = (DynamicLibraryInfo *) opaque;
863 
864         void *symbol_addr = ::dlsym (dylib_info->handle, symbol_name);
865         if (symbol_addr)
866         {
867 #ifndef LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED
868             // This host doesn't support limiting searches to this shared library
869             // so we need to verify that the match came from this shared library
870             // if it was requested in the Host::DynamicLibraryOpen() function.
871             if (dylib_info->open_options & eDynamicLibraryOpenOptionLimitGetSymbol)
872             {
873                 FileSpec match_dylib_spec (Host::GetModuleFileSpecForHostAddress (symbol_addr));
874                 if (match_dylib_spec != dylib_info->file_spec)
875                 {
876                     char dylib_path[PATH_MAX];
877                     if (dylib_info->file_spec.GetPath (dylib_path, sizeof(dylib_path)))
878                         error.SetErrorStringWithFormat ("symbol not found in \"%s\"", dylib_path);
879                     else
880                         error.SetErrorString ("symbol not found");
881                     return NULL;
882                 }
883             }
884 #endif
885             error.Clear();
886             return symbol_addr;
887         }
888         else
889         {
890             error.SetErrorString(::dlerror());
891         }
892     }
893     return NULL;
894 }
895 
896 bool
897 Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
898 {
899     // To get paths related to LLDB we get the path to the executable that
900     // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
901     // on linux this is assumed to be the "lldb" main executable. If LLDB on
902     // linux is actually in a shared library (lldb.so??) then this function will
903     // need to be modified to "do the right thing".
904 
905     switch (path_type)
906     {
907     case ePathTypeLLDBShlibDir:
908         {
909             static ConstString g_lldb_so_dir;
910             if (!g_lldb_so_dir)
911             {
912                 FileSpec lldb_file_spec (Host::GetModuleFileSpecForHostAddress ((void *)Host::GetLLDBPath));
913                 g_lldb_so_dir = lldb_file_spec.GetDirectory();
914             }
915             file_spec.GetDirectory() = g_lldb_so_dir;
916             return file_spec.GetDirectory();
917         }
918         break;
919 
920     case ePathTypeSupportExecutableDir:
921         {
922             static ConstString g_lldb_support_exe_dir;
923             if (!g_lldb_support_exe_dir)
924             {
925                 FileSpec lldb_file_spec;
926                 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
927                 {
928                     char raw_path[PATH_MAX];
929                     char resolved_path[PATH_MAX];
930                     lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
931 
932 #if defined (__APPLE__)
933                     char *framework_pos = ::strstr (raw_path, "LLDB.framework");
934                     if (framework_pos)
935                     {
936                         framework_pos += strlen("LLDB.framework");
937 #if !defined (__arm__)
938                         ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path));
939 #endif
940                     }
941 #endif
942                     FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
943                     g_lldb_support_exe_dir.SetCString(resolved_path);
944                 }
945             }
946             file_spec.GetDirectory() = g_lldb_support_exe_dir;
947             return file_spec.GetDirectory();
948         }
949         break;
950 
951     case ePathTypeHeaderDir:
952         {
953             static ConstString g_lldb_headers_dir;
954             if (!g_lldb_headers_dir)
955             {
956 #if defined (__APPLE__)
957                 FileSpec lldb_file_spec;
958                 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
959                 {
960                     char raw_path[PATH_MAX];
961                     char resolved_path[PATH_MAX];
962                     lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
963 
964                     char *framework_pos = ::strstr (raw_path, "LLDB.framework");
965                     if (framework_pos)
966                     {
967                         framework_pos += strlen("LLDB.framework");
968                         ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path));
969                     }
970                     FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
971                     g_lldb_headers_dir.SetCString(resolved_path);
972                 }
973 #else
974                 // TODO: Anyone know how we can determine this for linux? Other systems??
975                 g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
976 #endif
977             }
978             file_spec.GetDirectory() = g_lldb_headers_dir;
979             return file_spec.GetDirectory();
980         }
981         break;
982 
983     case ePathTypePythonDir:
984         {
985             // TODO: Anyone know how we can determine this for linux? Other systems?
986             // For linux we are currently assuming the location of the lldb
987             // binary that contains this function is the directory that will
988             // contain lldb.so, lldb.py and embedded_interpreter.py...
989 
990             static ConstString g_lldb_python_dir;
991             if (!g_lldb_python_dir)
992             {
993                 FileSpec lldb_file_spec;
994                 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
995                 {
996                     char raw_path[PATH_MAX];
997                     char resolved_path[PATH_MAX];
998                     lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
999 
1000 #if defined (__APPLE__)
1001                     char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1002                     if (framework_pos)
1003                     {
1004                         framework_pos += strlen("LLDB.framework");
1005                         ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
1006                     }
1007 #endif
1008                     FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1009                     g_lldb_python_dir.SetCString(resolved_path);
1010                 }
1011             }
1012             file_spec.GetDirectory() = g_lldb_python_dir;
1013             return file_spec.GetDirectory();
1014         }
1015         break;
1016 
1017     case ePathTypeLLDBSystemPlugins:    // System plug-ins directory
1018         {
1019 #if defined (__APPLE__)
1020             static ConstString g_lldb_system_plugin_dir;
1021             static bool g_lldb_system_plugin_dir_located = false;
1022             if (!g_lldb_system_plugin_dir_located)
1023             {
1024                 g_lldb_system_plugin_dir_located = true;
1025                 FileSpec lldb_file_spec;
1026                 if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
1027                 {
1028                     char raw_path[PATH_MAX];
1029                     char resolved_path[PATH_MAX];
1030                     lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
1031 
1032                     char *framework_pos = ::strstr (raw_path, "LLDB.framework");
1033                     if (framework_pos)
1034                     {
1035                         framework_pos += strlen("LLDB.framework");
1036                         ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
1037                         FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
1038                         g_lldb_system_plugin_dir.SetCString(resolved_path);
1039                     }
1040                     return false;
1041                 }
1042             }
1043 
1044             if (g_lldb_system_plugin_dir)
1045             {
1046                 file_spec.GetDirectory() = g_lldb_system_plugin_dir;
1047                 return true;
1048             }
1049 #endif
1050             // TODO: where would system LLDB plug-ins be located on linux? Other systems?
1051             return false;
1052         }
1053         break;
1054 
1055     case ePathTypeLLDBUserPlugins:      // User plug-ins directory
1056         {
1057 #if defined (__APPLE__)
1058             static ConstString g_lldb_user_plugin_dir;
1059             if (!g_lldb_user_plugin_dir)
1060             {
1061                 char user_plugin_path[PATH_MAX];
1062                 if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
1063                                        user_plugin_path,
1064                                        sizeof(user_plugin_path)))
1065                 {
1066                     g_lldb_user_plugin_dir.SetCString(user_plugin_path);
1067                 }
1068             }
1069             file_spec.GetDirectory() = g_lldb_user_plugin_dir;
1070             return file_spec.GetDirectory();
1071 #endif
1072             // TODO: where would user LLDB plug-ins be located on linux? Other systems?
1073             return false;
1074         }
1075     default:
1076         assert (!"Unhandled PathType");
1077         break;
1078     }
1079 
1080     return false;
1081 }
1082 
1083 
1084 bool
1085 Host::GetHostname (std::string &s)
1086 {
1087     char hostname[PATH_MAX];
1088     hostname[sizeof(hostname) - 1] = '\0';
1089     if (::gethostname (hostname, sizeof(hostname) - 1) == 0)
1090     {
1091         struct hostent* h = ::gethostbyname (hostname);
1092         if (h)
1093             s.assign (h->h_name);
1094         else
1095             s.assign (hostname);
1096         return true;
1097     }
1098     return false;
1099 }
1100 
1101 const char *
1102 Host::GetUserName (uint32_t uid, std::string &user_name)
1103 {
1104     struct passwd user_info;
1105     struct passwd *user_info_ptr = &user_info;
1106     char user_buffer[PATH_MAX];
1107     size_t user_buffer_size = sizeof(user_buffer);
1108     if (::getpwuid_r (uid,
1109                       &user_info,
1110                       user_buffer,
1111                       user_buffer_size,
1112                       &user_info_ptr) == 0)
1113     {
1114         if (user_info_ptr)
1115         {
1116             user_name.assign (user_info_ptr->pw_name);
1117             return user_name.c_str();
1118         }
1119     }
1120     user_name.clear();
1121     return NULL;
1122 }
1123 
1124 const char *
1125 Host::GetGroupName (uint32_t gid, std::string &group_name)
1126 {
1127     char group_buffer[PATH_MAX];
1128     size_t group_buffer_size = sizeof(group_buffer);
1129     struct group group_info;
1130     struct group *group_info_ptr = &group_info;
1131     // Try the threadsafe version first
1132     if (::getgrgid_r (gid,
1133                       &group_info,
1134                       group_buffer,
1135                       group_buffer_size,
1136                       &group_info_ptr) == 0)
1137     {
1138         if (group_info_ptr)
1139         {
1140             group_name.assign (group_info_ptr->gr_name);
1141             return group_name.c_str();
1142         }
1143     }
1144     else
1145     {
1146         // The threadsafe version isn't currently working
1147         // for me on darwin, but the non-threadsafe version
1148         // is, so I am calling it below.
1149         group_info_ptr = ::getgrgid (gid);
1150         if (group_info_ptr)
1151         {
1152             group_name.assign (group_info_ptr->gr_name);
1153             return group_name.c_str();
1154         }
1155     }
1156     group_name.clear();
1157     return NULL;
1158 }
1159 
1160 #if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
1161 bool
1162 Host::GetOSBuildString (std::string &s)
1163 {
1164     s.clear();
1165     return false;
1166 }
1167 
1168 bool
1169 Host::GetOSKernelDescription (std::string &s)
1170 {
1171     s.clear();
1172     return false;
1173 }
1174 #endif
1175 
1176 #if !defined(__APPLE__)
1177 uint32_t
1178 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
1179 {
1180     process_infos.Clear();
1181     return process_infos.GetSize();
1182 }
1183 #endif
1184 
1185 #if !defined (__APPLE__) && !defined (__FreeBSD__)
1186 bool
1187 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
1188 {
1189     process_info.Clear();
1190     return false;
1191 }
1192 #endif
1193 
1194 lldb::TargetSP
1195 Host::GetDummyTarget (lldb_private::Debugger &debugger)
1196 {
1197     static TargetSP dummy_target;
1198 
1199     if (!dummy_target)
1200     {
1201         Error err = debugger.GetTargetList().CreateTarget(debugger,
1202                                                           FileSpec(),
1203                                                           Host::GetTargetTriple().AsCString(),
1204                                                           false,
1205                                                           NULL,
1206                                                           dummy_target);
1207     }
1208 
1209     return dummy_target;
1210 }
1211 
1212 #if !defined (__APPLE__)
1213 bool
1214 Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1215 {
1216     return false;
1217 }
1218 
1219 void
1220 Host::SetCrashDescriptionWithFormat (const char *format, ...)
1221 {
1222 }
1223 
1224 void
1225 Host::SetCrashDescription (const char *description)
1226 {
1227 }
1228 
1229 lldb::pid_t
1230 LaunchApplication (const FileSpec &app_file_spec)
1231 {
1232     return LLDB_INVALID_PROCESS_ID;
1233 }
1234 
1235 #endif
1236