/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/X86/X86TargetObjectFile.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- X86TargetObjectFile.cpp - X86 Object Info -------------------------===// |
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 | | #include "X86TargetObjectFile.h" |
11 | | #include "llvm/ADT/StringExtras.h" |
12 | | #include "llvm/BinaryFormat/COFF.h" |
13 | | #include "llvm/BinaryFormat/Dwarf.h" |
14 | | #include "llvm/IR/Mangler.h" |
15 | | #include "llvm/IR/Operator.h" |
16 | | #include "llvm/MC/MCContext.h" |
17 | | #include "llvm/MC/MCExpr.h" |
18 | | #include "llvm/MC/MCSectionCOFF.h" |
19 | | #include "llvm/MC/MCSectionELF.h" |
20 | | #include "llvm/MC/MCValue.h" |
21 | | #include "llvm/Target/TargetLowering.h" |
22 | | |
23 | | using namespace llvm; |
24 | | using namespace dwarf; |
25 | | |
26 | | const MCExpr *X86_64MachoTargetObjectFile::getTTypeGlobalReference( |
27 | | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
28 | 11 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
29 | 11 | |
30 | 11 | // On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which |
31 | 11 | // is an indirect pc-relative reference. |
32 | 11 | if ((Encoding & DW_EH_PE_indirect) && 11 (Encoding & DW_EH_PE_pcrel)11 ) { |
33 | 11 | const MCSymbol *Sym = TM.getSymbol(GV); |
34 | 11 | const MCExpr *Res = |
35 | 11 | MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext()); |
36 | 11 | const MCExpr *Four = MCConstantExpr::create(4, getContext()); |
37 | 11 | return MCBinaryExpr::createAdd(Res, Four, getContext()); |
38 | 11 | } |
39 | 0 |
|
40 | 0 | return TargetLoweringObjectFileMachO::getTTypeGlobalReference( |
41 | 0 | GV, Encoding, TM, MMI, Streamer); |
42 | 0 | } |
43 | | |
44 | | MCSymbol *X86_64MachoTargetObjectFile::getCFIPersonalitySymbol( |
45 | | const GlobalValue *GV, const TargetMachine &TM, |
46 | 42 | MachineModuleInfo *MMI) const { |
47 | 42 | return TM.getSymbol(GV); |
48 | 42 | } |
49 | | |
50 | | const MCExpr *X86_64MachoTargetObjectFile::getIndirectSymViaGOTPCRel( |
51 | | const MCSymbol *Sym, const MCValue &MV, int64_t Offset, |
52 | 5 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
53 | 5 | // On Darwin/X86-64, we need to use foo@GOTPCREL+4 to access the got entry |
54 | 5 | // from a data section. In case there's an additional offset, then use |
55 | 5 | // foo@GOTPCREL+4+<offset>. |
56 | 5 | unsigned FinalOff = Offset+MV.getConstant()+4; |
57 | 5 | const MCExpr *Res = |
58 | 5 | MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext()); |
59 | 5 | const MCExpr *Off = MCConstantExpr::create(FinalOff, getContext()); |
60 | 5 | return MCBinaryExpr::createAdd(Res, Off, getContext()); |
61 | 5 | } |
62 | | |
63 | | const MCExpr *X86ELFTargetObjectFile::getDebugThreadLocalSymbol( |
64 | 5 | const MCSymbol *Sym) const { |
65 | 5 | return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext()); |
66 | 5 | } |
67 | | |
68 | | void |
69 | | X86FreeBSDTargetObjectFile::Initialize(MCContext &Ctx, |
70 | 25 | const TargetMachine &TM) { |
71 | 25 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
72 | 25 | InitializeELF(TM.Options.UseInitArray); |
73 | 25 | } |
74 | | |
75 | | void |
76 | | X86FuchsiaTargetObjectFile::Initialize(MCContext &Ctx, |
77 | 5 | const TargetMachine &TM) { |
78 | 5 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
79 | 5 | InitializeELF(TM.Options.UseInitArray); |
80 | 5 | } |
81 | | |
82 | | void |
83 | | X86LinuxNaClTargetObjectFile::Initialize(MCContext &Ctx, |
84 | 1.51k | const TargetMachine &TM) { |
85 | 1.51k | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
86 | 1.51k | InitializeELF(TM.Options.UseInitArray); |
87 | 1.51k | } |
88 | | |
89 | | void X86SolarisTargetObjectFile::Initialize(MCContext &Ctx, |
90 | 5 | const TargetMachine &TM) { |
91 | 5 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
92 | 5 | InitializeELF(TM.Options.UseInitArray); |
93 | 5 | } |
94 | | |
95 | | const MCExpr *X86WindowsTargetObjectFile::lowerRelativeReference( |
96 | | const GlobalValue *LHS, const GlobalValue *RHS, |
97 | 74 | const TargetMachine &TM) const { |
98 | 74 | // Our symbols should exist in address space zero, cowardly no-op if |
99 | 74 | // otherwise. |
100 | 74 | if (LHS->getType()->getPointerAddressSpace() != 0 || |
101 | 74 | RHS->getType()->getPointerAddressSpace() != 0) |
102 | 0 | return nullptr; |
103 | 74 | |
104 | 74 | // Both ptrtoint instructions must wrap global objects: |
105 | 74 | // - Only global variables are eligible for image relative relocations. |
106 | 74 | // - The subtrahend refers to the special symbol __ImageBase, a GlobalVariable. |
107 | 74 | // We expect __ImageBase to be a global variable without a section, externally |
108 | 74 | // defined. |
109 | 74 | // |
110 | 74 | // It should look something like this: @__ImageBase = external constant i8 |
111 | 74 | if (74 !isa<GlobalObject>(LHS) || 74 !isa<GlobalVariable>(RHS)74 || |
112 | 74 | LHS->isThreadLocal()74 || RHS->isThreadLocal()74 || |
113 | 74 | RHS->getName() != "__ImageBase"74 || !RHS->hasExternalLinkage()69 || |
114 | 74 | cast<GlobalVariable>(RHS)->hasInitializer()69 || RHS->hasSection()69 ) |
115 | 5 | return nullptr; |
116 | 69 | |
117 | 69 | return MCSymbolRefExpr::create(TM.getSymbol(LHS), |
118 | 69 | MCSymbolRefExpr::VK_COFF_IMGREL32, |
119 | 69 | getContext()); |
120 | 69 | } |
121 | | |
122 | 507 | static std::string APIntToHexString(const APInt &AI) { |
123 | 507 | unsigned Width = (AI.getBitWidth() / 8) * 2; |
124 | 507 | std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true); |
125 | 507 | unsigned Size = HexString.size(); |
126 | 507 | assert(Width >= Size && "hex string is too large!"); |
127 | 507 | HexString.insert(HexString.begin(), Width - Size, '0'); |
128 | 507 | |
129 | 507 | return HexString; |
130 | 507 | } |
131 | | |
132 | 564 | static std::string scalarConstantToHexString(const Constant *C) { |
133 | 564 | Type *Ty = C->getType(); |
134 | 564 | if (isa<UndefValue>(C)564 ) { |
135 | 6 | return APIntToHexString(APInt::getNullValue(Ty->getPrimitiveSizeInBits())); |
136 | 558 | } else if (const auto *558 CFP558 = dyn_cast<ConstantFP>(C)) { |
137 | 195 | return APIntToHexString(CFP->getValueAPF().bitcastToAPInt()); |
138 | 363 | } else if (const auto *363 CI363 = dyn_cast<ConstantInt>(C)) { |
139 | 306 | return APIntToHexString(CI->getValue()); |
140 | 0 | } else { |
141 | 57 | unsigned NumElements; |
142 | 57 | if (isa<VectorType>(Ty)) |
143 | 54 | NumElements = Ty->getVectorNumElements(); |
144 | 57 | else |
145 | 3 | NumElements = Ty->getArrayNumElements(); |
146 | 57 | std::string HexString; |
147 | 393 | for (int I = NumElements - 1, E = -1; I != E393 ; --I336 ) |
148 | 336 | HexString += scalarConstantToHexString(C->getAggregateElement(I)); |
149 | 558 | return HexString; |
150 | 558 | } |
151 | 0 | } |
152 | | |
153 | | MCSection *X86WindowsTargetObjectFile::getSectionForConstant( |
154 | | const DataLayout &DL, SectionKind Kind, const Constant *C, |
155 | 231 | unsigned &Align) const { |
156 | 231 | if (Kind.isMergeableConst() && 231 C228 ) { |
157 | 228 | const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | |
158 | 228 | COFF::IMAGE_SCN_MEM_READ | |
159 | 228 | COFF::IMAGE_SCN_LNK_COMDAT; |
160 | 228 | std::string COMDATSymName; |
161 | 228 | if (Kind.isMergeableConst4()228 ) { |
162 | 90 | if (Align <= 490 ) { |
163 | 90 | COMDATSymName = "__real@" + scalarConstantToHexString(C); |
164 | 90 | Align = 4; |
165 | 90 | } |
166 | 228 | } else if (138 Kind.isMergeableConst8()138 ) { |
167 | 84 | if (Align <= 884 ) { |
168 | 84 | COMDATSymName = "__real@" + scalarConstantToHexString(C); |
169 | 84 | Align = 8; |
170 | 84 | } |
171 | 138 | } else if (54 Kind.isMergeableConst16()54 ) { |
172 | 51 | if (Align <= 1651 ) { |
173 | 51 | COMDATSymName = "__xmm@" + scalarConstantToHexString(C); |
174 | 51 | Align = 16; |
175 | 51 | } |
176 | 54 | } else if (3 Kind.isMergeableConst32()3 ) { |
177 | 3 | if (Align <= 323 ) { |
178 | 3 | COMDATSymName = "__ymm@" + scalarConstantToHexString(C); |
179 | 3 | Align = 32; |
180 | 3 | } |
181 | 138 | } |
182 | 228 | |
183 | 228 | if (!COMDATSymName.empty()) |
184 | 228 | return getContext().getCOFFSection(".rdata", Characteristics, Kind, |
185 | 228 | COMDATSymName, |
186 | 228 | COFF::IMAGE_COMDAT_SELECT_ANY); |
187 | 3 | } |
188 | 3 | |
189 | 3 | return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align); |
190 | 3 | } |