1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
32 MCContext::MCContext(const MCAsmInfo
*mai
, const MCRegisterInfo
*mri
,
33 const MCObjectFileInfo
*mofi
, const SourceMgr
*mgr
,
35 : 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
) {
42 std::error_code EC
= llvm::sys::fs::current_path(CompilationDir
);
44 CompilationDir
.clear();
46 SecureLogFile
= getenv("AS_SECURE_LOG_FILE");
48 SecureLogUsed
= false;
50 if (SrcMgr
&& SrcMgr
->getNumBuffers())
52 SrcMgr
->getMemoryBuffer(SrcMgr
->getMainFileID())->getBufferIdentifier();
55 MCContext::~MCContext() {
60 // NOTE: The symbols are all allocated out of a bump pointer allocator,
61 // we don't need to free them here.
63 // If the stream for the .secure_log_unique directive was created free it.
64 delete (raw_ostream
*)SecureLog
;
67 //===----------------------------------------------------------------------===//
68 // Module Lifetime Management
69 //===----------------------------------------------------------------------===//
71 void MCContext::reset() {
76 CompilationDir
.clear();
78 MCDwarfLineTablesCUMap
.clear();
79 SectionStartEndSyms
.clear();
80 MCGenDwarfLabelEntries
.clear();
81 DwarfDebugFlags
= StringRef();
82 DwarfCompileUnitID
= 0;
83 CurrentDwarfLoc
= MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT
,0,0);
85 MachOUniquingMap
.clear();
86 ELFUniquingMap
.clear();
87 COFFUniquingMap
.clear();
90 AllowTemporaryLabels
= true;
92 GenDwarfForAssembly
= false;
93 GenDwarfFileNumber
= 0;
96 //===----------------------------------------------------------------------===//
97 // Symbol Manipulation
98 //===----------------------------------------------------------------------===//
100 MCSymbol
*MCContext::GetOrCreateSymbol(StringRef Name
) {
101 assert(!Name
.empty() && "Normal symbols cannot be unnamed!");
103 // Do the lookup and get the entire StringMapEntry. We want access to the
104 // key if we are creating the entry.
105 StringMapEntry
<MCSymbol
*> &Entry
= Symbols
.GetOrCreateValue(Name
);
106 MCSymbol
*Sym
= Entry
.getValue();
111 Sym
= CreateSymbol(Name
);
116 MCSymbol
*MCContext::CreateSymbol(StringRef Name
) {
117 // Determine whether this is an assembler temporary or normal label, if used.
118 bool isTemporary
= false;
119 if (AllowTemporaryLabels
)
120 isTemporary
= Name
.startswith(MAI
->getPrivateGlobalPrefix());
122 StringMapEntry
<bool> *NameEntry
= &UsedNames
.GetOrCreateValue(Name
);
123 if (NameEntry
->getValue()) {
124 assert(isTemporary
&& "Cannot rename non-temporary symbols");
125 SmallString
<128> NewName
= Name
;
127 NewName
.resize(Name
.size());
128 raw_svector_ostream(NewName
) << NextUniqueID
++;
129 NameEntry
= &UsedNames
.GetOrCreateValue(NewName
);
130 } while (NameEntry
->getValue());
132 NameEntry
->setValue(true);
134 // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer
135 // to the copy of the string that is embedded in the UsedNames entry.
136 MCSymbol
*Result
= new (*this) MCSymbol(NameEntry
->getKey(), isTemporary
);
141 MCSymbol
*MCContext::GetOrCreateSymbol(const Twine
&Name
) {
142 SmallString
<128> NameSV
;
143 return GetOrCreateSymbol(Name
.toStringRef(NameSV
));
146 MCSymbol
*MCContext::CreateLinkerPrivateTempSymbol() {
147 SmallString
<128> NameSV
;
148 raw_svector_ostream(NameSV
)
149 << MAI
->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID
++;
150 return CreateSymbol(NameSV
);
153 MCSymbol
*MCContext::CreateTempSymbol() {
154 SmallString
<128> NameSV
;
155 raw_svector_ostream(NameSV
)
156 << MAI
->getPrivateGlobalPrefix() << "tmp" << NextUniqueID
++;
157 return CreateSymbol(NameSV
);
160 unsigned MCContext::NextInstance(unsigned LocalLabelVal
) {
161 MCLabel
*&Label
= Instances
[LocalLabelVal
];
163 Label
= new (*this) MCLabel(0);
164 return Label
->incInstance();
167 unsigned MCContext::GetInstance(unsigned LocalLabelVal
) {
168 MCLabel
*&Label
= Instances
[LocalLabelVal
];
170 Label
= new (*this) MCLabel(0);
171 return Label
->getInstance();
174 MCSymbol
*MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal
,
176 MCSymbol
*&Sym
= LocalSymbols
[std::make_pair(LocalLabelVal
, Instance
)];
178 Sym
= CreateTempSymbol();
182 MCSymbol
*MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal
) {
183 unsigned Instance
= NextInstance(LocalLabelVal
);
184 return getOrCreateDirectionalLocalSymbol(LocalLabelVal
, Instance
);
187 MCSymbol
*MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal
,
189 unsigned Instance
= GetInstance(LocalLabelVal
);
192 return getOrCreateDirectionalLocalSymbol(LocalLabelVal
, Instance
);
195 MCSymbol
*MCContext::LookupSymbol(StringRef Name
) const {
196 return Symbols
.lookup(Name
);
199 MCSymbol
*MCContext::LookupSymbol(const Twine
&Name
) const {
200 SmallString
<128> NameSV
;
201 Name
.toVector(NameSV
);
202 return LookupSymbol(NameSV
.str());
205 //===----------------------------------------------------------------------===//
206 // Section Management
207 //===----------------------------------------------------------------------===//
209 const MCSectionMachO
*MCContext::
210 getMachOSection(StringRef Segment
, StringRef Section
,
211 unsigned TypeAndAttributes
,
212 unsigned Reserved2
, SectionKind Kind
) {
214 // We unique sections by their segment/section pair. The returned section
215 // may not have the same flags as the requested section, if so this should be
216 // diagnosed by the client as an error.
218 // Form the name to look up.
219 SmallString
<64> Name
;
224 // Do the lookup, if we have a hit, return it.
225 const MCSectionMachO
*&Entry
= MachOUniquingMap
[Name
.str()];
226 if (Entry
) return Entry
;
228 // Otherwise, return a new section.
229 return Entry
= new (*this) MCSectionMachO(Segment
, Section
, TypeAndAttributes
,
233 const MCSectionELF
*MCContext::
234 getELFSection(StringRef Section
, unsigned Type
, unsigned Flags
,
236 return getELFSection(Section
, Type
, Flags
, Kind
, 0, "");
239 void MCContext::renameELFSection(const MCSectionELF
*Section
, StringRef Name
) {
241 if (const MCSymbol
*Group
= Section
->getGroup())
242 GroupName
= Group
->getName();
244 ELFUniquingMap
.erase(SectionGroupPair(Section
->getSectionName(), GroupName
));
246 ELFUniquingMap
.insert(std::make_pair(SectionGroupPair(Name
, GroupName
),
248 StringRef CachedName
= I
->first
.first
;
249 const_cast<MCSectionELF
*>(Section
)->setSectionName(CachedName
);
252 const MCSectionELF
*MCContext::
253 getELFSection(StringRef Section
, unsigned Type
, unsigned Flags
,
254 SectionKind Kind
, unsigned EntrySize
, StringRef Group
) {
255 // Do the lookup, if we have a hit, return it.
256 auto IterBool
= ELFUniquingMap
.insert(
257 std::make_pair(SectionGroupPair(Section
, Group
), nullptr));
258 auto &Entry
= *IterBool
.first
;
259 if (!IterBool
.second
) return Entry
.second
;
261 // Possibly refine the entry size first.
263 EntrySize
= MCSectionELF::DetermineEntrySize(Kind
);
266 MCSymbol
*GroupSym
= nullptr;
268 GroupSym
= GetOrCreateSymbol(Group
);
270 StringRef CachedName
= Entry
.first
.first
;
271 MCSectionELF
*Result
= new (*this)
272 MCSectionELF(CachedName
, Type
, Flags
, Kind
, EntrySize
, GroupSym
);
273 Entry
.second
= Result
;
277 const MCSectionELF
*MCContext::CreateELFGroupSection() {
278 MCSectionELF
*Result
=
279 new (*this) MCSectionELF(".group", ELF::SHT_GROUP
, 0,
280 SectionKind::getReadOnly(), 4, nullptr);
284 const MCSectionCOFF
*MCContext::getCOFFSection(StringRef Section
,
285 unsigned Characteristics
,
287 StringRef COMDATSymName
,
289 // Do the lookup, if we have a hit, return it.
291 SectionGroupTriple
T(Section
, COMDATSymName
, Selection
);
292 auto IterBool
= COFFUniquingMap
.insert(std::make_pair(T
, nullptr));
293 auto Iter
= IterBool
.first
;
294 if (!IterBool
.second
)
297 MCSymbol
*COMDATSymbol
= nullptr;
298 if (!COMDATSymName
.empty())
299 COMDATSymbol
= GetOrCreateSymbol(COMDATSymName
);
301 StringRef CachedName
= std::get
<0>(Iter
->first
);
302 MCSectionCOFF
*Result
= new (*this)
303 MCSectionCOFF(CachedName
, Characteristics
, COMDATSymbol
, Selection
, Kind
);
305 Iter
->second
= Result
;
309 const MCSectionCOFF
*
310 MCContext::getCOFFSection(StringRef Section
, unsigned Characteristics
,
312 return getCOFFSection(Section
, Characteristics
, Kind
, "", 0);
315 const MCSectionCOFF
*MCContext::getCOFFSection(StringRef Section
) {
316 SectionGroupTriple
T(Section
, "", 0);
317 auto Iter
= COFFUniquingMap
.find(T
);
318 if (Iter
== COFFUniquingMap
.end())
323 const MCSectionCOFF
*
324 MCContext::getAssociativeCOFFSection(const MCSectionCOFF
*Sec
,
325 const MCSymbol
*KeySym
) {
326 // Return the normal section if we don't have to be associative.
330 // Make an associative section with the same name and kind as the normal
332 unsigned Characteristics
=
333 Sec
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
;
334 return getCOFFSection(Sec
->getSectionName(), Characteristics
, Sec
->getKind(),
336 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE
);
339 //===----------------------------------------------------------------------===//
341 //===----------------------------------------------------------------------===//
343 /// GetDwarfFile - takes a file name an number to place in the dwarf file and
344 /// directory tables. If the file number has already been allocated it is an
345 /// error and zero is returned and the client reports the error, else the
346 /// allocated file number is returned. The file numbers may be in any order.
347 unsigned MCContext::GetDwarfFile(StringRef Directory
, StringRef FileName
,
348 unsigned FileNumber
, unsigned CUID
) {
349 MCDwarfLineTable
&Table
= MCDwarfLineTablesCUMap
[CUID
];
350 return Table
.getFile(Directory
, FileName
, FileNumber
);
353 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
354 /// currently is assigned and false otherwise.
355 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber
, unsigned CUID
) {
356 const SmallVectorImpl
<MCDwarfFile
>& MCDwarfFiles
= getMCDwarfFiles(CUID
);
357 if(FileNumber
== 0 || FileNumber
>= MCDwarfFiles
.size())
360 return !MCDwarfFiles
[FileNumber
].Name
.empty();
363 /// finalizeDwarfSections - Emit end symbols for each non-empty code section.
364 /// Also remove empty sections from SectionStartEndSyms, to avoid generating
365 /// useless debug info for them.
366 void MCContext::finalizeDwarfSections(MCStreamer
&MCOS
) {
367 MCContext
&context
= MCOS
.getContext();
369 auto sec
= SectionStartEndSyms
.begin();
370 while (sec
!= SectionStartEndSyms
.end()) {
371 assert(sec
->second
.first
&& "Start symbol must be set by now");
372 MCOS
.SwitchSection(sec
->first
);
373 if (MCOS
.mayHaveInstructions()) {
374 MCSymbol
*SectionEndSym
= context
.CreateTempSymbol();
375 MCOS
.EmitLabel(SectionEndSym
);
376 sec
->second
.second
= SectionEndSym
;
379 MapVector
<const MCSection
*, std::pair
<MCSymbol
*, MCSymbol
*> >::iterator
381 sec
= SectionStartEndSyms
.erase(to_erase
);
386 void MCContext::FatalError(SMLoc Loc
, const Twine
&Msg
) const {
387 // If we have a source manager and a location, use it. Otherwise just
388 // use the generic report_fatal_error().
389 if (!SrcMgr
|| Loc
== SMLoc())
390 report_fatal_error(Msg
, false);
392 // Use the source manager to print the message.
393 SrcMgr
->PrintMessage(Loc
, SourceMgr::DK_Error
, Msg
);
395 // If we reached here, we are failing ungracefully. Run the interrupt handlers
396 // to make sure any special cleanups get done, in particular that we remove
397 // files registered with RemoveFileOnSignal.
398 sys::RunInterruptHandlers();