LLVM  3.7.0
WinCOFFStreamer.cpp
Go to the documentation of this file.
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"
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"
28 #include "llvm/Support/COFF.h"
29 #include "llvm/Support/Debug.h"
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "WinCOFFStreamer"
38 
39 namespace llvm {
42  : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {}
43 
45  const MCSubtargetInfo &STI) {
47 
50  raw_svector_ostream VecOS(Code);
51  getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
52  VecOS.flush();
53 
54  // Add the fixups and data.
55  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
56  Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
57  DF->getFixups().push_back(Fixups[i]);
58  }
59 
60  DF->getContents().append(Code.begin(), Code.end());
61 }
62 
63 void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
64  // FIXME: this is identical to the ELF one.
65  // This emulates the same behavior of GNU as. This makes it easier
66  // to compare the output as the major sections are in the same order.
67  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
69 
70  SwitchSection(getContext().getObjectFileInfo()->getDataSection());
72 
73  SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
75 
76  SwitchSection(getContext().getObjectFileInfo()->getTextSection());
77 }
78 
80  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
82 }
83 
85  llvm_unreachable("not implemented");
86 }
87 
89  llvm_unreachable("not implemented");
90 }
91 
94  assert(Symbol && "Symbol must be non-null!");
95  assert((!Symbol->isInSection() ||
96  Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
97  "Got non-COFF section in the COFF backend!");
98 
99  getAssembler().registerSymbol(*Symbol);
100 
101  switch (Attribute) {
102  default: return false;
103  case MCSA_WeakReference:
104  case MCSA_Weak:
105  cast<MCSymbolCOFF>(Symbol)->setIsWeakExternal();
106  Symbol->setExternal(true);
107  break;
108  case MCSA_Global:
109  Symbol->setExternal(true);
110  break;
111  }
112 
113  return true;
114 }
115 
117  llvm_unreachable("not implemented");
118 }
119 
121  assert((!Symbol->isInSection() ||
122  Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
123  "Got non-COFF section in the COFF backend!");
124 
125  if (CurSymbol)
126  FatalError("starting a new symbol definition without completing the "
127  "previous one");
128  CurSymbol = Symbol;
129 }
130 
132  if (!CurSymbol)
133  FatalError("storage class specified outside of symbol definition");
134 
135  if (StorageClass & ~COFF::SSC_Invalid)
136  FatalError("storage class value '" + Twine(StorageClass) +
137  "' out of range");
138 
140  cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
141 }
142 
144  if (!CurSymbol)
145  FatalError("symbol type specified outside of a symbol definition");
146 
147  if (Type & ~0xffff)
148  FatalError("type value '" + Twine(Type) + "' out of range");
149 
151  cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
152 }
153 
155  if (!CurSymbol)
156  FatalError("ending symbol definition without starting one");
157  CurSymbol = nullptr;
158 }
159 
161  // SafeSEH is a feature specific to 32-bit x86. It does not exist (and is
162  // unnecessary) on all platforms which use table-based exception dispatch.
163  if (getContext().getObjectFileInfo()->getTargetTriple().getArch() !=
164  Triple::x86)
165  return;
166 
167  const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol);
168  if (CSymbol->isSafeSEH())
169  return;
170 
172  getAssembler().registerSection(*SXData);
173  if (SXData->getAlignment() < 4)
174  SXData->setAlignment(4);
175 
176  new MCSafeSEHFragment(Symbol, SXData);
177 
178  getAssembler().registerSymbol(*Symbol);
179  CSymbol->setIsSafeSEH();
180 
181  // The Microsoft linker requires that the symbol type of a handler be
182  // function. Go ahead and oblige it here.
185 }
186 
189  const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
191  DF->getFixups().push_back(Fixup);
192  DF->getContents().resize(DF->getContents().size() + 2, 0);
193 }
194 
197  const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Symbol, getContext());
199  DF->getFixups().push_back(Fixup);
200  DF->getContents().resize(DF->getContents().size() + 4, 0);
201 }
202 
204  unsigned ByteAlignment) {
205  assert((!Symbol->isInSection() ||
206  Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
207  "Got non-COFF section in the COFF backend!");
208 
211  if (ByteAlignment > 32)
212  report_fatal_error("alignment is limited to 32-bytes");
213 
214  // Round size up to alignment so that we will honor the alignment request.
215  Size = std::max(Size, static_cast<uint64_t>(ByteAlignment));
216  }
217 
218  AssignSection(Symbol, nullptr);
219 
220  getAssembler().registerSymbol(*Symbol);
221  Symbol->setExternal(true);
222  Symbol->setCommon(Size, ByteAlignment);
223 
224  if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) {
225  SmallString<128> Directive;
226  raw_svector_ostream OS(Directive);
228 
229  OS << " -aligncomm:\"" << Symbol->getName() << "\","
230  << Log2_32_Ceil(ByteAlignment);
231  OS.flush();
232 
233  PushSection();
235  EmitBytes(Directive);
236  PopSection();
237  }
238 }
239 
241  unsigned ByteAlignment) {
242  assert(!Symbol->isInSection() && "Symbol must not already have a section!");
243 
245  getAssembler().registerSection(*Section);
246  if (Section->getAlignment() < ByteAlignment)
247  Section->setAlignment(ByteAlignment);
248 
249  getAssembler().registerSymbol(*Symbol);
250  Symbol->setExternal(false);
251 
252  AssignSection(Symbol, Section);
253 
254  if (ByteAlignment != 1)
255  new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0,
256  ByteAlignment, Section);
257 
258  MCFillFragment *Fragment = new MCFillFragment(
259  /*Value=*/0, /*ValueSize=*/0, Size, Section);
260  Symbol->setFragment(Fragment);
261 }
262 
264  uint64_t Size, unsigned ByteAlignment) {
265  llvm_unreachable("not implemented");
266 }
267 
269  uint64_t Size, unsigned ByteAlignment) {
270  llvm_unreachable("not implemented");
271 }
272 
274  getAssembler().addFileName(Filename);
275 }
276 
277 // TODO: Implement this if you want to emit .comment section in COFF obj files.
279  llvm_unreachable("not implemented");
280 }
281 
283  llvm_unreachable("not implemented");
284 }
285 
288 }
289 
291 void MCWinCOFFStreamer::FatalError(const Twine &Msg) const {
293 }
294 }
295 
void AssignSection(MCSymbol *Symbol, MCSection *Section)
Sets the symbol's section.
Definition: MCStreamer.cpp:192
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:48
unsigned Log2_32_Ceil(uint32_t Value)
Log2_32_Ceil - This function returns the ceil log base 2 of the specified value, 32 if the value is z...
Definition: MathExtras.h:481
void InitSections(bool NoExecStack) override
Create the default sections and set the initial one.
void EmitThumbFunc(MCSymbol *Func) override
Note in the output that the specified Func is a Thumb mode function (ARM target only).
void EmitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void setType(uint16_t Ty) const
Definition: MCSymbolCOFF.h:35
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:315
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override
Emits a COFF section index.
void EmitLabel(MCSymbol *Symbol) override
Emit a label for Symbol into the current section.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
SectionVariant getVariant() const
Definition: MCSection.h:111
void EmitWinEHHandlerData() override
void setAlignment(unsigned Value)
Definition: MCSection.h:125
const MCSymbol * CurSymbol
void EmitAssemblerFlag(MCAssemblerFlag Flag) override
Note in the output the specified Flag.
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg) const
Definition: MCContext.cpp:474
MCCodeEmitter & getEmitter() const
Definition: MCAssembler.h:735
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
void registerSymbol(const MCSymbol &Symbol, bool *Created=nullptr)
void PushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:301
void EmitCOFFSymbolStorageClass(int StorageClass) override
Emit the storage class of the symbol.
bool registerSection(MCSection &Section)
Definition: MCAssembler.h:859
unsigned getAlignment() const
Definition: MCSection.h:124
static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
COFF::SymbolStorageClass StorageClass
Definition: COFFYAML.cpp:294
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void EmitFileDirective(StringRef Filename) override
Switch to a new logical file.
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.
bool isSafeSEH() const
Definition: MCSymbolCOFF.h:53
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
void setCommon(uint64_t Size, unsigned Align)
Mark this symbol as being 'common'.
Definition: MCSymbol.h:343
A four-byte section relative fixup.
Definition: MCFixup.h:38
MCContext & getContext() const
Definition: MCStreamer.h:210
Context object for machine code objects.
Definition: MCContext.h:48
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:255
MCSection * getBSSSection() const
A two-byte section relative fixup.
Definition: MCFixup.h:37
Streaming object file generation interface.
void setExternal(bool Value) const
Definition: MCSymbol.h:390
void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override
Set the DescValue for the Symbol.
const Triple & getTargetTriple() const
SmallVectorImpl< char > & getContents()
Definition: MCAssembler.h:186
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a local common (.lcomm) symbol.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:97
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a common symbol.
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.
Definition: MCStreamer.cpp:701
MCAssembler & getAssembler()
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: Support/COFF.h:227
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:23
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCAssembler.h:211
A function that returns a base type.
Definition: Support/COFF.h:223
MCSection * getDrectveSection() const
.weak_reference (MachO)
Definition: MCDirectives.h:43
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:416
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit a thread local bss (.tbss) symbol.
void EmitCOFFSymbolType(int Type) override
Emit the type of the symbol.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:78
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
MCSection * getSXDataSection() const
PowerPC TLS Dynamic Call Fixup
void setFragment(MCFragment *Value) const
Definition: MCSymbol.h:385
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:264
#define LLVM_ATTRIBUTE_NORETURN
Definition: Compiler.h:204
MCSymbolAttr
Definition: MCDirectives.h:19
void addFileName(StringRef FileName)
Definition: MCAssembler.h:871
void EndCOFFSymbolDef() override
Marks the end of the symbol definition.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
.type _foo,
Definition: MCDirectives.h:30
void FinishImpl() override
Streamer specific finalization.
void EmitCOFFSecRel32(MCSymbol const *Symbol) override
Emits a COFF section relative relocation.
MCAssemblerFlag
Definition: MCDirectives.h:47
void setIsSafeSEH() const
Definition: MCSymbolCOFF.h:56
MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE, raw_pwrite_stream &OS)
void EmitLabel(MCSymbol *Symbol) override
Emit a label for Symbol into the current section.
MCSubtargetInfo - Generic base class for all target subtargets.
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override
void BeginCOFFSymbolDef(MCSymbol const *Symbol) override
Start emitting COFF symbol definition.
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:321
void EmitIdent(StringRef IdentString) override
Emit the "identifiers" directive.
Fragment for data and encoded instructions.
Definition: MCAssembler.h:228
void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override
Emit the zerofill section and an optional symbol.
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:310
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:229
bool isKnownWindowsMSVCEnvironment() const
Definition: Triple.h:436
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:258
void EmitCOFFSafeSEH(MCSymbol const *Symbol) override
Represents a location in source code.
Definition: SMLoc.h:23
MCDataFragment * getOrCreateDataFragment()
Get a data fragment to write into, creating a new one if the current fragment is not a data fragment...
void FinishImpl() override
Streamer specific finalization.
void resize(size_type N)
Definition: SmallVector.h:376