10b57cec5SDimitry Andric //===- ASanStackFrameLayout.h - ComputeASanStackFrameLayout -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This header defines ComputeASanStackFrameLayout and auxiliary data structs. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric #ifndef LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H 130b57cec5SDimitry Andric #define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H 140b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric namespace llvm { 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric class AllocaInst; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric // These magic constants should be the same as in 220b57cec5SDimitry Andric // in asan_internal.h from ASan runtime in compiler-rt. 230b57cec5SDimitry Andric static const int kAsanStackLeftRedzoneMagic = 0xf1; 240b57cec5SDimitry Andric static const int kAsanStackMidRedzoneMagic = 0xf2; 250b57cec5SDimitry Andric static const int kAsanStackRightRedzoneMagic = 0xf3; 260b57cec5SDimitry Andric static const int kAsanStackUseAfterReturnMagic = 0xf5; 270b57cec5SDimitry Andric static const int kAsanStackUseAfterScopeMagic = 0xf8; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric // Input/output data struct for ComputeASanStackFrameLayout. 300b57cec5SDimitry Andric struct ASanStackVariableDescription { 310b57cec5SDimitry Andric const char *Name; // Name of the variable that will be displayed by asan 320b57cec5SDimitry Andric // if a stack-related bug is reported. 330b57cec5SDimitry Andric uint64_t Size; // Size of the variable in bytes. 340b57cec5SDimitry Andric size_t LifetimeSize; // Size in bytes to use for lifetime analysis check. 350b57cec5SDimitry Andric // Will be rounded up to Granularity. 36*349cc55cSDimitry Andric uint64_t Alignment; // Alignment of the variable (power of 2). 370b57cec5SDimitry Andric AllocaInst *AI; // The actual AllocaInst. 380b57cec5SDimitry Andric size_t Offset; // Offset from the beginning of the frame; 390b57cec5SDimitry Andric // set by ComputeASanStackFrameLayout. 400b57cec5SDimitry Andric unsigned Line; // Line number. 410b57cec5SDimitry Andric }; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Output data struct for ComputeASanStackFrameLayout. 440b57cec5SDimitry Andric struct ASanStackFrameLayout { 45*349cc55cSDimitry Andric uint64_t Granularity; // Shadow granularity. 46*349cc55cSDimitry Andric uint64_t FrameAlignment; // Alignment for the entire frame. 47*349cc55cSDimitry Andric uint64_t FrameSize; // Size of the frame in bytes. 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric ASanStackFrameLayout ComputeASanStackFrameLayout( 510b57cec5SDimitry Andric // The array of stack variables. The elements may get reordered and changed. 520b57cec5SDimitry Andric SmallVectorImpl<ASanStackVariableDescription> &Vars, 530b57cec5SDimitry Andric // AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64. 54*349cc55cSDimitry Andric uint64_t Granularity, 550b57cec5SDimitry Andric // The minimal size of the left-most redzone (header). 560b57cec5SDimitry Andric // At least 4 pointer sizes, power of 2, and >= Granularity. 570b57cec5SDimitry Andric // The resulting FrameSize should be multiple of MinHeaderSize. 58*349cc55cSDimitry Andric uint64_t MinHeaderSize); 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // Compute frame description, see DescribeAddressIfStack in ASan runtime. 610b57cec5SDimitry Andric SmallString<64> ComputeASanStackFrameDescription( 620b57cec5SDimitry Andric const SmallVectorImpl<ASanStackVariableDescription> &Vars); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric // Returns shadow bytes with marked red zones. This shadow represents the state 650b57cec5SDimitry Andric // if the stack frame when all local variables are inside of the own scope. 660b57cec5SDimitry Andric SmallVector<uint8_t, 64> 670b57cec5SDimitry Andric GetShadowBytes(const SmallVectorImpl<ASanStackVariableDescription> &Vars, 680b57cec5SDimitry Andric const ASanStackFrameLayout &Layout); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // Returns shadow bytes with marked red zones and after scope. This shadow 710b57cec5SDimitry Andric // represents the state if the stack frame when all local variables are outside 720b57cec5SDimitry Andric // of the own scope. 730b57cec5SDimitry Andric SmallVector<uint8_t, 64> GetShadowBytesAfterScope( 740b57cec5SDimitry Andric // The array of stack variables. The elements may get reordered and changed. 750b57cec5SDimitry Andric const SmallVectorImpl<ASanStackVariableDescription> &Vars, 760b57cec5SDimitry Andric const ASanStackFrameLayout &Layout); 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric } // llvm namespace 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric #endif // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H 81