MCContext.cpp revision 263508
1//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
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#include "llvm/MC/MCContext.h"
11#include "llvm/ADT/SmallString.h"
12#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCAsmInfo.h"
14#include "llvm/MC/MCDwarf.h"
15#include "llvm/MC/MCLabel.h"
16#include "llvm/MC/MCObjectFileInfo.h"
17#include "llvm/MC/MCRegisterInfo.h"
18#include "llvm/MC/MCSectionCOFF.h"
19#include "llvm/MC/MCSectionELF.h"
20#include "llvm/MC/MCSectionMachO.h"
21#include "llvm/MC/MCSymbol.h"
22#include "llvm/Support/ELF.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/FileSystem.h"
25#include "llvm/Support/MemoryBuffer.h"
26#include "llvm/Support/Signals.h"
27#include "llvm/Support/SourceMgr.h"
28
29#include <map>
30
31using namespace llvm;
32
33typedef std::pair<std::string, std::string> SectionGroupPair;
34
35typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
36typedef std::map<SectionGroupPair, const MCSectionELF *> ELFUniqueMapTy;
37typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy;
38
39MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
40                     const MCObjectFileInfo *mofi, const SourceMgr *mgr,
41                     bool DoAutoReset) :
42  SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
43  Allocator(), Symbols(Allocator), UsedNames(Allocator),
44  NextUniqueID(0),
45  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
46  DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0),
47  AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
48
49  error_code EC = llvm::sys::fs::current_path(CompilationDir);
50  if (EC)
51    CompilationDir.clear();
52
53  MachOUniquingMap = 0;
54  ELFUniquingMap = 0;
55  COFFUniquingMap = 0;
56
57  SecureLogFile = getenv("AS_SECURE_LOG_FILE");
58  SecureLog = 0;
59  SecureLogUsed = false;
60
61  if (SrcMgr && SrcMgr->getNumBuffers() > 0)
62    MainFileName = SrcMgr->getMemoryBuffer(0)->getBufferIdentifier();
63  else
64    MainFileName = "";
65}
66
67MCContext::~MCContext() {
68
69  if (AutoReset)
70    reset();
71
72  // NOTE: The symbols are all allocated out of a bump pointer allocator,
73  // we don't need to free them here.
74
75  // If the stream for the .secure_log_unique directive was created free it.
76  delete (raw_ostream*)SecureLog;
77}
78
79//===----------------------------------------------------------------------===//
80// Module Lifetime Management
81//===----------------------------------------------------------------------===//
82
83void MCContext::reset() {
84  UsedNames.clear();
85  Symbols.clear();
86  Allocator.Reset();
87  Instances.clear();
88  MCDwarfFilesCUMap.clear();
89  MCDwarfDirsCUMap.clear();
90  MCGenDwarfLabelEntries.clear();
91  DwarfDebugFlags = StringRef();
92  MCLineSections.clear();
93  MCLineSectionOrder.clear();
94  DwarfCompileUnitID = 0;
95  MCLineTableSymbols.clear();
96  CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
97
98  // If we have the MachO uniquing map, free it.
99  delete (MachOUniqueMapTy*)MachOUniquingMap;
100  delete (ELFUniqueMapTy*)ELFUniquingMap;
101  delete (COFFUniqueMapTy*)COFFUniquingMap;
102  MachOUniquingMap = 0;
103  ELFUniquingMap = 0;
104  COFFUniquingMap = 0;
105
106  NextUniqueID = 0;
107  AllowTemporaryLabels = true;
108  DwarfLocSeen = false;
109  GenDwarfForAssembly = false;
110  GenDwarfFileNumber = 0;
111}
112
113//===----------------------------------------------------------------------===//
114// Symbol Manipulation
115//===----------------------------------------------------------------------===//
116
117MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
118  assert(!Name.empty() && "Normal symbols cannot be unnamed!");
119
120  // Do the lookup and get the entire StringMapEntry.  We want access to the
121  // key if we are creating the entry.
122  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
123  MCSymbol *Sym = Entry.getValue();
124
125  if (Sym)
126    return Sym;
127
128  Sym = CreateSymbol(Name);
129  Entry.setValue(Sym);
130  return Sym;
131}
132
133MCSymbol *MCContext::CreateSymbol(StringRef Name) {
134  // Determine whether this is an assembler temporary or normal label, if used.
135  bool isTemporary = false;
136  if (AllowTemporaryLabels)
137    isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
138
139  StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
140  if (NameEntry->getValue()) {
141    assert(isTemporary && "Cannot rename non temporary symbols");
142    SmallString<128> NewName = Name;
143    do {
144      NewName.resize(Name.size());
145      raw_svector_ostream(NewName) << NextUniqueID++;
146      NameEntry = &UsedNames.GetOrCreateValue(NewName);
147    } while (NameEntry->getValue());
148  }
149  NameEntry->setValue(true);
150
151  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
152  // to the copy of the string that is embedded in the UsedNames entry.
153  MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);
154
155  return Result;
156}
157
158MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
159  SmallString<128> NameSV;
160  Name.toVector(NameSV);
161  return GetOrCreateSymbol(NameSV.str());
162}
163
164MCSymbol *MCContext::CreateTempSymbol() {
165  SmallString<128> NameSV;
166  raw_svector_ostream(NameSV)
167    << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
168  return CreateSymbol(NameSV);
169}
170
171unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
172  MCLabel *&Label = Instances[LocalLabelVal];
173  if (!Label)
174    Label = new (*this) MCLabel(0);
175  return Label->incInstance();
176}
177
178unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
179  MCLabel *&Label = Instances[LocalLabelVal];
180  if (!Label)
181    Label = new (*this) MCLabel(0);
182  return Label->getInstance();
183}
184
185MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
186  return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
187                           Twine(LocalLabelVal) +
188                           "\2" +
189                           Twine(NextInstance(LocalLabelVal)));
190}
191MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
192                                               int bORf) {
193  return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
194                           Twine(LocalLabelVal) +
195                           "\2" +
196                           Twine(GetInstance(LocalLabelVal) + bORf));
197}
198
199MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
200  return Symbols.lookup(Name);
201}
202
203MCSymbol *MCContext::LookupSymbol(const Twine &Name) const {
204  SmallString<128> NameSV;
205  Name.toVector(NameSV);
206  return LookupSymbol(NameSV.str());
207}
208
209//===----------------------------------------------------------------------===//
210// Section Management
211//===----------------------------------------------------------------------===//
212
213const MCSectionMachO *MCContext::
214getMachOSection(StringRef Segment, StringRef Section,
215                unsigned TypeAndAttributes,
216                unsigned Reserved2, SectionKind Kind) {
217
218  // We unique sections by their segment/section pair.  The returned section
219  // may not have the same flags as the requested section, if so this should be
220  // diagnosed by the client as an error.
221
222  // Create the map if it doesn't already exist.
223  if (MachOUniquingMap == 0)
224    MachOUniquingMap = new MachOUniqueMapTy();
225  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;
226
227  // Form the name to look up.
228  SmallString<64> Name;
229  Name += Segment;
230  Name.push_back(',');
231  Name += Section;
232
233  // Do the lookup, if we have a hit, return it.
234  const MCSectionMachO *&Entry = Map[Name.str()];
235  if (Entry) return Entry;
236
237  // Otherwise, return a new section.
238  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
239                                            Reserved2, Kind);
240}
241
242const MCSectionELF *MCContext::
243getELFSection(StringRef Section, unsigned Type, unsigned Flags,
244              SectionKind Kind) {
245  return getELFSection(Section, Type, Flags, Kind, 0, "");
246}
247
248const MCSectionELF *MCContext::
249getELFSection(StringRef Section, unsigned Type, unsigned Flags,
250              SectionKind Kind, unsigned EntrySize, StringRef Group) {
251  if (ELFUniquingMap == 0)
252    ELFUniquingMap = new ELFUniqueMapTy();
253  ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
254
255  // Do the lookup, if we have a hit, return it.
256  std::pair<ELFUniqueMapTy::iterator, bool> Entry = Map.insert(
257      std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0));
258  if (!Entry.second) return Entry.first->second;
259
260  // Possibly refine the entry size first.
261  if (!EntrySize) {
262    EntrySize = MCSectionELF::DetermineEntrySize(Kind);
263  }
264
265  MCSymbol *GroupSym = NULL;
266  if (!Group.empty())
267    GroupSym = GetOrCreateSymbol(Group);
268
269  MCSectionELF *Result = new (*this) MCSectionELF(
270      Entry.first->first.first, Type, Flags, Kind, EntrySize, GroupSym);
271  Entry.first->second = Result;
272  return Result;
273}
274
275const MCSectionELF *MCContext::CreateELFGroupSection() {
276  MCSectionELF *Result =
277    new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
278                             SectionKind::getReadOnly(), 4, NULL);
279  return Result;
280}
281
282const MCSectionCOFF *
283MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
284                          SectionKind Kind, StringRef COMDATSymName,
285                          int Selection, const MCSectionCOFF *Assoc) {
286  if (COFFUniquingMap == 0)
287    COFFUniquingMap = new COFFUniqueMapTy();
288  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
289
290  // Do the lookup, if we have a hit, return it.
291
292  SectionGroupPair P(Section, COMDATSymName);
293  std::pair<COFFUniqueMapTy::iterator, bool> Entry =
294      Map.insert(std::make_pair(P, (MCSectionCOFF *)0));
295  COFFUniqueMapTy::iterator Iter = Entry.first;
296  if (!Entry.second)
297    return Iter->second;
298
299  const MCSymbol *COMDATSymbol = NULL;
300  if (!COMDATSymName.empty())
301    COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
302
303  MCSectionCOFF *Result =
304      new (*this) MCSectionCOFF(Iter->first.first, Characteristics,
305                                COMDATSymbol, Selection, Assoc, Kind);
306
307  Iter->second = Result;
308  return Result;
309}
310
311const MCSectionCOFF *
312MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
313                          SectionKind Kind) {
314  return getCOFFSection(Section, Characteristics, Kind, "", 0);
315}
316
317const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
318  if (COFFUniquingMap == 0)
319    COFFUniquingMap = new COFFUniqueMapTy();
320  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
321
322  SectionGroupPair P(Section, "");
323  COFFUniqueMapTy::iterator Iter = Map.find(P);
324  if (Iter == Map.end())
325    return 0;
326  return Iter->second;
327}
328
329//===----------------------------------------------------------------------===//
330// Dwarf Management
331//===----------------------------------------------------------------------===//
332
333/// GetDwarfFile - takes a file name an number to place in the dwarf file and
334/// directory tables.  If the file number has already been allocated it is an
335/// error and zero is returned and the client reports the error, else the
336/// allocated file number is returned.  The file numbers may be in any order.
337unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
338                                 unsigned FileNumber, unsigned CUID) {
339  // TODO: a FileNumber of zero says to use the next available file number.
340  // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
341  // to not be less than one.  This needs to be change to be not less than zero.
342
343  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
344  SmallVectorImpl<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
345  // Make space for this FileNumber in the MCDwarfFiles vector if needed.
346  if (FileNumber >= MCDwarfFiles.size()) {
347    MCDwarfFiles.resize(FileNumber + 1);
348  } else {
349    MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
350    if (ExistingFile)
351      // It is an error to use see the same number more than once.
352      return 0;
353  }
354
355  // Get the new MCDwarfFile slot for this FileNumber.
356  MCDwarfFile *&File = MCDwarfFiles[FileNumber];
357
358  if (Directory.empty()) {
359    // Separate the directory part from the basename of the FileName.
360    StringRef tFileName = sys::path::filename(FileName);
361    if (!tFileName.empty()) {
362      Directory = sys::path::parent_path(FileName);
363      if (!Directory.empty())
364        FileName = tFileName;
365    }
366  }
367
368  // Find or make a entry in the MCDwarfDirs vector for this Directory.
369  // Capture directory name.
370  unsigned DirIndex;
371  if (Directory.empty()) {
372    // For FileNames with no directories a DirIndex of 0 is used.
373    DirIndex = 0;
374  } else {
375    DirIndex = 0;
376    for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
377      if (Directory == MCDwarfDirs[DirIndex])
378        break;
379    }
380    if (DirIndex >= MCDwarfDirs.size()) {
381      char *Buf = static_cast<char *>(Allocate(Directory.size()));
382      memcpy(Buf, Directory.data(), Directory.size());
383      MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
384    }
385    // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
386    // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
387    // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
388    // are stored at MCDwarfFiles[FileNumber].Name .
389    DirIndex++;
390  }
391
392  // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
393  // vector.
394  char *Buf = static_cast<char *>(Allocate(FileName.size()));
395  memcpy(Buf, FileName.data(), FileName.size());
396  File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex);
397
398  // return the allocated FileNumber.
399  return FileNumber;
400}
401
402/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
403/// currently is assigned and false otherwise.
404bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
405  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
406  if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
407    return false;
408
409  return MCDwarfFiles[FileNumber] != 0;
410}
411
412void MCContext::FatalError(SMLoc Loc, const Twine &Msg) {
413  // If we have a source manager and a location, use it. Otherwise just
414  // use the generic report_fatal_error().
415  if (!SrcMgr || Loc == SMLoc())
416    report_fatal_error(Msg);
417
418  // Use the source manager to print the message.
419  SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
420
421  // If we reached here, we are failing ungracefully. Run the interrupt handlers
422  // to make sure any special cleanups get done, in particular that we remove
423  // files registered with RemoveFileOnSignal.
424  sys::RunInterruptHandlers();
425  exit(1);
426}
427