llvm.org GIT mirror llvm / ae94e59
Re-did 60519. It turns out Darwin's handling of hidden visibility symbols are a bit more complicate than I expected. Both declarations and weak definitions still need a stub indirection. However, the stubs are in data section and they contain the addresses of the actual symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60571 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
12 changed file(s) with 204 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
829829 /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol
830830 /// even in non-static mode.
831831 static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) {
832 return RelocM != Reloc::Static &&
833 (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
834 (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()));
832 // If symbol visibility is hidden, the extra load is not needed if
833 // the symbol is definitely defined in the current translation unit.
834 bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
835 if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
836 return false;
837 return RelocM != Reloc::Static && (isDecl || GV->mayBeOverridden());
835838 }
836839
837840 SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
3131 #include "llvm/ADT/SmallPtrSet.h"
3232 #include "llvm/ADT/Statistic.h"
3333 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/ADT/StringSet.h"
3435 #include "llvm/Support/Compiler.h"
3536 #include "llvm/Support/Mangler.h"
3637 #include "llvm/Support/MathExtras.h"
7273
7374 /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
7475 /// non-lazy-pointers for indirect access.
75 std::set> GVNonLazyPtrs;
76 StringSet<> GVNonLazyPtrs;
77
78 /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
79 /// visibility that require non-lazy-pointers for indirect access.
80 StringSet<> HiddenGVNonLazyPtrs;
7681
7782 /// FnStubs - Keeps the set of external function GlobalAddresses that the
7883 /// asm printer should generate stubs for.
79 std::set> FnStubs;
84 StringSet<> FnStubs;
8085
8186 /// PCRelGVs - Keeps the set of GlobalValues used in pc relative
8287 /// constantpool.
140145 if (!GV)
141146 Name += ACPV->getSymbol();
142147 if (ACPV->isNonLazyPointer()) {
143 GVNonLazyPtrs.insert(Name);
148 if (GV->hasHiddenVisibility())
149 HiddenGVNonLazyPtrs.insert(Name);
150 else
151 GVNonLazyPtrs.insert(Name);
144152 printSuffixedName(Name, "$non_lazy_ptr");
145153 } else if (ACPV->isStub()) {
146154 FnStubs.insert(Name);
926934 SwitchToDataSection("");
927935
928936 // Output stubs for dynamically-linked functions
929 unsigned j = 1;
930 for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end();
931 i != e; ++i, ++j) {
937 for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
938 i != e; ++i) {
932939 if (TM.getRelocationModel() == Reloc::PIC_)
933940 SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
934941 "none,16", 0);
939946 EmitAlignment(2);
940947 O << "\t.code\t32\n";
941948
942 std::string p = *i;
949 const char *p = i->getKeyData();
943950 printSuffixedName(p, "$stub");
944951 O << ":\n";
945 O << "\t.indirect_symbol " << *i << "\n";
952 O << "\t.indirect_symbol " << p << "\n";
946953 O << "\tldr ip, ";
947954 printSuffixedName(p, "$slp");
948955 O << "\n";
965972 SwitchToDataSection(".lazy_symbol_pointer", 0);
966973 printSuffixedName(p, "$lazy_ptr");
967974 O << ":\n";
968 O << "\t.indirect_symbol " << *i << "\n";
975 O << "\t.indirect_symbol " << p << "\n";
969976 O << "\t.long\tdyld_stub_binding_helper\n";
970977 }
971978 O << "\n";
972979
973980 // Output non-lazy-pointers for external and common global variables.
974 if (!GVNonLazyPtrs.empty())
981 if (!GVNonLazyPtrs.empty()) {
975982 SwitchToDataSection(".non_lazy_symbol_pointer", 0);
976 for (std::set::iterator i = GVNonLazyPtrs.begin(),
977 e = GVNonLazyPtrs.end(); i != e; ++i) {
978 std::string p = *i;
979 printSuffixedName(p, "$non_lazy_ptr");
980 O << ":\n";
981 O << "\t.indirect_symbol " << *i << "\n";
982 O << "\t.long\t0\n";
983 }
983 for (StringSet<>::iterator i = GVNonLazyPtrs.begin(),
984 e = GVNonLazyPtrs.end(); i != e; ++i) {
985 const char *p = i->getKeyData();
986 printSuffixedName(p, "$non_lazy_ptr");
987 O << ":\n";
988 O << "\t.indirect_symbol " << p << "\n";
989 O << "\t.long\t0\n";
990 }
991 }
992
993 if (!HiddenGVNonLazyPtrs.empty()) {
994 SwitchToSection(TAI->getDataSection());
995 for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
996 e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
997 const char *p = i->getKeyData();
998 EmitAlignment(2);
999 printSuffixedName(p, "$non_lazy_ptr");
1000 O << ":\n";
1001 O << "\t.long " << p << "\n";
1002 }
1003 }
1004
9841005
9851006 // Emit initial debug information.
9861007 // FIXME: Dwarf support.
4242 #include "llvm/Target/TargetOptions.h"
4343 #include "llvm/ADT/Statistic.h"
4444 #include "llvm/ADT/StringExtras.h"
45 #include
45 #include "llvm/ADT/StringSet.h"
4646 using namespace llvm;
4747
4848 STATISTIC(EmittedInsts, "Number of machine instrs printed");
4949
5050 namespace {
5151 struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
52 std::set FnStubs, GVStubs;
52 StringSet<> FnStubs, GVStubs, HiddenGVStubs;
5353 const PPCSubtarget &Subtarget;
5454
5555 PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
386386
387387 // External or weakly linked global variables need non-lazily-resolved stubs
388388 if (TM.getRelocationModel() != Reloc::Static) {
389 if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
390 GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
391 GVStubs.insert(Name);
392 printSuffixedName(Name, "$non_lazy_ptr");
389 if (GV->isDeclaration() || GV->mayBeOverridden()) {
390 if (GV->hasHiddenVisibility()) {
391 if (!GV->isDeclaration() && !GV->hasCommonLinkage())
392 O << Name;
393 else {
394 HiddenGVStubs.insert(Name);
395 printSuffixedName(Name, "$non_lazy_ptr");
396 }
397 } else {
398 GVStubs.insert(Name);
399 printSuffixedName(Name, "$non_lazy_ptr");
400 }
393401 if (GV->hasExternalWeakLinkage())
394402 ExtWeakSymbols.insert(GV);
395403 return;
415423 void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
416424 std::string Name = getGlobalLinkName(GV);
417425 if (TM.getRelocationModel() != Reloc::Static) {
418 GVStubs.insert(Name);
426 if (GV->hasHiddenVisibility())
427 HiddenGVStubs.insert(Name);
428 else
429 GVStubs.insert(Name);
419430 printSuffixedName(Name, "$non_lazy_ptr");
420431 return;
421432 }
978989
979990 // Output stubs for dynamically-linked functions
980991 if (TM.getRelocationModel() == Reloc::PIC_) {
981 for (std::set>::iterator i = FnStubs.begin(), e = FnStubs.end();
992 for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
982993 i != e; ++i) {
983994 SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
984995 "pure_instructions,32");
985996 EmitAlignment(4);
986 std::string p = *i;
987 std::string L0p = (p[0]=='\"') ? "\"L0$" + p.substr(1) : "L0$" + p ;
997 const char *p = i->getKeyData();
998 bool hasQuote = p[0]=='\"';
988999 printSuffixedName(p, "$stub");
9891000 O << ":\n";
990 O << "\t.indirect_symbol " << *i << '\n';
1001 O << "\t.indirect_symbol " << p << '\n';
9911002 O << "\tmflr r0\n";
992 O << "\tbcl 20,31," << L0p << '\n';
993 O << L0p << ":\n";
1003 O << "\tbcl 20,31,";
1004 if (hasQuote)
1005 O << "\"L0$" << &p[1];
1006 else
1007 O << "L0$" << p;
1008 O << '\n';
1009 if (hasQuote)
1010 O << "\"L0$" << &p[1];
1011 else
1012 O << "L0$" << p;
1013 O << ":\n";
9941014 O << "\tmflr r11\n";
9951015 O << "\taddis r11,r11,ha16(";
9961016 printSuffixedName(p, "$lazy_ptr");
997 O << "-" << L0p << ")\n";
1017 O << "-";
1018 if (hasQuote)
1019 O << "\"L0$" << &p[1];
1020 else
1021 O << "L0$" << p;
1022 O << ")\n";
9981023 O << "\tmtlr r0\n";
9991024 if (isPPC64)
10001025 O << "\tldu r12,lo16(";
10011026 else
10021027 O << "\tlwzu r12,lo16(";
10031028 printSuffixedName(p, "$lazy_ptr");
1004 O << "-" << L0p << ")(r11)\n";
1029 O << "-";
1030 if (hasQuote)
1031 O << "\"L0$" << &p[1];
1032 else
1033 O << "L0$" << p;
1034 O << ")(r11)\n";
10051035 O << "\tmtctr r12\n";
10061036 O << "\tbctr\n";
10071037 SwitchToDataSection(".lazy_symbol_pointer");
10081038 printSuffixedName(p, "$lazy_ptr");
10091039 O << ":\n";
1010 O << "\t.indirect_symbol " << *i << '\n';
1040 O << "\t.indirect_symbol " << p << '\n';
10111041 if (isPPC64)
10121042 O << "\t.quad dyld_stub_binding_helper\n";
10131043 else
10141044 O << "\t.long dyld_stub_binding_helper\n";
10151045 }
10161046 } else {
1017 for (std::set>::iterator i = FnStubs.begin(), e = FnStubs.end();
1047 for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
10181048 i != e; ++i) {
10191049 SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
10201050 "pure_instructions,16");
10211051 EmitAlignment(4);
1022 std::string p = *i;
1052 const char *p = i->getKeyData();
10231053 printSuffixedName(p, "$stub");
10241054 O << ":\n";
1025 O << "\t.indirect_symbol " << *i << '\n';
1055 O << "\t.indirect_symbol " << p << '\n';
10261056 O << "\tlis r11,ha16(";
10271057 printSuffixedName(p, "$lazy_ptr");
10281058 O << ")\n";
10371067 SwitchToDataSection(".lazy_symbol_pointer");
10381068 printSuffixedName(p, "$lazy_ptr");
10391069 O << ":\n";
1040 O << "\t.indirect_symbol " << *i << '\n';
1070 O << "\t.indirect_symbol " << p << '\n';
10411071 if (isPPC64)
10421072 O << "\t.quad dyld_stub_binding_helper\n";
10431073 else
10601090 // Output stubs for external and common global variables.
10611091 if (!GVStubs.empty()) {
10621092 SwitchToDataSection(".non_lazy_symbol_pointer");
1063 for (std::set::iterator I = GVStubs.begin(),
1064 E = GVStubs.end(); I != E; ++I) {
1065 std::string p = *I;
1093 for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end();
1094 i != e; ++i) {
1095 std::string p = i->getKeyData();
10661096 printSuffixedName(p, "$non_lazy_ptr");
10671097 O << ":\n";
1068 O << "\t.indirect_symbol " << *I << '\n';
1098 O << "\t.indirect_symbol " << p << '\n';
10691099 if (isPPC64)
10701100 O << "\t.quad\t0\n";
10711101 else
10721102 O << "\t.long\t0\n";
10731103 }
10741104 }
1105
1106 if (!HiddenGVStubs.empty()) {
1107 SwitchToSection(TAI->getDataSection());
1108 for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
1109 i != e; ++i) {
1110 std::string p = i->getKeyData();
1111 EmitAlignment(isPPC64 ? 3 : 2);
1112 printSuffixedName(p, "$non_lazy_ptr");
1113 O << ":\n";
1114 if (isPPC64)
1115 O << "\t.quad\t";
1116 else
1117 O << "\t.long\t";
1118 O << p << '\n';
1119 }
1120 }
1121
10751122
10761123 // Emit initial debug information.
10771124 DW.EndModule();
140140 // We never hae stubs if HasLazyResolverStubs=false or if in static mode.
141141 if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static)
142142 return false;
143
143 // If symbol visibility is hidden, the extra load is not needed if
144 // the symbol is definitely defined in the current translation unit.
145 bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
146 if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
147 return false;
144148 return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
145 GV->hasCommonLinkage() ||
146 (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode());
149 GV->hasCommonLinkage() || isDecl;
147150 }
389389 } else {
390390 FnStubs.insert(Name);
391391 printSuffixedName(Name, "$stub");
392 }
393 } else if (GV->hasHiddenVisibility()) {
394 if (!GV->isDeclaration() && !GV->hasCommonLinkage())
395 // Definition is not definitely in the current translation unit.
396 O << Name;
397 else {
398 HiddenGVStubs.insert(Name);
399 printSuffixedName(Name, "$non_lazy_ptr");
392400 }
393401 } else {
394402 GVStubs.insert(Name);
874882 O << GV << "\n\t.long\t0\n";
875883 }
876884
885 /// printHiddenGVStub - Print stub for a hidden global value.
886 ///
887 void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) {
888 EmitAlignment(2);
889 printSuffixedName(GV, "$non_lazy_ptr", Prefix);
890 if (Prefix) O << Prefix;
891 O << ":\n" << TAI->getData32bitsDirective() << GV << '\n';
892 }
893
877894
878895 bool X86ATTAsmPrinter::doFinalization(Module &M) {
879896 // Print out module-level global variables here.
907924 SwitchToDataSection("");
908925
909926 // Output stubs for dynamically-linked functions
910 unsigned j = 1;
911927 for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
912 i != e; ++i, ++j) {
928 i != e; ++i) {
913929 SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
914930 "self_modifying_code+pure_instructions,5", 0);
915931 const char *p = i->getKeyData();
948964 i != e; ++i)
949965 printGVStub(i->getKeyData());
950966
967 if (!HiddenGVStubs.empty()) {
968 SwitchToSection(TAI->getDataSection());
969 for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
970 i != e; ++i)
971 printHiddenGVStub(i->getKeyData());
972 }
973
951974 // Emit final debug information.
952975 DW.EndModule();
953976
120120 void printModuleLevelGV(const GlobalVariable* GVar);
121121
122122 void printGVStub(const char *GV, const char *Prefix = NULL);
123 void printHiddenGVStub(const char *GV, const char *Prefix = NULL);
123124
124125 bool runOnMachineFunction(MachineFunction &F);
125126
126127 void emitFunctionHeader(const MachineFunction &MF);
127128
128129 // Necessary for Darwin to print out the apprioriate types of linker stubs
129 StringSet<> FnStubs, GVStubs, LinkOnceStubs;
130 StringSet<> FnStubs, GVStubs, HiddenGVStubs;
130131
131132 // Necessary for dllexport support
132133 StringSet<> DLLExportedFns, DLLExportedGVs;
3939 if (TM.getRelocationModel() != Reloc::Static &&
4040 TM.getCodeModel() != CodeModel::Large) {
4141 if (isTargetDarwin()) {
42 return (!isDirectCall &&
43 (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
44 GV->hasCommonLinkage() ||
45 (GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())));
42 bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
43 if (GV->hasHiddenVisibility() &&
44 (Is64Bit || (!isDecl && !GV->hasCommonLinkage())))
45 // If symbol visibility is hidden, the extra load is not needed if
46 // target is x86-64 or the symbol is definitely defined in the current
47 // translation unit.
48 return false;
49 return !isDirectCall && (isDecl || GV->mayBeOverridden());
4650 } else if (isTargetELF()) {
4751 // Extra load is needed for all externally visible.
4852 if (isDirectCall)
0 ; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | grep non_lazy_ptr | count 6
1
2 @x = external hidden global i32 ; [#uses=1]
3 @y = extern_weak hidden global i32 ; [#uses=1]
4
5 define i32 @t() nounwind readonly {
6 entry:
7 %0 = load i32* @x, align 4 ; [#uses=1]
8 %1 = load i32* @y, align 4 ; [#uses=1]
9 %2 = add i32 %1, %0 ; [#uses=1]
10 ret i32 %2
11 }
0 ; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | not grep non_lazy_ptr
1
2 @x = weak hidden global i32 0 ; [#uses=1]
3
4 define i32 @t() nounwind readonly {
5 entry:
6 %0 = load i32* @x, align 4 ; [#uses=1]
7 ret i32 %0
8 }
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1
11 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
2 ; XFAIL: *
32
43 @x = weak hidden global i32 0 ; [#uses=1]
54
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 3
1 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
2 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long | count 2
3 ; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
4
5 @x = external hidden global i32 ; [#uses=1]
6 @y = extern_weak hidden global i32 ; [#uses=1]
7
8 define i32 @t() nounwind readonly {
9 entry:
10 %0 = load i32* @x, align 4 ; [#uses=1]
11 %1 = load i32* @y, align 4 ; [#uses=1]
12 %2 = add i32 %1, %0 ; [#uses=1]
13 ret i32 %2
14 }
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
1 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long
2 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm
3
4 @x = common hidden global i32 0 ; [#uses=1]
5
6 define i32 @t() nounwind readonly {
7 entry:
8 %0 = load i32* @x, align 4 ; [#uses=1]
9 ret i32 %0
10 }