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