1292068Ssjg//===-- UUID.h --------------------------------------------------*- C++ -*-===// 2236769Sobrien// 3236769Sobrien// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4236769Sobrien// See https://llvm.org/LICENSE.txt for license information. 5236769Sobrien// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6236769Sobrien// 7236769Sobrien//===----------------------------------------------------------------------===// 8236769Sobrien 9236769Sobrien#ifndef LLDB_UTILITY_UUID_H 10236769Sobrien#define LLDB_UTILITY_UUID_H 11236769Sobrien 12236769Sobrien#include "llvm/ADT/ArrayRef.h" 13236769Sobrien#include "llvm/ADT/StringRef.h" 14236769Sobrien#include "llvm/Support/Endian.h" 15236769Sobrien#include <cstddef> 16236769Sobrien#include <cstdint> 17236769Sobrien#include <string> 18236769Sobrien 19236769Sobriennamespace lldb_private { 20236769Sobrien 21236769Sobrien class Stream; 22236769Sobrien 23236769Sobrienclass UUID { 24236769Sobrien // Represents UUID's of various sizes. In all cases, a uuid of all zeros is 25236769Sobrien // treated as an "Invalid UUID" marker, and the UUID created from such data 26236769Sobrien // will return false for IsValid. 27236769Sobrienpublic: 28236769Sobrien UUID() = default; 29236769Sobrien 30236769Sobrien /// Creates a uuid from the data pointed to by the bytes argument. 31236769Sobrien UUID(llvm::ArrayRef<uint8_t> bytes) : m_bytes(bytes.begin(), bytes.end()) { 32236769Sobrien if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) { 33236769Sobrien Clear(); 34236769Sobrien } 35236769Sobrien } 36236769Sobrien 37236769Sobrien // Reference: 38236769Sobrien // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html 39236769Sobrien struct CvRecordPdb70 { 40236769Sobrien struct { 41236769Sobrien llvm::support::ulittle32_t Data1; 42236769Sobrien llvm::support::ulittle16_t Data2; 43236769Sobrien llvm::support::ulittle16_t Data3; 44236769Sobrien uint8_t Data4[8]; 45236769Sobrien } Uuid; 46236769Sobrien llvm::support::ulittle32_t Age; 47236769Sobrien // char PDBFileName[]; 48236769Sobrien }; 49236769Sobrien 50236769Sobrien /// Create a UUID from CvRecordPdb70. 51236769Sobrien UUID(CvRecordPdb70 debug_info); 52236769Sobrien 53236769Sobrien /// Creates a UUID from the data pointed to by the bytes argument. 54236769Sobrien UUID(const void *bytes, uint32_t num_bytes) { 55236769Sobrien if (!bytes) 56236769Sobrien return; 57236769Sobrien *this 58236769Sobrien = UUID(llvm::ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(bytes), 59236769Sobrien num_bytes)); 60236769Sobrien } 61236769Sobrien 62236769Sobrien void Clear() { m_bytes.clear(); } 63236769Sobrien 64236769Sobrien void Dump(Stream *s) const; 65236769Sobrien 66236769Sobrien llvm::ArrayRef<uint8_t> GetBytes() const { return m_bytes; } 67236769Sobrien 68236769Sobrien explicit operator bool() const { return IsValid(); } 69236769Sobrien bool IsValid() const { return !m_bytes.empty(); } 70236769Sobrien 71236769Sobrien std::string GetAsString(llvm::StringRef separator = "-") const; 72236769Sobrien 73236769Sobrien bool SetFromStringRef(llvm::StringRef str); 74236769Sobrien 75236769Sobrien /// Decode as many UUID bytes as possible from the C string \a cstr. 76236769Sobrien /// 77236769Sobrien /// \param[in] str 78236769Sobrien /// An llvm::StringRef that points at a UUID string value (no leading 79236769Sobrien /// spaces). The string must contain only hex characters and optionally 80236769Sobrien /// can contain the '-' sepearators. 81236769Sobrien /// 82236769Sobrien /// \param[in] uuid_bytes 83236769Sobrien /// A buffer of bytes that will contain a full or partially decoded UUID. 84236769Sobrien /// 85236769Sobrien /// \return 86236769Sobrien /// The original string, with all decoded bytes removed. 87236769Sobrien static llvm::StringRef 88236769Sobrien DecodeUUIDBytesFromString(llvm::StringRef str, 89236769Sobrien llvm::SmallVectorImpl<uint8_t> &uuid_bytes); 90236769Sobrien 91236769Sobrienprivate: 92236769Sobrien // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations 93236769Sobrien // for this case. 94236769Sobrien llvm::SmallVector<uint8_t, 20> m_bytes; 95236769Sobrien 96236769Sobrien friend bool operator==(const UUID &LHS, const UUID &RHS) { 97236769Sobrien return LHS.m_bytes == RHS.m_bytes; 98236769Sobrien } 99236769Sobrien friend bool operator!=(const UUID &LHS, const UUID &RHS) { 100236769Sobrien return !(LHS == RHS); 101236769Sobrien } 102236769Sobrien friend bool operator<(const UUID &LHS, const UUID &RHS) { 103236769Sobrien return LHS.m_bytes < RHS.m_bytes; 104236769Sobrien } 105236769Sobrien friend bool operator<=(const UUID &LHS, const UUID &RHS) { 106 return !(RHS < LHS); 107 } 108 friend bool operator>(const UUID &LHS, const UUID &RHS) { return RHS < LHS; } 109 friend bool operator>=(const UUID &LHS, const UUID &RHS) { 110 return !(LHS < RHS); 111 } 112}; 113} // namespace lldb_private 114 115#endif // LLDB_UTILITY_UUID_H 116