[asan] Append line number to variable name if line is available and in the same file as the function.

PR30498

Reviewers: eugenis

Differential Revision: https://reviews.llvm.org/D25715

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284546 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vitaly Buka 2016-10-18 23:29:41 +00:00
parent f2a459b587
commit 298a3d2a9a
5 changed files with 93 additions and 40 deletions

View File

@ -38,6 +38,7 @@ struct ASanStackVariableDescription {
AllocaInst *AI; // The actual AllocaInst.
size_t Offset; // Offset from the beginning of the frame;
// set by ComputeASanStackFrameLayout.
unsigned Line; // Line number.
};
// Output data struct for ComputeASanStackFrameLayout.

View File

@ -2247,7 +2247,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
if (LocalEscapeCall) LocalEscapeCall->moveBefore(InsBefore);
// Find static allocas with lifetime analysis.
DenseMap<const AllocaInst *, const ASanStackVariableDescription *>
DenseMap<const AllocaInst *,
std::pair<const ASanStackVariableDescription *, unsigned>>
AllocaToSVDMap;
for (const auto &APC : StaticAllocaPoisonCallVec) {
assert(APC.InsBefore);
@ -2255,22 +2256,31 @@ void FunctionStackPoisoner::processStaticAllocas() {
assert(ASan.isInterestingAlloca(*APC.AI));
assert(APC.AI->isStaticAlloca());
AllocaToSVDMap[APC.AI] = nullptr;
auto &Pair = AllocaToSVDMap[APC.AI];
if (const DILocation *FnLoc = EntryDebugLocation.get()) {
if (const DILocation *LifetimeLoc = APC.InsBefore->getDebugLoc().get()) {
if (LifetimeLoc->getFile() == FnLoc->getFile())
if (unsigned Line = LifetimeLoc->getLine())
Pair.second = std::min(Pair.second ? Pair.second : Line, Line);
}
}
}
SmallVector<ASanStackVariableDescription, 16> SVD;
SVD.reserve(AllocaVec.size());
for (AllocaInst *AI : AllocaVec) {
size_t UseAfterScopePoisonSize =
AllocaToSVDMap.find(AI) != AllocaToSVDMap.end()
? ASan.getAllocaSizeInBytes(*AI)
: 0;
ASanStackVariableDescription D = {AI->getName().data(),
ASan.getAllocaSizeInBytes(*AI),
UseAfterScopePoisonSize,
0,
AI->getAlignment(),
AI,
0,
0};
auto It = AllocaToSVDMap.find(AI);
if (It != AllocaToSVDMap.end()) {
D.LifetimeSize = D.Size;
D.Line = It->second.second;
}
SVD.push_back(D);
}
// Minimal header size (left redzone) is 4 pointers,
@ -2386,7 +2396,7 @@ void FunctionStackPoisoner::processStaticAllocas() {
for (const auto &Desc : SVD) {
auto It = AllocaToSVDMap.find(Desc.AI);
if (It != AllocaToSVDMap.end()) {
It->second = &Desc;
It->second.first = &Desc;
}
}
@ -2395,8 +2405,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
// Poison static allocas near lifetime intrinsics.
for (const auto &APC : StaticAllocaPoisonCallVec) {
// Must be already set.
assert(AllocaToSVDMap[APC.AI]);
const auto &Desc = *AllocaToSVDMap[APC.AI];
assert(AllocaToSVDMap[APC.AI].first);
const auto &Desc = *AllocaToSVDMap[APC.AI].first;
assert(Desc.Offset % L.Granularity == 0);
size_t Begin = Desc.Offset / L.Granularity;
size_t End = Begin + (APC.Size + L.Granularity - 1) / L.Granularity;

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@ -75,13 +76,17 @@ ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars,
size_t Alignment = std::max(Granularity, Vars[i].Alignment);
(void)Alignment; // Used only in asserts.
size_t Size = Vars[i].Size;
const char *Name = Vars[i].Name;
std::string Name = Vars[i].Name;
assert((Alignment & (Alignment - 1)) == 0);
assert(Layout.FrameAlignment >= Alignment);
assert((Offset % Alignment) == 0);
assert(Size > 0);
assert(Vars[i].LifetimeSize <= Size);
StackDescription << " " << Offset << " " << Size << " " << strlen(Name)
if (Vars[i].Line) {
Name += ":";
Name += std::to_string(Vars[i].Line);
}
StackDescription << " " << Offset << " " << Size << " " << Name.size()
<< " " << Name;
size_t NextAlignment = IsLast ? Granularity
: std::max(Granularity, Vars[i + 1].Alignment);

View File

@ -1,18 +1,21 @@
; Test the ASan's stack layout.
; More tests in tests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca=0 -S \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-STATIC
; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca=1 -S \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DYNAMIC
; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca=0 -asan-use-after-scope -S \
; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-STATIC
; RUN: opt < %s -asan -asan-module -asan-stack-dynamic-alloca=1 -asan-use-after-scope -S \
; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-DYNAMIC
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @Use(i8*)
declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
; CHECK: private unnamed_addr constant{{.*}}3 32 10 3 XXX 64 20 3 YYY 128 30 3 ZZZ
; CHECK: private unnamed_addr constant{{.*}}3 32 5 3 AAA 64 55 3 BBB 160 555 3 CCC
; CHECK: private unnamed_addr constant{{.*}}3 256 128 3 CCC 448 128 3 BBB 608 128 3 AAA
; CHECK: private unnamed_addr constant{{.*}}3 32 10 3 XXX 64 20 3 YYY 128 30 3 ZZZ\0
; CHECK: private unnamed_addr constant{{.*}}3 32 5 3 AAA 64 55 3 BBB 160 555 3 CCC\0
; CHECK: private unnamed_addr constant{{.*}}3 256 128 3 CCC 448 128 3 BBB 608 128 3 AAA\0
; CHECK: private unnamed_addr constant{{.*}}2 32 4 3 AAA 48 4 5 BBB:7\0
define void @Func1() sanitize_address {
entry:
@ -77,3 +80,36 @@ entry:
store volatile i8 0, i8* %arr3.ptr
ret void
}
; Check that line numbers are attached to variable names if variable
; in the same file as a function.
define void @Func5() sanitize_address #0 !dbg !11 {
%AAA = alloca i32, align 4 ; File is not the same as !11
%BBB = alloca i32, align 4 ; File is the same as !11
%BBB.ptr = bitcast i32* %BBB to i8*
call void @llvm.lifetime.start(i64 4, i8* nonnull %BBB.ptr), !dbg !12
store volatile i32 5, i32* %BBB, align 4
%AAA.ptr = bitcast i32* %AAA to i8*
call void @llvm.lifetime.start(i64 4, i8* nonnull %AAA.ptr), !dbg !14
store volatile i32 3, i32* %AAA, align 4
call void @llvm.lifetime.end(i64 4, i8* nonnull %AAA.ptr), !dbg !17
call void @llvm.lifetime.end(i64 4, i8* nonnull %BBB.ptr), !dbg !18
ret void
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
!1 = !DIFile(filename: "../file1.c", directory: "/")
!11 = distinct !DISubprogram(name: "Func5", scope: !1, file: !1, line: 6, unit: !0)
!12 = !DILocation(line: 7, column: 3, scope: !11)
!18 = !DILocation(line: 10, column: 1, scope: !11)
!21 = !DIFile(filename: "../file2.c", directory: "/")
!6 = distinct !DISubprogram(name: "Func4", scope: !1, file: !21, line: 2, unit: !0)
!15 = distinct !DILocation(line: 8, column: 3, scope: !11)
!14 = !DILocation(line: 3, column: 3, scope: !6, inlinedAt: !15)
!17 = !DILocation(line: 4, column: 1, scope: !6, inlinedAt: !15)

View File

@ -37,40 +37,41 @@ ShadowBytesToString(ArrayRef<uint8_t> ShadowBytes) {
SmallVector<ASanStackVariableDescription, 10> Vars = V; \
ASanStackFrameLayout L = \
ComputeASanStackFrameLayout(Vars, Granularity, MinHeaderSize); \
EXPECT_EQ(ExpectedDescr, L.DescriptionString); \
EXPECT_STREQ(ExpectedDescr, L.DescriptionString.c_str()); \
EXPECT_EQ(ExpectedShadow, ShadowBytesToString(GetShadowBytes(Vars, L))); \
EXPECT_EQ(ExpectedShadowAfterScope, \
ShadowBytesToString(GetShadowBytesAfterScope(Vars, L))); \
}
TEST(ASanStackFrameLayout, Test) {
#define VAR(name, size, lifetime, alignment) \
#define VAR(name, size, lifetime, alignment, line) \
ASanStackVariableDescription name##size##_##alignment = { \
#name #size "_" #alignment, \
size, \
lifetime, \
alignment, \
0, \
0 \
0, \
line, \
}
VAR(a, 1, 0, 1);
VAR(p, 1, 0, 32);
VAR(p, 1, 0, 256);
VAR(a, 2, 0, 1);
VAR(a, 3, 0, 1);
VAR(a, 4, 0, 1);
VAR(a, 7, 0, 1);
VAR(a, 8, 8, 1);
VAR(a, 9, 0, 1);
VAR(a, 16, 16, 1);
VAR(a, 41, 9, 1);
VAR(a, 105, 103, 1);
VAR(a, 1, 0, 1, 0);
VAR(p, 1, 0, 32, 15);
VAR(p, 1, 0, 256, 2700);
VAR(a, 2, 0, 1, 0);
VAR(a, 3, 0, 1, 0);
VAR(a, 4, 0, 1, 0);
VAR(a, 7, 0, 1, 0);
VAR(a, 8, 8, 1, 0);
VAR(a, 9, 0, 1, 0);
VAR(a, 16, 16, 1, 0);
VAR(a, 41, 9, 1, 7);
VAR(a, 105, 103, 1, 0);
TEST_LAYOUT({a1_1}, 8, 16, "1 16 1 4 a1_1", "LL1R", "LL1R");
TEST_LAYOUT({a1_1}, 64, 64, "1 64 1 4 a1_1", "L1", "L1");
TEST_LAYOUT({p1_32}, 8, 32, "1 32 1 5 p1_32", "LLLL1RRR", "LLLL1RRR");
TEST_LAYOUT({p1_32}, 8, 64, "1 64 1 5 p1_32", "LLLLLLLL1RRRRRRR",
TEST_LAYOUT({p1_32}, 8, 32, "1 32 1 8 p1_32:15", "LLLL1RRR", "LLLL1RRR");
TEST_LAYOUT({p1_32}, 8, 64, "1 64 1 8 p1_32:15", "LLLLLLLL1RRRRRRR",
"LLLLLLLL1RRRRRRR");
TEST_LAYOUT({a1_1}, 8, 32, "1 32 1 4 a1_1", "LLLL1RRR", "LLLL1RRR");
@ -81,24 +82,24 @@ TEST(ASanStackFrameLayout, Test) {
TEST_LAYOUT({a8_1}, 8, 32, "1 32 8 4 a8_1", "LLLL0RRR", "LLLLSRRR");
TEST_LAYOUT({a9_1}, 8, 32, "1 32 9 4 a9_1", "LLLL01RR", "LLLL01RR");
TEST_LAYOUT({a16_1}, 8, 32, "1 32 16 5 a16_1", "LLLL00RR", "LLLLSSRR");
TEST_LAYOUT({p1_256}, 8, 32, "1 256 1 6 p1_256",
TEST_LAYOUT({p1_256}, 8, 32, "1 256 1 11 p1_256:2700",
"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL1RRR",
"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL1RRR");
TEST_LAYOUT({a41_1}, 8, 32, "1 32 41 5 a41_1", "LLLL000001RRRRRR",
TEST_LAYOUT({a41_1}, 8, 32, "1 32 41 7 a41_1:7", "LLLL000001RRRRRR",
"LLLLSS0001RRRRRR");
TEST_LAYOUT({a105_1}, 8, 32, "1 32 105 6 a105_1", "LLLL00000000000001RRRRRR",
"LLLLSSSSSSSSSSSSS1RRRRRR");
{
SmallVector<ASanStackVariableDescription, 10> t = {a1_1, p1_256};
TEST_LAYOUT(t, 8, 32, "2 256 1 6 p1_256 272 1 4 a1_1",
TEST_LAYOUT(t, 8, 32, "2 256 1 11 p1_256:2700 272 1 4 a1_1",
"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL1M1R",
"LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL1M1R");
}
{
SmallVector<ASanStackVariableDescription, 10> t = {a1_1, a16_1, a41_1};
TEST_LAYOUT(t, 8, 32, "3 32 1 4 a1_1 48 16 5 a16_1 80 41 5 a41_1",
TEST_LAYOUT(t, 8, 32, "3 32 1 4 a1_1 48 16 5 a16_1 80 41 7 a41_1:7",
"LLLL1M00MM000001RRRR", "LLLL1MSSMMSS0001RRRR");
}
#undef VAR