llvm.org GIT mirror llvm / 7f80f1b
LTO: Pass SF_Executable flag through to InputFile::Symbol Summary: The linker needs to be able to determine whether a symbol is text or data to handle the case of a common being overridden by a strong definition in an archive. If the archive contains a text member of the same name as the common, that function is discarded. However, if the archive contains a data member of the same name, that strong definition overrides the common. This is a behavior of ld.bfd, which the Qualcomm linker also supports in LTO. Here's a test case to illustrate: #### cat > 1.c << \! int blah; ! cat > 2.c << \! int blah() { return 0; } ! cat > 3.c << \! int blah = 20; ! clang -c 1.c clang -c 2.c clang -c 3.c ar cr lib.a 2.o 3.o ld 1.o lib.a -t #### The correct output is: 1.o (lib.a)3.o Thanks to Shankar Easwaran and Hemant Kulkarni for the test case! Reviewers: mehdi_amini, rafael, pcc, davide Reviewed By: pcc Subscribers: davide, llvm-commits, inglorion Differential Revision: https://reviews.llvm.org/D31901 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300205 91177308-0d34-0410-b5e6-96231b3b80d8 Tobias Edler von Koch 3 years ago
5 changed file(s) with 24 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
125125 using irsymtab::Symbol::getCommonSize;
126126 using irsymtab::Symbol::getCommonAlignment;
127127 using irsymtab::Symbol::getCOFFWeakExternalFallback;
128 using irsymtab::Symbol::isExecutable;
128129 };
129130
130131 /// A range over the symbols in this InputFile.
9191 FB_global,
9292 FB_format_specific,
9393 FB_unnamed_addr,
94 FB_executable,
9495 };
9596
9697 /// The index into the Uncommon table, or -1 if this symbol does not have an
165166 bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
166167 bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
167168 bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
169 bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
168170
169171 uint64_t getCommonSize() const {
170172 assert(isCommon());
124124 Sym.Flags |= 1 << storage::Symbol::FB_global;
125125 if (Flags & object::BasicSymbolRef::SF_FormatSpecific)
126126 Sym.Flags |= 1 << storage::Symbol::FB_format_specific;
127 if (Flags & object::BasicSymbolRef::SF_Executable)
128 Sym.Flags |= 1 << storage::Symbol::FB_executable;
127129
128130 Sym.ComdatIndex = -1;
129131 auto *GV = Msym.dyn_cast();
1010 !0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}}
1111 !llvm.module.flags = !{ !0 }
1212
13 ; CHECK: H------ _g1
13 ; CHECK: D------X _fun
14 define i32 @fun() {
15 ret i32 0
16 }
17
18 ; CHECK: H------- _g1
1419 @g1 = hidden global i32 0
1520
16 ; CHECK: P------ _g2
21 ; CHECK: P------- _g2
1722 @g2 = protected global i32 0
1823
19 ; CHECK: D------ _g3
24 ; CHECK: D------- _g3
2025 @g3 = global i32 0
2126
22 ; CHECK: DU----- _g4
27 ; CHECK: DU------ _g4
2328 @g4 = external global i32
2429
25 ; CHECK: D--W--- _g5
30 ; CHECK: D--W---- _g5
2631 @g5 = weak global i32 0
2732
28 ; CHECK: D--W-O- _g6
33 ; CHECK: D--W-O-- _g6
2934 @g6 = linkonce_odr unnamed_addr global i32 0
3035
31 ; CHECK: D-----T _g7
36 ; CHECK: D-----T- _g7
3237 @g7 = thread_local global i32 0
3338
34 ; CHECK: D-C---- _g8
39 ; CHECK: D-C----- _g8
3540 ; CHECK-NEXT: size 4 align 8
3641 @g8 = common global i32 0, align 8
3742
38 ; CHECK: D------ _g9
43 ; CHECK: D------- _g9
3944 ; CHECK-NEXT: comdat g9
4045 $g9 = comdat any
4146 @g9 = global i32 0, comdat
4247
43 ; CHECK: D--WI-- _g10
48 ; CHECK: D--WI--- _g10
4449 ; CHECK-NEXT: comdat g9
4550 ; CHECK-NEXT: fallback _g9
4651 @g10 = weak alias i32, i32* @g9
316316 PrintBool('I', Sym.isIndirect());
317317 PrintBool('O', Sym.canBeOmittedFromSymbolTable());
318318 PrintBool('T', Sym.isTLS());
319 PrintBool('X', Sym.isExecutable());
319320 outs() << ' ' << Sym.getName() << '\n';
320321
321322 if (Sym.isCommon())
322 outs() << " size " << Sym.getCommonSize() << " align "
323 outs() << " size " << Sym.getCommonSize() << " align "
323324 << Sym.getCommonAlignment() << '\n';
324325
325326 int Comdat = Sym.getComdatIndex();
326327 if (Comdat != -1)
327 outs() << " comdat " << ComdatTable[Comdat] << '\n';
328 outs() << " comdat " << ComdatTable[Comdat] << '\n';
328329
329330 if (Sym.isWeak() && Sym.isIndirect())
330 outs() << " fallback " << Sym.getCOFFWeakExternalFallback() << '\n';
331 outs() << " fallback " << Sym.getCOFFWeakExternalFallback() << '\n';
331332 }
332333
333334 outs() << '\n';