llvm.org GIT mirror llvm / 654fe49
[sancov] Put .SCOV* sections into the right comdat groups on COFF Avoids linker errors about relocations against discarded sections. This was uncovered during the Chromium clang roll here: https://chromium-review.googlesource.com/c/chromium/src/+/1321863#message-717516acfcf829176f6a2f50980f7a4bdd66469a After this change, Chromium's libGLESv2 links successfully for me. Reviewers: metzman, hans, morehouse Differential Revision: https://reviews.llvm.org/D54232 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346381 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 10 months ago
5 changed file(s) with 110 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
2323
2424 namespace llvm {
2525
26 class Triple;
2627 class FunctionPass;
2728 class ModulePass;
2829 class OptimizationRemarkEmitter;
4445 // Returns F.getComdat() if it exists.
4546 // Otherwise creates a new comdat, sets F's comdat, and returns it.
4647 // Returns nullptr on failure.
47 Comdat *GetOrCreateFunctionComdat(Function &F, const std::string &ModuleId);
48 Comdat *GetOrCreateFunctionComdat(Function &F, Triple &T,
49 const std::string &ModuleId);
4850
4951 // Insert GCOV profiling instrumentation
5052 struct GCOVOptions {
742742 appendToCompilerUsed(M, GV);
743743 // Put GV into the F's Comadat so that if F is deleted GV can be deleted too.
744744 if (&F != HwasanCtorFunction)
745 if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
745 if (auto Comdat =
746 GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
746747 GV->setComdat(Comdat);
747748 }
748749
1313
1414 #include "llvm/Transforms/Instrumentation.h"
1515 #include "llvm-c/Initialization.h"
16 #include "llvm/ADT/Triple.h"
1617 #include "llvm/IR/IntrinsicInst.h"
1718 #include "llvm/IR/Module.h"
1819 #include "llvm/InitializePasses.h"
6970 return GV;
7071 }
7172
72 Comdat *llvm::GetOrCreateFunctionComdat(Function &F,
73 Comdat *llvm::GetOrCreateFunctionComdat(Function &F, Triple &T,
7374 const std::string &ModuleId) {
7475 if (auto Comdat = F.getComdat()) return Comdat;
7576 assert(F.hasName());
7677 Module *M = F.getParent();
7778 std::string Name = F.getName();
78 if (F.hasLocalLinkage()) {
79
80 // Make a unique comdat name for internal linkage things on ELF. On COFF, the
81 // name of the comdat group identifies the leader symbol of the comdat group.
82 // The linkage of the leader symbol is considered during comdat resolution,
83 // and internal symbols with the same name from different objects will not be
84 // merged.
85 if (T.isOSBinFormatELF() && F.hasLocalLinkage()) {
7986 if (ModuleId.empty())
8087 return nullptr;
8188 Name += ModuleId;
8289 }
83 F.setComdat(M->getOrInsertComdat(Name));
84 return F.getComdat();
90
91 // Make a new comdat for the function. Use the "no duplicates" selection kind
92 // for non-weak symbols if the object file format supports it.
93 Comdat *C = M->getOrInsertComdat(Name);
94 if (T.isOSBinFormatCOFF() && !F.isWeakForLinker())
95 C->setSelectionKind(Comdat::NoDuplicates);
96 F.setComdat(C);
97 return C;
8598 }
8699
87100 /// initializeInstrumentation - Initialize all passes in the TransformUtils
576576 *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
577577 Constant::getNullValue(ArrayTy), "__sancov_gen_");
578578
579 if (TargetTriple.isOSBinFormatELF())
580 if (auto Comdat = GetOrCreateFunctionComdat(F, CurModuleUniqueId))
579 if (TargetTriple.supportsCOMDAT())
580 if (auto Comdat =
581 GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
581582 Array->setComdat(Comdat);
582583 Array->setSection(getSectionName(Section));
583584 Array->setAlignment(Ty->isPointerTy() ? DL->getPointerSize()
0 ; RUN: opt < %s -sancov -sanitizer-coverage-level=1 -sanitizer-coverage-inline-8bit-counters=1 -sanitizer-coverage-pc-table=1 -S | FileCheck %s
1
2 ; Make sure we use the right comdat groups for COFF to avoid relocations
3 ; against discarded sections. Internal linkage functions are also different from
4 ; ELF. We don't add a module unique identifier.
5
6 ; Test based on this source:
7 ; int baz(int);
8 ; static int __attribute__((noinline)) bar(int x) {
9 ; if (x)
10 ; return baz(x);
11 ; return 0;
12 ; }
13 ; int foo(int x) {
14 ; if (baz(0))
15 ; x = bar(x);
16 ; return x;
17 ; }
18
19 ; Both new comdats should no duplicates on COFF.
20
21 ; CHECK: $foo = comdat noduplicates
22 ; CHECK: $bar = comdat noduplicates
23
24 ; Tables for 'foo' should be in the 'foo' comdat.
25
26 ; CHECK: @__sancov_gen_{{.*}} = private global [1 x i8] zeroinitializer, section ".SCOV$CM", comdat($foo), align 1
27
28 ; CHECK: @__sancov_gen_{{.*}} = private constant [2 x i64*]
29 ; CHECK-SAME: [i64* bitcast (i32 (i32)* @foo to i64*), i64* inttoptr (i64 1 to i64*)],
30 ; CHECK-SAME: section ".SCOVP$M", comdat($foo), align 8
31
32 ; Tables for 'bar' should be in the 'bar' comdat.
33
34 ; CHECK: @__sancov_gen_{{.*}} = private global [1 x i8] zeroinitializer, section ".SCOV$CM", comdat($bar), align 1
35
36 ; CHECK: @__sancov_gen_{{.*}} = private constant [2 x i64*]
37 ; CHECK-SAME: [i64* bitcast (i32 (i32)* @bar to i64*), i64* inttoptr (i64 1 to i64*)],
38 ; CHECK-SAME: section ".SCOVP$M", comdat($bar), align 8
39
40 ; 'foo' and 'bar' should be in their new comdat groups.
41
42 ; CHECK: define dso_local i32 @foo(i32 %x){{.*}} comdat {
43 ; CHECK: define internal fastcc i32 @bar(i32 %x){{.*}} comdat {
44
45 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
46 target triple = "x86_64-pc-windows-msvc19.14.26433"
47
48 ; Function Attrs: nounwind uwtable
49 define dso_local i32 @foo(i32 %x) local_unnamed_addr #0 {
50 entry:
51 %call = tail call i32 @baz(i32 0) #3
52 %tobool = icmp eq i32 %call, 0
53 br i1 %tobool, label %if.end, label %if.then
54
55 if.then: ; preds = %entry
56 %call1 = tail call fastcc i32 @bar(i32 %x)
57 br label %if.end
58
59 if.end: ; preds = %entry, %if.then
60 %x.addr.0 = phi i32 [ %call1, %if.then ], [ %x, %entry ]
61 ret i32 %x.addr.0
62 }
63
64 declare dso_local i32 @baz(i32) local_unnamed_addr #1
65
66 ; Function Attrs: noinline nounwind uwtable
67 define internal fastcc i32 @bar(i32 %x) unnamed_addr #2 {
68 entry:
69 %tobool = icmp eq i32 %x, 0
70 br i1 %tobool, label %return, label %if.then
71
72 if.then: ; preds = %entry
73 %call = tail call i32 @baz(i32 %x) #3
74 br label %return
75
76 return: ; preds = %entry, %if.then
77 %retval.0 = phi i32 [ %call, %if.then ], [ 0, %entry ]
78 ret i32 %retval.0
79 }
80
81 attributes #0 = { nounwind uwtable }
82 attributes #1 = { "asdf" }
83 attributes #2 = { noinline nounwind uwtable }
84 attributes #3 = { nounwind }