LLVM  15.0.0git
ASanStackFrameLayout.cpp
Go to the documentation of this file.
1 //===-- ASanStackFrameLayout.cpp - helper for AddressSanitizer ------------===//
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 // Definition of ComputeASanStackFrameLayout (see ASanStackFrameLayout.h).
10 //
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/SmallString.h"
17 #include <algorithm>
18 
19 namespace llvm {
20 
21 // We sort the stack variables by alignment (largest first) to minimize
22 // unnecessary large gaps due to alignment.
23 // It is tempting to also sort variables by size so that larger variables
24 // have larger redzones at both ends. But reordering will make report analysis
25 // harder, especially when temporary unnamed variables are present.
26 // So, until we can provide more information (type, line number, etc)
27 // for the stack variables we avoid reordering them too much.
28 static inline bool CompareVars(const ASanStackVariableDescription &a,
30  return a.Alignment > b.Alignment;
31 }
32 
33 // We also force minimal alignment for all vars to kMinAlignment so that vars
34 // with e.g. alignment 1 and alignment 16 do not get reordered by CompareVars.
35 static const uint64_t kMinAlignment = 16;
36 
37 // We want to add a full redzone after every variable.
38 // The larger the variable Size the larger is the redzone.
39 // The resulting frame size is a multiple of Alignment.
40 static uint64_t VarAndRedzoneSize(uint64_t Size, uint64_t Granularity,
41  uint64_t Alignment) {
42  uint64_t Res = 0;
43  if (Size <= 4) Res = 16;
44  else if (Size <= 16) Res = 32;
45  else if (Size <= 128) Res = Size + 32;
46  else if (Size <= 512) Res = Size + 64;
47  else if (Size <= 4096) Res = Size + 128;
48  else Res = Size + 256;
49  return alignTo(std::max(Res, 2 * Granularity), Alignment);
50 }
51 
52 ASanStackFrameLayout
54  uint64_t Granularity, uint64_t MinHeaderSize) {
55  assert(Granularity >= 8 && Granularity <= 64 &&
56  (Granularity & (Granularity - 1)) == 0);
57  assert(MinHeaderSize >= 16 && (MinHeaderSize & (MinHeaderSize - 1)) == 0 &&
58  MinHeaderSize >= Granularity);
59  const size_t NumVars = Vars.size();
60  assert(NumVars > 0);
61  for (size_t i = 0; i < NumVars; i++)
62  Vars[i].Alignment = std::max(Vars[i].Alignment, kMinAlignment);
63 
65 
66  ASanStackFrameLayout Layout;
67  Layout.Granularity = Granularity;
68  Layout.FrameAlignment = std::max(Granularity, Vars[0].Alignment);
69  uint64_t Offset =
70  std::max(std::max(MinHeaderSize, Granularity), Vars[0].Alignment);
71  assert((Offset % Granularity) == 0);
72  for (size_t i = 0; i < NumVars; i++) {
73  bool IsLast = i == NumVars - 1;
74  uint64_t Alignment = std::max(Granularity, Vars[i].Alignment);
75  (void)Alignment; // Used only in asserts.
76  uint64_t Size = Vars[i].Size;
77  assert((Alignment & (Alignment - 1)) == 0);
78  assert(Layout.FrameAlignment >= Alignment);
79  assert((Offset % Alignment) == 0);
80  assert(Size > 0);
81  uint64_t NextAlignment =
82  IsLast ? Granularity : std::max(Granularity, Vars[i + 1].Alignment);
83  uint64_t SizeWithRedzone =
84  VarAndRedzoneSize(Size, Granularity, NextAlignment);
85  Vars[i].Offset = Offset;
86  Offset += SizeWithRedzone;
87  }
88  if (Offset % MinHeaderSize) {
89  Offset += MinHeaderSize - (Offset % MinHeaderSize);
90  }
91  Layout.FrameSize = Offset;
92  assert((Layout.FrameSize % MinHeaderSize) == 0);
93  return Layout;
94 }
95 
98  SmallString<2048> StackDescriptionStorage;
99  raw_svector_ostream StackDescription(StackDescriptionStorage);
100  StackDescription << Vars.size();
101 
102  for (const auto &Var : Vars) {
103  std::string Name = Var.Name;
104  if (Var.Line) {
105  Name += ":";
106  Name += to_string(Var.Line);
107  }
108  StackDescription << " " << Var.Offset << " " << Var.Size << " "
109  << Name.size() << " " << Name;
110  }
111  return StackDescription.str();
112 }
113 
114 SmallVector<uint8_t, 64>
116  const ASanStackFrameLayout &Layout) {
117  assert(Vars.size() > 0);
119  SB.clear();
120  const uint64_t Granularity = Layout.Granularity;
121  SB.resize(Vars[0].Offset / Granularity, kAsanStackLeftRedzoneMagic);
122  for (const auto &Var : Vars) {
123  SB.resize(Var.Offset / Granularity, kAsanStackMidRedzoneMagic);
124 
125  SB.resize(SB.size() + Var.Size / Granularity, 0);
126  if (Var.Size % Granularity)
127  SB.push_back(Var.Size % Granularity);
128  }
129  SB.resize(Layout.FrameSize / Granularity, kAsanStackRightRedzoneMagic);
130  return SB;
131 }
132 
135  const ASanStackFrameLayout &Layout) {
136  SmallVector<uint8_t, 64> SB = GetShadowBytes(Vars, Layout);
137  const uint64_t Granularity = Layout.Granularity;
138 
139  for (const auto &Var : Vars) {
140  assert(Var.LifetimeSize <= Var.Size);
141  const uint64_t LifetimeShadowSize =
142  (Var.LifetimeSize + Granularity - 1) / Granularity;
143  const uint64_t Offset = Var.Offset / Granularity;
144  std::fill(SB.begin() + Offset, SB.begin() + Offset + LifetimeShadowSize,
146  }
147 
148  return SB;
149 }
150 
151 } // llvm namespace
i
i
Definition: README.txt:29
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::VarAndRedzoneSize
static uint64_t VarAndRedzoneSize(uint64_t Size, uint64_t Granularity, uint64_t Alignment)
Definition: ASanStackFrameLayout.cpp:40
llvm::GetShadowBytesAfterScope
SmallVector< uint8_t, 64 > GetShadowBytesAfterScope(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
Definition: ASanStackFrameLayout.cpp:133
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::GetShadowBytes
SmallVector< uint8_t, 64 > GetShadowBytes(const SmallVectorImpl< ASanStackVariableDescription > &Vars, const ASanStackFrameLayout &Layout)
Definition: ASanStackFrameLayout.cpp:115
llvm::kMinAlignment
static const uint64_t kMinAlignment
Definition: ASanStackFrameLayout.cpp:35
llvm::ASanStackFrameLayout::Granularity
uint64_t Granularity
Definition: ASanStackFrameLayout.h:45
ASanStackFrameLayout.h
a
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
Definition: README.txt:489
SmallString.h
b
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
Definition: README.txt:418
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition: SmallVector.h:619
llvm::SmallString< 64 >
llvm::CompareVars
static bool CompareVars(const ASanStackVariableDescription &a, const ASanStackVariableDescription &b)
Definition: ASanStackFrameLayout.cpp:28
uint64_t
llvm::kAsanStackUseAfterScopeMagic
static const int kAsanStackUseAfterScopeMagic
Definition: ASanStackFrameLayout.h:27
llvm::kAsanStackLeftRedzoneMagic
static const int kAsanStackLeftRedzoneMagic
Definition: ASanStackFrameLayout.h:23
llvm::ASanStackFrameLayout::FrameSize
uint64_t FrameSize
Definition: ASanStackFrameLayout.h:47
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ASanStackVariableDescription
Definition: ASanStackFrameLayout.h:30
llvm::ASanStackFrameLayout::FrameAlignment
uint64_t FrameAlignment
Definition: ASanStackFrameLayout.h:46
llvm::raw_svector_ostream::str
StringRef str() const
Return a StringRef for the vector contents.
Definition: raw_ostream.h:687
llvm::stable_sort
void stable_sort(R &&Range)
Definition: STLExtras.h:1749
llvm::kAsanStackRightRedzoneMagic
static const int kAsanStackRightRedzoneMagic
Definition: ASanStackFrameLayout.h:25
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:591
llvm::ComputeASanStackFrameDescription
SmallString< 64 > ComputeASanStackFrameDescription(const SmallVectorImpl< ASanStackVariableDescription > &Vars)
Definition: ASanStackFrameLayout.cpp:96
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:86
llvm::kAsanStackMidRedzoneMagic
static const int kAsanStackMidRedzoneMagic
Definition: ASanStackFrameLayout.h:24
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:662
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::ComputeASanStackFrameLayout
ASanStackFrameLayout ComputeASanStackFrameLayout(SmallVectorImpl< ASanStackVariableDescription > &Vars, uint64_t Granularity, uint64_t MinHeaderSize)
Definition: ASanStackFrameLayout.cpp:53
raw_ostream.h
llvm::ASanStackFrameLayout
Definition: ASanStackFrameLayout.h:44
ScopedPrinter.h