LLVM  10.0.0svn
MCWinCOFFStreamer.cpp
Go to the documentation of this file.
1 //===- llvm/MC/MCWinCOFFStreamer.cpp --------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains an implementation of a Windows COFF object file streamer.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/BinaryFormat/COFF.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixup.h"
24 #include "llvm/MC/MCFragment.h"
27 #include "llvm/MC/MCObjectWriter.h"
28 #include "llvm/MC/MCSection.h"
29 #include "llvm/MC/MCSymbolCOFF.h"
31 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/SMLoc.h"
36 #include <algorithm>
37 #include <cassert>
38 #include <cstdint>
39 
40 using namespace llvm;
41 
42 #define DEBUG_TYPE "WinCOFFStreamer"
43 
45  std::unique_ptr<MCAsmBackend> MAB,
46  std::unique_ptr<MCCodeEmitter> CE,
47  std::unique_ptr<MCObjectWriter> OW)
48  : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(CE)),
49  CurSymbol(nullptr) {}
50 
52  const MCSubtargetInfo &STI) {
54 
56  SmallString<256> Code;
57  raw_svector_ostream VecOS(Code);
58  getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
59 
60  // Add the fixups and data.
61  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
62  Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
63  DF->getFixups().push_back(Fixups[i]);
64  }
65  DF->setHasInstructions(STI);
66  DF->getContents().append(Code.begin(), Code.end());
67 }
68 
69 void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
70  // FIXME: this is identical to the ELF one.
71  // This emulates the same behavior of GNU as. This makes it easier
72  // to compare the output as the major sections are in the same order.
73  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
75 
76  SwitchSection(getContext().getObjectFileInfo()->getDataSection());
78 
79  SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
81 
82  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
83 }
84 
86  auto *Symbol = cast<MCSymbolCOFF>(S);
88 }
89 
91  // Let the target do whatever target specific stuff it needs to do.
93 
94  switch (Flag) {
95  // None of these require COFF specific handling.
96  case MCAF_SyntaxUnified:
97  case MCAF_Code16:
98  case MCAF_Code32:
99  case MCAF_Code64:
100  break;
102  llvm_unreachable("COFF doesn't support .subsections_via_symbols");
103  }
104 }
105 
107  llvm_unreachable("not implemented");
108 }
109 
112  auto *Symbol = cast<MCSymbolCOFF>(S);
114 
115  switch (Attribute) {
116  default: return false;
117  case MCSA_WeakReference:
118  case MCSA_Weak:
119  Symbol->setIsWeakExternal();
120  Symbol->setExternal(true);
121  break;
122  case MCSA_Global:
123  Symbol->setExternal(true);
124  break;
125  case MCSA_AltEntry:
126  llvm_unreachable("COFF doesn't support the .alt_entry attribute");
127  }
128 
129  return true;
130 }
131 
133  llvm_unreachable("not implemented");
134 }
135 
137  auto *Symbol = cast<MCSymbolCOFF>(S);
138  if (CurSymbol)
139  Error("starting a new symbol definition without completing the "
140  "previous one");
141  CurSymbol = Symbol;
142 }
143 
145  if (!CurSymbol) {
146  Error("storage class specified outside of symbol definition");
147  return;
148  }
149 
150  if (StorageClass & ~COFF::SSC_Invalid) {
151  Error("storage class value '" + Twine(StorageClass) +
152  "' out of range");
153  return;
154  }
155 
157  cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
158 }
159 
161  if (!CurSymbol) {
162  Error("symbol type specified outside of a symbol definition");
163  return;
164  }
165 
166  if (Type & ~0xffff) {
167  Error("type value '" + Twine(Type) + "' out of range");
168  return;
169  }
170 
172  cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
173 }
174 
176  if (!CurSymbol)
177  Error("ending symbol definition without starting one");
178  CurSymbol = nullptr;
179 }
180 
182  // SafeSEH is a feature specific to 32-bit x86. It does not exist (and is
183  // unnecessary) on all platforms which use table-based exception dispatch.
184  if (getContext().getObjectFileInfo()->getTargetTriple().getArch() !=
185  Triple::x86)
186  return;
187 
188  const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
189  if (CSymbol->isSafeSEH())
190  return;
191 
193  getAssembler().registerSection(*SXData);
194  if (SXData->getAlignment() < 4)
195  SXData->setAlignment(llvm::Align(4));
196 
197  new MCSymbolIdFragment(Symbol, SXData);
198 
199  getAssembler().registerSymbol(*Symbol);
200  CSymbol->setIsSafeSEH();
201 
202  // The Microsoft linker requires that the symbol type of a handler be
203  // function. Go ahead and oblige it here.
206 }
207 
211  if (Sec->getAlignment() < 4)
212  Sec->setAlignment(llvm::Align(4));
213 
215 
216  getAssembler().registerSymbol(*Symbol);
217 }
218 
220  visitUsedSymbol(*Symbol);
222  const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
224  DF->getFixups().push_back(Fixup);
225  DF->getContents().resize(DF->getContents().size() + 2, 0);
226 }
227 
229  uint64_t Offset) {
230  visitUsedSymbol(*Symbol);
232  // Create Symbol A for the relocation relative reference.
233  const MCExpr *MCE = MCSymbolRefExpr::create(Symbol, getContext());
234  // Add the constant offset, if given.
235  if (Offset)
237  MCE, MCConstantExpr::create(Offset, getContext()), getContext());
238  // Build the secrel32 relocation.
240  // Record the relocation.
241  DF->getFixups().push_back(Fixup);
242  // Emit 4 bytes (zeros) to the object file.
243  DF->getContents().resize(DF->getContents().size() + 4, 0);
244 }
245 
247  int64_t Offset) {
248  visitUsedSymbol(*Symbol);
250  // Create Symbol A for the relocation relative reference.
251  const MCExpr *MCE = MCSymbolRefExpr::create(
253  // Add the constant offset, if given.
254  if (Offset)
256  MCE, MCConstantExpr::create(Offset, getContext()), getContext());
257  // Build the imgrel relocation.
259  // Record the relocation.
260  DF->getFixups().push_back(Fixup);
261  // Emit 4 bytes (zeros) to the object file.
262  DF->getContents().resize(DF->getContents().size() + 4, 0);
263 }
264 
266  unsigned ByteAlignment) {
267  auto *Symbol = cast<MCSymbolCOFF>(S);
268 
270  if (T.isWindowsMSVCEnvironment()) {
271  if (ByteAlignment > 32)
272  report_fatal_error("alignment is limited to 32-bytes");
273 
274  // Round size up to alignment so that we will honor the alignment request.
275  Size = std::max(Size, static_cast<uint64_t>(ByteAlignment));
276  }
277 
279  Symbol->setExternal(true);
280  Symbol->setCommon(Size, ByteAlignment);
281 
282  if (!T.isWindowsMSVCEnvironment() && ByteAlignment > 1) {
283  SmallString<128> Directive;
284  raw_svector_ostream OS(Directive);
286 
287  OS << " -aligncomm:\"" << Symbol->getName() << "\","
288  << Log2_32_Ceil(ByteAlignment);
289 
290  PushSection();
292  EmitBytes(Directive);
293  PopSection();
294  }
295 }
296 
298  unsigned ByteAlignment) {
299  auto *Symbol = cast<MCSymbolCOFF>(S);
300 
302  PushSection();
303  SwitchSection(Section);
304  EmitValueToAlignment(ByteAlignment, 0, 1, 0);
305  EmitLabel(Symbol);
306  Symbol->setExternal(false);
307  EmitZeros(Size);
308  PopSection();
309 }
310 
312  uint64_t Size, unsigned ByteAlignment,
313  SMLoc Loc) {
314  llvm_unreachable("not implemented");
315 }
316 
318  uint64_t Size, unsigned ByteAlignment) {
319  llvm_unreachable("not implemented");
320 }
321 
322 // TODO: Implement this if you want to emit .comment section in COFF obj files.
324  llvm_unreachable("not implemented");
325 }
326 
328  llvm_unreachable("not implemented");
329 }
330 
333 }
334 
335 void MCWinCOFFStreamer::Error(const Twine &Msg) const {
336  getContext().reportError(SMLoc(), Msg);
337 }
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition: MathExtras.h:551
void EmitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void FinishImpl() override
Streamer specific finalization.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LLVMContext & Context
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:327
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCWinCOFFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCCodeEmitter > CE, std::unique_ptr< MCObjectWriter > OW)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
const MCSymbol * CurSymbol
void InitSections(bool NoExecStack) override
Create the default sections and set the initial one.
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:530
void registerSymbol(const MCSymbol &Symbol, bool *Created=nullptr)
void PushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:367
void EmitAssemblerFlag(MCAssemblerFlag Flag) override
Note in the output the specified Flag.
COFF::SymbolStorageClass StorageClass
Definition: COFFYAML.cpp:356
void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override
Emits a COFF section relative relocation.
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a common symbol.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:77
unsigned getAlignment() const
Definition: MCSection.h:121
MCContext & getContext() const
Definition: MCStreamer.h:252
Definition: BitVector.h:937
void EmitCOFFSymbolType(int Type) override
Emit the type of the symbol.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override
MCCodeEmitter & getEmitter() const
Definition: MCAssembler.h:294
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool registerSection(MCSection &Section)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
MCSection * getBSSSection() const
A four-byte section relative fixup.
Definition: MCFixup.h:43
void EmitWinEHHandlerData(SMLoc Loc) override
void BeginCOFFSymbolDef(MCSymbol const *Symbol) override
Start emitting COFF symbol definition.
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:65
MCSection * getSXDataSection() const
A two-byte section relative fixup.
Definition: MCFixup.h:42
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:51
Streaming object file generation interface.
.alt_entry (MachO)
Definition: MCDirectives.h:38
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:265
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:465
SmallVectorImpl< char > & getContents()
Definition: MCFragment.h:198
void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override
Set the DescValue for the Symbol.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:131
void EndCOFFSymbolDef() override
Marks the end of the symbol definition.
void EmitZeros(uint64_t NumBytes)
Emit NumBytes worth of zeros.
Definition: MCStreamer.cpp:207
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a local common (.lcomm) symbol.
void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
void visitUsedSymbol(const MCSymbol &Sym) override
void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
MCAssembler & getAssembler()
void setHasInstructions(const MCSubtargetInfo &STI)
Record that the fragment contains instructions with the MCSubtargetInfo in effect when the instructio...
Definition: MCFragment.h:178
void setAlignment(llvm::Align Value)
Definition: MCSection.h:122
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:224
void EmitCOFFSymbolStorageClass(int StorageClass) override
Emit the storage class of the symbol.
void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, SMLoc Loc=SMLoc()) override
Emit the zerofill section and an optional symbol.
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:322
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:687
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:50
.weak_reference (MachO)
Definition: MCDirectives.h:44
void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override
Emits a COFF image relative relocation.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:93
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override
Emits a COFF section index.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:40
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
MCSection * getDrectveSection() const
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
PowerPC TLS Dynamic Call Fixup
void EmitCOFFSafeSEH(MCSymbol const *Symbol) override
void setIsSafeSEH() const
Definition: MCSymbolCOFF.h:57
MCAsmBackend & getBackend() const
Definition: MCAssembler.h:292
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
void setType(uint16_t Ty) const
Definition: MCSymbolCOFF.h:36
Represents a symbol table index fragment.
Definition: MCFragment.h:571
const Triple & getTargetTriple() const
MCSymbolAttr
Definition: MCDirectives.h:18
MCSection * getCurrentSectionOnly() const
Definition: MCStreamer.h:345
.syntax (ARM/ELF)
Definition: MCDirectives.h:49
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:387
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:52
bool isSafeSEH() const
Definition: MCSymbolCOFF.h:54
.code64 (X86)
Definition: MCDirectives.h:53
MCDataFragment * getOrCreateDataFragment(const MCSubtargetInfo *STI=nullptr)
Get a data fragment to write into, creating a new one if the current fragment is not a data fragment...
virtual void handleAssemblerFlag(MCAssemblerFlag Flag)
Handle any target-specific assembler flags. By default, do nothing.
Definition: MCAsmBackend.h:175
void EmitCOFFSymbolIndex(MCSymbol const *Symbol) override
Emits the symbol table index of a Symbol into the current section.
.type _foo,
Definition: MCDirectives.h:30
void FinishImpl() override
Streamer specific finalization.
MCAssemblerFlag
Definition: MCDirectives.h:48
Generic base class for all target subtargets.
void EmitIdent(StringRef IdentString) override
Emit the "identifiers" directive.
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a thread local bss (.tbss) symbol.
uint32_t Size
Definition: Profile.cpp:46
Fragment for data and encoded instructions.
Definition: MCFragment.h:243
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:376
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Represents a location in source code.
Definition: SMLoc.h:23
void EmitThumbFunc(MCSymbol *Func) override
Note in the output that the specified Func is a Thumb mode function (ARM target only).
void resize(size_type N)
Definition: SmallVector.h:344
A function that returns a base type.
Definition: COFF.h:261