WinCOFFStreamer.cpp revision bf252bef674985f8a4d2de713acf9280e4d8d10b
1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//===-- llvm/MC/WinCOFFStreamer.cpp -----------------------------*- C++ -*-===//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//                     The LLVM Compiler Infrastructure
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// This file is distributed under the University of Illinois Open Source
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// License. See LICENSE.TXT for details.
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//===----------------------------------------------------------------------===//
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// This file contains an implementation of a Win32 COFF object file streamer.
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//===----------------------------------------------------------------------===//
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo#define DEBUG_TYPE "WinCOFFStreamer"
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo
163defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/MC/MCObjectStreamer.h"
178427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo#include "llvm/MC/MCContext.h"
188427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo#include "llvm/MC/MCSection.h"
193defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/MC/MCSymbol.h"
20fbb40098314ab45efa60667ad7ccae354c4f18daDarin Petkov#include "llvm/MC/MCExpr.h"
213defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/MC/MCValue.h"
22fbb40098314ab45efa60667ad7ccae354c4f18daDarin Petkov#include "llvm/MC/MCAssembler.h"
238427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo#include "llvm/MC/MCAsmLayout.h"
248427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo#include "llvm/MC/MCCodeEmitter.h"
258427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo#include "llvm/MC/MCSectionCOFF.h"
26be45bef9e283188b00e7def8967f81843669a7f1Chris Sosa#include "llvm/Target/TargetRegistry.h"
275bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold#include "llvm/Target/TargetAsmBackend.h"
283defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/ADT/StringMap.h"
29ac41a82e4be1be43913292d13d58b5eb2c572f53Alex Deymo
303defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/Support/COFF.h"
313defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/Support/Debug.h"
323defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com#include "llvm/Support/ErrorHandling.h"
3310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymo#include "llvm/Support/raw_ostream.h"
343defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comusing namespace llvm;
353defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
363defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comnamespace {
373defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comclass WinCOFFStreamer : public MCObjectStreamer {
38ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanpublic:
39ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCSymbol const *CurSymbol;
405bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
41ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  WinCOFFStreamer(MCContext &Context,
425a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                  TargetAsmBackend &TAB,
43ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                  MCCodeEmitter &CE,
4488b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko                  raw_ostream &OS);
455a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
465a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  void AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
475a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                       unsigned ByteAlignment, bool External);
48610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo
49c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  // MCStreamer interface
50856166594771c61973856f563e622ccb7dd48aa1Alex Deymo
51856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitLabel(MCSymbol *Symbol);
52856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
53856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
54ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
55ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
565bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
57ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  virtual void EmitCOFFSymbolStorageClass(int StorageClass);
58d04f8e24716d5acca6a7d116b63851adc1506845Gilad Arnold  virtual void EmitCOFFSymbolType(int Type);
59856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EndCOFFSymbolDef();
605a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
615a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
62610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo                                unsigned ByteAlignment);
63856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size);
64856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
65856166594771c61973856f563e622ccb7dd48aa1Alex Deymo                            unsigned Size,unsigned ByteAlignment);
66856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
67856166594771c61973856f563e622ccb7dd48aa1Alex Deymo                              uint64_t Size, unsigned ByteAlignment);
68856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
695a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  virtual void EmitValue(const MCExpr *Value, unsigned Size,
705a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                         unsigned AddrSpace);
71ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  virtual void EmitGPRel32Value(const MCExpr *Value);
725bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
7349d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov                                   unsigned ValueSize, unsigned MaxBytesToEmit);
74c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  virtual void EmitCodeAlignment(unsigned ByteAlignment,
75c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold                                 unsigned MaxBytesToEmit);
763defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
773defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  virtual void EmitFileDirective(StringRef Filename);
78c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  virtual void EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
79c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  virtual void EmitInstruction(const MCInst &Instruction);
803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  virtual void Finish();
81ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan};
82ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan} // end anonymous namespace.
83ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
84ae4697c073b84b260990a141acd53c6806da0708Jay SrinivasanWinCOFFStreamer::WinCOFFStreamer(MCContext &Context,
853defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com                                 TargetAsmBackend &TAB,
8649d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov                                 MCCodeEmitter &CE,
87a4a8a8ccc2d9e0285728ed247b43f09433e63323Darin Petkov                                 raw_ostream &OS)
883defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    : MCObjectStreamer(Context, TAB, OS, &CE)
893defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    , CurSymbol(NULL) {
903defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
913defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
9219a45f0eda0917b7788b925b501e774208474fdeGilad Arnoldvoid WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
9319a45f0eda0917b7788b925b501e774208474fdeGilad Arnold                                      unsigned ByteAlignment, bool External) {
943defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  assert(!Symbol->isInSection() && "Symbol must not already have a section!");
9519a45f0eda0917b7788b925b501e774208474fdeGilad Arnold
9619a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  std::string SectionName(".bss$linkonce");
9719a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  SectionName.append(Symbol->getName().begin(), Symbol->getName().end());
9819a45f0eda0917b7788b925b501e774208474fdeGilad Arnold
9919a45f0eda0917b7788b925b501e774208474fdeGilad Arnold  MCSymbolData &SymbolData = getAssembler().getOrCreateSymbolData(*Symbol);
1003defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
101d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  unsigned Characteristics =
1023defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com    COFF::IMAGE_SCN_LNK_COMDAT |
103ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
1045a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov    COFF::IMAGE_SCN_MEM_READ |
105c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold    COFF::IMAGE_SCN_MEM_WRITE;
1065a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
1075a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  int Selection = COFF::IMAGE_COMDAT_SELECT_LARGEST;
1085a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
109ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  const MCSection *Section = MCStreamer::getContext().getCOFFSection(
1105a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov    SectionName, Characteristics, Selection, SectionKind::getBSS());
1115bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
1125a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
113ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
114ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  if (SectionData.getAlignment() < ByteAlignment)
115ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    SectionData.setAlignment(ByteAlignment);
116db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
117ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  SymbolData.setExternal(External);
118ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
1195bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  Symbol->setSection(*Section);
120ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
121ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  if (ByteAlignment != 1)
122ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan      new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectionData);
1233defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com
1243defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  SymbolData.setFragment(new MCFillFragment(0, 0, Size, &SectionData));
125ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
126d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov
127c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold// MCStreamer interface
128d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov
129d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkovvoid WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
130d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov  // TODO: This is copied almost exactly from the MachOStreamer. Consider
131ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // merging into MCObjectStreamer?
132d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
133d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov  assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
1345bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  assert(CurSection && "Cannot emit before setting section!");
135d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov
136ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  Symbol->setSection(*CurSection);
137ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
138ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
139db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
140ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // FIXME: This is wasteful, we don't necessarily need to create a data
141ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // fragment. Instead, we should mark the symbol as pointing into the data
1425bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  // fragment if it exists, otherwise we should just queue the label and set its
143ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // fragment pointer when we emit the next fragment.
144ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCDataFragment *DF = getOrCreateDataFragment();
145ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
146d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov  assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
147d315dc7f336ceff8c1648ccd1a199ebb8c0a5a84Darin Petkov  SD.setFragment(DF);
148ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  SD.setOffset(DF->getContents().size());
1495a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov}
150c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold
1515a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
1525a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  llvm_unreachable("not implemented");
153ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
1545bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
1555a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
156ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // TODO: This is exactly the same as MachOStreamer. Consider merging into
157ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // MCObjectStreamer.
158db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan  getAssembler().getOrCreateSymbolData(*Symbol);
159ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  AddValueSymbols(Value);
160ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  Symbol->setVariableValue(Value);
161856166594771c61973856f563e622ccb7dd48aa1Alex Deymo}
162856166594771c61973856f563e622ccb7dd48aa1Alex Deymo
1633defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.comvoid WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
1643defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com                                          MCSymbolAttr Attribute) {
165ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  switch (Attribute) {
1665a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  case MCSA_WeakReference:
167c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold    getAssembler().getOrCreateSymbolData(*Symbol).modifyFlags(
1685a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov      COFF::SF_WeakReference,
1695a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov      COFF::SF_WeakReference);
170ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    break;
1715bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
1725a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  case MCSA_Global:
173ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    getAssembler().getOrCreateSymbolData(*Symbol).setExternal(true);
174ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    break;
175db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
176ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  default:
177ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    llvm_unreachable("unsupported attribute");
178856166594771c61973856f563e622ccb7dd48aa1Alex Deymo    break;
1793defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com  }
1803defe6acb3609e70e851a6eff062577d25a2af9dadlr@google.com}
181ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
1825a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
183c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  llvm_unreachable("not implemented");
1845a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov}
1855a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
186ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) {
1875bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  assert(CurSymbol == NULL && "EndCOFFSymbolDef must be called between calls "
1885a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                              "to BeginCOFFSymbolDef!");
189ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  CurSymbol = Symbol;
190ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
191ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
192db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasanvoid WinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
193ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
194ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  assert((StorageClass & ~0xFF) == 0 && "StorageClass must only have data in "
195ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                        "the first byte!");
196ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
1975a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags(
1985a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov    StorageClass << COFF::SF_ClassShift,
199ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    COFF::SF_ClassMask);
2005a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov}
201c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold
2025a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitCOFFSymbolType(int Type) {
2035a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
204ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  assert((Type & ~0xFFFF) == 0 && "Type must only have data in the first 2 "
2055bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold                                  "bytes");
2065a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
207ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags(
208ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    Type << COFF::SF_TypeShift,
209ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    COFF::SF_TypeMask);
210db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan}
211ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
212ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EndCOFFSymbolDef() {
213ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!");
214ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  CurSymbol = NULL;
2155a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov}
2165a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
217ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
2185a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  llvm_unreachable("not implemented");
219c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold}
2205a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
2215a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
2225a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                                       unsigned ByteAlignment) {
223ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  AddCommonSymbol(Symbol, Size, ByteAlignment, true);
2245bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold}
2255a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
226ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {
227ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  AddCommonSymbol(Symbol, Size, 1, false);
228ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
229db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
230ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
231ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                   unsigned Size,unsigned ByteAlignment) {
232ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  llvm_unreachable("not implemented");
233ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
234ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
2355a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
2365a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov                                     uint64_t Size, unsigned ByteAlignment) {
237ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  llvm_unreachable("not implemented");
2385a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov}
239c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold
2405a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkovvoid WinCOFFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
2415a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  // TODO: This is copied exactly from the MachOStreamer. Consider merging into
2425a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  // MCObjectStreamer?
243ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
2445bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold}
2455a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov
246ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitValue(const MCExpr *Value, unsigned Size,
247ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                unsigned AddrSpace) {
248ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  assert(AddrSpace == 0 && "Address space must be 0!");
249db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
250ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // TODO: This is copied exactly from the MachOStreamer. Consider merging into
251ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // MCObjectStreamer?
252ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCDataFragment *DF = getOrCreateDataFragment();
253ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
254ac41a82e4be1be43913292d13d58b5eb2c572f53Alex Deymo  // Avoid fixups when possible.
255970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes  int64_t AbsValue;
256970bb28905b44bf9f2cb986bb412ecda1095b0b1Andrew de los Reyes  if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue)) {
257ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    // FIXME: Endianness assumption.
2583f0303aa211e2de2d466cef063ff6f39fffe32ddAndrew de los Reyes    for (unsigned i = 0; i != Size; ++i)
259c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold      DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
2603f0303aa211e2de2d466cef063ff6f39fffe32ddAndrew de los Reyes  } else {
2613f0303aa211e2de2d466cef063ff6f39fffe32ddAndrew de los Reyes    DF->addFixup(MCFixup::Create(DF->getContents().size(),
262ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                 AddValueSymbols(Value),
263c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold                                 MCFixup::getKindForSize(Size)));
2645bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold    DF->getContents().resize(DF->getContents().size() + Size, 0);
2655a7f565a542196f24eb87ddac96508f8a84e3329Darin Petkov  }
266ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
2673f0303aa211e2de2d466cef063ff6f39fffe32ddAndrew de los Reyes
2683f0303aa211e2de2d466cef063ff6f39fffe32ddAndrew de los Reyesvoid WinCOFFStreamer::EmitGPRel32Value(const MCExpr *Value) {
269ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  llvm_unreachable("not implemented");
27049d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov}
271c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold
27249d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkovvoid WinCOFFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
27349d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov                                           int64_t Value,
27449d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov                                           unsigned ValueSize,
275ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                           unsigned MaxBytesToEmit) {
27649d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov  // TODO: This is copied exactly from the MachOStreamer. Consider merging into
27749d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov  // MCObjectStreamer?
278c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  if (MaxBytesToEmit == 0)
27949d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov    MaxBytesToEmit = ByteAlignment;
280ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
28110d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov                      getCurrentSectionData());
2825bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
28349d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov  // Update the maximum alignment on the current section if necessary.
284ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  if (ByteAlignment > getCurrentSectionData()->getAlignment())
285ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    getCurrentSectionData()->setAlignment(ByteAlignment);
286ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
287db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan
288ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitCodeAlignment(unsigned ByteAlignment,
289ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                        unsigned MaxBytesToEmit) {
2905bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  // TODO: This is copied exactly from the MachOStreamer. Consider merging into
291ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  // MCObjectStreamer?
292ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  if (MaxBytesToEmit == 0)
293ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan    MaxBytesToEmit = ByteAlignment;
29410d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov  MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
29510d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov                                           getCurrentSectionData());
296ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  F->setEmitNops(true);
29710d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov
298c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  // Update the maximum alignment on the current section if necessary.
29910d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov  if (ByteAlignment > getCurrentSectionData()->getAlignment())
30010d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov    getCurrentSectionData()->setAlignment(ByteAlignment);
30110d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov}
302ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
30310d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkovvoid WinCOFFStreamer::EmitValueToOffset(const MCExpr *Offset,
30410d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov                                        unsigned char Value) {
305c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  llvm_unreachable("not implemented");
30610d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov}
307ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
30810d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkovvoid WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
309856166594771c61973856f563e622ccb7dd48aa1Alex Deymo  // Ignore for now, linkers don't care, and proper debug
3105bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  // info will be a much large effort.
31110d02dd60d4c4f41f7f4ed92322fa7b597760118Darin Petkov}
312ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
313db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasanvoid WinCOFFStreamer::EmitDwarfFileDirective(unsigned FileNo,
314ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                             StringRef Filename) {
3155bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold  llvm_unreachable("not implemented");
316ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
317ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
318ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasanvoid WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) {
31949d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov  for (unsigned i = 0, e = Instruction.getNumOperands(); i != e; ++i)
32049d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov    if (Instruction.getOperand(i).isExpr())
321ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan      AddValueSymbols(Instruction.getOperand(i).getExpr());
322a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov
323c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  getCurrentSectionData()->setHasInstructions(true);
324a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov
325a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov  MCInstFragment *Fragment =
326a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov    new MCInstFragment(Instruction, getCurrentSectionData());
327ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
328a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov  raw_svector_ostream VecOS(Fragment->getCode());
329a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov
330c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold  getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS,
331a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov                                                Fragment->getFixups());
332ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan}
3335bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnold
334a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkovvoid WinCOFFStreamer::Finish() {
335ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCObjectStreamer::Finish();
336db0acdfca1ea33987e8b29325f4594417d1fae57Jay Srinivasan}
337ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan
3385bb4c90b8bdf931426d1926b21b0316a86b4b4e4Gilad Arnoldnamespace llvm
339ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan{
340ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan  MCStreamer *createWinCOFFStreamer(MCContext &Context,
341ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                    TargetAsmBackend &TAB,
342a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov                                    MCCodeEmitter &CE,
343a3df55badfc7dc25792aba1ca6e7ade582b566a7Darin Petkov                                    raw_ostream &OS,
344ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan                                    bool RelaxAll) {
34549d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov    WinCOFFStreamer *S = new WinCOFFStreamer(Context, TAB, CE, OS);
346c9abbec864f283d1873883bc8f9b523020ee2acbGilad Arnold    S->getAssembler().setRelaxAll(RelaxAll);
34749d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov    return S;
34849d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov  }
34949d91329a3a84d7e2b35f6e1ffc8a9b4d478515bDarin Petkov}
350ae4697c073b84b260990a141acd53c6806da0708Jay Srinivasan