--- tools/lldb/source/Host/bsdsunix/Host.cpp.orig 2020-05-14 10:00:31.326277000 +1000 +++ tools/lldb/source/Host/bsdsunix/Host.cpp 2020-05-14 09:49:58.683710000 +1000 @@ -0,0 +1,265 @@ +//===-- source/Host/bsdsunix/Host.cpp ------------------------------*- C++ +//-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/Endian.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" + +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Utility/CleanUp.h" +#include "lldb/Utility/NameMatches.h" + +#include "llvm/Support/Host.h" + +extern "C" { +extern char **environ; +} + +using namespace lldb; +using namespace lldb_private; + +size_t Host::GetEnvironment(StringList &env) { + char *v; + char **var = environ; + for (; var != NULL && *var != NULL; ++var) { + v = strchr(*var, (int)'-'); + if (v == NULL) + continue; + env.AppendString(v); + } + return env.GetSize(); +} + +static bool +GetBSDSUniXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, + ProcessInstanceInfo &process_info) { + if (process_info.ProcessIDIsValid()) { + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, + (int)process_info.GetProcessID()}; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) { + DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), + sizeof(void *)); + lldb::offset_t offset = 0; + const char *cstr; + + cstr = data.GetCStr(&offset); + if (cstr) { + process_info.GetExecutableFile().SetFile(cstr, false); + + if (!(match_info_ptr == NULL || + NameMatches( + process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName()))) + return false; + + Args &proc_args = process_info.GetArguments(); + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { + ++offset; + p = data.PeekData(offset, 1); + } + if (p == NULL || offset >= arg_data_size) + return true; + + cstr = data.GetCStr(&offset); + if (cstr) + proc_args.AppendArgument(llvm::StringRef(cstr)); + else + return true; + } + } + } + } + return false; +} + +static bool GetBSDSUniXProcessCPUType(ProcessInstanceInfo &process_info) { + if (process_info.ProcessIDIsValid()) { + process_info.GetArchitecture() = + HostInfo::GetArchitecture(HostInfo::eArchKindDefault); + return true; + } + process_info.GetArchitecture().Clear(); + return false; +} + +static bool GetBSDSUniXProcessUserAndGroup(ProcessInstanceInfo &process_info) { + struct kinfo_proc proc_kinfo; + size_t proc_kinfo_size; + + if (process_info.ProcessIDIsValid()) { + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, + (int)process_info.GetProcessID()}; + proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { + if (proc_kinfo_size > 0) { + process_info.SetParentProcessID(proc_kinfo.ki_ppid); + process_info.SetUserID(proc_kinfo.ki_ruid); + process_info.SetGroupID(proc_kinfo.ki_rgid); + process_info.SetEffectiveUserID(proc_kinfo.ki_uid); + if (proc_kinfo.ki_ngroups > 0) + process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + return true; + } + } + } + process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); + process_info.SetUserID(UINT32_MAX); + process_info.SetGroupID(UINT32_MAX); + process_info.SetEffectiveUserID(UINT32_MAX); + process_info.SetEffectiveGroupID(UINT32_MAX); + return false; +} + +uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + std::vector kinfos; + + int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; + + size_t pid_data_size = 0; + if (::sysctl(mib, 3, NULL, &pid_data_size, NULL, 0) != 0) + return 0; + + // Add a few extra in case a few more show up + const size_t estimated_pid_count = + (pid_data_size / sizeof(struct kinfo_proc)) + 10; + + kinfos.resize(estimated_pid_count); + pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); + + if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0) + return 0; + + const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); + + bool all_users = match_info.GetMatchAllUsers(); + const ::pid_t our_pid = getpid(); + const uid_t our_uid = getuid(); + for (size_t i = 0; i < actual_pid_count; i++) { + const struct kinfo_proc &kinfo = kinfos[i]; + const bool kinfo_user_matches = (all_users || (kinfo.ki_ruid == our_uid) || + // Special case, if lldb is being run as + // root we can attach to anything. + (our_uid == 0)); + + if (kinfo_user_matches == false || // Make sure the user is acceptable + kinfo.ki_pid == our_pid || // Skip this process + kinfo.ki_pid == 0 || // Skip kernel (kernel pid is zero) + kinfo.ki_stat == SZOMB || // Zombies are bad, they like brains... + kinfo.ki_flag & P_TRACED || // Being debugged? + kinfo.ki_flag & P_WEXIT) // Working on exiting + continue; + + // Every thread is a process in BSDSUniX, but all the threads of a single + // process + // have the same pid. Do not store the process info in the result list if a + // process + // with given identifier is already registered there. + bool already_registered = false; + for (uint32_t pi = 0; + !already_registered && (const int)kinfo.ki_numthreads > 1 && + pi < (const uint32_t)process_infos.GetSize(); + pi++) + already_registered = + (process_infos.GetProcessIDAtIndex(pi) == (uint32_t)kinfo.ki_pid); + + if (already_registered) + continue; + + ProcessInstanceInfo process_info; + process_info.SetProcessID(kinfo.ki_pid); + process_info.SetParentProcessID(kinfo.ki_ppid); + process_info.SetUserID(kinfo.ki_ruid); + process_info.SetGroupID(kinfo.ki_rgid); + process_info.SetEffectiveUserID(kinfo.ki_svuid); + process_info.SetEffectiveGroupID(kinfo.ki_svgid); + + // Make sure our info matches before we go fetch the name and cpu type + if (match_info.Matches(process_info) && + GetBSDSUniXProcessArgs(&match_info, process_info)) { + GetBSDSUniXProcessCPUType(process_info); + if (match_info.Matches(process_info)) + process_infos.Append(process_info); + } + } + + return process_infos.GetSize(); +} + +bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { + process_info.SetProcessID(pid); + + if (GetBSDSUniXProcessArgs(NULL, process_info)) { + // should use libprocstat instead of going right into sysctl? + GetBSDSUniXProcessCPUType(process_info); + GetBSDSUniXProcessUserAndGroup(process_info); + return true; + } + + process_info.Clear(); + return false; +} + +lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) { + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, 0}; + size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo); + DataBufferSP buf_sp; + + std::unique_ptr buf_ap(new DataBufferHeap(auxv_size, 0)); + + mib[3] = process->GetID(); + if (::sysctl(mib, 4, buf_ap->GetBytes(), &auxv_size, NULL, 0) == 0) { + buf_sp.reset(buf_ap.release()); + } else { + perror("sysctl failed on auxv"); + } + + return buf_sp; +} + +Error Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { + return Error("unimplemented"); +} --- tools/lldb/source/Host/bsdsunix/HostInfoBSDSUniX.cpp.orig 2020-05-14 10:00:31.329016000 +1000 +++ tools/lldb/source/Host/bsdsunix/HostInfoBSDSUniX.cpp 2020-05-14 09:50:34.157168000 +1000 @@ -0,0 +1,77 @@ +//===-- HostInfoBSDSUniX.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/bsdsunix/HostInfoBSDSUniX.h" + +#include +#include +#include +#include +#include + +using namespace lldb_private; + +uint32_t HostInfoBSDSUniX::GetMaxThreadNameLength() { return 16; } + +bool HostInfoBSDSUniX::GetOSVersion(uint32_t &major, uint32_t &minor, + uint32_t &update) { + struct utsname un; + + ::memset(&un, 0, sizeof(utsname)); + if (uname(&un) < 0) + return false; + + int status = sscanf(un.release, "%u.%u", &major, &minor); + return status == 2; +} + +bool HostInfoBSDSUniX::GetOSBuildString(std::string &s) { + int mib[2] = {CTL_KERN, KERN_OSREV}; + char osrev_str[12]; + uint32_t osrev = 0; + size_t osrev_len = sizeof(osrev); + + if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) { + ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev); + s.assign(osrev_str); + return true; + } + + s.clear(); + return false; +} + +bool HostInfoBSDSUniX::GetOSKernelDescription(std::string &s) { + struct utsname un; + + ::memset(&un, 0, sizeof(utsname)); + s.clear(); + + if (uname(&un) < 0) + return false; + + s.assign(un.version); + + return true; +} + +FileSpec HostInfoBSDSUniX::GetProgramFileSpec() { + static FileSpec g_program_filespec; + if (!g_program_filespec) { + int exe_path_mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid()}; + size_t exe_path_size; + if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) { + char *exe_path = new char[exe_path_size]; + if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) + g_program_filespec.SetFile(exe_path, false); + delete[] exe_path; + } + } + return g_program_filespec; +} --- tools/lldb/source/Host/bsdsunix/HostThreadBSDSUniX.cpp.orig 2020-05-14 10:00:31.331353000 +1000 +++ tools/lldb/source/Host/bsdsunix/HostThreadBSDSUniX.cpp 2020-05-14 09:58:50.178400000 +1000 @@ -0,0 +1,70 @@ +//===-- HostThreadBSDSUniX.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// lldb Includes +#include "lldb/Host/bsdsunix/HostThreadBSDSUniX.h" +#include "lldb/Host/Host.h" + +// C includes +#include +#include +#if defined(__BSDSUniX__) +#include +#endif +#include +#include +#include + +// C++ includes +#include + +using namespace lldb_private; + +HostThreadBSDSUniX::HostThreadBSDSUniX() {} + +HostThreadBSDSUniX::HostThreadBSDSUniX(lldb::thread_t thread) + : HostThreadPosix(thread) {} + +void HostThreadBSDSUniX::GetName(lldb::tid_t tid, + llvm::SmallVectorImpl &name) { + name.clear(); + int pid = Host::GetCurrentProcessID(); + + struct kinfo_proc *kp = nullptr, *nkp; + size_t len = 0; + int error; + int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD, + (int)pid}; + + while (1) { + error = sysctl(ctl, 4, kp, &len, nullptr, 0); + if (kp == nullptr || (error != 0 && errno == ENOMEM)) { + // Add extra space in case threads are added before next call. + len += sizeof(*kp) + len / 10; + nkp = (struct kinfo_proc *)realloc(kp, len); + if (nkp == nullptr) { + free(kp); + return; + } + kp = nkp; + continue; + } + if (error != 0) + len = 0; + break; + } + + for (size_t i = 0; i < len / sizeof(*kp); i++) { + if (kp[i].ki_tid == (lwpid_t)tid) { + name.append(kp[i].ki_tdname, kp[i].ki_tdname + strlen(kp[i].ki_tdname)); + break; + } + } + free(kp); +} --- tools/lldb/source/Host/bsdsunix/ThisThread.cpp.orig 2020-05-14 10:00:31.333680000 +1000 +++ tools/lldb/source/Host/bsdsunix/ThisThread.cpp 2020-05-14 09:53:13.348193000 +1000 @@ -0,0 +1,32 @@ +//===-- ThisThread.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ThisThread.h" +#include "lldb/Host/HostNativeThread.h" + +#include "llvm/ADT/SmallVector.h" + +#include +#if defined(__BSDSUniX__) +#include +#endif + +using namespace lldb_private; + +void ThisThread::SetName(llvm::StringRef name) { +#if defined(__BSDSUniX__) + ::pthread_set_name_np(::pthread_self(), name.data()); +#endif +} + +void ThisThread::GetName(llvm::SmallVectorImpl &name) { +#if defined(__BSDSUniX__) + HostNativeThread::GetName(::pthread_getthreadid_np(), name); +#endif +} --- tools/lldb/include/lldb/Host/bsdsunix/Config.h.orig 2020-05-14 10:48:18.462173000 +1000 +++ tools/lldb/include/lldb/Host/bsdsunix/Config.h 2020-05-14 10:44:30.356599000 +1000 @@ -0,0 +1,28 @@ +//===-- Config.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//---------------------------------------------------------------------- +// LLDB currently doesn't have a dynamic configuration mechanism, so we +// are going to hardcode things for now. Eventually these files will +// be auto generated by some configuration script that can detect +// platform functionality availability. +//---------------------------------------------------------------------- + +#ifndef liblldb_Platform_Config_h_ +#define liblldb_Platform_Config_h_ + +#define LLDB_CONFIG_TERMIOS_SUPPORTED 1 + +#define LLDB_CONFIG_TILDE_RESOLVES_TO_USER 1 + +//#define LLDB_CONFIG_DLOPEN_RTLD_FIRST_SUPPORTED 1 + +//#define LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED 1 + +#endif // #ifndef liblldb_Platform_Config_h_ --- tools/lldb/include/lldb/Host/bsdsunix/HostInfoBSDSUniX.h.orig 2020-05-14 10:48:18.464716000 +1000 +++ tools/lldb/include/lldb/Host/bsdsunix/HostInfoBSDSUniX.h 2020-05-14 10:45:46.812737000 +1000 @@ -0,0 +1,28 @@ +//===-- HostInfoBSDSUniX.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_bsdsunix_HostInfoBSDSUniX_h_ +#define lldb_Host_bsdsunix_HostInfoBSDSUniX_h_ + +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/posix/HostInfoPosix.h" + +namespace lldb_private { + +class HostInfoBSDSUniX : public HostInfoPosix { +public: + static uint32_t GetMaxThreadNameLength(); + static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); + static bool GetOSBuildString(std::string &s); + static bool GetOSKernelDescription(std::string &s); + static FileSpec GetProgramFileSpec(); +}; +} + +#endif --- tools/lldb/include/lldb/Host/bsdsunix/HostThreadBSDSUniX.h.orig 2020-05-14 10:48:18.466906000 +1000 +++ tools/lldb/include/lldb/Host/bsdsunix/HostThreadBSDSUniX.h 2020-05-14 10:46:14.606952000 +1000 @@ -0,0 +1,29 @@ +//===-- HostThreadBSDSUniX.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_bsdsunix_HostThreadBSDSUniX_h_ +#define lldb_Host_bsdsunix_HostThreadBSDSUniX_h_ + +#include "lldb/Host/posix/HostThreadPosix.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +class HostThreadBSDSUniX : public HostThreadPosix { +public: + HostThreadBSDSUniX(); + HostThreadBSDSUniX(lldb::thread_t thread); + + static void GetName(lldb::tid_t tid, llvm::SmallVectorImpl &name); +}; +} + +#endif