MCContext.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// License. See LICENSE.TXT for details.
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCContext.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/ADT/SmallString.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/ADT/Twine.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCAsmInfo.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCDwarf.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCLabel.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCObjectFileInfo.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCRegisterInfo.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCSectionCOFF.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCSectionELF.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCSectionMachO.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/MC/MCSymbol.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/ELF.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/FileSystem.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/MemoryBuffer.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/Signals.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/SourceMgr.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <map>
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using namespace llvm;
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const MCObjectFileInfo *mofi, const SourceMgr *mgr,
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     bool DoAutoReset)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
36      Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0),
37      CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
38      GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
39      AllowTemporaryLabels(true), DwarfCompileUnitID(0),
40      AutoReset(DoAutoReset) {
41
42  error_code EC = llvm::sys::fs::current_path(CompilationDir);
43  if (EC)
44    CompilationDir.clear();
45
46  SecureLogFile = getenv("AS_SECURE_LOG_FILE");
47  SecureLog = nullptr;
48  SecureLogUsed = false;
49
50  if (SrcMgr && SrcMgr->getNumBuffers() > 0)
51    MainFileName = SrcMgr->getMemoryBuffer(0)->getBufferIdentifier();
52}
53
54MCContext::~MCContext() {
55
56  if (AutoReset)
57    reset();
58
59  // NOTE: The symbols are all allocated out of a bump pointer allocator,
60  // we don't need to free them here.
61
62  // If the stream for the .secure_log_unique directive was created free it.
63  delete (raw_ostream*)SecureLog;
64}
65
66//===----------------------------------------------------------------------===//
67// Module Lifetime Management
68//===----------------------------------------------------------------------===//
69
70void MCContext::reset() {
71  UsedNames.clear();
72  Symbols.clear();
73  Allocator.Reset();
74  Instances.clear();
75  MCDwarfLineTablesCUMap.clear();
76  MCGenDwarfLabelEntries.clear();
77  DwarfDebugFlags = StringRef();
78  DwarfCompileUnitID = 0;
79  CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
80
81  MachOUniquingMap.clear();
82  ELFUniquingMap.clear();
83  COFFUniquingMap.clear();
84
85  NextUniqueID = 0;
86  AllowTemporaryLabels = true;
87  DwarfLocSeen = false;
88  GenDwarfForAssembly = false;
89  GenDwarfFileNumber = 0;
90}
91
92//===----------------------------------------------------------------------===//
93// Symbol Manipulation
94//===----------------------------------------------------------------------===//
95
96MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
97  assert(!Name.empty() && "Normal symbols cannot be unnamed!");
98
99  // Do the lookup and get the entire StringMapEntry.  We want access to the
100  // key if we are creating the entry.
101  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
102  MCSymbol *Sym = Entry.getValue();
103
104  if (Sym)
105    return Sym;
106
107  Sym = CreateSymbol(Name);
108  Entry.setValue(Sym);
109  return Sym;
110}
111
112MCSymbol *MCContext::CreateSymbol(StringRef Name) {
113  // Determine whether this is an assembler temporary or normal label, if used.
114  bool isTemporary = false;
115  if (AllowTemporaryLabels)
116    isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
117
118  StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
119  if (NameEntry->getValue()) {
120    assert(isTemporary && "Cannot rename non-temporary symbols");
121    SmallString<128> NewName = Name;
122    do {
123      NewName.resize(Name.size());
124      raw_svector_ostream(NewName) << NextUniqueID++;
125      NameEntry = &UsedNames.GetOrCreateValue(NewName);
126    } while (NameEntry->getValue());
127  }
128  NameEntry->setValue(true);
129
130  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
131  // to the copy of the string that is embedded in the UsedNames entry.
132  MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);
133
134  return Result;
135}
136
137MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
138  SmallString<128> NameSV;
139  return GetOrCreateSymbol(Name.toStringRef(NameSV));
140}
141
142MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
143  SmallString<128> NameSV;
144  raw_svector_ostream(NameSV)
145    << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
146  return CreateSymbol(NameSV);
147}
148
149MCSymbol *MCContext::CreateTempSymbol() {
150  SmallString<128> NameSV;
151  raw_svector_ostream(NameSV)
152    << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
153  return CreateSymbol(NameSV);
154}
155
156unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
157  MCLabel *&Label = Instances[LocalLabelVal];
158  if (!Label)
159    Label = new (*this) MCLabel(0);
160  return Label->incInstance();
161}
162
163unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
164  MCLabel *&Label = Instances[LocalLabelVal];
165  if (!Label)
166    Label = new (*this) MCLabel(0);
167  return Label->getInstance();
168}
169
170MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
171                                                       unsigned Instance) {
172  MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
173  if (!Sym)
174    Sym = CreateTempSymbol();
175  return Sym;
176}
177
178MCSymbol *MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal) {
179  unsigned Instance = NextInstance(LocalLabelVal);
180  return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
181}
182
183MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal,
184                                               bool Before) {
185  unsigned Instance = GetInstance(LocalLabelVal);
186  if (!Before)
187    ++Instance;
188  return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
189}
190
191MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
192  return Symbols.lookup(Name);
193}
194
195MCSymbol *MCContext::LookupSymbol(const Twine &Name) const {
196  SmallString<128> NameSV;
197  Name.toVector(NameSV);
198  return LookupSymbol(NameSV.str());
199}
200
201//===----------------------------------------------------------------------===//
202// Section Management
203//===----------------------------------------------------------------------===//
204
205const MCSectionMachO *MCContext::
206getMachOSection(StringRef Segment, StringRef Section,
207                unsigned TypeAndAttributes,
208                unsigned Reserved2, SectionKind Kind) {
209
210  // We unique sections by their segment/section pair.  The returned section
211  // may not have the same flags as the requested section, if so this should be
212  // diagnosed by the client as an error.
213
214  // Form the name to look up.
215  SmallString<64> Name;
216  Name += Segment;
217  Name.push_back(',');
218  Name += Section;
219
220  // Do the lookup, if we have a hit, return it.
221  const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()];
222  if (Entry) return Entry;
223
224  // Otherwise, return a new section.
225  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
226                                            Reserved2, Kind);
227}
228
229const MCSectionELF *MCContext::
230getELFSection(StringRef Section, unsigned Type, unsigned Flags,
231              SectionKind Kind) {
232  return getELFSection(Section, Type, Flags, Kind, 0, "");
233}
234
235void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) {
236  StringRef GroupName;
237  if (const MCSymbol *Group = Section->getGroup())
238    GroupName = Group->getName();
239
240  ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName));
241  auto I =
242      ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName),
243                                           Section)).first;
244  StringRef CachedName = I->first.first;
245  const_cast<MCSectionELF*>(Section)->setSectionName(CachedName);
246}
247
248const MCSectionELF *MCContext::
249getELFSection(StringRef Section, unsigned Type, unsigned Flags,
250              SectionKind Kind, unsigned EntrySize, StringRef Group) {
251  // Do the lookup, if we have a hit, return it.
252  auto IterBool = ELFUniquingMap.insert(
253      std::make_pair(SectionGroupPair(Section, Group), nullptr));
254  auto &Entry = *IterBool.first;
255  if (!IterBool.second) return Entry.second;
256
257  // Possibly refine the entry size first.
258  if (!EntrySize) {
259    EntrySize = MCSectionELF::DetermineEntrySize(Kind);
260  }
261
262  MCSymbol *GroupSym = nullptr;
263  if (!Group.empty())
264    GroupSym = GetOrCreateSymbol(Group);
265
266  StringRef CachedName = Entry.first.first;
267  MCSectionELF *Result = new (*this)
268      MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym);
269  Entry.second = Result;
270  return Result;
271}
272
273const MCSectionELF *MCContext::CreateELFGroupSection() {
274  MCSectionELF *Result =
275    new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
276                             SectionKind::getReadOnly(), 4, nullptr);
277  return Result;
278}
279
280const MCSectionCOFF *
281MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
282                          SectionKind Kind, StringRef COMDATSymName,
283                          int Selection, const MCSectionCOFF *Assoc) {
284  // Do the lookup, if we have a hit, return it.
285
286  SectionGroupPair P(Section, COMDATSymName);
287  auto IterBool = COFFUniquingMap.insert(std::make_pair(P, nullptr));
288  auto Iter = IterBool.first;
289  if (!IterBool.second)
290    return Iter->second;
291
292  const MCSymbol *COMDATSymbol = nullptr;
293  if (!COMDATSymName.empty())
294    COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
295
296  StringRef CachedName = Iter->first.first;
297  MCSectionCOFF *Result = new (*this) MCSectionCOFF(
298      CachedName, Characteristics, COMDATSymbol, Selection, Assoc, Kind);
299
300  Iter->second = Result;
301  return Result;
302}
303
304const MCSectionCOFF *
305MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
306                          SectionKind Kind) {
307  return getCOFFSection(Section, Characteristics, Kind, "", 0);
308}
309
310const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
311  SectionGroupPair P(Section, "");
312  auto Iter = COFFUniquingMap.find(P);
313  if (Iter == COFFUniquingMap.end())
314    return nullptr;
315  return Iter->second;
316}
317
318//===----------------------------------------------------------------------===//
319// Dwarf Management
320//===----------------------------------------------------------------------===//
321
322/// GetDwarfFile - takes a file name an number to place in the dwarf file and
323/// directory tables.  If the file number has already been allocated it is an
324/// error and zero is returned and the client reports the error, else the
325/// allocated file number is returned.  The file numbers may be in any order.
326unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
327                                 unsigned FileNumber, unsigned CUID) {
328  MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
329  return Table.getFile(Directory, FileName, FileNumber);
330}
331
332/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
333/// currently is assigned and false otherwise.
334bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
335  const SmallVectorImpl<MCDwarfFile>& MCDwarfFiles = getMCDwarfFiles(CUID);
336  if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
337    return false;
338
339  return !MCDwarfFiles[FileNumber].Name.empty();
340}
341
342void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const {
343  // If we have a source manager and a location, use it. Otherwise just
344  // use the generic report_fatal_error().
345  if (!SrcMgr || Loc == SMLoc())
346    report_fatal_error(Msg, false);
347
348  // Use the source manager to print the message.
349  SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
350
351  // If we reached here, we are failing ungracefully. Run the interrupt handlers
352  // to make sure any special cleanups get done, in particular that we remove
353  // files registered with RemoveFileOnSignal.
354  sys::RunInterruptHandlers();
355  exit(1);
356}
357