File: | lib/MC/WinCOFFStreamer.cpp |
Location: | line 259, column 1 |
Description: | Potential leak of memory pointed to by 'Fragment' |
1 | //===-- llvm/MC/WinCOFFStreamer.cpp -----------------------------*- C++ -*-===// | |||
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 | // This file contains an implementation of a Windows COFF object file streamer. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "llvm/MC/MCAsmBackend.h" | |||
15 | #include "llvm/MC/MCAsmLayout.h" | |||
16 | #include "llvm/MC/MCAssembler.h" | |||
17 | #include "llvm/MC/MCCodeEmitter.h" | |||
18 | #include "llvm/MC/MCContext.h" | |||
19 | #include "llvm/MC/MCExpr.h" | |||
20 | #include "llvm/MC/MCObjectFileInfo.h" | |||
21 | #include "llvm/MC/MCObjectStreamer.h" | |||
22 | #include "llvm/MC/MCSection.h" | |||
23 | #include "llvm/MC/MCSectionCOFF.h" | |||
24 | #include "llvm/MC/MCStreamer.h" | |||
25 | #include "llvm/MC/MCSymbolCOFF.h" | |||
26 | #include "llvm/MC/MCValue.h" | |||
27 | #include "llvm/MC/MCWinCOFFStreamer.h" | |||
28 | #include "llvm/Support/COFF.h" | |||
29 | #include "llvm/Support/Debug.h" | |||
30 | #include "llvm/Support/ErrorHandling.h" | |||
31 | #include "llvm/Support/MathExtras.h" | |||
32 | #include "llvm/Support/TargetRegistry.h" | |||
33 | #include "llvm/Support/raw_ostream.h" | |||
34 | ||||
35 | using namespace llvm; | |||
36 | ||||
37 | #define DEBUG_TYPE"WinCOFFStreamer" "WinCOFFStreamer" | |||
38 | ||||
39 | namespace llvm { | |||
40 | MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, | |||
41 | MCCodeEmitter &CE, raw_pwrite_stream &OS) | |||
42 | : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {} | |||
43 | ||||
44 | void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst, | |||
45 | const MCSubtargetInfo &STI) { | |||
46 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
47 | ||||
48 | SmallVector<MCFixup, 4> Fixups; | |||
49 | SmallString<256> Code; | |||
50 | raw_svector_ostream VecOS(Code); | |||
51 | getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); | |||
52 | ||||
53 | // Add the fixups and data. | |||
54 | for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { | |||
55 | Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); | |||
56 | DF->getFixups().push_back(Fixups[i]); | |||
57 | } | |||
58 | ||||
59 | DF->getContents().append(Code.begin(), Code.end()); | |||
60 | } | |||
61 | ||||
62 | void MCWinCOFFStreamer::InitSections(bool NoExecStack) { | |||
63 | // FIXME: this is identical to the ELF one. | |||
64 | // This emulates the same behavior of GNU as. This makes it easier | |||
65 | // to compare the output as the major sections are in the same order. | |||
66 | SwitchSection(getContext().getObjectFileInfo()->getTextSection()); | |||
67 | EmitCodeAlignment(4); | |||
68 | ||||
69 | SwitchSection(getContext().getObjectFileInfo()->getDataSection()); | |||
70 | EmitCodeAlignment(4); | |||
71 | ||||
72 | SwitchSection(getContext().getObjectFileInfo()->getBSSSection()); | |||
73 | EmitCodeAlignment(4); | |||
74 | ||||
75 | SwitchSection(getContext().getObjectFileInfo()->getTextSection()); | |||
76 | } | |||
77 | ||||
78 | void MCWinCOFFStreamer::EmitLabel(MCSymbol *Symbol) { | |||
79 | assert(Symbol->isUndefined() && "Cannot define a symbol twice!")((Symbol->isUndefined() && "Cannot define a symbol twice!" ) ? static_cast<void> (0) : __assert_fail ("Symbol->isUndefined() && \"Cannot define a symbol twice!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 79, __PRETTY_FUNCTION__)); | |||
80 | MCObjectStreamer::EmitLabel(Symbol); | |||
81 | } | |||
82 | ||||
83 | void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { | |||
84 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 84); | |||
85 | } | |||
86 | ||||
87 | void MCWinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) { | |||
88 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 88); | |||
89 | } | |||
90 | ||||
91 | bool MCWinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, | |||
92 | MCSymbolAttr Attribute) { | |||
93 | assert(Symbol && "Symbol must be non-null!")((Symbol && "Symbol must be non-null!") ? static_cast <void> (0) : __assert_fail ("Symbol && \"Symbol must be non-null!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 93, __PRETTY_FUNCTION__)); | |||
94 | assert((!Symbol->isInSection() ||(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 96, __PRETTY_FUNCTION__)) | |||
95 | Symbol->getSection().getVariant() == MCSection::SV_COFF) &&(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 96, __PRETTY_FUNCTION__)) | |||
96 | "Got non-COFF section in the COFF backend!")(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 96, __PRETTY_FUNCTION__)); | |||
97 | ||||
98 | getAssembler().registerSymbol(*Symbol); | |||
99 | ||||
100 | switch (Attribute) { | |||
101 | default: return false; | |||
102 | case MCSA_WeakReference: | |||
103 | case MCSA_Weak: | |||
104 | cast<MCSymbolCOFF>(Symbol)->setIsWeakExternal(); | |||
105 | Symbol->setExternal(true); | |||
106 | break; | |||
107 | case MCSA_Global: | |||
108 | Symbol->setExternal(true); | |||
109 | break; | |||
110 | } | |||
111 | ||||
112 | return true; | |||
113 | } | |||
114 | ||||
115 | void MCWinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { | |||
116 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 116); | |||
117 | } | |||
118 | ||||
119 | void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) { | |||
120 | assert((!Symbol->isInSection() ||(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 122, __PRETTY_FUNCTION__)) | |||
121 | Symbol->getSection().getVariant() == MCSection::SV_COFF) &&(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 122, __PRETTY_FUNCTION__)) | |||
122 | "Got non-COFF section in the COFF backend!")(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 122, __PRETTY_FUNCTION__)); | |||
123 | ||||
124 | if (CurSymbol) | |||
125 | FatalError("starting a new symbol definition without completing the " | |||
126 | "previous one"); | |||
127 | CurSymbol = Symbol; | |||
128 | } | |||
129 | ||||
130 | void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { | |||
131 | if (!CurSymbol) | |||
132 | FatalError("storage class specified outside of symbol definition"); | |||
133 | ||||
134 | if (StorageClass & ~COFF::SSC_Invalid) | |||
135 | FatalError("storage class value '" + Twine(StorageClass) + | |||
136 | "' out of range"); | |||
137 | ||||
138 | getAssembler().registerSymbol(*CurSymbol); | |||
139 | cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass); | |||
140 | } | |||
141 | ||||
142 | void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { | |||
143 | if (!CurSymbol) | |||
144 | FatalError("symbol type specified outside of a symbol definition"); | |||
145 | ||||
146 | if (Type & ~0xffff) | |||
147 | FatalError("type value '" + Twine(Type) + "' out of range"); | |||
148 | ||||
149 | getAssembler().registerSymbol(*CurSymbol); | |||
150 | cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type); | |||
151 | } | |||
152 | ||||
153 | void MCWinCOFFStreamer::EndCOFFSymbolDef() { | |||
154 | if (!CurSymbol) | |||
155 | FatalError("ending symbol definition without starting one"); | |||
156 | CurSymbol = nullptr; | |||
157 | } | |||
158 | ||||
159 | void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { | |||
160 | // SafeSEH is a feature specific to 32-bit x86. It does not exist (and is | |||
161 | // unnecessary) on all platforms which use table-based exception dispatch. | |||
162 | if (getContext().getObjectFileInfo()->getTargetTriple().getArch() != | |||
163 | Triple::x86) | |||
164 | return; | |||
165 | ||||
166 | const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol); | |||
167 | if (CSymbol->isSafeSEH()) | |||
168 | return; | |||
169 | ||||
170 | MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection(); | |||
171 | getAssembler().registerSection(*SXData); | |||
172 | if (SXData->getAlignment() < 4) | |||
173 | SXData->setAlignment(4); | |||
174 | ||||
175 | new MCSafeSEHFragment(Symbol, SXData); | |||
176 | ||||
177 | getAssembler().registerSymbol(*Symbol); | |||
178 | CSymbol->setIsSafeSEH(); | |||
179 | ||||
180 | // The Microsoft linker requires that the symbol type of a handler be | |||
181 | // function. Go ahead and oblige it here. | |||
182 | CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION | |||
183 | << COFF::SCT_COMPLEX_TYPE_SHIFT); | |||
184 | } | |||
185 | ||||
186 | void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { | |||
187 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
188 | const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); | |||
189 | MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2); | |||
190 | DF->getFixups().push_back(Fixup); | |||
191 | DF->getContents().resize(DF->getContents().size() + 2, 0); | |||
192 | } | |||
193 | ||||
194 | void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { | |||
195 | MCDataFragment *DF = getOrCreateDataFragment(); | |||
196 | const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext()); | |||
197 | MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_4); | |||
198 | DF->getFixups().push_back(Fixup); | |||
199 | DF->getContents().resize(DF->getContents().size() + 4, 0); | |||
200 | } | |||
201 | ||||
202 | void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
203 | unsigned ByteAlignment) { | |||
204 | assert((!Symbol->isInSection() ||(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 206, __PRETTY_FUNCTION__)) | |||
205 | Symbol->getSection().getVariant() == MCSection::SV_COFF) &&(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 206, __PRETTY_FUNCTION__)) | |||
206 | "Got non-COFF section in the COFF backend!")(((!Symbol->isInSection() || Symbol->getSection().getVariant () == MCSection::SV_COFF) && "Got non-COFF section in the COFF backend!" ) ? static_cast<void> (0) : __assert_fail ("(!Symbol->isInSection() || Symbol->getSection().getVariant() == MCSection::SV_COFF) && \"Got non-COFF section in the COFF backend!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 206, __PRETTY_FUNCTION__)); | |||
207 | ||||
208 | const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); | |||
209 | if (T.isKnownWindowsMSVCEnvironment()) { | |||
210 | if (ByteAlignment > 32) | |||
211 | report_fatal_error("alignment is limited to 32-bytes"); | |||
212 | ||||
213 | // Round size up to alignment so that we will honor the alignment request. | |||
214 | Size = std::max(Size, static_cast<uint64_t>(ByteAlignment)); | |||
215 | } | |||
216 | ||||
217 | AssignSection(Symbol, nullptr); | |||
218 | ||||
219 | getAssembler().registerSymbol(*Symbol); | |||
220 | Symbol->setExternal(true); | |||
221 | Symbol->setCommon(Size, ByteAlignment); | |||
222 | ||||
223 | if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { | |||
224 | SmallString<128> Directive; | |||
225 | raw_svector_ostream OS(Directive); | |||
226 | const MCObjectFileInfo *MFI = getContext().getObjectFileInfo(); | |||
227 | ||||
228 | OS << " -aligncomm:\"" << Symbol->getName() << "\"," | |||
229 | << Log2_32_Ceil(ByteAlignment); | |||
230 | ||||
231 | PushSection(); | |||
232 | SwitchSection(MFI->getDrectveSection()); | |||
233 | EmitBytes(Directive); | |||
234 | PopSection(); | |||
235 | } | |||
236 | } | |||
237 | ||||
238 | void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, | |||
239 | unsigned ByteAlignment) { | |||
240 | assert(!Symbol->isInSection() && "Symbol must not already have a section!")((!Symbol->isInSection() && "Symbol must not already have a section!" ) ? static_cast<void> (0) : __assert_fail ("!Symbol->isInSection() && \"Symbol must not already have a section!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 240, __PRETTY_FUNCTION__)); | |||
241 | ||||
242 | MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); | |||
243 | getAssembler().registerSection(*Section); | |||
244 | if (Section->getAlignment() < ByteAlignment) | |||
| ||||
245 | Section->setAlignment(ByteAlignment); | |||
246 | ||||
247 | getAssembler().registerSymbol(*Symbol); | |||
248 | Symbol->setExternal(false); | |||
249 | ||||
250 | AssignSection(Symbol, Section); | |||
251 | ||||
252 | if (ByteAlignment != 1) | |||
253 | new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0, | |||
254 | ByteAlignment, Section); | |||
255 | ||||
256 | MCFillFragment *Fragment = new MCFillFragment( | |||
257 | /*Value=*/0, /*ValueSize=*/0, Size, Section); | |||
258 | Symbol->setFragment(Fragment); | |||
259 | } | |||
| ||||
260 | ||||
261 | void MCWinCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, | |||
262 | uint64_t Size, unsigned ByteAlignment) { | |||
263 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 263); | |||
264 | } | |||
265 | ||||
266 | void MCWinCOFFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, | |||
267 | uint64_t Size, unsigned ByteAlignment) { | |||
268 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 268); | |||
269 | } | |||
270 | ||||
271 | void MCWinCOFFStreamer::EmitFileDirective(StringRef Filename) { | |||
272 | getAssembler().addFileName(Filename); | |||
273 | } | |||
274 | ||||
275 | // TODO: Implement this if you want to emit .comment section in COFF obj files. | |||
276 | void MCWinCOFFStreamer::EmitIdent(StringRef IdentString) { | |||
277 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 277); | |||
278 | } | |||
279 | ||||
280 | void MCWinCOFFStreamer::EmitWinEHHandlerData() { | |||
281 | llvm_unreachable("not implemented")::llvm::llvm_unreachable_internal("not implemented", "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn246424/lib/MC/WinCOFFStreamer.cpp" , 281); | |||
282 | } | |||
283 | ||||
284 | void MCWinCOFFStreamer::FinishImpl() { | |||
285 | MCObjectStreamer::FinishImpl(); | |||
286 | } | |||
287 | ||||
288 | LLVM_ATTRIBUTE_NORETURN__attribute__((noreturn)) | |||
289 | void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { | |||
290 | getContext().reportFatalError(SMLoc(), Msg); | |||
291 | } | |||
292 | } | |||
293 |