LLVM API Documentation

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