1 //===-- Stream.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_STREAM_H 10 #define LLDB_UTILITY_STREAM_H 11 12 #include "lldb/Utility/Flags.h" 13 #include "lldb/lldb-defines.h" 14 #include "lldb/lldb-enumerations.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/FormatVariadic.h" 17 #include "llvm/Support/raw_ostream.h" 18 19 #include <cstdarg> 20 #include <cstddef> 21 #include <cstdint> 22 #include <type_traits> 23 24 namespace lldb_private { 25 26 /// \class Stream Stream.h "lldb/Utility/Stream.h" 27 /// A stream class that can stream formatted output to a file. 28 class Stream { 29 public: 30 /// \a m_flags bit values. 31 enum { 32 eBinary = (1 << 0) ///< Get and put data as binary instead of as the default 33 /// string mode. 34 }; 35 36 /// Utility class for counting the bytes that were written to a stream in a 37 /// certain time span. 38 /// 39 /// \example 40 /// ByteDelta delta(*this); 41 /// WriteDataToStream("foo"); 42 /// return *delta; 43 class ByteDelta { 44 Stream *m_stream; 45 /// Bytes we have written so far when ByteDelta was created. 46 size_t m_start; 47 48 public: ByteDelta(Stream & s)49 ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {} 50 /// Returns the number of bytes written to the given Stream since this 51 /// ByteDelta object was created. 52 size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; } 53 }; 54 55 /// Construct with flags and address size and byte order. 56 /// 57 /// Construct with dump flags \a flags and the default address size. \a 58 /// flags can be any of the above enumeration logical OR'ed together. 59 Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, 60 bool colors = false); 61 62 /// Construct a default Stream, not binary, host byte order and host addr 63 /// size. 64 /// 65 Stream(bool colors = false); 66 67 // FIXME: Streams should not be copyable. Stream(const Stream & other)68 Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } 69 70 Stream &operator=(const Stream &rhs) { 71 m_flags = rhs.m_flags; 72 m_addr_size = rhs.m_addr_size; 73 m_byte_order = rhs.m_byte_order; 74 m_indent_level = rhs.m_indent_level; 75 return *this; 76 } 77 78 /// Destructor 79 virtual ~Stream(); 80 81 // Subclasses must override these methods 82 83 /// Flush the stream. 84 /// 85 /// Subclasses should flush the stream to make any output appear if the 86 /// stream has any buffering. 87 virtual void Flush() = 0; 88 89 /// Output character bytes to the stream. 90 /// 91 /// Appends \a src_len characters from the buffer \a src to the stream. 92 /// 93 /// \param[in] src 94 /// A buffer containing at least \a src_len bytes of data. 95 /// 96 /// \param[in] src_len 97 /// A number of bytes to append to the stream. 98 /// 99 /// \return 100 /// The number of bytes that were appended to the stream. Write(const void * src,size_t src_len)101 size_t Write(const void *src, size_t src_len) { 102 size_t appended_byte_count = WriteImpl(src, src_len); 103 m_bytes_written += appended_byte_count; 104 return appended_byte_count; 105 } 106 GetWrittenBytes()107 size_t GetWrittenBytes() const { return m_bytes_written; } 108 109 // Member functions 110 size_t PutChar(char ch); 111 112 /// Set the byte_order value. 113 /// 114 /// Sets the byte order of the data to extract. Extracted values will be 115 /// swapped if necessary when decoding. 116 /// 117 /// \param[in] byte_order 118 /// The byte order value to use when extracting data. 119 /// 120 /// \return 121 /// The old byte order value. 122 lldb::ByteOrder SetByteOrder(lldb::ByteOrder byte_order); 123 124 /// Format a C string from a printf style format and variable arguments and 125 /// encode and append the resulting C string as hex bytes. 126 /// 127 /// \param[in] format 128 /// A printf style format string. 129 /// 130 /// \param[in] ... 131 /// Any additional arguments needed for the printf format string. 132 /// 133 /// \return 134 /// The number of bytes that were appended to the stream. 135 size_t PrintfAsRawHex8(const char *format, ...) 136 __attribute__((__format__(__printf__, 2, 3))); 137 138 /// Append an uint8_t value in the hexadecimal format to the stream. 139 /// 140 /// \param[in] uvalue 141 /// The value to append. 142 /// 143 /// \return 144 /// The number of bytes that were appended to the stream. 145 size_t PutHex8(uint8_t uvalue); 146 147 size_t PutNHex8(size_t n, uint8_t uvalue); 148 149 size_t PutHex16(uint16_t uvalue, 150 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 151 152 size_t PutHex32(uint32_t uvalue, 153 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 154 155 size_t PutHex64(uint64_t uvalue, 156 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 157 158 size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, 159 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 160 size_t PutFloat(float f, 161 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 162 163 size_t PutDouble(double d, 164 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 165 166 size_t PutLongDouble(long double ld, 167 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); 168 169 size_t PutPointer(void *ptr); 170 171 // Append \a src_len bytes from \a src to the stream as hex characters (two 172 // ascii characters per byte of input data) 173 size_t 174 PutBytesAsRawHex8(const void *src, size_t src_len, 175 lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, 176 lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); 177 178 // Append \a src_len bytes from \a s to the stream as binary data. 179 size_t PutRawBytes(const void *s, size_t src_len, 180 lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid, 181 lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid); 182 183 size_t PutStringAsRawHex8(llvm::StringRef s); 184 185 /// Output a NULL terminated C string \a cstr to the stream \a s. 186 /// 187 /// \param[in] cstr 188 /// A NULL terminated C string. 189 /// 190 /// \return 191 /// A reference to this class so multiple things can be streamed 192 /// in one statement. 193 Stream &operator<<(const char *cstr); 194 195 Stream &operator<<(llvm::StringRef str); 196 197 /// Output a pointer value \a p to the stream \a s. 198 /// 199 /// \param[in] p 200 /// A void pointer. 201 /// 202 /// \return 203 /// A reference to this class so multiple things can be streamed 204 /// in one statement. 205 Stream &operator<<(const void *p); 206 207 /// Output a character \a ch to the stream \a s. 208 /// 209 /// \param[in] ch 210 /// A printable character value. 211 /// 212 /// \return 213 /// A reference to this class so multiple things can be streamed 214 /// in one statement. 215 Stream &operator<<(char ch); 216 217 Stream &operator<<(uint8_t uval) = delete; 218 Stream &operator<<(uint16_t uval) = delete; 219 Stream &operator<<(uint32_t uval) = delete; 220 Stream &operator<<(uint64_t uval) = delete; 221 Stream &operator<<(int8_t sval) = delete; 222 Stream &operator<<(int16_t sval) = delete; 223 Stream &operator<<(int32_t sval) = delete; 224 Stream &operator<<(int64_t sval) = delete; 225 226 /// Output a C string to the stream. 227 /// 228 /// Print a C string \a cstr to the stream. 229 /// 230 /// \param[in] cstr 231 /// The string to be output to the stream. 232 size_t PutCString(llvm::StringRef cstr); 233 234 /// Output a C string to the stream with color highlighting. 235 /// 236 /// Print a C string \a text to the stream, applying color highlighting to 237 /// the portions of the string that match the regex pattern \a pattern. The 238 /// pattern is matched as many times as possible throughout the string. If \a 239 /// pattern is nullptr, then no highlighting is applied. 240 /// 241 /// The highlighting is applied by enclosing the matching text in ANSI color 242 /// codes. The \a prefix parameter specifies the ANSI code to start the color 243 /// (the standard value is assumed to be 'ansi.fg.red', representing red 244 /// foreground), and the \a suffix parameter specifies the ANSI code to end 245 /// the color (the standard value is assumed to be 'ansi.normal', resetting to 246 /// default text style). These constants should be defined appropriately in 247 /// your environment. 248 /// 249 /// \param[in] text 250 /// The string to be output to the stream. 251 /// 252 /// \param[in] pattern 253 /// The regex pattern to match against the \a text string. Portions of \a 254 /// text matching this pattern will be colorized. If this parameter is 255 /// nullptr, highlighting is not performed. 256 /// \param[in] prefix 257 /// The ANSI color code to start colorization. This is 258 /// environment-dependent. 259 /// \param[in] suffix 260 /// The ANSI color code to end colorization. This is 261 /// environment-dependent. 262 263 void PutCStringColorHighlighted(llvm::StringRef text, 264 llvm::StringRef pattern = "", 265 llvm::StringRef prefix = "", 266 llvm::StringRef suffix = ""); 267 268 /// Output and End of Line character to the stream. 269 size_t EOL(); 270 271 /// Get the address size in bytes. 272 /// 273 /// \return 274 /// The size of an address in bytes that is used when outputting 275 /// address and pointer values to the stream. 276 uint32_t GetAddressByteSize() const; 277 278 /// The flags accessor. 279 /// 280 /// \return 281 /// A reference to the Flags member variable. 282 Flags &GetFlags(); 283 284 /// The flags const accessor. 285 /// 286 /// \return 287 /// A const reference to the Flags member variable. 288 const Flags &GetFlags() const; 289 290 //// The byte order accessor. 291 //// 292 //// \return 293 //// The byte order. 294 lldb::ByteOrder GetByteOrder() const; 295 296 /// Get the current indentation level. 297 /// 298 /// \return 299 /// The current indentation level. 300 unsigned GetIndentLevel() const; 301 302 /// Indent the current line in the stream. 303 /// 304 /// Indent the current line using the current indentation level and print an 305 /// optional string following the indentation spaces. 306 /// 307 /// \param[in] s 308 /// A string to print following the indentation. 309 size_t Indent(llvm::StringRef s = ""); 310 311 /// Decrement the current indentation level. 312 void IndentLess(unsigned amount = 2); 313 314 /// Increment the current indentation level. 315 void IndentMore(unsigned amount = 2); 316 317 /// Output an offset value. 318 /// 319 /// Put an offset \a uval out to the stream using the printf format in \a 320 /// format. 321 /// 322 /// \param[in] offset 323 /// The offset value. 324 /// 325 /// \param[in] format 326 /// The printf style format to use when outputting the offset. 327 void Offset(uint32_t offset, const char *format = "0x%8.8x: "); 328 329 /// Output printf formatted output to the stream. 330 /// 331 /// Print some formatted output to the stream. 332 /// 333 /// \param[in] format 334 /// A printf style format string. 335 /// 336 /// \param[in] ... 337 /// Variable arguments that are needed for the printf style 338 /// format string \a format. 339 size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); 340 341 size_t PrintfVarArg(const char *format, va_list args); 342 Format(const char * format,Args &&...args)343 template <typename... Args> void Format(const char *format, Args &&... args) { 344 PutCString(llvm::formatv(format, std::forward<Args>(args)...).str()); 345 } 346 347 /// Output a quoted C string value to the stream. 348 /// 349 /// Print a double quoted NULL terminated C string to the stream using the 350 /// printf format in \a format. 351 /// 352 /// \param[in] cstr 353 /// A NULL terminated C string value. 354 /// 355 /// \param[in] format 356 /// The optional C string format that can be overridden. 357 void QuotedCString(const char *cstr, const char *format = "\"%s\""); 358 359 /// Set the address size in bytes. 360 /// 361 /// \param[in] addr_size 362 /// The new size in bytes of an address to use when outputting 363 /// address and pointer values. 364 void SetAddressByteSize(uint32_t addr_size); 365 366 /// Set the current indentation level. 367 /// 368 /// \param[in] level 369 /// The new indentation level. 370 void SetIndentLevel(unsigned level); 371 372 /// Output a SLEB128 number to the stream. 373 /// 374 /// Put an SLEB128 \a uval out to the stream using the printf format in \a 375 /// format. 376 /// 377 /// \param[in] uval 378 /// A uint64_t value that was extracted as a SLEB128 value. 379 size_t PutSLEB128(int64_t uval); 380 381 /// Output a ULEB128 number to the stream. 382 /// 383 /// Put an ULEB128 \a uval out to the stream using the printf format in \a 384 /// format. 385 /// 386 /// \param[in] uval 387 /// A uint64_t value that was extracted as a ULEB128 value. 388 size_t PutULEB128(uint64_t uval); 389 390 /// Returns a raw_ostream that forwards the data to this Stream object. AsRawOstream()391 llvm::raw_ostream &AsRawOstream() { 392 return m_forwarder; 393 } 394 395 protected: 396 // Member variables 397 Flags m_flags; ///< Dump flags. 398 uint32_t m_addr_size = 4; ///< Size of an address in bytes. 399 lldb::ByteOrder 400 m_byte_order; ///< Byte order to use when encoding scalar types. 401 unsigned m_indent_level = 0; ///< Indention level. 402 std::size_t m_bytes_written = 0; ///< Number of bytes written so far. 403 404 void _PutHex8(uint8_t uvalue, bool add_prefix); 405 406 /// Output character bytes to the stream. 407 /// 408 /// Appends \a src_len characters from the buffer \a src to the stream. 409 /// 410 /// \param[in] src 411 /// A buffer containing at least \a src_len bytes of data. 412 /// 413 /// \param[in] src_len 414 /// A number of bytes to append to the stream. 415 /// 416 /// \return 417 /// The number of bytes that were appended to the stream. 418 virtual size_t WriteImpl(const void *src, size_t src_len) = 0; 419 420 /// \class RawOstreamForward Stream.h "lldb/Utility/Stream.h" 421 /// This is a wrapper class that exposes a raw_ostream interface that just 422 /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take 423 /// a raw_ostream within the LLDB code base. 424 class RawOstreamForward : public llvm::raw_ostream { 425 // Note: This stream must *not* maintain its own buffer, but instead 426 // directly write everything to the internal Stream class. Without this, 427 // we would run into the problem that the Stream written byte count would 428 // differ from the actually written bytes by the size of the internal 429 // raw_ostream buffer. 430 431 Stream &m_target; write_impl(const char * Ptr,size_t Size)432 void write_impl(const char *Ptr, size_t Size) override { 433 m_target.Write(Ptr, Size); 434 } 435 current_pos()436 uint64_t current_pos() const override { 437 return m_target.GetWrittenBytes(); 438 } 439 440 public: 441 RawOstreamForward(Stream &target, bool colors = false) raw_ostream(true)442 : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) { 443 enable_colors(colors); 444 } 445 }; 446 RawOstreamForward m_forwarder; 447 }; 448 449 /// Output an address value to this stream. 450 /// 451 /// Put an address \a addr out to the stream with optional \a prefix and \a 452 /// suffix strings. 453 /// 454 /// \param[in] s 455 /// The output stream. 456 /// 457 /// \param[in] addr 458 /// An address value. 459 /// 460 /// \param[in] addr_size 461 /// Size in bytes of the address, used for formatting. 462 /// 463 /// \param[in] prefix 464 /// A prefix C string. If nullptr, no prefix will be output. 465 /// 466 /// \param[in] suffix 467 /// A suffix C string. If nullptr, no suffix will be output. 468 void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, 469 const char *prefix = nullptr, const char *suffix = nullptr); 470 471 /// Output an address range to this stream. 472 /// 473 /// Put an address range \a lo_addr - \a hi_addr out to the stream with 474 /// optional \a prefix and \a suffix strings. 475 /// 476 /// \param[in] s 477 /// The output stream. 478 /// 479 /// \param[in] lo_addr 480 /// The start address of the address range. 481 /// 482 /// \param[in] hi_addr 483 /// The end address of the address range. 484 /// 485 /// \param[in] addr_size 486 /// Size in bytes of the address, used for formatting. 487 /// 488 /// \param[in] prefix 489 /// A prefix C string. If nullptr, no prefix will be output. 490 /// 491 /// \param[in] suffix 492 /// A suffix C string. If nullptr, no suffix will be output. 493 void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr, 494 uint32_t addr_size, const char *prefix = nullptr, 495 const char *suffix = nullptr); 496 497 } // namespace lldb_private 498 499 #endif // LLDB_UTILITY_STREAM_H 500