#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
bool DoAutoReset)
: SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
- Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0),
+ Symbols(Allocator), UsedNames(Allocator),
CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
AllowTemporaryLabels(true), DwarfCompileUnitID(0),
ELFUniquingMap.clear();
COFFUniquingMap.clear();
- NextUniqueID = 0;
+ NextID.clear();
AllowTemporaryLabels = true;
DwarfLocSeen = false;
GenDwarfForAssembly = false;
// Symbol Manipulation
//===----------------------------------------------------------------------===//
-MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
- assert(!Name.empty() && "Normal symbols cannot be unnamed!");
+MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
+ SmallString<128> NameSV;
+ StringRef NameRef = Name.toStringRef(NameSV);
- MCSymbol *&Sym = Symbols[Name];
+ assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
+ MCSymbol *&Sym = Symbols[NameRef];
if (!Sym)
- Sym = CreateSymbol(Name);
+ Sym = CreateSymbol(NameRef, false);
return Sym;
}
return Sym;
}
-MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName) {
- return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- "frameallocation_" + FuncName);
+MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
+ unsigned Idx) {
+ return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
+ "$frame_escape_" + Twine(Idx));
+}
+
+MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
+ return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
+ "$parent_frame_offset");
}
-MCSymbol *MCContext::CreateSymbol(StringRef Name) {
+MCSymbol *MCContext::CreateSymbol(StringRef Name, bool AlwaysAddSuffix) {
// Determine whether this is an assembler temporary or normal label, if used.
- bool isTemporary = false;
+ bool IsTemporary = false;
if (AllowTemporaryLabels)
- isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
+ IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
- auto NameEntry = UsedNames.insert(std::make_pair(Name, true));
- if (!NameEntry.second) {
- assert(isTemporary && "Cannot rename non-temporary symbols");
- SmallString<128> NewName = Name;
- do {
+ SmallString<128> NewName = Name;
+ bool AddSuffix = AlwaysAddSuffix;
+ unsigned &NextUniqueID = NextID[Name];
+ for (;;) {
+ if (AddSuffix) {
NewName.resize(Name.size());
raw_svector_ostream(NewName) << NextUniqueID++;
- NameEntry = UsedNames.insert(std::make_pair(NewName, true));
- } while (!NameEntry.second);
+ }
+ auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
+ if (NameEntry.second) {
+ // Ok, we found a name. Have the MCSymbol object itself refer to the copy
+ // of the string that is embedded in the UsedNames entry.
+ MCSymbol *Result =
+ new (*this) MCSymbol(NameEntry.first->getKey(), IsTemporary);
+ return Result;
+ }
+ assert(IsTemporary && "Cannot rename non-temporary symbols");
+ AddSuffix = true;
}
-
- // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer
- // to the copy of the string that is embedded in the UsedNames entry.
- MCSymbol *Result =
- new (*this) MCSymbol(NameEntry.first->getKey(), isTemporary);
-
- return Result;
+ llvm_unreachable("Infinite loop");
}
-MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
+MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
SmallString<128> NameSV;
- return GetOrCreateSymbol(Name.toStringRef(NameSV));
+ raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
+ return CreateSymbol(NameSV, AlwaysAddSuffix);
}
MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
SmallString<128> NameSV;
- raw_svector_ostream(NameSV)
- << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
- return CreateSymbol(NameSV);
+ raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
+ return CreateSymbol(NameSV, true);
}
MCSymbol *MCContext::CreateTempSymbol() {
- SmallString<128> NameSV;
- raw_svector_ostream(NameSV)
- << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
- return CreateSymbol(NameSV);
+ return createTempSymbol("tmp", true);
}
unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
}
-MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
- return Symbols.lookup(Name);
-}
-
MCSymbol *MCContext::LookupSymbol(const Twine &Name) const {
SmallString<128> NameSV;
- Name.toVector(NameSV);
- return LookupSymbol(NameSV.str());
+ StringRef NameRef = Name.toStringRef(NameSV);
+ return Symbols.lookup(NameRef);
}
//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//
-const MCSectionMachO *MCContext::
-getMachOSection(StringRef Segment, StringRef Section,
- unsigned TypeAndAttributes,
- unsigned Reserved2, SectionKind Kind) {
+const MCSectionMachO *
+MCContext::getMachOSection(StringRef Segment, StringRef Section,
+ unsigned TypeAndAttributes, unsigned Reserved2,
+ SectionKind Kind, const char *BeginSymName) {
// We unique sections by their segment/section pair. The returned section
// may not have the same flags as the requested section, if so this should be
Name += Section;
// Do the lookup, if we have a hit, return it.
- const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()];
- if (Entry) return Entry;
+ const MCSectionMachO *&Entry = MachOUniquingMap[Name];
+ if (Entry)
+ return Entry;
+
+ MCSymbol *Begin = nullptr;
+ if (BeginSymName)
+ Begin = createTempSymbol(BeginSymName, false);
// Otherwise, return a new section.
return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
- Reserved2, Kind);
-}
-
-const MCSectionELF *MCContext::
-getELFSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind) {
- return getELFSection(Section, Type, Flags, Kind, 0, "");
+ Reserved2, Kind, Begin);
}
void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) {
if (const MCSymbol *Group = Section->getGroup())
GroupName = Group->getName();
- ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName));
- auto I =
- ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName),
- Section)).first;
- StringRef CachedName = I->first.first;
+ unsigned UniqueID = Section->getUniqueID();
+ ELFUniquingMap.erase(
+ ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
+ auto I = ELFUniquingMap.insert(std::make_pair(
+ ELFSectionKey{Name, GroupName, UniqueID},
+ Section)).first;
+ StringRef CachedName = I->first.SectionName;
const_cast<MCSectionELF*>(Section)->setSectionName(CachedName);
}
-const MCSectionELF *MCContext::
-getELFSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind, unsigned EntrySize, StringRef Group) {
+const MCSectionELF *
+MCContext::createELFRelSection(StringRef Name, unsigned Type, unsigned Flags,
+ unsigned EntrySize, const MCSymbol *Group,
+ const MCSectionELF *Associated) {
+ StringMap<bool>::iterator I;
+ bool Inserted;
+ std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true));
+
+ return new (*this)
+ MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
+ EntrySize, Group, true, nullptr, Associated);
+}
+
+const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ StringRef Group, unsigned UniqueID,
+ const char *BeginSymName) {
+ MCSymbol *GroupSym = nullptr;
+ if (!Group.empty())
+ GroupSym = GetOrCreateSymbol(Group);
+
+ return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
+ BeginSymName, nullptr);
+}
+
+const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, unsigned EntrySize,
+ const MCSymbol *GroupSym,
+ unsigned UniqueID,
+ const char *BeginSymName,
+ const MCSectionELF *Associated) {
+ StringRef Group = "";
+ if (GroupSym)
+ Group = GroupSym->getName();
// Do the lookup, if we have a hit, return it.
auto IterBool = ELFUniquingMap.insert(
- std::make_pair(SectionGroupPair(Section, Group), nullptr));
+ std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr));
auto &Entry = *IterBool.first;
- if (!IterBool.second) return Entry.second;
+ if (!IterBool.second)
+ return Entry.second;
- // Possibly refine the entry size first.
- if (!EntrySize) {
- EntrySize = MCSectionELF::DetermineEntrySize(Kind);
- }
+ StringRef CachedName = Entry.first.SectionName;
- MCSymbol *GroupSym = nullptr;
- if (!Group.empty())
- GroupSym = GetOrCreateSymbol(Group);
+ SectionKind Kind;
+ if (Flags & ELF::SHF_EXECINSTR)
+ Kind = SectionKind::getText();
+ else
+ Kind = SectionKind::getReadOnly();
- StringRef CachedName = Entry.first.first;
- MCSectionELF *Result = new (*this)
- MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym);
+ MCSymbol *Begin = nullptr;
+ if (BeginSymName)
+ Begin = createTempSymbol(BeginSymName, false);
+
+ MCSectionELF *Result =
+ new (*this) MCSectionELF(CachedName, Type, Flags, Kind, EntrySize,
+ GroupSym, UniqueID, Begin, Associated);
Entry.second = Result;
return Result;
}
-const MCSectionELF *MCContext::CreateELFGroupSection() {
- MCSectionELF *Result =
- new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
- SectionKind::getReadOnly(), 4, nullptr);
+const MCSectionELF *MCContext::createELFGroupSection(const MCSymbol *Group) {
+ MCSectionELF *Result = new (*this)
+ MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
+ Group, ~0, nullptr, nullptr);
return Result;
}
-const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
- unsigned Characteristics,
- SectionKind Kind,
- StringRef COMDATSymName,
- int Selection) {
- // Do the lookup, if we have a hit, return it.
+const MCSectionCOFF *
+MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind, StringRef COMDATSymName,
+ int Selection, const char *BeginSymName) {
+ MCSymbol *COMDATSymbol = nullptr;
+ if (!COMDATSymName.empty()) {
+ COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
+ COMDATSymName = COMDATSymbol->getName();
+ }
- SectionGroupTriple T(Section, COMDATSymName, Selection);
+ // Do the lookup, if we have a hit, return it.
+ COFFSectionKey T{Section, COMDATSymName, Selection};
auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
auto Iter = IterBool.first;
if (!IterBool.second)
return Iter->second;
- MCSymbol *COMDATSymbol = nullptr;
- if (!COMDATSymName.empty())
- COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
+ MCSymbol *Begin = nullptr;
+ if (BeginSymName)
+ Begin = createTempSymbol(BeginSymName, false);
- StringRef CachedName = std::get<0>(Iter->first);
- MCSectionCOFF *Result = new (*this)
- MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind);
+ StringRef CachedName = Iter->first.SectionName;
+ MCSectionCOFF *Result = new (*this) MCSectionCOFF(
+ CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
Iter->second = Result;
return Result;
}
-const MCSectionCOFF *
-MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
- SectionKind Kind) {
- return getCOFFSection(Section, Characteristics, Kind, "", 0);
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind,
+ const char *BeginSymName) {
+ return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName);
}
const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
- SectionGroupTriple T(Section, "", 0);
+ COFFSectionKey T{Section, "", 0};
auto Iter = COFFUniquingMap.find(T);
if (Iter == COFFUniquingMap.end())
return nullptr;