1 //===-- UUID.h --------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_UTILITY_UUID_H 10 #define LLDB_UTILITY_UUID_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/Support/Endian.h" 15 #include "llvm/Support/Error.h" 16 #include <cstddef> 17 #include <cstdint> 18 #include <string> 19 20 namespace lldb_private { 21 22 class Stream; 23 24 /// Represents UUID's of various sizes. In all cases, a uuid of all zeros is 25 /// treated as an "Invalid UUID" marker, and the UUID created from such data 26 /// will return false for IsValid. 27 class UUID { 28 public: 29 UUID() = default; 30 31 /// Create a uuid from the data pointed to by the bytes argument. UUID(llvm::ArrayRef<uint8_t> bytes)32 UUID(llvm::ArrayRef<uint8_t> bytes) : m_bytes(bytes) { 33 if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) { 34 Clear(); 35 } 36 } 37 38 // Reference: 39 // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html 40 struct CvRecordPdb70 { 41 struct { 42 llvm::support::ulittle32_t Data1; 43 llvm::support::ulittle16_t Data2; 44 llvm::support::ulittle16_t Data3; 45 uint8_t Data4[8]; 46 } Uuid; 47 llvm::support::ulittle32_t Age; 48 // char PDBFileName[]; 49 }; 50 51 /// Create a UUID from CvRecordPdb70. 52 UUID(CvRecordPdb70 debug_info); 53 54 /// Create a UUID from the data pointed to by the bytes argument. UUID(const void * bytes,uint32_t num_bytes)55 UUID(const void *bytes, uint32_t num_bytes) { 56 if (!bytes) 57 return; 58 *this = UUID(llvm::ArrayRef<uint8_t>( 59 reinterpret_cast<const uint8_t *>(bytes), num_bytes)); 60 } 61 Clear()62 void Clear() { m_bytes.clear(); } 63 64 void Dump(Stream &s) const; 65 GetBytes()66 llvm::ArrayRef<uint8_t> GetBytes() const { return m_bytes; } 67 68 explicit operator bool() const { return IsValid(); } IsValid()69 bool IsValid() const { return !m_bytes.empty(); } 70 71 std::string GetAsString(llvm::StringRef separator = "-") const; 72 73 bool SetFromStringRef(llvm::StringRef str); 74 75 /// Decode as many UUID bytes as possible from the C string \a cstr. 76 /// 77 /// \param[in] str 78 /// An llvm::StringRef that points at a UUID string value (no leading 79 /// spaces). The string must contain only hex characters and optionally 80 /// can contain the '-' sepearators. 81 /// 82 /// \param[in] uuid_bytes 83 /// A buffer of bytes that will contain a full or partially decoded UUID. 84 /// 85 /// \return 86 /// The original string, with all decoded bytes removed. 87 static llvm::StringRef 88 DecodeUUIDBytesFromString(llvm::StringRef str, 89 llvm::SmallVectorImpl<uint8_t> &uuid_bytes); 90 91 /// Create a random UUID. 92 static UUID Generate(uint32_t num_bytes = 16); 93 94 private: 95 // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations 96 // for this case. 97 llvm::SmallVector<uint8_t, 20> m_bytes; 98 99 friend bool operator==(const UUID &LHS, const UUID &RHS) { 100 return LHS.m_bytes == RHS.m_bytes; 101 } 102 friend bool operator!=(const UUID &LHS, const UUID &RHS) { 103 return !(LHS == RHS); 104 } 105 friend bool operator<(const UUID &LHS, const UUID &RHS) { 106 return LHS.m_bytes < RHS.m_bytes; 107 } 108 friend bool operator<=(const UUID &LHS, const UUID &RHS) { 109 return !(RHS < LHS); 110 } 111 friend bool operator>(const UUID &LHS, const UUID &RHS) { return RHS < LHS; } 112 friend bool operator>=(const UUID &LHS, const UUID &RHS) { 113 return !(LHS < RHS); 114 } 115 }; 116 } // namespace lldb_private 117 118 #endif // LLDB_UTILITY_UUID_H 119