xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ASanStackFrameLayout.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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