Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //= OSLog.h - Analysis of calls to os_log builtins --*- 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. // This file defines APIs for determining the layout of the data buffer for
  10. // os_log() and os_trace().
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_AST_OSLOG_H
  15. #define LLVM_CLANG_AST_OSLOG_H
  16.  
  17. #include "clang/AST/ASTContext.h"
  18. #include "clang/AST/Expr.h"
  19.  
  20. namespace clang {
  21. namespace analyze_os_log {
  22.  
  23. /// An OSLogBufferItem represents a single item in the data written by a call
  24. /// to os_log() or os_trace().
  25. class OSLogBufferItem {
  26. public:
  27.   enum Kind {
  28.     // The item is a scalar (int, float, raw pointer, etc.). No further copying
  29.     // is required. This is the only kind allowed by os_trace().
  30.     ScalarKind = 0,
  31.  
  32.     // The item is a count, which describes the length of the following item to
  33.     // be copied. A count may only be followed by an item of kind StringKind,
  34.     // WideStringKind, or PointerKind.
  35.     CountKind,
  36.  
  37.     // The item is a pointer to a C string. If preceded by a count 'n',
  38.     // os_log() will copy at most 'n' bytes from the pointer.
  39.     StringKind,
  40.  
  41.     // The item is a pointer to a block of raw data. This item must be preceded
  42.     // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
  43.     PointerKind,
  44.  
  45.     // The item is a pointer to an Objective-C object. os_log() may retain the
  46.     // object for later processing.
  47.     ObjCObjKind,
  48.  
  49.     // The item is a pointer to wide-char string.
  50.     WideStringKind,
  51.  
  52.     // The item is corresponding to the '%m' format specifier, no value is
  53.     // populated in the buffer and the runtime is loading the errno value.
  54.     ErrnoKind,
  55.  
  56.     // The item is a mask type.
  57.     MaskKind
  58.   };
  59.  
  60.   enum {
  61.     // The item is marked "private" in the format string.
  62.     IsPrivate = 0x1,
  63.  
  64.     // The item is marked "public" in the format string.
  65.     IsPublic = 0x2,
  66.  
  67.     // The item is marked "sensitive" in the format string.
  68.     IsSensitive = 0x4 | IsPrivate
  69.   };
  70.  
  71. private:
  72.   Kind TheKind = ScalarKind;
  73.   const Expr *TheExpr = nullptr;
  74.   CharUnits ConstValue;
  75.   CharUnits Size; // size of the data, not including the header bytes
  76.   unsigned Flags = 0;
  77.   StringRef MaskType;
  78.  
  79. public:
  80.   OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
  81.                   StringRef maskType = StringRef())
  82.       : TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
  83.         MaskType(maskType) {
  84.     assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
  85.             (Flags == IsSensitive)) &&
  86.            "unexpected privacy flag");
  87.   }
  88.  
  89.   OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
  90.       : TheKind(CountKind), ConstValue(value),
  91.         Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
  92.  
  93.   unsigned char getDescriptorByte() const {
  94.     unsigned char result = Flags;
  95.     result |= ((unsigned)getKind()) << 4;
  96.     return result;
  97.   }
  98.  
  99.   unsigned char getSizeByte() const { return size().getQuantity(); }
  100.  
  101.   Kind getKind() const { return TheKind; }
  102.   bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
  103.  
  104.   const Expr *getExpr() const { return TheExpr; }
  105.   CharUnits getConstValue() const { return ConstValue; }
  106.   CharUnits size() const { return Size; }
  107.  
  108.   StringRef getMaskType() const { return MaskType; }
  109. };
  110.  
  111. class OSLogBufferLayout {
  112. public:
  113.   SmallVector<OSLogBufferItem, 4> Items;
  114.  
  115.   enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };
  116.  
  117.   CharUnits size() const {
  118.     CharUnits result;
  119.     result += CharUnits::fromQuantity(2); // summary byte, num-args byte
  120.     for (auto &item : Items) {
  121.       // descriptor byte, size byte
  122.       result += item.size() + CharUnits::fromQuantity(2);
  123.     }
  124.     return result;
  125.   }
  126.  
  127.   bool hasPrivateItems() const {
  128.     return llvm::any_of(
  129.         Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
  130.   }
  131.  
  132.   bool hasNonScalarOrMask() const {
  133.     return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
  134.       return Item.getKind() != OSLogBufferItem::ScalarKind ||
  135.              !Item.getMaskType().empty();
  136.     });
  137.   }
  138.  
  139.   unsigned char getSummaryByte() const {
  140.     unsigned char result = 0;
  141.     if (hasPrivateItems())
  142.       result |= HasPrivateItems;
  143.     if (hasNonScalarOrMask())
  144.       result |= HasNonScalarItems;
  145.     return result;
  146.   }
  147.  
  148.   unsigned char getNumArgsByte() const { return Items.size(); }
  149. };
  150.  
  151. // Given a call 'E' to one of the builtins __builtin_os_log_format() or
  152. // __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
  153. // the call will write into and store it in 'layout'. Returns 'false' if there
  154. // was some error encountered while computing the layout, and 'true' otherwise.
  155. bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,
  156.                               OSLogBufferLayout &layout);
  157.  
  158. } // namespace analyze_os_log
  159. } // namespace clang
  160. #endif
  161.