diff options
author | Ed Maste <emaste@FreeBSD.org> | 2016-01-04 01:16:32 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2016-01-04 01:16:32 +0000 |
commit | 9f2f44ceeb195c67fbbf0953f03c530f6f1e59d4 (patch) | |
tree | 1a3cc0a2c3d432ddf9ffc14f06bd43e8097fc93c /contrib/llvm/tools/lldb/source/Utility | |
parent | 0a97e59728ecf251d065745cb716ffe32b24aa28 (diff) | |
parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
download | src-9f2f44ceeb195c67fbbf0953f03c530f6f1e59d4.tar.gz src-9f2f44ceeb195c67fbbf0953f03c530f6f1e59d4.zip |
Merge LLDB 3.8
As with previous imports a number of plugins not immediately relevant
to FreeBSD have been excluded:
ABIMacOSX_i386
ABIMacOSX_arm
ABIMacOSX_arm64
ABISysV_hexagon
AppleObjCRuntimeV2
AppleObjCRuntimeV1
SystemRuntimeMacOSX
RenderScriptRuntime
GoLanguageRuntime
GoLanguage
ObjCLanguage
ObjCPlusPlusLanguage
ObjectFilePECOFF
DynamicLoaderWindowsDYLD
platform_linux
platform_netbsd
PlatformWindows
PlatformKalimba
platform_android
DynamicLoaderMacOSXDYLD
ObjectContainerUniversalMachO
PlatformRemoteiOS
PlatformMacOSX
OperatingSystemGo
Notes
Notes:
svn path=/projects/clang380-import/; revision=293127
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Utility')
14 files changed, 476 insertions, 248 deletions
diff --git a/contrib/llvm/tools/lldb/source/Utility/ARM64_GCC_Registers.h b/contrib/llvm/tools/lldb/source/Utility/ARM64_ehframe_Registers.h index 2166b3bf591a..0a5c68c63b7e 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ARM64_GCC_Registers.h +++ b/contrib/llvm/tools/lldb/source/Utility/ARM64_ehframe_Registers.h @@ -1,4 +1,4 @@ -//===-- ARM64_gdb_Registers.h -------------------------------------*- C++ -*-===// +//===-- ARM64_ehframe_Registers.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,13 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM64_gdb_Registers_h_ -#define utility_ARM64_gdb_Registers_h_ +#ifndef utility_ARM64_ehframe_Registers_h_ +#define utility_ARM64_ehframe_Registers_h_ -namespace arm64_gcc { +// The register numbers used in the eh_frame unwind information. +// Should be the same as DWARF register numbers. + +namespace arm64_ehframe { enum { @@ -88,5 +91,5 @@ enum } -#endif // utility_ARM64_gdb_Registers_h_ +#endif // utility_ARM64_ehframe_Registers_h_ diff --git a/contrib/llvm/tools/lldb/source/Utility/ARM_GCC_Registers.h b/contrib/llvm/tools/lldb/source/Utility/ARM_GCC_Registers.h deleted file mode 100644 index 974d01bfc78a..000000000000 --- a/contrib/llvm/tools/lldb/source/Utility/ARM_GCC_Registers.h +++ /dev/null @@ -1,146 +0,0 @@ -//===-- ARM_GCC_Registers.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef utility_ARM_GCC_Registers_h_ -#define utility_ARM_GCC_Registers_h_ - -enum -{ - gcc_r0 = 0, - gcc_r1, - gcc_r2, - gcc_r3, - gcc_r4, - gcc_r5, - gcc_r6, - gcc_r7, - gcc_r8, - gcc_r9, - gcc_r10, - gcc_r11, - gcc_r12, - gcc_sp, - gcc_lr, - gcc_pc, - gcc_cpsr -}; - -enum -{ -// Name Nr Rel Offset Size Type Raw value - gdb_arm_r0 = 0, // 0 0 4 int32_t - gdb_arm_r1 = 1, // 1 4 4 int32_t - gdb_arm_r2 = 2, // 2 8 4 int32_t - gdb_arm_r3 = 3, // 3 12 4 int32_t - gdb_arm_r4 = 4, // 4 16 4 int32_t - gdb_arm_r5 = 5, // 5 20 4 int32_t - gdb_arm_r6 = 6, // 6 24 4 int32_t - gdb_arm_r7 = 7, // 7 28 4 int32_t - gdb_arm_r8 = 8, // 8 32 4 int32_t - gdb_arm_r9 = 9, // 9 36 4 int32_t - gdb_arm_r10 = 10, // 10 40 4 int32_t - gdb_arm_r11 = 11, // 11 44 4 int32_t - gdb_arm_r12 = 12, // 12 48 4 int32_t - gdb_arm_sp = 13, // 13 52 4 int32_t - gdb_arm_lr = 14, // 14 56 4 int32_t - gdb_arm_pc = 15, // 15 60 4 int32_t - gdb_arm_f0 = 16, // 16 64 12 _arm_ext_littlebyte_bigword - gdb_arm_f1 = 17, // 17 76 12 _arm_ext_littlebyte_bigword - gdb_arm_f2 = 18, // 18 88 12 _arm_ext_littlebyte_bigword - gdb_arm_f3 = 19, // 19 100 12 _arm_ext_littlebyte_bigword - gdb_arm_f4 = 20, // 20 112 12 _arm_ext_littlebyte_bigword - gdb_arm_f5 = 21, // 21 124 12 _arm_ext_littlebyte_bigword - gdb_arm_f6 = 22, // 22 136 12 _arm_ext_littlebyte_bigword - gdb_arm_f7 = 23, // 23 148 12 _arm_ext_littlebyte_bigword - gdb_arm_f8 = 24, // 24 160 12 _arm_ext_littlebyte_bigword - gdb_arm_cpsr = 25, // 25 172 4 int32_t - gdb_arm_s0 = 26, // 26 176 4 _ieee_single_little - gdb_arm_s1 = 27, // 27 180 4 _ieee_single_little - gdb_arm_s2 = 28, // 28 184 4 _ieee_single_little - gdb_arm_s3 = 29, // 29 188 4 _ieee_single_little - gdb_arm_s4 = 30, // 30 192 4 _ieee_single_little - gdb_arm_s5 = 31, // 31 196 4 _ieee_single_little - gdb_arm_s6 = 32, // 32 200 4 _ieee_single_little - gdb_arm_s7 = 33, // 33 204 4 _ieee_single_little - gdb_arm_s8 = 34, // 34 208 4 _ieee_single_little - gdb_arm_s9 = 35, // 35 212 4 _ieee_single_little - gdb_arm_s10 = 36, // 36 216 4 _ieee_single_little - gdb_arm_s11 = 37, // 37 220 4 _ieee_single_little - gdb_arm_s12 = 38, // 38 224 4 _ieee_single_little - gdb_arm_s13 = 39, // 39 228 4 _ieee_single_little - gdb_arm_s14 = 40, // 40 232 4 _ieee_single_little - gdb_arm_s15 = 41, // 41 236 4 _ieee_single_little - gdb_arm_s16 = 42, // 42 240 4 _ieee_single_little - gdb_arm_s17 = 43, // 43 244 4 _ieee_single_little - gdb_arm_s18 = 44, // 44 248 4 _ieee_single_little - gdb_arm_s19 = 45, // 45 252 4 _ieee_single_little - gdb_arm_s20 = 46, // 46 256 4 _ieee_single_little - gdb_arm_s21 = 47, // 47 260 4 _ieee_single_little - gdb_arm_s22 = 48, // 48 264 4 _ieee_single_little - gdb_arm_s23 = 49, // 49 268 4 _ieee_single_little - gdb_arm_s24 = 50, // 50 272 4 _ieee_single_little - gdb_arm_s25 = 51, // 51 276 4 _ieee_single_little - gdb_arm_s26 = 52, // 52 280 4 _ieee_single_little - gdb_arm_s27 = 53, // 53 284 4 _ieee_single_little - gdb_arm_s28 = 54, // 54 288 4 _ieee_single_little - gdb_arm_s29 = 55, // 55 292 4 _ieee_single_little - gdb_arm_s30 = 56, // 56 296 4 _ieee_single_little - gdb_arm_s31 = 57, // 57 300 4 _ieee_single_little - gdb_arm_fpscr = 58, // 58 304 4 int32_t - gdb_arm_d16 = 59, // 59 308 8 _ieee_double_little - gdb_arm_d17 = 60, // 60 316 8 _ieee_double_little - gdb_arm_d18 = 61, // 61 324 8 _ieee_double_little - gdb_arm_d19 = 62, // 62 332 8 _ieee_double_little - gdb_arm_d20 = 63, // 63 340 8 _ieee_double_little - gdb_arm_d21 = 64, // 64 348 8 _ieee_double_little - gdb_arm_d22 = 65, // 65 356 8 _ieee_double_little - gdb_arm_d23 = 66, // 66 364 8 _ieee_double_little - gdb_arm_d24 = 67, // 67 372 8 _ieee_double_little - gdb_arm_d25 = 68, // 68 380 8 _ieee_double_little - gdb_arm_d26 = 69, // 69 388 8 _ieee_double_little - gdb_arm_d27 = 70, // 70 396 8 _ieee_double_little - gdb_arm_d28 = 71, // 71 404 8 _ieee_double_little - gdb_arm_d29 = 72, // 72 412 8 _ieee_double_little - gdb_arm_d30 = 73, // 73 420 8 _ieee_double_little - gdb_arm_d31 = 74, // 74 428 8 _ieee_double_little - gdb_arm_d0 = 75, // 0 436 8 _ieee_double_little - gdb_arm_d1 = 76, // 1 444 8 _ieee_double_little - gdb_arm_d2 = 77, // 2 452 8 _ieee_double_little - gdb_arm_d3 = 78, // 3 460 8 _ieee_double_little - gdb_arm_d4 = 79, // 4 468 8 _ieee_double_little - gdb_arm_d5 = 80, // 5 476 8 _ieee_double_little - gdb_arm_d6 = 81, // 6 484 8 _ieee_double_little - gdb_arm_d7 = 82, // 7 492 8 _ieee_double_little - gdb_arm_d8 = 83, // 8 500 8 _ieee_double_little - gdb_arm_d9 = 84, // 9 508 8 _ieee_double_little - gdb_arm_d10 = 85, // 10 516 8 _ieee_double_little - gdb_arm_d11 = 86, // 11 524 8 _ieee_double_little - gdb_arm_d12 = 87, // 12 532 8 _ieee_double_little - gdb_arm_d13 = 88, // 13 540 8 _ieee_double_little - gdb_arm_d14 = 89, // 14 548 8 _ieee_double_little - gdb_arm_d15 = 90, // 15 556 8 _ieee_double_little - gdb_arm_q0 = 91, // 16 564 16 _vec128 - gdb_arm_q1 = 92, // 17 580 16 _vec128 - gdb_arm_q2 = 93, // 18 596 16 _vec128 - gdb_arm_q3 = 94, // 19 612 16 _vec128 - gdb_arm_q4 = 95, // 20 628 16 _vec128 - gdb_arm_q5 = 96, // 21 644 16 _vec128 - gdb_arm_q6 = 97, // 22 660 16 _vec128 - gdb_arm_q7 = 98, // 23 676 16 _vec128 - gdb_arm_q8 = 99, // 24 692 16 _vec128 - gdb_arm_q9 = 100, // 25 708 16 _vec128 - gdb_arm_q10 = 101, // 26 724 16 _vec128 - gdb_arm_q11 = 102, // 27 740 16 _vec128 - gdb_arm_q12 = 103, // 28 756 16 _vec128 - gdb_arm_q13 = 104, // 29 772 16 _vec128 - gdb_arm_q14 = 105, // 30 788 16 _vec128 - gdb_arm_q15 = 106 // 31 804 16 _vec128 -}; -#endif // utility_ARM_GCC_Registers_h_ - diff --git a/contrib/llvm/tools/lldb/source/Utility/ARM_ehframe_Registers.h b/contrib/llvm/tools/lldb/source/Utility/ARM_ehframe_Registers.h new file mode 100644 index 000000000000..7d4951d6ce89 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Utility/ARM_ehframe_Registers.h @@ -0,0 +1,38 @@ +//===-- ARM_ehframe_Registers.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_ARM_ehframe_Registers_h_ +#define utility_ARM_ehframe_Registers_h_ + +// The register numbers used in the eh_frame unwind information. +// Should be the same as DWARF register numbers. + +enum +{ + ehframe_r0 = 0, + ehframe_r1, + ehframe_r2, + ehframe_r3, + ehframe_r4, + ehframe_r5, + ehframe_r6, + ehframe_r7, + ehframe_r8, + ehframe_r9, + ehframe_r10, + ehframe_r11, + ehframe_r12, + ehframe_sp, + ehframe_lr, + ehframe_pc, + ehframe_cpsr +}; + +#endif // utility_ARM_ehframe_Registers_h_ + diff --git a/contrib/llvm/tools/lldb/source/Utility/ConvertEnum.cpp b/contrib/llvm/tools/lldb/source/Utility/ConvertEnum.cpp index e108f5e75420..3231397a05e3 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ConvertEnum.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/ConvertEnum.cpp @@ -63,6 +63,8 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type) return "objc-cfstrings"; case eSectionTypeDWARFDebugAbbrev: return "dwarf-abbrev"; + case eSectionTypeDWARFDebugAddr: + return "dwarf-addr"; case eSectionTypeDWARFDebugAranges: return "dwarf-aranges"; case eSectionTypeDWARFDebugFrame: @@ -75,6 +77,8 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type) return "dwarf-loc"; case eSectionTypeDWARFDebugMacInfo: return "dwarf-macinfo"; + case eSectionTypeDWARFDebugMacro: + return "dwarf-macro"; case eSectionTypeDWARFDebugPubNames: return "dwarf-pubnames"; case eSectionTypeDWARFDebugPubTypes: @@ -83,6 +87,8 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type) return "dwarf-ranges"; case eSectionTypeDWARFDebugStr: return "dwarf-str"; + case eSectionTypeDWARFDebugStrOffsets: + return "dwarf-str-offsets"; case eSectionTypeELFSymbolTable: return "elf-symbol-table"; case eSectionTypeELFDynamicSymbols: @@ -101,8 +107,14 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type) return "apple-objc"; case eSectionTypeEHFrame: return "eh-frame"; + case eSectionTypeARMexidx: + return "ARM.exidx"; + case eSectionTypeARMextab: + return "ARM.extab"; case eSectionTypeCompactUnwind: return "compact-unwind"; + case eSectionTypeGoSymtab: + return "go-symtab"; case eSectionTypeOther: return "regular"; } diff --git a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp index 1e16a5ac9952..8b96a06e08e8 100644 --- a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp @@ -12,6 +12,7 @@ #include <limits.h> #include "lldb/Core/StreamString.h" #include "lldb/Host/StringConvert.h" +#include "llvm/Support/ErrorHandling.h" using namespace lldb_private; @@ -60,38 +61,66 @@ JSONString::Write (Stream& s) s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str()); } -JSONNumber::JSONNumber () : - JSONValue(JSONValue::Kind::Number), - m_is_integer(true), - m_data(0), - m_double(0.0) +uint64_t +JSONNumber::GetAsUnsigned() const { + switch (m_data_type) + { + case DataType::Unsigned: + return m_data.m_unsigned; + case DataType::Signed: + return (uint64_t)m_data.m_signed; + case DataType::Double: + return (uint64_t)m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } -JSONNumber::JSONNumber (uint64_t i) : - JSONValue(JSONValue::Kind::Number), - m_is_integer(true), - m_data(i), - m_double(0.0) +int64_t +JSONNumber::GetAsSigned() const { + switch (m_data_type) + { + case DataType::Unsigned: + return (int64_t)m_data.m_unsigned; + case DataType::Signed: + return m_data.m_signed; + case DataType::Double: + return (int64_t)m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } - -JSONNumber::JSONNumber (double d) : - JSONValue(JSONValue::Kind::Number), - m_is_integer(false), - m_data(0), - m_double(d) +double +JSONNumber::GetAsDouble() const { + switch (m_data_type) + { + case DataType::Unsigned: + return (double)m_data.m_unsigned; + case DataType::Signed: + return (double)m_data.m_signed; + case DataType::Double: + return m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } void JSONNumber::Write (Stream& s) { - if (m_is_integer) - s.Printf("%" PRIu64, m_data); - else - s.Printf("%g", m_double); + switch (m_data_type) + { + case DataType::Unsigned: + s.Printf("%" PRIu64, m_data.m_unsigned); + break; + case DataType::Signed: + s.Printf("%" PRId64, m_data.m_signed); + break; + case DataType::Double: + s.Printf("%g", m_data.m_double); + break; + } } JSONTrue::JSONTrue () : @@ -392,7 +421,7 @@ JSONParser::GetToken (std::string &value) case 'E': if (exp_index != 0) { - error.Printf("error: extra expenent character found at offset %" PRIu64, start_index); + error.Printf("error: extra exponent character found at offset %" PRIu64, start_index); value = std::move(error.GetString()); return Token::Error; } @@ -617,10 +646,20 @@ JSONParser::ParseJSONValue () case JSONParser::Token::Integer: { - bool success = false; - uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); - if (success) - return JSONValue::SP(new JSONNumber(uval)); + if (value.front() == '-') + { + bool success = false; + int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success); + if (success) + return JSONValue::SP(new JSONNumber(sval)); + } + else + { + bool success = false; + uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); + if (success) + return JSONValue::SP(new JSONNumber(uval)); + } } break; diff --git a/contrib/llvm/tools/lldb/source/Utility/ModuleCache.cpp b/contrib/llvm/tools/lldb/source/Utility/ModuleCache.cpp index ce0df241dc22..7c57d0baeccd 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ModuleCache.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/ModuleCache.cpp @@ -9,7 +9,9 @@ #include "ModuleCache.h" +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" @@ -27,8 +29,22 @@ using namespace lldb_private; namespace { const char* kModulesSubdir = ".cache"; -const char* kLockFileName = ".lock"; +const char* kLockDirName = ".lock"; const char* kTempFileName = ".temp"; +const char* kTempSymFileName = ".symtemp"; +const char* kSymFileExtension = ".sym"; + +class ModuleLock +{ +private: + File m_file; + std::unique_ptr<lldb_private::LockFile> m_lock; + FileSpec m_file_spec; + +public: + ModuleLock (const FileSpec &root_dir_spec, const UUID &uuid, Error& error); + void Delete (); +}; FileSpec JoinPath (const FileSpec &path1, const char* path2) @@ -59,13 +75,76 @@ GetModuleDirectory (const FileSpec &root_dir_spec, const UUID &uuid) return JoinPath (modules_dir_spec, uuid.GetAsString ().c_str ()); } +FileSpec +GetSymbolFileSpec(const FileSpec& module_file_spec) +{ + return FileSpec((module_file_spec.GetPath() + kSymFileExtension).c_str(), false); +} + +void +DeleteExistingModule (const FileSpec &root_dir_spec, const FileSpec &sysroot_module_path_spec) +{ + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_MODULES)); + UUID module_uuid; + { + auto module_sp = std::make_shared<Module>(ModuleSpec (sysroot_module_path_spec)); + module_uuid = module_sp->GetUUID (); + } + + if (!module_uuid.IsValid ()) + return; + + Error error; + ModuleLock lock (root_dir_spec, module_uuid, error); + if (error.Fail ()) + { + if (log) + log->Printf ("Failed to lock module %s: %s", + module_uuid.GetAsString ().c_str (), + error.AsCString ()); + } + + auto link_count = FileSystem::GetHardlinkCount (sysroot_module_path_spec); + if (link_count == -1) + return; + + if (link_count > 2) // module is referred by other hosts. + return; + + const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_uuid); + FileSystem::DeleteDirectory (module_spec_dir, true); + lock.Delete(); +} + +void +DecrementRefExistingModule (const FileSpec &root_dir_spec, const FileSpec &sysroot_module_path_spec) +{ + // Remove $platform/.cache/$uuid folder if nobody else references it. + DeleteExistingModule (root_dir_spec, sysroot_module_path_spec); + + // Remove sysroot link. + FileSystem::Unlink (sysroot_module_path_spec); + + FileSpec symfile_spec = GetSymbolFileSpec (sysroot_module_path_spec); + if (symfile_spec.Exists ()) // delete module's symbol file if exists. + FileSystem::Unlink (symfile_spec); +} + Error -CreateHostSysRootModuleLink (const FileSpec &root_dir_spec, const char *hostname, const FileSpec &platform_module_spec, const FileSpec &local_module_spec) +CreateHostSysRootModuleLink (const FileSpec &root_dir_spec, const char *hostname, + const FileSpec &platform_module_spec, + const FileSpec &local_module_spec, + bool delete_existing) { const auto sysroot_module_path_spec = JoinPath ( JoinPath (root_dir_spec, hostname), platform_module_spec.GetPath ().c_str ()); if (sysroot_module_path_spec.Exists()) - return Error (); + { + if (!delete_existing) + return Error (); + + DecrementRefExistingModule (root_dir_spec, sysroot_module_path_spec); + } const auto error = MakeDirectory (FileSpec (sysroot_module_path_spec.GetDirectory ().AsCString (), false)); if (error.Fail ()) @@ -76,14 +155,48 @@ CreateHostSysRootModuleLink (const FileSpec &root_dir_spec, const char *hostname } // namespace +ModuleLock::ModuleLock (const FileSpec &root_dir_spec, const UUID &uuid, Error& error) +{ + const auto lock_dir_spec = JoinPath (root_dir_spec, kLockDirName); + error = MakeDirectory (lock_dir_spec); + if (error.Fail ()) + return; + + m_file_spec = JoinPath (lock_dir_spec, uuid.GetAsString ().c_str ()); + m_file.Open (m_file_spec.GetCString (), + File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); + if (!m_file) + { + error.SetErrorToErrno (); + return; + } + + m_lock.reset (new lldb_private::LockFile (m_file.GetDescriptor ())); + error = m_lock->WriteLock (0, 1); + if (error.Fail ()) + error.SetErrorStringWithFormat ("Failed to lock file: %s", error.AsCString ()); +} + +void ModuleLock::Delete () +{ + if (!m_file) + return; + + m_file.Close (); + FileSystem::Unlink (m_file_spec); +} + +///////////////////////////////////////////////////////////////////////// + Error ModuleCache::Put (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, - const FileSpec &tmp_file) + const FileSpec &tmp_file, + const FileSpec &target_file) { const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ()); - const auto module_file_path = JoinPath (module_spec_dir, module_spec.GetFileSpec ().GetFilename ().AsCString ()); + const auto module_file_path = JoinPath (module_spec_dir, target_file.GetFilename ().AsCString ()); const auto tmp_file_path = tmp_file.GetPath (); const auto err_code = llvm::sys::fs::rename (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ()); @@ -91,7 +204,7 @@ ModuleCache::Put (const FileSpec &root_dir_spec, return Error ("Failed to rename file %s to %s: %s", tmp_file_path.c_str (), module_file_path.GetPath ().c_str (), err_code.message ().c_str ()); - const auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, module_spec.GetFileSpec(), module_file_path); + const auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, target_file, module_file_path, true); if (error.Fail ()) return Error ("Failed to create link to %s: %s", module_file_path.GetPath ().c_str (), error.AsCString ()); return Error (); @@ -122,7 +235,7 @@ ModuleCache::Get (const FileSpec &root_dir_spec, return Error ("Module %s has invalid file size", module_file_path.GetPath ().c_str ()); // We may have already cached module but downloaded from an another host - in this case let's create a link to it. - const auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, module_spec.GetFileSpec(), module_file_path); + auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, module_spec.GetFileSpec(), module_file_path, false); if (error.Fail ()) return Error ("Failed to create link to %s: %s", module_file_path.GetPath().c_str(), error.AsCString()); @@ -130,9 +243,19 @@ ModuleCache::Get (const FileSpec &root_dir_spec, cached_module_spec.GetUUID ().Clear (); // Clear UUID since it may contain md5 content hash instead of real UUID. cached_module_spec.GetFileSpec () = module_file_path; cached_module_spec.GetPlatformFileSpec () = module_spec.GetFileSpec (); - cached_module_sp.reset (new Module (cached_module_spec)); - if (did_create_ptr) - *did_create_ptr = true; + + error = ModuleList::GetSharedModule(cached_module_spec, + cached_module_sp, + nullptr, + nullptr, + did_create_ptr, + false); + if (error.Fail()) + return error; + + FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec ()); + if (symfile_spec.Exists ()) + cached_module_sp->SetSymbolFileFileSpec (symfile_spec); m_loaded_modules.insert (std::make_pair (module_spec.GetUUID ().GetAsString (), cached_module_sp)); @@ -143,7 +266,8 @@ Error ModuleCache::GetAndPut (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, - const Downloader &downloader, + const ModuleDownloader &module_downloader, + const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr) { @@ -152,18 +276,9 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec, if (error.Fail ()) return error; - // Open lock file. - const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName); - File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); - if (!lock_file) - { - error.SetErrorToErrno (); - return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); - } - LockFile lock (lock_file.GetDescriptor ()); - error = lock.WriteLock (0, 1); + ModuleLock lock (root_dir_spec, module_spec.GetUUID (), error); if (error.Fail ()) - return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); + return Error("Failed to lock module %s: %s", module_spec.GetUUID ().GetAsString().c_str(), error.AsCString ()); // Check local cache for a module. error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); @@ -171,16 +286,37 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec, return error; const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName); - error = downloader (module_spec, tmp_download_file_spec); + error = module_downloader (module_spec, tmp_download_file_spec); llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ()); if (error.Fail ()) return Error("Failed to download module: %s", error.AsCString ()); // Put downloaded file into local module cache. - error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec); + error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ()); if (error.Fail ()) return Error ("Failed to put module into cache: %s", error.AsCString ()); tmp_file_remover.releaseFile (); - return Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); + error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); + if (error.Fail ()) + return error; + + // Fetching a symbol file for the module + const auto tmp_download_sym_file_spec = JoinPath (module_spec_dir, kTempSymFileName); + error = symfile_downloader (cached_module_sp, tmp_download_sym_file_spec); + llvm::FileRemover tmp_symfile_remover (tmp_download_sym_file_spec.GetPath ().c_str ()); + if (error.Fail ()) + // Failed to download a symfile but fetching the module was successful. The module might + // contain the neccessary symbols and the debugging is also possible without a symfile. + return Error (); + + error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec ())); + if (error.Fail ()) + return Error ("Failed to put symbol file into cache: %s", error.AsCString ()); + + tmp_symfile_remover.releaseFile(); + + FileSpec symfile_spec = GetSymbolFileSpec (cached_module_sp->GetFileSpec ()); + cached_module_sp->SetSymbolFileFileSpec (symfile_spec); + return Error (); } diff --git a/contrib/llvm/tools/lldb/source/Utility/ModuleCache.h b/contrib/llvm/tools/lldb/source/Utility/ModuleCache.h index 791e2b35ae3d..bb9b308304b6 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ModuleCache.h +++ b/contrib/llvm/tools/lldb/source/Utility/ModuleCache.h @@ -46,13 +46,15 @@ class UUID; class ModuleCache { public: - using Downloader = std::function<Error (const ModuleSpec&, const FileSpec&)>; + using ModuleDownloader = std::function<Error (const ModuleSpec&, const FileSpec&)>; + using SymfileDownloader = std::function<Error (const lldb::ModuleSP&, const FileSpec&)>; Error GetAndPut(const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, - const Downloader &downloader, + const ModuleDownloader &module_downloader, + const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr); @@ -61,7 +63,8 @@ private: Put (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, - const FileSpec &tmp_file); + const FileSpec &tmp_file, + const FileSpec &target_file); Error Get (const FileSpec &root_dir_spec, diff --git a/contrib/llvm/tools/lldb/source/Utility/SharingPtr.cpp b/contrib/llvm/tools/lldb/source/Utility/SharingPtr.cpp index 4083975bba7c..7f1278567ff1 100644 --- a/contrib/llvm/tools/lldb/source/Utility/SharingPtr.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/SharingPtr.cpp @@ -11,7 +11,7 @@ #if defined (ENABLE_SP_LOGGING) -// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignements +// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments // and allow them to be queried using a pointer by a call to: #include <execinfo.h> #include <map> diff --git a/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp b/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp index 6302c033c0c1..ae92704668fc 100644 --- a/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp @@ -120,19 +120,30 @@ StringExtractor::DecodeHexU8() //---------------------------------------------------------------------- // Extract an unsigned character from two hex ASCII chars in the packet -// string +// string, or return fail_value on failure //---------------------------------------------------------------------- uint8_t StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail) { + // On success, fail_value will be overwritten with the next + // character in the stream + GetHexU8Ex(fail_value, set_eof_on_fail); + return fail_value; +} + +bool +StringExtractor::GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail) +{ int byte = DecodeHexU8(); if (byte == -1) { if (set_eof_on_fail || m_index >= m_packet.size()) m_index = UINT64_MAX; - return fail_value; + // ch should not be changed in case of failure + return false; } - return (uint8_t)byte; + ch = (uint8_t)byte; + return true; } uint32_t diff --git a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp index 17ee0b63f3e5..56df0be21edf 100644 --- a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -163,12 +163,12 @@ StringExtractorGDBRemote::GetServerPacketType () const case 'K': if (PACKET_STARTS_WITH ("qKillSpawnedProcess")) return eServerPacketType_qKillSpawnedProcess; break; - + case 'L': if (PACKET_STARTS_WITH ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer; if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess; break; - + case 'M': if (PACKET_STARTS_WITH ("qMemoryRegionInfo:")) return eServerPacketType_qMemoryRegionInfo; if (PACKET_MATCHES ("qMemoryRegionInfo")) return eServerPacketType_qMemoryRegionInfoSupported; @@ -182,7 +182,11 @@ StringExtractorGDBRemote::GetServerPacketType () const if (PACKET_STARTS_WITH ("qPlatform_chmod:")) return eServerPacketType_qPlatform_chmod; if (PACKET_MATCHES ("qProcessInfo")) return eServerPacketType_qProcessInfo; break; - + + case 'Q': + if (PACKET_MATCHES ("qQueryGDBServer")) return eServerPacketType_qQueryGDBServer; + break; + case 'R': if (PACKET_STARTS_WITH ("qRcmd,")) return eServerPacketType_qRcmd; if (PACKET_STARTS_WITH ("qRegisterInfo")) return eServerPacketType_qRegisterInfo; @@ -221,7 +225,9 @@ StringExtractorGDBRemote::GetServerPacketType () const break; case 'j': - if (PACKET_MATCHES("jSignalInfo")) return eServerPacketType_jSignalsInfo; + if (PACKET_MATCHES("jSignalsInfo")) return eServerPacketType_jSignalsInfo; + if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo; + case 'v': if (PACKET_STARTS_WITH("vFile:")) @@ -308,6 +314,12 @@ StringExtractorGDBRemote::GetServerPacketType () const case 'S': return eServerPacketType_S; + case 'x': + return eServerPacketType_x; + + case 'X': + return eServerPacketType_X; + case 'T': return eServerPacketType_T; diff --git a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.h b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.h index 475b5a8e36c8..7e2f1e7c6962 100644 --- a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.h @@ -54,6 +54,7 @@ public: eServerPacketType_qGroupName, eServerPacketType_qHostInfo, eServerPacketType_qLaunchGDBServer, + eServerPacketType_qQueryGDBServer, eServerPacketType_qKillSpawnedProcess, eServerPacketType_qLaunchSuccess, eServerPacketType_qModuleInfo, @@ -97,6 +98,7 @@ public: eServerPacketType_QSyncThreadState, eServerPacketType_QThreadSuffixSupported, + eServerPacketType_jThreadsInfo, eServerPacketType_qsThreadInfo, eServerPacketType_qfThreadInfo, eServerPacketType_qGetPid, @@ -144,6 +146,8 @@ public: eServerPacketType_s, eServerPacketType_S, eServerPacketType_T, + eServerPacketType_x, + eServerPacketType_X, eServerPacketType_Z, eServerPacketType_z, diff --git a/contrib/llvm/tools/lldb/source/Utility/TaskPool.cpp b/contrib/llvm/tools/lldb/source/Utility/TaskPool.cpp new file mode 100644 index 000000000000..75fe59d1e711 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Utility/TaskPool.cpp @@ -0,0 +1,88 @@ +//===--------------------- TaskPool.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/Utility/TaskPool.h" + +namespace +{ + class TaskPoolImpl + { + public: + static TaskPoolImpl& + GetInstance(); + + void + AddTask(std::function<void()>&& task_fn); + + private: + TaskPoolImpl(); + + static void + Worker(TaskPoolImpl* pool); + + std::queue<std::function<void()>> m_tasks; + std::mutex m_tasks_mutex; + uint32_t m_thread_count; + }; + +} // end of anonymous namespace + +TaskPoolImpl& +TaskPoolImpl::GetInstance() +{ + static TaskPoolImpl g_task_pool_impl; + return g_task_pool_impl; +} + +void +TaskPool::AddTaskImpl(std::function<void()>&& task_fn) +{ + TaskPoolImpl::GetInstance().AddTask(std::move(task_fn)); +} + +TaskPoolImpl::TaskPoolImpl() : + m_thread_count(0) +{ +} + +void +TaskPoolImpl::AddTask(std::function<void()>&& task_fn) +{ + static const uint32_t max_threads = std::thread::hardware_concurrency(); + + std::unique_lock<std::mutex> lock(m_tasks_mutex); + m_tasks.emplace(std::move(task_fn)); + if (m_thread_count < max_threads) + { + m_thread_count++; + lock.unlock(); + + std::thread (Worker, this).detach(); + } +} + +void +TaskPoolImpl::Worker(TaskPoolImpl* pool) +{ + while (true) + { + std::unique_lock<std::mutex> lock(pool->m_tasks_mutex); + if (pool->m_tasks.empty()) + { + pool->m_thread_count--; + break; + } + + std::function<void()> f = pool->m_tasks.front(); + pool->m_tasks.pop(); + lock.unlock(); + + f(); + } +} diff --git a/contrib/llvm/tools/lldb/source/Utility/UriParser.cpp b/contrib/llvm/tools/lldb/source/Utility/UriParser.cpp index 86020d17fc3e..77e16b02aaed 100644 --- a/contrib/llvm/tools/lldb/source/Utility/UriParser.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/UriParser.cpp @@ -10,10 +10,10 @@ #include "Utility/UriParser.h" // C Includes -#include <stdlib.h> -#include <stdio.h> // C++ Includes +#include <cstring> + // Other libraries and framework includes // Project includes #include "lldb/Host/StringConvert.h" @@ -24,43 +24,71 @@ using namespace lldb_private; // UriParser::Parse //---------------------------------------------------------------------- bool -UriParser::Parse(const char* uri, - std::string& scheme, - std::string& hostname, - int& port, - std::string& path - ) +UriParser::Parse(const std::string& uri, + std::string& scheme, + std::string& hostname, + int& port, + std::string& path) { - char scheme_buf[100] = {0}; - char hostname_buf[256] = {0}; - char port_buf[11] = {0}; // 10==strlen(2^32) - char path_buf[2049] = {'/', 0}; - - bool ok = false; - if (4==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]/%2047s", scheme_buf, hostname_buf, port_buf, path_buf+1)) { ok = true; } - else if (3==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]", scheme_buf, hostname_buf, port_buf)) { ok = true; } - else if (3==sscanf(uri, "%99[^:/]://%255[^/]/%2047s", scheme_buf, hostname_buf, path_buf+1)) { ok = true; } - else if (2==sscanf(uri, "%99[^:/]://%255[^/]", scheme_buf, hostname_buf)) { ok = true; } + std::string tmp_scheme, tmp_hostname, tmp_port, tmp_path; + + static const char* kSchemeSep = "://"; + auto pos = uri.find(kSchemeSep); + if (pos == std::string::npos) + return false; + + // Extract path. + tmp_scheme = uri.substr(0, pos); + auto host_pos = pos + strlen(kSchemeSep); + auto path_pos = uri.find('/', host_pos); + if (path_pos != std::string::npos) + tmp_path = uri.substr(path_pos); + else + tmp_path = "/"; + + auto host_port = uri.substr( + host_pos, ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos); + + // Extract hostname + if (host_port[0] == '[') + { + // hostname is enclosed with square brackets. + pos = host_port.find(']'); + if (pos == std::string::npos) + return false; + + tmp_hostname = host_port.substr(1, pos - 1); + host_port.erase(0, pos + 1); + } + else + { + pos = host_port.find(':'); + tmp_hostname = host_port.substr(0, (pos != std::string::npos) ? pos : host_port.size()); + host_port.erase(0, (pos != std::string::npos) ? pos : host_port.size()); + } - bool success = false; - int port_tmp = -1; - if (port_buf[0]) + // Extract port + tmp_port = host_port; + if (!tmp_port.empty()) { - port_tmp = StringConvert::ToUInt32(port_buf, UINT32_MAX, 10, &success); + if (tmp_port[0] != ':') + return false; + tmp_port = tmp_port.substr(1); + bool success = false; + auto port_tmp = StringConvert::ToUInt32(tmp_port.c_str(), UINT32_MAX, 10, &success); if (!success || port_tmp > 65535) { // there are invalid characters in port_buf return false; } - } - - if (ok) - { - scheme.assign(scheme_buf); - hostname.assign(hostname_buf); port = port_tmp; - path.assign(path_buf); } - return ok; + else + port = -1; + + scheme = tmp_scheme; + hostname = tmp_hostname; + path = tmp_path; + return true; } diff --git a/contrib/llvm/tools/lldb/source/Utility/UriParser.h b/contrib/llvm/tools/lldb/source/Utility/UriParser.h index fb129eaf79d5..8cbaaeab18cd 100644 --- a/contrib/llvm/tools/lldb/source/Utility/UriParser.h +++ b/contrib/llvm/tools/lldb/source/Utility/UriParser.h @@ -28,12 +28,12 @@ public: // // if the url is invalid, function returns false and // output parameters remain unchanged - static bool Parse(const char* uri, - std::string& scheme, - std::string& hostname, - int& port, - std::string& path - ); + static bool + Parse(const std::string& uri, + std::string& scheme, + std::string& hostname, + int& port, + std::string& path); }; #endif // utility_UriParser_h_ |