Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- RecordSerialization.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 LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
  10. #define LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
  11.  
  12. #include "llvm/ADT/ArrayRef.h"
  13. #include "llvm/ADT/StringRef.h"
  14. #include "llvm/DebugInfo/CodeView/CodeView.h"
  15. #include "llvm/DebugInfo/CodeView/CodeViewError.h"
  16. #include "llvm/Support/BinaryStreamReader.h"
  17. #include "llvm/Support/Endian.h"
  18. #include "llvm/Support/Error.h"
  19. #include <cinttypes>
  20.  
  21. namespace llvm {
  22. class APSInt;
  23. namespace codeview {
  24. using llvm::support::little32_t;
  25. using llvm::support::ulittle16_t;
  26. using llvm::support::ulittle32_t;
  27.  
  28. /// Limit on the size of all codeview symbol and type records, including the
  29. /// RecordPrefix. MSVC does not emit any records larger than this.
  30. enum : unsigned { MaxRecordLength = 0xFF00 };
  31.  
  32. struct RecordPrefix {
  33.   RecordPrefix() = default;
  34.   explicit RecordPrefix(uint16_t Kind) : RecordLen(2), RecordKind(Kind) {}
  35.  
  36.   ulittle16_t RecordLen;  // Record length, starting from &RecordKind.
  37.   ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
  38. };
  39.  
  40. /// Reinterpret a byte array as an array of characters. Does not interpret as
  41. /// a C string, as StringRef has several helpers (split) that make that easy.
  42. StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
  43. StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
  44.  
  45. inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
  46.  
  47. /// Decodes a numeric "leaf" value. These are integer literals encountered in
  48. /// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
  49. /// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
  50. /// that indicates the bitwidth and sign of the numeric data.
  51. Error consume(BinaryStreamReader &Reader, APSInt &Num);
  52.  
  53. /// Decodes a numeric leaf value that is known to be a particular type.
  54. Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
  55.  
  56. /// Decodes signed and unsigned fixed-length integers.
  57. Error consume(BinaryStreamReader &Reader, uint32_t &Item);
  58. Error consume(BinaryStreamReader &Reader, int32_t &Item);
  59.  
  60. /// Decodes a null terminated string.
  61. Error consume(BinaryStreamReader &Reader, StringRef &Item);
  62.  
  63. Error consume(StringRef &Data, APSInt &Num);
  64. Error consume(StringRef &Data, uint32_t &Item);
  65.  
  66. /// Decodes an arbitrary object whose layout matches that of the underlying
  67. /// byte sequence, and returns a pointer to the object.
  68. template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
  69.   return Reader.readObject(Item);
  70. }
  71.  
  72. template <typename T, typename U> struct serialize_conditional_impl {
  73.   serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
  74.  
  75.   Error deserialize(BinaryStreamReader &Reader) const {
  76.     if (!Func())
  77.       return Error::success();
  78.     return consume(Reader, Item);
  79.   }
  80.  
  81.   T &Item;
  82.   U Func;
  83. };
  84.  
  85. template <typename T, typename U>
  86. serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
  87.   return serialize_conditional_impl<T, U>(Item, Func);
  88. }
  89.  
  90. template <typename T, typename U> struct serialize_array_impl {
  91.   serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
  92.  
  93.   Error deserialize(BinaryStreamReader &Reader) const {
  94.     return Reader.readArray(Item, Func());
  95.   }
  96.  
  97.   ArrayRef<T> &Item;
  98.   U Func;
  99. };
  100.  
  101. template <typename T> struct serialize_vector_tail_impl {
  102.   serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
  103.  
  104.   Error deserialize(BinaryStreamReader &Reader) const {
  105.     T Field;
  106.     // Stop when we run out of bytes or we hit record padding bytes.
  107.     while (!Reader.empty() && Reader.peek() < LF_PAD0) {
  108.       if (auto EC = consume(Reader, Field))
  109.         return EC;
  110.       Item.push_back(Field);
  111.     }
  112.     return Error::success();
  113.   }
  114.  
  115.   std::vector<T> &Item;
  116. };
  117.  
  118. struct serialize_null_term_string_array_impl {
  119.   serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
  120.       : Item(Item) {}
  121.  
  122.   Error deserialize(BinaryStreamReader &Reader) const {
  123.     if (Reader.empty())
  124.       return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
  125.                                        "Null terminated string is empty!");
  126.  
  127.     while (Reader.peek() != 0) {
  128.       StringRef Field;
  129.       if (auto EC = Reader.readCString(Field))
  130.         return EC;
  131.       Item.push_back(Field);
  132.     }
  133.     return Reader.skip(1);
  134.   }
  135.  
  136.   std::vector<StringRef> &Item;
  137. };
  138.  
  139. template <typename T> struct serialize_arrayref_tail_impl {
  140.   serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
  141.  
  142.   Error deserialize(BinaryStreamReader &Reader) const {
  143.     uint32_t Count = Reader.bytesRemaining() / sizeof(T);
  144.     return Reader.readArray(Item, Count);
  145.   }
  146.  
  147.   ArrayRef<T> &Item;
  148. };
  149.  
  150. template <typename T> struct serialize_numeric_impl {
  151.   serialize_numeric_impl(T &Item) : Item(Item) {}
  152.  
  153.   Error deserialize(BinaryStreamReader &Reader) const {
  154.     return consume_numeric(Reader, Item);
  155.   }
  156.  
  157.   T &Item;
  158. };
  159.  
  160. template <typename T, typename U>
  161. serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
  162.   return serialize_array_impl<T, U>(Item, Func);
  163. }
  164.  
  165. inline serialize_null_term_string_array_impl
  166. serialize_null_term_string_array(std::vector<StringRef> &Item) {
  167.   return serialize_null_term_string_array_impl(Item);
  168. }
  169.  
  170. template <typename T>
  171. serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
  172.   return serialize_vector_tail_impl<T>(Item);
  173. }
  174.  
  175. template <typename T>
  176. serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
  177.   return serialize_arrayref_tail_impl<T>(Item);
  178. }
  179.  
  180. template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
  181.   return serialize_numeric_impl<T>(Item);
  182. }
  183.  
  184. template <typename T, typename U>
  185. Error consume(BinaryStreamReader &Reader,
  186.               const serialize_conditional_impl<T, U> &Item) {
  187.   return Item.deserialize(Reader);
  188. }
  189.  
  190. template <typename T, typename U>
  191. Error consume(BinaryStreamReader &Reader,
  192.               const serialize_array_impl<T, U> &Item) {
  193.   return Item.deserialize(Reader);
  194. }
  195.  
  196. inline Error consume(BinaryStreamReader &Reader,
  197.                      const serialize_null_term_string_array_impl &Item) {
  198.   return Item.deserialize(Reader);
  199. }
  200.  
  201. template <typename T>
  202. Error consume(BinaryStreamReader &Reader,
  203.               const serialize_vector_tail_impl<T> &Item) {
  204.   return Item.deserialize(Reader);
  205. }
  206.  
  207. template <typename T>
  208. Error consume(BinaryStreamReader &Reader,
  209.               const serialize_arrayref_tail_impl<T> &Item) {
  210.   return Item.deserialize(Reader);
  211. }
  212.  
  213. template <typename T>
  214. Error consume(BinaryStreamReader &Reader,
  215.               const serialize_numeric_impl<T> &Item) {
  216.   return Item.deserialize(Reader);
  217. }
  218.  
  219. template <typename T, typename U, typename... Args>
  220. Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
  221.   if (auto EC = consume(Reader, X))
  222.     return EC;
  223.   return consume(Reader, Y, std::forward<Args>(Rest)...);
  224. }
  225.  
  226. }
  227. }
  228.  
  229. #endif
  230.