d3a4a27cefdebfe629aa5166bc5ef9caa5234fe1
[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/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCSectionMachO.h"
13 #include "llvm/MC/MCSectionELF.h"
14 #include "llvm/MC/MCSectionCOFF.h"
15 #include "llvm/MC/MCSymbol.h"
16 #include "llvm/MC/MCLabel.h"
17 #include "llvm/MC/MCDwarf.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/Twine.h"
20 using namespace llvm;
21
22 typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
23 typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
24 typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
25
26
27 MCContext::MCContext(const MCAsmInfo &mai, const TargetAsmInfo *tai) :
28   MAI(mai), TAI(tai), NextUniqueID(0),
29   CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0) {
30   MachOUniquingMap = 0;
31   ELFUniquingMap = 0;
32   COFFUniquingMap = 0;
33
34   SecureLogFile = getenv("AS_SECURE_LOG_FILE");
35   SecureLog = 0;
36   SecureLogUsed = false;
37
38   DwarfLocSeen = false;
39 }
40
41 MCContext::~MCContext() {
42   // NOTE: The symbols are all allocated out of a bump pointer allocator,
43   // we don't need to free them here.
44
45   // If we have the MachO uniquing map, free it.
46   delete (MachOUniqueMapTy*)MachOUniquingMap;
47   delete (ELFUniqueMapTy*)ELFUniquingMap;
48   delete (COFFUniqueMapTy*)COFFUniquingMap;
49
50   // If the stream for the .secure_log_unique directive was created free it.
51   delete (raw_ostream*)SecureLog;
52 }
53
54 //===----------------------------------------------------------------------===//
55 // Symbol Manipulation
56 //===----------------------------------------------------------------------===//
57
58 MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
59   assert(!Name.empty() && "Normal symbols cannot be unnamed!");
60
61   // Do the lookup and get the entire StringMapEntry.  We want access to the
62   // key if we are creating the entry.
63   StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
64   MCSymbol *Sym = Entry.getValue();
65
66   if (Sym)
67     return Sym;
68
69   Sym = CreateSymbol(Name);
70   Entry.setValue(Sym);
71   return Sym;
72 }
73
74 MCSymbol *MCContext::CreateSymbol(StringRef Name) {
75   // Determine whether this is an assembler temporary or normal label.
76   bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
77
78   StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
79   if (NameEntry->getValue()) {
80     assert(isTemporary && "Cannot rename non temporary symbols");
81     SmallString<128> NewName;
82     do {
83       Twine T = Name + Twine(NextUniqueID++);
84       T.toVector(NewName);
85       StringRef foo = NewName;
86       NameEntry = &UsedNames.GetOrCreateValue(foo);
87     } while (NameEntry->getValue());
88   }
89   NameEntry->setValue(true);
90
91   // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
92   // to the copy of the string that is embedded in the UsedNames entry.
93   MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);
94
95   return Result;
96 }
97
98 MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
99   SmallString<128> NameSV;
100   Name.toVector(NameSV);
101   return GetOrCreateSymbol(NameSV.str());
102 }
103
104 MCSymbol *MCContext::CreateTempSymbol() {
105   SmallString<128> NameSV;
106   Twine Name = Twine(MAI.getPrivateGlobalPrefix()) + "tmp" +
107     Twine(NextUniqueID++);
108   Name.toVector(NameSV);
109   return CreateSymbol(NameSV);
110 }
111
112 unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
113   MCLabel *&Label = Instances[LocalLabelVal];
114   if (!Label)
115     Label = new (*this) MCLabel(0);
116   return Label->incInstance();
117 }
118
119 unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
120   MCLabel *&Label = Instances[LocalLabelVal];
121   if (!Label)
122     Label = new (*this) MCLabel(0);
123   return Label->getInstance();
124 }
125
126 MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
127   return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
128                            Twine(LocalLabelVal) +
129                            "\2" +
130                            Twine(NextInstance(LocalLabelVal)));
131 }
132 MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
133                                                int bORf) {
134   return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
135                            Twine(LocalLabelVal) +
136                            "\2" +
137                            Twine(GetInstance(LocalLabelVal) + bORf));
138 }
139
140 MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
141   return Symbols.lookup(Name);
142 }
143
144 //===----------------------------------------------------------------------===//
145 // Section Management
146 //===----------------------------------------------------------------------===//
147
148 const MCSectionMachO *MCContext::
149 getMachOSection(StringRef Segment, StringRef Section,
150                 unsigned TypeAndAttributes,
151                 unsigned Reserved2, SectionKind Kind) {
152
153   // We unique sections by their segment/section pair.  The returned section
154   // may not have the same flags as the requested section, if so this should be
155   // diagnosed by the client as an error.
156
157   // Create the map if it doesn't already exist.
158   if (MachOUniquingMap == 0)
159     MachOUniquingMap = new MachOUniqueMapTy();
160   MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;
161
162   // Form the name to look up.
163   SmallString<64> Name;
164   Name += Segment;
165   Name.push_back(',');
166   Name += Section;
167
168   // Do the lookup, if we have a hit, return it.
169   const MCSectionMachO *&Entry = Map[Name.str()];
170   if (Entry) return Entry;
171
172   // Otherwise, return a new section.
173   return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
174                                             Reserved2, Kind);
175 }
176
177 const MCSectionELF *MCContext::
178 getELFSection(StringRef Section, unsigned Type, unsigned Flags,
179               SectionKind Kind) {
180   return getELFSection(Section, Type, Flags, Kind, 0, "");
181 }
182
183 const MCSectionELF *MCContext::
184 getELFSection(StringRef Section, unsigned Type, unsigned Flags,
185               SectionKind Kind, unsigned EntrySize, StringRef Group) {
186   if (ELFUniquingMap == 0)
187     ELFUniquingMap = new ELFUniqueMapTy();
188   ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
189
190   // Do the lookup, if we have a hit, return it.
191   StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
192   if (Entry.getValue()) return Entry.getValue();
193
194   // Possibly refine the entry size first.
195   if (!EntrySize) {
196     EntrySize = MCSectionELF::DetermineEntrySize(Kind);
197   }
198
199   MCSymbol *GroupSym = NULL;
200   if (!Group.empty())
201     GroupSym = GetOrCreateSymbol(Group);
202
203   MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
204                                                   Kind, EntrySize, GroupSym);
205   Entry.setValue(Result);
206   return Result;
207 }
208
209 const MCSectionELF *MCContext::CreateELFGroupSection() {
210   MCSectionELF *Result =
211     new (*this) MCSectionELF(".group", MCSectionELF::SHT_GROUP, 0,
212                              SectionKind::getReadOnly(), 4, NULL);
213   return Result;
214 }
215
216 const MCSection *MCContext::getCOFFSection(StringRef Section,
217                                            unsigned Characteristics,
218                                            int Selection,
219                                            SectionKind Kind) {
220   if (COFFUniquingMap == 0)
221     COFFUniquingMap = new COFFUniqueMapTy();
222   COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
223
224   // Do the lookup, if we have a hit, return it.
225   StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
226   if (Entry.getValue()) return Entry.getValue();
227
228   MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
229                                                     Characteristics,
230                                                     Selection, Kind);
231
232   Entry.setValue(Result);
233   return Result;
234 }
235
236 //===----------------------------------------------------------------------===//
237 // Dwarf Management
238 //===----------------------------------------------------------------------===//
239
240 /// GetDwarfFile - takes a file name an number to place in the dwarf file and
241 /// directory tables.  If the file number has already been allocated it is an
242 /// error and zero is returned and the client reports the error, else the
243 /// allocated file number is returned.  The file numbers may be in any order.
244 unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
245   // TODO: a FileNumber of zero says to use the next available file number.
246   // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
247   // to not be less than one.  This needs to be change to be not less than zero.
248
249   // Make space for this FileNumber in the MCDwarfFiles vector if needed.
250   if (FileNumber >= MCDwarfFiles.size()) {
251     MCDwarfFiles.resize(FileNumber + 1);
252   } else {
253     MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
254     if (ExistingFile)
255       // It is an error to use see the same number more than once.
256       return 0;
257   }
258
259   // Get the new MCDwarfFile slot for this FileNumber.
260   MCDwarfFile *&File = MCDwarfFiles[FileNumber];
261
262   // Separate the directory part from the basename of the FileName.
263   std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');
264
265   // Find or make a entry in the MCDwarfDirs vector for this Directory.
266   StringRef Name;
267   unsigned DirIndex;
268   // Capture directory name.
269   if (Slash.second.empty()) {
270     Name = Slash.first;
271     DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used.
272   } else {
273     StringRef Directory = Slash.first;
274     Name = Slash.second;
275     for (DirIndex = 0; DirIndex < MCDwarfDirs.size(); DirIndex++) {
276       if (Directory == MCDwarfDirs[DirIndex])
277         break;
278     }
279     if (DirIndex >= MCDwarfDirs.size()) {
280       char *Buf = static_cast<char *>(Allocate(Directory.size()));
281       memcpy(Buf, Directory.data(), Directory.size());
282       MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
283     }
284     // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
285     // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
286     // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames are
287     // stored at MCDwarfFiles[FileNumber].Name .
288     DirIndex++;
289   }
290
291   // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
292   // vector.
293   char *Buf = static_cast<char *>(Allocate(Name.size()));
294   memcpy(Buf, Name.data(), Name.size());
295   File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex);
296
297   // return the allocated FileNumber.
298   return FileNumber;
299 }
300
301 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
302 /// currently is assigned and false otherwise.
303 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
304   if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
305     return false;
306
307   return MCDwarfFiles[FileNumber] != 0;
308 }