123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines APIs for determining the layout of the data buffer for
- // os_log() and os_trace().
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_OSLOG_H
- #define LLVM_CLANG_AST_OSLOG_H
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/Expr.h"
- namespace clang {
- namespace analyze_os_log {
- /// An OSLogBufferItem represents a single item in the data written by a call
- /// to os_log() or os_trace().
- class OSLogBufferItem {
- public:
- enum Kind {
- // The item is a scalar (int, float, raw pointer, etc.). No further copying
- // is required. This is the only kind allowed by os_trace().
- ScalarKind = 0,
- // The item is a count, which describes the length of the following item to
- // be copied. A count may only be followed by an item of kind StringKind,
- // WideStringKind, or PointerKind.
- CountKind,
- // The item is a pointer to a C string. If preceded by a count 'n',
- // os_log() will copy at most 'n' bytes from the pointer.
- StringKind,
- // The item is a pointer to a block of raw data. This item must be preceded
- // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
- PointerKind,
- // The item is a pointer to an Objective-C object. os_log() may retain the
- // object for later processing.
- ObjCObjKind,
- // The item is a pointer to wide-char string.
- WideStringKind,
- // The item is corresponding to the '%m' format specifier, no value is
- // populated in the buffer and the runtime is loading the errno value.
- ErrnoKind,
- // The item is a mask type.
- MaskKind
- };
- enum {
- // The item is marked "private" in the format string.
- IsPrivate = 0x1,
- // The item is marked "public" in the format string.
- IsPublic = 0x2,
- // The item is marked "sensitive" in the format string.
- IsSensitive = 0x4 | IsPrivate
- };
- private:
- Kind TheKind = ScalarKind;
- const Expr *TheExpr = nullptr;
- CharUnits ConstValue;
- CharUnits Size; // size of the data, not including the header bytes
- unsigned Flags = 0;
- StringRef MaskType;
- public:
- OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
- StringRef maskType = StringRef())
- : TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
- MaskType(maskType) {
- assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
- (Flags == IsSensitive)) &&
- "unexpected privacy flag");
- }
- OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
- : TheKind(CountKind), ConstValue(value),
- Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
- unsigned char getDescriptorByte() const {
- unsigned char result = Flags;
- result |= ((unsigned)getKind()) << 4;
- return result;
- }
- unsigned char getSizeByte() const { return size().getQuantity(); }
- Kind getKind() const { return TheKind; }
- bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
- const Expr *getExpr() const { return TheExpr; }
- CharUnits getConstValue() const { return ConstValue; }
- CharUnits size() const { return Size; }
- StringRef getMaskType() const { return MaskType; }
- };
- class OSLogBufferLayout {
- public:
- SmallVector<OSLogBufferItem, 4> Items;
- enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };
- CharUnits size() const {
- CharUnits result;
- result += CharUnits::fromQuantity(2); // summary byte, num-args byte
- for (auto &item : Items) {
- // descriptor byte, size byte
- result += item.size() + CharUnits::fromQuantity(2);
- }
- return result;
- }
- bool hasPrivateItems() const {
- return llvm::any_of(
- Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
- }
- bool hasNonScalarOrMask() const {
- return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
- return Item.getKind() != OSLogBufferItem::ScalarKind ||
- !Item.getMaskType().empty();
- });
- }
- unsigned char getSummaryByte() const {
- unsigned char result = 0;
- if (hasPrivateItems())
- result |= HasPrivateItems;
- if (hasNonScalarOrMask())
- result |= HasNonScalarItems;
- return result;
- }
- unsigned char getNumArgsByte() const { return Items.size(); }
- };
- // Given a call 'E' to one of the builtins __builtin_os_log_format() or
- // __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
- // the call will write into and store it in 'layout'. Returns 'false' if there
- // was some error encountered while computing the layout, and 'true' otherwise.
- bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,
- OSLogBufferLayout &layout);
- } // namespace analyze_os_log
- } // namespace clang
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|