Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/Utils/ASanStackFrameLayout.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ASanStackFrameLayout.cpp - helper for AddressSanitizer ------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// Definition of ComputeASanStackFrameLayout (see ASanStackFrameLayout.h).
11
//
12
//===----------------------------------------------------------------------===//
13
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
14
#include "llvm/ADT/SmallString.h"
15
#include "llvm/IR/DebugInfo.h"
16
#include "llvm/Support/MathExtras.h"
17
#include "llvm/Support/ScopedPrinter.h"
18
#include "llvm/Support/raw_ostream.h"
19
#include <algorithm>
20
21
namespace llvm {
22
23
// We sort the stack variables by alignment (largest first) to minimize
24
// unnecessary large gaps due to alignment.
25
// It is tempting to also sort variables by size so that larger variables
26
// have larger redzones at both ends. But reordering will make report analysis
27
// harder, especially when temporary unnamed variables are present.
28
// So, until we can provide more information (type, line number, etc)
29
// for the stack variables we avoid reordering them too much.
30
static inline bool CompareVars(const ASanStackVariableDescription &a,
31
60
                               const ASanStackVariableDescription &b) {
32
60
  return a.Alignment > b.Alignment;
33
60
}
34
35
// We also force minimal alignment for all vars to kMinAlignment so that vars
36
// with e.g. alignment 1 and alignment 16 do not get reordered by CompareVars.
37
static const size_t kMinAlignment = 16;
38
39
// The larger the variable Size the larger is the redzone.
40
// The resulting frame size is a multiple of Alignment.
41
150
static size_t VarAndRedzoneSize(size_t Size, size_t Alignment) {
42
150
  size_t Res = 0;
43
150
  if (
Size <= 4150
)
Res = 1668
;
44
82
  else 
if (82
Size <= 1682
)
Res = 3226
;
45
56
  else 
if (56
Size <= 12856
)
Res = Size + 3246
;
46
10
  else 
if (10
Size <= 51210
)
Res = Size + 642
;
47
8
  else 
if (8
Size <= 40968
)
Res = Size + 1288
;
48
0
  else                   Res = Size + 256;
49
150
  return alignTo(Res, Alignment);
50
150
}
51
52
ASanStackFrameLayout
53
ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars,
54
92
                            size_t Granularity, size_t MinHeaderSize) {
55
92
  assert(Granularity >= 8 && Granularity <= 64 &&
56
92
         (Granularity & (Granularity - 1)) == 0);
57
92
  assert(MinHeaderSize >= 16 && (MinHeaderSize & (MinHeaderSize - 1)) == 0 &&
58
92
         MinHeaderSize >= Granularity);
59
92
  const size_t NumVars = Vars.size();
60
92
  assert(NumVars > 0);
61
242
  for (size_t i = 0; 
i < NumVars242
;
i++150
)
62
150
    Vars[i].Alignment = std::max(Vars[i].Alignment, kMinAlignment);
63
92
64
92
  std::stable_sort(Vars.begin(), Vars.end(), CompareVars);
65
92
66
92
  ASanStackFrameLayout Layout;
67
92
  Layout.Granularity = Granularity;
68
92
  Layout.FrameAlignment = std::max(Granularity, Vars[0].Alignment);
69
92
  size_t Offset = std::max(std::max(MinHeaderSize, Granularity),
70
92
     Vars[0].Alignment);
71
92
  assert((Offset % Granularity) == 0);
72
242
  for (size_t i = 0; 
i < NumVars242
;
i++150
) {
73
150
    bool IsLast = i == NumVars - 1;
74
150
    size_t Alignment = std::max(Granularity, Vars[i].Alignment);
75
150
    (void)Alignment;  // Used only in asserts.
76
150
    size_t Size = Vars[i].Size;
77
150
    assert((Alignment & (Alignment - 1)) == 0);
78
150
    assert(Layout.FrameAlignment >= Alignment);
79
150
    assert((Offset % Alignment) == 0);
80
150
    assert(Size > 0);
81
92
    size_t NextAlignment = IsLast ? Granularity
82
58
                   : std::max(Granularity, Vars[i + 1].Alignment);
83
150
    size_t SizeWithRedzone = VarAndRedzoneSize(Size, NextAlignment);
84
150
    Vars[i].Offset = Offset;
85
150
    Offset += SizeWithRedzone;
86
150
  }
87
92
  if (
Offset % MinHeaderSize92
) {
88
44
    Offset += MinHeaderSize - (Offset % MinHeaderSize);
89
44
  }
90
92
  Layout.FrameSize = Offset;
91
92
  assert((Layout.FrameSize % MinHeaderSize) == 0);
92
92
  return Layout;
93
92
}
94
95
SmallString<64> ComputeASanStackFrameDescription(
96
92
    const SmallVectorImpl<ASanStackVariableDescription> &Vars) {
97
92
  SmallString<2048> StackDescriptionStorage;
98
92
  raw_svector_ostream StackDescription(StackDescriptionStorage);
99
92
  StackDescription << Vars.size();
100
92
101
150
  for (const auto &Var : Vars) {
102
150
    std::string Name = Var.Name;
103
150
    if (
Var.Line150
) {
104
11
      Name += ":";
105
11
      Name += to_string(Var.Line);
106
11
    }
107
150
    StackDescription << " " << Var.Offset << " " << Var.Size << " "
108
150
                     << Name.size() << " " << Name;
109
150
  }
110
92
  return StackDescription.str();
111
92
}
112
113
SmallVector<uint8_t, 64>
114
GetShadowBytes(const SmallVectorImpl<ASanStackVariableDescription> &Vars,
115
127
               const ASanStackFrameLayout &Layout) {
116
127
  assert(Vars.size() > 0);
117
127
  SmallVector<uint8_t, 64> SB;
118
127
  SB.clear();
119
127
  const size_t Granularity = Layout.Granularity;
120
127
  SB.resize(Vars[0].Offset / Granularity, kAsanStackLeftRedzoneMagic);
121
198
  for (const auto &Var : Vars) {
122
198
    SB.resize(Var.Offset / Granularity, kAsanStackMidRedzoneMagic);
123
198
124
198
    SB.resize(SB.size() + Var.Size / Granularity, 0);
125
198
    if (Var.Size % Granularity)
126
142
      SB.push_back(Var.Size % Granularity);
127
198
  }
128
127
  SB.resize(Layout.FrameSize / Granularity, kAsanStackRightRedzoneMagic);
129
127
  return SB;
130
127
}
131
132
SmallVector<uint8_t, 64> GetShadowBytesAfterScope(
133
    const SmallVectorImpl<ASanStackVariableDescription> &Vars,
134
92
    const ASanStackFrameLayout &Layout) {
135
92
  SmallVector<uint8_t, 64> SB = GetShadowBytes(Vars, Layout);
136
92
  const size_t Granularity = Layout.Granularity;
137
92
138
150
  for (const auto &Var : Vars) {
139
150
    assert(Var.LifetimeSize <= Var.Size);
140
150
    const size_t LifetimeShadowSize =
141
150
        (Var.LifetimeSize + Granularity - 1) / Granularity;
142
150
    const size_t Offset = Var.Offset / Granularity;
143
150
    std::fill(SB.begin() + Offset, SB.begin() + Offset + LifetimeShadowSize,
144
150
              kAsanStackUseAfterScopeMagic);
145
150
  }
146
92
147
92
  return SB;
148
92
}
149
150
} // llvm namespace