summaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /lib/MC
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/Android.mk4
-rw-r--r--lib/MC/CMakeLists.txt5
-rw-r--r--lib/MC/ConstantPools.cpp17
-rw-r--r--lib/MC/ELFObjectWriter.cpp98
-rw-r--r--lib/MC/LLVMBuild.txt2
-rw-r--r--lib/MC/MCAnalysis/Android.mk37
-rw-r--r--lib/MC/MCAnalysis/CMakeLists.txt8
-rw-r--r--lib/MC/MCAnalysis/LLVMBuild.txt5
-rw-r--r--lib/MC/MCAnalysis/MCAtom.cpp114
-rw-r--r--lib/MC/MCAnalysis/MCFunction.cpp76
-rw-r--r--lib/MC/MCAnalysis/MCModule.cpp142
-rw-r--r--lib/MC/MCAnalysis/MCModuleYAML.cpp464
-rw-r--r--lib/MC/MCAnalysis/MCObjectDisassembler.cpp574
-rw-r--r--lib/MC/MCAnalysis/MCObjectSymbolizer.cpp268
-rw-r--r--lib/MC/MCAnalysis/Makefile14
-rw-r--r--lib/MC/MCAsmInfo.cpp6
-rw-r--r--lib/MC/MCAsmInfoCOFF.cpp1
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp4
-rw-r--r--lib/MC/MCAsmInfoELF.cpp9
-rw-r--r--lib/MC/MCAsmStreamer.cpp24
-rw-r--r--lib/MC/MCAssembler.cpp76
-rw-r--r--lib/MC/MCContext.cpp62
-rw-r--r--lib/MC/MCDisassembler/Android.mk26
-rw-r--r--lib/MC/MCDisassembler/CMakeLists.txt3
-rw-r--r--lib/MC/MCDisassembler/Disassembler.cpp65
-rw-r--r--lib/MC/MCDisassembler/Disassembler.h4
-rw-r--r--lib/MC/MCDisassembler/MCDisassembler.cpp (renamed from lib/MC/MCDisassembler.cpp)2
-rw-r--r--lib/MC/MCDisassembler/MCExternalSymbolizer.cpp (renamed from lib/MC/MCExternalSymbolizer.cpp)2
-rw-r--r--lib/MC/MCDisassembler/MCRelocationInfo.cpp (renamed from lib/MC/MCRelocationInfo.cpp)2
-rw-r--r--lib/MC/MCDwarf.cpp252
-rw-r--r--lib/MC/MCELF.cpp4
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp3
-rw-r--r--lib/MC/MCELFStreamer.cpp57
-rw-r--r--lib/MC/MCExpr.cpp91
-rw-r--r--lib/MC/MCMachOStreamer.cpp10
-rw-r--r--lib/MC/MCNullStreamer.cpp1
-rw-r--r--lib/MC/MCObjectFileInfo.cpp59
-rw-r--r--lib/MC/MCObjectStreamer.cpp71
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp18
-rw-r--r--lib/MC/MCParser/AsmParser.cpp207
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp4
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp8
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp2
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp4
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp2
-rw-r--r--lib/MC/MCSectionCOFF.cpp18
-rw-r--r--lib/MC/MCSectionELF.cpp4
-rw-r--r--lib/MC/MCStreamer.cpp325
-rw-r--r--lib/MC/MCSubtargetInfo.cpp12
-rw-r--r--lib/MC/MCTargetOptions.cpp6
-rw-r--r--lib/MC/MCWin64EH.cpp173
-rw-r--r--lib/MC/MCWinEH.cpp84
-rw-r--r--lib/MC/MachObjectWriter.cpp82
-rw-r--r--lib/MC/Makefile2
-rw-r--r--lib/MC/StringTableBuilder.cpp45
-rw-r--r--lib/MC/SubtargetFeature.cpp18
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp338
-rw-r--r--lib/MC/WinCOFFStreamer.cpp33
58 files changed, 1259 insertions, 2788 deletions
diff --git a/lib/MC/Android.mk b/lib/MC/Android.mk
index fd587c4..c7c5c1f 100644
--- a/lib/MC/Android.mk
+++ b/lib/MC/Android.mk
@@ -13,13 +13,11 @@ mc_SRC_FILES := \
MCCodeEmitter.cpp \
MCCodeGenInfo.cpp \
MCContext.cpp \
- MCDisassembler.cpp \
MCDwarf.cpp \
MCELF.cpp \
MCELFObjectTargetWriter.cpp \
MCELFStreamer.cpp \
MCExpr.cpp \
- MCExternalSymbolizer.cpp \
MCInst.cpp \
MCInstPrinter.cpp \
MCInstrAnalysis.cpp \
@@ -32,7 +30,6 @@ mc_SRC_FILES := \
MCObjectStreamer.cpp \
MCObjectWriter.cpp \
MCRegisterInfo.cpp \
- MCRelocationInfo.cpp \
MCSection.cpp \
MCSectionCOFF.cpp \
MCSectionELF.cpp \
@@ -44,6 +41,7 @@ mc_SRC_FILES := \
MCTargetOptions.cpp \
MCValue.cpp \
MCWin64EH.cpp \
+ MCWinEH.cpp \
MachObjectWriter.cpp \
StringTableBuilder.cpp \
SubtargetFeature.cpp \
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index 330519e..7181bdc 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -11,13 +11,11 @@ add_llvm_library(LLVMMC
MCCodeEmitter.cpp
MCCodeGenInfo.cpp
MCContext.cpp
- MCDisassembler.cpp
MCDwarf.cpp
MCELF.cpp
MCELFObjectTargetWriter.cpp
MCELFStreamer.cpp
MCExpr.cpp
- MCExternalSymbolizer.cpp
MCInst.cpp
MCInstPrinter.cpp
MCInstrAnalysis.cpp
@@ -30,7 +28,6 @@ add_llvm_library(LLVMMC
MCObjectStreamer.cpp
MCObjectWriter.cpp
MCRegisterInfo.cpp
- MCRelocationInfo.cpp
MCSection.cpp
MCSectionCOFF.cpp
MCSectionELF.cpp
@@ -42,6 +39,7 @@ add_llvm_library(LLVMMC
MCTargetOptions.cpp
MCValue.cpp
MCWin64EH.cpp
+ MCWinEH.cpp
MachObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
@@ -50,6 +48,5 @@ add_llvm_library(LLVMMC
YAML.cpp
)
-add_subdirectory(MCAnalysis)
add_subdirectory(MCParser)
add_subdirectory(MCDisassembler)
diff --git a/lib/MC/ConstantPools.cpp b/lib/MC/ConstantPools.cpp
index f979dad..c4cea60 100644
--- a/lib/MC/ConstantPools.cpp
+++ b/lib/MC/ConstantPools.cpp
@@ -24,21 +24,22 @@ using namespace llvm;
void ConstantPool::emitEntries(MCStreamer &Streamer) {
if (Entries.empty())
return;
- Streamer.EmitCodeAlignment(4); // align to 4-byte address
Streamer.EmitDataRegion(MCDR_DataRegion);
for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end();
I != E; ++I) {
- Streamer.EmitLabel(I->first);
- Streamer.EmitValue(I->second, 4);
+ Streamer.EmitCodeAlignment(I->Size); // align naturally
+ Streamer.EmitLabel(I->Label);
+ Streamer.EmitValue(I->Value, I->Size);
}
Streamer.EmitDataRegion(MCDR_DataRegionEnd);
Entries.clear();
}
-const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context) {
+const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context,
+ unsigned Size) {
MCSymbol *CPEntryLabel = Context.CreateTempSymbol();
- Entries.push_back(std::make_pair(CPEntryLabel, Value));
+ Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size));
return MCSymbolRefExpr::Create(CPEntryLabel, Context);
}
@@ -89,7 +90,9 @@ void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
}
const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer,
- const MCExpr *Expr) {
+ const MCExpr *Expr,
+ unsigned Size) {
const MCSection *Section = Streamer.getCurrentSection().first;
- return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext());
+ return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(),
+ Size);
}
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 7fb9fae..e4442e1 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -81,23 +81,13 @@ public:
struct ELFRelocationEntry {
uint64_t Offset; // Where is the relocation.
- bool UseSymbol; // Relocate with a symbol, not the section.
- union {
- const MCSymbol *Symbol; // The symbol to relocate with.
- const MCSectionData *Section; // The section to relocate with.
- };
+ const MCSymbol *Symbol; // The symbol to relocate with.
unsigned Type; // The type of the relocation.
uint64_t Addend; // The addend to use.
ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
uint64_t Addend)
- : Offset(Offset), UseSymbol(true), Symbol(Symbol), Type(Type),
- Addend(Addend) {}
-
- ELFRelocationEntry(uint64_t Offset, const MCSectionData *Section,
- unsigned Type, uint64_t Addend)
- : Offset(Offset), UseSymbol(false), Section(Section), Type(Type),
- Addend(Addend) {}
+ : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
};
class ELFObjectWriter : public MCObjectWriter {
@@ -137,6 +127,14 @@ class ELFObjectWriter : public MCObjectWriter {
// Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const {
+ unsigned LHSType = MCELF::GetType(*SymbolData);
+ unsigned RHSType = MCELF::GetType(*RHS.SymbolData);
+ if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
+ return false;
+ if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
+ return true;
+ if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
+ return SectionIndex < RHS.SectionIndex;
return Name < RHS.Name;
}
};
@@ -246,7 +244,7 @@ class ELFObjectWriter : public MCObjectWriter {
/// \param NumRegularSections - Number of non-relocation sections.
void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
- RevGroupMapTy RevGroupMap,
+ const RevGroupMapTy &RevGroupMap,
unsigned NumRegularSections);
void ComputeIndexMap(MCAssembler &Asm,
@@ -651,22 +649,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
WriteSymbol(Writer, MSD, Layout);
}
- // Write out a symbol table entry for each regular section.
- for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e;
- ++i) {
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(i->getSection());
- if (Section.getType() == ELF::SHT_RELA ||
- Section.getType() == ELF::SHT_REL ||
- Section.getType() == ELF::SHT_STRTAB ||
- Section.getType() == ELF::SHT_SYMTAB ||
- Section.getType() == ELF::SHT_SYMTAB_SHNDX)
- continue;
- Writer.writeSymbol(0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT,
- SectionIndexMap.lookup(&Section), false);
- LastLocalSymbolIndex++;
- }
-
for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
ELFSymbolData &MSD = ExternalSymbolData[i];
MCSymbolData &Data = *MSD.SymbolData;
@@ -770,8 +752,9 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
}
// Most TLS relocations use a got, so they need the symbol. Even those that
- // are just an offset (@tpoff), require a symbol in some linkers (gold,
- // but not bfd ld).
+ // are just an offset (@tpoff), require a symbol in gold versions before
+ // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
+ // http://sourceware.org/PR16773.
if (Flags & ELF::SHF_TLS)
return true;
@@ -782,7 +765,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
if (Asm.isThumbFunc(&Sym))
return true;
- if (TargetObjectWriter->needsRelocateWithSymbol(Type))
+ if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type))
return true;
return false;
}
@@ -881,8 +864,11 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
if (!RelocateWithSymbol) {
const MCSection *SecA =
(SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
- const MCSectionData *SecAD = SecA ? &Asm.getSectionData(*SecA) : nullptr;
- ELFRelocationEntry Rec(FixupOffset, SecAD, Type, Addend);
+ auto *ELFSec = cast_or_null<MCSectionELF>(SecA);
+ MCSymbol *SectionSymbol =
+ ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec)
+ : nullptr;
+ ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
Relocations[FixupSection].push_back(Rec);
return;
}
@@ -991,7 +977,7 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
void
ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
- RevGroupMapTy RevGroupMap,
+ const RevGroupMapTy &RevGroupMap,
unsigned NumRegularSections) {
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
@@ -1037,7 +1023,7 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
MSD.SectionIndex = ELF::SHN_COMMON;
} else if (BaseSymbol->isUndefined()) {
if (isSignature && !Used)
- MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]);
+ MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap.lookup(&Symbol));
else
MSD.SectionIndex = ELF::SHN_UNDEF;
if (!Used && WeakrefUsed)
@@ -1060,7 +1046,10 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
Buf += Name.substr(Pos + Skip);
Name = Buf;
}
- MSD.Name = StrTabBuilder.add(Name);
+
+ // Sections have their own string table
+ if (MCELF::GetType(SD) != ELF::STT_SECTION)
+ MSD.Name = StrTabBuilder.add(Name);
if (MSD.SectionIndex == ELF::SHN_UNDEF)
UndefinedSymbolData.push_back(MSD);
@@ -1073,14 +1062,16 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
StrTabBuilder.add(*i);
- StrTabBuilder.finalize();
+ StrTabBuilder.finalize(StringTableBuilder::ELF);
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
FileSymbolData.push_back(StrTabBuilder.getOffset(*i));
- for (ELFSymbolData& MSD : LocalSymbolData)
- MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
- for (ELFSymbolData& MSD : ExternalSymbolData)
+ for (ELFSymbolData &MSD : LocalSymbolData)
+ MSD.StringIndex = MCELF::GetType(*MSD.SymbolData) == ELF::STT_SECTION
+ ? 0
+ : StrTabBuilder.getOffset(MSD.Name);
+ for (ELFSymbolData &MSD : ExternalSymbolData)
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
for (ELFSymbolData& MSD : UndefinedSymbolData)
MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
@@ -1096,8 +1087,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
LocalSymbolData[i].SymbolData->setIndex(Index++);
- Index += NumRegularSections;
-
for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
ExternalSymbolData[i].SymbolData->setIndex(Index++);
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
@@ -1353,18 +1342,8 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
const ELFRelocationEntry &Entry = Relocs[e - i - 1];
-
- unsigned Index;
- if (Entry.UseSymbol) {
- Index = getSymbolIndexInSymbolTable(Asm, Entry.Symbol);
- } else {
- const MCSectionData *Sec = Entry.Section;
- if (Sec)
- Index = Sec->getOrdinal() + FileSymbolData.size() +
- LocalSymbolData.size() + 1;
- else
- Index = 0;
- }
+ unsigned Index =
+ Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0;
if (is64Bit()) {
write(*F, Entry.Offset);
@@ -1446,7 +1425,7 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
static_cast<const MCSectionELF&>(it->getSection());
ShStrTabBuilder.add(Section.getSectionName());
}
- ShStrTabBuilder.finalize();
+ ShStrTabBuilder.finalize(StringTableBuilder::ELF);
F->getContents().append(ShStrTabBuilder.data().begin(),
ShStrTabBuilder.data().end());
}
@@ -1457,14 +1436,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
RevGroupMapTy &RevGroupMap,
SectionIndexMapTy &SectionIndexMap,
const RelMapTy &RelMap) {
- // Create the .note.GNU-stack section if needed.
MCContext &Ctx = Asm.getContext();
- if (Asm.getNoExecStack()) {
- const MCSectionELF *GnuStackSection =
- Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
- SectionKind::getReadOnly());
- Asm.getOrCreateSectionData(*GnuStackSection);
- }
// Build the groups
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
diff --git a/lib/MC/LLVMBuild.txt b/lib/MC/LLVMBuild.txt
index 3fcb50b..f06be45 100644
--- a/lib/MC/LLVMBuild.txt
+++ b/lib/MC/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = MCAnalysis MCDisassembler MCParser
+subdirectories = MCDisassembler MCParser
[component_0]
type = Library
diff --git a/lib/MC/MCAnalysis/Android.mk b/lib/MC/MCAnalysis/Android.mk
deleted file mode 100644
index 27f848a..0000000
--- a/lib/MC/MCAnalysis/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-mc_analysis_SRC_FILES := \
- MCAtom.cpp \
- MCFunction.cpp \
- MCModule.cpp \
- MCModuleYAML.cpp \
- MCObjectDisassembler.cpp \
- MCObjectSymbolizer.cpp
-
-# For the host
-# =====================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(mc_analysis_SRC_FILES)
-
-LOCAL_MODULE:= libLLVMMCAnalysis
-
-LOCAL_MODULE_TAGS := optional
-
-include $(LLVM_HOST_BUILD_MK)
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-# For the device
-# =====================================================
-include $(CLEAR_VARS)
-ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
-
-LOCAL_SRC_FILES := $(mc_analysis_SRC_FILES)
-
-LOCAL_MODULE:= libLLVMMCAnalysis
-
-LOCAL_MODULE_TAGS := optional
-
-include $(LLVM_DEVICE_BUILD_MK)
-include $(BUILD_STATIC_LIBRARY)
-endif
diff --git a/lib/MC/MCAnalysis/CMakeLists.txt b/lib/MC/MCAnalysis/CMakeLists.txt
deleted file mode 100644
index 81eae2d..0000000
--- a/lib/MC/MCAnalysis/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_llvm_library(LLVMMCAnalysis
- MCAtom.cpp
- MCFunction.cpp
- MCModule.cpp
- MCModuleYAML.cpp
- MCObjectDisassembler.cpp
- MCObjectSymbolizer.cpp
-)
diff --git a/lib/MC/MCAnalysis/LLVMBuild.txt b/lib/MC/MCAnalysis/LLVMBuild.txt
deleted file mode 100644
index 1b58fec..0000000
--- a/lib/MC/MCAnalysis/LLVMBuild.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-[component_0]
-type = Library
-name = MCAnalysis
-parent = Libraries
-required_libraries = MC Object Support
diff --git a/lib/MC/MCAnalysis/MCAtom.cpp b/lib/MC/MCAnalysis/MCAtom.cpp
deleted file mode 100644
index 82056ee..0000000
--- a/lib/MC/MCAnalysis/MCAtom.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCModule.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <iterator>
-
-using namespace llvm;
-
-// Pin the vtable to this file.
-void MCAtom::anchor() {}
-
-void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
- Parent->remap(this, NewBegin, NewEnd);
-}
-
-void MCAtom::remapForTruncate(uint64_t TruncPt) {
- assert((TruncPt >= Begin && TruncPt < End) &&
- "Truncation point not contained in atom!");
- remap(Begin, TruncPt);
-}
-
-void MCAtom::remapForSplit(uint64_t SplitPt,
- uint64_t &LBegin, uint64_t &LEnd,
- uint64_t &RBegin, uint64_t &REnd) {
- assert((SplitPt > Begin && SplitPt <= End) &&
- "Splitting at point not contained in atom!");
-
- // Compute the new begin/end points.
- LBegin = Begin;
- LEnd = SplitPt - 1;
- RBegin = SplitPt;
- REnd = End;
-
- // Remap this atom to become the lower of the two new ones.
- remap(LBegin, LEnd);
-}
-
-// MCDataAtom
-
-void MCDataAtom::addData(const MCData &D) {
- Data.push_back(D);
- if (Data.size() > End + 1 - Begin)
- remap(Begin, End + 1);
-}
-
-void MCDataAtom::truncate(uint64_t TruncPt) {
- remapForTruncate(TruncPt);
-
- Data.resize(TruncPt - Begin + 1);
-}
-
-MCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
- uint64_t LBegin, LEnd, RBegin, REnd;
- remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
-
- MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
- RightAtom->setName(getName());
-
- std::vector<MCData>::iterator I = Data.begin() + (RBegin - LBegin);
- assert(I != Data.end() && "Split point not found in range!");
-
- std::copy(I, Data.end(), std::back_inserter(RightAtom->Data));
- Data.erase(I, Data.end());
- return RightAtom;
-}
-
-// MCTextAtom
-
-void MCTextAtom::addInst(const MCInst &I, uint64_t Size) {
- if (NextInstAddress + Size - 1 > End)
- remap(Begin, NextInstAddress + Size - 1);
- Insts.push_back(MCDecodedInst(I, NextInstAddress, Size));
- NextInstAddress += Size;
-}
-
-void MCTextAtom::truncate(uint64_t TruncPt) {
- remapForTruncate(TruncPt);
-
- InstListTy::iterator I = Insts.begin();
- while (I != Insts.end() && I->Address <= TruncPt) ++I;
-
- assert(I != Insts.end() && "Truncation point not found in disassembly!");
- assert(I->Address == TruncPt + 1 &&
- "Truncation point does not fall on instruction boundary");
-
- Insts.erase(I, Insts.end());
-}
-
-MCTextAtom *MCTextAtom::split(uint64_t SplitPt) {
- uint64_t LBegin, LEnd, RBegin, REnd;
- remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
-
- MCTextAtom *RightAtom = Parent->createTextAtom(RBegin, REnd);
- RightAtom->setName(getName());
-
- InstListTy::iterator I = Insts.begin();
- while (I != Insts.end() && I->Address < SplitPt) ++I;
- assert(I != Insts.end() && "Split point not found in disassembly!");
- assert(I->Address == SplitPt &&
- "Split point does not fall on instruction boundary!");
-
- std::copy(I, Insts.end(), std::back_inserter(RightAtom->Insts));
- Insts.erase(I, Insts.end());
- Parent->splitBasicBlocksForAtom(this, RightAtom);
- return RightAtom;
-}
diff --git a/lib/MC/MCAnalysis/MCFunction.cpp b/lib/MC/MCAnalysis/MCFunction.cpp
deleted file mode 100644
index 4e09d1a..0000000
--- a/lib/MC/MCAnalysis/MCFunction.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===-- lib/MC/MCFunction.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCAnalysis/MCFunction.h"
-#include "llvm/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCModule.h"
-#include <algorithm>
-
-using namespace llvm;
-
-// MCFunction
-
-MCFunction::MCFunction(StringRef Name, MCModule *Parent)
- : Name(Name), ParentModule(Parent)
-{}
-
-MCBasicBlock &MCFunction::createBlock(const MCTextAtom &TA) {
- std::unique_ptr<MCBasicBlock> MCBB(new MCBasicBlock(TA, this));
- Blocks.push_back(std::move(MCBB));
- return *Blocks.back();
-}
-
-MCBasicBlock *MCFunction::find(uint64_t StartAddr) {
- for (const_iterator I = begin(), E = end(); I != E; ++I)
- if ((*I)->getInsts()->getBeginAddr() == StartAddr)
- return I->get();
- return nullptr;
-}
-
-const MCBasicBlock *MCFunction::find(uint64_t StartAddr) const {
- return const_cast<MCFunction *>(this)->find(StartAddr);
-}
-
-// MCBasicBlock
-
-MCBasicBlock::MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent)
- : Insts(&Insts), Parent(Parent) {
- getParent()->getParent()->trackBBForAtom(&Insts, this);
-}
-
-void MCBasicBlock::addSuccessor(const MCBasicBlock *MCBB) {
- if (!isSuccessor(MCBB))
- Successors.push_back(MCBB);
-}
-
-bool MCBasicBlock::isSuccessor(const MCBasicBlock *MCBB) const {
- return std::find(Successors.begin(), Successors.end(),
- MCBB) != Successors.end();
-}
-
-void MCBasicBlock::addPredecessor(const MCBasicBlock *MCBB) {
- if (!isPredecessor(MCBB))
- Predecessors.push_back(MCBB);
-}
-
-bool MCBasicBlock::isPredecessor(const MCBasicBlock *MCBB) const {
- return std::find(Predecessors.begin(), Predecessors.end(),
- MCBB) != Predecessors.end();
-}
-
-void MCBasicBlock::splitBasicBlock(MCBasicBlock *SplitBB) {
- assert(Insts->getEndAddr() + 1 == SplitBB->Insts->getBeginAddr() &&
- "Splitting unrelated basic blocks!");
- SplitBB->addPredecessor(this);
- assert(SplitBB->Successors.empty() &&
- "Split basic block shouldn't already have successors!");
- SplitBB->Successors = Successors;
- Successors.clear();
- addSuccessor(SplitBB);
-}
diff --git a/lib/MC/MCAnalysis/MCModule.cpp b/lib/MC/MCAnalysis/MCModule.cpp
deleted file mode 100644
index 7512299..0000000
--- a/lib/MC/MCAnalysis/MCModule.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-//===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCAnalysis/MCModule.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCFunction.h"
-#include <algorithm>
-
-using namespace llvm;
-
-static bool AtomComp(const MCAtom *L, uint64_t Addr) {
- return L->getEndAddr() < Addr;
-}
-
-static bool AtomCompInv(uint64_t Addr, const MCAtom *R) {
- return Addr < R->getEndAddr();
-}
-
-void MCModule::map(MCAtom *NewAtom) {
- uint64_t Begin = NewAtom->Begin;
-
- assert(Begin <= NewAtom->End && "Creating MCAtom with endpoints reversed?");
-
- // Check for atoms already covering this range.
- AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
- Begin, AtomComp);
- assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End)
- && "Offset range already occupied!");
-
- // Insert the new atom to the list.
- Atoms.insert(I, NewAtom);
-}
-
-MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) {
- MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End);
- map(NewAtom);
- return NewAtom;
-}
-
-MCDataAtom *MCModule::createDataAtom(uint64_t Begin, uint64_t End) {
- MCDataAtom *NewAtom = new MCDataAtom(this, Begin, End);
- map(NewAtom);
- return NewAtom;
-}
-
-// remap - Update the interval mapping for an atom.
-void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) {
- // Find and erase the old mapping.
- AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
- Atom->Begin, AtomComp);
- assert(I != atom_end() && "Atom offset not found in module!");
- assert(*I == Atom && "Previous atom mapping was invalid!");
- Atoms.erase(I);
-
- // FIXME: special case NewBegin == Atom->Begin
-
- // Insert the new mapping.
- AtomListTy::iterator NewI = std::lower_bound(atom_begin(), atom_end(),
- NewBegin, AtomComp);
- assert((NewI == atom_end() || (*NewI)->getBeginAddr() > Atom->End)
- && "Offset range already occupied!");
- Atoms.insert(NewI, Atom);
-
- // Update the atom internal bounds.
- Atom->Begin = NewBegin;
- Atom->End = NewEnd;
-}
-
-const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const {
- AtomListTy::const_iterator I = std::lower_bound(atom_begin(), atom_end(),
- Addr, AtomComp);
- if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
- return *I;
- return nullptr;
-}
-
-MCAtom *MCModule::findAtomContaining(uint64_t Addr) {
- return const_cast<MCAtom*>(
- const_cast<const MCModule *>(this)->findAtomContaining(Addr));
-}
-
-const MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) const {
- AtomListTy::const_iterator I = std::upper_bound(atom_begin(), atom_end(),
- Addr, AtomCompInv);
- if (I != atom_end())
- return *I;
- return nullptr;
-}
-
-MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) {
- return const_cast<MCAtom*>(
- const_cast<const MCModule *>(this)->findFirstAtomAfter(Addr));
-}
-
-MCFunction *MCModule::createFunction(StringRef Name) {
- std::unique_ptr<MCFunction> MCF(new MCFunction(Name, this));
- Functions.push_back(std::move(MCF));
- return Functions.back().get();
-}
-
-static bool CompBBToAtom(MCBasicBlock *BB, const MCTextAtom *Atom) {
- return BB->getInsts() < Atom;
-}
-
-void MCModule::splitBasicBlocksForAtom(const MCTextAtom *TA,
- const MCTextAtom *NewTA) {
- BBsByAtomTy::iterator
- I = std::lower_bound(BBsByAtom.begin(), BBsByAtom.end(),
- TA, CompBBToAtom);
- for (; I != BBsByAtom.end() && (*I)->getInsts() == TA; ++I) {
- MCBasicBlock *BB = *I;
- MCBasicBlock *NewBB = &BB->getParent()->createBlock(*NewTA);
- BB->splitBasicBlock(NewBB);
- }
-}
-
-void MCModule::trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BB) {
- assert(Atom == BB->getInsts() && "Text atom doesn't back the basic block!");
- BBsByAtomTy::iterator I = std::lower_bound(BBsByAtom.begin(),
- BBsByAtom.end(),
- Atom, CompBBToAtom);
- for (; I != BBsByAtom.end() && (*I)->getInsts() == Atom; ++I)
- if (*I == BB)
- return;
- BBsByAtom.insert(I, BB);
-}
-
-MCModule::MCModule() : Entrypoint(0) { }
-
-MCModule::~MCModule() {
- for (AtomListTy::iterator AI = atom_begin(),
- AE = atom_end();
- AI != AE; ++AI)
- delete *AI;
-}
diff --git a/lib/MC/MCAnalysis/MCModuleYAML.cpp b/lib/MC/MCAnalysis/MCModuleYAML.cpp
deleted file mode 100644
index 876b06d..0000000
--- a/lib/MC/MCAnalysis/MCModuleYAML.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-//===- MCModuleYAML.cpp - MCModule YAMLIO implementation ------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines classes for handling the YAML representation of MCModule.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCAnalysis/MCModuleYAML.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCFunction.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/YAML.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/YAMLTraits.h"
-#include <vector>
-
-namespace llvm {
-
-namespace {
-
-// This class is used to map opcode and register names to enum values.
-//
-// There are at least 3 obvious ways to do this:
-// 1- Generate an MII/MRI method using a tablegen StringMatcher
-// 2- Write an MII/MRI method using std::lower_bound and the assumption that
-// the enums are sorted (starting at a fixed value).
-// 3- Do the matching manually as is done here.
-//
-// Why 3?
-// 1- A StringMatcher function for thousands of entries would incur
-// a non-negligible binary size overhead.
-// 2- The lower_bound comparators would be somewhat involved and aren't
-// obviously reusable (see LessRecordRegister in llvm/TableGen/Record.h)
-// 3- This isn't actually something useful outside tests (but the same argument
-// can be made against having {MII,MRI}::getName).
-//
-// If this becomes useful outside this specific situation, feel free to do
-// the Right Thing (tm) and move the functionality to MII/MRI.
-//
-class InstrRegInfoHolder {
- typedef StringMap<unsigned, BumpPtrAllocator> EnumValByNameTy;
- EnumValByNameTy InstEnumValueByName;
- EnumValByNameTy RegEnumValueByName;
-
-public:
- const MCInstrInfo &MII;
- const MCRegisterInfo &MRI;
- InstrRegInfoHolder(const MCInstrInfo &MII, const MCRegisterInfo &MRI)
- : InstEnumValueByName(NextPowerOf2(MII.getNumOpcodes())),
- RegEnumValueByName(NextPowerOf2(MRI.getNumRegs())), MII(MII), MRI(MRI) {
- for (int i = 0, e = MII.getNumOpcodes(); i != e; ++i)
- InstEnumValueByName[MII.getName(i)] = i;
- for (int i = 0, e = MRI.getNumRegs(); i != e; ++i)
- RegEnumValueByName[MRI.getName(i)] = i;
- }
-
- bool matchRegister(StringRef Name, unsigned &Reg) {
- EnumValByNameTy::const_iterator It = RegEnumValueByName.find(Name);
- if (It == RegEnumValueByName.end())
- return false;
- Reg = It->getValue();
- return true;
- }
- bool matchOpcode(StringRef Name, unsigned &Opc) {
- EnumValByNameTy::const_iterator It = InstEnumValueByName.find(Name);
- if (It == InstEnumValueByName.end())
- return false;
- Opc = It->getValue();
- return true;
- }
-};
-
-} // end unnamed namespace
-
-namespace MCModuleYAML {
-
-LLVM_YAML_STRONG_TYPEDEF(unsigned, OpcodeEnum)
-
-struct Operand {
- MCOperand MCOp;
-};
-
-struct Inst {
- OpcodeEnum Opcode;
- std::vector<Operand> Operands;
- uint64_t Size;
-};
-
-struct Atom {
- MCAtom::AtomKind Type;
- yaml::Hex64 StartAddress;
- uint64_t Size;
-
- std::vector<Inst> Insts;
- yaml::BinaryRef Data;
-};
-
-struct BasicBlock {
- yaml::Hex64 Address;
- std::vector<yaml::Hex64> Preds;
- std::vector<yaml::Hex64> Succs;
-};
-
-struct Function {
- StringRef Name;
- std::vector<BasicBlock> BasicBlocks;
-};
-
-struct Module {
- std::vector<Atom> Atoms;
- std::vector<Function> Functions;
-};
-
-} // end namespace MCModuleYAML
-} // end namespace llvm
-
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::MCModuleYAML::Operand)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Inst)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Atom)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::BasicBlock)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MCModuleYAML::Function)
-
-namespace llvm {
-
-namespace yaml {
-
-template <> struct ScalarEnumerationTraits<MCAtom::AtomKind> {
- static void enumeration(IO &IO, MCAtom::AtomKind &Kind);
-};
-
-template <> struct MappingTraits<MCModuleYAML::Atom> {
- static void mapping(IO &IO, MCModuleYAML::Atom &A);
-};
-
-template <> struct MappingTraits<MCModuleYAML::Inst> {
- static void mapping(IO &IO, MCModuleYAML::Inst &I);
-};
-
-template <> struct MappingTraits<MCModuleYAML::BasicBlock> {
- static void mapping(IO &IO, MCModuleYAML::BasicBlock &BB);
-};
-
-template <> struct MappingTraits<MCModuleYAML::Function> {
- static void mapping(IO &IO, MCModuleYAML::Function &Fn);
-};
-
-template <> struct MappingTraits<MCModuleYAML::Module> {
- static void mapping(IO &IO, MCModuleYAML::Module &M);
-};
-
-template <> struct ScalarTraits<MCModuleYAML::Operand> {
- static void output(const MCModuleYAML::Operand &, void *,
- llvm::raw_ostream &);
- static StringRef input(StringRef, void *, MCModuleYAML::Operand &);
- static bool mustQuote(StringRef) { return false; }
-};
-
-template <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> {
- static void output(const MCModuleYAML::OpcodeEnum &, void *,
- llvm::raw_ostream &);
- static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
- static bool mustQuote(StringRef) { return false; }
-};
-
-void ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration(
- IO &IO, MCAtom::AtomKind &Value) {
- IO.enumCase(Value, "Text", MCAtom::TextAtom);
- IO.enumCase(Value, "Data", MCAtom::DataAtom);
-}
-
-void MappingTraits<MCModuleYAML::Atom>::mapping(IO &IO, MCModuleYAML::Atom &A) {
- IO.mapRequired("StartAddress", A.StartAddress);
- IO.mapRequired("Size", A.Size);
- IO.mapRequired("Type", A.Type);
- if (A.Type == MCAtom::TextAtom)
- IO.mapRequired("Content", A.Insts);
- else if (A.Type == MCAtom::DataAtom)
- IO.mapRequired("Content", A.Data);
-}
-
-void MappingTraits<MCModuleYAML::Inst>::mapping(IO &IO, MCModuleYAML::Inst &I) {
- IO.mapRequired("Inst", I.Opcode);
- IO.mapRequired("Size", I.Size);
- IO.mapRequired("Ops", I.Operands);
-}
-
-void
-MappingTraits<MCModuleYAML::BasicBlock>::mapping(IO &IO,
- MCModuleYAML::BasicBlock &BB) {
- IO.mapRequired("Address", BB.Address);
- IO.mapRequired("Preds", BB.Preds);
- IO.mapRequired("Succs", BB.Succs);
-}
-
-void MappingTraits<MCModuleYAML::Function>::mapping(IO &IO,
- MCModuleYAML::Function &F) {
- IO.mapRequired("Name", F.Name);
- IO.mapRequired("BasicBlocks", F.BasicBlocks);
-}
-
-void MappingTraits<MCModuleYAML::Module>::mapping(IO &IO,
- MCModuleYAML::Module &M) {
- IO.mapRequired("Atoms", M.Atoms);
- IO.mapOptional("Functions", M.Functions);
-}
-
-void
-ScalarTraits<MCModuleYAML::Operand>::output(const MCModuleYAML::Operand &Val,
- void *Ctx, raw_ostream &Out) {
- InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
-
- // FIXME: Doesn't support FPImm and expr/inst, but do these make sense?
- if (Val.MCOp.isImm())
- Out << "I" << Val.MCOp.getImm();
- else if (Val.MCOp.isReg())
- Out << "R" << IRI->MRI.getName(Val.MCOp.getReg());
- else
- llvm_unreachable("Trying to output invalid MCOperand!");
-}
-
-StringRef
-ScalarTraits<MCModuleYAML::Operand>::input(StringRef Scalar, void *Ctx,
- MCModuleYAML::Operand &Val) {
- InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
- char Type = 0;
- if (Scalar.size() >= 1)
- Type = Scalar.front();
- if (Type != 'R' && Type != 'I')
- return "Operand must start with 'R' (register) or 'I' (immediate).";
- if (Type == 'R') {
- unsigned Reg;
- if (!IRI->matchRegister(Scalar.substr(1), Reg))
- return "Invalid register name.";
- Val.MCOp = MCOperand::CreateReg(Reg);
- } else if (Type == 'I') {
- int64_t RIVal;
- if (Scalar.substr(1).getAsInteger(10, RIVal))
- return "Invalid immediate value.";
- Val.MCOp = MCOperand::CreateImm(RIVal);
- } else {
- Val.MCOp = MCOperand();
- }
- return StringRef();
-}
-
-void ScalarTraits<MCModuleYAML::OpcodeEnum>::output(
- const MCModuleYAML::OpcodeEnum &Val, void *Ctx, raw_ostream &Out) {
- InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
- Out << IRI->MII.getName(Val);
-}
-
-StringRef
-ScalarTraits<MCModuleYAML::OpcodeEnum>::input(StringRef Scalar, void *Ctx,
- MCModuleYAML::OpcodeEnum &Val) {
- InstrRegInfoHolder *IRI = (InstrRegInfoHolder *)Ctx;
- unsigned Opc;
- if (!IRI->matchOpcode(Scalar, Opc))
- return "Invalid instruction opcode.";
- Val = Opc;
- return "";
-}
-
-} // end namespace yaml
-
-namespace {
-
-class MCModule2YAML {
- const MCModule &MCM;
- MCModuleYAML::Module YAMLModule;
- void dumpAtom(const MCAtom *MCA);
- void dumpFunction(const MCFunction &MCF);
- void dumpBasicBlock(const MCBasicBlock *MCBB);
-
-public:
- MCModule2YAML(const MCModule &MCM);
- MCModuleYAML::Module &getYAMLModule();
-};
-
-class YAML2MCModule {
- MCModule &MCM;
-
-public:
- YAML2MCModule(MCModule &MCM);
- StringRef parse(const MCModuleYAML::Module &YAMLModule);
-};
-
-} // end unnamed namespace
-
-MCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() {
- for (MCModule::const_atom_iterator AI = MCM.atom_begin(), AE = MCM.atom_end();
- AI != AE; ++AI)
- dumpAtom(*AI);
- for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end();
- FI != FE; ++FI)
- dumpFunction(**FI);
-}
-
-void MCModule2YAML::dumpAtom(const MCAtom *MCA) {
- YAMLModule.Atoms.resize(YAMLModule.Atoms.size() + 1);
- MCModuleYAML::Atom &A = YAMLModule.Atoms.back();
- A.Type = MCA->getKind();
- A.StartAddress = MCA->getBeginAddr();
- A.Size = MCA->getEndAddr() - MCA->getBeginAddr() + 1;
- if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(MCA)) {
- const size_t InstCount = TA->size();
- A.Insts.resize(InstCount);
- for (size_t i = 0; i != InstCount; ++i) {
- const MCDecodedInst &MCDI = TA->at(i);
- A.Insts[i].Opcode = MCDI.Inst.getOpcode();
- A.Insts[i].Size = MCDI.Size;
- const unsigned OpCount = MCDI.Inst.getNumOperands();
- A.Insts[i].Operands.resize(OpCount);
- for (unsigned oi = 0; oi != OpCount; ++oi)
- A.Insts[i].Operands[oi].MCOp = MCDI.Inst.getOperand(oi);
- }
- } else if (const MCDataAtom *DA = dyn_cast<MCDataAtom>(MCA)) {
- A.Data = DA->getData();
- } else {
- llvm_unreachable("Unknown atom type.");
- }
-}
-
-void MCModule2YAML::dumpFunction(const MCFunction &MCF) {
- YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1);
- MCModuleYAML::Function &F = YAMLModule.Functions.back();
- F.Name = MCF.getName();
- for (MCFunction::const_iterator BBI = MCF.begin(), BBE = MCF.end();
- BBI != BBE; ++BBI) {
- const MCBasicBlock &MCBB = **BBI;
- F.BasicBlocks.resize(F.BasicBlocks.size() + 1);
- MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back();
- BB.Address = MCBB.getInsts()->getBeginAddr();
- for (MCBasicBlock::pred_const_iterator PI = MCBB.pred_begin(),
- PE = MCBB.pred_end();
- PI != PE; ++PI)
- BB.Preds.push_back((*PI)->getInsts()->getBeginAddr());
- for (MCBasicBlock::succ_const_iterator SI = MCBB.succ_begin(),
- SE = MCBB.succ_end();
- SI != SE; ++SI)
- BB.Succs.push_back((*SI)->getInsts()->getBeginAddr());
- }
-}
-
-MCModuleYAML::Module &MCModule2YAML::getYAMLModule() { return YAMLModule; }
-
-YAML2MCModule::YAML2MCModule(MCModule &MCM) : MCM(MCM) {}
-
-StringRef YAML2MCModule::parse(const MCModuleYAML::Module &YAMLModule) {
- typedef std::vector<MCModuleYAML::Atom>::const_iterator AtomIt;
- typedef std::vector<MCModuleYAML::Inst>::const_iterator InstIt;
- typedef std::vector<MCModuleYAML::Operand>::const_iterator OpIt;
-
- typedef DenseMap<uint64_t, MCTextAtom *> AddrToTextAtomTy;
- AddrToTextAtomTy TAByAddr;
-
- for (AtomIt AI = YAMLModule.Atoms.begin(), AE = YAMLModule.Atoms.end();
- AI != AE; ++AI) {
- uint64_t StartAddress = AI->StartAddress;
- if (AI->Size == 0)
- return "Atoms can't be empty!";
- uint64_t EndAddress = StartAddress + AI->Size - 1;
- switch (AI->Type) {
- case MCAtom::TextAtom: {
- MCTextAtom *TA = MCM.createTextAtom(StartAddress, EndAddress);
- TAByAddr[StartAddress] = TA;
- for (InstIt II = AI->Insts.begin(), IE = AI->Insts.end(); II != IE;
- ++II) {
- MCInst MI;
- MI.setOpcode(II->Opcode);
- for (OpIt OI = II->Operands.begin(), OE = II->Operands.end(); OI != OE;
- ++OI)
- MI.addOperand(OI->MCOp);
- TA->addInst(MI, II->Size);
- }
- break;
- }
- case MCAtom::DataAtom: {
- MCDataAtom *DA = MCM.createDataAtom(StartAddress, EndAddress);
- SmallVector<char, 64> Data;
- raw_svector_ostream OS(Data);
- AI->Data.writeAsBinary(OS);
- OS.flush();
- for (size_t i = 0, e = Data.size(); i != e; ++i)
- DA->addData((uint8_t)Data[i]);
- break;
- }
- }
- }
-
- typedef std::vector<MCModuleYAML::Function>::const_iterator FuncIt;
- typedef std::vector<MCModuleYAML::BasicBlock>::const_iterator BBIt;
- typedef std::vector<yaml::Hex64>::const_iterator AddrIt;
- for (FuncIt FI = YAMLModule.Functions.begin(),
- FE = YAMLModule.Functions.end();
- FI != FE; ++FI) {
- MCFunction *MCFN = MCM.createFunction(FI->Name);
- for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
- BBI != BBE; ++BBI) {
- AddrToTextAtomTy::const_iterator It = TAByAddr.find(BBI->Address);
- if (It == TAByAddr.end())
- return "Basic block start address doesn't match any text atom!";
- MCFN->createBlock(*It->second);
- }
- for (BBIt BBI = FI->BasicBlocks.begin(), BBE = FI->BasicBlocks.end();
- BBI != BBE; ++BBI) {
- MCBasicBlock *MCBB = MCFN->find(BBI->Address);
- if (!MCBB)
- return "Couldn't find matching basic block in function.";
- for (AddrIt PI = BBI->Preds.begin(), PE = BBI->Preds.end(); PI != PE;
- ++PI) {
- MCBasicBlock *Pred = MCFN->find(*PI);
- if (!Pred)
- return "Couldn't find predecessor basic block.";
- MCBB->addPredecessor(Pred);
- }
- for (AddrIt SI = BBI->Succs.begin(), SE = BBI->Succs.end(); SI != SE;
- ++SI) {
- MCBasicBlock *Succ = MCFN->find(*SI);
- if (!Succ)
- return "Couldn't find predecessor basic block.";
- MCBB->addSuccessor(Succ);
- }
- }
- }
- return "";
-}
-
-StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
- const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
- MCModule2YAML Dumper(MCM);
- InstrRegInfoHolder IRI(MII, MRI);
- yaml::Output YOut(OS, (void *)&IRI);
- YOut << Dumper.getYAMLModule();
- return "";
-}
-
-StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
- const MCInstrInfo &MII, const MCRegisterInfo &MRI) {
- MCM.reset(new MCModule);
- YAML2MCModule Parser(*MCM);
- MCModuleYAML::Module YAMLModule;
- InstrRegInfoHolder IRI(MII, MRI);
- yaml::Input YIn(YamlContent, (void *)&IRI);
- YIn >> YAMLModule;
- if (std::error_code ec = YIn.error())
- return ec.message();
- StringRef err = Parser.parse(YAMLModule);
- if (!err.empty())
- return err;
- return "";
-}
-
-} // end namespace llvm
diff --git a/lib/MC/MCAnalysis/MCObjectDisassembler.cpp b/lib/MC/MCAnalysis/MCObjectDisassembler.cpp
deleted file mode 100644
index 0f789ff..0000000
--- a/lib/MC/MCAnalysis/MCObjectDisassembler.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-//===- lib/MC/MCObjectDisassembler.cpp ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCObjectDisassembler.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCFunction.h"
-#include "llvm/MC/MCAnalysis/MCModule.h"
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCInstrAnalysis.h"
-#include "llvm/MC/MCObjectSymbolizer.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MachO.h"
-#include "llvm/Support/MemoryObject.h"
-#include "llvm/Support/StringRefMemoryObject.h"
-#include "llvm/Support/raw_ostream.h"
-#include <map>
-
-using namespace llvm;
-using namespace object;
-
-#define DEBUG_TYPE "mc"
-
-MCObjectDisassembler::MCObjectDisassembler(const ObjectFile &Obj,
- const MCDisassembler &Dis,
- const MCInstrAnalysis &MIA)
- : Obj(Obj), Dis(Dis), MIA(MIA), MOS(nullptr) {}
-
-uint64_t MCObjectDisassembler::getEntrypoint() {
- for (const SymbolRef &Symbol : Obj.symbols()) {
- StringRef Name;
- Symbol.getName(Name);
- if (Name == "main" || Name == "_main") {
- uint64_t Entrypoint;
- Symbol.getAddress(Entrypoint);
- return getEffectiveLoadAddr(Entrypoint);
- }
- }
- return 0;
-}
-
-ArrayRef<uint64_t> MCObjectDisassembler::getStaticInitFunctions() {
- return ArrayRef<uint64_t>();
-}
-
-ArrayRef<uint64_t> MCObjectDisassembler::getStaticExitFunctions() {
- return ArrayRef<uint64_t>();
-}
-
-MemoryObject *MCObjectDisassembler::getRegionFor(uint64_t Addr) {
- // FIXME: Keep track of object sections.
- return FallbackRegion.get();
-}
-
-uint64_t MCObjectDisassembler::getEffectiveLoadAddr(uint64_t Addr) {
- return Addr;
-}
-
-uint64_t MCObjectDisassembler::getOriginalLoadAddr(uint64_t Addr) {
- return Addr;
-}
-
-MCModule *MCObjectDisassembler::buildEmptyModule() {
- MCModule *Module = new MCModule;
- Module->Entrypoint = getEntrypoint();
- return Module;
-}
-
-MCModule *MCObjectDisassembler::buildModule(bool withCFG) {
- MCModule *Module = buildEmptyModule();
-
- buildSectionAtoms(Module);
- if (withCFG)
- buildCFG(Module);
- return Module;
-}
-
-void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) {
- for (const SectionRef &Section : Obj.sections()) {
- bool isText;
- Section.isText(isText);
- bool isData;
- Section.isData(isData);
- if (!isData && !isText)
- continue;
-
- uint64_t StartAddr;
- Section.getAddress(StartAddr);
- uint64_t SecSize;
- Section.getSize(SecSize);
- if (StartAddr == UnknownAddressOrSize || SecSize == UnknownAddressOrSize)
- continue;
- StartAddr = getEffectiveLoadAddr(StartAddr);
-
- StringRef Contents;
- Section.getContents(Contents);
- StringRefMemoryObject memoryObject(Contents, StartAddr);
-
- // We don't care about things like non-file-backed sections yet.
- if (Contents.size() != SecSize || !SecSize)
- continue;
- uint64_t EndAddr = StartAddr + SecSize - 1;
-
- StringRef SecName;
- Section.getName(SecName);
-
- if (isText) {
- MCTextAtom *Text = nullptr;
- MCDataAtom *InvalidData = nullptr;
-
- uint64_t InstSize;
- for (uint64_t Index = 0; Index < SecSize; Index += InstSize) {
- const uint64_t CurAddr = StartAddr + Index;
- MCInst Inst;
- if (Dis.getInstruction(Inst, InstSize, memoryObject, CurAddr, nulls(),
- nulls())) {
- if (!Text) {
- Text = Module->createTextAtom(CurAddr, CurAddr);
- Text->setName(SecName);
- }
- Text->addInst(Inst, InstSize);
- InvalidData = nullptr;
- } else {
- assert(InstSize && "getInstruction() consumed no bytes");
- if (!InvalidData) {
- Text = nullptr;
- InvalidData = Module->createDataAtom(CurAddr, CurAddr+InstSize - 1);
- }
- for (uint64_t I = 0; I < InstSize; ++I)
- InvalidData->addData(Contents[Index+I]);
- }
- }
- } else {
- MCDataAtom *Data = Module->createDataAtom(StartAddr, EndAddr);
- Data->setName(SecName);
- for (uint64_t Index = 0; Index < SecSize; ++Index)
- Data->addData(Contents[Index]);
- }
- }
-}
-
-namespace {
- struct BBInfo;
- typedef SmallPtrSet<BBInfo*, 2> BBInfoSetTy;
-
- struct BBInfo {
- MCTextAtom *Atom;
- MCBasicBlock *BB;
- BBInfoSetTy Succs;
- BBInfoSetTy Preds;
- MCObjectDisassembler::AddressSetTy SuccAddrs;
-
- BBInfo() : Atom(nullptr), BB(nullptr) {}
-
- void addSucc(BBInfo &Succ) {
- Succs.insert(&Succ);
- Succ.Preds.insert(this);
- }
- };
-}
-
-static void RemoveDupsFromAddressVector(MCObjectDisassembler::AddressSetTy &V) {
- std::sort(V.begin(), V.end());
- V.erase(std::unique(V.begin(), V.end()), V.end());
-}
-
-void MCObjectDisassembler::buildCFG(MCModule *Module) {
- typedef std::map<uint64_t, BBInfo> BBInfoByAddrTy;
- BBInfoByAddrTy BBInfos;
- AddressSetTy Splits;
- AddressSetTy Calls;
-
- for (const SymbolRef &Symbol : Obj.symbols()) {
- SymbolRef::Type SymType;
- Symbol.getType(SymType);
- if (SymType == SymbolRef::ST_Function) {
- uint64_t SymAddr;
- Symbol.getAddress(SymAddr);
- SymAddr = getEffectiveLoadAddr(SymAddr);
- Calls.push_back(SymAddr);
- Splits.push_back(SymAddr);
- }
- }
-
- assert(Module->func_begin() == Module->func_end()
- && "Module already has a CFG!");
-
- // First, determine the basic block boundaries and call targets.
- for (MCModule::atom_iterator AI = Module->atom_begin(),
- AE = Module->atom_end();
- AI != AE; ++AI) {
- MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI);
- if (!TA) continue;
- Calls.push_back(TA->getBeginAddr());
- BBInfos[TA->getBeginAddr()].Atom = TA;
- for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end();
- II != IE; ++II) {
- if (MIA.isTerminator(II->Inst))
- Splits.push_back(II->Address + II->Size);
- uint64_t Target;
- if (MIA.evaluateBranch(II->Inst, II->Address, II->Size, Target)) {
- if (MIA.isCall(II->Inst))
- Calls.push_back(Target);
- Splits.push_back(Target);
- }
- }
- }
-
- RemoveDupsFromAddressVector(Splits);
- RemoveDupsFromAddressVector(Calls);
-
- // Split text atoms into basic block atoms.
- for (AddressSetTy::const_iterator SI = Splits.begin(), SE = Splits.end();
- SI != SE; ++SI) {
- MCAtom *A = Module->findAtomContaining(*SI);
- if (!A) continue;
- MCTextAtom *TA = cast<MCTextAtom>(A);
- if (TA->getBeginAddr() == *SI)
- continue;
- MCTextAtom *NewAtom = TA->split(*SI);
- BBInfos[NewAtom->getBeginAddr()].Atom = NewAtom;
- StringRef BBName = TA->getName();
- BBName = BBName.substr(0, BBName.find_last_of(':'));
- NewAtom->setName((BBName + ":" + utohexstr(*SI)).str());
- }
-
- // Compute succs/preds.
- for (MCModule::atom_iterator AI = Module->atom_begin(),
- AE = Module->atom_end();
- AI != AE; ++AI) {
- MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI);
- if (!TA) continue;
- BBInfo &CurBB = BBInfos[TA->getBeginAddr()];
- const MCDecodedInst &LI = TA->back();
- if (MIA.isBranch(LI.Inst)) {
- uint64_t Target;
- if (MIA.evaluateBranch(LI.Inst, LI.Address, LI.Size, Target))
- CurBB.addSucc(BBInfos[Target]);
- if (MIA.isConditionalBranch(LI.Inst))
- CurBB.addSucc(BBInfos[LI.Address + LI.Size]);
- } else if (!MIA.isTerminator(LI.Inst))
- CurBB.addSucc(BBInfos[LI.Address + LI.Size]);
- }
-
-
- // Create functions and basic blocks.
- for (AddressSetTy::const_iterator CI = Calls.begin(), CE = Calls.end();
- CI != CE; ++CI) {
- BBInfo &BBI = BBInfos[*CI];
- if (!BBI.Atom) continue;
-
- MCFunction &MCFN = *Module->createFunction(BBI.Atom->getName());
-
- // Create MCBBs.
- SmallSetVector<BBInfo*, 16> Worklist;
- Worklist.insert(&BBI);
- for (size_t wi = 0; wi < Worklist.size(); ++wi) {
- BBInfo *BBI = Worklist[wi];
- if (!BBI->Atom)
- continue;
- BBI->BB = &MCFN.createBlock(*BBI->Atom);
- // Add all predecessors and successors to the worklist.
- for (BBInfoSetTy::iterator SI = BBI->Succs.begin(), SE = BBI->Succs.end();
- SI != SE; ++SI)
- Worklist.insert(*SI);
- for (BBInfoSetTy::iterator PI = BBI->Preds.begin(), PE = BBI->Preds.end();
- PI != PE; ++PI)
- Worklist.insert(*PI);
- }
-
- // Set preds/succs.
- for (size_t wi = 0; wi < Worklist.size(); ++wi) {
- BBInfo *BBI = Worklist[wi];
- MCBasicBlock *MCBB = BBI->BB;
- if (!MCBB)
- continue;
- for (BBInfoSetTy::iterator SI = BBI->Succs.begin(), SE = BBI->Succs.end();
- SI != SE; ++SI)
- if ((*SI)->BB)
- MCBB->addSuccessor((*SI)->BB);
- for (BBInfoSetTy::iterator PI = BBI->Preds.begin(), PE = BBI->Preds.end();
- PI != PE; ++PI)
- if ((*PI)->BB)
- MCBB->addPredecessor((*PI)->BB);
- }
- }
-}
-
-// Basic idea of the disassembly + discovery:
-//
-// start with the wanted address, insert it in the worklist
-// while worklist not empty, take next address in the worklist:
-// - check if atom exists there
-// - if middle of atom:
-// - split basic blocks referencing the atom
-// - look for an already encountered BBInfo (using a map<atom, bbinfo>)
-// - if there is, split it (new one, fallthrough, move succs, etc..)
-// - if start of atom: nothing else to do
-// - if no atom: create new atom and new bbinfo
-// - look at the last instruction in the atom, add succs to worklist
-// for all elements in the worklist:
-// - create basic block, update preds/succs, etc..
-//
-MCBasicBlock *MCObjectDisassembler::getBBAt(MCModule *Module, MCFunction *MCFN,
- uint64_t BBBeginAddr,
- AddressSetTy &CallTargets,
- AddressSetTy &TailCallTargets) {
- typedef std::map<uint64_t, BBInfo> BBInfoByAddrTy;
- typedef SmallSetVector<uint64_t, 16> AddrWorklistTy;
- BBInfoByAddrTy BBInfos;
- AddrWorklistTy Worklist;
-
- Worklist.insert(BBBeginAddr);
- for (size_t wi = 0; wi < Worklist.size(); ++wi) {
- const uint64_t BeginAddr = Worklist[wi];
- BBInfo *BBI = &BBInfos[BeginAddr];
-
- MCTextAtom *&TA = BBI->Atom;
- assert(!TA && "Discovered basic block already has an associated atom!");
-
- // Look for an atom at BeginAddr.
- if (MCAtom *A = Module->findAtomContaining(BeginAddr)) {
- // FIXME: We don't care about mixed atoms, see above.
- TA = cast<MCTextAtom>(A);
-
- // The found atom doesn't begin at BeginAddr, we have to split it.
- if (TA->getBeginAddr() != BeginAddr) {
- // FIXME: Handle overlapping atoms: middle-starting instructions, etc..
- MCTextAtom *NewTA = TA->split(BeginAddr);
-
- // Look for an already encountered basic block that needs splitting
- BBInfoByAddrTy::iterator It = BBInfos.find(TA->getBeginAddr());
- if (It != BBInfos.end() && It->second.Atom) {
- BBI->SuccAddrs = It->second.SuccAddrs;
- It->second.SuccAddrs.clear();
- It->second.SuccAddrs.push_back(BeginAddr);
- }
- TA = NewTA;
- }
- BBI->Atom = TA;
- } else {
- // If we didn't find an atom, then we have to disassemble to create one!
-
- MemoryObject *Region = getRegionFor(BeginAddr);
- if (!Region)
- llvm_unreachable(("Couldn't find suitable region for disassembly at " +
- utostr(BeginAddr)).c_str());
-
- uint64_t InstSize;
- uint64_t EndAddr = Region->getBase() + Region->getExtent();
-
- // We want to stop before the next atom and have a fallthrough to it.
- if (MCTextAtom *NextAtom =
- cast_or_null<MCTextAtom>(Module->findFirstAtomAfter(BeginAddr)))
- EndAddr = std::min(EndAddr, NextAtom->getBeginAddr());
-
- for (uint64_t Addr = BeginAddr; Addr < EndAddr; Addr += InstSize) {
- MCInst Inst;
- if (Dis.getInstruction(Inst, InstSize, *Region, Addr, nulls(),
- nulls())) {
- if (!TA)
- TA = Module->createTextAtom(Addr, Addr);
- TA->addInst(Inst, InstSize);
- } else {
- // We don't care about splitting mixed atoms either.
- llvm_unreachable("Couldn't disassemble instruction in atom.");
- }
-
- uint64_t BranchTarget;
- if (MIA.evaluateBranch(Inst, Addr, InstSize, BranchTarget)) {
- if (MIA.isCall(Inst))
- CallTargets.push_back(BranchTarget);
- }
-
- if (MIA.isTerminator(Inst))
- break;
- }
- BBI->Atom = TA;
- }
-
- assert(TA && "Couldn't disassemble atom, none was created!");
- assert(TA->begin() != TA->end() && "Empty atom!");
-
- MemoryObject *Region = getRegionFor(TA->getBeginAddr());
- assert(Region && "Couldn't find region for already disassembled code!");
- uint64_t EndRegion = Region->getBase() + Region->getExtent();
-
- // Now we have a basic block atom, add successors.
- // Add the fallthrough block.
- if ((MIA.isConditionalBranch(TA->back().Inst) ||
- !MIA.isTerminator(TA->back().Inst)) &&
- (TA->getEndAddr() + 1 < EndRegion)) {
- BBI->SuccAddrs.push_back(TA->getEndAddr() + 1);
- Worklist.insert(TA->getEndAddr() + 1);
- }
-
- // If the terminator is a branch, add the target block.
- if (MIA.isBranch(TA->back().Inst)) {
- uint64_t BranchTarget;
- if (MIA.evaluateBranch(TA->back().Inst, TA->back().Address,
- TA->back().Size, BranchTarget)) {
- StringRef ExtFnName;
- if (MOS)
- ExtFnName =
- MOS->findExternalFunctionAt(getOriginalLoadAddr(BranchTarget));
- if (!ExtFnName.empty()) {
- TailCallTargets.push_back(BranchTarget);
- CallTargets.push_back(BranchTarget);
- } else {
- BBI->SuccAddrs.push_back(BranchTarget);
- Worklist.insert(BranchTarget);
- }
- }
- }
- }
-
- for (size_t wi = 0, we = Worklist.size(); wi != we; ++wi) {
- const uint64_t BeginAddr = Worklist[wi];
- BBInfo *BBI = &BBInfos[BeginAddr];
-
- assert(BBI->Atom && "Found a basic block without an associated atom!");
-
- // Look for a basic block at BeginAddr.
- BBI->BB = MCFN->find(BeginAddr);
- if (BBI->BB) {
- // FIXME: check that the succs/preds are the same
- continue;
- }
- // If there was none, we have to create one from the atom.
- BBI->BB = &MCFN->createBlock(*BBI->Atom);
- }
-
- for (size_t wi = 0, we = Worklist.size(); wi != we; ++wi) {
- const uint64_t BeginAddr = Worklist[wi];
- BBInfo *BBI = &BBInfos[BeginAddr];
- MCBasicBlock *BB = BBI->BB;
-
- RemoveDupsFromAddressVector(BBI->SuccAddrs);
- for (AddressSetTy::const_iterator SI = BBI->SuccAddrs.begin(),
- SE = BBI->SuccAddrs.end();
- SE != SE; ++SI) {
- MCBasicBlock *Succ = BBInfos[*SI].BB;
- BB->addSuccessor(Succ);
- Succ->addPredecessor(BB);
- }
- }
-
- assert(BBInfos[Worklist[0]].BB &&
- "No basic block created at requested address?");
-
- return BBInfos[Worklist[0]].BB;
-}
-
-MCFunction *
-MCObjectDisassembler::createFunction(MCModule *Module, uint64_t BeginAddr,
- AddressSetTy &CallTargets,
- AddressSetTy &TailCallTargets) {
- // First, check if this is an external function.
- StringRef ExtFnName;
- if (MOS)
- ExtFnName = MOS->findExternalFunctionAt(getOriginalLoadAddr(BeginAddr));
- if (!ExtFnName.empty())
- return Module->createFunction(ExtFnName);
-
- // If it's not, look for an existing function.
- for (MCModule::func_iterator FI = Module->func_begin(),
- FE = Module->func_end();
- FI != FE; ++FI) {
- if ((*FI)->empty())
- continue;
- // FIXME: MCModule should provide a findFunctionByAddr()
- if ((*FI)->getEntryBlock()->getInsts()->getBeginAddr() == BeginAddr)
- return FI->get();
- }
-
- // Finally, just create a new one.
- MCFunction *MCFN = Module->createFunction("");
- getBBAt(Module, MCFN, BeginAddr, CallTargets, TailCallTargets);
- return MCFN;
-}
-
-// MachO MCObjectDisassembler implementation.
-
-MCMachOObjectDisassembler::MCMachOObjectDisassembler(
- const MachOObjectFile &MOOF, const MCDisassembler &Dis,
- const MCInstrAnalysis &MIA, uint64_t VMAddrSlide,
- uint64_t HeaderLoadAddress)
- : MCObjectDisassembler(MOOF, Dis, MIA), MOOF(MOOF),
- VMAddrSlide(VMAddrSlide), HeaderLoadAddress(HeaderLoadAddress) {
-
- for (const SectionRef &Section : MOOF.sections()) {
- StringRef Name;
- Section.getName(Name);
- // FIXME: We should use the S_ section type instead of the name.
- if (Name == "__mod_init_func") {
- DEBUG(dbgs() << "Found __mod_init_func section!\n");
- Section.getContents(ModInitContents);
- } else if (Name == "__mod_exit_func") {
- DEBUG(dbgs() << "Found __mod_exit_func section!\n");
- Section.getContents(ModExitContents);
- }
- }
-}
-
-// FIXME: Only do the translations for addresses actually inside the object.
-uint64_t MCMachOObjectDisassembler::getEffectiveLoadAddr(uint64_t Addr) {
- return Addr + VMAddrSlide;
-}
-
-uint64_t
-MCMachOObjectDisassembler::getOriginalLoadAddr(uint64_t EffectiveAddr) {
- return EffectiveAddr - VMAddrSlide;
-}
-
-uint64_t MCMachOObjectDisassembler::getEntrypoint() {
- uint64_t EntryFileOffset = 0;
-
- // Look for LC_MAIN.
- {
- uint32_t LoadCommandCount = MOOF.getHeader().ncmds;
- MachOObjectFile::LoadCommandInfo Load = MOOF.getFirstLoadCommandInfo();
- for (unsigned I = 0;; ++I) {
- if (Load.C.cmd == MachO::LC_MAIN) {
- EntryFileOffset =
- ((const MachO::entry_point_command *)Load.Ptr)->entryoff;
- break;
- }
-
- if (I == LoadCommandCount - 1)
- break;
- else
- Load = MOOF.getNextLoadCommandInfo(Load);
- }
- }
-
- // If we didn't find anything, default to the common implementation.
- // FIXME: Maybe we could also look at LC_UNIXTHREAD and friends?
- if (EntryFileOffset)
- return MCObjectDisassembler::getEntrypoint();
-
- return EntryFileOffset + HeaderLoadAddress;
-}
-
-ArrayRef<uint64_t> MCMachOObjectDisassembler::getStaticInitFunctions() {
- // FIXME: We only handle 64bit mach-o
- assert(MOOF.is64Bit());
-
- size_t EntrySize = 8;
- size_t EntryCount = ModInitContents.size() / EntrySize;
- return ArrayRef<uint64_t>(
- reinterpret_cast<const uint64_t *>(ModInitContents.data()), EntryCount);
-}
-
-ArrayRef<uint64_t> MCMachOObjectDisassembler::getStaticExitFunctions() {
- // FIXME: We only handle 64bit mach-o
- assert(MOOF.is64Bit());
-
- size_t EntrySize = 8;
- size_t EntryCount = ModExitContents.size() / EntrySize;
- return ArrayRef<uint64_t>(
- reinterpret_cast<const uint64_t *>(ModExitContents.data()), EntryCount);
-}
diff --git a/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp b/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp
deleted file mode 100644
index b149596..0000000
--- a/lib/MC/MCAnalysis/MCObjectSymbolizer.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-//===-- lib/MC/MCObjectSymbolizer.cpp -------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCObjectSymbolizer.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCRelocationInfo.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-
-using namespace llvm;
-using namespace object;
-
-//===- MCMachObjectSymbolizer ---------------------------------------------===//
-
-namespace {
-class MCMachObjectSymbolizer : public MCObjectSymbolizer {
- const MachOObjectFile *MOOF;
- // __TEXT;__stubs support.
- uint64_t StubsStart;
- uint64_t StubsCount;
- uint64_t StubSize;
- uint64_t StubsIndSymIndex;
-
-public:
- MCMachObjectSymbolizer(MCContext &Ctx,
- std::unique_ptr<MCRelocationInfo> RelInfo,
- const MachOObjectFile *MOOF);
-
- StringRef findExternalFunctionAt(uint64_t Addr) override;
-
- void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value,
- uint64_t Address) override;
-};
-} // End unnamed namespace
-
-MCMachObjectSymbolizer::MCMachObjectSymbolizer(
- MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
- const MachOObjectFile *MOOF)
- : MCObjectSymbolizer(Ctx, std::move(RelInfo), MOOF), MOOF(MOOF),
- StubsStart(0), StubsCount(0), StubSize(0), StubsIndSymIndex(0) {
-
- for (const SectionRef &Section : MOOF->sections()) {
- StringRef Name;
- Section.getName(Name);
- if (Name == "__stubs") {
- SectionRef StubsSec = Section;
- if (MOOF->is64Bit()) {
- MachO::section_64 S = MOOF->getSection64(StubsSec.getRawDataRefImpl());
- StubsIndSymIndex = S.reserved1;
- StubSize = S.reserved2;
- } else {
- MachO::section S = MOOF->getSection(StubsSec.getRawDataRefImpl());
- StubsIndSymIndex = S.reserved1;
- StubSize = S.reserved2;
- }
- assert(StubSize && "Mach-O stub entry size can't be zero!");
- StubsSec.getAddress(StubsStart);
- StubsSec.getSize(StubsCount);
- StubsCount /= StubSize;
- }
- }
-}
-
-StringRef MCMachObjectSymbolizer::findExternalFunctionAt(uint64_t Addr) {
- // FIXME: also, this can all be done at the very beginning, by iterating over
- // all stubs and creating the calls to outside functions. Is it worth it
- // though?
- if (!StubSize)
- return StringRef();
- uint64_t StubIdx = (Addr - StubsStart) / StubSize;
- if (StubIdx >= StubsCount)
- return StringRef();
-
- uint32_t SymtabIdx =
- MOOF->getIndirectSymbolTableEntry(MOOF->getDysymtabLoadCommand(), StubIdx);
-
- StringRef SymName;
- symbol_iterator SI = MOOF->symbol_begin();
- for (uint32_t i = 0; i != SymtabIdx; ++i)
- ++SI;
- SI->getName(SymName);
- assert(SI != MOOF->symbol_end() && "Stub wasn't found in the symbol table!");
- assert(SymName.front() == '_' && "Mach-O symbol doesn't start with '_'!");
- return SymName.substr(1);
-}
-
-void MCMachObjectSymbolizer::
-tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value,
- uint64_t Address) {
- if (const RelocationRef *R = findRelocationAt(Address)) {
- const MCExpr *RelExpr = RelInfo->createExprForRelocation(*R);
- if (!RelExpr || RelExpr->EvaluateAsAbsolute(Value) == false)
- return;
- }
- uint64_t Addr = Value;
- if (const SectionRef *S = findSectionContaining(Addr)) {
- StringRef Name; S->getName(Name);
- uint64_t SAddr; S->getAddress(SAddr);
- if (Name == "__cstring") {
- StringRef Contents;
- S->getContents(Contents);
- Contents = Contents.substr(Addr - SAddr);
- cStream << " ## literal pool for: "
- << Contents.substr(0, Contents.find_first_of(0));
- }
- }
-}
-
-//===- MCObjectSymbolizer -------------------------------------------------===//
-
-MCObjectSymbolizer::MCObjectSymbolizer(
- MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
- const ObjectFile *Obj)
- : MCSymbolizer(Ctx, std::move(RelInfo)), Obj(Obj), SortedSections(),
- AddrToReloc() {}
-
-bool MCObjectSymbolizer::
-tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
- int64_t Value, uint64_t Address, bool IsBranch,
- uint64_t Offset, uint64_t InstSize) {
- if (IsBranch) {
- StringRef ExtFnName = findExternalFunctionAt((uint64_t)Value);
- if (!ExtFnName.empty()) {
- MCSymbol *Sym = Ctx.GetOrCreateSymbol(ExtFnName);
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
- MI.addOperand(MCOperand::CreateExpr(Expr));
- return true;
- }
- }
-
- if (const RelocationRef *R = findRelocationAt(Address + Offset)) {
- if (const MCExpr *RelExpr = RelInfo->createExprForRelocation(*R)) {
- MI.addOperand(MCOperand::CreateExpr(RelExpr));
- return true;
- }
- // Only try to create a symbol+offset expression if there is no relocation.
- return false;
- }
-
- // Interpret Value as a branch target.
- if (IsBranch == false)
- return false;
- uint64_t UValue = Value;
- // FIXME: map instead of looping each time?
- for (const SymbolRef &Symbol : Obj->symbols()) {
- uint64_t SymAddr;
- Symbol.getAddress(SymAddr);
- uint64_t SymSize;
- Symbol.getSize(SymSize);
- StringRef SymName;
- Symbol.getName(SymName);
- SymbolRef::Type SymType;
- Symbol.getType(SymType);
- if (SymAddr == UnknownAddressOrSize || SymSize == UnknownAddressOrSize ||
- SymName.empty() || SymType != SymbolRef::ST_Function)
- continue;
-
- if ( SymAddr == UValue ||
- (SymAddr <= UValue && SymAddr + SymSize > UValue)) {
- MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName);
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
- if (SymAddr != UValue) {
- const MCExpr *Off = MCConstantExpr::Create(UValue - SymAddr, Ctx);
- Expr = MCBinaryExpr::CreateAdd(Expr, Off, Ctx);
- }
- MI.addOperand(MCOperand::CreateExpr(Expr));
- return true;
- }
- }
- return false;
-}
-
-void MCObjectSymbolizer::
-tryAddingPcLoadReferenceComment(raw_ostream &cStream,
- int64_t Value, uint64_t Address) {
-}
-
-StringRef MCObjectSymbolizer::findExternalFunctionAt(uint64_t Addr) {
- return StringRef();
-}
-
-MCObjectSymbolizer *MCObjectSymbolizer::createObjectSymbolizer(
- MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
- const ObjectFile *Obj) {
- if (const MachOObjectFile *MOOF = dyn_cast<MachOObjectFile>(Obj))
- return new MCMachObjectSymbolizer(Ctx, std::move(RelInfo), MOOF);
- return new MCObjectSymbolizer(Ctx, std::move(RelInfo), Obj);
-}
-
-// SortedSections implementation.
-
-static bool SectionStartsBefore(const SectionRef &S, uint64_t Addr) {
- uint64_t SAddr; S.getAddress(SAddr);
- return SAddr < Addr;
-}
-
-const SectionRef *MCObjectSymbolizer::findSectionContaining(uint64_t Addr) {
- if (SortedSections.empty())
- buildSectionList();
-
- SortedSectionList::iterator
- EndIt = SortedSections.end(),
- It = std::lower_bound(SortedSections.begin(), EndIt,
- Addr, SectionStartsBefore);
- if (It == EndIt)
- return nullptr;
- uint64_t SAddr; It->getAddress(SAddr);
- uint64_t SSize; It->getSize(SSize);
- if (Addr >= SAddr + SSize)
- return nullptr;
- return &*It;
-}
-
-const RelocationRef *MCObjectSymbolizer::findRelocationAt(uint64_t Addr) {
- if (AddrToReloc.empty())
- buildRelocationByAddrMap();
-
- AddrToRelocMap::const_iterator RI = AddrToReloc.find(Addr);
- if (RI == AddrToReloc.end())
- return nullptr;
- return &RI->second;
-}
-
-void MCObjectSymbolizer::buildSectionList() {
- for (const SectionRef &Section : Obj->sections()) {
- bool RequiredForExec;
- Section.isRequiredForExecution(RequiredForExec);
- if (RequiredForExec == false)
- continue;
- uint64_t SAddr;
- Section.getAddress(SAddr);
- uint64_t SSize;
- Section.getSize(SSize);
- SortedSectionList::iterator It =
- std::lower_bound(SortedSections.begin(), SortedSections.end(), SAddr,
- SectionStartsBefore);
- if (It != SortedSections.end()) {
- uint64_t FoundSAddr; It->getAddress(FoundSAddr);
- if (FoundSAddr < SAddr + SSize)
- llvm_unreachable("Inserting overlapping sections");
- }
- SortedSections.insert(It, Section);
- }
-}
-
-void MCObjectSymbolizer::buildRelocationByAddrMap() {
- for (const SectionRef &Section : Obj->sections()) {
- for (const RelocationRef &Reloc : Section.relocations()) {
- uint64_t Address;
- Reloc.getAddress(Address);
- // At a specific address, only keep the first relocation.
- if (AddrToReloc.find(Address) == AddrToReloc.end())
- AddrToReloc[Address] = Reloc;
- }
- }
-}
diff --git a/lib/MC/MCAnalysis/Makefile b/lib/MC/MCAnalysis/Makefile
deleted file mode 100644
index add2dbd..0000000
--- a/lib/MC/MCAnalysis/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/MC/MCAnalysys/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMCAnalysis
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index f8081ef..2fb558f 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -32,7 +32,6 @@ MCAsmInfo::MCAsmInfo() {
HasMachoZeroFillDirective = false;
HasMachoTBSSDirective = false;
HasStaticCtorDtorReferenceInStaticMode = false;
- LinkerRequiresNonEmptyDwarfLines = false;
MaxInstLength = 4;
MinInstAlignment = 1;
DollarIsPC = false;
@@ -64,7 +63,7 @@ MCAsmInfo::MCAsmInfo() {
GPRel64Directive = nullptr;
GPRel32Directive = nullptr;
GlobalDirective = "\t.globl\t";
- HasSetDirective = true;
+ SetDirectiveSuppressesReloc = false;
HasAggressiveSymbolFolding = true;
COMMDirectiveAlignmentIsInBytes = true;
LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
@@ -79,10 +78,9 @@ MCAsmInfo::MCAsmInfo() {
HiddenVisibilityAttr = MCSA_Hidden;
HiddenDeclarationVisibilityAttr = MCSA_Hidden;
ProtectedVisibilityAttr = MCSA_Protected;
- HasLEB128 = false;
SupportsDebugInformation = false;
ExceptionsType = ExceptionHandling::None;
- WinEHEncodingType = WinEH::EncodingType::ET_Invalid;
+ WinEHEncodingType = WinEH::EncodingType::Invalid;
DwarfUsesRelocationsAcrossSections = true;
DwarfFDESymbolsUseAbsDiff = false;
DwarfRegNumForCFI = false;
diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp
index 9945637..bb3f0d3 100644
--- a/lib/MC/MCAsmInfoCOFF.cpp
+++ b/lib/MC/MCAsmInfoCOFF.cpp
@@ -32,7 +32,6 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
ProtectedVisibilityAttr = MCSA_Invalid;
// Set up DWARF directives
- HasLEB128 = true; // Target asm supports leb128 directives (little-endian)
SupportsDebugInformation = true;
NeedsDwarfSectionOffsetDirective = true;
diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp
index eaf28dd..66a138b 100644
--- a/lib/MC/MCAsmInfoDarwin.cpp
+++ b/lib/MC/MCAsmInfoDarwin.cpp
@@ -42,9 +42,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasMachoTBSSDirective = true; // Uses .tbss
HasStaticCtorDtorReferenceInStaticMode = true;
- // FIXME: Darwin 10 and newer don't need this.
- LinkerRequiresNonEmptyDwarfLines = true;
-
// FIXME: Change this once MC is the system assembler.
HasAggressiveSymbolFolding = false;
@@ -60,4 +57,5 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
DwarfUsesRelocationsAcrossSections = false;
UseIntegratedAssembler = true;
+ SetDirectiveSuppressesReloc = true;
}
diff --git a/lib/MC/MCAsmInfoELF.cpp b/lib/MC/MCAsmInfoELF.cpp
index ccb3dc3..9f70d8d 100644
--- a/lib/MC/MCAsmInfoELF.cpp
+++ b/lib/MC/MCAsmInfoELF.cpp
@@ -13,10 +13,19 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmInfoELF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Support/ELF.h"
using namespace llvm;
void MCAsmInfoELF::anchor() { }
+const MCSection *
+MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const {
+ return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS,
+ 0, SectionKind::getMetadata());
+}
+
MCAsmInfoELF::MCAsmInfoELF() {
HasIdentDirective = true;
WeakRefDirective = "\t.weak\t";
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 6973bbb..f60c7fc 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -700,7 +700,6 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
EmitULEB128IntValue(IntValue);
return;
}
- assert(MAI->hasLEB128() && "Cannot print a .uleb");
OS << ".uleb128 " << *Value;
EmitEOL();
}
@@ -711,7 +710,6 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitSLEB128IntValue(IntValue);
return;
}
- assert(MAI->hasLEB128() && "Cannot print a .sleb");
OS << ".sleb128 " << *Value;
EmitEOL();
}
@@ -1089,19 +1087,6 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
EmitEOL();
}
-static const MCSection *getWin64EHTableSection(StringRef suffix,
- MCContext &context) {
- // FIXME: This doesn't belong in MCObjectFileInfo. However,
- /// this duplicate code in MCWin64EH.cpp.
- if (suffix == "")
- return context.getObjectFileInfo()->getXDataSection();
- return context.getCOFFSection((".xdata"+suffix).str(),
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
- SectionKind::getDataRel());
-}
-
void MCAsmStreamer::EmitWinEHHandlerData() {
MCStreamer::EmitWinEHHandlerData();
@@ -1109,11 +1094,10 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
// cause the section switch to be visible in the emitted assembly.
// We only do this so the section switch that terminates the handler
// data block is visible.
- MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
- StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
- const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext());
- if (xdataSect)
- SwitchSectionNoChange(xdataSect);
+ WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
+ if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
+ CurFrame->Function, getContext()))
+ SwitchSectionNoChange(XData);
OS << "\t.seh_handlerdata";
EmitEOL();
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index a8aad71..85d0c13 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -141,7 +141,7 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout,
// If SD is a variable, evaluate it.
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout))
+ if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
@@ -187,7 +187,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
const MCExpr *Expr = Symbol.getVariableValue();
MCValue Value;
- if (!Expr->EvaluateAsValue(Value, this))
+ if (!Expr->EvaluateAsValue(Value, this, nullptr))
llvm_unreachable("Invalid Expression");
const MCSymbolRefExpr *RefB = Value.getSymB();
@@ -291,7 +291,9 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
: Section(&_Section),
Ordinal(~UINT32_C(0)),
Alignment(1),
- BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false),
+ BundleLockState(NotBundleLocked),
+ BundleLockNestingDepth(0),
+ BundleGroupBeforeFirstInst(false),
HasInstructions(false)
{
if (A)
@@ -328,17 +330,33 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
return IP;
}
+void MCSectionData::setBundleLockState(BundleLockStateType NewState) {
+ if (NewState == NotBundleLocked) {
+ if (BundleLockNestingDepth == 0) {
+ report_fatal_error("Mismatched bundle_lock/unlock directives");
+ }
+ if (--BundleLockNestingDepth == 0) {
+ BundleLockState = NotBundleLocked;
+ }
+ return;
+ }
+
+ // If any of the directives is an align_to_end directive, the whole nested
+ // group is align_to_end. So don't downgrade from align_to_end to just locked.
+ if (BundleLockState != BundleLockedAlignToEnd) {
+ BundleLockState = NewState;
+ }
+ ++BundleLockNestingDepth;
+}
+
/* *** */
MCSymbolData::MCSymbolData() : Symbol(nullptr) {}
MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
uint64_t _Offset, MCAssembler *A)
- : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
- IsExternal(false), IsPrivateExtern(false),
- CommonSize(0), SymbolSize(nullptr), CommonAlign(0),
- Flags(0), Index(0)
-{
+ : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
+ SymbolSize(nullptr), CommonAlign(-1U), Flags(0), Index(0) {
if (A)
A->getSymbolList().push_back(this);
}
@@ -348,9 +366,9 @@ MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
raw_ostream &OS_)
- : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
- OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false),
- SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
+ : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
+ OS(OS_), BundleAlignSize(0), RelaxAll(false),
+ SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
VersionMinInfo.Major = 0; // Major version == 0 for "none specified"
}
@@ -364,11 +382,15 @@ void MCAssembler::reset() {
SymbolMap.clear();
IndirectSymbols.clear();
DataRegions.clear();
+ LinkerOptions.clear();
+ FileNames.clear();
ThumbFuncs.clear();
+ BundleAlignSize = 0;
RelaxAll = false;
- NoExecStack = false;
SubsectionsViaSymbols = false;
ELFHeaderEFlags = 0;
+ LOHContainer.reset();
+ VersionMinInfo.Major = 0;
// reset objects owned by us
getBackend().reset();
@@ -438,11 +460,12 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const {
// a relocatable expr.
// FIXME: Should this be the behavior of EvaluateAsRelocatable itself?
static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout,
- MCValue &Target) {
- if (Expr.EvaluateAsValue(Target, &Layout))
+ const MCFixup &Fixup, MCValue &Target) {
+ if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) {
if (Target.isAbsolute())
return true;
- return Expr.EvaluateAsRelocatable(Target, &Layout);
+ }
+ return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup);
}
bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
@@ -454,7 +477,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
// probably merge the two into a single callback that tries to evaluate a
// fixup and records a relocation if one is needed.
const MCExpr *Expr = Fixup.getValue();
- if (!evaluate(*Expr, Layout, Target))
+ if (!evaluate(*Expr, Layout, Fixup, Target))
getContext().FatalError(Fixup.getLoc(), "expected relocatable expression");
bool IsPCRel = Backend.getFixupKindInfo(
@@ -993,11 +1016,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
}
bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
- int64_t Value = 0;
uint64_t OldSize = LF.getContents().size();
- bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t Value = LF.getValue().evaluateKnownAbsolute(Layout);
SmallString<8> &Data = LF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
@@ -1012,11 +1032,8 @@ bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) {
bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF) {
MCContext &Context = Layout.getAssembler().getContext();
- int64_t AddrDelta = 0;
uint64_t OldSize = DF.getContents().size();
- bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout);
int64_t LineDelta;
LineDelta = DF.getLineDelta();
SmallString<8> &Data = DF.getContents();
@@ -1030,11 +1047,8 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
MCDwarfCallFrameFragment &DF) {
MCContext &Context = Layout.getAssembler().getContext();
- int64_t AddrDelta = 0;
uint64_t OldSize = DF.getContents().size();
- bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
- (void)IsAbs;
- assert(IsAbs);
+ int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout);
SmallString<8> &Data = DF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
@@ -1247,8 +1261,10 @@ void MCSymbolData::dump() const {
raw_ostream &OS = llvm::errs();
OS << "<MCSymbolData Symbol:" << getSymbol()
- << " Fragment:" << getFragment() << " Offset:" << getOffset()
- << " Flags:" << getFlags() << " Index:" << getIndex();
+ << " Fragment:" << getFragment();
+ if (!isCommon())
+ OS << " Offset:" << getOffset();
+ OS << " Flags:" << getFlags() << " Index:" << getIndex();
if (isCommon())
OS << " (common, size:" << getCommonSize()
<< " align: " << getCommonAlignment() << ")";
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 960a071..8630b25 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -73,7 +73,10 @@ void MCContext::reset() {
Symbols.clear();
Allocator.Reset();
Instances.clear();
+ CompilationDir.clear();
+ MainFileName.clear();
MCDwarfLineTablesCUMap.clear();
+ SectionStartEndSyms.clear();
MCGenDwarfLabelEntries.clear();
DwarfDebugFlags = StringRef();
DwarfCompileUnitID = 0;
@@ -97,16 +100,33 @@ void MCContext::reset() {
MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
assert(!Name.empty() && "Normal symbols cannot be unnamed!");
- // Do the lookup and get the entire StringMapEntry. We want access to the
- // key if we are creating the entry.
- StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
- MCSymbol *Sym = Entry.getValue();
+ MCSymbol *&Sym = Symbols[Name];
+ if (!Sym)
+ Sym = CreateSymbol(Name);
+
+ return Sym;
+}
+
+MCSymbol *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
+ MCSymbol *&Sym = SectionSymbols[&Section];
if (Sym)
return Sym;
- Sym = CreateSymbol(Name);
- Entry.setValue(Sym);
+ StringRef Name = Section.getSectionName();
+
+ MCSymbol *&OldSym = Symbols[Name];
+ if (OldSym && OldSym->isUndefined()) {
+ Sym = OldSym;
+ return OldSym;
+ }
+
+ auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first;
+ Sym = new (*this) MCSymbol(NameIter->getKey(), /*isTemporary*/ false);
+
+ if (!OldSym)
+ OldSym = Sym;
+
return Sym;
}
@@ -116,21 +136,21 @@ MCSymbol *MCContext::CreateSymbol(StringRef Name) {
if (AllowTemporaryLabels)
isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
- StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
- if (NameEntry->getValue()) {
+ auto NameEntry = UsedNames.insert(std::make_pair(Name, true));
+ if (!NameEntry.second) {
assert(isTemporary && "Cannot rename non-temporary symbols");
SmallString<128> NewName = Name;
do {
NewName.resize(Name.size());
raw_svector_ostream(NewName) << NextUniqueID++;
- NameEntry = &UsedNames.GetOrCreateValue(NewName);
- } while (NameEntry->getValue());
+ NameEntry = UsedNames.insert(std::make_pair(NewName, true));
+ } while (!NameEntry.second);
}
- NameEntry->setValue(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->getKey(), isTemporary);
+ MCSymbol *Result =
+ new (*this) MCSymbol(NameEntry.first->getKey(), isTemporary);
return Result;
}
@@ -291,7 +311,7 @@ const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
if (!IterBool.second)
return Iter->second;
- const MCSymbol *COMDATSymbol = nullptr;
+ MCSymbol *COMDATSymbol = nullptr;
if (!COMDATSymName.empty())
COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
@@ -317,6 +337,22 @@ const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
return Iter->second;
}
+const MCSectionCOFF *
+MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec,
+ const MCSymbol *KeySym) {
+ // Return the normal section if we don't have to be associative.
+ if (!KeySym)
+ return Sec;
+
+ // Make an associative section with the same name and kind as the normal
+ // section.
+ unsigned Characteristics =
+ Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
+ return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
+ KeySym->getName(),
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+}
+
//===----------------------------------------------------------------------===//
// Dwarf Management
//===----------------------------------------------------------------------===//
diff --git a/lib/MC/MCDisassembler/Android.mk b/lib/MC/MCDisassembler/Android.mk
index 7f73df3..87455e2 100644
--- a/lib/MC/MCDisassembler/Android.mk
+++ b/lib/MC/MCDisassembler/Android.mk
@@ -1,15 +1,37 @@
LOCAL_PATH:= $(call my-dir)
+mc_disassembler_SRC_FILES := \
+ Disassembler.cpp \
+ MCDisassembler.cpp \
+ MCExternalSymbolizer.cpp \
+ MCRelocationInfo.cpp
+
+
# For the host
# =====================================================
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- Disassembler.cpp
+LOCAL_SRC_FILES := $(mc_disassembler_SRC_FILES)
LOCAL_MODULE:= libLLVMMCDisassembler
LOCAL_MODULE_TAGS := optional
+
include $(LLVM_HOST_BUILD_MK)
include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the device
+# =====================================================
+include $(CLEAR_VARS)
+ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
+
+LOCAL_SRC_FILES := $(mc_disassembler_SRC_FILES)
+
+LOCAL_MODULE:= libLLVMMCDisassembler
+
+LOCAL_MODULE_TAGS := optional
+
+include $(LLVM_DEVICE_BUILD_MK)
+include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/lib/MC/MCDisassembler/CMakeLists.txt b/lib/MC/MCDisassembler/CMakeLists.txt
index 5195b9e..f266f8f 100644
--- a/lib/MC/MCDisassembler/CMakeLists.txt
+++ b/lib/MC/MCDisassembler/CMakeLists.txt
@@ -1,3 +1,6 @@
add_llvm_library(LLVMMCDisassembler
Disassembler.cpp
+ MCRelocationInfo.cpp
+ MCExternalSymbolizer.cpp
+ MCDisassembler.cpp
)
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp
index 0530c26..d0d7f30 100644
--- a/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -21,7 +21,6 @@
#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -33,10 +32,11 @@ using namespace llvm;
// functions can all be passed as NULL. If successful, this returns a
// disassembler context. If not, it returns NULL.
//
-LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
- void *DisInfo, int TagType,
- LLVMOpInfoCallback GetOpInfo,
- LLVMSymbolLookupCallback SymbolLookUp){
+LLVMDisasmContextRef
+LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU,
+ const char *Features, void *DisInfo, int TagType,
+ LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp) {
// Get the target.
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
@@ -56,11 +56,8 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
if (!MII)
return nullptr;
- // Package up features to be passed to target/subtarget
- std::string FeaturesStr;
-
const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU,
- FeaturesStr);
+ Features);
if (!STI)
return nullptr;
@@ -101,11 +98,19 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
return DC;
}
+LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
+ void *DisInfo, int TagType,
+ LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp){
+ return LLVMCreateDisasmCPUFeatures(Triple, CPU, "", DisInfo, TagType,
+ GetOpInfo, SymbolLookUp);
+}
+
LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) {
- return LLVMCreateDisasmCPU(Triple, "", DisInfo, TagType, GetOpInfo,
- SymbolLookUp);
+ return LLVMCreateDisasmCPUFeatures(Triple, "", "", DisInfo, TagType,
+ GetOpInfo, SymbolLookUp);
}
//
@@ -116,30 +121,6 @@ void LLVMDisasmDispose(LLVMDisasmContextRef DCR){
delete DC;
}
-namespace {
-//
-// The memory object created by LLVMDisasmInstruction().
-//
-class DisasmMemoryObject : public MemoryObject {
- uint8_t *Bytes;
- uint64_t Size;
- uint64_t BasePC;
-public:
- DisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
- Bytes(bytes), Size(size), BasePC(basePC) {}
-
- uint64_t getBase() const override { return BasePC; }
- uint64_t getExtent() const override { return Size; }
-
- int readByte(uint64_t Addr, uint8_t *Byte) const override {
- if (Addr - BasePC >= Size)
- return -1;
- *Byte = Bytes[Addr - BasePC];
- return 0;
- }
-};
-} // end anonymous namespace
-
/// \brief Emits the comments that are stored in \p DC comment stream.
/// Each comment in the comment stream must end with a newline.
static void emitComments(LLVMDisasmContext *DC,
@@ -202,19 +183,19 @@ static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
// Try to compute scheduling information.
const MCSubtargetInfo *STI = DC->getSubtargetInfo();
- const MCSchedModel *SCModel = STI->getSchedModel();
+ const MCSchedModel SCModel = STI->getSchedModel();
const int NoInformationAvailable = -1;
// Check if we have a scheduling model for instructions.
- if (!SCModel || !SCModel->hasInstrSchedModel())
- // Try to fall back to the itinerary model if we do not have a
- // scheduling model.
+ if (!SCModel.hasInstrSchedModel())
+ // Try to fall back to the itinerary model if the scheduling model doesn't
+ // have a scheduling table. Note the default does not have a table.
return getItineraryLatency(DC, Inst);
// Get the scheduling class of the requested instruction.
const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
unsigned SCClass = Desc.getSchedClass();
- const MCSchedClassDesc *SCDesc = SCModel->getSchedClassDesc(SCClass);
+ const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass);
// Resolving the variant SchedClass requires an MI to pass to
// SubTargetInfo::resolveSchedClass.
if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
@@ -263,7 +244,7 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
size_t OutStringSize){
LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
// Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject.
- DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC);
+ ArrayRef<uint8_t> Data(Bytes, BytesSize);
uint64_t Size;
MCInst Inst;
@@ -272,7 +253,7 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
MCDisassembler::DecodeStatus S;
SmallVector<char, 64> InsnStr;
raw_svector_ostream Annotations(InsnStr);
- S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC,
+ S = DisAsm->getInstruction(Inst, Size, Data, PC,
/*REMOVE*/ nulls(), Annotations);
switch (S) {
case MCDisassembler::Fail:
diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h
index d1d40cd..46d0c4c 100644
--- a/lib/MC/MCDisassembler/Disassembler.h
+++ b/lib/MC/MCDisassembler/Disassembler.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_DISASSEMBLER_H
-#define LLVM_MC_DISASSEMBLER_H
+#ifndef LLVM_LIB_MC_MCDISASSEMBLER_DISASSEMBLER_H
+#define LLVM_LIB_MC_MCDISASSEMBLER_DISASSEMBLER_H
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
diff --git a/lib/MC/MCDisassembler.cpp b/lib/MC/MCDisassembler/MCDisassembler.cpp
index 77d9ce1..1084e5e 100644
--- a/lib/MC/MCDisassembler.cpp
+++ b/lib/MC/MCDisassembler/MCDisassembler.cpp
@@ -1,4 +1,4 @@
-//===-- lib/MC/MCDisassembler.cpp - Disassembler interface ------*- C++ -*-===//
+//===-- MCDisassembler.cpp - Disassembler interface -----------------------===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/MC/MCExternalSymbolizer.cpp b/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
index 7c3073a..0145623 100644
--- a/lib/MC/MCExternalSymbolizer.cpp
+++ b/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp
@@ -1,4 +1,4 @@
-//===-- lib/MC/MCExternalSymbolizer.cpp - External symbolizer ---*- C++ -*-===//
+//===-- MCExternalSymbolizer.cpp - External symbolizer --------------------===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/MC/MCRelocationInfo.cpp b/lib/MC/MCDisassembler/MCRelocationInfo.cpp
index a00c009..ff0c27f 100644
--- a/lib/MC/MCRelocationInfo.cpp
+++ b/lib/MC/MCDisassembler/MCRelocationInfo.cpp
@@ -1,4 +1,4 @@
-//==-- lib/MC/MCRelocationInfo.cpp -------------------------------*- C++ -*-==//
+//==-- MCRelocationInfo.cpp ------------------------------------------------==//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 0a3fab8..5effb01 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -247,6 +247,22 @@ std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS)
return Emit(MCOS, StandardOpcodeLengths);
}
+static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
+ MCContext &Context = OS.getContext();
+ assert(!isa<MCSymbolRefExpr>(Expr));
+ if (Context.getAsmInfo()->hasAggressiveSymbolFolding())
+ return Expr;
+
+ MCSymbol *ABS = Context.CreateTempSymbol();
+ OS.EmitAssignment(ABS, Expr);
+ return MCSymbolRefExpr::Create(ABS, Context);
+}
+
+static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) {
+ const MCExpr *ABS = forceExpAbs(OS, Value);
+ OS.EmitValue(ABS, Size);
+}
+
std::pair<MCSymbol *, MCSymbol *>
MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
ArrayRef<char> StandardOpcodeLengths) const {
@@ -265,8 +281,8 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
// The first 4 bytes is the total length of the information for this
// compilation unit (not including these 4 bytes for the length).
- MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym,4),
- 4);
+ emitAbsValue(*MCOS,
+ MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4);
// Next 2 bytes is the Version, which is Dwarf 2.
MCOS->EmitIntValue(2, 2);
@@ -278,8 +294,9 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
// section to the end of the prologue. Not including the 4 bytes for the
// total length, the 2 bytes for the version, and these 4 bytes for the
// length of the prologue.
- MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
- (4 + 2 + 4)), 4);
+ emitAbsValue(
+ *MCOS,
+ MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, (4 + 2 + 4)), 4);
// Parameters of the state machine, are next.
MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1);
@@ -327,18 +344,6 @@ void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS) const {
for (const auto &LineSec : MCLineSections.getMCLineEntries())
EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
- if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
- MCLineSections.getMCLineEntries().empty()) {
- // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
- // it requires:
- // total_length >= prologue_length + 10
- // We are 4 bytes short, since we have total_length = 51 and
- // prologue_length = 45
-
- // The regular end_sequence should be sufficient.
- MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
- }
-
// This is the end of the section, so set the value of the symbol at the end
// of this section (that was used in a previous expression).
MCOS->EmitLabel(LineEndSym);
@@ -363,10 +368,10 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory,
FileNumber = SourceIdMap.size() + 1;
assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) &&
"Don't mix autonumbered and explicit numbered line table usage");
- StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(
- (Directory + Twine('\0') + FileName).str(), FileNumber);
- if (Ent.getValue() != FileNumber)
- return Ent.getValue();
+ auto IterBool = SourceIdMap.insert(
+ std::make_pair((Directory + Twine('\0') + FileName).str(), FileNumber));
+ if (!IterBool.second)
+ return IterBool.first->second;
}
// Make space for this FileNumber in the MCDwarfFiles vector if needed.
MCDwarfFiles.resize(FileNumber + 1);
@@ -519,7 +524,8 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
- if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1) {
+ if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3) {
EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
} else {
EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
@@ -596,7 +602,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
// The 4 byte offset to the compile unit in the .debug_info from the start
// of the .debug_info.
if (InfoSectionSymbol)
- MCOS->EmitSymbolValue(InfoSectionSymbol, 4);
+ MCOS->EmitSymbolValue(InfoSectionSymbol, 4,
+ asmInfo->needsDwarfSectionOffsetDirective());
else
MCOS->EmitIntValue(0, 4);
// The 1 byte size of an address.
@@ -620,7 +627,7 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
*StartSymbol, *EndSymbol, 0);
MCOS->EmitValue(Addr, AddrSize);
- MCOS->EmitAbsValue(Size, AddrSize);
+ emitAbsValue(*MCOS, Size, AddrSize);
}
// And finally the pair of terminating zeros.
@@ -650,18 +657,19 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// The 4 byte total length of the information for this compilation unit, not
// including these 4 bytes.
const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
- MCOS->EmitAbsValue(Length, 4);
+ emitAbsValue(*MCOS, Length, 4);
// The 2 byte DWARF version.
MCOS->EmitIntValue(context.getDwarfVersion(), 2);
+ const MCAsmInfo &AsmInfo = *context.getAsmInfo();
// The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
// it is at the start of that section so this is zero.
- if (AbbrevSectionSymbol) {
- MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
- } else {
+ if (AbbrevSectionSymbol == nullptr)
MCOS->EmitIntValue(0, 4);
- }
+ else
+ MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4,
+ AsmInfo.needsDwarfSectionOffsetDirective());
const MCAsmInfo *asmInfo = context.getAsmInfo();
int AddrSize = asmInfo->getPointerSize();
@@ -675,11 +683,11 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
// which is at the start of that section so this is zero.
- if (LineSectionSymbol) {
- MCOS->EmitSymbolValue(LineSectionSymbol, 4);
- } else {
+ if (LineSectionSymbol)
+ MCOS->EmitSymbolValue(LineSectionSymbol, 4,
+ AsmInfo.needsDwarfSectionOffsetDirective());
+ else
MCOS->EmitIntValue(0, 4);
- }
if (RangesSectionSymbol) {
// There are multiple sections containing code, so we must use the
@@ -740,14 +748,10 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// AT_producer, the version of the assembler tool.
StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
- if (!DwarfDebugProducer.empty()){
+ if (!DwarfDebugProducer.empty())
MCOS->EmitBytes(DwarfDebugProducer);
- }
- else {
- MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
- MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
- MCOS->EmitBytes(StringRef(")"));
- }
+ else
+ MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
@@ -824,7 +828,7 @@ static void EmitGenDwarfRanges(MCStreamer *MCOS) {
const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
*StartSymbol, *EndSymbol, 0);
MCOS->EmitIntValue(0, AddrSize);
- MCOS->EmitAbsValue(SectionSize, AddrSize);
+ emitAbsValue(*MCOS, SectionSize, AddrSize);
}
// Emit end of list entry
@@ -858,10 +862,11 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
if (MCOS->getContext().getGenDwarfSectionSyms().empty())
return;
- // We only need to use the .debug_ranges section if we have multiple
- // code sections.
+ // We only use the .debug_ranges section if we have multiple code sections,
+ // and we are emitting a DWARF version which supports it.
const bool UseRangesSection =
- MCOS->getContext().getGenDwarfSectionSyms().size() > 1;
+ MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3;
CreateDwarfSectionSymbols |= UseRangesSection;
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -974,18 +979,16 @@ static unsigned getSizeForEncoding(MCStreamer &streamer,
}
}
-static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol,
- unsigned symbolEncoding, bool isEH,
- const char *comment = nullptr) {
+static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
+ unsigned symbolEncoding, bool isEH) {
MCContext &context = streamer.getContext();
const MCAsmInfo *asmInfo = context.getAsmInfo();
const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
symbolEncoding,
streamer);
unsigned size = getSizeForEncoding(streamer, symbolEncoding);
- if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment);
if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
- streamer.EmitAbsValue(v, size);
+ emitAbsValue(streamer, v, size);
else
streamer.EmitValue(v, size);
}
@@ -1004,17 +1007,16 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
namespace {
class FrameEmitterImpl {
int CFAOffset;
- int CIENum;
bool IsEH;
const MCSymbol *SectionStart;
public:
FrameEmitterImpl(bool isEH)
- : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {}
+ : CFAOffset(0), IsEH(isEH), SectionStart(nullptr) {}
void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
- /// EmitCompactUnwind - Emit the unwind information in a compact way.
- void EmitCompactUnwind(MCStreamer &streamer,
+ /// Emit the unwind information in a compact way.
+ void EmitCompactUnwind(MCObjectStreamer &streamer,
const MCDwarfFrameInfo &frame);
const MCSymbol &EmitCIE(MCObjectStreamer &streamer,
@@ -1036,65 +1038,18 @@ namespace {
} // end anonymous namespace
-static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
- StringRef Prefix) {
- if (Streamer.isVerboseAsm()) {
- const char *EncStr;
- switch (Encoding) {
- default: EncStr = "<unknown encoding>"; break;
- case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break;
- case dwarf::DW_EH_PE_omit: EncStr = "omit"; break;
- case dwarf::DW_EH_PE_pcrel: EncStr = "pcrel"; break;
- case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break;
- case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break;
- case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break;
- case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break;
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
- EncStr = "pcrel udata4";
- break;
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
- EncStr = "pcrel sdata4";
- break;
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
- EncStr = "pcrel udata8";
- break;
- case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
- EncStr = "screl sdata8";
- break;
- case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4:
- EncStr = "indirect pcrel udata4";
- break;
- case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4:
- EncStr = "indirect pcrel sdata4";
- break;
- case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8:
- EncStr = "indirect pcrel udata8";
- break;
- case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8:
- EncStr = "indirect pcrel sdata8";
- break;
- }
-
- Streamer.AddComment(Twine(Prefix) + " = " + EncStr);
- }
-
+static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
Streamer.EmitIntValue(Encoding, 1);
}
void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
const MCCFIInstruction &Instr) {
int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
- bool VerboseAsm = Streamer.isVerboseAsm();
switch (Instr.getOperation()) {
case MCCFIInstruction::OpRegister: {
unsigned Reg1 = Instr.getRegister();
unsigned Reg2 = Instr.getRegister2();
- if (VerboseAsm) {
- Streamer.AddComment("DW_CFA_register");
- Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1));
- Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2));
- }
Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
Streamer.EmitULEB128IntValue(Reg1);
Streamer.EmitULEB128IntValue(Reg2);
@@ -1106,10 +1061,6 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
}
case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
- if (VerboseAsm) {
- Streamer.AddComment("DW_CFA_undefined");
- Streamer.AddComment(Twine("Reg ") + Twine(Reg));
- }
Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
Streamer.EmitULEB128IntValue(Reg);
return;
@@ -1119,8 +1070,6 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
const bool IsRelative =
Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;
- if (VerboseAsm)
- Streamer.AddComment("DW_CFA_def_cfa_offset");
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
if (IsRelative)
@@ -1128,37 +1077,21 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
else
CFAOffset = -Instr.getOffset();
- if (VerboseAsm)
- Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
Streamer.EmitULEB128IntValue(CFAOffset);
return;
}
case MCCFIInstruction::OpDefCfa: {
- if (VerboseAsm)
- Streamer.AddComment("DW_CFA_def_cfa");
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
-
- if (VerboseAsm)
- Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
Streamer.EmitULEB128IntValue(Instr.getRegister());
-
CFAOffset = -Instr.getOffset();
-
- if (VerboseAsm)
- Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
Streamer.EmitULEB128IntValue(CFAOffset);
return;
}
case MCCFIInstruction::OpDefCfaRegister: {
- if (VerboseAsm)
- Streamer.AddComment("DW_CFA_def_cfa_register");
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
-
- if (VerboseAsm)
- Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
Streamer.EmitULEB128IntValue(Instr.getRegister());
return;
@@ -1176,63 +1109,44 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
Offset = Offset / dataAlignmentFactor;
if (Offset < 0) {
- if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
- if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
Streamer.EmitULEB128IntValue(Reg);
- if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
Streamer.EmitSLEB128IntValue(Offset);
} else if (Reg < 64) {
- if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
- Twine(Reg) + ")");
Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
- if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
Streamer.EmitULEB128IntValue(Offset);
} else {
- if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
- if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
Streamer.EmitULEB128IntValue(Reg);
- if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
Streamer.EmitULEB128IntValue(Offset);
}
return;
}
case MCCFIInstruction::OpRememberState:
- if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
return;
case MCCFIInstruction::OpRestoreState:
- if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
return;
case MCCFIInstruction::OpSameValue: {
unsigned Reg = Instr.getRegister();
- if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
- if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
Streamer.EmitULEB128IntValue(Reg);
return;
}
case MCCFIInstruction::OpRestore: {
unsigned Reg = Instr.getRegister();
- if (VerboseAsm) {
- Streamer.AddComment("DW_CFA_restore");
- Streamer.AddComment(Twine("Reg ") + Twine(Reg));
- }
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
return;
}
case MCCFIInstruction::OpEscape:
- if (VerboseAsm) Streamer.AddComment("Escape bytes");
Streamer.EmitBytes(Instr.getValues());
return;
}
llvm_unreachable("Unhandled case in switch");
}
-/// EmitFrameMoves - Emit frame instructions to describe the layout of the
-/// frame.
+/// Emit frame instructions to describe the layout of the frame.
void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer,
ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel) {
@@ -1246,7 +1160,6 @@ void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer,
if (BaseLabel && Label) {
MCSymbol *ThisSym = Label;
if (ThisSym != BaseLabel) {
- if (streamer.isVerboseAsm()) streamer.AddComment("DW_CFA_advance_loc4");
streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
BaseLabel = ThisSym;
}
@@ -1256,12 +1169,11 @@ void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer,
}
}
-/// EmitCompactUnwind - Emit the unwind information in a compact way.
-void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
+/// Emit the unwind information in a compact way.
+void FrameEmitterImpl::EmitCompactUnwind(MCObjectStreamer &Streamer,
const MCDwarfFrameInfo &Frame) {
MCContext &Context = Streamer.getContext();
const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
- bool VerboseAsm = Streamer.isVerboseAsm();
// range-start range-length compact-unwind-enc personality-func lsda
// _foo LfooEnd-_foo 0x00000023 0 0
@@ -1296,24 +1208,19 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
// Range Start
unsigned FDEEncoding = MOFI->getFDEEncoding();
unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
- if (VerboseAsm) Streamer.AddComment("Range Start");
Streamer.EmitSymbolValue(Frame.Begin, Size);
// Range Length
const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
*Frame.End, 0);
- if (VerboseAsm) Streamer.AddComment("Range Length");
- Streamer.EmitAbsValue(Range, 4);
+ emitAbsValue(Streamer, Range, 4);
// Compact Encoding
Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
- if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" +
- Twine::utohexstr(Encoding));
Streamer.EmitIntValue(Encoding, Size);
// Personality Function
Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr);
- if (VerboseAsm) Streamer.AddComment("Personality Function");
if (!DwarfEHFrameOnly && Frame.Personality)
Streamer.EmitSymbolValue(Frame.Personality, Size);
else
@@ -1321,7 +1228,6 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
// LSDA
Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
- if (VerboseAsm) Streamer.AddComment("LSDA");
if (!DwarfEHFrameOnly && Frame.Lsda)
Streamer.EmitSymbolValue(Frame.Lsda, Size);
else
@@ -1338,27 +1244,22 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
MCContext &context = streamer.getContext();
const MCRegisterInfo *MRI = context.getRegisterInfo();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
- bool verboseAsm = streamer.isVerboseAsm();
MCSymbol *sectionStart = context.CreateTempSymbol();
streamer.EmitLabel(sectionStart);
- CIENum++;
MCSymbol *sectionEnd = context.CreateTempSymbol();
// Length
const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
*sectionEnd, 4);
- if (verboseAsm) streamer.AddComment("CIE Length");
- streamer.EmitAbsValue(Length, 4);
+ emitAbsValue(streamer, Length, 4);
// CIE ID
unsigned CIE_ID = IsEH ? 0 : -1;
- if (verboseAsm) streamer.AddComment("CIE ID Tag");
streamer.EmitIntValue(CIE_ID, 4);
// Version
- if (verboseAsm) streamer.AddComment("DW_CIE_VERSION");
// For DWARF2, we use CIE version 1
// For DWARF3+, we use CIE version 3
uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3;
@@ -1367,7 +1268,6 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
// Augmentation String
SmallString<8> Augmentation;
if (IsEH) {
- if (verboseAsm) streamer.AddComment("CIE Augmentation");
Augmentation += "z";
if (personality)
Augmentation += "P";
@@ -1381,15 +1281,12 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
streamer.EmitIntValue(0, 1);
// Code Alignment Factor
- if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor");
streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
// Data Alignment Factor
- if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor");
streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer));
// Return Address Register
- if (verboseAsm) streamer.AddComment("CIE Return Address Column");
if (CIEVersion == 1) {
assert(MRI->getRARegister() <= 255 &&
"DWARF 2 encodes return_address_register in one byte");
@@ -1414,24 +1311,21 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
// Encoding of the FDE pointers
augmentationLength += 1;
- if (verboseAsm) streamer.AddComment("Augmentation Size");
streamer.EmitULEB128IntValue(augmentationLength);
// Augmentation Data (optional)
if (personality) {
// Personality Encoding
- EmitEncodingByte(streamer, personalityEncoding,
- "Personality Encoding");
+ emitEncodingByte(streamer, personalityEncoding);
// Personality
- if (verboseAsm) streamer.AddComment("Personality");
EmitPersonality(streamer, *personality, personalityEncoding);
}
if (lsda)
- EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding");
+ emitEncodingByte(streamer, lsdaEncoding);
// Encoding of the FDE pointers
- EmitEncodingByte(streamer, MOFI->getFDEEncoding(), "FDE Encoding");
+ emitEncodingByte(streamer, MOFI->getFDEEncoding());
}
// Initial Instructions
@@ -1457,12 +1351,10 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
MCSymbol *fdeStart = context.CreateTempSymbol();
MCSymbol *fdeEnd = context.CreateTempSymbol();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
- bool verboseAsm = streamer.isVerboseAsm();
// Length
const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
- if (verboseAsm) streamer.AddComment("FDE Length");
- streamer.EmitAbsValue(Length, 4);
+ emitAbsValue(streamer, Length, 4);
streamer.EmitLabel(fdeStart);
@@ -1471,12 +1363,11 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
if (IsEH) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
0);
- if (verboseAsm) streamer.AddComment("FDE CIE Offset");
- streamer.EmitAbsValue(offset, 4);
+ emitAbsValue(streamer, offset, 4);
} else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
cieStart, 0);
- streamer.EmitAbsValue(offset, 4);
+ emitAbsValue(streamer, offset, 4);
} else {
streamer.EmitSymbolValue(&cieStart, 4);
}
@@ -1485,13 +1376,12 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
unsigned PCEncoding =
IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
- EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location");
+ emitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH);
// PC Range
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
*frame.End, 0);
- if (verboseAsm) streamer.AddComment("FDE address range");
- streamer.EmitAbsValue(Range, PCSize);
+ emitAbsValue(streamer, Range, PCSize);
if (IsEH) {
// Augmentation Data Length
@@ -1500,13 +1390,11 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer,
if (frame.Lsda)
augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);
- if (verboseAsm) streamer.AddComment("Augmentation size");
streamer.EmitULEB128IntValue(augmentationLength);
// Augmentation Data
if (frame.Lsda)
- EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true,
- "Language Specific Data Area");
+ emitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true);
}
// Call Frame Instructions
@@ -1574,7 +1462,7 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
MCContext &Context = Streamer.getContext();
const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
FrameEmitterImpl Emitter(IsEH);
- ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
+ ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
// Emit the compact unwind info if available.
bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp
index 0a9cd31..386c209 100644
--- a/lib/MC/MCELF.cpp
+++ b/lib/MC/MCELF.cpp
@@ -61,7 +61,7 @@ void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
}
-unsigned MCELF::GetVisibility(MCSymbolData &SD) {
+unsigned MCELF::GetVisibility(const MCSymbolData &SD) {
unsigned Visibility =
(SD.getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift;
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
@@ -76,7 +76,7 @@ void MCELF::setOther(MCSymbolData &SD, unsigned Other) {
SD.setFlags(OtherFlags | (Other << ELF_STO_Shift));
}
-unsigned MCELF::getOther(MCSymbolData &SD) {
+unsigned MCELF::getOther(const MCSymbolData &SD) {
unsigned Other =
(SD.getFlags() & (0x3f << ELF_STO_Shift)) >> ELF_STO_Shift;
return Other;
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index 4012c44..84176dc 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -24,6 +24,7 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
IsN64(IsN64_){
}
-bool MCELFObjectTargetWriter::needsRelocateWithSymbol(unsigned Type) const {
+bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
+ unsigned Type) const {
return false;
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 7c70540..bdc4a84 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -38,19 +39,23 @@ using namespace llvm;
MCELFStreamer::~MCELFStreamer() {
}
-void MCELFStreamer::InitSections() {
+void MCELFStreamer::InitSections(bool NoExecStack) {
// This emulates the same behavior of GNU as. This makes it easier
// to compare the output as the major sections are in the same order.
- SwitchSection(getContext().getObjectFileInfo()->getTextSection());
+ MCContext &Ctx = getContext();
+ SwitchSection(Ctx.getObjectFileInfo()->getTextSection());
EmitCodeAlignment(4);
- SwitchSection(getContext().getObjectFileInfo()->getDataSection());
+ SwitchSection(Ctx.getObjectFileInfo()->getDataSection());
EmitCodeAlignment(4);
- SwitchSection(getContext().getObjectFileInfo()->getBSSSection());
+ SwitchSection(Ctx.getObjectFileInfo()->getBSSSection());
EmitCodeAlignment(4);
- SwitchSection(getContext().getObjectFileInfo()->getTextSection());
+ SwitchSection(Ctx.getObjectFileInfo()->getTextSection());
+
+ if (NoExecStack)
+ SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
}
void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
@@ -87,10 +92,19 @@ void MCELFStreamer::ChangeSection(const MCSection *Section,
MCSectionData *CurSection = getCurrentSectionData();
if (CurSection && CurSection->isBundleLocked())
report_fatal_error("Unterminated .bundle_lock when changing a section");
- const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
+
+ MCAssembler &Asm = getAssembler();
+ auto *SectionELF = static_cast<const MCSectionELF *>(Section);
+ const MCSymbol *Grp = SectionELF->getGroup();
if (Grp)
- getAssembler().getOrCreateSymbolData(*Grp);
+ Asm.getOrCreateSymbolData(*Grp);
+
this->MCObjectStreamer::ChangeSection(Section, Subsection);
+ MCSymbol *SectionSymbol = getContext().getOrCreateSectionSymbol(*SectionELF);
+ if (SectionSymbol->isUndefined()) {
+ EmitLabel(SectionSymbol);
+ MCELF::SetType(Asm.getSymbolData(*SectionSymbol), ELF::STT_SECTION);
+ }
}
void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
@@ -448,11 +462,13 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
} else {
DF = new MCDataFragment();
insert(DF);
- if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {
- // If this is a new fragment created for a bundle-locked group, and the
- // group was marked as "align_to_end", set a flag in the fragment.
- DF->setAlignToBundleEnd(true);
- }
+ }
+ if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {
+ // If this fragment is for a group marked "align_to_end", set a flag
+ // in the fragment. This can happen after the fragment has already been
+ // created if there are nested bundle_align groups and an inner one
+ // is the one marked align_to_end.
+ DF->setAlignToBundleEnd(true);
}
// We're now emitting an instruction in a bundle group, so this flag has
@@ -474,10 +490,11 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst,
void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
assert(AlignPow2 <= 30 && "Invalid bundle alignment");
MCAssembler &Assembler = getAssembler();
- if (Assembler.getBundleAlignSize() == 0 && AlignPow2 > 0)
- Assembler.setBundleAlignSize(1 << AlignPow2);
+ if (AlignPow2 > 0 && (Assembler.getBundleAlignSize() == 0 ||
+ Assembler.getBundleAlignSize() == 1U << AlignPow2))
+ Assembler.setBundleAlignSize(1U << AlignPow2);
else
- report_fatal_error(".bundle_align_mode should be only set once per file");
+ report_fatal_error(".bundle_align_mode cannot be changed once set");
}
void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
@@ -487,12 +504,12 @@ void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
//
if (!getAssembler().isBundlingEnabled())
report_fatal_error(".bundle_lock forbidden when bundling is disabled");
- else if (SD->isBundleLocked())
- report_fatal_error("Nesting of .bundle_lock is forbidden");
+
+ if (!SD->isBundleLocked())
+ SD->setBundleGroupBeforeFirstInst(true);
SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd :
MCSectionData::BundleLocked);
- SD->setBundleGroupBeforeFirstInst(true);
}
void MCELFStreamer::EmitBundleUnlock() {
@@ -543,12 +560,10 @@ void MCELFStreamer::FinishImpl() {
MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll, bool NoExecStack) {
+ bool RelaxAll) {
MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
- if (NoExecStack)
- S->getAssembler().setNoExecStack(true);
return S;
}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index f724716..6e648b2 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -49,12 +49,8 @@ void MCExpr::print(raw_ostream &OS) const {
else
OS << Sym;
- if (SRE.getKind() != MCSymbolRefExpr::VK_None) {
- if (SRE.getMCAsmInfo().useParensForSymbolVariant())
- OS << '(' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()) << ')';
- else
- OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
- }
+ if (SRE.getKind() != MCSymbolRefExpr::VK_None)
+ SRE.printVariantKind(OS);
return;
}
@@ -150,6 +146,15 @@ const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) {
/* *** */
+MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
+ const MCAsmInfo *MAI)
+ : MCExpr(MCExpr::SymbolRef), Kind(Kind),
+ UseParensForSymbolVariant(MAI->useParensForSymbolVariant()),
+ HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()),
+ Symbol(Symbol) {
+ assert(Symbol);
+}
+
const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym,
VariantKind Kind,
MCContext &Ctx) {
@@ -247,6 +252,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h";
case VK_PPC_GOT_TLSLD_HA: return "got@tlsld@ha";
case VK_PPC_TLSLD: return "tlsld";
+ case VK_PPC_LOCAL: return "local";
case VK_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
case VK_Mips_GOT16: return "GOT16";
@@ -273,7 +279,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_Mips_CALL_LO16: return "CALL_LO16";
case VK_Mips_PCREL_HI16: return "PCREL_HI16";
case VK_Mips_PCREL_LO16: return "PCREL_LO16";
- case VK_COFF_IMGREL32: return "IMGREL32";
+ case VK_COFF_IMGREL32: return "IMGREL";
}
llvm_unreachable("Invalid variant kind");
}
@@ -442,6 +448,13 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Default(VK_Invalid);
}
+void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const {
+ if (UseParensForSymbolVariant)
+ OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')';
+ else
+ OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind());
+}
+
/* *** */
void MCTargetExpr::anchor() {}
@@ -467,9 +480,27 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const {
return EvaluateAsAbsolute(Res, &Asm, nullptr, nullptr);
}
+int64_t MCExpr::evaluateKnownAbsolute(const MCAsmLayout &Layout) const {
+ int64_t Res;
+ bool Abs =
+ evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, true);
+ (void)Abs;
+ assert(Abs && "Not actually absolute");
+ return Res;
+}
+
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const SectionAddrMap *Addrs) const {
+ // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us
+ // absolutize differences across sections and that is what the MachO writer
+ // uses Addrs for.
+ return evaluateAsAbsolute(Res, Asm, Layout, Addrs, Addrs);
+}
+
+bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs, bool InSet) const {
MCValue Value;
// Fast path constants.
@@ -478,12 +509,8 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return true;
}
- // FIXME: The use if InSet = Addrs is a hack. Setting InSet causes us
- // absolutize differences across sections and that is what the MachO writer
- // uses Addrs for.
- bool IsRelocatable =
- EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs,
- /*ForceVarExpansion*/ false);
+ bool IsRelocatable = EvaluateAsRelocatableImpl(
+ Value, Asm, Layout, nullptr, Addrs, InSet, /*ForceVarExpansion*/ false);
// Record the current value.
Res = Value.getConstant();
@@ -632,27 +659,31 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm,
}
bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
- const MCAsmLayout *Layout) const {
+ const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const {
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
- return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
- /*ForceVarExpansion*/ false);
+ return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
+ false, /*ForceVarExpansion*/ false);
}
-bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const {
+bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const {
MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr;
- return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false,
- /*ForceVarExpansion*/ true);
+ return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr,
+ false, /*ForceVarExpansion*/ true);
}
bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
+ const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet,
bool ForceVarExpansion) const {
++stats::MCExprEvaluate;
switch (getKind()) {
case Target:
- return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout);
+ return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout,
+ Fixup);
case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
@@ -661,16 +692,15 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
case SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
- const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
// Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(
- Res, Asm, Layout, Addrs, true, ForceVarExpansion)) {
+ Res, Asm, Layout, Fixup, Addrs, true, ForceVarExpansion)) {
const MCSymbolRefExpr *A = Res.getSymA();
const MCSymbolRefExpr *B = Res.getSymB();
- if (MCAsmInfo.hasSubsectionsViaSymbols()) {
+ if (SRE->hasSubsectionsViaSymbols()) {
// FIXME: This is small hack. Given
// a = b + 4
// .long a
@@ -697,8 +727,9 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this);
MCValue Value;
- if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs,
- InSet, ForceVarExpansion))
+ if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout,
+ Fixup, Addrs, InSet,
+ ForceVarExpansion))
return false;
switch (AUE->getOpcode()) {
@@ -731,10 +762,12 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
- if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Addrs,
- InSet, ForceVarExpansion) ||
- !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Addrs,
- InSet, ForceVarExpansion))
+ if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout,
+ Fixup, Addrs, InSet,
+ ForceVarExpansion) ||
+ !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout,
+ Fixup, Addrs, InSet,
+ ForceVarExpansion))
return false;
// We only support a few operations on non-constant expressions, handle
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index 9e8bc94..a147c3d 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -55,6 +55,12 @@ public:
: MCObjectStreamer(Context, MAB, OS, Emitter),
LabelSections(label) {}
+ /// state management
+ void reset() override {
+ HasSectionLabel.clear();
+ MCObjectStreamer::reset();
+ }
+
/// @name MCStreamer Interface
/// @{
@@ -90,8 +96,8 @@ public:
unsigned ByteAlignment) override;
void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0) override;
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0) override;
+ void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment = 0) override;
void EmitFileDirective(StringRef Filename) override {
// FIXME: Just ignore the .file; it isn't important enough to fail the
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index d543402..fc56728 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -29,7 +29,6 @@ namespace {
return true;
}
- void EmitCOFFSecRel32(MCSymbol const *Symbol) override {}
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override {}
void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr,
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index d490ef3..1b88462 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -24,7 +24,7 @@ static bool useCompactUnwind(const Triple &T) {
return false;
// aarch64 always has it.
- if (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64)
+ if (T.getArch() == Triple::aarch64)
return true;
// Use it on newer version of OS X.
@@ -43,8 +43,7 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
// MachO
SupportsWeakOmittedEHFrame = false;
- if (T.isOSDarwin() &&
- (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64))
+ if (T.isOSDarwin() && T.getArch() == Triple::aarch64)
SupportsCompactUnwindWithoutEHFrame = true;
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel
@@ -178,7 +177,7 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86)
CompactUnwindDwarfEHFrameOnly = 0x04000000;
- else if (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64)
+ else if (T.getArch() == Triple::aarch64)
CompactUnwindDwarfEHFrameOnly = 0x03000000;
}
@@ -287,6 +286,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM)
break;
// Fallthrough if not using EHABI
+ case Triple::ppc:
case Triple::x86:
PersonalityEncoding = (RelocM == Reloc::PIC_)
? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
@@ -321,8 +321,6 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
break;
case Triple::aarch64:
case Triple::aarch64_be:
- case Triple::arm64:
- case Triple::arm64_be:
// The small model guarantees static code/data size < 4GB, but not where it
// will be in memory. Most of these could end up >2GB away so even a signed
// pc-relative 32-bit address is insufficient, theoretically.
@@ -340,6 +338,8 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
break;
case Triple::mips:
case Triple::mipsel:
+ case Triple::mips64:
+ case Triple::mips64el:
// MIPS uses indirect pointer to refer personality functions, so that the
// eh_frame section can be read-only. DW.ref.personality will be generated
// for relocation.
@@ -563,6 +563,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfInfoDWOSection =
Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfTypesDWOSection =
+ Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfAbbrevDWOSection =
Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
@@ -582,15 +585,19 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfAddrSection =
Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+
+ StackMapSection =
+ Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS,
+ ELF::SHF_ALLOC,
+ SectionKind::getMetadata());
+
}
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
bool IsWoA = T.getArch() == Triple::arm || T.getArch() == Triple::thumb;
- // The object file format cannot represent common symbols with explicit
- // alignments.
- CommDirectiveSupportsAlignment = false;
+ CommDirectiveSupportsAlignment = true;
// COFF
BSSSection =
@@ -738,6 +745,10 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfTypesDWOSection =
+ Ctx->getCOFFSection(".debug_types.dwo", COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfAbbrevDWOSection =
Ctx->getCOFFSection(".debug_abbrev.dwo",
COFF::IMAGE_SCN_MEM_DISCARDABLE |
@@ -770,6 +781,27 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfAccelNamesSection =
+ Ctx->getCOFFSection(".apple_names",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfAccelNamespaceSection =
+ Ctx->getCOFFSection(".apple_namespaces",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfAccelTypesSection =
+ Ctx->getCOFFSection(".apple_types",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfAccelObjCSection =
+ Ctx->getCOFFSection(".apple_objc",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+
DrectveSection =
Ctx->getCOFFSection(".drectve",
COFF::IMAGE_SCN_LNK_INFO |
@@ -827,7 +859,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm,
// cellspu-apple-darwin. Perhaps we should fix in Triple?
if ((Arch == Triple::x86 || Arch == Triple::x86_64 ||
Arch == Triple::arm || Arch == Triple::thumb ||
- Arch == Triple::arm64 || Arch == Triple::aarch64 ||
+ Arch == Triple::aarch64 ||
Arch == Triple::ppc || Arch == Triple::ppc64 ||
Arch == Triple::UnknownArch) &&
(TT.isOSDarwin() || TT.isOSBinFormatMachO())) {
@@ -849,13 +881,6 @@ const MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const {
SectionKind::getMetadata(), 0, utostr(Hash));
}
-const MCSection *
-MCObjectFileInfo::getDwarfTypesDWOSection(uint64_t Hash) const {
- return Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS,
- ELF::SHF_GROUP, SectionKind::getMetadata(), 0,
- utostr(Hash));
-}
-
void MCObjectFileInfo::InitEHFrameSection() {
if (Env == IsMachO)
EHFrameSection =
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index a721b59..21e6867 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -42,6 +42,21 @@ MCObjectStreamer::~MCObjectStreamer() {
delete Assembler;
}
+void MCObjectStreamer::flushPendingLabels(MCFragment *F) {
+ if (PendingLabels.size()) {
+ if (!F) {
+ F = new MCDataFragment();
+ CurSectionData->getFragmentList().insert(CurInsertionPoint, F);
+ F->setParent(CurSectionData);
+ }
+ for (MCSymbolData *SD : PendingLabels) {
+ SD->setFragment(F);
+ SD->setOffset(0);
+ }
+ PendingLabels.clear();
+ }
+}
+
void MCObjectStreamer::reset() {
if (Assembler)
Assembler->reset();
@@ -49,6 +64,7 @@ void MCObjectStreamer::reset() {
CurInsertionPoint = MCSectionData::iterator();
EmitEHFrame = true;
EmitDebugFrame = false;
+ PendingLabels.clear();
MCStreamer::reset();
}
@@ -72,7 +88,7 @@ MCFragment *MCObjectStreamer::getCurrentFragment() const {
return nullptr;
}
-MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
+MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
// When bundling is enabled, we don't want to add data to a fragment that
// already has instructions (see MCELFStreamer::EmitInstToData for details)
@@ -127,15 +143,17 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
MCStreamer::EmitLabel(Symbol);
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
-
- // FIXME: This is wasteful, we don't necessarily need to create a data
- // fragment. Instead, we should mark the symbol as pointing into the data
- // fragment if it exists, otherwise we should just queue the label and set its
- // fragment pointer when we emit the next fragment.
- MCDataFragment *F = getOrCreateDataFragment();
assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
- SD.setFragment(F);
- SD.setOffset(F->getContents().size());
+
+ // If there is a current fragment, mark the symbol as pointing into it.
+ // Otherwise queue the label and set its fragment pointer when we emit the
+ // next fragment.
+ if (auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment())) {
+ SD.setFragment(F);
+ SD.setOffset(F->getContents().size());
+ } else {
+ PendingLabels.push_back(&SD);
+ }
}
void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
@@ -144,7 +162,6 @@ void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
EmitULEB128IntValue(IntValue);
return;
}
- Value = ForceExpAbs(Value);
insert(new MCLEBFragment(*Value, false));
}
@@ -154,7 +171,6 @@ void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitSLEB128IntValue(IntValue);
return;
}
- Value = ForceExpAbs(Value);
insert(new MCLEBFragment(*Value, true));
}
@@ -166,6 +182,7 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
void MCObjectStreamer::ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
+ flushPendingLabels(nullptr);
CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
@@ -266,33 +283,54 @@ void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
Isa, Discriminator, FileName);
}
+static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
+ const MCSymbol *B) {
+ MCContext &Context = OS.getContext();
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *ARef = MCSymbolRefExpr::Create(A, Variant, Context);
+ const MCExpr *BRef = MCSymbolRefExpr::Create(B, Variant, Context);
+ const MCExpr *AddrDelta =
+ MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
+ return AddrDelta;
+}
+
+static void emitDwarfSetLineAddr(MCObjectStreamer &OS, int64_t LineDelta,
+ const MCSymbol *Label, int PointerSize) {
+ // emit the sequence to set the address
+ OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
+ OS.EmitULEB128IntValue(PointerSize + 1);
+ OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
+ OS.EmitSymbolValue(Label, PointerSize);
+
+ // emit the sequence for the LineDelta (from 1) and a zero address delta.
+ MCDwarfLineAddr::Emit(&OS, LineDelta, 0);
+}
+
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) {
if (!LastLabel) {
- EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
+ emitDwarfSetLineAddr(*this, LineDelta, Label, PointerSize);
return;
}
- const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
+ const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
int64_t Res;
if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
MCDwarfLineAddr::Emit(this, LineDelta, Res);
return;
}
- AddrDelta = ForceExpAbs(AddrDelta);
insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
}
void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label) {
- const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
+ const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
int64_t Res;
if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
return;
}
- AddrDelta = ForceExpAbs(AddrDelta);
insert(new MCDwarfCallFrameFragment(*AddrDelta));
}
@@ -379,5 +417,6 @@ void MCObjectStreamer::FinishImpl() {
// Dump out the dwarf file & directory tables and line tables.
MCDwarfLineTable::Emit(this);
+ flushPendingLabels(nullptr);
getAssembler().Finish();
}
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index 145ad4a..5c8ec66 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -417,7 +417,7 @@ AsmToken AsmLexer::LexQuote() {
StringRef AsmLexer::LexUntilEndOfStatement() {
TokStart = CurPtr;
- while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
+ while (!isAtStartOfComment(CurPtr) && // Start of line comment.
!isAtStatementSeparator(CurPtr) && // End of statement marker.
*CurPtr != '\n' && *CurPtr != '\r' &&
(*CurPtr != 0 || CurPtr != CurBuf.end())) {
@@ -458,9 +458,17 @@ const AsmToken AsmLexer::peekTok(bool ShouldSkipSpace) {
return Token;
}
-bool AsmLexer::isAtStartOfComment(char Char) {
- // FIXME: This won't work for multi-character comment indicators like "//".
- return Char == *MAI.getCommentString();
+bool AsmLexer::isAtStartOfComment(const char *Ptr) {
+ const char *CommentString = MAI.getCommentString();
+
+ if (CommentString[1] == '\0')
+ return CommentString[0] == Ptr[0];
+
+ // FIXME: special case for the bogus "##" comment string in X86MCAsmInfoDarwin
+ if (CommentString[1] == '#')
+ return CommentString[0] == Ptr[0];
+
+ return strncmp(Ptr, CommentString, strlen(CommentString)) == 0;
}
bool AsmLexer::isAtStatementSeparator(const char *Ptr) {
@@ -473,7 +481,7 @@ AsmToken AsmLexer::LexToken() {
// This always consumes at least one character.
int CurChar = getNextChar();
- if (isAtStartOfComment(CurChar)) {
+ if (isAtStartOfComment(TokStart)) {
// If this comment starts with a '#', then return the Hash token and let
// the assembler parser see if it can be parsed as a cpp line filename
// comment. We do this only if we are at the start of a line.
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 62ab4a5..de7d961 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -45,10 +45,6 @@
#include <vector>
using namespace llvm;
-static cl::opt<bool>
-FatalAssemblerWarnings("fatal-assembler-warnings",
- cl::desc("Consider warnings as error"));
-
MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
@@ -73,19 +69,13 @@ struct MCAsmMacro {
MCAsmMacroParameters Parameters;
public:
- MCAsmMacro(StringRef N, StringRef B, ArrayRef<MCAsmMacroParameter> P) :
- Name(N), Body(B), Parameters(P) {}
+ MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
+ : Name(N), Body(B), Parameters(std::move(P)) {}
};
/// \brief Helper class for storing information about an active macro
/// instantiation.
struct MacroInstantiation {
- /// The macro being instantiated.
- const MCAsmMacro *TheMacro;
-
- /// The macro instantiation with substitutions.
- MemoryBuffer *Instantiation;
-
/// The location of the instantiation.
SMLoc InstantiationLoc;
@@ -95,9 +85,11 @@ struct MacroInstantiation {
/// The location where parsing should resume upon instantiation completion.
SMLoc ExitLoc;
+ /// The depth of TheCondStack at the start of the instantiation.
+ size_t CondStackDepth;
+
public:
- MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL,
- MemoryBuffer *I);
+ MacroInstantiation(SMLoc IL, int EB, SMLoc EL, size_t CondStackDepth);
};
struct ParseStatementInfo {
@@ -129,7 +121,7 @@ private:
SourceMgr &SrcMgr;
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
- MCAsmParserExtension *PlatformParser;
+ std::unique_ptr<MCAsmParserExtension> PlatformParser;
/// This is the current buffer index we're lexing from as managed by the
/// SourceMgr object.
@@ -144,7 +136,7 @@ private:
StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
/// \brief Map of currently defined macros.
- StringMap<MCAsmMacro*> MacroMap;
+ StringMap<MCAsmMacro> MacroMap;
/// \brief Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
@@ -246,7 +238,8 @@ public:
private:
- bool parseStatement(ParseStatementInfo &Info);
+ bool parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI);
void eatToEndOfLine();
bool parseCppHashLineFilenameComment(const SMLoc &L);
@@ -269,7 +262,7 @@ private:
const MCAsmMacro* lookupMacro(StringRef Name);
/// \brief Define a new macro with the given name and information.
- void defineMacro(StringRef Name, const MCAsmMacro& Macro);
+ void defineMacro(StringRef Name, MCAsmMacro Macro);
/// \brief Undefine a macro. If no such macro was defined, it's a no-op.
void undefineMacro(StringRef Name);
@@ -355,9 +348,10 @@ private:
DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
- DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
+ DK_MACROS_ON, DK_MACROS_OFF,
+ DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_SLEB128, DK_ULEB128,
- DK_ERR, DK_ERROR,
+ DK_ERR, DK_ERROR, DK_WARNING,
DK_END
};
@@ -407,6 +401,7 @@ private:
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool parseDirectiveExitMacro(StringRef Directive);
bool parseDirectiveEndMacro(StringRef Directive);
bool parseDirectiveMacro(SMLoc DirectiveLoc);
bool parseDirectiveMacrosOnOff(StringRef Directive);
@@ -474,6 +469,9 @@ private:
// ".err" or ".error"
bool parseDirectiveError(SMLoc DirectiveLoc, bool WithMessage);
+ // ".warning"
+ bool parseDirectiveWarning(SMLoc DirectiveLoc);
+
void initializeDirectiveKindMap();
};
}
@@ -504,34 +502,24 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
// Initialize the platform / file format parser.
switch (_Ctx.getObjectFileInfo()->getObjectFileType()) {
case MCObjectFileInfo::IsCOFF:
- PlatformParser = createCOFFAsmParser();
- PlatformParser->Initialize(*this);
- break;
+ PlatformParser.reset(createCOFFAsmParser());
+ break;
case MCObjectFileInfo::IsMachO:
- PlatformParser = createDarwinAsmParser();
- PlatformParser->Initialize(*this);
- IsDarwin = true;
- break;
+ PlatformParser.reset(createDarwinAsmParser());
+ IsDarwin = true;
+ break;
case MCObjectFileInfo::IsELF:
- PlatformParser = createELFAsmParser();
- PlatformParser->Initialize(*this);
- break;
+ PlatformParser.reset(createELFAsmParser());
+ break;
}
+ PlatformParser->Initialize(*this);
initializeDirectiveKindMap();
}
AsmParser::~AsmParser() {
assert((HadError || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
-
- // Destroy any macros.
- for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(),
- ie = MacroMap.end();
- it != ie; ++it)
- delete it->getValue();
-
- delete PlatformParser;
}
void AsmParser::printMacroInstantiations() {
@@ -550,7 +538,7 @@ void AsmParser::Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
}
bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
- if (FatalAssemblerWarnings)
+ if (getTargetParser().getTargetOptions().MCFatalWarnings)
return Error(L, Msg, Ranges);
printMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
printMacroInstantiations();
@@ -619,7 +607,7 @@ const AsmToken &AsmParser::Lex() {
bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Create the initial section, if requested.
if (!NoInitialTextSection)
- Out.InitSections();
+ Out.InitSections(false);
// Prime the lexer.
Lex();
@@ -643,7 +631,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
ParseStatementInfo Info;
- if (!parseStatement(Info))
+ if (!parseStatement(Info, nullptr))
continue;
// We had an error, validate that one was emitted and recover by skipping to
@@ -702,7 +690,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
void AsmParser::checkForValidSection() {
if (!ParsingInlineAsm && !getStreamer().getCurrentSection().first) {
TokError("expected section directive before assembly directive");
- Out.InitSections();
+ Out.InitSections(false);
}
}
@@ -1188,7 +1176,8 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
/// ::= EndOfStatement
/// ::= Label* Directive ...Operands... EndOfStatement
/// ::= Label* Identifier OperandList* EndOfStatement
-bool AsmParser::parseStatement(ParseStatementInfo &Info) {
+bool AsmParser::parseStatement(ParseStatementInfo &Info,
+ MCAsmParserSemaCallback *SI) {
if (Lexer.is(AsmToken::EndOfStatement)) {
Out.AddBlankLine();
Lex();
@@ -1298,9 +1287,16 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
// FIXME: This doesn't diagnose assignment to a symbol which has been
// implicitly marked as external.
MCSymbol *Sym;
- if (LocalLabelVal == -1)
+ if (LocalLabelVal == -1) {
+ if (ParsingInlineAsm && SI) {
+ StringRef RewrittenLabel = SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
+ assert(RewrittenLabel.size() && "We should have an internal name here.");
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Label, IDLoc,
+ IDVal.size(), RewrittenLabel));
+ IDVal = RewrittenLabel;
+ }
Sym = getContext().GetOrCreateSymbol(IDVal);
- else
+ } else
Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
@@ -1542,6 +1538,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
return parseDirectiveMacrosOnOff(IDVal);
case DK_MACRO:
return parseDirectiveMacro(IDLoc);
+ case DK_EXITM:
+ return parseDirectiveExitMacro(IDVal);
case DK_ENDM:
case DK_ENDMACRO:
return parseDirectiveEndMacro(IDVal);
@@ -1553,6 +1551,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
return parseDirectiveError(IDLoc, false);
case DK_ERROR:
return parseDirectiveError(IDLoc, true);
+ case DK_WARNING:
+ return parseDirectiveWarning(IDLoc);
}
return Error(IDLoc, "unknown directive");
@@ -1630,7 +1630,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
// If parsing succeeded, match the instruction.
if (!HadError) {
- unsigned ErrorInfo;
+ uint64_t ErrorInfo;
getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
Info.ParsedOperands, Out,
ErrorInfo, ParsingInlineAsm);
@@ -1856,10 +1856,10 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
return false;
}
-MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB,
- SMLoc EL, MemoryBuffer *I)
- : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB),
- ExitLoc(EL) {}
+MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
+ size_t CondStackDepth)
+ : InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
+ CondStackDepth(CondStackDepth) {}
static bool isOperator(AsmToken::TokenKind kind) {
switch (kind) {
@@ -2078,21 +2078,15 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
}
const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) {
- StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name);
- return (I == MacroMap.end()) ? nullptr : I->getValue();
+ StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
+ return (I == MacroMap.end()) ? nullptr : &I->getValue();
}
-void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) {
- MacroMap[Name] = new MCAsmMacro(Macro);
+void AsmParser::defineMacro(StringRef Name, MCAsmMacro Macro) {
+ MacroMap.insert(std::make_pair(Name, std::move(Macro)));
}
-void AsmParser::undefineMacro(StringRef Name) {
- StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name);
- if (I != MacroMap.end()) {
- delete I->getValue();
- MacroMap.erase(I);
- }
-}
+void AsmParser::undefineMacro(StringRef Name) { MacroMap.erase(Name); }
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
@@ -2117,17 +2111,17 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// instantiation.
OS << ".endmacro\n";
- MemoryBuffer *Instantiation =
+ std::unique_ptr<MemoryBuffer> Instantiation =
MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
// Create the macro instantiation object and add to the current macro
// instantiation stack.
MacroInstantiation *MI = new MacroInstantiation(
- M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
+ CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
@@ -2600,12 +2594,14 @@ bool AsmParser::parseDirectiveFill() {
if (!isUInt<32>(FillExpr) && FillSize > 4)
Warning(ExprLoc, "'.fill' directive pattern has been truncated to 32-bits");
- int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize;
- FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8);
-
- for (uint64_t i = 0, e = NumValues; i != e; ++i) {
- getStreamer().EmitIntValue(FillExpr, NonZeroFillSize);
- getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize);
+ if (NumValues > 0) {
+ int64_t NonZeroFillSize = FillSize > 4 ? 4 : FillSize;
+ FillExpr &= ~0ULL >> (64 - NonZeroFillSize * 8);
+ for (uint64_t i = 0, e = NumValues; i != e; ++i) {
+ getStreamer().EmitIntValue(FillExpr, NonZeroFillSize);
+ if (NonZeroFillSize < FillSize)
+ getStreamer().EmitIntValue(0, FillSize - NonZeroFillSize);
+ }
}
return false;
@@ -3292,7 +3288,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
if (Qualifier == "req")
Parameter.Required = true;
- else if (Qualifier == "vararg" && !IsDarwin)
+ else if (Qualifier == "vararg")
Parameter.Vararg = true;
else
return Error(QualLoc, Qualifier + " is not a valid parameter qualifier "
@@ -3313,7 +3309,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
"'" + Parameter.Name + "' in macro '" + Name + "'");
}
- Parameters.push_back(Parameter);
+ Parameters.push_back(std::move(Parameter));
if (getLexer().is(AsmToken::Comma))
Lex();
@@ -3365,7 +3361,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
const char *BodyEnd = EndToken.getLoc().getPointer();
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
- defineMacro(Name, MCAsmMacro(Name, Body, Parameters));
+ defineMacro(Name, MCAsmMacro(Name, Body, std::move(Parameters)));
return false;
}
@@ -3471,6 +3467,26 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
"found in body which will have no effect");
}
+/// parseDirectiveExitMacro
+/// ::= .exitm
+bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Directive + "' directive");
+
+ if (!isInsideMacroInstantiation())
+ return TokError("unexpected '" + Directive + "' in file, "
+ "no current macro definition");
+
+ // Exit all conditionals that are active in the current macro.
+ while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
+ TheCondState = TheCondStack.back();
+ TheCondStack.pop_back();
+ }
+
+ handleMacroExit();
+ return false;
+}
+
/// parseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
@@ -4073,6 +4089,32 @@ bool AsmParser::parseDirectiveError(SMLoc L, bool WithMessage) {
return true;
}
+/// parseDirectiveWarning
+/// ::= .warning [string]
+bool AsmParser::parseDirectiveWarning(SMLoc L) {
+ if (!TheCondStack.empty()) {
+ if (TheCondStack.back().Ignore) {
+ eatToEndOfStatement();
+ return false;
+ }
+ }
+
+ StringRef Message = ".warning directive invoked in source file";
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (Lexer.isNot(AsmToken::String)) {
+ TokError(".warning argument must be a string");
+ eatToEndOfStatement();
+ return true;
+ }
+
+ Message = getTok().getStringContents();
+ Lex();
+ }
+
+ Warning(L, Message);
+ return false;
+}
+
/// parseDirectiveEndIf
/// ::= .endif
bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
@@ -4200,11 +4242,13 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
+ DirectiveKindMap[".exitm"] = DK_EXITM;
DirectiveKindMap[".endm"] = DK_ENDM;
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
DirectiveKindMap[".purgem"] = DK_PURGEM;
DirectiveKindMap[".err"] = DK_ERR;
DirectiveKindMap[".error"] = DK_ERROR;
+ DirectiveKindMap[".warning"] = DK_WARNING;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
@@ -4246,7 +4290,8 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
// We Are Anonymous.
- MacroLikeBodies.push_back(MCAsmMacro(StringRef(), Body, None));
+ MacroLikeBodies.push_back(
+ MCAsmMacro(StringRef(), Body, MCAsmMacroParameters()));
return &MacroLikeBodies.back();
}
@@ -4254,17 +4299,17 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS) {
OS << ".endr\n";
- MemoryBuffer *Instantiation =
+ std::unique_ptr<MemoryBuffer> Instantiation =
MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
// Create the macro instantiation object and add to the current macro
// instantiation stack.
MacroInstantiation *MI = new MacroInstantiation(
- M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ DirectiveLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
- CurBuffer = SrcMgr.AddNewSourceBuffer(MI->Instantiation, SMLoc());
+ CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
Lex();
}
@@ -4490,7 +4535,7 @@ bool AsmParser::parseMSInlineAsm(
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
- if (parseStatement(Info))
+ if (parseStatement(Info, &SI))
return true;
if (Info.ParseError)
@@ -4510,7 +4555,8 @@ bool AsmParser::parseMSInlineAsm(
continue;
// Register operand.
- if (Operand.isReg() && !Operand.needAddressOf()) {
+ if (Operand.isReg() && !Operand.needAddressOf() &&
+ !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
unsigned NumDefs = Desc.getNumDefs();
// Clobber.
if (NumDefs && Operand.getMCOperandNum() < NumDefs)
@@ -4615,6 +4661,9 @@ bool AsmParser::parseMSInlineAsm(
case AOK_ImmPrefix:
OS << "$$";
break;
+ case AOK_Label:
+ OS << Ctx.getAsmInfo()->getPrivateGlobalPrefix() << AR.Label;
+ break;
case AOK_Input:
OS << '$' << InputIdx++;
break;
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index 5ecf9e5..6f82e6e 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -364,6 +364,10 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
+ if (!getLexer().is(AsmToken::Identifier))
+ return TokError("expected comdat type such as 'discard' or 'largest' "
+ "after protection bits");
+
if (parseCOMDATType(Type))
return true;
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index b2a6785..3ea745e 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -638,13 +638,13 @@ bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
// Open the secure log file if we haven't already.
raw_ostream *OS = getContext().getSecureLog();
if (!OS) {
- std::string Err;
- OS = new raw_fd_ostream(SecureLogFile, Err,
+ std::error_code EC;
+ OS = new raw_fd_ostream(SecureLogFile, EC,
sys::fs::F_Append | sys::fs::F_Text);
- if (!Err.empty()) {
+ if (EC) {
delete OS;
return Error(IDLoc, Twine("can't open secure log file: ") +
- SecureLogFile + " (" + Err + ")");
+ SecureLogFile + " (" + EC.message() + ")");
}
getContext().setSecureLog(OS);
}
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 98b2b3b..e302004 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -555,7 +555,7 @@ EndStmt:
std::make_pair(ELFSection, std::make_pair(nullptr, nullptr)));
if (InsertResult.second) {
if (getContext().getDwarfVersion() <= 2)
- Error(loc, "DWARF2 only supports one section per compilation unit");
+ Warning(loc, "DWARF2 only supports one section per compilation unit");
MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol();
getStreamer().EmitLabel(SectionStartSymbol);
diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index 530814b..795cc85 100644
--- a/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -30,3 +30,7 @@ SMLoc AsmToken::getLoc() const {
SMLoc AsmToken::getEndLoc() const {
return SMLoc::getFromPointer(Str.data() + Str.size());
}
+
+SMRange AsmToken::getLocRange() const {
+ return SMRange(getLoc(), getEndLoc());
+}
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index e417aa9..290dcb2 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -29,7 +29,7 @@ void MCAsmParser::setTargetParser(MCTargetAsmParser &P) {
TargetParser->Initialize(*this);
}
-const AsmToken &MCAsmParser::getTok() {
+const AsmToken &MCAsmParser::getTok() const {
return getLexer().getTok();
}
diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp
index fc2bd36..e95845f0 100644
--- a/lib/MC/MCSectionCOFF.cpp
+++ b/lib/MC/MCSectionCOFF.cpp
@@ -47,18 +47,22 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
}
OS << "\t.section\t" << getSectionName() << ",\"";
- if (getKind().isText())
+ if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)
OS << 'x';
- else if (getKind().isBSS())
- OS << 'b';
- if (getKind().isWriteable())
+ if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)
OS << 'w';
- else
+ else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)
OS << 'r';
- if (getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE)
- OS << 'n';
+ else
+ OS << 'y';
if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
OS << 'd';
+ if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ OS << 'b';
+ if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)
+ OS << 'n';
+ if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)
+ OS << 's';
OS << '"';
if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
index 09eb3e7..a29bb97 100644
--- a/lib/MC/MCSectionELF.cpp
+++ b/lib/MC/MCSectionELF.cpp
@@ -19,8 +19,8 @@ using namespace llvm;
MCSectionELF::~MCSectionELF() {} // anchor.
-// ShouldOmitSectionDirective - Decides whether a '.section' directive
-// should be printed before the section name
+// Decides whether a '.section' directive
+// should be printed before the section name.
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index bdcdb97..f11ee66 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
@@ -37,47 +38,26 @@ void MCTargetStreamer::finish() {}
void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
MCStreamer::MCStreamer(MCContext &Ctx)
- : Context(Ctx), CurrentW64UnwindInfo(nullptr) {
+ : Context(Ctx), CurrentWinFrameInfo(nullptr) {
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
}
MCStreamer::~MCStreamer() {
- for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
- delete W64UnwindInfos[i];
+ for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
+ delete WinFrameInfos[i];
}
void MCStreamer::reset() {
- for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
- delete W64UnwindInfos[i];
- W64UnwindInfos.clear();
- CurrentW64UnwindInfo = nullptr;
+ DwarfFrameInfos.clear();
+ for (unsigned i = 0; i < getNumWinFrameInfos(); ++i)
+ delete WinFrameInfos[i];
+ WinFrameInfos.clear();
+ CurrentWinFrameInfo = nullptr;
+ SymbolOrdering.clear();
SectionStack.clear();
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
}
-const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
- const MCSymbol *A,
- const MCSymbol *B) {
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- const MCExpr *ARef =
- MCSymbolRefExpr::Create(A, Variant, Context);
- const MCExpr *BRef =
- MCSymbolRefExpr::Create(B, Variant, Context);
- const MCExpr *AddrDelta =
- MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
- return AddrDelta;
-}
-
-const MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
- assert(!isa<MCSymbolRefExpr>(Expr));
- if (Context.getAsmInfo()->hasAggressiveSymbolFolding())
- return Expr;
-
- MCSymbol *ABS = Context.CreateTempSymbol();
- EmitAssignment(ABS, Expr);
- return MCSymbolRefExpr::Create(ABS, Context);
-}
-
raw_ostream &MCStreamer::GetCommentOS() {
// By default, discard comments.
return nulls();
@@ -86,28 +66,15 @@ raw_ostream &MCStreamer::GetCommentOS() {
void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
- for (std::vector<MCDwarfFrameInfo>::iterator I = FrameInfos.begin(),
- E = FrameInfos.end(); I != E; ++I)
- I->CompactUnwindEncoding =
- (MAB ? MAB->generateCompactUnwindEncoding(I->Instructions) : 0);
-}
-
-void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
- const MCSymbol *Label, int PointerSize) {
- // emit the sequence to set the address
- EmitIntValue(dwarf::DW_LNS_extended_op, 1);
- EmitULEB128IntValue(PointerSize + 1);
- EmitIntValue(dwarf::DW_LNE_set_address, 1);
- EmitSymbolValue(Label, PointerSize);
-
- // emit the sequence for the LineDelta (from 1) and a zero address delta.
- MCDwarfLineAddr::Emit(this, LineDelta, 0);
+ for (auto &FI : DwarfFrameInfos)
+ FI.CompactUnwindEncoding =
+ (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
}
/// EmitIntValue - Special case of EmitValue that avoids the client having to
/// pass in a MCExpr for constant integers.
void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
- assert(Size <= 8 && "Invalid size");
+ assert(1 <= Size && Size <= 8 && "Invalid size");
assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
"Invalid size");
char buf[8];
@@ -137,19 +104,20 @@ void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
EmitBytes(OSE.str());
}
-void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) {
- const MCExpr *ABS = ForceExpAbs(Value);
- EmitValue(ABS, Size);
-}
-
-
void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
EmitValueImpl(Value, Size, Loc);
}
-void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) {
- EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
+void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ bool IsSectionRelative) {
+ assert((!IsSectionRelative || Size == 4) &&
+ "SectionRelative value requires 4-bytes");
+
+ if (!IsSectionRelative)
+ EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
+ else
+ EmitCOFFSecRel32(Sym);
}
void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
@@ -198,14 +166,14 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
return Table.getLabel();
}
-MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() {
- if (FrameInfos.empty())
+MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
+ if (DwarfFrameInfos.empty())
return nullptr;
- return &FrameInfos.back();
+ return &DwarfFrameInfos.back();
}
-void MCStreamer::EnsureValidFrame() {
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+void MCStreamer::EnsureValidDwarfFrame() {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame || CurFrame->End)
report_fatal_error("No open frame");
}
@@ -214,7 +182,7 @@ void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol) {
}
-void MCStreamer::InitSections() {
+void MCStreamer::InitSections(bool NoExecStack) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
@@ -239,18 +207,12 @@ void MCStreamer::EmitLabel(MCSymbol *Symbol) {
TS->emitLabel(Symbol);
}
-void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
- CurFrame->CompactUnwindEncoding = CompactUnwindEncoding;
-}
-
void MCStreamer::EmitCFISections(bool EH, bool Debug) {
assert(EH || Debug);
}
void MCStreamer::EmitCFIStartProc(bool IsSimple) {
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (CurFrame && !CurFrame->End)
report_fatal_error("Starting a frame before finishing the previous one!");
@@ -258,15 +220,25 @@ void MCStreamer::EmitCFIStartProc(bool IsSimple) {
Frame.IsSimple = IsSimple;
EmitCFIStartProcImpl(Frame);
- FrameInfos.push_back(Frame);
+ const MCAsmInfo* MAI = Context.getAsmInfo();
+ if (MAI) {
+ for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
+ if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
+ Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
+ Frame.CurrentCfaRegister = Inst.getRegister();
+ }
+ }
+ }
+
+ DwarfFrameInfos.push_back(Frame);
}
void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
}
void MCStreamer::EmitCFIEndProc() {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
EmitCFIEndProcImpl(*CurFrame);
}
@@ -277,7 +249,7 @@ void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
}
MCSymbol *MCStreamer::EmitCFICommon() {
- EnsureValidFrame();
+ EnsureValidDwarfFrame();
MCSymbol *Label = getContext().CreateTempSymbol();
EmitLabel(Label);
return Label;
@@ -287,15 +259,16 @@ void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfa(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
+ CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
}
void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfaOffset(Label, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -303,7 +276,7 @@ void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -311,15 +284,16 @@ void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createDefCfaRegister(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
+ CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
}
void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createOffset(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -327,21 +301,21 @@ void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRelOffset(Label, Register, Offset);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
unsigned Encoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Personality = Sym;
CurFrame->PersonalityEncoding = Encoding;
}
void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Lsda = Sym;
CurFrame->LsdaEncoding = Encoding;
}
@@ -349,7 +323,7 @@ void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
void MCStreamer::EmitCFIRememberState() {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -357,7 +331,7 @@ void MCStreamer::EmitCFIRestoreState() {
// FIXME: Error if there is no matching cfi_remember_state.
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -365,7 +339,7 @@ void MCStreamer::EmitCFISameValue(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createSameValue(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -373,20 +347,20 @@ void MCStreamer::EmitCFIRestore(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRestore(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFIEscape(StringRef Values) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
void MCStreamer::EmitCFISignalFrame() {
- EnsureValidFrame();
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->IsSignalFrame = true;
}
@@ -394,7 +368,7 @@ void MCStreamer::EmitCFIUndefined(int64_t Register) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createUndefined(Label, Register);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -402,7 +376,7 @@ void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createRegister(Label, Register1, Register2);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
@@ -410,164 +384,167 @@ void MCStreamer::EmitCFIWindowSave() {
MCSymbol *Label = EmitCFICommon();
MCCFIInstruction Instruction =
MCCFIInstruction::createWindowSave(Label);
- MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
CurFrame->Instructions.push_back(Instruction);
}
-void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
- W64UnwindInfos.push_back(Frame);
- CurrentW64UnwindInfo = W64UnwindInfos.back();
-}
-
-void MCStreamer::EnsureValidW64UnwindInfo() {
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (!CurFrame || CurFrame->End)
+void MCStreamer::EnsureValidWinFrameInfo() {
+ if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
report_fatal_error("No open Win64 EH frame function!");
}
void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame && !CurFrame->End)
+ if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
report_fatal_error("Starting a function before ending the previous one!");
- MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
- Frame->Begin = getContext().CreateTempSymbol();
- Frame->Function = Symbol;
- EmitLabel(Frame->Begin);
- setCurrentW64UnwindInfo(Frame);
+
+ MCSymbol *StartProc = getContext().CreateTempSymbol();
+ EmitLabel(StartProc);
+
+ WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc));
+ CurrentWinFrameInfo = WinFrameInfos.back();
}
void MCStreamer::EmitWinCFIEndProc() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Not all chained regions terminated!");
- CurFrame->End = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->End);
+
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+ CurrentWinFrameInfo->End = Label;
}
void MCStreamer::EmitWinCFIStartChained() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo;
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- Frame->Begin = getContext().CreateTempSymbol();
- Frame->Function = CurFrame->Function;
- Frame->ChainedParent = CurFrame;
- EmitLabel(Frame->Begin);
- setCurrentW64UnwindInfo(Frame);
+ EnsureValidWinFrameInfo();
+
+ MCSymbol *StartProc = getContext().CreateTempSymbol();
+ EmitLabel(StartProc);
+
+ WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function,
+ StartProc, CurrentWinFrameInfo));
+ CurrentWinFrameInfo = WinFrameInfos.back();
}
void MCStreamer::EmitWinCFIEndChained() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (!CurFrame->ChainedParent)
+ EnsureValidWinFrameInfo();
+ if (!CurrentWinFrameInfo->ChainedParent)
report_fatal_error("End of a chained region outside a chained region!");
- CurFrame->End = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->End);
- CurrentW64UnwindInfo = CurFrame->ChainedParent;
+
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+
+ CurrentWinFrameInfo->End = Label;
+ CurrentWinFrameInfo =
+ const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent);
}
void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
bool Except) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Chained unwind areas can't have handlers!");
- CurFrame->ExceptionHandler = Sym;
+ CurrentWinFrameInfo->ExceptionHandler = Sym;
if (!Except && !Unwind)
report_fatal_error("Don't know what kind of handler this is!");
if (Unwind)
- CurFrame->HandlesUnwind = true;
+ CurrentWinFrameInfo->HandlesUnwind = true;
if (Except)
- CurFrame->HandlesExceptions = true;
+ CurrentWinFrameInfo->HandlesExceptions = true;
}
void MCStreamer::EmitWinEHHandlerData() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->ChainedParent)
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->ChainedParent)
report_fatal_error("Chained unwind areas can't have handlers!");
}
void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+ EnsureValidWinFrameInfo();
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->LastFrameInst >= 0)
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->LastFrameInst >= 0)
report_fatal_error("Frame register and offset already specified!");
if (Offset & 0x0F)
report_fatal_error("Misaligned frame pointer offset!");
if (Offset > 240)
report_fatal_error("Frame offset must be less than or equal to 240!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset);
EmitLabel(Label);
- CurFrame->LastFrameInst = CurFrame->Instructions.size();
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SetFPReg(Label, Register, Offset);
+ CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
- EnsureValidW64UnwindInfo();
+ EnsureValidWinFrameInfo();
if (Size == 0)
report_fatal_error("Allocation size must be non-zero!");
if (Size & 7)
report_fatal_error("Misaligned stack allocation!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Label, Size);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
+ EnsureValidWinFrameInfo();
if (Offset & 7)
report_fatal_error("Misaligned saved register offset!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
- Label, Register, Offset);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
- EnsureValidW64UnwindInfo();
+ EnsureValidWinFrameInfo();
if (Offset & 0x0F)
report_fatal_error("Misaligned saved vector register offset!");
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
- Label, Register, Offset);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveXMM(Label, Register, Offset);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFIPushFrame(bool Code) {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- if (CurFrame->Instructions.size() > 0)
+ EnsureValidWinFrameInfo();
+ if (CurrentWinFrameInfo->Instructions.size() > 0)
report_fatal_error("If present, PushMachFrame must be the first UOP");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code);
EmitLabel(Label);
- CurFrame->Instructions.push_back(Inst);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
+ CurrentWinFrameInfo->Instructions.push_back(Inst);
}
void MCStreamer::EmitWinCFIEndProlog() {
- EnsureValidW64UnwindInfo();
- MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo;
- CurFrame->PrologEnd = getContext().CreateTempSymbol();
- EmitLabel(CurFrame->PrologEnd);
+ EnsureValidWinFrameInfo();
+
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ EmitLabel(Label);
+
+ CurrentWinFrameInfo->PrologEnd = Label;
}
void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
@@ -590,15 +567,11 @@ void MCStreamer::EmitRawText(const Twine &T) {
EmitRawTextImpl(T.toStringRef(Str));
}
-void MCStreamer::EmitW64Tables() {
- if (!getNumW64UnwindInfos())
- return;
-
- MCWin64EHUnwindEmitter::Emit(*this);
+void MCStreamer::EmitWindowsUnwindTables() {
}
void MCStreamer::Finish() {
- if (!FrameInfos.empty() && !FrameInfos.back().End)
+ if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
report_fatal_error("Unfinished frame!");
MCTargetStreamer *TS = getTargetStreamer();
diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp
index 4424c91..b8e42bd 100644
--- a/lib/MC/MCSubtargetInfo.cpp
+++ b/lib/MC/MCSubtargetInfo.cpp
@@ -17,8 +17,6 @@
using namespace llvm;
-MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
-
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented
/// with feature string). Recompute feature bits and scheduling model.
void
@@ -33,7 +31,7 @@ MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
if (!CPU.empty())
CPUSchedModel = getSchedModelForCPU(CPU);
else
- CPUSchedModel = &MCSchedModel::DefaultSchedModel;
+ CPUSchedModel = MCSchedModel::GetDefaultSchedModel();
}
void
@@ -78,7 +76,7 @@ uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
}
-const MCSchedModel *
+MCSchedModel
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
assert(ProcSchedModels && "Processor machine model not available!");
@@ -97,15 +95,15 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
errs() << "'" << CPU
<< "' is not a recognized processor for this target"
<< " (ignoring processor)\n";
- return &MCSchedModel::DefaultSchedModel;
+ return MCSchedModel::GetDefaultSchedModel();
}
assert(Found->Value && "Missing processor SchedModel value");
- return (const MCSchedModel *)Found->Value;
+ return *(const MCSchedModel *)Found->Value;
}
InstrItineraryData
MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
- const MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
+ const MCSchedModel SchedModel = getSchedModelForCPU(CPU);
return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
}
diff --git a/lib/MC/MCTargetOptions.cpp b/lib/MC/MCTargetOptions.cpp
index efd724a..3093ba2 100644
--- a/lib/MC/MCTargetOptions.cpp
+++ b/lib/MC/MCTargetOptions.cpp
@@ -13,8 +13,8 @@ namespace llvm {
MCTargetOptions::MCTargetOptions()
: SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
- MCSaveTempLabels(false), MCUseDwarfDirectory(false),
- ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
- DwarfVersion(0) {}
+ MCFatalWarnings(false), MCSaveTempLabels(false),
+ MCUseDwarfDirectory(false), ShowMCEncoding(false), ShowMCInst(false),
+ AsmVerbose(false), DwarfVersion(0) {}
} // end namespace llvm
diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp
index bb651647..dfadb3c 100644
--- a/lib/MC/MCWin64EH.cpp
+++ b/lib/MC/MCWin64EH.cpp
@@ -15,15 +15,16 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Win64EH.h"
namespace llvm {
// NOTE: All relocations generated here are 4-byte image-relative.
-static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
+static uint8_t CountOfUnwindCodes(std::vector<WinEH::Instruction> &Insns) {
uint8_t Count = 0;
for (const auto &I : Insns) {
- switch (I.getOperation()) {
+ switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
case Win64EH::UOP_PushNonVol:
case Win64EH::UOP_AllocSmall:
case Win64EH::UOP_SetFPReg:
@@ -39,86 +40,83 @@ static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
Count += 3;
break;
case Win64EH::UOP_AllocLarge:
- Count += (I.getSize() > 512 * 1024 - 8) ? 3 : 2;
+ Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2;
break;
}
}
return Count;
}
-static void EmitAbsDifference(MCStreamer &streamer, MCSymbol *lhs,
- MCSymbol *rhs) {
- MCContext &context = streamer.getContext();
- const MCExpr *diff = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(
- lhs, context),
- MCSymbolRefExpr::Create(
- rhs, context),
- context);
- streamer.EmitAbsValue(diff, 1);
-
+static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
+ const MCSymbol *RHS) {
+ MCContext &Context = Streamer.getContext();
+ const MCExpr *Diff =
+ MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LHS, Context),
+ MCSymbolRefExpr::Create(RHS, Context), Context);
+ Streamer.EmitValue(Diff, 1);
}
-static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
- MCWin64EHInstruction &inst) {
+static void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin,
+ WinEH::Instruction &inst) {
uint8_t b2;
uint16_t w;
- b2 = (inst.getOperation() & 0x0F);
- switch (inst.getOperation()) {
+ b2 = (inst.Operation & 0x0F);
+ switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
case Win64EH::UOP_PushNonVol:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
- b2 |= (inst.getRegister() & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
+ b2 |= (inst.Register & 0x0F) << 4;
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_AllocLarge:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
- if (inst.getSize() > 512*1024-8) {
+ EmitAbsDifference(streamer, inst.Label, begin);
+ if (inst.Offset > 512 * 1024 - 8) {
b2 |= 0x10;
streamer.EmitIntValue(b2, 1);
- w = inst.getSize() & 0xFFF8;
+ w = inst.Offset & 0xFFF8;
streamer.EmitIntValue(w, 2);
- w = inst.getSize() >> 16;
+ w = inst.Offset >> 16;
} else {
streamer.EmitIntValue(b2, 1);
- w = inst.getSize() >> 3;
+ w = inst.Offset >> 3;
}
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_AllocSmall:
- b2 |= (((inst.getSize()-8) >> 3) & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SetFPReg:
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SaveNonVol:
case Win64EH::UOP_SaveXMM128:
- b2 |= (inst.getRegister() & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (inst.Register & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
- w = inst.getOffset() >> 3;
- if (inst.getOperation() == Win64EH::UOP_SaveXMM128)
+ w = inst.Offset >> 3;
+ if (inst.Operation == Win64EH::UOP_SaveXMM128)
w >>= 1;
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_SaveNonVolBig:
case Win64EH::UOP_SaveXMM128Big:
- b2 |= (inst.getRegister() & 0x0F) << 4;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ b2 |= (inst.Register & 0x0F) << 4;
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
- if (inst.getOperation() == Win64EH::UOP_SaveXMM128Big)
- w = inst.getOffset() & 0xFFF0;
+ if (inst.Operation == Win64EH::UOP_SaveXMM128Big)
+ w = inst.Offset & 0xFFF0;
else
- w = inst.getOffset() & 0xFFF8;
+ w = inst.Offset & 0xFFF8;
streamer.EmitIntValue(w, 2);
- w = inst.getOffset() >> 16;
+ w = inst.Offset >> 16;
streamer.EmitIntValue(w, 2);
break;
case Win64EH::UOP_PushMachFrame:
- if (inst.isPushCodeFrame())
+ if (inst.Offset == 1)
b2 |= 0x10;
- EmitAbsDifference(streamer, inst.getLabel(), begin);
+ EmitAbsDifference(streamer, inst.Label, begin);
streamer.EmitIntValue(b2, 1);
break;
}
@@ -138,7 +136,7 @@ static void EmitSymbolRefWithOfs(MCStreamer &streamer,
}
static void EmitRuntimeFunction(MCStreamer &streamer,
- const MCWin64EHUnwindInfo *info) {
+ const WinEH::FrameInfo *info) {
MCContext &context = streamer.getContext();
streamer.EmitValueToAlignment(4);
@@ -149,14 +147,17 @@ static void EmitRuntimeFunction(MCStreamer &streamer,
context), 4);
}
-static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
+static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
// If this UNWIND_INFO already has a symbol, it's already been emitted.
- if (info->Symbol) return;
+ if (info->Symbol)
+ return;
MCContext &context = streamer.getContext();
+ MCSymbol *Label = context.CreateTempSymbol();
+
streamer.EmitValueToAlignment(4);
- info->Symbol = context.CreateTempSymbol();
- streamer.EmitLabel(info->Symbol);
+ streamer.EmitLabel(Label);
+ info->Symbol = Label;
// Upper 3 bits are the version number (currently 1).
uint8_t flags = 0x01;
@@ -180,17 +181,16 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
uint8_t frame = 0;
if (info->LastFrameInst >= 0) {
- MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst];
- assert(frameInst.getOperation() == Win64EH::UOP_SetFPReg);
- frame = (frameInst.getRegister() & 0x0F) |
- (frameInst.getOffset() & 0xF0);
+ WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst];
+ assert(frameInst.Operation == Win64EH::UOP_SetFPReg);
+ frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0);
}
streamer.EmitIntValue(frame, 1);
// Emit unwind instructions (in reverse order).
uint8_t numInst = info->Instructions.size();
for (uint8_t c = 0; c < numInst; ++c) {
- MCWin64EHInstruction inst = info->Instructions.back();
+ WinEH::Instruction inst = info->Instructions.back();
info->Instructions.pop_back();
EmitUnwindCode(streamer, info->Begin, inst);
}
@@ -218,77 +218,38 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
}
}
-StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) {
- if (!func || !func->isInSection()) return "";
- const MCSection *section = &func->getSection();
- const MCSectionCOFF *COFFSection;
- if ((COFFSection = dyn_cast<MCSectionCOFF>(section))) {
- StringRef name = COFFSection->getSectionName();
- size_t dollar = name.find('$');
- size_t dot = name.find('.', 1);
- if (dollar == StringRef::npos && dot == StringRef::npos)
- return "";
- if (dot == StringRef::npos)
- return name.substr(dollar);
- if (dollar == StringRef::npos || dot < dollar)
- return name.substr(dot);
- return name.substr(dollar);
- }
- return "";
-}
-
-static const MCSection *getWin64EHTableSection(StringRef suffix,
- MCContext &context) {
- if (suffix == "")
- return context.getObjectFileInfo()->getXDataSection();
-
- return context.getCOFFSection((".xdata"+suffix).str(),
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getDataRel());
-}
-
-static const MCSection *getWin64EHFuncTableSection(StringRef suffix,
- MCContext &context) {
- if (suffix == "")
- return context.getObjectFileInfo()->getPDataSection();
- return context.getCOFFSection((".pdata"+suffix).str(),
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ,
- SectionKind::getDataRel());
-}
-
-void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
- MCWin64EHUnwindInfo *info) {
- // Switch sections (the static function above is meant to be called from
- // here and from Emit().
- MCContext &context = streamer.getContext();
- const MCSection *xdataSect =
- getWin64EHTableSection(GetSectionSuffix(info->Function), context);
- streamer.SwitchSection(xdataSect);
-
- llvm::EmitUnwindInfo(streamer, info);
-}
-
-void MCWin64EHUnwindEmitter::Emit(MCStreamer &Streamer) {
+namespace Win64EH {
+void UnwindEmitter::Emit(MCStreamer &Streamer) const {
MCContext &Context = Streamer.getContext();
// Emit the unwind info structs first.
- for (const auto &CFI : Streamer.getW64UnwindInfos()) {
+ for (const auto &CFI : Streamer.getWinFrameInfos()) {
const MCSection *XData =
- getWin64EHTableSection(GetSectionSuffix(CFI->Function), Context);
+ getXDataSection(CFI->Function, Context);
Streamer.SwitchSection(XData);
EmitUnwindInfo(Streamer, CFI);
}
// Now emit RUNTIME_FUNCTION entries.
- for (const auto &CFI : Streamer.getW64UnwindInfos()) {
+ for (const auto &CFI : Streamer.getWinFrameInfos()) {
const MCSection *PData =
- getWin64EHFuncTableSection(GetSectionSuffix(CFI->Function), Context);
+ getPDataSection(CFI->Function, Context);
Streamer.SwitchSection(PData);
EmitRuntimeFunction(Streamer, CFI);
}
}
+void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
+ WinEH::FrameInfo *info) const {
+ // Switch sections (the static function above is meant to be called from
+ // here and from Emit().
+ MCContext &context = Streamer.getContext();
+ const MCSection *xdataSect =
+ getXDataSection(info->Function, context);
+ Streamer.SwitchSection(xdataSect);
+
+ llvm::EmitUnwindInfo(Streamer, info);
+}
+}
} // End of namespace llvm
diff --git a/lib/MC/MCWinEH.cpp b/lib/MC/MCWinEH.cpp
new file mode 100644
index 0000000..f0c354f
--- /dev/null
+++ b/lib/MC/MCWinEH.cpp
@@ -0,0 +1,84 @@
+//===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/COFF.h"
+
+namespace llvm {
+namespace WinEH {
+static StringRef getSectionSuffix(const MCSymbol *Function) {
+ if (!Function || !Function->isInSection())
+ return "";
+
+ const MCSection *FunctionSection = &Function->getSection();
+ if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
+ StringRef Name = Section->getSectionName();
+ size_t Dollar = Name.find('$');
+ size_t Dot = Name.find('.', 1);
+
+ if (Dollar == StringRef::npos && Dot == StringRef::npos)
+ return "";
+ if (Dot == StringRef::npos)
+ return Name.substr(Dollar);
+ if (Dollar == StringRef::npos || Dot < Dollar)
+ return Name.substr(Dot);
+
+ return Name.substr(Dollar);
+ }
+
+ return "";
+}
+
+static const MCSection *getUnwindInfoSection(
+ StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
+ MCContext &Context) {
+ // If Function is in a COMDAT, get or create an unwind info section in that
+ // COMDAT group.
+ if (Function && Function->isInSection()) {
+ const MCSectionCOFF *FunctionSection =
+ cast<MCSectionCOFF>(&Function->getSection());
+ if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
+ return Context.getAssociativeCOFFSection(
+ UnwindSec, FunctionSection->getCOMDATSymbol());
+ }
+ }
+
+ // If Function is in a section other than .text, create a new .pdata section.
+ // Otherwise use the plain .pdata section.
+ StringRef Suffix = getSectionSuffix(Function);
+ if (Suffix.empty())
+ return UnwindSec;
+ return Context.getCOFFSection((SecName + Suffix).str(),
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getDataRel());
+}
+
+const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
+ MCContext &Context) {
+ const MCSectionCOFF *PData =
+ cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
+ return getUnwindInfoSection(".pdata", PData, Function, Context);
+}
+
+const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
+ MCContext &Context) {
+ const MCSectionCOFF *XData =
+ cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
+ return getUnwindInfoSection(".xdata", XData, Function, Context);
+}
+
+}
+}
+
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 5214398..577c4b7 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -41,7 +41,7 @@ void MachObjectWriter::reset() {
bool MachObjectWriter::
doesSymbolRequireExternRelocation(const MCSymbolData *SD) {
// Undefined symbols are always extern.
- if (SD->Symbol->isUndefined())
+ if (SD->getSymbol().isUndefined())
return true;
// References to weak definitions require external relocation entries; the
@@ -84,7 +84,7 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
MCValue Target;
- if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout))
+ if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr))
report_fatal_error("unable to evaluate offset for variable '" +
S.getName() + "'");
@@ -525,15 +525,10 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
}
/// ComputeSymbolTable - Compute the symbol table data
-///
-/// \param StringTable [out] - The string table data.
-/// \param StringIndexMap [out] - Map from symbol names to offsets in the
-/// string table.
-void MachObjectWriter::
-ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
- std::vector<MachSymbolData> &LocalSymbolData,
- std::vector<MachSymbolData> &ExternalSymbolData,
- std::vector<MachSymbolData> &UndefinedSymbolData) {
+void MachObjectWriter::ComputeSymbolTable(
+ MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData,
+ std::vector<MachSymbolData> &ExternalSymbolData,
+ std::vector<MachSymbolData> &UndefinedSymbolData) {
// Build section lookup table.
DenseMap<const MCSection*, uint8_t> SectionIndexMap;
unsigned Index = 1;
@@ -542,37 +537,34 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
SectionIndexMap[&it->getSection()] = Index;
assert(Index <= 256 && "Too many sections!");
- // Index 0 is always the empty string.
- StringMap<uint64_t> StringIndexMap;
- StringTable += '\x00';
+ // Build the string table.
+ for (MCSymbolData &SD : Asm.symbols()) {
+ const MCSymbol &Symbol = SD.getSymbol();
+ if (!Asm.isSymbolLinkerVisible(Symbol))
+ continue;
+
+ StringTable.add(Symbol.getName());
+ }
+ StringTable.finalize(StringTableBuilder::MachO);
- // Build the symbol arrays and the string table, but only for non-local
- // symbols.
+ // Build the symbol arrays but only for non-local symbols.
//
- // The particular order that we collect the symbols and create the string
- // table, then sort the symbols is chosen to match 'as'. Even though it
- // doesn't matter for correctness, this is important for letting us diff .o
- // files.
+ // The particular order that we collect and then sort the symbols is chosen to
+ // match 'as'. Even though it doesn't matter for correctness, this is
+ // important for letting us diff .o files.
for (MCSymbolData &SD : Asm.symbols()) {
const MCSymbol &Symbol = SD.getSymbol();
// Ignore non-linker visible symbols.
- if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
+ if (!Asm.isSymbolLinkerVisible(Symbol))
continue;
if (!SD.isExternal() && !Symbol.isUndefined())
continue;
- uint64_t &Entry = StringIndexMap[Symbol.getName()];
- if (!Entry) {
- Entry = StringTable.size();
- StringTable += Symbol.getName();
- StringTable += '\x00';
- }
-
MachSymbolData MSD;
MSD.SymbolData = &SD;
- MSD.StringIndex = Entry;
+ MSD.StringIndex = StringTable.getOffset(Symbol.getName());
if (Symbol.isUndefined()) {
MSD.SectionIndex = 0;
@@ -592,22 +584,15 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
const MCSymbol &Symbol = SD.getSymbol();
// Ignore non-linker visible symbols.
- if (!Asm.isSymbolLinkerVisible(SD.getSymbol()))
+ if (!Asm.isSymbolLinkerVisible(Symbol))
continue;
if (SD.isExternal() || Symbol.isUndefined())
continue;
- uint64_t &Entry = StringIndexMap[Symbol.getName()];
- if (!Entry) {
- Entry = StringTable.size();
- StringTable += Symbol.getName();
- StringTable += '\x00';
- }
-
MachSymbolData MSD;
MSD.SymbolData = &SD;
- MSD.StringIndex = Entry;
+ MSD.StringIndex = StringTable.getOffset(Symbol.getName());
if (Symbol.isAbsolute()) {
MSD.SectionIndex = 0;
@@ -631,10 +616,6 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
ExternalSymbolData[i].SymbolData->setIndex(Index++);
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
-
- // The string table is padded to a multiple of 4.
- while (StringTable.size() % 4)
- StringTable += '\x00';
}
void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
@@ -664,7 +645,7 @@ void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
// and neither symbol is external, mark the variable as absolute.
const MCExpr *Expr = SD.getSymbol().getVariableValue();
MCValue Value;
- if (Expr->EvaluateAsRelocatable(Value, &Layout)) {
+ if (Expr->EvaluateAsRelocatable(Value, &Layout, nullptr)) {
if (Value.getSymA() && Value.getSymB())
const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
}
@@ -683,7 +664,7 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
markAbsoluteVariableSymbols(Asm, Layout);
// Compute symbol table information and bind symbol indices.
- ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
+ ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
UndefinedSymbolData);
}
@@ -745,6 +726,10 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
return false;
}
+ // If they are not in the same section, we can't compute the diff.
+ if (&SecA != &SecB)
+ return false;
+
const MCFragment *FA = Asm.getSymbolData(SA).getFragment();
// Bail if the symbol has no fragment.
@@ -752,12 +737,7 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
return false;
A_Base = FA->getAtom();
- if (!A_Base)
- return false;
-
B_Base = FB.getAtom();
- if (!B_Base)
- return false;
// If the atoms are the same, they are guaranteed to have the same address.
if (A_Base == B_Base)
@@ -922,7 +902,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
sizeof(MachO::nlist_64) :
sizeof(MachO::nlist));
WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
- StringTableOffset, StringTable.size());
+ StringTableOffset, StringTable.data().size());
WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
FirstExternalSymbol, NumExternalSymbols,
@@ -1028,7 +1008,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
WriteNlist(UndefinedSymbolData[i], Layout);
// Write the string table.
- OS << StringTable.str();
+ OS << StringTable.data();
}
}
diff --git a/lib/MC/Makefile b/lib/MC/Makefile
index a10f17e..bf8b7c0 100644
--- a/lib/MC/Makefile
+++ b/lib/MC/Makefile
@@ -10,7 +10,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMMC
BUILD_ARCHIVE := 1
-PARALLEL_DIRS := MCAnalysis MCParser MCDisassembler
+PARALLEL_DIRS := MCParser MCDisassembler
include $(LEVEL)/Makefile.common
diff --git a/lib/MC/StringTableBuilder.cpp b/lib/MC/StringTableBuilder.cpp
index db58ece..9de9363 100644
--- a/lib/MC/StringTableBuilder.cpp
+++ b/lib/MC/StringTableBuilder.cpp
@@ -9,6 +9,8 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
using namespace llvm;
@@ -25,19 +27,32 @@ static bool compareBySuffix(StringRef a, StringRef b) {
return sizeA > sizeB;
}
-void StringTableBuilder::finalize() {
+void StringTableBuilder::finalize(Kind kind) {
SmallVector<StringRef, 8> Strings;
+ Strings.reserve(StringIndexMap.size());
+
for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
Strings.push_back(i->getKey());
std::sort(Strings.begin(), Strings.end(), compareBySuffix);
- // FIXME: Starting with a null byte is ELF specific. Generalize this so we
- // can use the class with other object formats.
- StringTable += '\x00';
+ switch (kind) {
+ case ELF:
+ case MachO:
+ // Start the table with a NUL byte.
+ StringTable += '\x00';
+ break;
+ case WinCOFF:
+ // Make room to write the table size later.
+ StringTable.append(4, '\x00');
+ break;
+ }
StringRef Previous;
for (StringRef s : Strings) {
+ if (kind == WinCOFF)
+ assert(s.size() > COFF::NameSize && "Short string in COFF string table!");
+
if (Previous.endswith(s)) {
StringIndexMap[s] = StringTable.size() - 1 - s.size();
continue;
@@ -48,4 +63,26 @@ void StringTableBuilder::finalize() {
StringTable += '\x00';
Previous = s;
}
+
+ switch (kind) {
+ case ELF:
+ break;
+ case MachO:
+ // Pad to multiple of 4.
+ while (StringTable.size() % 4)
+ StringTable += '\x00';
+ break;
+ case WinCOFF:
+ // Write the table size in the first word.
+ assert(StringTable.size() <= std::numeric_limits<uint32_t>::max());
+ uint32_t size = static_cast<uint32_t>(StringTable.size());
+ support::endian::write<uint32_t, support::little, support::unaligned>(
+ StringTable.data(), size);
+ break;
+ }
+}
+
+void StringTableBuilder::clear() {
+ StringTable.clear();
+ StringIndexMap.clear();
}
diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp
index 27525c7..587be54 100644
--- a/lib/MC/SubtargetFeature.cpp
+++ b/lib/MC/SubtargetFeature.cpp
@@ -27,7 +27,7 @@ using namespace llvm;
/// hasFlag - Determine if a feature has a flag; '+' or '-'
///
-static inline bool hasFlag(const StringRef Feature) {
+static inline bool hasFlag(StringRef Feature) {
assert(!Feature.empty() && "Empty string");
// Get first character
char Ch = Feature[0];
@@ -37,13 +37,13 @@ static inline bool hasFlag(const StringRef Feature) {
/// StripFlag - Return string stripped of flag.
///
-static inline std::string StripFlag(const StringRef Feature) {
+static inline std::string StripFlag(StringRef Feature) {
return hasFlag(Feature) ? Feature.substr(1) : Feature;
}
/// isEnabled - Return true if enable flag; '+'.
///
-static inline bool isEnabled(const StringRef Feature) {
+static inline bool isEnabled(StringRef Feature) {
assert(!Feature.empty() && "Empty string");
// Get first character
char Ch = Feature[0];
@@ -53,8 +53,8 @@ static inline bool isEnabled(const StringRef Feature) {
/// Split - Splits a string of comma separated items in to a vector of strings.
///
-static void Split(std::vector<std::string> &V, const StringRef S) {
- SmallVector<StringRef, 2> Tmp;
+static void Split(std::vector<std::string> &V, StringRef S) {
+ SmallVector<StringRef, 3> Tmp;
S.split(Tmp, ",", -1, false /* KeepEmpty */);
V.assign(Tmp.begin(), Tmp.end());
}
@@ -81,7 +81,7 @@ static std::string Join(const std::vector<std::string> &V) {
}
/// Adding features.
-void SubtargetFeatures::AddFeature(const StringRef String) {
+void SubtargetFeatures::AddFeature(StringRef String) {
// Don't add empty features or features we already have.
if (!String.empty())
// Convert to lowercase, prepend flag if we don't already have a flag.
@@ -136,7 +136,7 @@ static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
// SubtargetFeatures Implementation
//===----------------------------------------------------------------------===//
-SubtargetFeatures::SubtargetFeatures(const StringRef Initial) {
+SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
// Break up string into separate features
Split(Features, Initial);
}
@@ -181,7 +181,7 @@ void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
/// ToggleFeature - Toggle a feature and returns the newly updated feature
/// bits.
uint64_t
-SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature,
+SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
// Find feature in table.
@@ -213,7 +213,7 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature,
/// getFeatureBits - Get feature bits a CPU.
///
uint64_t
-SubtargetFeatures::getFeatureBits(const StringRef CPU,
+SubtargetFeatures::getFeatureBits(StringRef CPU,
ArrayRef<SubtargetFeatureKV> CPUTable,
ArrayRef<SubtargetFeatureKV> FeatureTable) {
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index a462c0d..1046e04 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -26,8 +26,10 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeValue.h"
#include <cstdio>
@@ -71,7 +73,6 @@ public:
MCSymbolData const *MCData;
COFFSymbol(StringRef name);
- size_t size() const;
void set_name_offset(uint32_t Offset);
bool should_keep() const;
@@ -102,20 +103,6 @@ public:
static size_t size();
};
-// This class holds the COFF string table.
-class StringTable {
- typedef StringMap<size_t> map;
- map Map;
-
- void update_length();
-public:
- std::vector<char> Data;
-
- StringTable();
- size_t size() const;
- size_t insert(StringRef String);
-};
-
class WinCOFFObjectWriter : public MCObjectWriter {
public:
@@ -131,13 +118,26 @@ public:
COFF::header Header;
sections Sections;
symbols Symbols;
- StringTable Strings;
+ StringTableBuilder Strings;
// Maps used during object file creation.
section_map SectionMap;
symbol_map SymbolMap;
+ bool UseBigObj;
+
WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS);
+
+ void reset() override {
+ memset(&Header, 0, sizeof(Header));
+ Header.Machine = TargetObjectWriter->getMachine();
+ Sections.clear();
+ Symbols.clear();
+ Strings.clear();
+ SectionMap.clear();
+ SymbolMap.clear();
+ MCObjectWriter::reset();
+ }
COFFSymbol *createSymbol(StringRef Name);
COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol);
@@ -150,10 +150,10 @@ public:
void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
const MCAsmLayout &Layout);
- void MakeSymbolReal(COFFSymbol &S, size_t Index);
- void MakeSectionReal(COFFSection &S, size_t Number);
+ void SetSymbolName(COFFSymbol &S);
+ void SetSectionName(COFFSection &S);
- bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm);
+ bool ExportSymbol(const MCSymbol &Symbol, MCAssembler &Asm);
bool IsPhysicalSection(COFFSection *S);
@@ -170,6 +170,11 @@ public:
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
+ bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB, bool InSet,
+ bool IsPCRel) const override;
+
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
@@ -179,12 +184,9 @@ public:
};
}
-static inline void write_uint32_le(void *Data, uint32_t const &Value) {
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
- Ptr[0] = (Value & 0x000000FF) >> 0;
- Ptr[1] = (Value & 0x0000FF00) >> 8;
- Ptr[2] = (Value & 0x00FF0000) >> 16;
- Ptr[3] = (Value & 0xFF000000) >> 24;
+static inline void write_uint32_le(void *Data, uint32_t Value) {
+ support::endian::write<uint32_t, support::little, support::unaligned>(Data,
+ Value);
}
//------------------------------------------------------------------------------
@@ -199,10 +201,6 @@ COFFSymbol::COFFSymbol(StringRef name)
memset(&Data, 0, sizeof(Data));
}
-size_t COFFSymbol::size() const {
- return COFF::SymbolSize + (Data.NumberOfAuxSymbols * COFF::SymbolSize);
-}
-
// In the case that the name does not fit within 8 bytes, the offset
// into the string table is stored in the last 4 bytes instead, leaving
// the first 4 bytes as 0.
@@ -254,55 +252,11 @@ size_t COFFSection::size() {
}
//------------------------------------------------------------------------------
-// StringTable class implementation
-
-/// Write the length of the string table into Data.
-/// The length of the string table includes uint32 length header.
-void StringTable::update_length() {
- write_uint32_le(&Data.front(), Data.size());
-}
-
-StringTable::StringTable() {
- // The string table data begins with the length of the entire string table
- // including the length header. Allocate space for this header.
- Data.resize(4);
- update_length();
-}
-
-size_t StringTable::size() const {
- return Data.size();
-}
-
-/// Add String to the table iff it is not already there.
-/// @returns the index into the string table where the string is now located.
-size_t StringTable::insert(StringRef String) {
- map::iterator i = Map.find(String);
-
- if (i != Map.end())
- return i->second;
-
- size_t Offset = Data.size();
-
- // Insert string data into string table.
- Data.insert(Data.end(), String.begin(), String.end());
- Data.push_back('\0');
-
- // Put a reference to it in the map.
- Map[String] = Offset;
-
- // Update the internal length field.
- update_length();
-
- return Offset;
-}
-
-//------------------------------------------------------------------------------
// WinCOFFObjectWriter class implementation
WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
raw_ostream &OS)
- : MCObjectWriter(OS, true)
- , TargetObjectWriter(MOTW) {
+ : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) {
memset(&Header, 0, sizeof(Header));
Header.Machine = TargetObjectWriter->getMachine();
@@ -456,19 +410,22 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
// If no storage class was specified in the streamer, define it here.
if (coff_symbol->Data.StorageClass == 0) {
- bool external = ResSymData.isExternal() || !ResSymData.Fragment;
+ bool IsExternal =
+ ResSymData.isExternal() ||
+ (!ResSymData.getFragment() && !ResSymData.getSymbol().isVariable());
- coff_symbol->Data.StorageClass =
- external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
+ coff_symbol->Data.StorageClass = IsExternal
+ ? COFF::IMAGE_SYM_CLASS_EXTERNAL
+ : COFF::IMAGE_SYM_CLASS_STATIC;
}
if (!Base) {
coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
} else {
const MCSymbolData &BaseData = Assembler.getSymbolData(*Base);
- if (BaseData.Fragment) {
+ if (BaseData.getFragment()) {
COFFSection *Sec =
- SectionMap[&BaseData.Fragment->getParent()->getSection()];
+ SectionMap[&BaseData.getFragment()->getParent()->getSection()];
if (coff_symbol->Section && coff_symbol->Section != Sec)
report_fatal_error("conflicting sections for symbol");
@@ -508,11 +465,9 @@ static void encodeBase64StringEntry(char* Buffer, uint64_t Value) {
}
}
-/// making a section real involves assigned it a number and putting
-/// name into the string table if needed
-void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
+void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
if (S.Name.size() > COFF::NameSize) {
- uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
+ uint64_t StringTableEntry = Strings.getOffset(S.Name);
if (StringTableEntry <= Max6DecimalOffset) {
std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
@@ -530,32 +485,33 @@ void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
}
} else
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
-
- S.Number = Number;
- S.Symbol->Data.SectionNumber = S.Number;
- S.Symbol->Aux[0].Aux.SectionDefinition.Number = S.Number;
}
-void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
- if (S.Name.size() > COFF::NameSize) {
- size_t StringTableEntry = Strings.insert(S.Name.c_str());
-
- S.set_name_offset(StringTableEntry);
- } else
+void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
+ if (S.Name.size() > COFF::NameSize)
+ S.set_name_offset(Strings.getOffset(S.Name));
+ else
std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
- S.Index = Index;
}
-bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData,
+bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol,
MCAssembler &Asm) {
// This doesn't seem to be right. Strings referred to from the .data section
// need symbols so they can be linked to code in the .text section right?
- // return Asm.isSymbolLinkerVisible(SymbolData.getSymbol());
+ // return Asm.isSymbolLinkerVisible(Symbol);
+
+ // Non-temporary labels should always be visible to the linker.
+ if (!Symbol.isTemporary())
+ return true;
+
+ // Absolute temporary labels are never visible.
+ if (!Symbol.isInSection())
+ return false;
// For now, all non-variable symbols are exported,
// the linker will sort the rest out for us.
- return SymbolData.isExternal() || !SymbolData.getSymbol().isVariable();
+ return !Symbol.isVariable();
}
bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
@@ -567,19 +523,39 @@ bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
// entity writing methods
void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
- WriteLE16(Header.Machine);
- WriteLE16(Header.NumberOfSections);
- WriteLE32(Header.TimeDateStamp);
- WriteLE32(Header.PointerToSymbolTable);
- WriteLE32(Header.NumberOfSymbols);
- WriteLE16(Header.SizeOfOptionalHeader);
- WriteLE16(Header.Characteristics);
+ if (UseBigObj) {
+ WriteLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
+ WriteLE16(0xFFFF);
+ WriteLE16(COFF::BigObjHeader::MinBigObjectVersion);
+ WriteLE16(Header.Machine);
+ WriteLE32(Header.TimeDateStamp);
+ for (uint8_t MagicChar : COFF::BigObjMagic)
+ Write8(MagicChar);
+ WriteLE32(0);
+ WriteLE32(0);
+ WriteLE32(0);
+ WriteLE32(0);
+ WriteLE32(Header.NumberOfSections);
+ WriteLE32(Header.PointerToSymbolTable);
+ WriteLE32(Header.NumberOfSymbols);
+ } else {
+ WriteLE16(Header.Machine);
+ WriteLE16(static_cast<int16_t>(Header.NumberOfSections));
+ WriteLE32(Header.TimeDateStamp);
+ WriteLE32(Header.PointerToSymbolTable);
+ WriteLE32(Header.NumberOfSymbols);
+ WriteLE16(Header.SizeOfOptionalHeader);
+ WriteLE16(Header.Characteristics);
+ }
}
void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
WriteBytes(StringRef(S.Data.Name, COFF::NameSize));
WriteLE32(S.Data.Value);
- WriteLE16(S.Data.SectionNumber);
+ if (UseBigObj)
+ WriteLE32(S.Data.SectionNumber);
+ else
+ WriteLE16(static_cast<int16_t>(S.Data.SectionNumber));
WriteLE16(S.Data.Type);
Write8(S.Data.StorageClass);
Write8(S.Data.NumberOfAuxSymbols);
@@ -597,6 +573,8 @@ void WinCOFFObjectWriter::WriteAuxiliarySymbols(
WriteLE32(i->Aux.FunctionDefinition.PointerToLinenumber);
WriteLE32(i->Aux.FunctionDefinition.PointerToNextFunction);
WriteZeros(sizeof(i->Aux.FunctionDefinition.unused));
+ if (UseBigObj)
+ WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATbfAndefSymbol:
WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused1));
@@ -604,24 +582,32 @@ void WinCOFFObjectWriter::WriteAuxiliarySymbols(
WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused2));
WriteLE32(i->Aux.bfAndefSymbol.PointerToNextFunction);
WriteZeros(sizeof(i->Aux.bfAndefSymbol.unused3));
+ if (UseBigObj)
+ WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATWeakExternal:
WriteLE32(i->Aux.WeakExternal.TagIndex);
WriteLE32(i->Aux.WeakExternal.Characteristics);
WriteZeros(sizeof(i->Aux.WeakExternal.unused));
+ if (UseBigObj)
+ WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
case ATFile:
- WriteBytes(StringRef(reinterpret_cast<const char *>(i->Aux.File.FileName),
- sizeof(i->Aux.File.FileName)));
+ WriteBytes(
+ StringRef(reinterpret_cast<const char *>(&i->Aux),
+ UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size));
break;
case ATSectionDefinition:
WriteLE32(i->Aux.SectionDefinition.Length);
WriteLE16(i->Aux.SectionDefinition.NumberOfRelocations);
WriteLE16(i->Aux.SectionDefinition.NumberOfLinenumbers);
WriteLE32(i->Aux.SectionDefinition.CheckSum);
- WriteLE16(i->Aux.SectionDefinition.Number);
+ WriteLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number));
Write8(i->Aux.SectionDefinition.Selection);
WriteZeros(sizeof(i->Aux.SectionDefinition.unused));
+ WriteLE16(static_cast<int16_t>(i->Aux.SectionDefinition.Number >> 16));
+ if (UseBigObj)
+ WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size);
break;
}
}
@@ -654,45 +640,27 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
// "Define" each section & symbol. This creates section & symbol
// entries in the staging area.
-
- static_assert(sizeof(((COFF::AuxiliaryFile *)nullptr)->FileName) == COFF::SymbolSize,
- "size mismatch for COFF::AuxiliaryFile::FileName");
- for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end();
- FI != FE; ++FI) {
- // round up to calculate the number of auxiliary symbols required
- unsigned Count = (FI->size() + COFF::SymbolSize - 1) / COFF::SymbolSize;
-
- COFFSymbol *file = createSymbol(".file");
- file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
- file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
- file->Aux.resize(Count);
-
- unsigned Offset = 0;
- unsigned Length = FI->size();
- for (auto & Aux : file->Aux) {
- Aux.AuxType = ATFile;
-
- if (Length > COFF::SymbolSize) {
- memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, COFF::SymbolSize);
- Length = Length - COFF::SymbolSize;
- } else {
- memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, Length);
- memset(&Aux.Aux.File.FileName[Length], 0, COFF::SymbolSize - Length);
- Length = 0;
- }
-
- Offset = Offset + COFF::SymbolSize;
- }
- }
-
for (const auto & Section : Asm)
DefineSection(Section);
for (MCSymbolData &SD : Asm.symbols())
- if (ExportSymbol(SD, Asm))
+ if (ExportSymbol(SD.getSymbol(), Asm))
DefineSymbol(SD, Asm, Layout);
}
+bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB,
+ bool InSet, bool IsPCRel) const {
+ // MS LINK expects to be able to replace all references to a function with a
+ // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
+ // away any relocations to functions.
+ if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >>
+ COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
+ return false;
+ return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB,
+ InSet, IsPCRel);
+}
+
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
@@ -744,7 +712,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
// Offset of the symbol in the section
int64_t a = Layout.getSymbolOffset(&B_SD);
- // Ofeset of the relocation in the section
+ // Offset of the relocation in the section
int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
FixedValue = b - a;
@@ -765,8 +733,8 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
// Turn relocations for temporary symbols into section relocations.
if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) {
Reloc.Symb = coff_symbol->Section->Symbol;
- FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->Fragment)
- + coff_symbol->MCData->getOffset();
+ FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->getFragment()) +
+ coff_symbol->MCData->getOffset();
} else
Reloc.Symb = coff_symbol;
@@ -828,26 +796,67 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
+ size_t SectionsSize = Sections.size();
+ if (SectionsSize > static_cast<size_t>(INT32_MAX))
+ report_fatal_error(
+ "PE COFF object files can't have more than 2147483647 sections");
+
// Assign symbol and section indexes and offsets.
- Header.NumberOfSections = 0;
+ int32_t NumberOfSections = static_cast<int32_t>(SectionsSize);
- DenseMap<COFFSection *, uint16_t> SectionIndices;
- for (auto & Section : Sections) {
- size_t Number = ++Header.NumberOfSections;
+ UseBigObj = NumberOfSections > COFF::MaxNumberOfSections16;
+
+ DenseMap<COFFSection *, int32_t> SectionIndices(
+ NextPowerOf2(NumberOfSections));
+
+ // Assign section numbers.
+ size_t Number = 1;
+ for (const auto &Section : Sections) {
SectionIndices[Section.get()] = Number;
- MakeSectionReal(*Section, Number);
+ Section->Number = Number;
+ Section->Symbol->Data.SectionNumber = Number;
+ Section->Symbol->Aux[0].Aux.SectionDefinition.Number = Number;
+ ++Number;
}
+ Header.NumberOfSections = NumberOfSections;
Header.NumberOfSymbols = 0;
- for (auto & Symbol : Symbols) {
+ for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end();
+ FI != FE; ++FI) {
+ // round up to calculate the number of auxiliary symbols required
+ unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
+ unsigned Count = (FI->size() + SymbolSize - 1) / SymbolSize;
+
+ COFFSymbol *file = createSymbol(".file");
+ file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
+ file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
+ file->Aux.resize(Count);
+
+ unsigned Offset = 0;
+ unsigned Length = FI->size();
+ for (auto & Aux : file->Aux) {
+ Aux.AuxType = ATFile;
+
+ if (Length > SymbolSize) {
+ memcpy(&Aux.Aux, FI->c_str() + Offset, SymbolSize);
+ Length = Length - SymbolSize;
+ } else {
+ memcpy(&Aux.Aux, FI->c_str() + Offset, Length);
+ memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
+ break;
+ }
+
+ Offset += SymbolSize;
+ }
+ }
+
+ for (auto &Symbol : Symbols) {
// Update section number & offset for symbols that have them.
if (Symbol->Section)
Symbol->Data.SectionNumber = Symbol->Section->Number;
-
if (Symbol->should_keep()) {
- MakeSymbolReal(*Symbol, Header.NumberOfSymbols++);
-
+ Symbol->Index = Header.NumberOfSymbols++;
// Update auxiliary symbol info.
Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
@@ -855,6 +864,22 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
Symbol->Index = -1;
}
+ // Build string table.
+ for (const auto &S : Sections)
+ if (S->Name.size() > COFF::NameSize)
+ Strings.add(S->Name);
+ for (const auto &S : Symbols)
+ if (S->should_keep() && S->Name.size() > COFF::NameSize)
+ Strings.add(S->Name);
+ Strings.finalize(StringTableBuilder::WinCOFF);
+
+ // Set names.
+ for (const auto &S : Sections)
+ SetSectionName(*S);
+ for (auto &S : Symbols)
+ if (S->should_keep())
+ SetSymbolName(*S);
+
// Fixup weak external references.
for (auto & Symbol : Symbols) {
if (Symbol->Other) {
@@ -897,7 +922,10 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
unsigned offset = 0;
- offset += COFF::HeaderSize;
+ if (UseBigObj)
+ offset += COFF::Header32Size;
+ else
+ offset += COFF::Header16Size;
offset += COFF::SectionSize * Header.NumberOfSections;
for (const auto & Section : Asm) {
@@ -918,7 +946,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
if (RelocationsOverflow) {
- // Signal overflow by setting NumberOfSections to max value. Actual
+ // Signal overflow by setting NumberOfRelocations to max value. Actual
// size is found in reloc #0. Microsoft tools understand this.
Sec->Header.NumberOfRelocations = 0xffff;
} else {
@@ -1014,7 +1042,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
if (Symbol->Index != -1)
WriteSymbol(*Symbol);
- OS.write((char const *)&Strings.Data.front(), Strings.Data.size());
+ OS.write(Strings.data().data(), Strings.data().size());
}
MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) :
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index d391a3f..6a8054d 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -25,11 +25,11 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/MC/MCWin64EH.h"
#include "llvm/MC/MCWinCOFFStreamer.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
@@ -61,7 +61,7 @@ void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst,
DF->getContents().append(Code.begin(), Code.end());
}
-void MCWinCOFFStreamer::InitSections() {
+void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
// FIXME: this is identical to the ELF one.
// This emulates the same behavior of GNU as. This makes it easier
// to compare the output as the major sections are in the same order.
@@ -133,7 +133,7 @@ void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
if (!CurSymbol)
FatalError("storage class specified outside of symbol definition");
- if (StorageClass & ~0xff)
+ if (StorageClass & ~COFF::SSC_Invalid)
FatalError(Twine("storage class value '") + itostr(StorageClass) +
"' out of range");
@@ -163,7 +163,7 @@ void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext());
MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2);
DF->getFixups().push_back(Fixup);
- DF->getContents().resize(DF->getContents().size() + 4, 0);
+ DF->getContents().resize(DF->getContents().size() + 2, 0);
}
void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
@@ -184,14 +184,35 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Symbol->getSection().getVariant() == MCSection::SV_COFF) &&
"Got non-COFF section in the COFF backend!");
- if (ByteAlignment > 32)
- report_fatal_error("alignment is limited to 32-bytes");
+ const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+ if (T.isKnownWindowsMSVCEnvironment()) {
+ if (ByteAlignment > 32)
+ report_fatal_error("alignment is limited to 32-bytes");
+
+ // Round size up to alignment so that we will honor the alignment request.
+ Size = std::max(Size, static_cast<uint64_t>(ByteAlignment));
+ }
AssignSection(Symbol, nullptr);
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
SD.setExternal(true);
SD.setCommon(Size, ByteAlignment);
+
+ if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) {
+ SmallString<128> Directive;
+ raw_svector_ostream OS(Directive);
+ const MCObjectFileInfo *MFI = getContext().getObjectFileInfo();
+
+ OS << " -aligncomm:\"" << Symbol->getName() << "\","
+ << Log2_32_Ceil(ByteAlignment);
+ OS.flush();
+
+ PushSection();
+ SwitchSection(MFI->getDrectveSection());
+ EmitBytes(Directive);
+ PopSection();
+ }
}
void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,