summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/MC
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/lib/MC
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/lib/MC')
-rw-r--r--contrib/llvm/lib/MC/ELFObjectWriter.cpp76
-rw-r--r--contrib/llvm/lib/MC/MCAsmBackend.cpp4
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfo.cpp15
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp1
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp2
-rw-r--r--contrib/llvm/lib/MC/MCAsmInfoELF.cpp23
-rw-r--r--contrib/llvm/lib/MC/MCAsmStreamer.cpp310
-rw-r--r--contrib/llvm/lib/MC/MCAssembler.cpp17
-rw-r--r--contrib/llvm/lib/MC/MCAtom.cpp123
-rw-r--r--contrib/llvm/lib/MC/MCContext.cpp84
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler.cpp42
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp171
-rw-r--r--contrib/llvm/lib/MC/MCDisassembler/Disassembler.h9
-rw-r--r--contrib/llvm/lib/MC/MCDwarf.cpp210
-rw-r--r--contrib/llvm/lib/MC/MCELF.cpp7
-rw-r--r--contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp18
-rw-r--r--contrib/llvm/lib/MC/MCELFStreamer.cpp122
-rw-r--r--contrib/llvm/lib/MC/MCExpr.cpp205
-rw-r--r--contrib/llvm/lib/MC/MCExternalSymbolizer.cpp181
-rw-r--r--contrib/llvm/lib/MC/MCFunction.cpp81
-rw-r--r--contrib/llvm/lib/MC/MCInstPrinter.cpp10
-rw-r--r--contrib/llvm/lib/MC/MCInstrAnalysis.cpp9
-rw-r--r--contrib/llvm/lib/MC/MCMachOStreamer.cpp36
-rw-r--r--contrib/llvm/lib/MC/MCModule.cpp125
-rw-r--r--contrib/llvm/lib/MC/MCModuleYAML.cpp461
-rw-r--r--contrib/llvm/lib/MC/MCNullStreamer.cpp20
-rw-r--r--contrib/llvm/lib/MC/MCObjectDisassembler.cpp584
-rw-r--r--contrib/llvm/lib/MC/MCObjectFileInfo.cpp41
-rw-r--r--contrib/llvm/lib/MC/MCObjectStreamer.cpp48
-rw-r--r--contrib/llvm/lib/MC/MCObjectSymbolizer.cpp310
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmLexer.cpp58
-rw-r--r--contrib/llvm/lib/MC/MCParser/AsmParser.cpp1658
-rw-r--r--contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp284
-rw-r--r--contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp43
-rw-r--r--contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp121
-rw-r--r--contrib/llvm/lib/MC/MCPureStreamer.cpp20
-rw-r--r--contrib/llvm/lib/MC/MCRegisterInfo.cpp12
-rw-r--r--contrib/llvm/lib/MC/MCRelocationInfo.cpp39
-rw-r--r--contrib/llvm/lib/MC/MCSectionCOFF.cpp24
-rw-r--r--contrib/llvm/lib/MC/MCSectionELF.cpp57
-rw-r--r--contrib/llvm/lib/MC/MCStreamer.cpp149
-rw-r--r--contrib/llvm/lib/MC/MCSubtargetInfo.cpp9
-rw-r--r--contrib/llvm/lib/MC/MCSymbol.cpp17
-rw-r--r--contrib/llvm/lib/MC/MCSymbolizer.cpp20
-rw-r--r--contrib/llvm/lib/MC/MCWin64EH.cpp50
-rw-r--r--contrib/llvm/lib/MC/MachObjectWriter.cpp117
-rw-r--r--contrib/llvm/lib/MC/SubtargetFeature.cpp8
-rw-r--r--contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp106
-rw-r--r--contrib/llvm/lib/MC/WinCOFFStreamer.cpp27
49 files changed, 4437 insertions, 1727 deletions
diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
index 3d99548..9899bb2 100644
--- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp
@@ -73,10 +73,6 @@ class ELFObjectWriter : public MCObjectWriter {
// Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const {
- if (MCELF::GetType(*SymbolData) == ELF::STT_FILE)
- return true;
- if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE)
- return false;
return SymbolData->getSymbol().getName() <
RHS.SymbolData->getSymbol().getName();
}
@@ -98,6 +94,7 @@ class ELFObjectWriter : public MCObjectWriter {
/// @{
SmallString<256> StringTable;
+ std::vector<uint64_t> FileSymbolData;
std::vector<ELFSymbolData> LocalSymbolData;
std::vector<ELFSymbolData> ExternalSymbolData;
std::vector<ELFSymbolData> UndefinedSymbolData;
@@ -551,7 +548,7 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
uint8_t Type = MCELF::GetType(Data);
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
- // Other and Visibility share the same byte with Visability using the lower
+ // Other and Visibility share the same byte with Visibility using the lower
// 2 bits
uint8_t Visibility = MCELF::GetVisibility(OrigData);
uint8_t Other = MCELF::getOther(OrigData) <<
@@ -590,8 +587,15 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF,
// The first entry is the undefined symbol entry.
WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false);
+ for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) {
+ WriteSymbolEntry(SymtabF, ShndxF, FileSymbolData[i],
+ ELF::STT_FILE | ELF::STB_LOCAL, 0, 0,
+ ELF::STV_DEFAULT, ELF::SHN_ABS, true);
+ }
+
// Write the symbol table entries.
- LastLocalSymbolIndex = LocalSymbolData.size() + 1;
+ LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1;
+
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
ELFSymbolData &MSD = LocalSymbolData[i];
WriteSymbol(SymtabF, ShndxF, MSD, Layout);
@@ -759,9 +763,6 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) +
Fixup.getOffset();
- // FIXME: no tests cover this. Is adjustFixupOffset dead code?
- TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset);
-
if (!hasRelocationAddend())
Addend = 0;
@@ -883,6 +884,20 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
// FIXME: We could optimize suffixes in strtab in the same way we
// optimize them in shstrtab.
+ for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(),
+ ie = Asm.file_names_end();
+ it != ie;
+ ++it) {
+ StringRef Name = *it;
+ uint64_t &Entry = StringIndexMap[Name];
+ if (!Entry) {
+ Entry = StringTable.size();
+ StringTable += Name;
+ StringTable += '\x00';
+ }
+ FileSymbolData.push_back(Entry);
+ }
+
// Add the data for the symbols.
for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
ie = Asm.symbol_end(); it != ie; ++it) {
@@ -967,7 +982,7 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
// Set the symbol indices. Local symbols must come before all other
// symbols with non-local bindings.
- unsigned Index = 1;
+ unsigned Index = FileSymbolData.size() + 1;
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
LocalSymbolData[i].SymbolData->setIndex(Index++);
@@ -1005,11 +1020,18 @@ void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
else
EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
+ unsigned Flags = 0;
+ StringRef Group = "";
+ if (Section.getFlags() & ELF::SHF_GROUP) {
+ Flags = ELF::SHF_GROUP;
+ Group = Section.getGroup()->getName();
+ }
+
const MCSectionELF *RelaSection =
Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
- ELF::SHT_RELA : ELF::SHT_REL, 0,
+ ELF::SHT_RELA : ELF::SHT_REL, Flags,
SectionKind::getReadOnly(),
- EntrySize, "");
+ EntrySize, Group);
RelMap[&Section] = RelaSection;
Asm.getOrCreateSectionData(*RelaSection);
}
@@ -1069,7 +1091,7 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
else if (entry.Index < 0)
entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol);
else
- entry.Index += LocalSymbolData.size();
+ entry.Index += FileSymbolData.size() + LocalSymbolData.size();
if (is64Bit()) {
String64(*F, entry.r_offset);
if (TargetObjectWriter->isN64()) {
@@ -1100,11 +1122,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
}
}
-static int compareBySuffix(const void *a, const void *b) {
- const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a);
- const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b);
- const StringRef &NameA = secA->getSectionName();
- const StringRef &NameB = secB->getSectionName();
+static int compareBySuffix(const MCSectionELF *const *a,
+ const MCSectionELF *const *b) {
+ const StringRef &NameA = (*a)->getSectionName();
+ const StringRef &NameB = (*b)->getSectionName();
const unsigned sizeA = NameA.size();
const unsigned sizeB = NameB.size();
const unsigned len = std::min(sizeA, sizeB);
@@ -1295,10 +1316,12 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
// Remove ".rel" and ".rela" prefixes.
unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
StringRef SectionName = Section.getSectionName().substr(SecNameLen);
+ StringRef GroupName =
+ Section.getGroup() ? Section.getGroup()->getName() : "";
- InfoSection = Asm.getContext().getELFSection(SectionName,
- ELF::SHT_PROGBITS, 0,
- SectionKind::getReadOnly());
+ InfoSection = Asm.getContext().getELFSection(SectionName, ELF::SHT_PROGBITS,
+ 0, SectionKind::getReadOnly(),
+ 0, GroupName);
sh_info = SectionIndexMap.lookup(InfoSection);
break;
}
@@ -1348,11 +1371,12 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
SectionKind::getText()));
} else if (SecName.startswith(".ARM.exidx")) {
- sh_link = SectionIndexMap.lookup(
- Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1),
- ELF::SHT_PROGBITS,
- ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
- SectionKind::getText()));
+ StringRef GroupName =
+ Section.getGroup() ? Section.getGroup()->getName() : "";
+ sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection(
+ SecName.substr(sizeof(".ARM.exidx") - 1), ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, SectionKind::getText(), 0,
+ GroupName));
}
}
diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp
index 53960e7..c4c98cc 100644
--- a/contrib/llvm/lib/MC/MCAsmBackend.cpp
+++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCFixupKindInfo.h"
using namespace llvm;
@@ -37,7 +38,6 @@ MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{ "FK_SecRel_8", 0, 64, 0 }
};
- assert((size_t)Kind <= sizeof(Builtins) / sizeof(Builtins[0]) &&
- "Unknown fixup kind");
+ assert((size_t)Kind <= array_lengthof(Builtins) && "Unknown fixup kind");
return Builtins[Kind];
}
diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp
index 9e60884..28f1c95 100644
--- a/contrib/llvm/lib/MC/MCAsmInfo.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp
@@ -34,7 +34,8 @@ MCAsmInfo::MCAsmInfo() {
HasStaticCtorDtorReferenceInStaticMode = false;
LinkerRequiresNonEmptyDwarfLines = false;
MaxInstLength = 4;
- PCSymbol = "$";
+ MinInstAlignment = 1;
+ DollarIsPC = false;
SeparatorString = ";";
CommentColumn = 40;
CommentString = "#";
@@ -49,10 +50,7 @@ MCAsmInfo::MCAsmInfo() {
Code32Directive = ".code32";
Code64Directive = ".code64";
AssemblerDialect = 0;
- AllowQuotesInName = false;
- AllowNameToStartWithDigit = false;
- AllowPeriodsInName = true;
- AllowUTF8 = true;
+ AllowAtInName = false;
UseDataRegionDirectives = false;
ZeroDirective = "\t.zero\t";
AsciiDirective = "\t.ascii\t";
@@ -75,8 +73,8 @@ MCAsmInfo::MCAsmInfo() {
LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
HasDotTypeDotSizeDirective = true;
HasSingleParameterDotFile = true;
+ HasIdentDirective = false;
HasNoDeadStrip = false;
- HasSymbolResolver = false;
WeakRefDirective = 0;
WeakDefDirective = 0;
LinkOnceDirective = 0;
@@ -86,7 +84,6 @@ MCAsmInfo::MCAsmInfo() {
HasLEB128 = false;
SupportsDebugInformation = false;
ExceptionsType = ExceptionHandling::None;
- DwarfUsesInlineInfoSection = false;
DwarfUsesRelocationsAcrossSections = true;
DwarfRegNumForCFI = false;
HasMicrosoftFastStdCallMangling = false;
@@ -97,7 +94,7 @@ MCAsmInfo::~MCAsmInfo() {
}
-unsigned MCAsmInfo::getULEB128Size(unsigned Value) {
+unsigned MCAsmInfo::getULEB128Size(uint64_t Value) {
unsigned Size = 0;
do {
Value >>= 7;
@@ -106,7 +103,7 @@ unsigned MCAsmInfo::getULEB128Size(unsigned Value) {
return Size;
}
-unsigned MCAsmInfo::getSLEB128Size(int Value) {
+unsigned MCAsmInfo::getSLEB128Size(int64_t Value) {
unsigned Size = 0;
int Sign = Value >> (8 * sizeof(Value) - 1);
bool IsMore;
diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
index 33350d9..9d9f98e 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp
@@ -43,7 +43,6 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() {
void MCAsmInfoMicrosoft::anchor() { }
MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() {
- AllowQuotesInName = true;
}
void MCAsmInfoGNUCOFF::anchor() { }
diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
index a0e3eba..704c816 100644
--- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
+++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp
@@ -26,7 +26,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
GlobalPrefix = "_";
PrivateGlobalPrefix = "L";
LinkerPrivateGlobalPrefix = "l";
- AllowQuotesInName = true;
HasSingleParameterDotFile = false;
HasSubsectionsViaSymbols = true;
@@ -58,7 +57,6 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
HasDotTypeDotSizeDirective = false;
HasNoDeadStrip = true;
- HasSymbolResolver = true;
DwarfUsesRelocationsAcrossSections = false;
}
diff --git a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
new file mode 100644
index 0000000..8cf4e4f
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp
@@ -0,0 +1,23 @@
+//===-- MCAsmInfoELF.cpp - ELF asm properties -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target asm properties related what form asm statements
+// should take in general on ELF-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCAsmInfoELF.h"
+using namespace llvm;
+
+void MCAsmInfoELF::anchor() { }
+
+MCAsmInfoELF::MCAsmInfoELF() {
+ HasIdentDirective = true;
+ WeakRefDirective = "\t.weak\t";
+}
diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
index 9e86785..ca49f8f 100644
--- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp
@@ -25,11 +25,12 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/PathV2.h"
+#include "llvm/Support/Path.h"
#include <cctype>
using namespace llvm;
@@ -38,7 +39,7 @@ namespace {
class MCAsmStreamer : public MCStreamer {
protected:
formatted_raw_ostream &OS;
- const MCAsmInfo &MAI;
+ const MCAsmInfo *MAI;
private:
OwningPtr<MCInstPrinter> InstPrinter;
OwningPtr<MCCodeEmitter> Emitter;
@@ -65,17 +66,15 @@ private:
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
public:
- MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
- bool isVerboseAsm, bool useLoc, bool useCFI,
- bool useDwarfDirectory,
- MCInstPrinter *printer, MCCodeEmitter *emitter,
- MCAsmBackend *asmbackend,
- bool showInst)
- : MCStreamer(SK_AsmStreamer, Context), OS(os), MAI(Context.getAsmInfo()),
- InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
- CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
- ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
- UseDwarfDirectory(useDwarfDirectory) {
+ MCAsmStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
+ formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc,
+ bool useCFI, bool useDwarfDirectory, MCInstPrinter *printer,
+ MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst)
+ : MCStreamer(Context, TargetStreamer), OS(os), MAI(Context.getAsmInfo()),
+ InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
+ CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
+ ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
+ UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream);
}
@@ -154,7 +153,7 @@ public:
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label);
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
@@ -180,12 +179,10 @@ public:
virtual void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitBytes(StringRef Data);
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace);
- virtual void EmitIntValue(uint64_t Value, unsigned Size,
- unsigned AddrSpace = 0);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
+ virtual void EmitIntValue(uint64_t Value, unsigned Size);
virtual void EmitULEB128Value(const MCExpr *Value);
@@ -196,8 +193,7 @@ public:
virtual void EmitGPRel32Value(const MCExpr *Value);
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
@@ -217,6 +213,7 @@ public:
unsigned Isa, unsigned Discriminator,
StringRef FileName);
+ virtual void EmitIdent(StringRef IdentString);
virtual void EmitCFISections(bool EH, bool Debug);
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
virtual void EmitCFIDefCfaOffset(int64_t Offset);
@@ -232,6 +229,7 @@ public:
virtual void EmitCFISignalFrame();
virtual void EmitCFIUndefined(int64_t Register);
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
+ virtual void EmitCFIWindowSave();
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
@@ -248,17 +246,6 @@ public:
virtual void EmitWin64EHPushFrame(bool Code);
virtual void EmitWin64EHEndProlog();
- virtual void EmitFnStart();
- virtual void EmitFnEnd();
- virtual void EmitCantUnwind();
- virtual void EmitPersonality(const MCSymbol *Personality);
- virtual void EmitHandlerData();
- virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
- virtual void EmitPad(int64_t Offset);
- virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
-
- virtual void EmitTCEntry(const MCSymbol &S);
-
virtual void EmitInstruction(const MCInst &Inst);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
@@ -268,15 +255,9 @@ public:
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
- virtual void EmitRawText(StringRef String);
+ virtual void EmitRawTextImpl(StringRef String);
virtual void FinishImpl();
-
- /// @}
-
- static bool classof(const MCStreamer *S) {
- return S->getKind() == SK_AsmStreamer;
- }
};
} // end anonymous namespace.
@@ -312,9 +293,9 @@ void MCAsmStreamer::EmitCommentsAndEOL() {
"Comment array not newline terminated");
do {
// Emit a line of comments.
- OS.PadToColumn(MAI.getCommentColumn());
+ OS.PadToColumn(MAI->getCommentColumn());
size_t Position = Comments.find('\n');
- OS << MAI.getCommentString() << ' ' << Comments.substr(0, Position) << '\n';
+ OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
Comments = Comments.substr(Position+1);
} while (!Comments.empty());
@@ -332,7 +313,7 @@ static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
void MCAsmStreamer::ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
assert(Section && "Cannot switch to a null section!");
- Section->PrintSwitchToSection(MAI, OS, Subsection);
+ Section->PrintSwitchToSection(*MAI, OS, Subsection);
}
void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
@@ -354,7 +335,7 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCStreamer::EmitLabel(Symbol);
- OS << *Symbol << MAI.getLabelSuffix();
+ OS << *Symbol << MAI->getLabelSuffix();
EmitEOL();
}
@@ -362,7 +343,7 @@ void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCStreamer::EmitDebugLabel(Symbol);
- OS << *Symbol << MAI.getDebugLabelSuffix();
+ OS << *Symbol << MAI->getDebugLabelSuffix();
EmitEOL();
}
@@ -370,9 +351,9 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
- case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break;
- case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break;
- case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break;
+ case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
+ case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
+ case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
}
EmitEOL();
}
@@ -388,9 +369,7 @@ void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
}
void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
- MCContext &Ctx = getContext();
- const MCAsmInfo &MAI = Ctx.getAsmInfo();
- if (!MAI.doesSupportDataRegionDirectives())
+ if (!MAI->doesSupportDataRegionDirectives())
return;
switch (Kind) {
case MCDR_DataRegion: OS << "\t.data_region"; break;
@@ -407,7 +386,7 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
// MCSymbols when they have spaces in them.
OS << "\t.thumb_func";
// Only Mach-O hasSubsectionsViaSymbols()
- if (MAI.hasSubsectionsViaSymbols())
+ if (MAI->hasSubsectionsViaSymbols())
OS << '\t' << *Func;
EmitEOL();
}
@@ -441,7 +420,7 @@ void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
}
-void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
switch (Attribute) {
case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
@@ -452,11 +431,12 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
- assert(MAI.hasDotTypeDotSizeDirective() && "Symbol Attr not supported");
+ if (!MAI->hasDotTypeDotSizeDirective())
+ return false; // Symbol attribute not supported
OS << "\t.type\t" << *Symbol << ','
- << ((MAI.getCommentString()[0] != '@') ? '@' : '%');
+ << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
switch (Attribute) {
- default: llvm_unreachable("Unknown ELF .type");
+ default: return false;
case MCSA_ELF_TypeFunction: OS << "function"; break;
case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
case MCSA_ELF_TypeObject: OS << "object"; break;
@@ -466,9 +446,9 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
}
EmitEOL();
- return;
+ return true;
case MCSA_Global: // .globl/.global
- OS << MAI.getGlobalDirective();
+ OS << MAI->getGlobalDirective();
FlagMap[Symbol] |= EHGlobal;
break;
case MCSA_Hidden: OS << "\t.hidden\t"; break;
@@ -490,12 +470,14 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
FlagMap[Symbol] |= EHWeakDefinition;
break;
// .weak_reference
- case MCSA_WeakReference: OS << MAI.getWeakRefDirective(); break;
+ case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
}
OS << *Symbol;
EmitEOL();
+
+ return true;
}
void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
@@ -529,15 +511,18 @@ void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
}
void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
- assert(MAI.hasDotTypeDotSizeDirective());
+ assert(MAI->hasDotTypeDotSizeDirective());
OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
}
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
+ // Common symbols do not belong to any actual section.
+ AssignSection(Symbol, NULL);
+
OS << "\t.comm\t" << *Symbol << ',' << Size;
if (ByteAlignment != 0) {
- if (MAI.getCOMMDirectiveAlignmentIsInBytes())
+ if (MAI->getCOMMDirectiveAlignmentIsInBytes())
OS << ',' << ByteAlignment;
else
OS << ',' << Log2_32(ByteAlignment);
@@ -551,9 +536,12 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
/// @param Size - The size of the common symbol.
void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlign) {
+ // Common symbols do not belong to any actual section.
+ AssignSection(Symbol, NULL);
+
OS << "\t.lcomm\t" << *Symbol << ',' << Size;
if (ByteAlign > 1) {
- switch (MAI.getLCOMMDirectiveAlignmentType()) {
+ switch (MAI->getLCOMMDirectiveAlignmentType()) {
case LCOMM::NoAlignment:
llvm_unreachable("alignment not supported on .lcomm!");
case LCOMM::ByteAlignment:
@@ -570,6 +558,9 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
+ if (Symbol)
+ AssignSection(Symbol, Section);
+
// Note: a .zerofill directive does not switch sections.
OS << ".zerofill ";
@@ -590,6 +581,8 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
// e.g. _a.
void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
+ AssignSection(Symbol, Section);
+
assert(Symbol != NULL && "Symbol shouldn't be NULL!");
// Instead of using the Section we'll just use the shortcut.
// This is a mach-o specific directive and section.
@@ -638,13 +631,13 @@ static void PrintQuotedString(StringRef Data, raw_ostream &OS) {
}
-void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
+void MCAsmStreamer::EmitBytes(StringRef Data) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
if (Data.empty()) return;
if (Data.size() == 1) {
- OS << MAI.getData8bitsDirective(AddrSpace);
+ OS << MAI->getData8bitsDirective();
OS << (unsigned)(unsigned char)Data[0];
EmitEOL();
return;
@@ -652,46 +645,43 @@ void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
// If the data ends with 0 and the target supports .asciz, use it, otherwise
// use .ascii
- if (MAI.getAscizDirective() && Data.back() == 0) {
- OS << MAI.getAscizDirective();
+ if (MAI->getAscizDirective() && Data.back() == 0) {
+ OS << MAI->getAscizDirective();
Data = Data.substr(0, Data.size()-1);
} else {
- OS << MAI.getAsciiDirective();
+ OS << MAI->getAsciiDirective();
}
- OS << ' ';
PrintQuotedString(Data, OS);
EmitEOL();
}
-void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size,
- unsigned AddrSpace) {
- EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace);
+void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
+ EmitValue(MCConstantExpr::Create(Value, getContext()), Size);
}
-void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {
+void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
const char *Directive = 0;
switch (Size) {
default: break;
- case 1: Directive = MAI.getData8bitsDirective(AddrSpace); break;
- case 2: Directive = MAI.getData16bitsDirective(AddrSpace); break;
- case 4: Directive = MAI.getData32bitsDirective(AddrSpace); break;
+ case 1: Directive = MAI->getData8bitsDirective(); break;
+ case 2: Directive = MAI->getData16bitsDirective(); break;
+ case 4: Directive = MAI->getData32bitsDirective(); break;
case 8:
- Directive = MAI.getData64bitsDirective(AddrSpace);
+ Directive = MAI->getData64bitsDirective();
// If the target doesn't support 64-bit data, emit as two 32-bit halves.
if (Directive) break;
int64_t IntValue;
if (!Value->EvaluateAsAbsolute(IntValue))
report_fatal_error("Don't know how to emit this value.");
- if (getContext().getAsmInfo().isLittleEndian()) {
- EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
- EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
+ if (MAI->isLittleEndian()) {
+ EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
+ EmitIntValue((uint32_t)(IntValue >> 32), 4);
} else {
- EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace);
- EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace);
+ EmitIntValue((uint32_t)(IntValue >> 32), 4);
+ EmitIntValue((uint32_t)(IntValue >> 0 ), 4);
}
return;
}
@@ -707,7 +697,7 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) {
EmitULEB128IntValue(IntValue);
return;
}
- assert(MAI.hasLEB128() && "Cannot print a .uleb");
+ assert(MAI->hasLEB128() && "Cannot print a .uleb");
OS << ".uleb128 " << *Value;
EmitEOL();
}
@@ -718,41 +708,39 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) {
EmitSLEB128IntValue(IntValue);
return;
}
- assert(MAI.hasLEB128() && "Cannot print a .sleb");
+ assert(MAI->hasLEB128() && "Cannot print a .sleb");
OS << ".sleb128 " << *Value;
EmitEOL();
}
void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) {
- assert(MAI.getGPRel64Directive() != 0);
- OS << MAI.getGPRel64Directive() << *Value;
+ assert(MAI->getGPRel64Directive() != 0);
+ OS << MAI->getGPRel64Directive() << *Value;
EmitEOL();
}
void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
- assert(MAI.getGPRel32Directive() != 0);
- OS << MAI.getGPRel32Directive() << *Value;
+ assert(MAI->getGPRel32Directive() != 0);
+ OS << MAI->getGPRel32Directive() << *Value;
EmitEOL();
}
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
-void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace) {
+void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
if (NumBytes == 0) return;
- if (AddrSpace == 0)
- if (const char *ZeroDirective = MAI.getZeroDirective()) {
- OS << ZeroDirective << NumBytes;
- if (FillValue != 0)
- OS << ',' << (int)FillValue;
- EmitEOL();
- return;
- }
+ if (const char *ZeroDirective = MAI->getZeroDirective()) {
+ OS << ZeroDirective << NumBytes;
+ if (FillValue != 0)
+ OS << ',' << (int)FillValue;
+ EmitEOL();
+ return;
+ }
// Emit a byte at a time.
- MCStreamer::EmitFill(NumBytes, FillValue, AddrSpace);
+ MCStreamer::EmitFill(NumBytes, FillValue);
}
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
@@ -763,14 +751,14 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
if (isPowerOf2_32(ByteAlignment)) {
switch (ValueSize) {
default: llvm_unreachable("Invalid size for machine code value!");
- case 1: OS << MAI.getAlignDirective(); break;
+ case 1: OS << MAI->getAlignDirective(); break;
// FIXME: use MAI for this!
case 2: OS << ".p2alignw "; break;
case 4: OS << ".p2alignl "; break;
case 8: llvm_unreachable("Unsupported alignment size!");
}
- if (MAI.getAlignmentIsInBytes())
+ if (MAI->getAlignmentIsInBytes())
OS << ByteAlignment;
else
OS << Log2_32(ByteAlignment);
@@ -806,7 +794,7 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit) {
// Emit with a text fill value.
- EmitValueToAlignment(ByteAlignment, MAI.getTextAlignFillValue(),
+ EmitValueToAlignment(ByteAlignment, MAI->getTextAlignFillValue(),
1, MaxBytesToEmit);
}
@@ -820,7 +808,7 @@ bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
- assert(MAI.hasSingleParameterDotFile());
+ assert(MAI->hasSingleParameterDotFile());
OS << "\t.file\t";
PrintQuotedString(Filename, OS);
EmitEOL();
@@ -886,13 +874,20 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
OS << "discriminator " << Discriminator;
if (IsVerboseAsm) {
- OS.PadToColumn(MAI.getCommentColumn());
- OS << MAI.getCommentString() << ' ' << FileName << ':'
+ OS.PadToColumn(MAI->getCommentColumn());
+ OS << MAI->getCommentString() << ' ' << FileName << ':'
<< Line << ':' << Column;
}
EmitEOL();
}
+void MCAsmStreamer::EmitIdent(StringRef IdentString) {
+ assert(MAI->hasIdentDirective() && ".ident directive not supported");
+ OS << "\t.ident\t";
+ PrintQuotedString(IdentString, OS);
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) {
MCStreamer::EmitCFISections(EH, Debug);
@@ -936,9 +931,9 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
}
void MCAsmStreamer::EmitRegisterName(int64_t Register) {
- if (InstPrinter && !MAI.useDwarfRegNumForCFI()) {
- const MCRegisterInfo &MRI = getContext().getRegisterInfo();
- unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true);
+ if (InstPrinter && !MAI->useDwarfRegNumForCFI()) {
+ const MCRegisterInfo *MRI = getContext().getRegisterInfo();
+ unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true);
InstPrinter->printRegName(OS, LLVMRegister);
} else {
OS << Register;
@@ -1094,6 +1089,16 @@ void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
EmitEOL();
}
+void MCAsmStreamer::EmitCFIWindowSave() {
+ MCStreamer::EmitCFIWindowSave();
+
+ if (!UseCFI)
+ return;
+
+ OS << "\t.cfi_window_save";
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
MCStreamer::EmitWin64EHStartProc(Symbol);
@@ -1276,7 +1281,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
unsigned Bit = (Code[i] >> j) & 1;
unsigned FixupBit;
- if (getContext().getAsmInfo().isLittleEndian())
+ if (MAI->isLittleEndian())
FixupBit = i * 8 + j;
else
FixupBit = i * 8 + (7-j);
@@ -1299,73 +1304,6 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
}
}
-void MCAsmStreamer::EmitFnStart() {
- OS << "\t.fnstart";
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitFnEnd() {
- OS << "\t.fnend";
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitCantUnwind() {
- OS << "\t.cantunwind";
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitHandlerData() {
- OS << "\t.handlerdata";
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
- OS << "\t.personality " << Personality->getName();
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
- OS << "\t.setfp\t";
- InstPrinter->printRegName(OS, FpReg);
- OS << ", ";
- InstPrinter->printRegName(OS, SpReg);
- if (Offset)
- OS << ", #" << Offset;
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitPad(int64_t Offset) {
- OS << "\t.pad\t#" << Offset;
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
- bool isVector) {
- assert(RegList.size() && "RegList should not be empty");
- if (isVector)
- OS << "\t.vsave\t{";
- else
- OS << "\t.save\t{";
-
- InstPrinter->printRegName(OS, RegList[0]);
-
- for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
- OS << ", ";
- InstPrinter->printRegName(OS, RegList[i]);
- }
-
- OS << "}";
- EmitEOL();
-}
-
-void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) {
- OS << "\t.tc ";
- OS << S.getName();
- OS << "[TC],";
- OS << S.getName();
- EmitEOL();
-}
-
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
@@ -1376,7 +1314,7 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
// Show the MCInst if enabled.
if (ShowInst) {
- Inst.dump_pretty(GetCommentOS(), &MAI, InstPrinter.get(), "\n ");
+ Inst.dump_pretty(GetCommentOS(), MAI, InstPrinter.get(), "\n ");
GetCommentOS() << "\n";
}
@@ -1384,7 +1322,7 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
if (InstPrinter)
InstPrinter->printInst(&Inst, OS, "");
else
- Inst.print(OS, &MAI);
+ Inst.print(OS, MAI);
EmitEOL();
}
@@ -1408,7 +1346,7 @@ void MCAsmStreamer::EmitBundleUnlock() {
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
-void MCAsmStreamer::EmitRawText(StringRef String) {
+void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
if (!String.empty() && String.back() == '\n')
String = String.substr(0, String.size()-1);
OS << String;
@@ -1427,14 +1365,16 @@ void MCAsmStreamer::FinishImpl() {
MCGenDwarfInfo::Emit(this, LineSectionSymbol);
if (!UseCFI)
- EmitFrames(false);
+ EmitFrames(AsmBackend.get(), false);
}
+
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
+ MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &OS,
- bool isVerboseAsm, bool useLoc,
- bool useCFI, bool useDwarfDirectory,
- MCInstPrinter *IP, MCCodeEmitter *CE,
- MCAsmBackend *MAB, bool ShowInst) {
- return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
- useDwarfDirectory, IP, CE, MAB, ShowInst);
+ bool isVerboseAsm, bool useLoc, bool useCFI,
+ bool useDwarfDirectory, MCInstPrinter *IP,
+ MCCodeEmitter *CE, MCAsmBackend *MAB,
+ bool ShowInst) {
+ return new MCAsmStreamer(Context, TargetStreamer, OS, isVerboseAsm, useLoc,
+ useCFI, useDwarfDirectory, IP, CE, MAB, ShowInst);
}
diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp
index fb5ab28..68111f1 100644
--- a/contrib/llvm/lib/MC/MCAssembler.cpp
+++ b/contrib/llvm/lib/MC/MCAssembler.cpp
@@ -580,10 +580,10 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_Align: {
++stats::EmittedAlignFragments;
const MCAlignFragment &AF = cast<MCAlignFragment>(F);
- uint64_t Count = FragmentSize / AF.getValueSize();
-
assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");
+ uint64_t Count = FragmentSize / AF.getValueSize();
+
// FIXME: This error shouldn't actually occur (the front end should emit
// multiple .align directives to enforce the semantics it wants), but is
// severe enough that we want to report it. How to handle this?
@@ -708,12 +708,13 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
case MCFragment::FT_Align:
// Check that we aren't trying to write a non-zero value into a virtual
// section.
- assert((!cast<MCAlignFragment>(it)->getValueSize() ||
- !cast<MCAlignFragment>(it)->getValue()) &&
+ assert((cast<MCAlignFragment>(it)->getValueSize() == 0 ||
+ cast<MCAlignFragment>(it)->getValue() == 0) &&
"Invalid align in virtual section!");
break;
case MCFragment::FT_Fill:
- assert(!cast<MCFillFragment>(it)->getValueSize() &&
+ assert((cast<MCFillFragment>(it)->getValueSize() == 0 ||
+ cast<MCFillFragment>(it)->getValue() == 0) &&
"Invalid fill in virtual section!");
break;
}
@@ -904,6 +905,7 @@ 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);
@@ -914,13 +916,14 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout,
SmallString<8> &Data = DF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
- MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OSE);
+ MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OSE);
OSE.flush();
return OldSize != Data.size();
}
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);
@@ -929,7 +932,7 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
SmallString<8> &Data = DF.getContents();
Data.clear();
raw_svector_ostream OSE(Data);
- MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OSE);
+ MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OSE);
OSE.flush();
return OldSize != Data.size();
}
diff --git a/contrib/llvm/lib/MC/MCAtom.cpp b/contrib/llvm/lib/MC/MCAtom.cpp
index d714443..bc353cd 100644
--- a/contrib/llvm/lib/MC/MCAtom.cpp
+++ b/contrib/llvm/lib/MC/MCAtom.cpp
@@ -10,88 +10,105 @@
#include "llvm/MC/MCAtom.h"
#include "llvm/MC/MCModule.h"
#include "llvm/Support/ErrorHandling.h"
+#include <iterator>
using namespace llvm;
-void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) {
- assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!");
+// Pin the vtable to this file.
+void MCAtom::anchor() {}
- assert(Address < End+Size &&
- "Instruction not contiguous with end of atom!");
- if (Address > End)
- Parent->remap(this, Begin, End+Size);
-
- Text.push_back(std::make_pair(Address, I));
+void MCAtom::remap(uint64_t NewBegin, uint64_t NewEnd) {
+ Parent->remap(this, NewBegin, NewEnd);
}
-void MCAtom::addData(const MCData &D) {
- assert(Type == DataAtom && "Trying to add MCData to a non-data atom!");
- Parent->remap(this, Begin, End+1);
-
- Data.push_back(D);
+void MCAtom::remapForTruncate(uint64_t TruncPt) {
+ assert((TruncPt >= Begin && TruncPt < End) &&
+ "Truncation point not contained in atom!");
+ remap(Begin, TruncPt);
}
-MCAtom *MCAtom::split(uint64_t SplitPt) {
+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.
- uint64_t LeftBegin = Begin;
- uint64_t LeftEnd = SplitPt - 1;
- uint64_t RightBegin = SplitPt;
- uint64_t RightEnd = End;
+ LBegin = Begin;
+ LEnd = SplitPt - 1;
+ RBegin = SplitPt;
+ REnd = End;
// Remap this atom to become the lower of the two new ones.
- Parent->remap(this, LeftBegin, LeftEnd);
+ remap(LBegin, LEnd);
+}
- // Create a new atom for the higher atom.
- MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd);
+// MCDataAtom
- // Split the contents of the original atom between it and the new one. The
- // precise method depends on whether this is a data or a text atom.
- if (isDataAtom()) {
- std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin);
+void MCDataAtom::addData(const MCData &D) {
+ Data.push_back(D);
+ if (Data.size() > End + 1 - Begin)
+ remap(Begin, End + 1);
+}
- assert(I != Data.end() && "Split point not found in range!");
+void MCDataAtom::truncate(uint64_t TruncPt) {
+ remapForTruncate(TruncPt);
- std::copy(I, Data.end(), RightAtom->Data.end());
- Data.erase(I, Data.end());
- } else if (isTextAtom()) {
- std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
+ Data.resize(TruncPt - Begin + 1);
+}
- while (I != Text.end() && I->first < SplitPt) ++I;
+MCDataAtom *MCDataAtom::split(uint64_t SplitPt) {
+ uint64_t LBegin, LEnd, RBegin, REnd;
+ remapForSplit(SplitPt, LBegin, LEnd, RBegin, REnd);
- assert(I != Text.end() && "Split point not found in disassembly!");
- assert(I->first == SplitPt &&
- "Split point does not fall on instruction boundary!");
+ MCDataAtom *RightAtom = Parent->createDataAtom(RBegin, REnd);
+ RightAtom->setName(getName());
- std::copy(I, Text.end(), RightAtom->Text.end());
- Text.erase(I, Text.end());
- } else
- llvm_unreachable("Unknown atom type!");
+ 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;
}
-void MCAtom::truncate(uint64_t TruncPt) {
- assert((TruncPt >= Begin && TruncPt < End) &&
- "Truncation point not contained in atom!");
+// MCTextAtom
- Parent->remap(this, Begin, TruncPt);
+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;
+}
- if (isDataAtom()) {
- Data.resize(TruncPt - Begin + 1);
- } else if (isTextAtom()) {
- std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
+void MCTextAtom::truncate(uint64_t TruncPt) {
+ remapForTruncate(TruncPt);
- while (I != Text.end() && I->first <= TruncPt) ++I;
+ InstListTy::iterator I = Insts.begin();
+ while (I != Insts.end() && I->Address <= TruncPt) ++I;
- assert(I != Text.end() && "Truncation point not found in disassembly!");
- assert(I->first == TruncPt+1 &&
- "Truncation point does not fall on instruction boundary");
+ assert(I != Insts.end() && "Truncation point not found in disassembly!");
+ assert(I->Address == TruncPt + 1 &&
+ "Truncation point does not fall on instruction boundary");
- Text.erase(I, Text.end());
- } else
- llvm_unreachable("Unknown atom type!");
+ 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/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp
index 9adcc02..a0acda5 100644
--- a/contrib/llvm/lib/MC/MCContext.cpp
+++ b/contrib/llvm/lib/MC/MCContext.cpp
@@ -21,27 +21,35 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
+
+#include <map>
+
using namespace llvm;
-typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
-typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
-typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
+typedef std::pair<std::string, std::string> SectionGroupPair;
+typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
+typedef std::map<SectionGroupPair, const MCSectionELF *> ELFUniqueMapTy;
+typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy;
-MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
+MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
bool DoAutoReset) :
SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
Allocator(), Symbols(Allocator), UsedNames(Allocator),
NextUniqueID(0),
- CompilationDir(llvm::sys::Path::GetCurrentDirectory().str()),
CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0),
AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
+ error_code EC = llvm::sys::fs::current_path(CompilationDir);
+ if (EC)
+ CompilationDir.clear();
+
MachOUniquingMap = 0;
ELFUniquingMap = 0;
COFFUniquingMap = 0;
@@ -126,7 +134,7 @@ MCSymbol *MCContext::CreateSymbol(StringRef Name) {
// Determine whether this is an assembler temporary or normal label, if used.
bool isTemporary = false;
if (AllowTemporaryLabels)
- isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
+ isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
if (NameEntry->getValue()) {
@@ -156,7 +164,7 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
MCSymbol *MCContext::CreateTempSymbol() {
SmallString<128> NameSV;
raw_svector_ostream(NameSV)
- << MAI.getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
+ << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
return CreateSymbol(NameSV);
}
@@ -175,14 +183,14 @@ unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
}
MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
- return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
+ return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
Twine(LocalLabelVal) +
"\2" +
Twine(NextInstance(LocalLabelVal)));
}
MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
int bORf) {
- return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
+ return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
Twine(LocalLabelVal) +
"\2" +
Twine(GetInstance(LocalLabelVal) + bORf));
@@ -245,8 +253,9 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags,
ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
// Do the lookup, if we have a hit, return it.
- StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
- if (Entry.getValue()) return Entry.getValue();
+ std::pair<ELFUniqueMapTy::iterator, bool> Entry = Map.insert(
+ std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0));
+ if (!Entry.second) return Entry.first->second;
// Possibly refine the entry size first.
if (!EntrySize) {
@@ -257,9 +266,9 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags,
if (!Group.empty())
GroupSym = GetOrCreateSymbol(Group);
- MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
- Kind, EntrySize, GroupSym);
- Entry.setValue(Result);
+ MCSectionELF *Result = new (*this) MCSectionELF(
+ Entry.first->first.first, Type, Flags, Kind, EntrySize, GroupSym);
+ Entry.first->second = Result;
return Result;
}
@@ -270,26 +279,53 @@ const MCSectionELF *MCContext::CreateELFGroupSection() {
return Result;
}
-const MCSection *MCContext::getCOFFSection(StringRef Section,
- unsigned Characteristics,
- int Selection,
- SectionKind Kind) {
+const MCSectionCOFF *
+MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind, StringRef COMDATSymName,
+ int Selection, const MCSectionCOFF *Assoc) {
if (COFFUniquingMap == 0)
COFFUniquingMap = new COFFUniqueMapTy();
COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
// Do the lookup, if we have a hit, return it.
- StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
- if (Entry.getValue()) return Entry.getValue();
- MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
- Characteristics,
- Selection, Kind);
+ SectionGroupPair P(Section, COMDATSymName);
+ std::pair<COFFUniqueMapTy::iterator, bool> Entry =
+ Map.insert(std::make_pair(P, (MCSectionCOFF *)0));
+ COFFUniqueMapTy::iterator Iter = Entry.first;
+ if (!Entry.second)
+ return Iter->second;
+
+ const MCSymbol *COMDATSymbol = NULL;
+ if (!COMDATSymName.empty())
+ COMDATSymbol = GetOrCreateSymbol(COMDATSymName);
- Entry.setValue(Result);
+ MCSectionCOFF *Result =
+ new (*this) MCSectionCOFF(Iter->first.first, Characteristics,
+ COMDATSymbol, Selection, Assoc, Kind);
+
+ Iter->second = Result;
return Result;
}
+const MCSectionCOFF *
+MCContext::getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind) {
+ return getCOFFSection(Section, Characteristics, Kind, "", 0);
+}
+
+const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
+ if (COFFUniquingMap == 0)
+ COFFUniquingMap = new COFFUniqueMapTy();
+ COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
+
+ SectionGroupPair P(Section, "");
+ COFFUniqueMapTy::iterator Iter = Map.find(P);
+ if (Iter == Map.end())
+ return 0;
+ return Iter->second;
+}
+
//===----------------------------------------------------------------------===//
// Dwarf Management
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/MC/MCDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler.cpp
index 0809690..bfd51ab 100644
--- a/contrib/llvm/lib/MC/MCDisassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler.cpp
@@ -8,7 +8,49 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCExternalSymbolizer.h"
+#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
MCDisassembler::~MCDisassembler() {
}
+
+void
+MCDisassembler::setupForSymbolicDisassembly(
+ LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp,
+ void *DisInfo,
+ MCContext *Ctx,
+ OwningPtr<MCRelocationInfo> &RelInfo) {
+ this->GetOpInfo = GetOpInfo;
+ this->SymbolLookUp = SymbolLookUp;
+ this->DisInfo = DisInfo;
+ this->Ctx = Ctx;
+ assert(Ctx != 0 && "No MCContext given for symbolic disassembly");
+ if (!Symbolizer)
+ Symbolizer.reset(new MCExternalSymbolizer(*Ctx, RelInfo, GetOpInfo,
+ SymbolLookUp, DisInfo));
+}
+
+bool MCDisassembler::tryAddingSymbolicOperand(MCInst &Inst, int64_t Value,
+ uint64_t Address, bool IsBranch,
+ uint64_t Offset,
+ uint64_t InstSize) const {
+ raw_ostream &cStream = CommentStream ? *CommentStream : nulls();
+ if (Symbolizer)
+ return Symbolizer->tryAddingSymbolicOperand(Inst, cStream, Value, Address,
+ IsBranch, Offset, InstSize);
+ return false;
+}
+
+void MCDisassembler::tryAddingPcLoadReferenceComment(int64_t Value,
+ uint64_t Address) const {
+ raw_ostream &cStream = CommentStream ? *CommentStream : nulls();
+ if (Symbolizer)
+ Symbolizer->tryAddingPcLoadReferenceComment(cStream, Value, Address);
+}
+
+void MCDisassembler::setSymbolizer(OwningPtr<MCSymbolizer> &Symzer) {
+ Symbolizer.reset(Symzer.take());
+}
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
index 4766b37..a0066c8 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp
@@ -16,8 +16,11 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#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"
@@ -40,10 +43,15 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
// Get the target.
std::string Error;
const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
- assert(TheTarget && "Unable to create target!");
+ if (!TheTarget)
+ return 0;
+
+ const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple);
+ if (!MRI)
+ return 0;
// Get the assembler info needed to setup the MCContext.
- const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(Triple);
+ const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple);
if (!MAI)
return 0;
@@ -51,10 +59,6 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
if (!MII)
return 0;
- const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple);
- if (!MRI)
- return 0;
-
// Package up features to be passed to target/subtarget
std::string FeaturesStr;
@@ -64,7 +68,7 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
return 0;
// Set up the MCContext for creating symbols and MCExpr's.
- MCContext *Ctx = new MCContext(*MAI, *MRI, 0);
+ MCContext *Ctx = new MCContext(MAI, MRI, 0);
if (!Ctx)
return 0;
@@ -72,8 +76,18 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI);
if (!DisAsm)
return 0;
- DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, Ctx);
+ OwningPtr<MCRelocationInfo> RelInfo(
+ TheTarget->createMCRelocationInfo(Triple, *Ctx));
+ if (!RelInfo)
+ return 0;
+
+ OwningPtr<MCSymbolizer> Symbolizer(
+ TheTarget->createMCSymbolizer(Triple, GetOpInfo, SymbolLookUp, DisInfo,
+ Ctx, RelInfo.take()));
+ DisAsm->setSymbolizer(Symbolizer);
+ DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo,
+ Ctx, RelInfo);
// Set up the instruction printer.
int AsmPrinterVariant = MAI->getAssemblerDialect();
MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant,
@@ -88,6 +102,7 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
if (!DC)
return 0;
+ DC->setCPU(CPU);
return DC;
}
@@ -130,6 +145,112 @@ public:
};
} // 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,
+ formatted_raw_ostream &FormattedOS) {
+ // Flush the stream before taking its content.
+ DC->CommentStream.flush();
+ StringRef Comments = DC->CommentsToEmit.str();
+ // Get the default information for printing a comment.
+ const MCAsmInfo *MAI = DC->getAsmInfo();
+ const char *CommentBegin = MAI->getCommentString();
+ unsigned CommentColumn = MAI->getCommentColumn();
+ bool IsFirst = true;
+ while (!Comments.empty()) {
+ if (!IsFirst)
+ FormattedOS << '\n';
+ // Emit a line of comments.
+ FormattedOS.PadToColumn(CommentColumn);
+ size_t Position = Comments.find('\n');
+ FormattedOS << CommentBegin << ' ' << Comments.substr(0, Position);
+ // Move after the newline character.
+ Comments = Comments.substr(Position+1);
+ IsFirst = false;
+ }
+ FormattedOS.flush();
+
+ // Tell the comment stream that the vector changed underneath it.
+ DC->CommentsToEmit.clear();
+ DC->CommentStream.resync();
+}
+
+/// \brief Gets latency information for \p Inst form the itinerary
+/// scheduling model, based on \p DC information.
+/// \return The maximum expected latency over all the operands or -1
+/// if no information are available.
+static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
+ const int NoInformationAvailable = -1;
+
+ // Check if we have a CPU to get the itinerary information.
+ if (DC->getCPU().empty())
+ return NoInformationAvailable;
+
+ // Get itinerary information.
+ const MCSubtargetInfo *STI = DC->getSubtargetInfo();
+ InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU());
+ // Get the scheduling class of the requested instruction.
+ const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
+ unsigned SCClass = Desc.getSchedClass();
+
+ int Latency = 0;
+ for (unsigned OpIdx = 0, OpIdxEnd = Inst.getNumOperands(); OpIdx != OpIdxEnd;
+ ++OpIdx)
+ Latency = std::max(Latency, IID.getOperandCycle(SCClass, OpIdx));
+
+ return Latency;
+}
+
+/// \brief Gets latency information for \p Inst, based on \p DC information.
+/// \return The maximum expected latency over all the definitions or -1
+/// if no information are available.
+static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
+ // Try to compute scheduling information.
+ const MCSubtargetInfo *STI = DC->getSubtargetInfo();
+ 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.
+ 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);
+ // Resolving the variant SchedClass requires an MI to pass to
+ // SubTargetInfo::resolveSchedClass.
+ if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant())
+ return NoInformationAvailable;
+
+ // Compute output latency.
+ int Latency = 0;
+ for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
+ DefIdx != DefEnd; ++DefIdx) {
+ // Lookup the definition's write latency in SubtargetInfo.
+ const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc,
+ DefIdx);
+ Latency = std::max(Latency, WLEntry->Cycles);
+ }
+
+ return Latency;
+}
+
+
+/// \brief Emits latency information in DC->CommentStream for \p Inst, based
+/// on the information available in \p DC.
+static void emitLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
+ int Latency = getLatency(DC, Inst);
+
+ // Report only interesting latency.
+ if (Latency < 2)
+ return;
+
+ DC->CommentStream << "Latency: " << Latency << '\n';
+}
+
//
// LLVMDisasmInstruction() disassembles a single instruction using the
// disassembler context specified in the parameter DC. The bytes of the
@@ -154,8 +275,10 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
const MCDisassembler *DisAsm = DC->getDisAsm();
MCInstPrinter *IP = DC->getIP();
MCDisassembler::DecodeStatus S;
+ SmallVector<char, 64> InsnStr;
+ raw_svector_ostream Annotations(InsnStr);
S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC,
- /*REMOVE*/ nulls(), DC->CommentStream);
+ /*REMOVE*/ nulls(), Annotations);
switch (S) {
case MCDisassembler::Fail:
case MCDisassembler::SoftFail:
@@ -163,17 +286,18 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes,
return 0;
case MCDisassembler::Success: {
- DC->CommentStream.flush();
- StringRef Comments = DC->CommentsToEmit.str();
+ Annotations.flush();
+ StringRef AnnotationsStr = Annotations.str();
SmallVector<char, 64> InsnStr;
raw_svector_ostream OS(InsnStr);
- IP->printInst(&Inst, OS, Comments);
- OS.flush();
+ formatted_raw_ostream FormattedOS(OS);
+ IP->printInst(&Inst, FormattedOS, AnnotationsStr);
+
+ if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency)
+ emitLatency(DC, Inst);
- // Tell the comment stream that the vector changed underneath it.
- DC->CommentsToEmit.clear();
- DC->CommentStream.resync();
+ emitComments(DC, FormattedOS);
assert(OutStringSize != 0 && "Output buffer cannot be zero size");
size_t OutputSize = std::min(OutStringSize-1, InsnStr.size());
@@ -195,12 +319,14 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
MCInstPrinter *IP = DC->getIP();
IP->setUseMarkup(1);
+ DC->addOptions(LLVMDisassembler_Option_UseMarkup);
Options &= ~LLVMDisassembler_Option_UseMarkup;
}
if (Options & LLVMDisassembler_Option_PrintImmHex){
LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
MCInstPrinter *IP = DC->getIP();
IP->setPrintImmHex(1);
+ DC->addOptions(LLVMDisassembler_Option_PrintImmHex);
Options &= ~LLVMDisassembler_Option_PrintImmHex;
}
if (Options & LLVMDisassembler_Option_AsmPrinterVariant){
@@ -216,8 +342,21 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
if (IP) {
DC->setIP(IP);
+ DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant);
Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
}
}
+ if (Options & LLVMDisassembler_Option_SetInstrComments) {
+ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+ MCInstPrinter *IP = DC->getIP();
+ IP->setCommentStream(DC->CommentStream);
+ DC->addOptions(LLVMDisassembler_Option_SetInstrComments);
+ Options &= ~LLVMDisassembler_Option_SetInstrComments;
+ }
+ if (Options & LLVMDisassembler_Option_PrintLatency) {
+ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+ DC->addOptions(LLVMDisassembler_Option_PrintLatency);
+ Options &= ~LLVMDisassembler_Option_PrintLatency;
+ }
return (Options == 0);
}
diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
index 6eb59d0..4855af2 100644
--- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
+++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.h
@@ -73,6 +73,10 @@ private:
llvm::OwningPtr<const llvm::MCDisassembler> DisAsm;
// The instruction printer for the target architecture.
llvm::OwningPtr<llvm::MCInstPrinter> IP;
+ // The options used to set up the disassembler.
+ uint64_t Options;
+ // The CPU string.
+ std::string CPU;
public:
// Comment stream and backing vector.
@@ -90,6 +94,7 @@ public:
MCInstPrinter *iP) : TripleName(tripleName),
DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
SymbolLookUp(symbolLookUp), TheTarget(theTarget),
+ Options(0),
CommentStream(CommentsToEmit) {
MAI.reset(mAI);
MRI.reset(mRI);
@@ -114,6 +119,10 @@ public:
const MCSubtargetInfo *getSubtargetInfo() const { return MSI.get(); }
MCInstPrinter *getIP() { return IP.get(); }
void setIP(MCInstPrinter *NewIP) { IP.reset(NewIP); }
+ uint64_t getOptions() const { return Options; }
+ void addOptions(uint64_t Options) { this->Options |= Options; }
+ StringRef getCPU() const { return CPU; }
+ void setCPU(const char *CPU) { this->CPU = CPU; }
};
} // namespace llvm
diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp
index 18982e9..479f445 100644
--- a/contrib/llvm/lib/MC/MCDwarf.cpp
+++ b/contrib/llvm/lib/MC/MCDwarf.cpp
@@ -16,7 +16,6 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -47,20 +46,15 @@ using namespace llvm;
// Range of line offsets in a special line info. opcode.
#define DWARF2_LINE_RANGE 14
-// Define the architecture-dependent minimum instruction length (in bytes).
-// This value should be rather too small than too big.
-#define DWARF2_LINE_MIN_INSN_LENGTH 1
-
-// Note: when DWARF2_LINE_MIN_INSN_LENGTH == 1 which is the current setting,
-// this routine is a nop and will be optimized away.
-static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta) {
- if (DWARF2_LINE_MIN_INSN_LENGTH == 1)
+static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
+ unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
+ if (MinInsnLength == 1)
return AddrDelta;
- if (AddrDelta % DWARF2_LINE_MIN_INSN_LENGTH != 0) {
+ if (AddrDelta % MinInsnLength != 0) {
// TODO: report this error, but really only once.
;
}
- return AddrDelta / DWARF2_LINE_MIN_INSN_LENGTH;
+ return AddrDelta / MinInsnLength;
}
//
@@ -182,9 +176,9 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
// At this point we want to emit/create the sequence to encode the delta in
// line numbers and the increment of the address from the previous Label
// and the current Label.
- const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
+ const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
- asmInfo.getPointerSize());
+ asmInfo->getPointerSize());
LastLine = it->getLine();
LastLabel = Label;
@@ -210,9 +204,9 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
// Switch back the dwarf line section.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
- const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
+ const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
- asmInfo.getPointerSize());
+ asmInfo->getPointerSize());
}
//
@@ -274,10 +268,10 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
// 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, 0);
+ (4 + 2 + 4)), 4);
// Parameters of the state machine, are next.
- MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);
+ MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1);
MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
MCOS->EmitIntValue(DWARF2_LINE_BASE, 1);
MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1);
@@ -338,7 +332,7 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
EmitDwarfLineTable(MCOS, Sec, Line, CUID);
}
- if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
+ if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines()
&& MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
// The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
// it requires:
@@ -357,32 +351,24 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
return LineStartSym;
}
-/// Utility function to write the encoding to an object writer.
-void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta,
- uint64_t AddrDelta) {
- SmallString<256> Tmp;
- raw_svector_ostream OS(Tmp);
- MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
- OW->WriteBytes(OS.str());
-}
-
/// Utility function to emit the encoding to a streamer.
void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta,
uint64_t AddrDelta) {
+ MCContext &Context = MCOS->getContext();
SmallString<256> Tmp;
raw_svector_ostream OS(Tmp);
- MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
+ MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OS);
MCOS->EmitBytes(OS.str());
}
/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
-void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
- raw_ostream &OS) {
+void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta,
+ uint64_t AddrDelta, raw_ostream &OS) {
uint64_t Temp, Opcode;
bool NeedCopy = false;
// Scale the address delta by the minimum instruction length.
- AddrDelta = ScaleAddrDelta(AddrDelta);
+ AddrDelta = ScaleAddrDelta(Context, AddrDelta);
// A LineDelta of INT64_MAX is a signal that this is actually a
// DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
@@ -481,7 +467,8 @@ static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
- EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
+ if (!context.getCompilationDir().empty())
+ EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
if (!DwarfDebugFlags.empty())
EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
@@ -534,8 +521,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
// Figure the padding after the header before the table of address and size
// pairs who's values are PointerSize'ed.
- const MCAsmInfo &asmInfo = context.getAsmInfo();
- int AddrSize = asmInfo.getPointerSize();
+ const MCAsmInfo *asmInfo = context.getAsmInfo();
+ int AddrSize = asmInfo->getPointerSize();
int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
if (Pad == 2 * AddrSize)
Pad = 0;
@@ -615,8 +602,8 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
MCOS->EmitIntValue(0, 4);
}
- const MCAsmInfo &asmInfo = context.getAsmInfo();
- int AddrSize = asmInfo.getPointerSize();
+ const MCAsmInfo *asmInfo = context.getAsmInfo();
+ int AddrSize = asmInfo->getPointerSize();
// The 1 byte size of an address.
MCOS->EmitIntValue(AddrSize, 1);
@@ -657,8 +644,10 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_comp_dir, the working directory the assembly was done in.
- MCOS->EmitBytes(context.getCompilationDir());
- MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
+ if (!context.getCompilationDir().empty()) {
+ MCOS->EmitBytes(context.getCompilationDir());
+ MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
+ }
// AT_APPLE_flags, the command line arguments of the assembler tool.
StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
@@ -743,9 +732,9 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
// Create the dwarf sections in this order (.debug_line already created).
MCContext &context = MCOS->getContext();
- const MCAsmInfo &AsmInfo = context.getAsmInfo();
+ const MCAsmInfo *AsmInfo = context.getAsmInfo();
bool CreateDwarfSectionSymbols =
- AsmInfo.doesDwarfUseRelocationsAcrossSections();
+ AsmInfo->doesDwarfUseRelocationsAcrossSections();
if (!CreateDwarfSectionSymbols)
LineSectionSymbol = NULL;
MCSymbol *AbbrevSectionSymbol = NULL;
@@ -821,9 +810,9 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
static int getDataAlignmentFactor(MCStreamer &streamer) {
MCContext &context = streamer.getContext();
- const MCAsmInfo &asmInfo = context.getAsmInfo();
- int size = asmInfo.getCalleeSaveStackSlotSize();
- if (asmInfo.isStackGrowthDirectionUp())
+ const MCAsmInfo *asmInfo = context.getAsmInfo();
+ int size = asmInfo->getCalleeSaveStackSlotSize();
+ if (asmInfo->isStackGrowthDirectionUp())
return size;
else
return -size;
@@ -837,7 +826,7 @@ static unsigned getSizeForEncoding(MCStreamer &streamer,
default: llvm_unreachable("Unknown Encoding");
case dwarf::DW_EH_PE_absptr:
case dwarf::DW_EH_PE_signed:
- return context.getAsmInfo().getPointerSize();
+ return context.getAsmInfo()->getPointerSize();
case dwarf::DW_EH_PE_udata2:
case dwarf::DW_EH_PE_sdata2:
return 2;
@@ -853,10 +842,10 @@ static unsigned getSizeForEncoding(MCStreamer &streamer,
static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
unsigned symbolEncoding, const char *comment = 0) {
MCContext &context = streamer.getContext();
- const MCAsmInfo &asmInfo = context.getAsmInfo();
- const MCExpr *v = asmInfo.getExprForFDESymbol(&symbol,
- symbolEncoding,
- streamer);
+ 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);
streamer.EmitAbsValue(v, size);
@@ -865,25 +854,14 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
unsigned symbolEncoding) {
MCContext &context = streamer.getContext();
- const MCAsmInfo &asmInfo = context.getAsmInfo();
- const MCExpr *v = asmInfo.getExprForPersonalitySymbol(&symbol,
- symbolEncoding,
- streamer);
+ const MCAsmInfo *asmInfo = context.getAsmInfo();
+ const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
+ symbolEncoding,
+ streamer);
unsigned size = getSizeForEncoding(streamer, symbolEncoding);
streamer.EmitValue(v, size);
}
-static const MachineLocation TranslateMachineLocation(
- const MCRegisterInfo &MRI,
- const MachineLocation &Loc) {
- unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ?
- MachineLocation::VirtualFP :
- unsigned(MRI.getDwarfRegNum(Loc.getReg(), true));
- const MachineLocation &NewLoc = Loc.isReg() ?
- MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset());
- return NewLoc;
-}
-
namespace {
class FrameEmitterImpl {
int CFAOffset;
@@ -898,9 +876,7 @@ namespace {
void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
- /// EmitCompactUnwind - Emit the unwind information in a compact way. If
- /// we're successful, return 'true'. Otherwise, return 'false' and it will
- /// emit the normal CIE and FDE.
+ /// EmitCompactUnwind - Emit the unwind information in a compact way.
void EmitCompactUnwind(MCStreamer &streamer,
const MCDwarfFrameInfo &frame);
@@ -914,7 +890,7 @@ namespace {
const MCSymbol &cieStart,
const MCDwarfFrameInfo &frame);
void EmitCFIInstructions(MCStreamer &streamer,
- const std::vector<MCCFIInstruction> &Instrs,
+ ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel);
void EmitCFIInstruction(MCStreamer &Streamer,
const MCCFIInstruction &Instr);
@@ -986,6 +962,10 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
Streamer.EmitULEB128IntValue(Reg2);
return;
}
+ case MCCFIInstruction::OpWindowSave: {
+ Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
+ return;
+ }
case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
if (VerboseAsm) {
@@ -1116,7 +1096,7 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer,
- const std::vector<MCCFIInstruction> &Instrs,
+ ArrayRef<MCCFIInstruction> Instrs,
MCSymbol *BaseLabel) {
for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
const MCCFIInstruction &Instr = Instrs[i];
@@ -1138,9 +1118,7 @@ void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer,
}
}
-/// EmitCompactUnwind - Emit the unwind information in a compact way. If we're
-/// successful, return 'true'. Otherwise, return 'false' and it will emit the
-/// normal CIE and FDE.
+/// EmitCompactUnwind - Emit the unwind information in a compact way.
void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
const MCDwarfFrameInfo &Frame) {
MCContext &Context = Streamer.getContext();
@@ -1219,7 +1197,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
bool IsSignalFrame,
unsigned lsdaEncoding) {
MCContext &context = streamer.getContext();
- const MCRegisterInfo &MRI = context.getRegisterInfo();
+ const MCRegisterInfo *MRI = context.getRegisterInfo();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
bool verboseAsm = streamer.isVerboseAsm();
@@ -1267,7 +1245,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
// Code Alignment Factor
if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor");
- streamer.EmitULEB128IntValue(1);
+ streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
// Data Alignment Factor
if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor");
@@ -1275,7 +1253,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
// Return Address Register
if (verboseAsm) streamer.AddComment("CIE Return Address Column");
- streamer.EmitULEB128IntValue(MRI.getDwarfRegNum(MRI.getRARegister(), true));
+ streamer.EmitULEB128IntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true));
// Augmentation Data Length (optional)
@@ -1315,38 +1293,13 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
// Initial Instructions
- const MCAsmInfo &MAI = context.getAsmInfo();
- const std::vector<MachineMove> &Moves = MAI.getInitialFrameState();
- std::vector<MCCFIInstruction> Instructions;
-
- for (int i = 0, n = Moves.size(); i != n; ++i) {
- MCSymbol *Label = Moves[i].getLabel();
- const MachineLocation &Dst =
- TranslateMachineLocation(MRI, Moves[i].getDestination());
- const MachineLocation &Src =
- TranslateMachineLocation(MRI, Moves[i].getSource());
-
- if (Dst.isReg()) {
- assert(Dst.getReg() == MachineLocation::VirtualFP);
- assert(!Src.isReg());
- MCCFIInstruction Inst =
- MCCFIInstruction::createDefCfa(Label, Src.getReg(), -Src.getOffset());
- Instructions.push_back(Inst);
- } else {
- assert(Src.isReg());
- unsigned Reg = Src.getReg();
- int Offset = Dst.getOffset();
- MCCFIInstruction Inst =
- MCCFIInstruction::createOffset(Label, Reg, Offset);
- Instructions.push_back(Inst);
- }
- }
-
+ const MCAsmInfo *MAI = context.getAsmInfo();
+ const std::vector<MCCFIInstruction> &Instructions =
+ MAI->getInitialFrameState();
EmitCFIInstructions(streamer, Instructions, NULL);
// Padding
- streamer.EmitValueToAlignment(IsEH
- ? 4 : context.getAsmInfo().getPointerSize());
+ streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());
streamer.EmitLabel(sectionEnd);
return *sectionStart;
@@ -1376,13 +1329,13 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
streamer.EmitLabel(fdeStart);
// CIE Pointer
- const MCAsmInfo &asmInfo = context.getAsmInfo();
+ const MCAsmInfo *asmInfo = context.getAsmInfo();
if (IsEH) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
0);
if (verboseAsm) streamer.AddComment("FDE CIE Offset");
streamer.EmitAbsValue(offset, 4);
- } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) {
+ } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
cieStart, 0);
streamer.EmitAbsValue(offset, 4);
@@ -1469,36 +1422,33 @@ namespace llvm {
};
}
-void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
- bool UsingCFI,
- bool IsEH) {
+void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB,
+ bool UsingCFI, bool IsEH) {
+ Streamer.generateCompactUnwindEncodings(MAB);
+
MCContext &Context = Streamer.getContext();
- MCObjectFileInfo *MOFI =
- const_cast<MCObjectFileInfo*>(Context.getObjectFileInfo());
+ const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
FrameEmitterImpl Emitter(UsingCFI, IsEH);
ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
// Emit the compact unwind info if available.
if (IsEH && MOFI->getCompactUnwindSection()) {
- unsigned NumFrameInfos = Streamer.getNumFrameInfos();
bool SectionEmitted = false;
-
- if (NumFrameInfos) {
- for (unsigned i = 0; i < NumFrameInfos; ++i) {
- const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i);
- if (Frame.CompactUnwindEncoding == 0) continue;
- if (!SectionEmitted) {
- Streamer.SwitchSection(MOFI->getCompactUnwindSection());
- Streamer.EmitValueToAlignment(Context.getAsmInfo().getPointerSize());
- SectionEmitted = true;
- }
- Emitter.EmitCompactUnwind(Streamer, Frame);
+ for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
+ const MCDwarfFrameInfo &Frame = FrameArray[i];
+ if (Frame.CompactUnwindEncoding == 0) continue;
+ if (!SectionEmitted) {
+ Streamer.SwitchSection(MOFI->getCompactUnwindSection());
+ Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
+ SectionEmitted = true;
}
+ Emitter.EmitCompactUnwind(Streamer, Frame);
}
}
- const MCSection &Section = IsEH ? *MOFI->getEHFrameSection() :
- *MOFI->getDwarfFrameSection();
+ const MCSection &Section =
+ IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() :
+ *MOFI->getDwarfFrameSection();
Streamer.SwitchSection(&Section);
MCSymbol *SectionStart = Context.CreateTempSymbol();
Streamer.EmitLabel(SectionStart);
@@ -1525,22 +1475,26 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
Streamer.EmitLabel(FDEEnd);
}
- Streamer.EmitValueToAlignment(Context.getAsmInfo().getPointerSize());
+ Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize());
if (FDEEnd)
Streamer.EmitLabel(FDEEnd);
}
void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
uint64_t AddrDelta) {
+ MCContext &Context = Streamer.getContext();
SmallString<256> Tmp;
raw_svector_ostream OS(Tmp);
- MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS);
+ MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS);
Streamer.EmitBytes(OS.str());
}
-void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta,
+void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context,
+ uint64_t AddrDelta,
raw_ostream &OS) {
- // FIXME: Assumes the code alignment factor is 1.
+ // Scale the address delta by the minimum instruction length.
+ AddrDelta = ScaleAddrDelta(Context, AddrDelta);
+
if (AddrDelta == 0) {
} else if (isUIntN(6, AddrDelta)) {
uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
diff --git a/contrib/llvm/lib/MC/MCELF.cpp b/contrib/llvm/lib/MC/MCELF.cpp
index 560cdbc..ebb189e 100644
--- a/contrib/llvm/lib/MC/MCELF.cpp
+++ b/contrib/llvm/lib/MC/MCELF.cpp
@@ -36,8 +36,8 @@ unsigned MCELF::GetBinding(const MCSymbolData &SD) {
void MCELF::SetType(MCSymbolData &SD, unsigned Type) {
assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
- Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
- Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC);
+ Type == ELF::STT_COMMON || Type == ELF::STT_TLS ||
+ Type == ELF::STT_GNU_IFUNC);
uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
@@ -47,8 +47,7 @@ unsigned MCELF::GetType(const MCSymbolData &SD) {
uint32_t Type = (SD.getFlags() & (0xf << ELF_STT_Shift)) >> ELF_STT_Shift;
assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT ||
Type == ELF::STT_FUNC || Type == ELF::STT_SECTION ||
- Type == ELF::STT_FILE || Type == ELF::STT_COMMON ||
- Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC);
+ Type == ELF::STT_COMMON || Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC);
return Type;
}
diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
index 4cac84d..0c39e4a 100644
--- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp
@@ -39,13 +39,23 @@ const MCSymbol *MCELFObjectTargetWriter::undefinedExplicitRelSym(const MCValue &
return &Symbol.AliasedSymbol();
}
-void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup,
- uint64_t &RelocOffset) {
+// ELF doesn't require relocations to be in any order. We sort by the r_offset,
+// just to match gnu as for easier comparison. The use type and index is an
+// arbitrary way of making the sort deterministic.
+static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
+ const ELFRelocationEntry &A = *AP;
+ const ELFRelocationEntry &B = *BP;
+ if (A.r_offset != B.r_offset)
+ return B.r_offset - A.r_offset;
+ if (B.Type != A.Type)
+ return A.Type - B.Type;
+ if (B.Index != A.Index)
+ return B.Index - A.Index;
+ llvm_unreachable("ELFRelocs might be unstable!");
}
void
MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) {
- // Sort by the r_offset, just like gnu as does.
- array_pod_sort(Relocs.begin(), Relocs.end());
+ array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
}
diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp
index 116f86f..e806cb9 100644
--- a/contrib/llvm/lib/MC/MCELFStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELF.h"
@@ -96,6 +97,9 @@ void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
}
void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
+ // Let the target do whatever target specific stuff it needs to do.
+ getAssembler().getBackend().handleAssemblerFlag(Flag);
+ // Do any generic stuff we need to do.
switch (Flag) {
case MCAF_SyntaxUnified: return; // no-op here.
case MCAF_Code16: return; // Change parsing mode; no-op here.
@@ -148,8 +152,8 @@ static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) {
return T2;
}
-void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
- MCSymbolAttr Attribute) {
+bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) {
// Indirect symbols are handled differently, to match how 'as' handles
// them. This makes writing matching .o files easier.
if (Attribute == MCSA_IndirectSymbol) {
@@ -159,7 +163,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
ISD.Symbol = Symbol;
ISD.SectionData = getCurrentSectionData();
getAssembler().getIndirectSymbols().push_back(ISD);
- return;
+ return true;
}
// Adding a symbol attribute always introduces the symbol, note that an
@@ -182,7 +186,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_WeakDefAutoPrivate:
case MCSA_Invalid:
case MCSA_IndirectSymbol:
- llvm_unreachable("Invalid symbol attribute for ELF!");
+ return false;
case MCSA_NoDeadStrip:
case MCSA_ELF_TypeGnuUniqueObject:
@@ -251,6 +255,8 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCELF::SetVisibility(SD, ELF::STV_INTERNAL);
break;
}
+
+ return true;
}
void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -270,7 +276,8 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
ELF::SHF_WRITE |
ELF::SHF_ALLOC,
SectionKind::getBSS());
- Symbol->setSection(*Section);
+
+ AssignSection(Symbol, Section);
struct LocalCommon L = {&SD, Size, ByteAlignment};
LocalCommons.push_back(L);
@@ -296,12 +303,11 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
EmitCommonSymbol(Symbol, Size, ByteAlignment);
}
-void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {
+void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
if (getCurrentSectionData()->isBundleLocked())
report_fatal_error("Emitting values inside a locked bundle is forbidden");
fixSymbolsInTLSFixups(Value);
- MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace);
+ MCObjectStreamer::EmitValueImpl(Value, Size);
}
void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
@@ -314,20 +320,29 @@ void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
ValueSize, MaxBytesToEmit);
}
-
-// Add a symbol for the file name of this module. This is the second
-// entry in the module's symbol table (the first being the null symbol).
+// Add a symbol for the file name of this module. They start after the
+// null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol
+// with the same name may appear.
void MCELFStreamer::EmitFileDirective(StringRef Filename) {
- MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename);
- Symbol->setSection(*getCurrentSection().first);
- Symbol->setAbsolute();
-
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
-
- SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
+ getAssembler().addFileName(Filename);
+}
+
+void MCELFStreamer::EmitIdent(StringRef IdentString) {
+ const MCSection *Comment = getAssembler().getContext().getELFSection(
+ ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS,
+ SectionKind::getReadOnly(), 1, "");
+ PushSection();
+ SwitchSection(Comment);
+ if (!SeenIdent) {
+ EmitIntValue(0, 1);
+ SeenIdent = true;
+ }
+ EmitBytes(IdentString);
+ EmitIntValue(0, 1);
+ PopSection();
}
-void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
+void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
switch (expr->getKind()) {
case MCExpr::Target:
cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
@@ -363,18 +378,41 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_Mips_GOTTPREL:
case MCSymbolRefExpr::VK_Mips_TPREL_HI:
case MCSymbolRefExpr::VK_Mips_TPREL_LO:
- case MCSymbolRefExpr::VK_PPC_TPREL16_HA:
- case MCSymbolRefExpr::VK_PPC_TPREL16_LO:
- case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
- case MCSymbolRefExpr::VK_PPC_DTPREL16_LO:
- case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA:
- case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_DTPMOD:
+ case MCSymbolRefExpr::VK_PPC_TPREL:
+ case MCSymbolRefExpr::VK_PPC_TPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HI:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HA:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
+ case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
+ case MCSymbolRefExpr::VK_PPC_DTPREL:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
+ case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
+ case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
+ case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
case MCSymbolRefExpr::VK_PPC_TLS:
- case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
- case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
case MCSymbolRefExpr::VK_PPC_TLSGD:
- case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA:
- case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
case MCSymbolRefExpr::VK_PPC_TLSLD:
break;
}
@@ -503,9 +541,7 @@ void MCELFStreamer::EmitBundleUnlock() {
SD->setBundleLockState(MCSectionData::NotBundleLocked);
}
-void MCELFStreamer::FinishImpl() {
- EmitFrames(true);
-
+void MCELFStreamer::Flush() {
for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
e = LocalCommons.end();
i != e; ++i) {
@@ -526,17 +562,23 @@ void MCELFStreamer::FinishImpl() {
SectData.setAlignment(ByteAlignment);
}
- this->MCObjectStreamer::FinishImpl();
+ LocalCommons.clear();
}
-void MCELFStreamer::EmitTCEntry(const MCSymbol &S) {
- // Creates a R_PPC64_TOC relocation
- MCObjectStreamer::EmitSymbolValue(&S, 8);
+
+void MCELFStreamer::FinishImpl() {
+ EmitFrames(NULL, true);
+
+ Flush();
+
+ this->MCObjectStreamer::FinishImpl();
}
-MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll, bool NoExecStack) {
- MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
+MCStreamer *llvm::createELFStreamer(MCContext &Context,
+ MCTargetStreamer *Streamer,
+ MCAsmBackend &MAB, raw_ostream &OS,
+ MCCodeEmitter *CE, bool RelaxAll,
+ bool NoExecStack) {
+ MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
if (NoExecStack)
diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp
index 06bc72f..c777e64 100644
--- a/contrib/llvm/lib/MC/MCExpr.cpp
+++ b/contrib/llvm/lib/MC/MCExpr.cpp
@@ -42,13 +42,6 @@ void MCExpr::print(raw_ostream &OS) const {
// Parenthesize names that start with $ so that they don't look like
// absolute names.
bool UseParens = Sym.getName()[0] == '$';
-
- if (SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_HA16 ||
- SRE.getKind() == MCSymbolRefExpr::VK_PPC_DARWIN_LO16) {
- OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
- UseParens = true;
- }
-
if (UseParens)
OS << '(' << Sym << ')';
else
@@ -65,9 +58,7 @@ void MCExpr::print(raw_ostream &OS) const {
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
- else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
- SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 &&
- SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_LO16)
+ else if (SRE.getKind() != MCSymbolRefExpr::VK_None)
OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
return;
@@ -205,26 +196,56 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_ARM_TARGET1: return "(target1)";
case VK_ARM_TARGET2: return "(target2)";
case VK_ARM_PREL31: return "(prel31)";
- case VK_PPC_TOC: return "tocbase";
- case VK_PPC_TOC_ENTRY: return "toc";
- case VK_PPC_DARWIN_HA16: return "ha16";
- case VK_PPC_DARWIN_LO16: return "lo16";
- case VK_PPC_GAS_HA16: return "ha";
- case VK_PPC_GAS_LO16: return "l";
- case VK_PPC_TPREL16_HA: return "tprel@ha";
- case VK_PPC_TPREL16_LO: return "tprel@l";
- case VK_PPC_DTPREL16_HA: return "dtprel@ha";
- case VK_PPC_DTPREL16_LO: return "dtprel@l";
- case VK_PPC_TOC16_HA: return "toc@ha";
- case VK_PPC_TOC16_LO: return "toc@l";
- case VK_PPC_GOT_TPREL16_HA: return "got@tprel@ha";
- case VK_PPC_GOT_TPREL16_LO: return "got@tprel@l";
+ case VK_PPC_LO: return "l";
+ case VK_PPC_HI: return "h";
+ case VK_PPC_HA: return "ha";
+ case VK_PPC_HIGHER: return "higher";
+ case VK_PPC_HIGHERA: return "highera";
+ case VK_PPC_HIGHEST: return "highest";
+ case VK_PPC_HIGHESTA: return "highesta";
+ case VK_PPC_GOT_LO: return "got@l";
+ case VK_PPC_GOT_HI: return "got@h";
+ case VK_PPC_GOT_HA: return "got@ha";
+ case VK_PPC_TOCBASE: return "tocbase";
+ case VK_PPC_TOC: return "toc";
+ case VK_PPC_TOC_LO: return "toc@l";
+ case VK_PPC_TOC_HI: return "toc@h";
+ case VK_PPC_TOC_HA: return "toc@ha";
+ case VK_PPC_DTPMOD: return "dtpmod";
+ case VK_PPC_TPREL: return "tprel";
+ case VK_PPC_TPREL_LO: return "tprel@l";
+ case VK_PPC_TPREL_HI: return "tprel@h";
+ case VK_PPC_TPREL_HA: return "tprel@ha";
+ case VK_PPC_TPREL_HIGHER: return "tprel@higher";
+ case VK_PPC_TPREL_HIGHERA: return "tprel@highera";
+ case VK_PPC_TPREL_HIGHEST: return "tprel@highest";
+ case VK_PPC_TPREL_HIGHESTA: return "tprel@highesta";
+ case VK_PPC_DTPREL: return "dtprel";
+ case VK_PPC_DTPREL_LO: return "dtprel@l";
+ case VK_PPC_DTPREL_HI: return "dtprel@h";
+ case VK_PPC_DTPREL_HA: return "dtprel@ha";
+ case VK_PPC_DTPREL_HIGHER: return "dtprel@higher";
+ case VK_PPC_DTPREL_HIGHERA: return "dtprel@highera";
+ case VK_PPC_DTPREL_HIGHEST: return "dtprel@highest";
+ case VK_PPC_DTPREL_HIGHESTA: return "dtprel@highesta";
+ case VK_PPC_GOT_TPREL: return "got@tprel";
+ case VK_PPC_GOT_TPREL_LO: return "got@tprel@l";
+ case VK_PPC_GOT_TPREL_HI: return "got@tprel@h";
+ case VK_PPC_GOT_TPREL_HA: return "got@tprel@ha";
+ case VK_PPC_GOT_DTPREL: return "got@dtprel";
+ case VK_PPC_GOT_DTPREL_LO: return "got@dtprel@l";
+ case VK_PPC_GOT_DTPREL_HI: return "got@dtprel@h";
+ case VK_PPC_GOT_DTPREL_HA: return "got@dtprel@ha";
case VK_PPC_TLS: return "tls";
- case VK_PPC_GOT_TLSGD16_HA: return "got@tlsgd@ha";
- case VK_PPC_GOT_TLSGD16_LO: return "got@tlsgd@l";
- case VK_PPC_GOT_TLSLD16_HA: return "got@tlsld@ha";
- case VK_PPC_GOT_TLSLD16_LO: return "got@tlsld@l";
+ case VK_PPC_GOT_TLSGD: return "got@tlsgd";
+ case VK_PPC_GOT_TLSGD_LO: return "got@tlsgd@l";
+ case VK_PPC_GOT_TLSGD_HI: return "got@tlsgd@h";
+ case VK_PPC_GOT_TLSGD_HA: return "got@tlsgd@ha";
case VK_PPC_TLSGD: return "tlsgd";
+ case VK_PPC_GOT_TLSLD: return "got@tlsld";
+ case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l";
+ 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_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
@@ -290,40 +311,104 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("imgrel", VK_COFF_IMGREL32)
.Case("SECREL32", VK_SECREL)
.Case("secrel32", VK_SECREL)
- .Case("HA", VK_PPC_GAS_HA16)
- .Case("ha", VK_PPC_GAS_HA16)
- .Case("L", VK_PPC_GAS_LO16)
- .Case("l", VK_PPC_GAS_LO16)
- .Case("TOCBASE", VK_PPC_TOC)
- .Case("tocbase", VK_PPC_TOC)
- .Case("TOC", VK_PPC_TOC_ENTRY)
- .Case("toc", VK_PPC_TOC_ENTRY)
- .Case("TOC@HA", VK_PPC_TOC16_HA)
- .Case("toc@ha", VK_PPC_TOC16_HA)
- .Case("TOC@L", VK_PPC_TOC16_LO)
- .Case("toc@l", VK_PPC_TOC16_LO)
+ .Case("L", VK_PPC_LO)
+ .Case("l", VK_PPC_LO)
+ .Case("H", VK_PPC_HI)
+ .Case("h", VK_PPC_HI)
+ .Case("HA", VK_PPC_HA)
+ .Case("ha", VK_PPC_HA)
+ .Case("HIGHER", VK_PPC_HIGHER)
+ .Case("higher", VK_PPC_HIGHER)
+ .Case("HIGHERA", VK_PPC_HIGHERA)
+ .Case("highera", VK_PPC_HIGHERA)
+ .Case("HIGHEST", VK_PPC_HIGHEST)
+ .Case("highest", VK_PPC_HIGHEST)
+ .Case("HIGHESTA", VK_PPC_HIGHESTA)
+ .Case("highesta", VK_PPC_HIGHESTA)
+ .Case("GOT@L", VK_PPC_GOT_LO)
+ .Case("got@l", VK_PPC_GOT_LO)
+ .Case("GOT@H", VK_PPC_GOT_HI)
+ .Case("got@h", VK_PPC_GOT_HI)
+ .Case("GOT@HA", VK_PPC_GOT_HA)
+ .Case("got@ha", VK_PPC_GOT_HA)
+ .Case("TOCBASE", VK_PPC_TOCBASE)
+ .Case("tocbase", VK_PPC_TOCBASE)
+ .Case("TOC", VK_PPC_TOC)
+ .Case("toc", VK_PPC_TOC)
+ .Case("TOC@L", VK_PPC_TOC_LO)
+ .Case("toc@l", VK_PPC_TOC_LO)
+ .Case("TOC@H", VK_PPC_TOC_HI)
+ .Case("toc@h", VK_PPC_TOC_HI)
+ .Case("TOC@HA", VK_PPC_TOC_HA)
+ .Case("toc@ha", VK_PPC_TOC_HA)
.Case("TLS", VK_PPC_TLS)
.Case("tls", VK_PPC_TLS)
- .Case("TPREL@HA", VK_PPC_TPREL16_HA)
- .Case("tprel@ha", VK_PPC_TPREL16_HA)
- .Case("TPREL@L", VK_PPC_TPREL16_LO)
- .Case("tprel@l", VK_PPC_TPREL16_LO)
- .Case("DTPREL@HA", VK_PPC_DTPREL16_HA)
- .Case("dtprel@ha", VK_PPC_DTPREL16_HA)
- .Case("DTPREL@L", VK_PPC_DTPREL16_LO)
- .Case("dtprel@l", VK_PPC_DTPREL16_LO)
- .Case("GOT@TPREL@HA", VK_PPC_GOT_TPREL16_HA)
- .Case("got@tprel@ha", VK_PPC_GOT_TPREL16_HA)
- .Case("GOT@TPREL@L", VK_PPC_GOT_TPREL16_LO)
- .Case("got@tprel@l", VK_PPC_GOT_TPREL16_LO)
- .Case("GOT@TLSGD@HA", VK_PPC_GOT_TLSGD16_HA)
- .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD16_HA)
- .Case("GOT@TLSGD@L", VK_PPC_GOT_TLSGD16_LO)
- .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD16_LO)
- .Case("GOT@TLSLD@HA", VK_PPC_GOT_TLSLD16_HA)
- .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD16_HA)
- .Case("GOT@TLSLD@L", VK_PPC_GOT_TLSLD16_LO)
- .Case("got@tlsld@l", VK_PPC_GOT_TLSLD16_LO)
+ .Case("DTPMOD", VK_PPC_DTPMOD)
+ .Case("dtpmod", VK_PPC_DTPMOD)
+ .Case("TPREL", VK_PPC_TPREL)
+ .Case("tprel", VK_PPC_TPREL)
+ .Case("TPREL@L", VK_PPC_TPREL_LO)
+ .Case("tprel@l", VK_PPC_TPREL_LO)
+ .Case("TPREL@H", VK_PPC_TPREL_HI)
+ .Case("tprel@h", VK_PPC_TPREL_HI)
+ .Case("TPREL@HA", VK_PPC_TPREL_HA)
+ .Case("tprel@ha", VK_PPC_TPREL_HA)
+ .Case("TPREL@HIGHER", VK_PPC_TPREL_HIGHER)
+ .Case("tprel@higher", VK_PPC_TPREL_HIGHER)
+ .Case("TPREL@HIGHERA", VK_PPC_TPREL_HIGHERA)
+ .Case("tprel@highera", VK_PPC_TPREL_HIGHERA)
+ .Case("TPREL@HIGHEST", VK_PPC_TPREL_HIGHEST)
+ .Case("tprel@highest", VK_PPC_TPREL_HIGHEST)
+ .Case("TPREL@HIGHESTA", VK_PPC_TPREL_HIGHESTA)
+ .Case("tprel@highesta", VK_PPC_TPREL_HIGHESTA)
+ .Case("DTPREL", VK_PPC_DTPREL)
+ .Case("dtprel", VK_PPC_DTPREL)
+ .Case("DTPREL@L", VK_PPC_DTPREL_LO)
+ .Case("dtprel@l", VK_PPC_DTPREL_LO)
+ .Case("DTPREL@H", VK_PPC_DTPREL_HI)
+ .Case("dtprel@h", VK_PPC_DTPREL_HI)
+ .Case("DTPREL@HA", VK_PPC_DTPREL_HA)
+ .Case("dtprel@ha", VK_PPC_DTPREL_HA)
+ .Case("DTPREL@HIGHER", VK_PPC_DTPREL_HIGHER)
+ .Case("dtprel@higher", VK_PPC_DTPREL_HIGHER)
+ .Case("DTPREL@HIGHERA", VK_PPC_DTPREL_HIGHERA)
+ .Case("dtprel@highera", VK_PPC_DTPREL_HIGHERA)
+ .Case("DTPREL@HIGHEST", VK_PPC_DTPREL_HIGHEST)
+ .Case("dtprel@highest", VK_PPC_DTPREL_HIGHEST)
+ .Case("DTPREL@HIGHESTA", VK_PPC_DTPREL_HIGHESTA)
+ .Case("dtprel@highesta", VK_PPC_DTPREL_HIGHESTA)
+ .Case("GOT@TPREL", VK_PPC_GOT_TPREL)
+ .Case("got@tprel", VK_PPC_GOT_TPREL)
+ .Case("GOT@TPREL@L", VK_PPC_GOT_TPREL_LO)
+ .Case("got@tprel@l", VK_PPC_GOT_TPREL_LO)
+ .Case("GOT@TPREL@H", VK_PPC_GOT_TPREL_HI)
+ .Case("got@tprel@h", VK_PPC_GOT_TPREL_HI)
+ .Case("GOT@TPREL@HA", VK_PPC_GOT_TPREL_HA)
+ .Case("got@tprel@ha", VK_PPC_GOT_TPREL_HA)
+ .Case("GOT@DTPREL", VK_PPC_GOT_DTPREL)
+ .Case("got@dtprel", VK_PPC_GOT_DTPREL)
+ .Case("GOT@DTPREL@L", VK_PPC_GOT_DTPREL_LO)
+ .Case("got@dtprel@l", VK_PPC_GOT_DTPREL_LO)
+ .Case("GOT@DTPREL@H", VK_PPC_GOT_DTPREL_HI)
+ .Case("got@dtprel@h", VK_PPC_GOT_DTPREL_HI)
+ .Case("GOT@DTPREL@HA", VK_PPC_GOT_DTPREL_HA)
+ .Case("got@dtprel@ha", VK_PPC_GOT_DTPREL_HA)
+ .Case("GOT@TLSGD", VK_PPC_GOT_TLSGD)
+ .Case("got@tlsgd", VK_PPC_GOT_TLSGD)
+ .Case("GOT@TLSGD@L", VK_PPC_GOT_TLSGD_LO)
+ .Case("got@tlsgd@l", VK_PPC_GOT_TLSGD_LO)
+ .Case("GOT@TLSGD@H", VK_PPC_GOT_TLSGD_HI)
+ .Case("got@tlsgd@h", VK_PPC_GOT_TLSGD_HI)
+ .Case("GOT@TLSGD@HA", VK_PPC_GOT_TLSGD_HA)
+ .Case("got@tlsgd@ha", VK_PPC_GOT_TLSGD_HA)
+ .Case("GOT@TLSLD", VK_PPC_GOT_TLSLD)
+ .Case("got@tlsld", VK_PPC_GOT_TLSLD)
+ .Case("GOT@TLSLD@L", VK_PPC_GOT_TLSLD_LO)
+ .Case("got@tlsld@l", VK_PPC_GOT_TLSLD_LO)
+ .Case("GOT@TLSLD@H", VK_PPC_GOT_TLSLD_HI)
+ .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
+ .Case("GOT@TLSLD@HA", VK_PPC_GOT_TLSLD_HA)
+ .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
.Default(VK_Invalid);
}
diff --git a/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp b/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp
new file mode 100644
index 0000000..ca368b2
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCExternalSymbolizer.cpp
@@ -0,0 +1,181 @@
+//===-- lib/MC/MCExternalSymbolizer.cpp - External symbolizer ---*- 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/MCExternalSymbolizer.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+
+using namespace llvm;
+
+// This function tries to add a symbolic operand in place of the immediate
+// Value in the MCInst. The immediate Value has had any PC adjustment made by
+// the caller. If the instruction is a branch instruction then IsBranch is true,
+// else false. If the getOpInfo() function was set as part of the
+// setupForSymbolicDisassembly() call then that function is called to get any
+// symbolic information at the Address for this instruction. If that returns
+// non-zero then the symbolic information it returns is used to create an MCExpr
+// and that is added as an operand to the MCInst. If getOpInfo() returns zero
+// and IsBranch is true then a symbol look up for Value is done and if a symbol
+// is found an MCExpr is created with that, else an MCExpr with Value is
+// created. This function returns true if it adds an operand to the MCInst and
+// false otherwise.
+bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI,
+ raw_ostream &cStream,
+ int64_t Value,
+ uint64_t Address,
+ bool IsBranch,
+ uint64_t Offset,
+ uint64_t InstSize) {
+ struct LLVMOpInfo1 SymbolicOp;
+ std::memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
+ SymbolicOp.Value = Value;
+
+ if (!GetOpInfo ||
+ !GetOpInfo(DisInfo, Address, Offset, InstSize, 1, &SymbolicOp)) {
+ // Clear SymbolicOp.Value from above and also all other fields.
+ std::memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
+ if (!SymbolLookUp)
+ return false;
+ uint64_t ReferenceType;
+ if (IsBranch)
+ ReferenceType = LLVMDisassembler_ReferenceType_In_Branch;
+ else
+ ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
+ const char *ReferenceName;
+ const char *Name = SymbolLookUp(DisInfo, Value, &ReferenceType, Address,
+ &ReferenceName);
+ if (Name) {
+ SymbolicOp.AddSymbol.Name = Name;
+ SymbolicOp.AddSymbol.Present = true;
+ }
+ // For branches always create an MCExpr so it gets printed as hex address.
+ else if (IsBranch) {
+ SymbolicOp.Value = Value;
+ }
+ if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub)
+ cStream << "symbol stub for: " << ReferenceName;
+ else if(ReferenceType == LLVMDisassembler_ReferenceType_Out_Objc_Message)
+ cStream << "Objc message: " << ReferenceName;
+ if (!Name && !IsBranch)
+ return false;
+ }
+
+ const MCExpr *Add = NULL;
+ if (SymbolicOp.AddSymbol.Present) {
+ if (SymbolicOp.AddSymbol.Name) {
+ StringRef Name(SymbolicOp.AddSymbol.Name);
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
+ Add = MCSymbolRefExpr::Create(Sym, Ctx);
+ } else {
+ Add = MCConstantExpr::Create((int)SymbolicOp.AddSymbol.Value, Ctx);
+ }
+ }
+
+ const MCExpr *Sub = NULL;
+ if (SymbolicOp.SubtractSymbol.Present) {
+ if (SymbolicOp.SubtractSymbol.Name) {
+ StringRef Name(SymbolicOp.SubtractSymbol.Name);
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
+ Sub = MCSymbolRefExpr::Create(Sym, Ctx);
+ } else {
+ Sub = MCConstantExpr::Create((int)SymbolicOp.SubtractSymbol.Value, Ctx);
+ }
+ }
+
+ const MCExpr *Off = NULL;
+ if (SymbolicOp.Value != 0)
+ Off = MCConstantExpr::Create(SymbolicOp.Value, Ctx);
+
+ const MCExpr *Expr;
+ if (Sub) {
+ const MCExpr *LHS;
+ if (Add)
+ LHS = MCBinaryExpr::CreateSub(Add, Sub, Ctx);
+ else
+ LHS = MCUnaryExpr::CreateMinus(Sub, Ctx);
+ if (Off != 0)
+ Expr = MCBinaryExpr::CreateAdd(LHS, Off, Ctx);
+ else
+ Expr = LHS;
+ } else if (Add) {
+ if (Off != 0)
+ Expr = MCBinaryExpr::CreateAdd(Add, Off, Ctx);
+ else
+ Expr = Add;
+ } else {
+ if (Off != 0)
+ Expr = Off;
+ else
+ Expr = MCConstantExpr::Create(0, Ctx);
+ }
+
+ Expr = RelInfo->createExprForCAPIVariantKind(Expr, SymbolicOp.VariantKind);
+ if (!Expr)
+ return false;
+
+ MI.addOperand(MCOperand::CreateExpr(Expr));
+ return true;
+}
+
+// This function tries to add a comment as to what is being referenced by a load
+// instruction with the base register that is the Pc. These can often be values
+// in a literal pool near the Address of the instruction. The Address of the
+// instruction and its immediate Value are used as a possible literal pool entry.
+// The SymbolLookUp call back will return the name of a symbol referenced by the
+// literal pool's entry if the referenced address is that of a symbol. Or it
+// will return a pointer to a literal 'C' string if the referenced address of
+// the literal pool's entry is an address into a section with C string literals.
+// Or if the reference is to an Objective-C data structure it will return a
+// specific reference type for it and a string.
+void MCExternalSymbolizer::tryAddingPcLoadReferenceComment(raw_ostream &cStream,
+ int64_t Value,
+ uint64_t Address) {
+ if (SymbolLookUp) {
+ uint64_t ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load;
+ const char *ReferenceName;
+ (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName);
+ if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr)
+ cStream << "literal pool symbol address: " << ReferenceName;
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
+ cStream << "literal pool for: \"" << ReferenceName << "\"";
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_Objc_CFString_Ref)
+ cStream << "Objc cfstring ref: @\"" << ReferenceName << "\"";
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_Objc_Message)
+ cStream << "Objc message: " << ReferenceName;
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_Objc_Message_Ref)
+ cStream << "Objc message ref: " << ReferenceName;
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_Objc_Selector_Ref)
+ cStream << "Objc selector ref: " << ReferenceName;
+ else if(ReferenceType ==
+ LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref)
+ cStream << "Objc class ref: " << ReferenceName;
+ }
+}
+
+namespace llvm {
+MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp,
+ void *DisInfo,
+ MCContext *Ctx,
+ MCRelocationInfo *RelInfo) {
+ assert(Ctx != 0 && "No MCContext given for symbolic disassembly");
+
+ OwningPtr<MCRelocationInfo> RelInfoOwingPtr(RelInfo);
+ return new MCExternalSymbolizer(*Ctx, RelInfoOwingPtr, GetOpInfo,
+ SymbolLookUp, DisInfo);
+}
+}
diff --git a/contrib/llvm/lib/MC/MCFunction.cpp b/contrib/llvm/lib/MC/MCFunction.cpp
new file mode 100644
index 0000000..767e1e0
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCFunction.cpp
@@ -0,0 +1,81 @@
+//===-- 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/MCFunction.h"
+#include "llvm/MC/MCAtom.h"
+#include "llvm/MC/MCModule.h"
+#include <algorithm>
+
+using namespace llvm;
+
+// MCFunction
+
+MCFunction::MCFunction(StringRef Name, MCModule *Parent)
+ : Name(Name), ParentModule(Parent)
+{}
+
+MCFunction::~MCFunction() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ delete *I;
+}
+
+MCBasicBlock &MCFunction::createBlock(const MCTextAtom &TA) {
+ MCBasicBlock *MCBB = new MCBasicBlock(TA, this);
+ Blocks.push_back(MCBB);
+ return *MCBB;
+}
+
+MCBasicBlock *MCFunction::find(uint64_t StartAddr) {
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ if ((*I)->getInsts()->getBeginAddr() == StartAddr)
+ return *I;
+ return 0;
+}
+
+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/contrib/llvm/lib/MC/MCInstPrinter.cpp b/contrib/llvm/lib/MC/MCInstPrinter.cpp
index c729d49..ba71245 100644
--- a/contrib/llvm/lib/MC/MCInstPrinter.cpp
+++ b/contrib/llvm/lib/MC/MCInstPrinter.cpp
@@ -31,9 +31,13 @@ void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) {
if (!Annot.empty()) {
- if (CommentStream)
+ if (CommentStream) {
(*CommentStream) << Annot;
- else
+ // By definition (see MCInstPrinter.h), CommentStream must end with
+ // a newline after each comment.
+ if (Annot.back() != '\n')
+ (*CommentStream) << '\n';
+ } else
OS << " " << MAI.getCommentString() << " " << Annot;
}
}
@@ -89,6 +93,7 @@ format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const {
return format("%" PRIx64 "h", Value);
}
}
+ llvm_unreachable("unsupported print style");
}
format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const {
@@ -101,4 +106,5 @@ format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const {
else
return format("%" PRIx64 "h", Value);
}
+ llvm_unreachable("unsupported print style");
}
diff --git a/contrib/llvm/lib/MC/MCInstrAnalysis.cpp b/contrib/llvm/lib/MC/MCInstrAnalysis.cpp
index 7736702..2d8336d 100644
--- a/contrib/llvm/lib/MC/MCInstrAnalysis.cpp
+++ b/contrib/llvm/lib/MC/MCInstrAnalysis.cpp
@@ -10,12 +10,13 @@
#include "llvm/MC/MCInstrAnalysis.h"
using namespace llvm;
-uint64_t MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
- uint64_t Size) const {
+bool MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
+ uint64_t Size, uint64_t &Target) const {
if (Inst.getNumOperands() == 0 ||
Info->get(Inst.getOpcode()).OpInfo[0].OperandType != MCOI::OPERAND_PCREL)
- return -1ULL;
+ return false;
int64_t Imm = Inst.getOperand(0).getImm();
- return Addr+Size+Imm;
+ Target = Addr+Size+Imm;
+ return true;
}
diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
index e08b01b..2924dcd 100644
--- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp
@@ -1,3 +1,4 @@
+//===-- MCMachOStreamer.cpp - MachO Streamer ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -36,7 +37,7 @@ private:
public:
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
- : MCObjectStreamer(SK_MachOStreamer, Context, MAB, OS, Emitter) {}
+ : MCObjectStreamer(Context, 0, MAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
@@ -51,7 +52,7 @@ public:
virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
@@ -81,16 +82,14 @@ public:
// FIXME: Just ignore the .file; it isn't important enough to fail the
// entire assembly.
- //report_fatal_error("unsupported directive: '.file'");
+ // report_fatal_error("unsupported directive: '.file'");
}
- virtual void FinishImpl();
-
- /// @}
-
- static bool classof(const MCStreamer *S) {
- return S->getKind() == SK_MachOStreamer;
+ virtual void EmitIdent(StringRef IdentString) {
+ llvm_unreachable("macho doesn't support this directive");
}
+
+ virtual void FinishImpl();
};
} // end anonymous namespace.
@@ -122,7 +121,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
// isSymbolLinkerVisible uses the section.
- Symbol->setSection(*getCurrentSection().first);
+ AssignSection(Symbol, getCurrentSection().first);
// We have to create a new fragment if this is an atom defining symbol,
// fragments cannot span atoms.
if (getAssembler().isSymbolLinkerVisible(*Symbol))
@@ -217,7 +216,7 @@ void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) {
SD.setFlags(SD.getFlags() | SF_ThumbFunc);
}
-void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
// Indirect symbols are handled differently, to match how 'as' handles
// them. This makes writing matching .o files easier.
@@ -228,7 +227,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
ISD.Symbol = Symbol;
ISD.SectionData = getCurrentSectionData();
getAssembler().getIndirectSymbols().push_back(ISD);
- return;
+ return true;
}
// Adding a symbol attribute always introduces the symbol, note that an
@@ -257,7 +256,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_Protected:
case MCSA_Weak:
case MCSA_Local:
- llvm_unreachable("Invalid symbol attribute for Mach-O!");
+ return false;
case MCSA_Global:
SD.setExternal(true);
@@ -309,6 +308,8 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
SD.setFlags(SD.getFlags() | SF_WeakDefinition | SF_WeakReference);
break;
}
+
+ return true;
}
void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
@@ -324,6 +325,8 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
// FIXME: Darwin 'as' does appear to allow redef of a .comm by itself.
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ AssignSection(Symbol, NULL);
+
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
SD.setExternal(true);
SD.setCommon(Size, ByteAlignment);
@@ -346,7 +349,8 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
if (!Symbol)
return;
- // FIXME: Assert that this section has the zerofill type.
+ // On darwin all virtual sections have zerofill type.
+ assert(Section->isVirtualSection() && "Section does not have zerofill type!");
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
@@ -359,7 +363,7 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
SD.setFragment(F);
- Symbol->setSection(*Section);
+ AssignSection(Symbol, Section);
// Update the maximum alignment on the zero fill section if necessary.
if (ByteAlignment > SectData.getAlignment())
@@ -392,7 +396,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) {
}
void MCMachOStreamer::FinishImpl() {
- EmitFrames(true);
+ EmitFrames(&getAssembler().getBackend(), true);
// We have to set the fragment atom associations so we can relax properly for
// Mach-O.
diff --git a/contrib/llvm/lib/MC/MCModule.cpp b/contrib/llvm/lib/MC/MCModule.cpp
index f563160..7e9e18a 100644
--- a/contrib/llvm/lib/MC/MCModule.cpp
+++ b/contrib/llvm/lib/MC/MCModule.cpp
@@ -7,39 +7,136 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCAtom.h"
#include "llvm/MC/MCModule.h"
+#include "llvm/MC/MCAtom.h"
+#include "llvm/MC/MCFunction.h"
+#include <algorithm>
using namespace llvm;
-MCAtom *MCModule::createAtom(MCAtom::AtomType Type,
- uint64_t Begin, uint64_t End) {
- assert(Begin < End && "Creating MCAtom with endpoints reversed?");
+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.
- IntervalMap<uint64_t, MCAtom*>::iterator I = OffsetMap.find(Begin);
- assert((!I.valid() || I.start() < End) && "Offset range already occupied!");
+ AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
+ Begin, AtomComp);
+ assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End)
+ && "Offset range already occupied!");
- // Create the new atom and add it to our maps.
- MCAtom *NewAtom = new MCAtom(Type, this, Begin, End);
- AtomAllocationTracker.insert(NewAtom);
- OffsetMap.insert(Begin, End, NewAtom);
+ // 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.
- IntervalMap<uint64_t, MCAtom*>::iterator I = OffsetMap.find(Atom->Begin);
- assert(I.valid() && "Atom offset not found in module!");
+ 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!");
- I.erase();
+ Atoms.erase(I);
+
+ // FIXME: special case NewBegin == Atom->Begin
// Insert the new mapping.
- OffsetMap.insert(NewBegin, NewEnd, Atom);
+ 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 0;
+}
+
+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 0;
+}
+
+MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) {
+ return const_cast<MCAtom*>(
+ const_cast<const MCModule *>(this)->findFirstAtomAfter(Addr));
+}
+
+MCFunction *MCModule::createFunction(StringRef Name) {
+ Functions.push_back(new MCFunction(Name, this));
+ return Functions.back();
+}
+
+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() {
+ for (AtomListTy::iterator AI = atom_begin(),
+ AE = atom_end();
+ AI != AE; ++AI)
+ delete *AI;
+ for (FunctionListTy::iterator FI = func_begin(),
+ FE = func_end();
+ FI != FE; ++FI)
+ delete *FI;
+}
diff --git a/contrib/llvm/lib/MC/MCModuleYAML.cpp b/contrib/llvm/lib/MC/MCModuleYAML.cpp
new file mode 100644
index 0000000..e2de578
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCModuleYAML.cpp
@@ -0,0 +1,461 @@
+//===- 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/MCModuleYAML.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCAtom.h"
+#include "llvm/MC/MCFunction.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Object/YAML.h"
+#include "llvm/Support/Allocator.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;
+ object::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 &);
+};
+
+template <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> {
+ static void output(const MCModuleYAML::OpcodeEnum &, void *,
+ llvm::raw_ostream &);
+ static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &);
+};
+
+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(OwningPtr<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 (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/contrib/llvm/lib/MC/MCNullStreamer.cpp b/contrib/llvm/lib/MC/MCNullStreamer.cpp
index 659706a..9b9c4aa 100644
--- a/contrib/llvm/lib/MC/MCNullStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCNullStreamer.cpp
@@ -19,7 +19,7 @@ namespace {
class MCNullStreamer : public MCStreamer {
public:
- MCNullStreamer(MCContext &Context) : MCStreamer(SK_NullStreamer, Context) {}
+ MCNullStreamer(MCContext &Context) : MCStreamer(Context, 0) {}
/// @name MCStreamer Interface
/// @{
@@ -37,7 +37,7 @@ namespace {
virtual void EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
assert(getCurrentSection().first &&"Cannot emit before setting section!");
- Symbol->setSection(*getCurrentSection().first);
+ AssignSection(Symbol, getCurrentSection().first);
}
virtual void EmitDebugLabel(MCSymbol *Symbol) {
EmitLabel(Symbol);
@@ -52,7 +52,9 @@ namespace {
const MCSymbol *Label,
unsigned PointerSize) {}
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){}
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){
+ return true;
+ }
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
@@ -71,10 +73,9 @@ namespace {
uint64_t Size = 0, unsigned ByteAlignment = 0) {}
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {}
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
+ virtual void EmitBytes(StringRef Data) {}
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {}
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) {}
virtual void EmitULEB128Value(const MCExpr *Value) {}
virtual void EmitSLEB128Value(const MCExpr *Value) {}
virtual void EmitGPRel32Value(const MCExpr *Value) {}
@@ -108,13 +109,6 @@ namespace {
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
RecordProcEnd(Frame);
}
-
- /// @}
-
- static bool classof(const MCStreamer *S) {
- return S->getKind() == SK_NullStreamer;
- }
-
};
}
diff --git a/contrib/llvm/lib/MC/MCObjectDisassembler.cpp b/contrib/llvm/lib/MC/MCObjectDisassembler.cpp
new file mode 100644
index 0000000..16a110f0
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCObjectDisassembler.cpp
@@ -0,0 +1,584 @@
+//===- 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/MCAtom.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCFunction.h"
+#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCModule.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;
+
+MCObjectDisassembler::MCObjectDisassembler(const ObjectFile &Obj,
+ const MCDisassembler &Dis,
+ const MCInstrAnalysis &MIA)
+ : Obj(Obj), Dis(Dis), MIA(MIA), MOS(0) {}
+
+uint64_t MCObjectDisassembler::getEntrypoint() {
+ error_code ec;
+ for (symbol_iterator SI = Obj.begin_symbols(), SE = Obj.end_symbols();
+ SI != SE; SI.increment(ec)) {
+ if (ec)
+ break;
+ StringRef Name;
+ SI->getName(Name);
+ if (Name == "main" || Name == "_main") {
+ uint64_t Entrypoint;
+ SI->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) {
+ error_code ec;
+ for (section_iterator SI = Obj.begin_sections(),
+ SE = Obj.end_sections();
+ SI != SE;
+ SI.increment(ec)) {
+ if (ec) break;
+
+ bool isText; SI->isText(isText);
+ bool isData; SI->isData(isData);
+ if (!isData && !isText)
+ continue;
+
+ uint64_t StartAddr; SI->getAddress(StartAddr);
+ uint64_t SecSize; SI->getSize(SecSize);
+ if (StartAddr == UnknownAddressOrSize || SecSize == UnknownAddressOrSize)
+ continue;
+ StartAddr = getEffectiveLoadAddr(StartAddr);
+
+ StringRef Contents; SI->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; SI->getName(SecName);
+
+ if (isText) {
+ MCTextAtom *Text = 0;
+ MCDataAtom *InvalidData = 0;
+
+ 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 = 0;
+ } else {
+ assert(InstSize && "getInstruction() consumed no bytes");
+ if (!InvalidData) {
+ Text = 0;
+ 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(0), BB(0) {}
+
+ 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;
+
+ error_code ec;
+ for (symbol_iterator SI = Obj.begin_symbols(), SE = Obj.end_symbols();
+ SI != SE; SI.increment(ec)) {
+ if (ec)
+ break;
+ SymbolRef::Type SymType;
+ SI->getType(SymType);
+ if (SymType == SymbolRef::ST_Function) {
+ uint64_t SymAddr;
+ SI->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;
+ }
+
+ // 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) {
+
+ error_code ec;
+ for (section_iterator SI = MOOF.begin_sections(), SE = MOOF.end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (ec)
+ break;
+ StringRef Name;
+ SI->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");
+ SI->getContents(ModInitContents);
+ } else if (Name == "__mod_exit_func") {
+ DEBUG(dbgs() << "Found __mod_exit_func section!\n");
+ SI->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/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
index 96b62f1..8ef4a0a 100644
--- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -39,6 +39,9 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
= Ctx->getMachOSection("__DATA", "__data", 0,
SectionKind::getDataRel());
+ // BSSSection might not be expected initialized on msvc.
+ BSSSection = 0;
+
TLSDataSection // .tdata
= Ctx->getMachOSection("__DATA", "__thread_data",
MCSectionMachO::S_THREAD_LOCAL_REGULAR,
@@ -79,7 +82,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
// to using it in -static mode.
SixteenByteConstantSection = 0;
if (RelocM != Reloc::Static &&
- T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64)
+ T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64 &&
+ T.getArch() != Triple::ppc64le)
SixteenByteConstantSection = // .literal16
Ctx->getMachOSection("__TEXT", "__literal16",
MCSectionMachO::S_16BYTE_LITERALS,
@@ -198,6 +202,14 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
Ctx->getMachOSection("__DWARF", "__debug_pubtypes",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+ DwarfGnuPubNamesSection =
+ Ctx->getMachOSection("__DWARF", "__debug_gnu_pubn",
+ MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
+ DwarfGnuPubTypesSection =
+ Ctx->getMachOSection("__DWARF", "__debug_gnu_pubt",
+ MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
DwarfStrSection =
Ctx->getMachOSection("__DWARF", "__debug_str",
MCSectionMachO::S_ATTR_DEBUG,
@@ -222,6 +234,9 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
Ctx->getMachOSection("__DWARF", "__debug_inlined",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+ StackMapSection =
+ Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", 0,
+ SectionKind::getMetadata());
TLSExtraDataSection = TLSTLVSection;
}
@@ -288,7 +303,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
FDEEncoding = dwarf::DW_EH_PE_udata4;
TTypeEncoding = dwarf::DW_EH_PE_absptr;
}
- } else if (T.getArch() == Triple::ppc64) {
+ } else if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_udata8;
LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
@@ -434,6 +449,12 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfPubTypesSection =
Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfGnuPubNamesSection =
+ Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfGnuPubTypesSection =
+ Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfStrSection =
Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS,
ELF::SHF_MERGE | ELF::SHF_STRINGS,
@@ -495,6 +516,12 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
// COFF
+ BSSSection =
+ Ctx->getCOFFSection(".bss",
+ COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getBSS());
TextSection =
Ctx->getCOFFSection(".text",
COFF::IMAGE_SCN_CNT_CODE |
@@ -584,6 +611,16 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfGnuPubNamesSection =
+ Ctx->getCOFFSection(".debug_gnu_pubnames",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+ DwarfGnuPubTypesSection =
+ Ctx->getCOFFSection(".debug_gnu_pubtypes",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfStrSection =
Ctx->getCOFFSection(".debug_str",
COFF::IMAGE_SCN_MEM_DISCARDABLE |
diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
index d21ce8d..bc14c2a 100644
--- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp
@@ -18,22 +18,26 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
-MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+MCObjectStreamer::MCObjectStreamer(MCContext &Context,
+ MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter_)
- : MCStreamer(Kind, Context),
+ : MCStreamer(Context, TargetStreamer),
Assembler(new MCAssembler(Context, TAB, *Emitter_,
*TAB.createObjectWriter(OS), OS)),
CurSectionData(0) {}
-MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+MCObjectStreamer::MCObjectStreamer(MCContext &Context,
+ MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter_,
MCAssembler *_Assembler)
- : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
+ : MCStreamer(Context, TargetStreamer), Assembler(_Assembler),
+ CurSectionData(0) {}
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();
@@ -98,15 +102,15 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
return Value;
}
-void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {
- assert(AddrSpace == 0 && "Address space must be 0!");
+void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
MCDataFragment *DF = getOrCreateDataFragment();
+ MCLineEntry::Make(this, getCurrentSection().first);
+
// Avoid fixups when possible.
int64_t AbsValue;
if (AddValueSymbols(Value)->EvaluateAsAbsolute(AbsValue, getAssembler())) {
- EmitIntValue(AbsValue, Size, AddrSpace);
+ EmitIntValue(AbsValue, Size);
return;
}
DF->getFixups().push_back(
@@ -241,7 +245,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
}
#ifndef NDEBUG
-static const char *BundlingNotImplementedMsg =
+static const char *const BundlingNotImplementedMsg =
"Aligned bundling is not implemented for this object format";
#endif
@@ -257,6 +261,19 @@ void MCObjectStreamer::EmitBundleUnlock() {
llvm_unreachable(BundlingNotImplementedMsg);
}
+void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa,
+ unsigned Discriminator,
+ StringRef FileName) {
+ // In case we see two .loc directives in a row, make sure the
+ // first one gets a line entry.
+ MCLineEntry::Make(this, getCurrentSection().first);
+
+ this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
+ Isa, Discriminator, FileName);
+}
+
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
@@ -287,8 +304,8 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
insert(new MCDwarfCallFrameFragment(*AddrDelta));
}
-void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
- assert(AddrSpace == 0 && "Address space must be 0!");
+void MCObjectStreamer::EmitBytes(StringRef Data) {
+ MCLineEntry::Make(this, getCurrentSection().first);
getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
}
@@ -351,14 +368,17 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
DF->getContents().resize(DF->getContents().size() + 8, 0);
}
-void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace) {
- assert(AddrSpace == 0 && "Address space must be 0!");
+void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
// FIXME: A MCFillFragment would be more memory efficient but MCExpr has
// problems evaluating expressions across multiple fragments.
getOrCreateDataFragment()->getContents().append(NumBytes, FillValue);
}
+void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
+ unsigned ItemSize = getCurrentSection().first->isVirtualSection() ? 0 : 1;
+ insert(new MCFillFragment(0, ItemSize, NumBytes));
+}
+
void MCObjectStreamer::FinishImpl() {
// Dump out the dwarf file & directory tables and line tables.
const MCSymbol *LineSectionSymbol = NULL;
diff --git a/contrib/llvm/lib/MC/MCObjectSymbolizer.cpp b/contrib/llvm/lib/MC/MCObjectSymbolizer.cpp
new file mode 100644
index 0000000..b9131d1
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCObjectSymbolizer.cpp
@@ -0,0 +1,310 @@
+//===-- 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/MachO.h"
+#include "llvm/Object/ELFObjectFile.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, OwningPtr<MCRelocationInfo> &RelInfo,
+ const MachOObjectFile *MOOF);
+
+ StringRef findExternalFunctionAt(uint64_t Addr) LLVM_OVERRIDE;
+
+ void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
+ int64_t Value,
+ uint64_t Address) LLVM_OVERRIDE;
+};
+} // End unnamed namespace
+
+
+MCMachObjectSymbolizer::
+MCMachObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
+ const MachOObjectFile *MOOF)
+ : MCObjectSymbolizer(Ctx, RelInfo, MOOF), MOOF(MOOF),
+ StubsStart(0), StubsCount(0), StubSize(0), StubsIndSymIndex(0) {
+
+ error_code ec;
+ for (section_iterator SI = MOOF->begin_sections(), SE = MOOF->end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (ec) break;
+ StringRef Name; SI->getName(Name);
+ if (Name == "__stubs") {
+ SectionRef StubsSec = *SI;
+ 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->begin_symbols();
+ error_code ec;
+ for (uint32_t i = 0; i != SymtabIdx; ++i) {
+ SI.increment(ec);
+ }
+ SI->getName(SymName);
+ assert(SI != MOOF->end_symbols() && "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,
+ OwningPtr<MCRelocationInfo> &RelInfo,
+ const ObjectFile *Obj)
+ : MCSymbolizer(Ctx, 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?
+ error_code ec;
+ for (symbol_iterator SI = Obj->begin_symbols(), SE = Obj->end_symbols();
+ SI != SE; SI.increment(ec)) {
+ if (ec) break;
+ uint64_t SymAddr; SI->getAddress(SymAddr);
+ uint64_t SymSize; SI->getSize(SymSize);
+ StringRef SymName; SI->getName(SymName);
+ SymbolRef::Type SymType; SI->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,
+ OwningPtr<MCRelocationInfo> &RelInfo,
+ const ObjectFile *Obj) {
+ if (const MachOObjectFile *MOOF = dyn_cast<MachOObjectFile>(Obj))
+ return new MCMachObjectSymbolizer(Ctx, RelInfo, MOOF);
+ return new MCObjectSymbolizer(Ctx, 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 0;
+ uint64_t SAddr; It->getAddress(SAddr);
+ uint64_t SSize; It->getSize(SSize);
+ if (Addr >= SAddr + SSize)
+ return 0;
+ 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 0;
+ return &RI->second;
+}
+
+void MCObjectSymbolizer::buildSectionList() {
+ error_code ec;
+ for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (ec) break;
+
+ bool RequiredForExec; SI->isRequiredForExecution(RequiredForExec);
+ if (RequiredForExec == false)
+ continue;
+ uint64_t SAddr; SI->getAddress(SAddr);
+ uint64_t SSize; SI->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, *SI);
+ }
+}
+
+void MCObjectSymbolizer::buildRelocationByAddrMap() {
+ error_code ec;
+ for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (ec) break;
+
+ section_iterator RelSecI = SI->getRelocatedSection();
+ if (RelSecI == Obj->end_sections())
+ continue;
+
+ uint64_t StartAddr; RelSecI->getAddress(StartAddr);
+ uint64_t Size; RelSecI->getSize(Size);
+ bool RequiredForExec; RelSecI->isRequiredForExecution(RequiredForExec);
+ if (RequiredForExec == false || Size == 0)
+ continue;
+ for (relocation_iterator RI = SI->begin_relocations(),
+ RE = SI->end_relocations();
+ RI != RE;
+ RI.increment(ec)) {
+ if (ec) break;
+ // FIXME: libObject is inconsistent regarding error handling. The
+ // overwhelming majority of methods always return object_error::success,
+ // and assert for simple errors.. Here, ELFObjectFile::getRelocationOffset
+ // asserts when the file type isn't ET_REL.
+ // This workaround handles x86-64 elf, the only one that has a relocinfo.
+ uint64_t Offset;
+ if (Obj->isELF()) {
+ const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj);
+ if (ELFObj == 0)
+ break;
+ if (ELFObj->getELFFile()->getHeader()->e_type == ELF::ET_REL) {
+ RI->getOffset(Offset);
+ Offset += StartAddr;
+ } else {
+ RI->getAddress(Offset);
+ }
+ } else {
+ RI->getOffset(Offset);
+ Offset += StartAddr;
+ }
+ // At a specific address, only keep the first relocation.
+ if (AddrToReloc.find(Offset) == AddrToReloc.end())
+ AddrToReloc[Offset] = *RI;
+ }
+ }
+}
diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
index c1c594a..b49dd01 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -91,9 +91,56 @@ AsmToken AsmLexer::LexFloatLiteral() {
StringRef(TokStart, CurPtr - TokStart));
}
-/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
+/// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+
+/// while making sure there are enough actual digits around for the constant to
+/// be valid.
+///
+/// The leading "0x[0-9a-fA-F]*" (i.e. integer part) has already been consumed
+/// before we get here.
+AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) {
+ assert((*CurPtr == 'p' || *CurPtr == 'P' || *CurPtr == '.') &&
+ "unexpected parse state in floating hex");
+ bool NoFracDigits = true;
+
+ // Skip the fractional part if there is one
+ if (*CurPtr == '.') {
+ ++CurPtr;
+
+ const char *FracStart = CurPtr;
+ while (isxdigit(*CurPtr))
+ ++CurPtr;
+
+ NoFracDigits = CurPtr == FracStart;
+ }
+
+ if (NoIntDigits && NoFracDigits)
+ return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
+ "expected at least one significand digit");
+
+ // Make sure we do have some kind of proper exponent part
+ if (*CurPtr != 'p' && *CurPtr != 'P')
+ return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
+ "expected exponent part 'p'");
+ ++CurPtr;
+
+ if (*CurPtr == '+' || *CurPtr == '-')
+ ++CurPtr;
+
+ // N.b. exponent digits are *not* hex
+ const char *ExpStart = CurPtr;
+ while (isdigit(*CurPtr))
+ ++CurPtr;
+
+ if (CurPtr == ExpStart)
+ return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
+ "expected at least one exponent digit");
+
+ return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
+}
+
+/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]*
static bool IsIdentifierChar(char c) {
- return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@';
+ return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@' || c == '?';
}
AsmToken AsmLexer::LexIdentifier() {
// Check for floating point literals.
@@ -265,7 +312,12 @@ AsmToken AsmLexer::LexDigit() {
while (isxdigit(CurPtr[0]))
++CurPtr;
- // Requires at least one hex digit.
+ // "0x.0p0" is valid, and "0x0p0" (but not "0xp0" for example, which will be
+ // diagnosed by LexHexFloatLiteral).
+ if (CurPtr[0] == '.' || CurPtr[0] == 'p' || CurPtr[0] == 'P')
+ return LexHexFloatLiteral(NumStart == CurPtr);
+
+ // Otherwise requires at least one hex digit.
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "invalid hexadecimal number");
diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
index edefdb4..a91bd93 100644
--- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -94,13 +94,13 @@ public:
};
struct ParseStatementInfo {
- /// ParsedOperands - The parsed operands from the last parsed statement.
+ /// \brief The parsed operands from the last parsed statement.
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
- /// Opcode - The opcode from the last parsed instruction.
+ /// \brief The opcode from the last parsed instruction.
unsigned Opcode;
- /// Error - Was there an error parsing the inline assembly?
+ /// \brief Was there an error parsing the inline assembly?
bool ParseError;
SmallVectorImpl<AsmRewrite> *AsmRewrites;
@@ -138,17 +138,20 @@ private:
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
- /// ExtensionDirectiveMap - maps directive names to handler methods in parser
+ /// \brief maps directive names to handler methods in parser
/// extensions. Extensions register themselves in this map by calling
/// addDirectiveHandler.
StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
- /// MacroMap - Map of currently defined macros.
+ /// \brief Map of currently defined macros.
StringMap<MCAsmMacro*> MacroMap;
- /// ActiveMacros - Stack of active macro instantiations.
+ /// \brief Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
+ /// \brief List of bodies of anonymous macros.
+ std::deque<MCAsmMacro> MacroLikeBodies;
+
/// Boolean tracking whether macro substitution is enabled.
unsigned MacrosEnabledFlag : 1;
@@ -160,14 +163,21 @@ private:
int64_t CppHashLineNumber;
SMLoc CppHashLoc;
int CppHashBuf;
+ /// When generating dwarf for assembly source files we need to calculate the
+ /// logical line number based on the last parsed cpp hash file line comment
+ /// and current line. Since this is slow and messes up the SourceMgr's
+ /// cache we save the last info we queried with SrcMgr.FindLineNumber().
+ SMLoc LastQueryIDLoc;
+ int LastQueryBuffer;
+ unsigned LastQueryLine;
/// AssemblerDialect. ~OU means unset value and use value provided by MAI.
unsigned AssemblerDialect;
- /// IsDarwin - is Darwin compatibility enabled?
+ /// \brief is Darwin compatibility enabled?
bool IsDarwin;
- /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
+ /// \brief Are we parsing ms-style inline assembly?
bool ParsingInlineAsm;
public:
@@ -225,7 +235,7 @@ public:
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool parseAbsoluteExpression(int64_t &Res);
- /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// \brief Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
virtual bool parseIdentifier(StringRef &Res);
virtual void eatToEndOfStatement();
@@ -235,11 +245,11 @@ public:
private:
- bool ParseStatement(ParseStatementInfo &Info);
- void EatToEndOfLine();
- bool ParseCppHashLineFilenameComment(const SMLoc &L);
+ bool parseStatement(ParseStatementInfo &Info);
+ void eatToEndOfLine();
+ bool parseCppHashLineFilenameComment(const SMLoc &L);
- void CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
+ void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
MCAsmMacroParameters Parameters);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
const MCAsmMacroParameters &Parameters,
@@ -247,55 +257,56 @@ private:
const SMLoc &L);
/// \brief Are macros enabled in the parser?
- bool MacrosEnabled() {return MacrosEnabledFlag;}
+ bool areMacrosEnabled() {return MacrosEnabledFlag;}
/// \brief Control a flag in the parser that enables or disables macros.
- void SetMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
+ void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
/// \brief Lookup a previously defined macro.
/// \param Name Macro name.
/// \returns Pointer to macro. NULL if no such macro was defined.
- const MCAsmMacro* LookupMacro(StringRef Name);
+ 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, const MCAsmMacro& Macro);
/// \brief Undefine a macro. If no such macro was defined, it's a no-op.
- void UndefineMacro(StringRef Name);
+ void undefineMacro(StringRef Name);
/// \brief Are we inside a macro instantiation?
- bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
+ bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
- /// \brief Handle entry to macro instantiation.
+ /// \brief Handle entry to macro instantiation.
///
/// \param M The macro.
/// \param NameLoc Instantiation location.
- bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
+ bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
/// \brief Handle exit from macro instantiation.
- void HandleMacroExit();
+ void handleMacroExit();
/// \brief Extract AsmTokens for a macro argument. If the argument delimiter
/// is initially unknown, set it to AsmToken::Eof. It will be set to the
/// correct delimiter by the method.
- bool ParseMacroArgument(MCAsmMacroArgument &MA,
+ bool parseMacroArgument(MCAsmMacroArgument &MA,
AsmToken::TokenKind &ArgumentDelimiter);
/// \brief Parse all macro arguments for a given macro.
- bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
+ bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
- void PrintMacroInstantiations();
- void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
+ void printMacroInstantiations();
+ void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = None) const {
SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
}
static void DiagHandler(const SMDiagnostic &Diag, void *Context);
- /// EnterIncludeFile - Enter the specified file. This returns true on failure.
- bool EnterIncludeFile(const std::string &Filename);
- /// ProcessIncbinFile - Process the specified file for the .incbin directive.
+ /// \brief Enter the specified file. This returns true on failure.
+ bool enterIncludeFile(const std::string &Filename);
+
+ /// \brief Process the specified file for the .incbin directive.
/// This returns true on failure.
- bool ProcessIncbinFile(const std::string &Filename);
+ bool processIncbinFile(const std::string &Filename);
/// \brief Reset the current lexer position to that given by \p Loc. The
/// current token is not set; clients should ensure Lex() is called
@@ -303,7 +314,7 @@ private:
///
/// \param InBuffer If not -1, should be the known buffer id that contains the
/// location.
- void JumpToLoc(SMLoc Loc, int InBuffer=-1);
+ void jumpToLoc(SMLoc Loc, int InBuffer=-1);
/// \brief Parse up to the end of statement and a return the contents from the
/// current token until the end of the statement; the current token on exit
@@ -312,17 +323,16 @@ private:
/// \brief Parse until the end of a statement or a comma is encountered,
/// return the contents from the current token up to the end or comma.
- StringRef ParseStringToComma();
+ StringRef parseStringToComma();
- bool ParseAssignment(StringRef Name, bool allow_redef,
+ bool parseAssignment(StringRef Name, bool allow_redef,
bool NoDeadStrip = false);
- bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
+ bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
+ bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
+ bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
- bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
+ bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
// Generic (target and platform independent) directive parsing.
enum DirectiveKind {
@@ -332,7 +342,7 @@ private:
DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
- DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_INDIRECT_SYMBOL,
+ DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
@@ -345,112 +355,113 @@ private:
DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
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_REGISTER, DK_CFI_WINDOW_SAVE,
DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_SLEB128, DK_ULEB128
};
- /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for
+ /// \brief Maps directive name --> DirectiveKind enum, for
/// directives parsed by this class.
StringMap<DirectiveKind> DirectiveKindMap;
// ".ascii", ".asciz", ".string"
- bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
- bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
- bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
- bool ParseDirectiveFill(); // ".fill"
- bool ParseDirectiveZero(); // ".zero"
+ bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
+ bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ...
+ bool parseDirectiveRealValue(const fltSemantics &); // ".single", ...
+ bool parseDirectiveFill(); // ".fill"
+ bool parseDirectiveZero(); // ".zero"
// ".set", ".equ", ".equiv"
- bool ParseDirectiveSet(StringRef IDVal, bool allow_redef);
- bool ParseDirectiveOrg(); // ".org"
+ bool parseDirectiveSet(StringRef IDVal, bool allow_redef);
+ bool parseDirectiveOrg(); // ".org"
// ".align{,32}", ".p2align{,w,l}"
- bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
+ bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
// ".file", ".line", ".loc", ".stabs"
- bool ParseDirectiveFile(SMLoc DirectiveLoc);
- bool ParseDirectiveLine();
- bool ParseDirectiveLoc();
- bool ParseDirectiveStabs();
+ bool parseDirectiveFile(SMLoc DirectiveLoc);
+ bool parseDirectiveLine();
+ bool parseDirectiveLoc();
+ bool parseDirectiveStabs();
// .cfi directives
- bool ParseDirectiveCFIRegister(SMLoc DirectiveLoc);
- bool ParseDirectiveCFISections();
- bool ParseDirectiveCFIStartProc();
- bool ParseDirectiveCFIEndProc();
- bool ParseDirectiveCFIDefCfaOffset();
- bool ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIAdjustCfaOffset();
- bool ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIOffset(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
- bool ParseDirectiveCFIRememberState();
- bool ParseDirectiveCFIRestoreState();
- bool ParseDirectiveCFISameValue(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRestore(SMLoc DirectiveLoc);
- bool ParseDirectiveCFIEscape();
- bool ParseDirectiveCFISignalFrame();
- bool ParseDirectiveCFIUndefined(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIWindowSave();
+ bool parseDirectiveCFISections();
+ bool parseDirectiveCFIStartProc();
+ bool parseDirectiveCFIEndProc();
+ bool parseDirectiveCFIDefCfaOffset();
+ bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIAdjustCfaOffset();
+ bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
+ bool parseDirectiveCFIRememberState();
+ bool parseDirectiveCFIRestoreState();
+ bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
+ bool parseDirectiveCFIEscape();
+ bool parseDirectiveCFISignalFrame();
+ bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
// macro directives
- bool ParseDirectivePurgeMacro(SMLoc DirectiveLoc);
- bool ParseDirectiveEndMacro(StringRef Directive);
- bool ParseDirectiveMacro(SMLoc DirectiveLoc);
- bool ParseDirectiveMacrosOnOff(StringRef Directive);
+ bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool parseDirectiveEndMacro(StringRef Directive);
+ bool parseDirectiveMacro(SMLoc DirectiveLoc);
+ bool parseDirectiveMacrosOnOff(StringRef Directive);
// ".bundle_align_mode"
- bool ParseDirectiveBundleAlignMode();
+ bool parseDirectiveBundleAlignMode();
// ".bundle_lock"
- bool ParseDirectiveBundleLock();
+ bool parseDirectiveBundleLock();
// ".bundle_unlock"
- bool ParseDirectiveBundleUnlock();
+ bool parseDirectiveBundleUnlock();
// ".space", ".skip"
- bool ParseDirectiveSpace(StringRef IDVal);
+ bool parseDirectiveSpace(StringRef IDVal);
// .sleb128 (Signed=true) and .uleb128 (Signed=false)
- bool ParseDirectiveLEB128(bool Signed);
+ bool parseDirectiveLEB128(bool Signed);
- /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
+ /// \brief Parse a directive like ".globl" which
/// accepts a single symbol (which should be a label or an external).
- bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
+ bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
- bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
+ bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
- bool ParseDirectiveAbort(); // ".abort"
- bool ParseDirectiveInclude(); // ".include"
- bool ParseDirectiveIncbin(); // ".incbin"
+ bool parseDirectiveAbort(); // ".abort"
+ bool parseDirectiveInclude(); // ".include"
+ bool parseDirectiveIncbin(); // ".incbin"
- bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
+ bool parseDirectiveIf(SMLoc DirectiveLoc); // ".if"
// ".ifb" or ".ifnb", depending on ExpectBlank.
- bool ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
+ bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
// ".ifc" or ".ifnc", depending on ExpectEqual.
- bool ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
+ bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual);
// ".ifdef" or ".ifndef", depending on expect_defined
- bool ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
- bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
- bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
- bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
+ bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
+ bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
+ bool parseDirectiveElse(SMLoc DirectiveLoc); // ".else"
+ bool parseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
virtual bool parseEscapedString(std::string &Data);
- const MCExpr *ApplyModifierToExpr(const MCExpr *E,
+ const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
// Macro-like directives
- MCAsmMacro *ParseMacroLikeBody(SMLoc DirectiveLoc);
- void InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
+ MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
+ void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS);
- bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
- bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
- bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
- bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
+ bool parseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
+ bool parseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
+ bool parseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
+ bool parseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
// "_emit" or "__emit"
- bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
+ bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
size_t Len);
// "align"
- bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
+ bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
void initializeDirectiveKindMap();
};
@@ -466,12 +477,12 @@ extern MCAsmParserExtension *createCOFFAsmParser();
enum { DEFAULT_ADDRSPACE = 0 };
-AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
- MCStreamer &_Out, const MCAsmInfo &_MAI)
- : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
- PlatformParser(0),
- CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0),
- AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
+AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out,
+ const MCAsmInfo &_MAI)
+ : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
+ PlatformParser(0), CurBuffer(0), MacrosEnabledFlag(true),
+ CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false),
+ ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -502,37 +513,40 @@ AsmParser::~AsmParser() {
assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
// Destroy any macros.
- for (StringMap<MCAsmMacro*>::iterator it = MacroMap.begin(),
- ie = MacroMap.end(); it != ie; ++it)
+ for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(),
+ ie = MacroMap.end();
+ it != ie; ++it)
delete it->getValue();
delete PlatformParser;
}
-void AsmParser::PrintMacroInstantiations() {
+void AsmParser::printMacroInstantiations() {
// Print the active macro instantiation stack.
- for (std::vector<MacroInstantiation*>::const_reverse_iterator
- it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it)
- PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
+ for (std::vector<MacroInstantiation *>::const_reverse_iterator
+ it = ActiveMacros.rbegin(),
+ ie = ActiveMacros.rend();
+ it != ie; ++it)
+ printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
"while in macro instantiation");
}
bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
if (FatalAssemblerWarnings)
return Error(L, Msg, Ranges);
- PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
- PrintMacroInstantiations();
+ printMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
+ printMacroInstantiations();
return false;
}
bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges) {
HadError = true;
- PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges);
- PrintMacroInstantiations();
+ printMessage(L, SourceMgr::DK_Error, Msg, Ranges);
+ printMacroInstantiations();
return true;
}
-bool AsmParser::EnterIncludeFile(const std::string &Filename) {
+bool AsmParser::enterIncludeFile(const std::string &Filename) {
std::string IncludedFile;
int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
if (NewBuf == -1)
@@ -545,22 +559,21 @@ bool AsmParser::EnterIncludeFile(const std::string &Filename) {
return false;
}
-/// Process the specified .incbin file by seaching for it in the include paths
+/// Process the specified .incbin file by searching for it in the include paths
/// then just emitting the byte contents of the file to the streamer. This
/// returns true on failure.
-bool AsmParser::ProcessIncbinFile(const std::string &Filename) {
+bool AsmParser::processIncbinFile(const std::string &Filename) {
std::string IncludedFile;
int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
if (NewBuf == -1)
return true;
// Pick up the bytes from the file and emit them.
- getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer(),
- DEFAULT_ADDRSPACE);
+ getStreamer().EmitBytes(SrcMgr.getMemoryBuffer(NewBuf)->getBuffer());
return false;
}
-void AsmParser::JumpToLoc(SMLoc Loc, int InBuffer) {
+void AsmParser::jumpToLoc(SMLoc Loc, int InBuffer) {
if (InBuffer != -1) {
CurBuffer = InBuffer;
} else {
@@ -577,7 +590,7 @@ const AsmToken &AsmParser::Lex() {
// include stack.
SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
if (ParentIncludeLoc != SMLoc()) {
- JumpToLoc(ParentIncludeLoc);
+ jumpToLoc(ParentIncludeLoc);
tok = &Lexer.Lex();
}
}
@@ -614,7 +627,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// While we have input, parse each statement.
while (Lexer.isNot(AsmToken::Eof)) {
ParseStatementInfo Info;
- if (!ParseStatement(Info)) continue;
+ if (!parseStatement(Info))
+ continue;
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
@@ -628,7 +642,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Check to see there are no empty DwarfFile slots.
const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
- getContext().getMCDwarfFiles();
+ getContext().getMCDwarfFiles();
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
if (!MCDwarfFiles[i])
TokError("unassigned file number: " + Twine(i) + " for .file directives");
@@ -641,7 +655,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
const MCContext::SymbolTable &Symbols = getContext().getSymbols();
for (MCContext::SymbolTable::const_iterator i = Symbols.begin(),
- e = Symbols.end();
+ e = Symbols.end();
i != e; ++i) {
MCSymbol *Sym = i->getValue();
// Variable symbols may not be marked as defined, so check those
@@ -651,13 +665,12 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// FIXME: We would really like to refer back to where the symbol was
// first referenced for a source location. We need to add something
// to track that. Currently, we just point to the end of the file.
- PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error,
- "assembler local symbol '" + Sym->getName() +
- "' not defined");
+ printMessage(
+ getLexer().getLoc(), SourceMgr::DK_Error,
+ "assembler local symbol '" + Sym->getName() + "' not defined");
}
}
-
// Finalize the output stream if there are no errors and if the client wants
// us to.
if (!HadError && !NoFinalize)
@@ -673,10 +686,9 @@ void AsmParser::checkForValidSection() {
}
}
-/// eatToEndOfStatement - Throw away the rest of the line for testing purposes.
+/// \brief Throw away the rest of the line for testing purposes.
void AsmParser::eatToEndOfStatement() {
- while (Lexer.isNot(AsmToken::EndOfStatement) &&
- Lexer.isNot(AsmToken::Eof))
+ while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
Lex();
// Eat EOL.
@@ -687,33 +699,32 @@ void AsmParser::eatToEndOfStatement() {
StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
- while (Lexer.isNot(AsmToken::EndOfStatement) &&
- Lexer.isNot(AsmToken::Eof))
+ while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
}
-StringRef AsmParser::ParseStringToComma() {
+StringRef AsmParser::parseStringToComma() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) &&
- Lexer.isNot(AsmToken::Comma) &&
- Lexer.isNot(AsmToken::Eof))
+ Lexer.isNot(AsmToken::Comma) && Lexer.isNot(AsmToken::Eof))
Lex();
const char *End = getTok().getLoc().getPointer();
return StringRef(Start, End - Start);
}
-/// ParseParenExpr - Parse a paren expression and return it.
+/// \brief Parse a paren expression and return it.
/// NOTE: This assumes the leading '(' has already been consumed.
///
/// parenexpr ::= expr)
///
-bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (parseExpression(Res)) return true;
+bool AsmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (parseExpression(Res))
+ return true;
if (Lexer.isNot(AsmToken::RParen))
return TokError("expected ')' in parentheses expression");
EndLoc = Lexer.getTok().getEndLoc();
@@ -721,13 +732,14 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
-/// ParseBracketExpr - Parse a bracket expression and return it.
+/// \brief Parse a bracket expression and return it.
/// NOTE: This assumes the leading '[' has already been consumed.
///
/// bracketexpr ::= expr]
///
-bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (parseExpression(Res)) return true;
+bool AsmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+ if (parseExpression(Res))
+ return true;
if (Lexer.isNot(AsmToken::RBrac))
return TokError("expected ']' in brackets expression");
EndLoc = Lexer.getTok().getEndLoc();
@@ -735,13 +747,13 @@ bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
-/// ParsePrimaryExpr - Parse a primary expression and return it.
+/// \brief Parse a primary expression and return it.
/// primaryexpr ::= (parenexpr
/// primaryexpr ::= symbol
/// primaryexpr ::= number
/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,- primaryexpr
-bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
+bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
SMLoc FirstTokenLoc = getLexer().getLoc();
AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
switch (FirstTokenKind) {
@@ -752,36 +764,54 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return true;
case AsmToken::Exclaim:
Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
+ if (parsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateLNot(Res, getContext());
return false;
case AsmToken::Dollar:
+ case AsmToken::At:
case AsmToken::String:
case AsmToken::Identifier: {
StringRef Identifier;
if (parseIdentifier(Identifier)) {
- if (FirstTokenKind == AsmToken::Dollar)
- return Error(FirstTokenLoc, "invalid token in expression");
- return true;
+ if (FirstTokenKind == AsmToken::Dollar) {
+ if (Lexer.getMAI().getDollarIsPC()) {
+ // This is a '$' reference, which references the current PC. Emit a
+ // temporary label to the streamer and refer to it.
+ MCSymbol *Sym = Ctx.CreateTempSymbol();
+ Out.EmitLabel(Sym);
+ Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+ getContext());
+ EndLoc = FirstTokenLoc;
+ return false;
+ } else
+ return Error(FirstTokenLoc, "invalid token in expression");
+ return true;
+ }
}
EndLoc = SMLoc::getFromPointer(Identifier.end());
// This is a symbol reference.
+ StringRef SymbolName = Identifier;
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
std::pair<StringRef, StringRef> Split = Identifier.split('@');
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
// Lookup the symbol variant if used.
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
if (Split.first.size() != Identifier.size()) {
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
- if (Variant == MCSymbolRefExpr::VK_Invalid) {
+ if (Variant != MCSymbolRefExpr::VK_Invalid) {
+ SymbolName = Split.first;
+ } else if (MAI.doesAllowAtInName()) {
+ Variant = MCSymbolRefExpr::VK_None;
+ } else {
Variant = MCSymbolRefExpr::VK_None;
return TokError("invalid variant '" + Split.second + "'");
}
}
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
+
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
@@ -805,11 +835,21 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
// Look for 'b' or 'f' following an Integer as a directional label
if (Lexer.getKind() == AsmToken::Identifier) {
StringRef IDVal = getTok().getString();
- if (IDVal == "f" || IDVal == "b"){
- MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
- IDVal == "f" ? 1 : 0);
- Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
- getContext());
+ // Lookup the symbol variant if used.
+ std::pair<StringRef, StringRef> Split = IDVal.split('@');
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ if (Split.first.size() != IDVal.size()) {
+ Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
+ if (Variant == MCSymbolRefExpr::VK_Invalid) {
+ Variant = MCSymbolRefExpr::VK_None;
+ return TokError("invalid variant '" + Split.second + "'");
+ }
+ IDVal = Split.first;
+ }
+ if (IDVal == "f" || IDVal == "b") {
+ MCSymbol *Sym =
+ Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "f" ? 1 : 0);
+ Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
if (IDVal == "b" && Sym->isUndefined())
return Error(Loc, "invalid reference to undefined symbol");
EndLoc = Lexer.getTok().getEndLoc();
@@ -838,27 +878,27 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
case AsmToken::LParen:
Lex(); // Eat the '('.
- return ParseParenExpr(Res, EndLoc);
+ return parseParenExpr(Res, EndLoc);
case AsmToken::LBrac:
if (!PlatformParser->HasBracketExpressions())
return TokError("brackets expression not supported on this target");
Lex(); // Eat the '['.
- return ParseBracketExpr(Res, EndLoc);
+ return parseBracketExpr(Res, EndLoc);
case AsmToken::Minus:
Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
+ if (parsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateMinus(Res, getContext());
return false;
case AsmToken::Plus:
Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
+ if (parsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreatePlus(Res, getContext());
return false;
case AsmToken::Tilde:
Lex(); // Eat the operator.
- if (ParsePrimaryExpr(Res, EndLoc))
+ if (parsePrimaryExpr(Res, EndLoc))
return true;
Res = MCUnaryExpr::CreateNot(Res, getContext());
return false;
@@ -870,13 +910,13 @@ bool AsmParser::parseExpression(const MCExpr *&Res) {
return parseExpression(Res, EndLoc);
}
-bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- return ParsePrimaryExpr(Res, EndLoc);
-}
-
const MCExpr *
-AsmParser::ApplyModifierToExpr(const MCExpr *E,
+AsmParser::applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant) {
+ // Ask the target implementation about this expression first.
+ const MCExpr *NewE = getTargetParser().applyModifierToExpr(E, Variant, Ctx);
+ if (NewE)
+ return NewE;
// Recurse over the given expression, rebuilding it to apply the given variant
// if there is exactly one symbol.
switch (E->getKind()) {
@@ -888,8 +928,8 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
if (SRE->getKind() != MCSymbolRefExpr::VK_None) {
- TokError("invalid variant on expression '" +
- getTok().getIdentifier() + "' (already modified)");
+ TokError("invalid variant on expression '" + getTok().getIdentifier() +
+ "' (already modified)");
return E;
}
@@ -898,7 +938,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
case MCExpr::Unary: {
const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
- const MCExpr *Sub = ApplyModifierToExpr(UE->getSubExpr(), Variant);
+ const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant);
if (!Sub)
return 0;
return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext());
@@ -906,14 +946,16 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
case MCExpr::Binary: {
const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
- const MCExpr *LHS = ApplyModifierToExpr(BE->getLHS(), Variant);
- const MCExpr *RHS = ApplyModifierToExpr(BE->getRHS(), Variant);
+ const MCExpr *LHS = applyModifierToExpr(BE->getLHS(), Variant);
+ const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant);
if (!LHS && !RHS)
return 0;
- if (!LHS) LHS = BE->getLHS();
- if (!RHS) RHS = BE->getRHS();
+ if (!LHS)
+ LHS = BE->getLHS();
+ if (!RHS)
+ RHS = BE->getRHS();
return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
}
@@ -922,7 +964,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
llvm_unreachable("Invalid expression kind!");
}
-/// parseExpression - Parse an expression and return it.
+/// \brief Parse an expression and return it.
///
/// expr ::= expr &&,|| expr -> lowest.
/// expr ::= expr |,^,&,! expr
@@ -935,7 +977,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
// Parse the expression.
Res = 0;
- if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
+ if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc))
return true;
// As a special case, we support 'a op b @ modifier' by rewriting the
@@ -948,11 +990,11 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
return TokError("unexpected symbol modifier following '@'");
MCSymbolRefExpr::VariantKind Variant =
- MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
+ MCSymbolRefExpr::getVariantKindForName(getTok().getIdentifier());
if (Variant == MCSymbolRefExpr::VK_Invalid)
return TokError("invalid variant '" + getTok().getIdentifier() + "'");
- const MCExpr *ModifiedRes = ApplyModifierToExpr(Res, Variant);
+ const MCExpr *ModifiedRes = applyModifierToExpr(Res, Variant);
if (!ModifiedRes) {
return TokError("invalid modifier '" + getTok().getIdentifier() +
"' (no symbols present)");
@@ -972,8 +1014,7 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
Res = 0;
- return ParseParenExpr(Res, EndLoc) ||
- ParseBinOpRHS(1, Res, EndLoc);
+ return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
}
bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
@@ -993,9 +1034,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
MCBinaryExpr::Opcode &Kind) {
switch (K) {
default:
- return 0; // not a binop.
+ return 0; // not a binop.
- // Lowest Precedence: &&, ||
+ // Lowest Precedence: &&, ||
case AsmToken::AmpAmp:
Kind = MCBinaryExpr::LAnd;
return 1;
@@ -1003,10 +1044,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
Kind = MCBinaryExpr::LOr;
return 1;
-
- // Low Precedence: |, &, ^
- //
- // FIXME: gas seems to support '!' as an infix operator?
+ // Low Precedence: |, &, ^
+ //
+ // FIXME: gas seems to support '!' as an infix operator?
case AsmToken::Pipe:
Kind = MCBinaryExpr::Or;
return 2;
@@ -1017,7 +1057,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
Kind = MCBinaryExpr::And;
return 2;
- // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
+ // Low Intermediate Precedence: ==, !=, <>, <, <=, >, >=
case AsmToken::EqualEqual:
Kind = MCBinaryExpr::EQ;
return 3;
@@ -1038,7 +1078,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
Kind = MCBinaryExpr::GTE;
return 3;
- // Intermediate Precedence: <<, >>
+ // Intermediate Precedence: <<, >>
case AsmToken::LessLess:
Kind = MCBinaryExpr::Shl;
return 4;
@@ -1046,7 +1086,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
Kind = MCBinaryExpr::Shr;
return 4;
- // High Intermediate Precedence: +, -
+ // High Intermediate Precedence: +, -
case AsmToken::Plus:
Kind = MCBinaryExpr::Add;
return 5;
@@ -1054,7 +1094,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
Kind = MCBinaryExpr::Sub;
return 5;
- // Highest Precedence: *, /, %
+ // Highest Precedence: *, /, %
case AsmToken::Star:
Kind = MCBinaryExpr::Mul;
return 6;
@@ -1067,10 +1107,9 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K,
}
}
-
-/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
+/// \brief Parse all binary operators with precedence >= 'Precedence'.
/// Res contains the LHS of the expression on input.
-bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
+bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
SMLoc &EndLoc) {
while (1) {
MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
@@ -1085,15 +1124,15 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
// Eat the next primary expression.
const MCExpr *RHS;
- if (ParsePrimaryExpr(RHS, EndLoc)) return true;
+ if (parsePrimaryExpr(RHS, EndLoc))
+ return true;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
MCBinaryExpr::Opcode Dummy;
unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
- if (TokPrec < NextTokPrec) {
- if (ParseBinOpRHS(TokPrec+1, RHS, EndLoc)) return true;
- }
+ if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
+ return true;
// Merge LHS and RHS according to operator.
Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
@@ -1104,7 +1143,7 @@ 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) {
if (Lexer.is(AsmToken::EndOfStatement)) {
Out.AddBlankLine();
Lex();
@@ -1118,7 +1157,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
int64_t LocalLabelVal = -1;
// A full line comment is a '#' as the first token.
if (Lexer.is(AsmToken::Hash))
- return ParseCppHashLineFilenameComment(IDLoc);
+ return parseCppHashLineFilenameComment(IDLoc);
// Allow an integer followed by a ':' as a directional local label.
if (Lexer.is(AsmToken::Integer)) {
@@ -1149,34 +1188,34 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// have to do this so that .endif isn't skipped in a ".if 0" block for
// example.
StringMap<DirectiveKind>::const_iterator DirKindIt =
- DirectiveKindMap.find(IDVal);
- DirectiveKind DirKind =
- (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE :
- DirKindIt->getValue();
+ DirectiveKindMap.find(IDVal);
+ DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
+ ? DK_NO_DIRECTIVE
+ : DirKindIt->getValue();
switch (DirKind) {
- default:
- break;
- case DK_IF:
- return ParseDirectiveIf(IDLoc);
- case DK_IFB:
- return ParseDirectiveIfb(IDLoc, true);
- case DK_IFNB:
- return ParseDirectiveIfb(IDLoc, false);
- case DK_IFC:
- return ParseDirectiveIfc(IDLoc, true);
- case DK_IFNC:
- return ParseDirectiveIfc(IDLoc, false);
- case DK_IFDEF:
- return ParseDirectiveIfdef(IDLoc, true);
- case DK_IFNDEF:
- case DK_IFNOTDEF:
- return ParseDirectiveIfdef(IDLoc, false);
- case DK_ELSEIF:
- return ParseDirectiveElseIf(IDLoc);
- case DK_ELSE:
- return ParseDirectiveElse(IDLoc);
- case DK_ENDIF:
- return ParseDirectiveEndIf(IDLoc);
+ default:
+ break;
+ case DK_IF:
+ return parseDirectiveIf(IDLoc);
+ case DK_IFB:
+ return parseDirectiveIfb(IDLoc, true);
+ case DK_IFNB:
+ return parseDirectiveIfb(IDLoc, false);
+ case DK_IFC:
+ return parseDirectiveIfc(IDLoc, true);
+ case DK_IFNC:
+ return parseDirectiveIfc(IDLoc, false);
+ case DK_IFDEF:
+ return parseDirectiveIfdef(IDLoc, true);
+ case DK_IFNDEF:
+ case DK_IFNOTDEF:
+ return parseDirectiveIfdef(IDLoc, false);
+ case DK_ELSEIF:
+ return parseDirectiveElseIf(IDLoc);
+ case DK_ELSE:
+ return parseDirectiveElse(IDLoc);
+ case DK_ENDIF:
+ return parseDirectiveEndIf(IDLoc);
}
// Ignore the statement if in the middle of inactive conditional
@@ -1223,6 +1262,8 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
IDLoc);
+ getTargetParser().onLabelParsed(Sym);
+
// Consume any end of statement token, if present, to avoid spurious
// AddBlankLine calls().
if (Lexer.is(AsmToken::EndOfStatement)) {
@@ -1238,24 +1279,24 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// identifier '=' ... -> assignment statement
Lex();
- return ParseAssignment(IDVal, true);
+ return parseAssignment(IDVal, true);
default: // Normal instruction or directive.
break;
}
// If macros are enabled, check to see if this is a macro instantiation.
- if (MacrosEnabled())
- if (const MCAsmMacro *M = LookupMacro(IDVal)) {
- return HandleMacroEntry(M, IDLoc);
+ if (areMacrosEnabled())
+ if (const MCAsmMacro *M = lookupMacro(IDVal)) {
+ return handleMacroEntry(M, IDLoc);
}
// Otherwise, we have a normal instruction or directive.
-
+
// Directives start with "."
if (IDVal[0] == '.' && IDVal != ".") {
// There are several entities interested in parsing directives:
- //
+ //
// 1. The target-specific assembly parser. Some directives are target
// specific or may potentially behave differently on certain targets.
// 2. Asm parser extensions. For example, platform-specific parsers
@@ -1272,185 +1313,185 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// Next, check the extention directive map to see if any extension has
// registered itself to parse this directive.
- std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
- ExtensionDirectiveMap.lookup(IDVal);
+ std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
+ ExtensionDirectiveMap.lookup(IDVal);
if (Handler.first)
return (*Handler.second)(Handler.first, IDVal, IDLoc);
// Finally, if no one else is interested in this directive, it must be
// generic and familiar to this class.
switch (DirKind) {
- default:
- break;
- case DK_SET:
- case DK_EQU:
- return ParseDirectiveSet(IDVal, true);
- case DK_EQUIV:
- return ParseDirectiveSet(IDVal, false);
- case DK_ASCII:
- return ParseDirectiveAscii(IDVal, false);
- case DK_ASCIZ:
- case DK_STRING:
- return ParseDirectiveAscii(IDVal, true);
- case DK_BYTE:
- return ParseDirectiveValue(1);
- case DK_SHORT:
- case DK_VALUE:
- case DK_2BYTE:
- return ParseDirectiveValue(2);
- case DK_LONG:
- case DK_INT:
- case DK_4BYTE:
- return ParseDirectiveValue(4);
- case DK_QUAD:
- case DK_8BYTE:
- return ParseDirectiveValue(8);
- case DK_SINGLE:
- case DK_FLOAT:
- return ParseDirectiveRealValue(APFloat::IEEEsingle);
- case DK_DOUBLE:
- return ParseDirectiveRealValue(APFloat::IEEEdouble);
- case DK_ALIGN: {
- bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
- return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1);
- }
- case DK_ALIGN32: {
- bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
- return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4);
- }
- case DK_BALIGN:
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
- case DK_BALIGNW:
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
- case DK_BALIGNL:
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
- case DK_P2ALIGN:
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
- case DK_P2ALIGNW:
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
- case DK_P2ALIGNL:
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
- case DK_ORG:
- return ParseDirectiveOrg();
- case DK_FILL:
- return ParseDirectiveFill();
- case DK_ZERO:
- return ParseDirectiveZero();
- case DK_EXTERN:
- eatToEndOfStatement(); // .extern is the default, ignore it.
- return false;
- case DK_GLOBL:
- case DK_GLOBAL:
- return ParseDirectiveSymbolAttribute(MCSA_Global);
- case DK_INDIRECT_SYMBOL:
- return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
- case DK_LAZY_REFERENCE:
- return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
- case DK_NO_DEAD_STRIP:
- return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
- case DK_SYMBOL_RESOLVER:
- return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
- case DK_PRIVATE_EXTERN:
- return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
- case DK_REFERENCE:
- return ParseDirectiveSymbolAttribute(MCSA_Reference);
- case DK_WEAK_DEFINITION:
- return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
- case DK_WEAK_REFERENCE:
- return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
- case DK_WEAK_DEF_CAN_BE_HIDDEN:
- return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
- case DK_COMM:
- case DK_COMMON:
- return ParseDirectiveComm(/*IsLocal=*/false);
- case DK_LCOMM:
- return ParseDirectiveComm(/*IsLocal=*/true);
- case DK_ABORT:
- return ParseDirectiveAbort();
- case DK_INCLUDE:
- return ParseDirectiveInclude();
- case DK_INCBIN:
- return ParseDirectiveIncbin();
- case DK_CODE16:
- case DK_CODE16GCC:
- return TokError(Twine(IDVal) + " not supported yet");
- case DK_REPT:
- return ParseDirectiveRept(IDLoc);
- case DK_IRP:
- return ParseDirectiveIrp(IDLoc);
- case DK_IRPC:
- return ParseDirectiveIrpc(IDLoc);
- case DK_ENDR:
- return ParseDirectiveEndr(IDLoc);
- case DK_BUNDLE_ALIGN_MODE:
- return ParseDirectiveBundleAlignMode();
- case DK_BUNDLE_LOCK:
- return ParseDirectiveBundleLock();
- case DK_BUNDLE_UNLOCK:
- return ParseDirectiveBundleUnlock();
- case DK_SLEB128:
- return ParseDirectiveLEB128(true);
- case DK_ULEB128:
- return ParseDirectiveLEB128(false);
- case DK_SPACE:
- case DK_SKIP:
- return ParseDirectiveSpace(IDVal);
- case DK_FILE:
- return ParseDirectiveFile(IDLoc);
- case DK_LINE:
- return ParseDirectiveLine();
- case DK_LOC:
- return ParseDirectiveLoc();
- case DK_STABS:
- return ParseDirectiveStabs();
- case DK_CFI_SECTIONS:
- return ParseDirectiveCFISections();
- case DK_CFI_STARTPROC:
- return ParseDirectiveCFIStartProc();
- case DK_CFI_ENDPROC:
- return ParseDirectiveCFIEndProc();
- case DK_CFI_DEF_CFA:
- return ParseDirectiveCFIDefCfa(IDLoc);
- case DK_CFI_DEF_CFA_OFFSET:
- return ParseDirectiveCFIDefCfaOffset();
- case DK_CFI_ADJUST_CFA_OFFSET:
- return ParseDirectiveCFIAdjustCfaOffset();
- case DK_CFI_DEF_CFA_REGISTER:
- return ParseDirectiveCFIDefCfaRegister(IDLoc);
- case DK_CFI_OFFSET:
- return ParseDirectiveCFIOffset(IDLoc);
- case DK_CFI_REL_OFFSET:
- return ParseDirectiveCFIRelOffset(IDLoc);
- case DK_CFI_PERSONALITY:
- return ParseDirectiveCFIPersonalityOrLsda(true);
- case DK_CFI_LSDA:
- return ParseDirectiveCFIPersonalityOrLsda(false);
- case DK_CFI_REMEMBER_STATE:
- return ParseDirectiveCFIRememberState();
- case DK_CFI_RESTORE_STATE:
- return ParseDirectiveCFIRestoreState();
- case DK_CFI_SAME_VALUE:
- return ParseDirectiveCFISameValue(IDLoc);
- case DK_CFI_RESTORE:
- return ParseDirectiveCFIRestore(IDLoc);
- case DK_CFI_ESCAPE:
- return ParseDirectiveCFIEscape();
- case DK_CFI_SIGNAL_FRAME:
- return ParseDirectiveCFISignalFrame();
- case DK_CFI_UNDEFINED:
- return ParseDirectiveCFIUndefined(IDLoc);
- case DK_CFI_REGISTER:
- return ParseDirectiveCFIRegister(IDLoc);
- case DK_MACROS_ON:
- case DK_MACROS_OFF:
- return ParseDirectiveMacrosOnOff(IDVal);
- case DK_MACRO:
- return ParseDirectiveMacro(IDLoc);
- case DK_ENDM:
- case DK_ENDMACRO:
- return ParseDirectiveEndMacro(IDVal);
- case DK_PURGEM:
- return ParseDirectivePurgeMacro(IDLoc);
+ default:
+ break;
+ case DK_SET:
+ case DK_EQU:
+ return parseDirectiveSet(IDVal, true);
+ case DK_EQUIV:
+ return parseDirectiveSet(IDVal, false);
+ case DK_ASCII:
+ return parseDirectiveAscii(IDVal, false);
+ case DK_ASCIZ:
+ case DK_STRING:
+ return parseDirectiveAscii(IDVal, true);
+ case DK_BYTE:
+ return parseDirectiveValue(1);
+ case DK_SHORT:
+ case DK_VALUE:
+ case DK_2BYTE:
+ return parseDirectiveValue(2);
+ case DK_LONG:
+ case DK_INT:
+ case DK_4BYTE:
+ return parseDirectiveValue(4);
+ case DK_QUAD:
+ case DK_8BYTE:
+ return parseDirectiveValue(8);
+ case DK_SINGLE:
+ case DK_FLOAT:
+ return parseDirectiveRealValue(APFloat::IEEEsingle);
+ case DK_DOUBLE:
+ return parseDirectiveRealValue(APFloat::IEEEdouble);
+ case DK_ALIGN: {
+ bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
+ return parseDirectiveAlign(IsPow2, /*ExprSize=*/1);
+ }
+ case DK_ALIGN32: {
+ bool IsPow2 = !getContext().getAsmInfo()->getAlignmentIsInBytes();
+ return parseDirectiveAlign(IsPow2, /*ExprSize=*/4);
+ }
+ case DK_BALIGN:
+ return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
+ case DK_BALIGNW:
+ return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
+ case DK_BALIGNL:
+ return parseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
+ case DK_P2ALIGN:
+ return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ case DK_P2ALIGNW:
+ return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
+ case DK_P2ALIGNL:
+ return parseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+ case DK_ORG:
+ return parseDirectiveOrg();
+ case DK_FILL:
+ return parseDirectiveFill();
+ case DK_ZERO:
+ return parseDirectiveZero();
+ case DK_EXTERN:
+ eatToEndOfStatement(); // .extern is the default, ignore it.
+ return false;
+ case DK_GLOBL:
+ case DK_GLOBAL:
+ return parseDirectiveSymbolAttribute(MCSA_Global);
+ case DK_LAZY_REFERENCE:
+ return parseDirectiveSymbolAttribute(MCSA_LazyReference);
+ case DK_NO_DEAD_STRIP:
+ return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
+ case DK_SYMBOL_RESOLVER:
+ return parseDirectiveSymbolAttribute(MCSA_SymbolResolver);
+ case DK_PRIVATE_EXTERN:
+ return parseDirectiveSymbolAttribute(MCSA_PrivateExtern);
+ case DK_REFERENCE:
+ return parseDirectiveSymbolAttribute(MCSA_Reference);
+ case DK_WEAK_DEFINITION:
+ return parseDirectiveSymbolAttribute(MCSA_WeakDefinition);
+ case DK_WEAK_REFERENCE:
+ return parseDirectiveSymbolAttribute(MCSA_WeakReference);
+ case DK_WEAK_DEF_CAN_BE_HIDDEN:
+ return parseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
+ case DK_COMM:
+ case DK_COMMON:
+ return parseDirectiveComm(/*IsLocal=*/false);
+ case DK_LCOMM:
+ return parseDirectiveComm(/*IsLocal=*/true);
+ case DK_ABORT:
+ return parseDirectiveAbort();
+ case DK_INCLUDE:
+ return parseDirectiveInclude();
+ case DK_INCBIN:
+ return parseDirectiveIncbin();
+ case DK_CODE16:
+ case DK_CODE16GCC:
+ return TokError(Twine(IDVal) + " not supported yet");
+ case DK_REPT:
+ return parseDirectiveRept(IDLoc);
+ case DK_IRP:
+ return parseDirectiveIrp(IDLoc);
+ case DK_IRPC:
+ return parseDirectiveIrpc(IDLoc);
+ case DK_ENDR:
+ return parseDirectiveEndr(IDLoc);
+ case DK_BUNDLE_ALIGN_MODE:
+ return parseDirectiveBundleAlignMode();
+ case DK_BUNDLE_LOCK:
+ return parseDirectiveBundleLock();
+ case DK_BUNDLE_UNLOCK:
+ return parseDirectiveBundleUnlock();
+ case DK_SLEB128:
+ return parseDirectiveLEB128(true);
+ case DK_ULEB128:
+ return parseDirectiveLEB128(false);
+ case DK_SPACE:
+ case DK_SKIP:
+ return parseDirectiveSpace(IDVal);
+ case DK_FILE:
+ return parseDirectiveFile(IDLoc);
+ case DK_LINE:
+ return parseDirectiveLine();
+ case DK_LOC:
+ return parseDirectiveLoc();
+ case DK_STABS:
+ return parseDirectiveStabs();
+ case DK_CFI_SECTIONS:
+ return parseDirectiveCFISections();
+ case DK_CFI_STARTPROC:
+ return parseDirectiveCFIStartProc();
+ case DK_CFI_ENDPROC:
+ return parseDirectiveCFIEndProc();
+ case DK_CFI_DEF_CFA:
+ return parseDirectiveCFIDefCfa(IDLoc);
+ case DK_CFI_DEF_CFA_OFFSET:
+ return parseDirectiveCFIDefCfaOffset();
+ case DK_CFI_ADJUST_CFA_OFFSET:
+ return parseDirectiveCFIAdjustCfaOffset();
+ case DK_CFI_DEF_CFA_REGISTER:
+ return parseDirectiveCFIDefCfaRegister(IDLoc);
+ case DK_CFI_OFFSET:
+ return parseDirectiveCFIOffset(IDLoc);
+ case DK_CFI_REL_OFFSET:
+ return parseDirectiveCFIRelOffset(IDLoc);
+ case DK_CFI_PERSONALITY:
+ return parseDirectiveCFIPersonalityOrLsda(true);
+ case DK_CFI_LSDA:
+ return parseDirectiveCFIPersonalityOrLsda(false);
+ case DK_CFI_REMEMBER_STATE:
+ return parseDirectiveCFIRememberState();
+ case DK_CFI_RESTORE_STATE:
+ return parseDirectiveCFIRestoreState();
+ case DK_CFI_SAME_VALUE:
+ return parseDirectiveCFISameValue(IDLoc);
+ case DK_CFI_RESTORE:
+ return parseDirectiveCFIRestore(IDLoc);
+ case DK_CFI_ESCAPE:
+ return parseDirectiveCFIEscape();
+ case DK_CFI_SIGNAL_FRAME:
+ return parseDirectiveCFISignalFrame();
+ case DK_CFI_UNDEFINED:
+ return parseDirectiveCFIUndefined(IDLoc);
+ case DK_CFI_REGISTER:
+ return parseDirectiveCFIRegister(IDLoc);
+ case DK_CFI_WINDOW_SAVE:
+ return parseDirectiveCFIWindowSave();
+ case DK_MACROS_ON:
+ case DK_MACROS_OFF:
+ return parseDirectiveMacrosOnOff(IDVal);
+ case DK_MACRO:
+ return parseDirectiveMacro(IDLoc);
+ case DK_ENDM:
+ case DK_ENDMACRO:
+ return parseDirectiveEndMacro(IDVal);
+ case DK_PURGEM:
+ return parseDirectivePurgeMacro(IDLoc);
}
return Error(IDLoc, "unknown directive");
@@ -1459,19 +1500,19 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// __asm _emit or __asm __emit
if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
IDVal == "_EMIT" || IDVal == "__EMIT"))
- return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size());
+ return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
// __asm align
if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
- return ParseDirectiveMSAlign(IDLoc, Info);
+ return parseDirectiveMSAlign(IDLoc, Info);
checkForValidSection();
// Canonicalize the opcode to lower case.
std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
- IDLoc, Info.ParsedOperands);
+ bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, IDLoc,
+ Info.ParsedOperands);
Info.ParseError = HadError;
// Dump the parsed representation, if requested.
@@ -1486,7 +1527,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
}
OS << "]";
- PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str());
+ printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
}
// If we are generating dwarf for assembly source files and the current
@@ -1494,38 +1535,49 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// the instruction.
if (!HadError && getContext().getGenDwarfForAssembly() &&
getContext().getGenDwarfSection() ==
- getStreamer().getCurrentSection().first) {
+ getStreamer().getCurrentSection().first) {
unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
// If we previously parsed a cpp hash file line comment then make sure the
// current Dwarf File is for the CppHashFilename if not then emit the
// Dwarf File table for it and adjust the line number for the .loc.
- const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
- getContext().getMCDwarfFiles();
+ const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
+ getContext().getMCDwarfFiles();
if (CppHashFilename.size() != 0) {
if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() !=
CppHashFilename)
getStreamer().EmitDwarfFileDirective(
- getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename);
-
- unsigned CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc,CppHashBuf);
- Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
+ getContext().nextGenDwarfFileNumber(), StringRef(),
+ CppHashFilename);
+
+ // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's
+ // cache with the different Loc from the call above we save the last
+ // info we queried here with SrcMgr.FindLineNumber().
+ unsigned CppHashLocLineNo;
+ if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf)
+ CppHashLocLineNo = LastQueryLine;
+ else {
+ CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf);
+ LastQueryLine = CppHashLocLineNo;
+ LastQueryIDLoc = CppHashLoc;
+ LastQueryBuffer = CppHashBuf;
+ }
+ Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
}
- getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(),
- Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ?
- DWARF2_FLAG_IS_STMT : 0, 0, 0,
- StringRef());
+ getStreamer().EmitDwarfLocDirective(
+ getContext().getGenDwarfFileNumber(), Line, 0,
+ DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
+ StringRef());
}
// If parsing succeeded, match the instruction.
if (!HadError) {
unsigned ErrorInfo;
- HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode,
- Info.ParsedOperands,
- Out, ErrorInfo,
- ParsingInlineAsm);
+ HadError = getTargetParser().MatchAndEmitInstruction(
+ IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
+ ParsingInlineAsm);
}
// Don't skip the rest of the line, the instruction parser is responsible for
@@ -1533,25 +1585,25 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return false;
}
-/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line
+/// eatToEndOfLine uses the Lexer to eat the characters to the end of the line
/// since they may not be able to be tokenized to get to the end of line token.
-void AsmParser::EatToEndOfLine() {
+void AsmParser::eatToEndOfLine() {
if (!Lexer.is(AsmToken::EndOfStatement))
Lexer.LexUntilEndOfLine();
- // Eat EOL.
- Lex();
+ // Eat EOL.
+ Lex();
}
-/// ParseCppHashLineFilenameComment as this:
+/// parseCppHashLineFilenameComment as this:
/// ::= # number "filename"
/// or just as a full line comment if it doesn't have a number and a string.
-bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
+bool AsmParser::parseCppHashLineFilenameComment(const SMLoc &L) {
Lex(); // Eat the hash token.
if (getLexer().isNot(AsmToken::Integer)) {
// Consume the line since in cases it is not a well-formed line directive,
// as if were simply a full line comment.
- EatToEndOfLine();
+ eatToEndOfLine();
return false;
}
@@ -1559,13 +1611,13 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
Lex();
if (getLexer().isNot(AsmToken::String)) {
- EatToEndOfLine();
+ eatToEndOfLine();
return false;
}
StringRef Filename = getTok().getString();
// Get rid of the enclosing quotes.
- Filename = Filename.substr(1, Filename.size()-2);
+ Filename = Filename.substr(1, Filename.size() - 2);
// Save the SMLoc, Filename and LineNumber for later use by diagnostics.
CppHashLoc = L;
@@ -1574,14 +1626,14 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) {
CppHashBuf = CurBuffer;
// Ignore any trailing characters, they're just comment.
- EatToEndOfLine();
+ eatToEndOfLine();
return false;
}
-/// DiagHandler - will use the last parsed cpp hash line filename comment
+/// \brief will use the last parsed cpp hash line filename comment
/// for the Filename and LineNo if any in the diagnostic.
void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
- const AsmParser *Parser = static_cast<const AsmParser*>(Context);
+ const AsmParser *Parser = static_cast<const AsmParser *>(Context);
raw_ostream &OS = errs();
const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
@@ -1589,19 +1641,18 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
- // Like SourceMgr::PrintMessage() we need to print the include stack if any
+ // Like SourceMgr::printMessage() we need to print the include stack if any
// before printing the message.
int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) {
- SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
- DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
+ SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
+ DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
}
// If we have not parsed a cpp hash line filename comment or the source
// manager changed or buffer changed (like in a nested include) then just
// print the normal diagnostic using its Filename and LineNo.
- if (!Parser->CppHashLineNumber ||
- &DiagSrcMgr != &Parser->SrcMgr ||
+ if (!Parser->CppHashLineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
DiagBuf != CppHashBuf) {
if (Parser->SavedDiagHandler)
Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
@@ -1613,17 +1664,16 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// Use the CppHashFilename and calculate a line number based on the
// CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
// the diagnostic.
- const std::string Filename = Parser->CppHashFilename;
+ const std::string &Filename = Parser->CppHashFilename;
int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
int CppHashLocLineNo =
Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
- int LineNo = Parser->CppHashLineNumber - 1 +
- (DiagLocLineNo - CppHashLocLineNo);
+ int LineNo =
+ Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
- SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(),
- Filename, LineNo, Diag.getColumnNo(),
- Diag.getKind(), Diag.getMessage(),
+ SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
+ Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
Diag.getLineContents(), Diag.getRanges());
if (Parser->SavedDiagHandler)
@@ -1643,8 +1693,7 @@ static bool isIdentifierChar(char c) {
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
const MCAsmMacroParameters &Parameters,
- const MCAsmMacroArguments &A,
- const SMLoc &L) {
+ const MCAsmMacroArguments &A, const SMLoc &L) {
unsigned NParameters = Parameters.size();
if (NParameters != 0 && NParameters != A.size())
return Error(L, "Wrong number of arguments");
@@ -1680,27 +1729,28 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
break;
if (!NParameters) {
- switch (Body[Pos+1]) {
- // $$ => $
+ switch (Body[Pos + 1]) {
+ // $$ => $
case '$':
OS << '$';
break;
- // $n => number of arguments
+ // $n => number of arguments
case 'n':
OS << A.size();
break;
- // $[0-9] => argument
+ // $[0-9] => argument
default: {
// Missing arguments are ignored.
- unsigned Index = Body[Pos+1] - '0';
+ unsigned Index = Body[Pos + 1] - '0';
if (Index >= A.size())
break;
// Otherwise substitute with the token values, with spaces eliminated.
for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
- ie = A[Index].end(); it != ie; ++it)
+ ie = A[Index].end();
+ it != ie; ++it)
OS << it->getString();
break;
}
@@ -1711,23 +1761,24 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
while (isIdentifierChar(Body[I]) && I + 1 != End)
++I;
- const char *Begin = Body.data() + Pos +1;
- StringRef Argument(Begin, I - (Pos +1));
+ const char *Begin = Body.data() + Pos + 1;
+ StringRef Argument(Begin, I - (Pos + 1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
if (Parameters[Index].first == Argument)
break;
if (Index == NParameters) {
- if (Body[Pos+1] == '(' && Body[Pos+2] == ')')
- Pos += 3;
- else {
- OS << '\\' << Argument;
- Pos = I;
- }
+ if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
+ Pos += 3;
+ else {
+ OS << '\\' << Argument;
+ Pos = I;
+ }
} else {
for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
- ie = A[Index].end(); it != ie; ++it)
+ ie = A[Index].end();
+ it != ie; ++it)
if (it->getKind() == AsmToken::String)
OS << it->getStringContents();
else
@@ -1743,48 +1794,43 @@ 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(const MCAsmMacro *M, SMLoc IL, int EB,
+ SMLoc EL, MemoryBuffer *I)
+ : TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB),
+ ExitLoc(EL) {}
-static bool IsOperator(AsmToken::TokenKind kind)
-{
- switch (kind)
- {
- default:
- return false;
- case AsmToken::Plus:
- case AsmToken::Minus:
- case AsmToken::Tilde:
- case AsmToken::Slash:
- case AsmToken::Star:
- case AsmToken::Dot:
- case AsmToken::Equal:
- case AsmToken::EqualEqual:
- case AsmToken::Pipe:
- case AsmToken::PipePipe:
- case AsmToken::Caret:
- case AsmToken::Amp:
- case AsmToken::AmpAmp:
- case AsmToken::Exclaim:
- case AsmToken::ExclaimEqual:
- case AsmToken::Percent:
- case AsmToken::Less:
- case AsmToken::LessEqual:
- case AsmToken::LessLess:
- case AsmToken::LessGreater:
- case AsmToken::Greater:
- case AsmToken::GreaterEqual:
- case AsmToken::GreaterGreater:
- return true;
+static bool isOperator(AsmToken::TokenKind kind) {
+ switch (kind) {
+ default:
+ return false;
+ case AsmToken::Plus:
+ case AsmToken::Minus:
+ case AsmToken::Tilde:
+ case AsmToken::Slash:
+ case AsmToken::Star:
+ case AsmToken::Dot:
+ case AsmToken::Equal:
+ case AsmToken::EqualEqual:
+ case AsmToken::Pipe:
+ case AsmToken::PipePipe:
+ case AsmToken::Caret:
+ case AsmToken::Amp:
+ case AsmToken::AmpAmp:
+ case AsmToken::Exclaim:
+ case AsmToken::ExclaimEqual:
+ case AsmToken::Percent:
+ case AsmToken::Less:
+ case AsmToken::LessEqual:
+ case AsmToken::LessLess:
+ case AsmToken::LessGreater:
+ case AsmToken::Greater:
+ case AsmToken::GreaterEqual:
+ case AsmToken::GreaterGreater:
+ return true;
}
}
-bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA,
+bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA,
AsmToken::TokenKind &ArgumentDelimiter) {
unsigned ParenLevel = 0;
unsigned AddTokens = 0;
@@ -1818,7 +1864,7 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA,
// one into this argument
if (ArgumentDelimiter == AsmToken::Space ||
ArgumentDelimiter == AsmToken::Eof) {
- if (IsOperator(Lexer.getKind())) {
+ if (isOperator(Lexer.getKind())) {
// Check to see whether the token is used as an operator,
// or part of an identifier
const char *NextChar = getTok().getEndLoc().getPointer();
@@ -1828,14 +1874,14 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA,
if (!AddTokens && ParenLevel == 0) {
if (ArgumentDelimiter == AsmToken::Eof &&
- !IsOperator(Lexer.getKind()))
+ !isOperator(Lexer.getKind()))
ArgumentDelimiter = AsmToken::Space;
break;
}
}
}
- // HandleMacroEntry relies on not advancing the lexer here
+ // handleMacroEntry relies on not advancing the lexer here
// to be able to fill in the remaining default parameter values
if (Lexer.is(AsmToken::EndOfStatement))
break;
@@ -1860,10 +1906,11 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &MA,
}
// Parse the macro instantiation arguments.
-bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) {
+bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
+ MCAsmMacroArguments &A) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
// Argument delimiter is initially unknown. It will be set by
- // ParseMacroArgument()
+ // parseMacroArgument()
AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
// Parse two kinds of macro invocations:
@@ -1873,7 +1920,7 @@ bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A)
++Parameter) {
MCAsmMacroArgument MA;
- if (ParseMacroArgument(MA, ArgumentDelimiter))
+ if (parseMacroArgument(MA, ArgumentDelimiter))
return true;
if (!MA.empty() || !NParameters)
@@ -1904,31 +1951,31 @@ bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A)
return TokError("Too many arguments");
}
-const MCAsmMacro* AsmParser::LookupMacro(StringRef Name) {
- StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) {
+ StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name);
return (I == MacroMap.end()) ? NULL : I->getValue();
}
-void AsmParser::DefineMacro(StringRef Name, const MCAsmMacro& Macro) {
+void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) {
MacroMap[Name] = new MCAsmMacro(Macro);
}
-void AsmParser::UndefineMacro(StringRef Name) {
- StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+void AsmParser::undefineMacro(StringRef Name) {
+ StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name);
if (I != MacroMap.end()) {
delete I->getValue();
MacroMap.erase(I);
}
}
-bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
+bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
// this, although we should protect against infinite loops.
if (ActiveMacros.size() == 20)
return TokError("macros cannot be nested more than 20 levels deep");
MCAsmMacroArguments A;
- if (ParseMacroArguments(M, A))
+ if (parseMacroArguments(M, A))
return true;
// Remove any trailing empty arguments. Do this after-the-fact as we have
@@ -1951,14 +1998,12 @@ bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
OS << ".endmacro\n";
MemoryBuffer *Instantiation =
- MemoryBuffer::getMemBufferCopy(OS.str(), "<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);
+ MacroInstantiation *MI = new MacroInstantiation(
+ M, NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
@@ -1969,9 +2014,9 @@ bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
return false;
}
-void AsmParser::HandleMacroExit() {
+void AsmParser::handleMacroExit() {
// Jump to the EndOfStatement we should return to, and consume it.
- JumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
+ jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer);
Lex();
// Pop the instantiation entry.
@@ -1979,29 +2024,30 @@ void AsmParser::HandleMacroExit() {
ActiveMacros.pop_back();
}
-static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
+static bool isUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
switch (Value->getKind()) {
case MCExpr::Binary: {
- const MCBinaryExpr *BE = static_cast<const MCBinaryExpr*>(Value);
- return IsUsedIn(Sym, BE->getLHS()) || IsUsedIn(Sym, BE->getRHS());
+ const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(Value);
+ return isUsedIn(Sym, BE->getLHS()) || isUsedIn(Sym, BE->getRHS());
}
case MCExpr::Target:
case MCExpr::Constant:
return false;
case MCExpr::SymbolRef: {
- const MCSymbol &S = static_cast<const MCSymbolRefExpr*>(Value)->getSymbol();
+ const MCSymbol &S =
+ static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
if (S.isVariable())
- return IsUsedIn(Sym, S.getVariableValue());
+ return isUsedIn(Sym, S.getVariableValue());
return &S == Sym;
}
case MCExpr::Unary:
- return IsUsedIn(Sym, static_cast<const MCUnaryExpr*>(Value)->getSubExpr());
+ return isUsedIn(Sym, static_cast<const MCUnaryExpr *>(Value)->getSubExpr());
}
llvm_unreachable("Unknown expr kind!");
}
-bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
+bool AsmParser::parseAssignment(StringRef Name, bool allow_redef,
bool NoDeadStrip) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Lexer.getLoc();
@@ -2034,7 +2080,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
//
// FIXME: Diagnostics. Note the location of the definition as a label.
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
- if (IsUsedIn(Sym, Value))
+ if (isUsedIn(Sym, Value))
return Error(EqualLoc, "Recursive use of '" + Name + "'");
else if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
@@ -2046,7 +2092,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
return Error(EqualLoc, "invalid assignment to '" + Name + "'");
else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
- Name + "'");
+ Name + "'");
// Don't count these checks as uses.
Sym->setUsed(false);
@@ -2060,7 +2106,6 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
if (NoDeadStrip)
Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip);
-
return false;
}
@@ -2069,31 +2114,30 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
/// ::= string
bool AsmParser::parseIdentifier(StringRef &Res) {
// The assembler has relaxed rules for accepting identifiers, in particular we
- // allow things like '.globl $foo', which would normally be separate
- // tokens. At this level, we have already lexed so we cannot (currently)
+ // allow things like '.globl $foo' and '.def @feat.00', which would normally be
+ // separate tokens. At this level, we have already lexed so we cannot (currently)
// handle this as a context dependent token, instead we detect adjacent tokens
// and return the combined identifier.
- if (Lexer.is(AsmToken::Dollar)) {
- SMLoc DollarLoc = getLexer().getLoc();
+ if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
+ SMLoc PrefixLoc = getLexer().getLoc();
- // Consume the dollar sign, and check for a following identifier.
+ // Consume the prefix character, and check for a following identifier.
Lex();
if (Lexer.isNot(AsmToken::Identifier))
return true;
- // We have a '$' followed by an identifier, make sure they are adjacent.
- if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
+ // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
+ if (PrefixLoc.getPointer() + 1 != getTok().getLoc().getPointer())
return true;
// Construct the joined identifier and consume the token.
- Res = StringRef(DollarLoc.getPointer(),
- getTok().getIdentifier().size() + 1);
+ Res =
+ StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
Lex();
return false;
}
- if (Lexer.isNot(AsmToken::Identifier) &&
- Lexer.isNot(AsmToken::String))
+ if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
return true;
Res = getTok().getIdentifier();
@@ -2103,11 +2147,11 @@ bool AsmParser::parseIdentifier(StringRef &Res) {
return false;
}
-/// ParseDirectiveSet:
+/// parseDirectiveSet:
/// ::= .equ identifier ',' expression
/// ::= .equiv identifier ',' expression
/// ::= .set identifier ',' expression
-bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
+bool AsmParser::parseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
if (parseIdentifier(Name))
@@ -2117,7 +2161,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
return TokError("unexpected token in '" + Twine(IDVal) + "'");
Lex();
- return ParseAssignment(Name, allow_redef, true);
+ return parseAssignment(Name, allow_redef, true);
}
bool AsmParser::parseEscapedString(std::string &Data) {
@@ -2138,15 +2182,15 @@ bool AsmParser::parseEscapedString(std::string &Data) {
return TokError("unexpected backslash at end of string");
// Recognize octal sequences.
- if ((unsigned) (Str[i] - '0') <= 7) {
+ if ((unsigned)(Str[i] - '0') <= 7) {
// Consume up to three octal characters.
unsigned Value = Str[i] - '0';
- if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
+ if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
++i;
Value = Value * 8 + (Str[i] - '0');
- if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
+ if (i + 1 != e && ((unsigned)(Str[i + 1] - '0')) <= 7) {
++i;
Value = Value * 8 + (Str[i] - '0');
}
@@ -2155,7 +2199,7 @@ bool AsmParser::parseEscapedString(std::string &Data) {
if (Value > 255)
return TokError("invalid octal escape sequence (out of range)");
- Data += (unsigned char) Value;
+ Data += (unsigned char)Value;
continue;
}
@@ -2178,9 +2222,9 @@ bool AsmParser::parseEscapedString(std::string &Data) {
return false;
}
-/// ParseDirectiveAscii:
+/// parseDirectiveAscii:
/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
-bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
+bool AsmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
checkForValidSection();
@@ -2192,9 +2236,9 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
if (parseEscapedString(Data))
return true;
- getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
+ getStreamer().EmitBytes(Data);
if (ZeroTerminated)
- getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
+ getStreamer().EmitBytes(StringRef("\0", 1));
Lex();
@@ -2211,9 +2255,9 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
return false;
}
-/// ParseDirectiveValue
+/// parseDirectiveValue
/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
-bool AsmParser::ParseDirectiveValue(unsigned Size) {
+bool AsmParser::parseDirectiveValue(unsigned Size) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
checkForValidSection();
@@ -2229,9 +2273,9 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
uint64_t IntValue = MCE->getValue();
if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
return Error(ExprLoc, "literal value out of range for directive");
- getStreamer().EmitIntValue(IntValue, Size, DEFAULT_ADDRSPACE);
+ getStreamer().EmitIntValue(IntValue, Size);
} else
- getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
+ getStreamer().EmitValue(Value, Size);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -2247,9 +2291,9 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
return false;
}
-/// ParseDirectiveRealValue
+/// parseDirectiveRealValue
/// ::= (.single | .double) [ expression (, expression)* ]
-bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
+bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
checkForValidSection();
@@ -2279,7 +2323,7 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
else
return TokError("invalid floating point literal");
} else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
- APFloat::opInvalidOp)
+ APFloat::opInvalidOp)
return TokError("invalid floating point literal");
if (IsNeg)
Value.changeSign();
@@ -2290,7 +2334,7 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
// Emit the value as an integer.
APInt AsInt = Value.bitcastToAPInt();
getStreamer().EmitIntValue(AsInt.getLimitedValue(),
- AsInt.getBitWidth() / 8, DEFAULT_ADDRSPACE);
+ AsInt.getBitWidth() / 8);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -2305,9 +2349,9 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
return false;
}
-/// ParseDirectiveZero
+/// parseDirectiveZero
/// ::= .zero expression
-bool AsmParser::ParseDirectiveZero() {
+bool AsmParser::parseDirectiveZero() {
checkForValidSection();
int64_t NumBytes;
@@ -2326,53 +2370,58 @@ bool AsmParser::ParseDirectiveZero() {
Lex();
- getStreamer().EmitFill(NumBytes, Val, DEFAULT_ADDRSPACE);
+ getStreamer().EmitFill(NumBytes, Val);
return false;
}
-/// ParseDirectiveFill
-/// ::= .fill expression , expression , expression
-bool AsmParser::ParseDirectiveFill() {
+/// parseDirectiveFill
+/// ::= .fill expression [ , expression [ , expression ] ]
+bool AsmParser::parseDirectiveFill() {
checkForValidSection();
int64_t NumValues;
if (parseAbsoluteExpression(NumValues))
return true;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
+ int64_t FillSize = 1;
+ int64_t FillExpr = 0;
- int64_t FillSize;
- if (parseAbsoluteExpression(FillSize))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.fill' directive");
- Lex();
+ if (parseAbsoluteExpression(FillSize))
+ return true;
- int64_t FillExpr;
- if (parseAbsoluteExpression(FillExpr))
- return true;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lex();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.fill' directive");
+ if (parseAbsoluteExpression(FillExpr))
+ return true;
- Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.fill' directive");
+
+ Lex();
+ }
+ }
if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
for (uint64_t i = 0, e = NumValues; i != e; ++i)
- getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
+ getStreamer().EmitIntValue(FillExpr, FillSize);
return false;
}
-/// ParseDirectiveOrg
+/// parseDirectiveOrg
/// ::= .org expression [ , expression ]
-bool AsmParser::ParseDirectiveOrg() {
+bool AsmParser::parseDirectiveOrg() {
checkForValidSection();
const MCExpr *Offset;
@@ -2405,9 +2454,9 @@ bool AsmParser::ParseDirectiveOrg() {
return false;
}
-/// ParseDirectiveAlign
+/// parseDirectiveAlign
/// ::= {.align, ...} expression [ , expression [ , expression ]]
-bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
+bool AsmParser::parseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
checkForValidSection();
SMLoc AlignmentLoc = getLexer().getLoc();
@@ -2471,13 +2520,13 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
if (MaxBytesLoc.isValid()) {
if (MaxBytesToFill < 1) {
Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
- "many bytes, ignoring maximum bytes expression");
+ "many bytes, ignoring maximum bytes expression");
MaxBytesToFill = 0;
}
if (MaxBytesToFill >= Alignment) {
Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
- "has no effect");
+ "has no effect");
MaxBytesToFill = 0;
}
}
@@ -2497,10 +2546,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
return false;
}
-/// ParseDirectiveFile
+/// parseDirectiveFile
/// ::= .file [number] filename
/// ::= .file number directory filename
-bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
// FIXME: I'm not sure what this is.
int64_t FileNumber = -1;
SMLoc FileNumberLoc = getLexer().getLoc();
@@ -2516,17 +2565,21 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
return TokError("unexpected token in '.file' directive");
// Usually the directory and filename together, otherwise just the directory.
- StringRef Path = getTok().getString();
- Path = Path.substr(1, Path.size()-2);
+ // Allow the strings to have escaped octal character sequence.
+ std::string Path = getTok().getString();
+ if (parseEscapedString(Path))
+ return true;
Lex();
StringRef Directory;
StringRef Filename;
+ std::string FilenameData;
if (getLexer().is(AsmToken::String)) {
if (FileNumber == -1)
return TokError("explicit path specified, but no file number");
- Filename = getTok().getString();
- Filename = Filename.substr(1, Filename.size()-2);
+ if (parseEscapedString(FilenameData))
+ return true;
+ Filename = FilenameData;
Directory = Path;
Lex();
} else {
@@ -2540,8 +2593,9 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
getStreamer().EmitFileDirective(Filename);
else {
if (getContext().getGenDwarfForAssembly() == true)
- Error(DirectiveLoc, "input can't have .file dwarf directives when -g is "
- "used to generate dwarf debug info for assembly code");
+ Error(DirectiveLoc,
+ "input can't have .file dwarf directives when -g is "
+ "used to generate dwarf debug info for assembly code");
if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename))
Error(FileNumberLoc, "file number already allocated");
@@ -2550,15 +2604,15 @@ bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveLine
+/// parseDirectiveLine
/// ::= .line [number]
-bool AsmParser::ParseDirectiveLine() {
+bool AsmParser::parseDirectiveLine() {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getLexer().isNot(AsmToken::Integer))
return TokError("unexpected token in '.line' directive");
int64_t LineNumber = getTok().getIntVal();
- (void) LineNumber;
+ (void)LineNumber;
Lex();
// FIXME: Do something with the .line.
@@ -2570,14 +2624,14 @@ bool AsmParser::ParseDirectiveLine() {
return false;
}
-/// ParseDirectiveLoc
+/// parseDirectiveLoc
/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
/// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
/// The first number is a file number, must have been previously assigned with
/// a .file directive, the second number is the line number and optionally the
/// third number is a column position (zero if not specified). The remaining
/// optional items are .loc sub-directives.
-bool AsmParser::ParseDirectiveLoc() {
+bool AsmParser::parseDirectiveLoc() {
if (getLexer().isNot(AsmToken::Integer))
return TokError("unexpected token in '.loc' directive");
int64_t FileNumber = getTok().getIntVal();
@@ -2590,8 +2644,8 @@ bool AsmParser::ParseDirectiveLoc() {
int64_t LineNumber = 0;
if (getLexer().is(AsmToken::Integer)) {
LineNumber = getTok().getIntVal();
- if (LineNumber < 1)
- return TokError("line number less than one in '.loc' directive");
+ if (LineNumber < 0)
+ return TokError("line number less than zero in '.loc' directive");
Lex();
}
@@ -2671,15 +2725,15 @@ bool AsmParser::ParseDirectiveLoc() {
return false;
}
-/// ParseDirectiveStabs
+/// parseDirectiveStabs
/// ::= .stabs string, number, number, number
-bool AsmParser::ParseDirectiveStabs() {
+bool AsmParser::parseDirectiveStabs() {
return TokError("unsupported directive '.stabs'");
}
-/// ParseDirectiveCFISections
+/// parseDirectiveCFISections
/// ::= .cfi_sections section [, section]
-bool AsmParser::ParseDirectiveCFISections() {
+bool AsmParser::parseDirectiveCFISections() {
StringRef Name;
bool EH = false;
bool Debug = false;
@@ -2708,40 +2762,40 @@ bool AsmParser::ParseDirectiveCFISections() {
return false;
}
-/// ParseDirectiveCFIStartProc
+/// parseDirectiveCFIStartProc
/// ::= .cfi_startproc
-bool AsmParser::ParseDirectiveCFIStartProc() {
+bool AsmParser::parseDirectiveCFIStartProc() {
getStreamer().EmitCFIStartProc();
return false;
}
-/// ParseDirectiveCFIEndProc
+/// parseDirectiveCFIEndProc
/// ::= .cfi_endproc
-bool AsmParser::ParseDirectiveCFIEndProc() {
+bool AsmParser::parseDirectiveCFIEndProc() {
getStreamer().EmitCFIEndProc();
return false;
}
-/// ParseRegisterOrRegisterNumber - parse register name or number.
-bool AsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
+/// \brief parse register name or number.
+bool AsmParser::parseRegisterOrRegisterNumber(int64_t &Register,
SMLoc DirectiveLoc) {
unsigned RegNo;
if (getLexer().isNot(AsmToken::Integer)) {
if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
return true;
- Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true);
+ Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
} else
return parseAbsoluteExpression(Register);
return false;
}
-/// ParseDirectiveCFIDefCfa
+/// parseDirectiveCFIDefCfa
/// ::= .cfi_def_cfa register, offset
-bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2756,9 +2810,9 @@ bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveCFIDefCfaOffset
+/// parseDirectiveCFIDefCfaOffset
/// ::= .cfi_def_cfa_offset offset
-bool AsmParser::ParseDirectiveCFIDefCfaOffset() {
+bool AsmParser::parseDirectiveCFIDefCfaOffset() {
int64_t Offset = 0;
if (parseAbsoluteExpression(Offset))
return true;
@@ -2767,11 +2821,11 @@ bool AsmParser::ParseDirectiveCFIDefCfaOffset() {
return false;
}
-/// ParseDirectiveCFIRegister
+/// parseDirectiveCFIRegister
/// ::= .cfi_register register, register
-bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
int64_t Register1 = 0;
- if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2779,16 +2833,23 @@ bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) {
Lex();
int64_t Register2 = 0;
- if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
return true;
getStreamer().EmitCFIRegister(Register1, Register2);
return false;
}
-/// ParseDirectiveCFIAdjustCfaOffset
+/// parseDirectiveCFIWindowSave
+/// ::= .cfi_window_save
+bool AsmParser::parseDirectiveCFIWindowSave() {
+ getStreamer().EmitCFIWindowSave();
+ return false;
+}
+
+/// parseDirectiveCFIAdjustCfaOffset
/// ::= .cfi_adjust_cfa_offset adjustment
-bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() {
+bool AsmParser::parseDirectiveCFIAdjustCfaOffset() {
int64_t Adjustment = 0;
if (parseAbsoluteExpression(Adjustment))
return true;
@@ -2797,24 +2858,24 @@ bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() {
return false;
}
-/// ParseDirectiveCFIDefCfaRegister
+/// parseDirectiveCFIDefCfaRegister
/// ::= .cfi_def_cfa_register register
-bool AsmParser::ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFIDefCfaRegister(Register);
return false;
}
-/// ParseDirectiveCFIOffset
+/// parseDirectiveCFIOffset
/// ::= .cfi_offset register, offset
-bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
int64_t Offset = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2828,12 +2889,12 @@ bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveCFIRelOffset
+/// parseDirectiveCFIRelOffset
/// ::= .cfi_rel_offset register, offset
-bool AsmParser::ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2870,11 +2931,11 @@ static bool isValidEncoding(int64_t Encoding) {
return true;
}
-/// ParseDirectiveCFIPersonalityOrLsda
+/// parseDirectiveCFIPersonalityOrLsda
/// IsPersonality true for cfi_personality, false for cfi_lsda
/// ::= .cfi_personality encoding, [symbol_name]
/// ::= .cfi_lsda encoding, [symbol_name]
-bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
+bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
int64_t Encoding = 0;
if (parseAbsoluteExpression(Encoding))
return true;
@@ -2901,46 +2962,46 @@ bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
return false;
}
-/// ParseDirectiveCFIRememberState
+/// parseDirectiveCFIRememberState
/// ::= .cfi_remember_state
-bool AsmParser::ParseDirectiveCFIRememberState() {
+bool AsmParser::parseDirectiveCFIRememberState() {
getStreamer().EmitCFIRememberState();
return false;
}
-/// ParseDirectiveCFIRestoreState
+/// parseDirectiveCFIRestoreState
/// ::= .cfi_remember_state
-bool AsmParser::ParseDirectiveCFIRestoreState() {
+bool AsmParser::parseDirectiveCFIRestoreState() {
getStreamer().EmitCFIRestoreState();
return false;
}
-/// ParseDirectiveCFISameValue
+/// parseDirectiveCFISameValue
/// ::= .cfi_same_value register
-bool AsmParser::ParseDirectiveCFISameValue(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFISameValue(Register);
return false;
}
-/// ParseDirectiveCFIRestore
+/// parseDirectiveCFIRestore
/// ::= .cfi_restore register
-bool AsmParser::ParseDirectiveCFIRestore(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFIRestore(Register);
return false;
}
-/// ParseDirectiveCFIEscape
+/// parseDirectiveCFIEscape
/// ::= .cfi_escape expression[,...]
-bool AsmParser::ParseDirectiveCFIEscape() {
+bool AsmParser::parseDirectiveCFIEscape() {
std::string Values;
int64_t CurrValue;
if (parseAbsoluteExpression(CurrValue))
@@ -2961,9 +3022,9 @@ bool AsmParser::ParseDirectiveCFIEscape() {
return false;
}
-/// ParseDirectiveCFISignalFrame
+/// parseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
-bool AsmParser::ParseDirectiveCFISignalFrame() {
+bool AsmParser::parseDirectiveCFISignalFrame() {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(getLexer().getLoc(),
"unexpected token in '.cfi_signal_frame'");
@@ -2972,40 +3033,40 @@ bool AsmParser::ParseDirectiveCFISignalFrame() {
return false;
}
-/// ParseDirectiveCFIUndefined
+/// parseDirectiveCFIUndefined
/// ::= .cfi_undefined register
-bool AsmParser::ParseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
int64_t Register = 0;
- if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
+ if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFIUndefined(Register);
return false;
}
-/// ParseDirectiveMacrosOnOff
+/// parseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off
-bool AsmParser::ParseDirectiveMacrosOnOff(StringRef Directive) {
+bool AsmParser::parseDirectiveMacrosOnOff(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(getLexer().getLoc(),
"unexpected token in '" + Directive + "' directive");
- SetMacrosEnabled(Directive == ".macros_on");
+ setMacrosEnabled(Directive == ".macros_on");
return false;
}
-/// ParseDirectiveMacro
+/// parseDirectiveMacro
/// ::= .macro name [parameters]
-bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
StringRef Name;
if (parseIdentifier(Name))
return TokError("expected identifier in '.macro' directive");
MCAsmMacroParameters Parameters;
// Argument delimiter is initially unknown. It will be set by
- // ParseMacroArgument()
+ // parseMacroArgument()
AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
@@ -3015,7 +3076,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
if (getLexer().is(AsmToken::Equal)) {
Lex();
- if (ParseMacroArgument(Parameter.second, ArgumentDelimiter))
+ if (parseMacroArgument(Parameter.second, ArgumentDelimiter))
return true;
}
@@ -3055,19 +3116,19 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
eatToEndOfStatement();
}
- if (LookupMacro(Name)) {
+ if (lookupMacro(Name)) {
return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
}
const char *BodyStart = StartToken.getLoc().getPointer();
const char *BodyEnd = EndToken.getLoc().getPointer();
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
- CheckForBadMacro(DirectiveLoc, Name, Body, Parameters);
- DefineMacro(Name, MCAsmMacro(Name, Body, Parameters));
+ checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
+ defineMacro(Name, MCAsmMacro(Name, Body, Parameters));
return false;
}
-/// CheckForBadMacro
+/// checkForBadMacro
///
/// With the support added for named parameters there may be code out there that
/// is transitioning from positional parameters. In versions of gas that did
@@ -3081,7 +3142,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
/// intended or change the macro to use the named parameters. It is possible
/// this warning will trigger when the none of the named parameters are used
/// and the strings like $1 are infact to simply to be passed trough unchanged.
-void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
+void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
StringRef Body,
MCAsmMacroParameters Parameters) {
// If this macro is not defined with named parameters the warning we are
@@ -3119,21 +3180,21 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
break;
if (Body[Pos] == '$') {
- switch (Body[Pos+1]) {
- // $$ => $
+ switch (Body[Pos + 1]) {
+ // $$ => $
case '$':
break;
- // $n => number of arguments
+ // $n => number of arguments
case 'n':
PositionalParametersFound = true;
break;
- // $[0-9] => argument
+ // $[0-9] => argument
default: {
PositionalParametersFound = true;
break;
- }
+ }
}
Pos += 2;
} else {
@@ -3141,19 +3202,19 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
while (isIdentifierChar(Body[I]) && I + 1 != End)
++I;
- const char *Begin = Body.data() + Pos +1;
- StringRef Argument(Begin, I - (Pos +1));
+ const char *Begin = Body.data() + Pos + 1;
+ StringRef Argument(Begin, I - (Pos + 1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
if (Parameters[Index].first == Argument)
break;
if (Index == NParameters) {
- if (Body[Pos+1] == '(' && Body[Pos+2] == ')')
- Pos += 3;
- else {
- Pos = I;
- }
+ if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
+ Pos += 3;
+ else {
+ Pos = I;
+ }
} else {
NamedParametersFound = true;
Pos += 1 + Argument.size();
@@ -3169,29 +3230,29 @@ void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
"found in body which will have no effect");
}
-/// ParseDirectiveEndMacro
+/// parseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
-bool AsmParser::ParseDirectiveEndMacro(StringRef Directive) {
+bool AsmParser::parseDirectiveEndMacro(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Directive + "' directive");
// If we are inside a macro instantiation, terminate the current
// instantiation.
- if (InsideMacroInstantiation()) {
- HandleMacroExit();
+ if (isInsideMacroInstantiation()) {
+ handleMacroExit();
return false;
}
// Otherwise, this .endmacro is a stray entry in the file; well formed
// .endmacro directives are handled during the macro definition parsing.
return TokError("unexpected '" + Directive + "' in file, "
- "no current macro definition");
+ "no current macro definition");
}
-/// ParseDirectivePurgeMacro
+/// parseDirectivePurgeMacro
/// ::= .purgem
-bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
if (parseIdentifier(Name))
return TokError("expected identifier in '.purgem' directive");
@@ -3199,16 +3260,16 @@ bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.purgem' directive");
- if (!LookupMacro(Name))
+ if (!lookupMacro(Name))
return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
- UndefineMacro(Name);
+ undefineMacro(Name);
return false;
}
-/// ParseDirectiveBundleAlignMode
+/// parseDirectiveBundleAlignMode
/// ::= {.bundle_align_mode} expression
-bool AsmParser::ParseDirectiveBundleAlignMode() {
+bool AsmParser::parseDirectiveBundleAlignMode() {
checkForValidSection();
// Expect a single argument: an expression that evaluates to a constant
@@ -3232,9 +3293,9 @@ bool AsmParser::ParseDirectiveBundleAlignMode() {
return false;
}
-/// ParseDirectiveBundleLock
+/// parseDirectiveBundleLock
/// ::= {.bundle_lock} [align_to_end]
-bool AsmParser::ParseDirectiveBundleLock() {
+bool AsmParser::parseDirectiveBundleLock() {
checkForValidSection();
bool AlignToEnd = false;
@@ -3242,7 +3303,7 @@ bool AsmParser::ParseDirectiveBundleLock() {
StringRef Option;
SMLoc Loc = getTok().getLoc();
const char *kInvalidOptionError =
- "invalid option for '.bundle_lock' directive";
+ "invalid option for '.bundle_lock' directive";
if (parseIdentifier(Option))
return Error(Loc, kInvalidOptionError);
@@ -3261,9 +3322,9 @@ bool AsmParser::ParseDirectiveBundleLock() {
return false;
}
-/// ParseDirectiveBundleLock
+/// parseDirectiveBundleLock
/// ::= {.bundle_lock}
-bool AsmParser::ParseDirectiveBundleUnlock() {
+bool AsmParser::parseDirectiveBundleUnlock() {
checkForValidSection();
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3274,9 +3335,9 @@ bool AsmParser::ParseDirectiveBundleUnlock() {
return false;
}
-/// ParseDirectiveSpace
+/// parseDirectiveSpace
/// ::= (.skip | .space) expression [ , expression ]
-bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
+bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
checkForValidSection();
int64_t NumBytes;
@@ -3299,18 +3360,18 @@ bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
Lex();
if (NumBytes <= 0)
- return TokError("invalid number of bytes in '" +
- Twine(IDVal) + "' directive");
+ return TokError("invalid number of bytes in '" + Twine(IDVal) +
+ "' directive");
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
+ getStreamer().EmitFill(NumBytes, FillExpr);
return false;
}
-/// ParseDirectiveLEB128
+/// parseDirectiveLEB128
/// ::= (.sleb128 | .uleb128) expression
-bool AsmParser::ParseDirectiveLEB128(bool Signed) {
+bool AsmParser::parseDirectiveLEB128(bool Signed) {
checkForValidSection();
const MCExpr *Value;
@@ -3328,9 +3389,9 @@ bool AsmParser::ParseDirectiveLEB128(bool Signed) {
return false;
}
-/// ParseDirectiveSymbolAttribute
+/// parseDirectiveSymbolAttribute
/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
-bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
+bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
StringRef Name;
@@ -3345,7 +3406,8 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
if (Sym->isTemporary())
return Error(Loc, "non-local symbol required in directive");
- getStreamer().EmitSymbolAttribute(Sym, Attr);
+ if (!getStreamer().EmitSymbolAttribute(Sym, Attr))
+ return Error(Loc, "unable to emit symbol attribute");
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -3360,9 +3422,9 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
return false;
}
-/// ParseDirectiveComm
+/// parseDirectiveComm
/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
-bool AsmParser::ParseDirectiveComm(bool IsLocal) {
+bool AsmParser::parseDirectiveComm(bool IsLocal) {
checkForValidSection();
SMLoc IDLoc = getLexer().getLoc();
@@ -3412,14 +3474,14 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
// but a size of .lcomm creates a bss symbol of size zero.
if (Size < 0)
return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
- "be less than zero");
+ "be less than zero");
// NOTE: The alignment in the directive is a power of 2 value, the assembler
// may internally end up wanting an alignment in bytes.
// FIXME: Diagnose overflow.
if (Pow2Alignment < 0)
return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
- "alignment, can't be less than zero");
+ "alignment, can't be less than zero");
if (!Sym->isUndefined())
return Error(IDLoc, "invalid symbol redefinition");
@@ -3434,9 +3496,9 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
return false;
}
-/// ParseDirectiveAbort
+/// parseDirectiveAbort
/// ::= .abort [... message ...]
-bool AsmParser::ParseDirectiveAbort() {
+bool AsmParser::parseDirectiveAbort() {
// FIXME: Use loc from directive.
SMLoc Loc = getLexer().getLoc();
@@ -3455,25 +3517,25 @@ bool AsmParser::ParseDirectiveAbort() {
return false;
}
-/// ParseDirectiveInclude
+/// parseDirectiveInclude
/// ::= .include "filename"
-bool AsmParser::ParseDirectiveInclude() {
+bool AsmParser::parseDirectiveInclude() {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in '.include' directive");
- std::string Filename = getTok().getString();
+ // Allow the strings to have escaped octal character sequence.
+ std::string Filename;
+ if (parseEscapedString(Filename))
+ return true;
SMLoc IncludeLoc = getLexer().getLoc();
Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.include' directive");
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
// Attempt to switch the lexer to the included file before consuming the end
// of statement to avoid losing it when we switch.
- if (EnterIncludeFile(Filename)) {
+ if (enterIncludeFile(Filename)) {
Error(IncludeLoc, "Could not find include file '" + Filename + "'");
return true;
}
@@ -3481,24 +3543,24 @@ bool AsmParser::ParseDirectiveInclude() {
return false;
}
-/// ParseDirectiveIncbin
+/// parseDirectiveIncbin
/// ::= .incbin "filename"
-bool AsmParser::ParseDirectiveIncbin() {
+bool AsmParser::parseDirectiveIncbin() {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in '.incbin' directive");
- std::string Filename = getTok().getString();
+ // Allow the strings to have escaped octal character sequence.
+ std::string Filename;
+ if (parseEscapedString(Filename))
+ return true;
SMLoc IncbinLoc = getLexer().getLoc();
Lex();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.incbin' directive");
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
// Attempt to process the included file.
- if (ProcessIncbinFile(Filename)) {
+ if (processIncbinFile(Filename)) {
Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
return true;
}
@@ -3506,9 +3568,9 @@ bool AsmParser::ParseDirectiveIncbin() {
return false;
}
-/// ParseDirectiveIf
+/// parseDirectiveIf
/// ::= .if expression
-bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveIf(SMLoc DirectiveLoc) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
@@ -3530,9 +3592,9 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveIfb
+/// parseDirectiveIfb
/// ::= .ifb string
-bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
+bool AsmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
@@ -3553,16 +3615,16 @@ bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
return false;
}
-/// ParseDirectiveIfc
+/// parseDirectiveIfc
/// ::= .ifc string1, string2
-bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
+bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
eatToEndOfStatement();
} else {
- StringRef Str1 = ParseStringToComma();
+ StringRef Str1 = parseStringToComma();
if (getLexer().isNot(AsmToken::Comma))
return TokError("unexpected token in '.ifc' directive");
@@ -3583,9 +3645,9 @@ bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
return false;
}
-/// ParseDirectiveIfdef
+/// parseDirectiveIfdef
/// ::= .ifdef symbol
-bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
+bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
StringRef Name;
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
@@ -3610,9 +3672,9 @@ bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
return false;
}
-/// ParseDirectiveElseIf
+/// parseDirectiveElseIf
/// ::= .elseif expression
-bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveElseIf(SMLoc DirectiveLoc) {
if (TheCondState.TheCond != AsmCond::IfCond &&
TheCondState.TheCond != AsmCond::ElseIfCond)
Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
@@ -3641,9 +3703,9 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveElse
+/// parseDirectiveElse
/// ::= .else
-bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.else' directive");
@@ -3665,16 +3727,15 @@ bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
return false;
}
-/// ParseDirectiveEndIf
+/// parseDirectiveEndIf
/// ::= .endif
-bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.endif' directive");
Lex();
- if ((TheCondState.TheCond == AsmCond::NoCond) ||
- TheCondStack.empty())
+ if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
".else");
if (!TheCondStack.empty()) {
@@ -3718,7 +3779,6 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".extern"] = DK_EXTERN;
DirectiveKindMap[".globl"] = DK_GLOBL;
DirectiveKindMap[".global"] = DK_GLOBAL;
- DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL;
DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
@@ -3780,6 +3840,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
+ DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
@@ -3788,8 +3849,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".purgem"] = DK_PURGEM;
}
-
-MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
+MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
AsmToken EndToken, StartToken = getTok();
unsigned NestLevel = 0;
@@ -3806,8 +3866,7 @@ MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
}
// Otherwise, check whether we have reached the .endr.
- if (Lexer.is(AsmToken::Identifier) &&
- getTok().getIdentifier() == ".endr") {
+ if (Lexer.is(AsmToken::Identifier) && getTok().getIdentifier() == ".endr") {
if (NestLevel == 0) {
EndToken = getTok();
Lex();
@@ -3831,22 +3890,21 @@ MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
// We Are Anonymous.
StringRef Name;
MCAsmMacroParameters Parameters;
- return new MCAsmMacro(Name, Body, Parameters);
+ MacroLikeBodies.push_back(MCAsmMacro(Name, Body, Parameters));
+ return &MacroLikeBodies.back();
}
-void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
+void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS) {
OS << ".endr\n";
MemoryBuffer *Instantiation =
- MemoryBuffer::getMemBufferCopy(OS.str(), "<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);
+ MacroInstantiation *MI = new MacroInstantiation(
+ M, DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
@@ -3855,7 +3913,7 @@ void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
Lex();
}
-bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc) {
int64_t Count;
if (parseAbsoluteExpression(Count))
return TokError("unexpected token in '.rept' directive");
@@ -3870,7 +3928,7 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
Lex();
// Lex the rept definition.
- MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -3884,14 +3942,14 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc()))
return true;
}
- InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+ instantiateMacroLikeBody(M, DirectiveLoc, OS);
return false;
}
-/// ParseDirectiveIrp
+/// parseDirectiveIrp
/// ::= .irp symbol,values
-bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
@@ -3906,14 +3964,14 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
Lex();
MCAsmMacroArguments A;
- if (ParseMacroArguments(0, A))
+ if (parseMacroArguments(0, A))
return true;
// Eat the end of statement.
Lex();
// Lex the irp definition.
- MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -3930,14 +3988,14 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
return true;
}
- InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+ instantiateMacroLikeBody(M, DirectiveLoc, OS);
return false;
}
-/// ParseDirectiveIrpc
+/// parseDirectiveIrpc
/// ::= .irpc symbol,values
-bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
@@ -3952,7 +4010,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
Lex();
MCAsmMacroArguments A;
- if (ParseMacroArguments(0, A))
+ if (parseMacroArguments(0, A))
return true;
if (A.size() != 1 || A.front().size() != 1)
@@ -3962,7 +4020,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
Lex();
// Lex the irpc definition.
- MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -3975,7 +4033,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
std::size_t I, End = Values.size();
for (I = 0; I < End; ++I) {
MCAsmMacroArgument Arg;
- Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1)));
+ Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1)));
MCAsmMacroArguments Args;
Args.push_back(Arg);
@@ -3984,24 +4042,24 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
return true;
}
- InstantiateMacroLikeBody(M, DirectiveLoc, OS);
+ instantiateMacroLikeBody(M, DirectiveLoc, OS);
return false;
}
-bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
+bool AsmParser::parseDirectiveEndr(SMLoc DirectiveLoc) {
if (ActiveMacros.empty())
return TokError("unmatched '.endr' directive");
// The only .repl that should get here are the ones created by
- // InstantiateMacroLikeBody.
+ // instantiateMacroLikeBody.
assert(getLexer().is(AsmToken::EndOfStatement));
- HandleMacroExit();
+ handleMacroExit();
return false;
}
-bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
+bool AsmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
size_t Len) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
@@ -4018,7 +4076,7 @@ bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
return false;
}
-bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
+bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
if (parseExpression(Value))
@@ -4030,16 +4088,15 @@ bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
if (!isPowerOf2_64(IntValue))
return Error(ExprLoc, "literal value not a power of two greater then zero");
- Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5,
- Log2_64(IntValue)));
+ Info.AsmRewrites->push_back(
+ AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue)));
return false;
}
// We are comparing pointers, but the pointers are relative to a single string.
// Thus, this should always be deterministic.
-static int RewritesSort(const void *A, const void *B) {
- const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A);
- const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B);
+static int rewritesSort(const AsmRewrite *AsmRewriteA,
+ const AsmRewrite *AsmRewriteB) {
if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
return -1;
if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
@@ -4049,25 +4106,22 @@ static int RewritesSort(const void *A, const void *B) {
// rewrite to the same location. Make sure the SizeDirective rewrite is
// performed first, then the Imm/ImmPrefix and finally the Input/Output. This
// ensures the sort algorithm is stable.
- if (AsmRewritePrecedence [AsmRewriteA->Kind] >
- AsmRewritePrecedence [AsmRewriteB->Kind])
+ if (AsmRewritePrecedence[AsmRewriteA->Kind] >
+ AsmRewritePrecedence[AsmRewriteB->Kind])
return -1;
- if (AsmRewritePrecedence [AsmRewriteA->Kind] <
- AsmRewritePrecedence [AsmRewriteB->Kind])
+ if (AsmRewritePrecedence[AsmRewriteA->Kind] <
+ AsmRewritePrecedence[AsmRewriteB->Kind])
return 1;
- llvm_unreachable ("Unstable rewrite sort.");
+ llvm_unreachable("Unstable rewrite sort.");
}
-bool
-AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
- unsigned &NumOutputs, unsigned &NumInputs,
- SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
- SmallVectorImpl<std::string> &Constraints,
- SmallVectorImpl<std::string> &Clobbers,
- const MCInstrInfo *MII,
- const MCInstPrinter *IP,
- MCAsmParserSemaCallback &SI) {
+bool AsmParser::parseMSInlineAsm(
+ void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
+ unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
+ SmallVectorImpl<std::string> &Constraints,
+ SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
+ const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
SmallVector<void *, 4> InputDecls;
SmallVector<void *, 4> OutputDecls;
SmallVector<bool, 4> InputDeclsAddressOf;
@@ -4086,7 +4140,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned OutputIdx = 0;
while (getLexer().isNot(AsmToken::Eof)) {
ParseStatementInfo Info(&AsmStrRewrites);
- if (ParseStatement(Info))
+ if (parseStatement(Info))
return true;
if (Info.ParseError)
@@ -4174,7 +4228,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
raw_string_ostream OS(AsmStringIR);
const char *AsmStart = SrcMgr.getMemoryBuffer(0)->getBufferStart();
const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd();
- array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), RewritesSort);
+ array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(),
E = AsmStrRewrites.end();
I != E; ++I) {
@@ -4199,7 +4253,8 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned AdditionalSkip = 0;
// Rewrite expressions in $N notation.
switch (Kind) {
- default: break;
+ default:
+ break;
case AOK_Imm:
OS << "$$" << (*I).Val;
break;
@@ -4254,8 +4309,7 @@ AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
}
/// \brief Create an MCAsmParser instance.
-MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM,
- MCContext &C, MCStreamer &Out,
- const MCAsmInfo &MAI) {
+MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
+ MCStreamer &Out, const MCAsmInfo &MAI) {
return new AsmParser(SM, C, Out, MAI);
}
diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index a50eab2..d8343a3 100644
--- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -35,6 +35,13 @@ class COFFAsmParser : public MCAsmParserExtension {
unsigned Characteristics,
SectionKind Kind);
+ bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
+ SectionKind Kind, StringRef COMDATSymName,
+ COFF::COMDATType Type, const MCSectionCOFF *Assoc);
+
+ bool ParseSectionName(StringRef &SectionName);
+ bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags);
+
virtual void Initialize(MCAsmParser &Parser) {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
@@ -42,11 +49,13 @@ class COFFAsmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
// Win64 EH directives.
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
@@ -100,11 +109,15 @@ class COFFAsmParser : public MCAsmParserExtension {
SectionKind::getBSS());
}
+ bool ParseDirectiveSection(StringRef, SMLoc);
bool ParseDirectiveDef(StringRef, SMLoc);
bool ParseDirectiveScl(StringRef, SMLoc);
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveEndef(StringRef, SMLoc);
bool ParseDirectiveSecRel32(StringRef, SMLoc);
+ bool parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
+ const MCSectionCOFF *&Assoc);
+ bool ParseDirectiveLinkOnce(StringRef, SMLoc);
// Win64 EH directives.
bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -130,6 +143,119 @@ public:
} // end annonomous namespace.
+static SectionKind computeSectionKind(unsigned Flags) {
+ if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
+ return SectionKind::getText();
+ if (Flags & COFF::IMAGE_SCN_MEM_READ &&
+ (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
+ return SectionKind::getReadOnly();
+ return SectionKind::getDataRel();
+}
+
+bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) {
+ enum {
+ None = 0,
+ Alloc = 1 << 0,
+ Code = 1 << 1,
+ Load = 1 << 2,
+ InitData = 1 << 3,
+ Shared = 1 << 4,
+ NoLoad = 1 << 5,
+ NoRead = 1 << 6,
+ NoWrite = 1 << 7
+ };
+
+ bool ReadOnlyRemoved = false;
+ unsigned SecFlags = None;
+
+ for (unsigned i = 0; i < FlagsString.size(); ++i) {
+ switch (FlagsString[i]) {
+ case 'a':
+ // Ignored.
+ break;
+
+ case 'b': // bss section
+ SecFlags |= Alloc;
+ if (SecFlags & InitData)
+ return TokError("conflicting section flags 'b' and 'd'.");
+ SecFlags &= ~Load;
+ break;
+
+ case 'd': // data section
+ SecFlags |= InitData;
+ if (SecFlags & Alloc)
+ return TokError("conflicting section flags 'b' and 'd'.");
+ SecFlags &= ~NoWrite;
+ if ((SecFlags & NoLoad) == 0)
+ SecFlags |= Load;
+ break;
+
+ case 'n': // section is not loaded
+ SecFlags |= NoLoad;
+ SecFlags &= ~Load;
+ break;
+
+ case 'r': // read-only
+ ReadOnlyRemoved = false;
+ SecFlags |= NoWrite;
+ if ((SecFlags & Code) == 0)
+ SecFlags |= InitData;
+ if ((SecFlags & NoLoad) == 0)
+ SecFlags |= Load;
+ break;
+
+ case 's': // shared section
+ SecFlags |= Shared | InitData;
+ SecFlags &= ~NoWrite;
+ if ((SecFlags & NoLoad) == 0)
+ SecFlags |= Load;
+ break;
+
+ case 'w': // writable
+ SecFlags &= ~NoWrite;
+ ReadOnlyRemoved = true;
+ break;
+
+ case 'x': // executable section
+ SecFlags |= Code;
+ if ((SecFlags & NoLoad) == 0)
+ SecFlags |= Load;
+ if (!ReadOnlyRemoved)
+ SecFlags |= NoWrite;
+ break;
+
+ case 'y': // not readable
+ SecFlags |= NoRead | NoWrite;
+ break;
+
+ default:
+ return TokError("unknown flag");
+ }
+ }
+
+ *Flags = 0;
+
+ if (SecFlags == None)
+ SecFlags = InitData;
+
+ if (SecFlags & Code)
+ *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
+ if (SecFlags & InitData)
+ *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
+ if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
+ *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ if (SecFlags & NoLoad)
+ *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
+ if ((SecFlags & NoRead) == 0)
+ *Flags |= COFF::IMAGE_SCN_MEM_READ;
+ if ((SecFlags & NoWrite) == 0)
+ *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
+ if (SecFlags & Shared)
+ *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
+
+ return false;
+}
+
/// ParseDirectiveSymbolAttribute
/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
@@ -164,13 +290,96 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
unsigned Characteristics,
SectionKind Kind) {
+ return ParseSectionSwitch(Section, Characteristics, Kind, "",
+ COFF::IMAGE_COMDAT_SELECT_ANY, 0);
+}
+
+bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind,
+ StringRef COMDATSymName,
+ COFF::COMDATType Type,
+ const MCSectionCOFF *Assoc) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in section switching directive");
Lex();
getStreamer().SwitchSection(getContext().getCOFFSection(
- Section, Characteristics, Kind));
+ Section, Characteristics, Kind, COMDATSymName, Type, Assoc));
+
+ return false;
+}
+
+bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
+ if (!getLexer().is(AsmToken::Identifier))
+ return true;
+
+ SectionName = getTok().getIdentifier();
+ Lex();
+ return false;
+}
+
+// .section name [, "flags"] [, identifier [ identifier ], identifier]
+//
+// Supported flags:
+// a: Ignored.
+// b: BSS section (uninitialized data)
+// d: data section (initialized data)
+// n: Discardable section
+// r: Readable section
+// s: Shared section
+// w: Writable section
+// x: Executable section
+// y: Not-readable section (clears 'r')
+//
+// Subsections are not supported.
+bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
+ StringRef SectionName;
+
+ if (ParseSectionName(SectionName))
+ return TokError("expected identifier in directive");
+
+ unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE;
+
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in directive");
+
+ StringRef FlagsStr = getTok().getStringContents();
+ Lex();
+
+ if (ParseSectionFlags(FlagsStr, &Flags))
+ return true;
+ }
+
+ COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
+ const MCSectionCOFF *Assoc = 0;
+ StringRef COMDATSymName;
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ Flags |= COFF::IMAGE_SCN_LNK_COMDAT;
+ if (parseCOMDATTypeAndAssoc(Type, Assoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected comma in directive");
+ Lex();
+
+ if (getParser().parseIdentifier(COMDATSymName))
+ return TokError("expected identifier in directive");
+ }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ SectionKind Kind = computeSectionKind(Flags);
+ ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type, Assoc);
return false;
}
@@ -235,6 +444,75 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
return false;
}
+/// ::= [ identifier [ identifier ] ]
+bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type,
+ const MCSectionCOFF *&Assoc) {
+ StringRef TypeId = getTok().getIdentifier();
+
+ Type = StringSwitch<COFF::COMDATType>(TypeId)
+ .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
+ .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
+ .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
+ .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
+ .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+ .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
+ .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
+ .Default((COFF::COMDATType)0);
+
+ if (Type == 0)
+ return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
+
+ Lex();
+
+ if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ SMLoc Loc = getTok().getLoc();
+ StringRef AssocName;
+ if (ParseSectionName(AssocName))
+ return TokError("expected associated section name");
+
+ Assoc = static_cast<const MCSectionCOFF*>(
+ getContext().getCOFFSection(AssocName));
+ if (!Assoc)
+ return Error(Loc, "cannot associate unknown section '" + AssocName + "'");
+ if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT))
+ return Error(Loc, "associated section must be a COMDAT section");
+ if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+ return Error(Loc, "associated section cannot be itself associative");
+ }
+
+ return false;
+}
+
+/// ParseDirectiveLinkOnce
+/// ::= .linkonce [ identifier [ identifier ] ]
+bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
+ COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY;
+ const MCSectionCOFF *Assoc = 0;
+ if (getLexer().is(AsmToken::Identifier))
+ if (parseCOMDATTypeAndAssoc(Type, Assoc))
+ return true;
+
+ const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>(
+ getStreamer().getCurrentSection().first);
+
+
+ if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ if (Assoc == Current)
+ return Error(Loc, "cannot associate a section with itself");
+ }
+
+ if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
+ return Error(Loc, Twine("section '") + Current->getSectionName() +
+ "' is already linkonce");
+
+ Current->setSelection(Type, Assoc);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ return false;
+}
+
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
StringRef SymbolID;
if (getParser().parseIdentifier(SymbolID))
@@ -453,7 +731,7 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
SMLoc startLoc = getLexer().getLoc();
if (getLexer().is(AsmToken::Percent)) {
- const MCRegisterInfo &MRI = getContext().getRegisterInfo();
+ const MCRegisterInfo *MRI = getContext().getRegisterInfo();
SMLoc endLoc;
unsigned LLVMRegNo;
if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
@@ -473,7 +751,7 @@ bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
return Error(startLoc, "expected non-volatile register");
#endif
- int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo);
+ int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
if (SEHRegNo < 0)
return Error(startLoc,"register can't be represented in SEH unwind info");
RegNo = SEHRegNo;
diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
index 7eb8b74..4c9bafa 100644
--- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -45,6 +45,8 @@ public:
this->MCAsmParserExtension::Initialize(Parser);
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
+ ".indirect_symbol");
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
".subsections_via_symbols");
@@ -69,6 +71,7 @@ public:
".end_data_region");
// Special section directives.
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveBss>(".bss");
addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
".const_data");
@@ -163,6 +166,7 @@ public:
}
bool ParseDirectiveDesc(StringRef, SMLoc);
+ bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
bool ParseDirectiveLinkerOption(StringRef, SMLoc);
@@ -179,6 +183,10 @@ public:
bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
// Named Section Directive
+ bool ParseSectionDirectiveBss(StringRef, SMLoc) {
+ return ParseSectionSwitch("__DATA", "__bss");
+ }
+
bool ParseSectionDirectiveConst(StringRef, SMLoc) {
return ParseSectionSwitch("__TEXT", "__const");
}
@@ -415,6 +423,39 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveIndirectSymbol
+/// ::= .indirect_symbol identifier
+bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
+ const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
+ getStreamer().getCurrentSection().first);
+ unsigned SectionType = Current->getType();
+ if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+ SectionType != MCSectionMachO::S_SYMBOL_STUBS)
+ return Error(Loc, "indirect symbol not in a symbol pointer or stub "
+ "section");
+
+ StringRef Name;
+ if (getParser().parseIdentifier(Name))
+ return TokError("expected identifier in .indirect_symbol directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ // Assembler local symbols don't make any sense here. Complain loudly.
+ if (Sym->isTemporary())
+ return TokError("non-local symbol required in directive");
+
+ if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
+ return TokError("unable to emit indirect symbol attribute for: " + Name);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.indirect_symbol' directive");
+
+ Lex();
+
+ return false;
+}
+
/// ParseDirectiveDumpOrLoad
/// ::= ( .dump | .load ) "filename"
bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
@@ -593,7 +634,7 @@ bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
raw_ostream *OS = getContext().getSecureLog();
if (OS == NULL) {
std::string Err;
- OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
+ OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append);
if (!Err.empty()) {
delete OS;
return Error(IDLoc, Twine("can't open secure log file: ") +
diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index 3134fc3..8807975 100644
--- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ELF.h"
using namespace llvm;
@@ -30,14 +31,11 @@ class ELFAsmParser : public MCAsmParserExtension {
getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind);
- bool SeenIdent;
+ bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind);
public:
- ELFAsmParser() : SeenIdent(false) {
- BracketExpressionsSupported = true;
- }
+ ELFAsmParser() { BracketExpressionsSupported = true; }
virtual void Initialize(MCAsmParser &Parser) {
// Call the base implementation.
@@ -241,7 +239,6 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
}
for (;;) {
- StringRef Tmp;
unsigned CurSize;
SMLoc PrevLoc = getLexer().getLoc();
@@ -279,14 +276,17 @@ static SectionKind computeSectionKind(unsigned Flags) {
return SectionKind::getDataRel();
}
-static int parseSectionFlags(StringRef flagsStr) {
- int flags = 0;
+static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
+ unsigned flags = 0;
for (unsigned i = 0; i < flagsStr.size(); i++) {
switch (flagsStr[i]) {
case 'a':
flags |= ELF::SHF_ALLOC;
break;
+ case 'e':
+ flags |= ELF::SHF_EXCLUDE;
+ break;
case 'x':
flags |= ELF::SHF_EXECINSTR;
break;
@@ -311,8 +311,11 @@ static int parseSectionFlags(StringRef flagsStr) {
case 'G':
flags |= ELF::SHF_GROUP;
break;
+ case '?':
+ *UseLastGroup = true;
+ break;
default:
- return -1;
+ return -1U;
}
}
@@ -352,6 +355,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
StringRef GroupName;
unsigned Flags = 0;
const MCExpr *Subsection = 0;
+ bool UseLastGroup = false;
// Set the defaults first.
if (SectionName == ".fini" || SectionName == ".init" ||
@@ -377,13 +381,16 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
StringRef FlagsStr = getTok().getStringContents();
Lex();
- int extraFlags = parseSectionFlags(FlagsStr);
- if (extraFlags < 0)
+ unsigned extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
+ if (extraFlags == -1U)
return TokError("unknown flag");
Flags |= extraFlags;
bool Mergeable = Flags & ELF::SHF_MERGE;
bool Group = Flags & ELF::SHF_GROUP;
+ if (Group && UseLastGroup)
+ return TokError("Section cannot specifiy a group name while also acting "
+ "as a member of the last group");
if (getLexer().isNot(AsmToken::Comma)) {
if (Mergeable)
@@ -392,10 +399,13 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
return TokError("Group section must specify the type");
} else {
Lex();
- if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
- return TokError("expected '@' or '%' before type");
+ if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) ||
+ getLexer().is(AsmToken::String)) {
+ if (!getLexer().is(AsmToken::String))
+ Lex();
+ } else
+ return TokError("expected '@<type>', '%<type>' or \"<type>\"");
- Lex();
if (getParser().parseIdentifier(TypeName))
return TokError("expected identifier in directive");
@@ -461,6 +471,16 @@ EndStmt:
return TokError("unknown section type");
}
+ if (UseLastGroup) {
+ MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
+ if (const MCSectionELF *Section =
+ cast_or_null<MCSectionELF>(CurrentSection.first))
+ if (const MCSymbol *Group = Section->getGroup()) {
+ GroupName = Group->getName();
+ Flags |= ELF::SHF_GROUP;
+ }
+ }
+
SectionKind Kind = computeSectionKind(Flags);
getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
Flags, Kind, Size,
@@ -479,7 +499,11 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
}
/// ParseDirectiveELFType
+/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
+/// ::= .type identifier , #attribute
/// ::= .type identifier , @attribute
+/// ::= .type identifier , %attribute
+/// ::= .type identifier , "attribute"
bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
@@ -492,26 +516,42 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
return TokError("unexpected token in '.type' directive");
Lex();
- if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
- return TokError("expected '@' or '%' before type");
- Lex();
-
StringRef Type;
SMLoc TypeLoc;
+ MCSymbolAttr Attr;
+ if (getLexer().is(AsmToken::Identifier)) {
+ TypeLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(Type))
+ return TokError("expected symbol type in directive");
+ Attr = StringSwitch<MCSymbolAttr>(Type)
+ .Case("STT_FUNC", MCSA_ELF_TypeFunction)
+ .Case("STT_OBJECT", MCSA_ELF_TypeObject)
+ .Case("STT_TLS", MCSA_ELF_TypeTLS)
+ .Case("STT_COMMON", MCSA_ELF_TypeCommon)
+ .Case("STT_NOTYPE", MCSA_ELF_TypeNoType)
+ .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction)
+ .Default(MCSA_Invalid);
+ } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) ||
+ getLexer().is(AsmToken::Percent) ||
+ getLexer().is(AsmToken::String)) {
+ if (!getLexer().is(AsmToken::String))
+ Lex();
- TypeLoc = getLexer().getLoc();
- if (getParser().parseIdentifier(Type))
- return TokError("expected symbol type in directive");
-
- MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
- .Case("function", MCSA_ELF_TypeFunction)
- .Case("object", MCSA_ELF_TypeObject)
- .Case("tls_object", MCSA_ELF_TypeTLS)
- .Case("common", MCSA_ELF_TypeCommon)
- .Case("notype", MCSA_ELF_TypeNoType)
- .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
- .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
- .Default(MCSA_Invalid);
+ TypeLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(Type))
+ return TokError("expected symbol type in directive");
+ Attr = StringSwitch<MCSymbolAttr>(Type)
+ .Case("function", MCSA_ELF_TypeFunction)
+ .Case("object", MCSA_ELF_TypeObject)
+ .Case("tls_object", MCSA_ELF_TypeTLS)
+ .Case("common", MCSA_ELF_TypeCommon)
+ .Case("notype", MCSA_ELF_TypeNoType)
+ .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
+ .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
+ .Default(MCSA_Invalid);
+ } else
+ return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
+ "'%<type>' or \"<type>\"");
if (Attr == MCSA_Invalid)
return Error(TypeLoc, "unsupported attribute in '.type' directive");
@@ -536,22 +576,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
Lex();
- const MCSection *Comment =
- getContext().getELFSection(".comment", ELF::SHT_PROGBITS,
- ELF::SHF_MERGE |
- ELF::SHF_STRINGS,
- SectionKind::getReadOnly(),
- 1, "");
-
- getStreamer().PushSection();
- getStreamer().SwitchSection(Comment);
- if (!SeenIdent) {
- getStreamer().EmitIntValue(0, 1);
- SeenIdent = true;
- }
- getStreamer().EmitBytes(Data);
- getStreamer().EmitIntValue(0, 1);
- getStreamer().PopSection();
+ getStreamer().EmitIdent(Data);
return false;
}
diff --git a/contrib/llvm/lib/MC/MCPureStreamer.cpp b/contrib/llvm/lib/MC/MCPureStreamer.cpp
index 8ae724f..f7bf002 100644
--- a/contrib/llvm/lib/MC/MCPureStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCPureStreamer.cpp
@@ -29,7 +29,7 @@ private:
public:
MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
- : MCObjectStreamer(SK_PureStreamer, Context, TAB, OS, Emitter) {}
+ : MCObjectStreamer(Context, 0, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
@@ -40,7 +40,7 @@ public:
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
uint64_t Size = 0, unsigned ByteAlignment = 0);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitBytes(StringRef Data);
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
@@ -51,8 +51,9 @@ public:
virtual void FinishImpl();
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) {
report_fatal_error("unsupported directive in pure streamer");
+ return false;
}
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
report_fatal_error("unsupported directive in pure streamer");
@@ -93,16 +94,13 @@ public:
virtual void EmitFileDirective(StringRef Filename) {
report_fatal_error("unsupported directive in pure streamer");
}
+ virtual void EmitIdent(StringRef IdentString) {
+ report_fatal_error("unsupported directive in pure streamer");
+ }
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename, unsigned CUID = 0) {
report_fatal_error("unsupported directive in pure streamer");
}
-
- /// @}
-
- static bool classof(const MCStreamer *S) {
- return S->getKind() == SK_PureStreamer;
- }
};
} // end anonymous namespace.
@@ -120,7 +118,7 @@ void MCPureStreamer::EmitLabel(MCSymbol *Symbol) {
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSection().first && "Cannot emit before setting section!");
- Symbol->setSection(*getCurrentSection().first);
+ AssignSection(Symbol, getCurrentSection().first);
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
@@ -149,7 +147,7 @@ void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
report_fatal_error("not yet implemented in pure streamer");
}
-void MCPureStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) {
+void MCPureStreamer::EmitBytes(StringRef Data) {
// TODO: This is exactly the same as WinCOFFStreamer. Consider merging into
// MCObjectStreamer.
getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end());
diff --git a/contrib/llvm/lib/MC/MCRegisterInfo.cpp b/contrib/llvm/lib/MC/MCRegisterInfo.cpp
index 5c71106..ce79cd5 100644
--- a/contrib/llvm/lib/MC/MCRegisterInfo.cpp
+++ b/contrib/llvm/lib/MC/MCRegisterInfo.cpp
@@ -46,6 +46,18 @@ unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const {
return 0;
}
+unsigned MCRegisterInfo::getSubRegIdxSize(unsigned Idx) const {
+ assert(Idx && Idx < getNumSubRegIndices() &&
+ "This is not a subregister index");
+ return SubRegIdxRanges[Idx].Size;
+}
+
+unsigned MCRegisterInfo::getSubRegIdxOffset(unsigned Idx) const {
+ assert(Idx && Idx < getNumSubRegIndices() &&
+ "This is not a subregister index");
+ return SubRegIdxRanges[Idx].Offset;
+}
+
int MCRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
diff --git a/contrib/llvm/lib/MC/MCRelocationInfo.cpp b/contrib/llvm/lib/MC/MCRelocationInfo.cpp
new file mode 100644
index 0000000..53c48ded
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCRelocationInfo.cpp
@@ -0,0 +1,39 @@
+//==-- lib/MC/MCRelocationInfo.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/MCRelocationInfo.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm-c/Disassembler.h"
+
+using namespace llvm;
+
+MCRelocationInfo::MCRelocationInfo(MCContext &Ctx)
+ : Ctx(Ctx) {
+}
+
+MCRelocationInfo::~MCRelocationInfo() {
+}
+
+const MCExpr *
+MCRelocationInfo::createExprForRelocation(object::RelocationRef Rel) {
+ return 0;
+}
+
+const MCExpr *
+MCRelocationInfo::createExprForCAPIVariantKind(const MCExpr *SubExpr,
+ unsigned VariantKind) {
+ if (VariantKind != LLVMDisassembler_VariantKind_None)
+ return 0;
+ return SubExpr;
+}
+
+MCRelocationInfo *llvm::createMCRelocationInfo(StringRef TT, MCContext &Ctx) {
+ return new MCRelocationInfo(Ctx);
+}
diff --git a/contrib/llvm/lib/MC/MCSectionCOFF.cpp b/contrib/llvm/lib/MC/MCSectionCOFF.cpp
index 6cedf06..64aa2c5 100644
--- a/contrib/llvm/lib/MC/MCSectionCOFF.cpp
+++ b/contrib/llvm/lib/MC/MCSectionCOFF.cpp
@@ -28,6 +28,17 @@ bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
return false;
}
+void MCSectionCOFF::setSelection(int Selection,
+ const MCSectionCOFF *Assoc) const {
+ assert(Selection != 0 && "invalid COMDAT selection type");
+ assert((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ==
+ (Assoc != 0) &&
+ "associative COMDAT section must have an associated section");
+ this->Selection = Selection;
+ this->Assoc = Assoc;
+ Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+}
+
void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
const MCExpr *Subsection) const {
@@ -63,12 +74,15 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
OS << "\t.linkonce same_contents\n";
break;
- //NOTE: as of binutils 2.20, there is no way to specifiy select largest
- // with the .linkonce directive. For now, we treat it as an invalid
- // comdat selection value.
+ case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+ OS << "\t.linkonce associative " << Assoc->getSectionName() << "\n";
+ break;
case COFF::IMAGE_COMDAT_SELECT_LARGEST:
- // OS << "\t.linkonce largest\n";
- // break;
+ OS << "\t.linkonce largest\n";
+ break;
+ case COFF::IMAGE_COMDAT_SELECT_NEWEST:
+ OS << "\t.linkonce newest\n";
+ break;
default:
assert (0 && "unsupported COFF selection type");
break;
diff --git a/contrib/llvm/lib/MC/MCSectionELF.cpp b/contrib/llvm/lib/MC/MCSectionELF.cpp
index bf1a984..09eb3e7 100644
--- a/contrib/llvm/lib/MC/MCSectionELF.cpp
+++ b/contrib/llvm/lib/MC/MCSectionELF.cpp
@@ -32,6 +32,29 @@ bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
return false;
}
+static void printName(raw_ostream &OS, StringRef Name) {
+ if (Name.find_first_not_of("0123456789_."
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
+ OS << Name;
+ return;
+ }
+ OS << '"';
+ for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
+ if (*B == '"') // Unquoted "
+ OS << "\\\"";
+ else if (*B != '\\') // Neither " or backslash
+ OS << *B;
+ else if (B + 1 == E) // Trailing backslash
+ OS << "\\\\";
+ else {
+ OS << B[0] << B[1]; // Quoted character
+ ++B;
+ }
+ }
+ OS << '"';
+}
+
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
const MCExpr *Subsection) const {
@@ -44,27 +67,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
return;
}
- StringRef name = getSectionName();
- if (name.find_first_not_of("0123456789_."
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == name.npos) {
- OS << "\t.section\t" << name;
- } else {
- OS << "\t.section\t\"";
- for (const char *b = name.begin(), *e = name.end(); b < e; ++b) {
- if (*b == '"') // Unquoted "
- OS << "\\\"";
- else if (*b != '\\') // Neither " or backslash
- OS << *b;
- else if (b + 1 == e) // Trailing backslash
- OS << "\\\\";
- else {
- OS << b[0] << b[1]; // Quoted character
- ++b;
- }
- }
- OS << '"';
- }
+ OS << "\t.section\t";
+ printName(OS, getSectionName());
// Handle the weird solaris syntax if desired.
if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
@@ -75,6 +79,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << ",#execinstr";
if (Flags & ELF::SHF_WRITE)
OS << ",#write";
+ if (Flags & ELF::SHF_EXCLUDE)
+ OS << ",#exclude";
if (Flags & ELF::SHF_TLS)
OS << ",#tls";
OS << '\n';
@@ -84,6 +90,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << ",\"";
if (Flags & ELF::SHF_ALLOC)
OS << 'a';
+ if (Flags & ELF::SHF_EXCLUDE)
+ OS << 'e';
if (Flags & ELF::SHF_EXECINSTR)
OS << 'x';
if (Flags & ELF::SHF_GROUP)
@@ -131,8 +139,11 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
OS << "," << EntrySize;
}
- if (Flags & ELF::SHF_GROUP)
- OS << "," << Group->getName() << ",comdat";
+ if (Flags & ELF::SHF_GROUP) {
+ OS << ",";
+ printName(OS, Group->getName());
+ OS << ",comdat";
+ }
OS << '\n';
if (Subsection)
diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp
index 8f1895e..2e1d69b 100644
--- a/contrib/llvm/lib/MC/MCStreamer.cpp
+++ b/contrib/llvm/lib/MC/MCStreamer.cpp
@@ -10,6 +10,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -21,10 +22,17 @@
#include <cstdlib>
using namespace llvm;
-MCStreamer::MCStreamer(StreamerKind Kind, MCContext &Ctx)
- : Kind(Kind), Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
- CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) {
+// Pin the vtables to this file.
+MCTargetStreamer::~MCTargetStreamer() {}
+void ARMTargetStreamer::anchor() {}
+
+MCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer)
+ : Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true),
+ EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0),
+ AutoInitSections(false) {
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
+ if (TargetStreamer)
+ TargetStreamer->setStreamer(this);
}
MCStreamer::~MCStreamer() {
@@ -58,7 +66,7 @@ const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
}
const MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) {
- if (Context.getAsmInfo().hasAggressiveSymbolFolding() ||
+ if (Context.getAsmInfo()->hasAggressiveSymbolFolding() ||
isa<MCSymbolRefExpr>(Expr))
return Expr;
@@ -72,6 +80,13 @@ raw_ostream &MCStreamer::GetCommentOS() {
return nulls();
}
+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
@@ -86,55 +101,49 @@ void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
/// 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,
- unsigned AddrSpace) {
+void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
assert(Size <= 8 && "Invalid size");
assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
"Invalid size");
char buf[8];
- const bool isLittleEndian = Context.getAsmInfo().isLittleEndian();
+ const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
for (unsigned i = 0; i != Size; ++i) {
unsigned index = isLittleEndian ? i : (Size - i - 1);
buf[i] = uint8_t(Value >> (index * 8));
}
- EmitBytes(StringRef(buf, Size), AddrSpace);
+ EmitBytes(StringRef(buf, Size));
}
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
-void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding,
- unsigned AddrSpace) {
+void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
encodeULEB128(Value, OSE, Padding);
- EmitBytes(OSE.str(), AddrSpace);
+ EmitBytes(OSE.str());
}
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
-void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) {
+void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
encodeSLEB128(Value, OSE);
- EmitBytes(OSE.str(), AddrSpace);
+ EmitBytes(OSE.str());
}
-void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {
+void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) {
const MCExpr *ABS = ForceExpAbs(Value);
- EmitValue(ABS, Size, AddrSpace);
+ EmitValue(ABS, Size);
}
-void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
- unsigned AddrSpace) {
- EmitValueImpl(Value, Size, AddrSpace);
+void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) {
+ EmitValueImpl(Value, Size);
}
-void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
- unsigned AddrSpace) {
- EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size,
- AddrSpace);
+void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) {
+ EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size);
}
void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
@@ -147,11 +156,15 @@ void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
-void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace) {
+void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
const MCExpr *E = MCConstantExpr::Create(FillValue, getContext());
for (uint64_t i = 0, e = NumBytes; i != e; ++i)
- EmitValue(E, 1, AddrSpace);
+ EmitValue(E, 1);
+}
+
+/// The implementation in this class just redirects to EmitFill.
+void MCStreamer::EmitZeros(uint64_t NumBytes) {
+ EmitFill(NumBytes, 0);
}
bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
@@ -185,17 +198,28 @@ void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol) {
}
+void MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) {
+ if (Section)
+ Symbol->setSection(*Section);
+ else
+ Symbol->setUndefined();
+
+ // As we emit symbols into a section, track the order so that they can
+ // be sorted upon later. Zero is reserved to mean 'unemitted'.
+ SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
+}
+
void MCStreamer::EmitLabel(MCSymbol *Symbol) {
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSection().first && "Cannot emit before setting section!");
- Symbol->setSection(*getCurrentSection().first);
+ AssignSection(Symbol, getCurrentSection().first);
LastSymbol = Symbol;
}
void MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSection().first && "Cannot emit before setting section!");
- Symbol->setSection(*getCurrentSection().first);
+ AssignSection(Symbol, getCurrentSection().first);
LastSymbol = Symbol;
}
@@ -229,7 +253,7 @@ void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) {
Frame.Function = LastSymbol;
// If the function is externally visible, we need to create a local
// symbol to avoid relocations.
- StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix();
+ StringRef Prefix = getContext().getAsmInfo()->getPrivateGlobalPrefix();
if (LastSymbol && LastSymbol->getName().startswith(Prefix)) {
Frame.Begin = LastSymbol;
} else {
@@ -382,6 +406,14 @@ void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
CurFrame->Instructions.push_back(Instruction);
}
+void MCStreamer::EmitCFIWindowSave() {
+ MCSymbol *Label = EmitCFICommon();
+ MCCFIInstruction Instruction =
+ MCCFIInstruction::createWindowSave(Label);
+ MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+ CurFrame->Instructions.push_back(Instruction);
+}
+
void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
W64UnwindInfos.push_back(Frame);
CurrentW64UnwindInfo = W64UnwindInfos.back();
@@ -472,7 +504,9 @@ void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) {
report_fatal_error("Frame register and offset already specified!");
if (Offset & 0x0F)
report_fatal_error("Misaligned frame pointer offset!");
- MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, 0, Register, Offset);
+ MCSymbol *Label = getContext().CreateTempSymbol();
+ MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset);
+ EmitLabel(Label);
CurFrame->LastFrameInst = CurFrame->Instructions.size();
CurFrame->Instructions.push_back(Inst);
}
@@ -536,54 +570,10 @@ void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
llvm_unreachable("This file format doesn't support this directive");
}
-void MCStreamer::EmitFnStart() {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitFnEnd() {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitCantUnwind() {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitHandlerData() {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitPersonality(const MCSymbol *Personality) {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitPad(int64_t Offset) {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) {
- errs() << "Not implemented yet\n";
- abort();
-}
-
-void MCStreamer::EmitTCEntry(const MCSymbol &S) {
- llvm_unreachable("Unsupported method");
-}
-
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
-void MCStreamer::EmitRawText(StringRef String) {
+void MCStreamer::EmitRawTextImpl(StringRef String) {
errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
" something must not be fully mc'ized\n";
abort();
@@ -591,19 +581,18 @@ void MCStreamer::EmitRawText(StringRef String) {
void MCStreamer::EmitRawText(const Twine &T) {
SmallString<128> Str;
- T.toVector(Str);
- EmitRawText(Str.str());
+ EmitRawTextImpl(T.toStringRef(Str));
}
-void MCStreamer::EmitFrames(bool usingCFI) {
+void MCStreamer::EmitFrames(MCAsmBackend *MAB, bool usingCFI) {
if (!getNumFrameInfos())
return;
if (EmitEHFrame)
- MCDwarfFrameEmitter::Emit(*this, usingCFI, true);
+ MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, true);
if (EmitDebugFrame)
- MCDwarfFrameEmitter::Emit(*this, usingCFI, false);
+ MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, false);
}
void MCStreamer::EmitW64Tables() {
diff --git a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
index f18828d..8d8e290 100644
--- a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
+++ b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp
@@ -27,6 +27,11 @@ MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
ProcFeatures, NumFeatures);
+ InitCPUSchedModel(CPU);
+}
+
+void
+MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) {
if (!CPU.empty())
CPUSchedModel = getSchedModelForCPU(CPU);
else
@@ -91,10 +96,8 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
#endif
// Find entry
- SubtargetInfoKV KV;
- KV.Key = CPU.data();
const SubtargetInfoKV *Found =
- std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, KV);
+ std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, CPU);
if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) {
errs() << "'" << CPU
<< "' is not a recognized processor for this target"
diff --git a/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp
index b973c57..2416525 100644
--- a/contrib/llvm/lib/MC/MCSymbol.cpp
+++ b/contrib/llvm/lib/MC/MCSymbol.cpp
@@ -68,12 +68,23 @@ void MCSymbol::print(raw_ostream &OS) const {
// The name for this MCSymbol is required to be a valid target name. However,
// some targets support quoting names with funny characters. If the name
// contains a funny character, then print it quoted.
- if (!NameNeedsQuoting(getName())) {
- OS << getName();
+ StringRef Name = getName();
+ if (!NameNeedsQuoting(Name)) {
+ OS << Name;
return;
}
- OS << '"' << getName() << '"';
+ OS << '"';
+ for (unsigned I = 0, E = Name.size(); I != E; ++I) {
+ char C = Name[I];
+ if (C == '\n')
+ OS << "\\n";
+ else if (C == '"')
+ OS << "\\\"";
+ else
+ OS << C;
+ }
+ OS << '"';
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/contrib/llvm/lib/MC/MCSymbolizer.cpp b/contrib/llvm/lib/MC/MCSymbolizer.cpp
new file mode 100644
index 0000000..1020b74
--- /dev/null
+++ b/contrib/llvm/lib/MC/MCSymbolizer.cpp
@@ -0,0 +1,20 @@
+//===-- llvm/MC/MCSymbolizer.cpp - MCSymbolizer class -----------*- 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/MCSymbolizer.h"
+#include "llvm/MC/MCRelocationInfo.h"
+
+using namespace llvm;
+
+MCSymbolizer::MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo)
+ : Ctx(Ctx), RelInfo(RelInfo.take()) {
+}
+
+MCSymbolizer::~MCSymbolizer() {
+}
diff --git a/contrib/llvm/lib/MC/MCWin64EH.cpp b/contrib/llvm/lib/MC/MCWin64EH.cpp
index c5b637c..b8b07d3 100644
--- a/contrib/llvm/lib/MC/MCWin64EH.cpp
+++ b/contrib/llvm/lib/MC/MCWin64EH.cpp
@@ -64,7 +64,7 @@ static void EmitAbsDifference(MCStreamer &streamer, MCSymbol *lhs,
static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
MCWin64EHInstruction &inst) {
- uint8_t b1, b2;
+ uint8_t b2;
uint16_t w;
b2 = (inst.getOperation() & 0x0F);
switch (inst.getOperation()) {
@@ -93,8 +93,7 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SetFPReg:
- b1 = inst.getOffset() & 0xF0;
- streamer.EmitIntValue(b1, 1);
+ EmitAbsDifference(streamer, inst.getLabel(), begin);
streamer.EmitIntValue(b2, 1);
break;
case Win64EH::UOP_SaveNonVol:
@@ -129,14 +128,29 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
}
}
+static void EmitSymbolRefWithOfs(MCStreamer &streamer,
+ const MCSymbol *Base,
+ const MCSymbol *Other) {
+ MCContext &Context = streamer.getContext();
+ const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::Create(Base, Context);
+ const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::Create(Other, Context);
+ const MCExpr *Ofs = MCBinaryExpr::CreateSub(OtherRef, BaseRef, Context);
+ const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::Create(Base,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ Context);
+ streamer.EmitValue(MCBinaryExpr::CreateAdd(BaseRefRel, Ofs, Context), 4);
+}
+
static void EmitRuntimeFunction(MCStreamer &streamer,
const MCWin64EHUnwindInfo *info) {
MCContext &context = streamer.getContext();
streamer.EmitValueToAlignment(4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->Begin, context), 4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->End, context), 4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol, context), 4);
+ EmitSymbolRefWithOfs(streamer, info->Function, info->Begin);
+ EmitSymbolRefWithOfs(streamer, info->Function, info->End);
+ streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ context), 4);
}
static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
@@ -145,11 +159,11 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
MCContext &context = streamer.getContext();
streamer.EmitValueToAlignment(4);
- // Upper 3 bits are the version number (currently 1).
- uint8_t flags = 0x01;
info->Symbol = context.CreateTempSymbol();
streamer.EmitLabel(info->Symbol);
+ // Upper 3 bits are the version number (currently 1).
+ uint8_t flags = 0x01;
if (info->ChainedParent)
flags |= Win64EH::UNW_ChainInfo << 3;
else {
@@ -185,20 +199,26 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
EmitUnwindCode(streamer, info->Begin, inst);
}
+ // For alignment purposes, the instruction array will always have an even
+ // number of entries, with the final entry potentially unused (in which case
+ // the array will be one longer than indicated by the count of unwind codes
+ // field).
+ if (numCodes & 1) {
+ streamer.EmitIntValue(0, 2);
+ }
+
if (flags & (Win64EH::UNW_ChainInfo << 3))
EmitRuntimeFunction(streamer, info->ChainedParent);
else if (flags &
((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3))
- streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, context),
- 4);
- else if (numCodes < 2) {
+ streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ context), 4);
+ else if (numCodes == 0) {
// The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not
// a chained unwind info, if there is no handler, and if there are fewer
// than 2 slots used in the unwind code array, we have to pad to 8 bytes.
- if (numCodes == 1)
- streamer.EmitIntValue(0, 2);
- else
- streamer.EmitIntValue(0, 4);
+ streamer.EmitIntValue(0, 4);
}
}
diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp
index a5ba3c3..8234aff 100644
--- a/contrib/llvm/lib/MC/MachObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp
@@ -20,12 +20,11 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MachO.h"
#include <vector>
using namespace llvm;
-using namespace llvm::object;
void MachObjectWriter::reset() {
Relocations.clear();
@@ -128,7 +127,7 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
uint32_t Flags = 0;
if (SubsectionsViaSymbols)
- Flags |= macho::HF_SubsectionsViaSymbols;
+ Flags |= MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
// struct mach_header (28 bytes) or
// struct mach_header_64 (32 bytes)
@@ -136,12 +135,12 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
uint64_t Start = OS.tell();
(void) Start;
- Write32(is64Bit() ? macho::HM_Object64 : macho::HM_Object32);
+ Write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
Write32(TargetObjectWriter->getCPUType());
Write32(TargetObjectWriter->getCPUSubtype());
- Write32(macho::HFT_Object);
+ Write32(MachO::MH_OBJECT);
Write32(NumLoadCommands);
Write32(LoadCommandsSize);
Write32(Flags);
@@ -149,7 +148,7 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
Write32(0); // reserved
assert(OS.tell() - Start ==
- (is64Bit() ? macho::Header64Size : macho::Header32Size));
+ (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header)));
}
/// WriteSegmentLoadCommand - Write a segment load command.
@@ -167,12 +166,12 @@ void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
(void) Start;
unsigned SegmentLoadCommandSize =
- is64Bit() ? macho::SegmentLoadCommand64Size:
- macho::SegmentLoadCommand32Size;
- Write32(is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment);
+ is64Bit() ? sizeof(MachO::segment_command_64):
+ sizeof(MachO::segment_command);
+ Write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
Write32(SegmentLoadCommandSize +
- NumSections * (is64Bit() ? macho::Section64Size :
- macho::Section32Size));
+ NumSections * (is64Bit() ? sizeof(MachO::section_64) :
+ sizeof(MachO::section)));
WriteBytes("", 16);
if (is64Bit()) {
@@ -186,8 +185,10 @@ void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
Write32(SectionDataStartOffset); // file offset
Write32(SectionDataSize); // file size
}
- Write32(0x7); // maxprot
- Write32(0x7); // initprot
+ // maxprot
+ Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
+ // initprot
+ Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE);
Write32(NumSections);
Write32(0); // flags
@@ -240,8 +241,8 @@ void MachObjectWriter::WriteSection(const MCAssembler &Asm,
if (is64Bit())
Write32(0); // reserved3
- assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size :
- macho::Section32Size));
+ assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) :
+ sizeof(MachO::section)));
}
void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
@@ -253,14 +254,14 @@ void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
uint64_t Start = OS.tell();
(void) Start;
- Write32(macho::LCT_Symtab);
- Write32(macho::SymtabLoadCommandSize);
+ Write32(MachO::LC_SYMTAB);
+ Write32(sizeof(MachO::symtab_command));
Write32(SymbolOffset);
Write32(NumSymbols);
Write32(StringTableOffset);
Write32(StringTableSize);
- assert(OS.tell() - Start == macho::SymtabLoadCommandSize);
+ assert(OS.tell() - Start == sizeof(MachO::symtab_command));
}
void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
@@ -276,8 +277,8 @@ void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
uint64_t Start = OS.tell();
(void) Start;
- Write32(macho::LCT_Dysymtab);
- Write32(macho::DysymtabLoadCommandSize);
+ Write32(MachO::LC_DYSYMTAB);
+ Write32(sizeof(MachO::dysymtab_command));
Write32(FirstLocalSymbol);
Write32(NumLocalSymbols);
Write32(FirstExternalSymbol);
@@ -297,7 +298,7 @@ void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
Write32(0); // locreloff
Write32(0); // nlocrel
- assert(OS.tell() - Start == macho::DysymtabLoadCommandSize);
+ assert(OS.tell() - Start == sizeof(MachO::dysymtab_command));
}
void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
@@ -312,20 +313,20 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
//
// FIXME: Are the prebound or indirect fields possible here?
if (Symbol.isUndefined())
- Type = macho::STT_Undefined;
+ Type = MachO::N_UNDF;
else if (Symbol.isAbsolute())
- Type = macho::STT_Absolute;
+ Type = MachO::N_ABS;
else
- Type = macho::STT_Section;
+ Type = MachO::N_SECT;
// FIXME: Set STAB bits.
if (Data.isPrivateExtern())
- Type |= macho::STF_PrivateExtern;
+ Type |= MachO::N_PEXT;
// Set external bit.
if (Data.isExternal() || Symbol.isUndefined())
- Type |= macho::STF_External;
+ Type |= MachO::N_EXT;
// Compute the symbol address.
if (Symbol.isDefined()) {
@@ -341,7 +342,8 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
if (Log2Size > 15)
report_fatal_error("invalid 'common' alignment '" +
- Twine(Align) + "'");
+ Twine(Align) + "' for '" + Symbol.getName() + "'",
+ false);
// FIXME: Keep this mask with the SymbolFlags enumeration.
Flags = (Flags & 0xF0FF) | (Log2Size << 8);
}
@@ -369,17 +371,17 @@ void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
(void) Start;
Write32(Type);
- Write32(macho::LinkeditLoadCommandSize);
+ Write32(sizeof(MachO::linkedit_data_command));
Write32(DataOffset);
Write32(DataSize);
- assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
+ assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command));
}
static unsigned ComputeLinkerOptionsLoadCommandSize(
const std::vector<std::string> &Options, bool is64Bit)
{
- unsigned Size = sizeof(macho::LinkerOptionsLoadCommand);
+ unsigned Size = sizeof(MachO::linker_options_command);
for (unsigned i = 0, e = Options.size(); i != e; ++i)
Size += Options[i].size() + 1;
return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
@@ -392,10 +394,10 @@ void MachObjectWriter::WriteLinkerOptionsLoadCommand(
uint64_t Start = OS.tell();
(void) Start;
- Write32(macho::LCT_LinkerOptions);
+ Write32(MachO::LC_LINKER_OPTIONS);
Write32(Size);
Write32(Options.size());
- uint64_t BytesWritten = sizeof(macho::LinkerOptionsLoadCommand);
+ uint64_t BytesWritten = sizeof(MachO::linker_options_command);
for (unsigned i = 0, e = Options.size(); i != e; ++i) {
// Write each string, including the null byte.
const std::string &Option = Options[i];
@@ -428,6 +430,22 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
//
// FIXME: Revisit this when the dust settles.
+ // Report errors for use of .indirect_symbol not in a symbol pointer section
+ // or stub section.
+ for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
+ ie = Asm.indirect_symbol_end(); it != ie; ++it) {
+ const MCSectionMachO &Section =
+ cast<MCSectionMachO>(it->SectionData->getSection());
+
+ if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+ Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) {
+ MCSymbol &Symbol = *it->Symbol;
+ report_fatal_error("indirect symbol '" + Symbol.getName() +
+ "' not in a symbol pointer or stub section");
+ }
+ }
+
// Bind non lazy symbol pointers first.
unsigned IndirectIndex = 0;
for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
@@ -723,14 +741,14 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// section headers) and the symbol table.
unsigned NumLoadCommands = 1;
uint64_t LoadCommandsSize = is64Bit() ?
- macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
- macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
+ sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
+ sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
// Add the data-in-code load command size, if used.
unsigned NumDataRegions = Asm.getDataRegions().size();
if (NumDataRegions) {
++NumLoadCommands;
- LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ LoadCommandsSize += sizeof(MachO::linkedit_data_command);
}
// Add the symbol table load command sizes, if used.
@@ -738,8 +756,8 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
UndefinedSymbolData.size();
if (NumSymbols) {
NumLoadCommands += 2;
- LoadCommandsSize += (macho::SymtabLoadCommandSize +
- macho::DysymtabLoadCommandSize);
+ LoadCommandsSize += (sizeof(MachO::symtab_command) +
+ sizeof(MachO::dysymtab_command));
}
// Add the linker option load commands sizes.
@@ -753,8 +771,8 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// Compute the total size of the section data, as well as its file size and vm
// size.
- uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
- macho::Header32Size) + LoadCommandsSize;
+ uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
+ sizeof(MachO::mach_header)) + LoadCommandsSize;
uint64_t SectionDataSize = 0;
uint64_t SectionDataFileSize = 0;
uint64_t VMSize = 0;
@@ -791,11 +809,11 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
- std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
+ std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
unsigned NumRelocs = Relocs.size();
uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
- RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
+ RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
}
// Write the data-in-code load command, if used.
@@ -803,7 +821,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
if (NumDataRegions) {
uint64_t DataRegionsOffset = RelocTableEnd;
uint64_t DataRegionsSize = NumDataRegions * 8;
- WriteLinkeditLoadCommand(macho::LCT_DataInCode, DataRegionsOffset,
+ WriteLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset,
DataRegionsSize);
}
@@ -830,8 +848,9 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// The string table is written after symbol table.
uint64_t StringTableOffset =
- SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? macho::Nlist64Size :
- macho::Nlist32Size);
+ SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
+ sizeof(MachO::nlist_64) :
+ sizeof(MachO::nlist));
WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
StringTableOffset, StringTable.size());
@@ -864,10 +883,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
ie = Asm.end(); it != ie; ++it) {
// Write the section relocation entries, in reverse order to match 'as'
// (approximately, the exact algorithm is more complicated than this).
- std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
+ std::vector<MachO::any_relocation_info> &Relocs = Relocations[it];
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
- Write32(Relocs[e - i - 1].Word0);
- Write32(Relocs[e - i - 1].Word1);
+ Write32(Relocs[e - i - 1].r_word0);
+ Write32(Relocs[e - i - 1].r_word1);
}
}
@@ -906,9 +925,9 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// If this symbol is defined and internal, mark it as such.
if (it->Symbol->isDefined() &&
!Asm.getSymbolData(*it->Symbol).isExternal()) {
- uint32_t Flags = macho::ISF_Local;
+ uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
if (it->Symbol->isAbsolute())
- Flags |= macho::ISF_Absolute;
+ Flags |= MachO::INDIRECT_SYMBOL_ABS;
Write32(Flags);
continue;
}
diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp
index 7625abd..2fb91f2 100644
--- a/contrib/llvm/lib/MC/SubtargetFeature.cpp
+++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp
@@ -121,13 +121,10 @@ void SubtargetFeatures::AddFeature(const StringRef String,
/// Find KV in array using binary search.
static const SubtargetFeatureKV *Find(StringRef S, const SubtargetFeatureKV *A,
size_t L) {
- // Make the lower bound element we're looking for
- SubtargetFeatureKV KV;
- KV.Key = S.data();
// Determine the end of the array
const SubtargetFeatureKV *Hi = A + L;
// Binary search the array
- const SubtargetFeatureKV *F = std::lower_bound(A, Hi, KV);
+ const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S);
// If not found then return NULL
if (F == Hi || StringRef(F->Key) != S) return NULL;
// Return the found array item
@@ -353,8 +350,7 @@ void SubtargetFeatures::dump() const {
}
#endif
-/// getDefaultSubtargetFeatures - Return a string listing the features
-/// associated with the target triple.
+/// Adds the default features for the specified target triple.
///
/// FIXME: This is an inelegant way of specifying the features of a
/// subtarget. It would be better if we could encode this information
diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 518b59e..d9ca86d 100644
--- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
@@ -137,7 +138,7 @@ public:
symbol_map SymbolMap;
WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS);
- ~WinCOFFObjectWriter();
+ virtual ~WinCOFFObjectWriter();
COFFSymbol *createSymbol(StringRef Name);
COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol);
@@ -147,13 +148,12 @@ public:
object_t *createCOFFEntity(StringRef Name, list_t &List);
void DefineSection(MCSectionData const &SectionData);
- void DefineSymbol(MCSymbolData const &SymbolData,
- MCAssembler &Assembler);
+ void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler,
+ const MCAsmLayout &Layout);
void MakeSymbolReal(COFFSymbol &S, size_t Index);
void MakeSectionReal(COFFSection &S, size_t Number);
- bool ExportSection(COFFSection const *S);
bool ExportSymbol(MCSymbolData const &SymbolData, MCAssembler &Asm);
bool IsPhysicalSection(COFFSection *S);
@@ -189,17 +189,6 @@ static inline void write_uint32_le(void *Data, uint32_t const &Value) {
Ptr[3] = (Value & 0xFF000000) >> 24;
}
-static inline void write_uint16_le(void *Data, uint16_t const &Value) {
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
- Ptr[0] = (Value & 0x00FF) >> 0;
- Ptr[1] = (Value & 0xFF00) >> 8;
-}
-
-static inline void write_uint8_le(void *Data, uint8_t const &Value) {
- uint8_t *Ptr = reinterpret_cast<uint8_t *>(Data);
- Ptr[0] = (Value & 0xFF) >> 0;
-}
-
//------------------------------------------------------------------------------
// Symbol class implementation
@@ -410,7 +399,8 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
/// This function takes a section data object from the assembler
/// and creates the associated COFF symbol staging object.
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
- MCAssembler &Assembler) {
+ MCAssembler &Assembler,
+ const MCAsmLayout &Layout) {
MCSymbol const &Symbol = SymbolData.getSymbol();
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
SymbolMap[&Symbol] = coff_symbol;
@@ -451,6 +441,12 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
const MCSymbolData &ResSymData =
Assembler.getSymbolData(Symbol.AliasedSymbol());
+ if (Symbol.isVariable()) {
+ int64_t Addr;
+ if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout))
+ coff_symbol->Data.Value = Addr;
+ }
+
coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0;
coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16;
@@ -462,7 +458,9 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
}
- if (ResSymData.Fragment != NULL)
+ if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable())
+ coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
+ else if (ResSymData.Fragment != NULL)
coff_symbol->Section =
SectionMap[&ResSymData.Fragment->getParent()->getSection()];
@@ -474,18 +472,21 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
/// name into the string table if needed
void WinCOFFObjectWriter::MakeSectionReal(COFFSection &S, size_t Number) {
if (S.Name.size() > COFF::NameSize) {
- size_t StringTableEntry = Strings.insert(S.Name.c_str());
-
- // FIXME: Why is this number 999999? This number is never mentioned in the
- // spec. I'm assuming this is due to the printed value needing to fit into
- // the S.Header.Name field. In which case why not 9999999 (7 9's instead of
- // 6)? The spec does not state if this entry should be null terminated in
- // this case, and thus this seems to be the best way to do it. I think I
- // just solved my own FIXME...
- if (StringTableEntry > 999999)
- report_fatal_error("COFF string table is greater than 999999 bytes.");
-
- std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
+ const unsigned Max6DecimalSize = 999999;
+ const unsigned Max7DecimalSize = 9999999;
+ uint64_t StringTableEntry = Strings.insert(S.Name.c_str());
+
+ if (StringTableEntry <= Max6DecimalSize) {
+ std::sprintf(S.Header.Name, "/%d", unsigned(StringTableEntry));
+ } else if (StringTableEntry <= Max7DecimalSize) {
+ // With seven digits, we have to skip the terminating null. Because
+ // sprintf always appends it, we use a larger temporary buffer.
+ char buffer[9] = { };
+ std::sprintf(buffer, "/%d", unsigned(StringTableEntry));
+ std::memcpy(S.Header.Name, buffer, 8);
+ } else {
+ report_fatal_error("COFF string table is greater than 9,999,999 bytes.");
+ }
} else
std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
@@ -504,10 +505,6 @@ void WinCOFFObjectWriter::MakeSymbolReal(COFFSymbol &S, size_t Index) {
S.Index = Index;
}
-bool WinCOFFObjectWriter::ExportSection(COFFSection const *S) {
- return !S->MCData->getFragmentList().empty();
-}
-
bool WinCOFFObjectWriter::ExportSymbol(MCSymbolData const &SymbolData,
MCAssembler &Asm) {
// This doesn't seem to be right. Strings referred to from the .data section
@@ -621,9 +618,10 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
DefineSection(*i);
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
- e = Asm.symbol_end(); i != e; i++) {
+ e = Asm.symbol_end();
+ i != e; i++) {
if (ExportSymbol(*i, Asm)) {
- DefineSymbol(*i, Asm);
+ DefineSymbol(*i, Asm, Layout);
}
}
}
@@ -636,8 +634,9 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
uint64_t &FixedValue) {
assert(Target.getSymA() != NULL && "Relocation must reference a symbol!");
- const MCSymbol *A = &Target.getSymA()->getSymbol();
- MCSymbolData &A_SD = Asm.getSymbolData(*A);
+ const MCSymbol &Symbol = Target.getSymA()->getSymbol();
+ const MCSymbol &A = Symbol.AliasedSymbol();
+ MCSymbolData &A_SD = Asm.getSymbolData(A);
MCSectionData const *SectionData = Fragment->getParent();
@@ -707,10 +706,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
// Assign symbol and section indexes and offsets.
Header.NumberOfSections = 0;
+ DenseMap<COFFSection *, uint16_t> SectionIndices;
for (sections::iterator i = Sections.begin(),
e = Sections.end(); i != e; i++) {
if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
- MakeSectionReal(**i, ++Header.NumberOfSections);
+ size_t Number = ++Header.NumberOfSections;
+ SectionIndices[*i] = Number;
+ MakeSectionReal(**i, Number);
} else {
(*i)->Number = -1;
}
@@ -754,6 +756,31 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
}
}
+ // Fixup associative COMDAT sections.
+ for (sections::iterator i = Sections.begin(),
+ e = Sections.end(); i != e; i++) {
+ if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+ continue;
+
+ const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>(
+ (*i)->MCData->getSection());
+
+ COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
+ if (!Assoc) {
+ report_fatal_error(Twine("Missing associated COMDAT section ") +
+ MCSec.getAssocSection()->getSectionName() +
+ " for section " + MCSec.getSectionName());
+ }
+
+ // Skip this section if the associated section is unused.
+ if (Assoc->Number == -1)
+ continue;
+
+ (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
+ }
+
+
// Assign file offsets to COFF object file structures.
unsigned offset = 0;
@@ -888,6 +915,9 @@ MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) :
Machine(Machine_) {
}
+// Pin the vtable to this file.
+void MCWinCOFFObjectTargetWriter::anchor() {}
+
//------------------------------------------------------------------------------
// WinCOFFObjectWriter factory function
diff --git a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
index 75f343c..5b5aad7 100644
--- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
+++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp
@@ -55,7 +55,7 @@ public:
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
- virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+ virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
virtual void EmitCOFFSymbolStorageClass(int StorageClass);
@@ -72,13 +72,10 @@ public:
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment);
virtual void EmitFileDirective(StringRef Filename);
+ virtual void EmitIdent(StringRef IdentString);
virtual void EmitWin64EHHandlerData();
virtual void FinishImpl();
- static bool classof(const MCStreamer *S) {
- return S->getKind() == SK_WinCOFFStreamer;
- }
-
private:
virtual void EmitInstToData(const MCInst &Inst) {
MCDataFragment *DF = getOrCreateDataFragment();
@@ -134,8 +131,7 @@ private:
WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
MCCodeEmitter &CE, raw_ostream &OS)
- : MCObjectStreamer(SK_WinCOFFStreamer, Context, MAB, OS, &CE),
- CurSymbol(NULL) {}
+ : MCObjectStreamer(Context, 0, MAB, OS, &CE), CurSymbol(NULL) {}
void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, bool External) {
@@ -155,7 +151,8 @@ void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
int Selection = COFF::IMAGE_COMDAT_SELECT_LARGEST;
const MCSection *Section = MCStreamer::getContext().getCOFFSection(
- SectionName, Characteristics, Selection, SectionKind::getBSS());
+ SectionName, Characteristics, SectionKind::getBSS(), Symbol->getName(),
+ Selection);
MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section);
@@ -164,7 +161,7 @@ void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
SymbolData.setExternal(External);
- Symbol->setSection(*Section);
+ AssignSection(Symbol, Section);
if (ByteAlignment != 1)
new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectionData);
@@ -201,7 +198,7 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
+bool WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
assert(Symbol && "Symbol must be non-null!");
assert((Symbol->isInSection()
@@ -221,8 +218,10 @@ void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
break;
default:
- llvm_unreachable("unsupported attribute");
+ return false;
}
+
+ return true;
}
void WinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
@@ -309,6 +308,11 @@ void WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
// info will be a much large effort.
}
+// TODO: Implement this if you want to emit .comment section in COFF obj files.
+void WinCOFFStreamer::EmitIdent(StringRef IdentString) {
+ llvm_unreachable("unsupported directive");
+}
+
void WinCOFFStreamer::EmitWin64EHHandlerData() {
MCStreamer::EmitWin64EHHandlerData();
@@ -318,6 +322,7 @@ void WinCOFFStreamer::EmitWin64EHHandlerData() {
}
void WinCOFFStreamer::FinishImpl() {
+ EmitFrames(NULL, true);
EmitW64Tables();
MCObjectStreamer::FinishImpl();
}
OpenPOWER on IntegriCloud