diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
| commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
| tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/MC/MCAsmStreamer.cpp | |
| parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) | |
Notes
Diffstat (limited to 'lib/MC/MCAsmStreamer.cpp')
| -rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 197 |
1 files changed, 137 insertions, 60 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 9e5553fa8d42..3357553cf19f 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -22,17 +22,14 @@ #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" #include <cctype> using namespace llvm; @@ -140,6 +137,8 @@ public: void EmitDataRegion(MCDataRegionType Kind) override; void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor, unsigned Update) override; + void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, + unsigned Update) override; void EmitThumbFunc(MCSymbol *Func) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; @@ -225,7 +224,9 @@ public: StringRef FileName) override; MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override; - bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override; + bool EmitCVFileDirective(unsigned FileNo, StringRef Filename, + ArrayRef<uint8_t> Checksum, + unsigned ChecksumKind) override; bool EmitCVFuncIdDirective(unsigned FuncId) override; bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, @@ -245,6 +246,8 @@ public: StringRef FixedSizePortion) override; void EmitCVStringTableDirective() override; void EmitCVFileChecksumsDirective() override; + void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override; + void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override; void EmitIdent(StringRef IdentString) override; void EmitCFISections(bool EH, bool Debug) override; @@ -256,6 +259,7 @@ public: void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override; void EmitCFIRememberState() override; void EmitCFIRestoreState() override; + void EmitCFIRestore(int64_t Register) override; void EmitCFISameValue(int64_t Register) override; void EmitCFIRelOffset(int64_t Register, int64_t Offset) override; void EmitCFIAdjustCfaOffset(int64_t Adjustment) override; @@ -265,21 +269,26 @@ public: void EmitCFIUndefined(int64_t Register) override; void EmitCFIRegister(int64_t Register1, int64_t Register2) override; void EmitCFIWindowSave() override; + void EmitCFIReturnColumn(int64_t Register) override; + + void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override; + void EmitWinCFIEndProc(SMLoc Loc) override; + void EmitWinCFIStartChained(SMLoc Loc) override; + void EmitWinCFIEndChained(SMLoc Loc) override; + void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override; + void EmitWinCFISetFrame(unsigned Register, unsigned Offset, + SMLoc Loc) override; + void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override; + void EmitWinCFISaveReg(unsigned Register, unsigned Offset, + SMLoc Loc) override; + void EmitWinCFISaveXMM(unsigned Register, unsigned Offset, + SMLoc Loc) override; + void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override; + void EmitWinCFIEndProlog(SMLoc Loc) override; - void EmitWinCFIStartProc(const MCSymbol *Symbol) override; - void EmitWinCFIEndProc() override; - void EmitWinCFIStartChained() override; - void EmitWinCFIEndChained() override; - void EmitWinCFIPushReg(unsigned Register) override; - void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override; - void EmitWinCFIAllocStack(unsigned Size) override; - void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override; - void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override; - void EmitWinCFIPushFrame(bool Code) override; - void EmitWinCFIEndProlog() override; - - void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override; - void EmitWinEHHandlerData() override; + void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, + SMLoc Loc) override; + void EmitWinEHHandlerData(SMLoc Loc) override; void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo) override; @@ -464,15 +473,39 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) { EmitEOL(); } -void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major, +static const char *getVersionMinDirective(MCVersionMinType Type) { + switch (Type) { + case MCVM_WatchOSVersionMin: return ".watchos_version_min"; + case MCVM_TvOSVersionMin: return ".tvos_version_min"; + case MCVM_IOSVersionMin: return ".ios_version_min"; + case MCVM_OSXVersionMin: return ".macosx_version_min"; + } + llvm_unreachable("Invalid MC version min type"); +} + +void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update) { - switch (Kind) { - case MCVM_WatchOSVersionMin: OS << "\t.watchos_version_min"; break; - case MCVM_TvOSVersionMin: OS << "\t.tvos_version_min"; break; - case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break; - case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break; + OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor; + if (Update) + OS << ", " << Update; + EmitEOL(); +} + +static const char *getPlatformName(MachO::PlatformType Type) { + switch (Type) { + case MachO::PLATFORM_MACOS: return "macos"; + case MachO::PLATFORM_IOS: return "ios"; + case MachO::PLATFORM_TVOS: return "tvos"; + case MachO::PLATFORM_WATCHOS: return "watchos"; + case MachO::PLATFORM_BRIDGEOS: return "bridgeos"; } - OS << " " << Major << ", " << Minor; + llvm_unreachable("Invalid Mach-O platform type"); +} + +void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major, + unsigned Minor, unsigned Update) { + const char *PlatformName = getPlatformName((MachO::PlatformType)Platform); + OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor; if (Update) OS << ", " << Update; EmitEOL(); @@ -1119,13 +1152,25 @@ MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) { return MCStreamer::getDwarfLineTableSymbol(0); } -bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) { - if (!getContext().getCVContext().addFile(FileNo, Filename)) +bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename, + ArrayRef<uint8_t> Checksum, + unsigned ChecksumKind) { + if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum, + ChecksumKind)) return false; OS << "\t.cv_file\t" << FileNo << ' '; - PrintQuotedString(Filename, OS); + + if (!ChecksumKind) { + EmitEOL(); + return true; + } + + OS << ' '; + PrintQuotedString(toHex(Checksum), OS); + OS << ' ' << ChecksumKind; + EmitEOL(); return true; } @@ -1227,6 +1272,17 @@ void MCAsmStreamer::EmitCVFileChecksumsDirective() { EmitEOL(); } +void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) { + OS << "\t.cv_filechecksumoffset\t" << FileNo; + EmitEOL(); +} + +void MCAsmStreamer::EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) { + OS << "\t.cv_fpo_data\t"; + ProcSym->print(OS, MAI); + EmitEOL(); +} + void MCAsmStreamer::EmitIdent(StringRef IdentString) { assert(MAI->hasIdentDirective() && ".ident directive not supported"); OS << "\t.ident\t"; @@ -1263,12 +1319,17 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { void MCAsmStreamer::EmitRegisterName(int64_t Register) { if (!MAI->useDwarfRegNumForCFI()) { + // User .cfi_* directives can use arbitrary DWARF register numbers, not + // just ones that map to LLVM register numbers and have known names. + // Fall back to using the original number directly if no name is known. const MCRegisterInfo *MRI = getContext().getRegisterInfo(); - unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true); - InstPrinter->printRegName(OS, LLVMRegister); - } else { - OS << Register; + int LLVMRegister = MRI->getLLVMRegNumFromEH(Register); + if (LLVMRegister != -1) { + InstPrinter->printRegName(OS, LLVMRegister); + return; + } } + OS << Register; } void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { @@ -1353,6 +1414,13 @@ void MCAsmStreamer::EmitCFIRestoreState() { EmitEOL(); } +void MCAsmStreamer::EmitCFIRestore(int64_t Register) { + MCStreamer::EmitCFIRestore(Register); + OS << "\t.cfi_restore "; + EmitRegisterName(Register); + EmitEOL(); +} + void MCAsmStreamer::EmitCFISameValue(int64_t Register) { MCStreamer::EmitCFISameValue(Register); OS << "\t.cfi_same_value "; @@ -1398,38 +1466,44 @@ void MCAsmStreamer::EmitCFIWindowSave() { EmitEOL(); } -void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { - MCStreamer::EmitWinCFIStartProc(Symbol); +void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) { + MCStreamer::EmitCFIReturnColumn(Register); + OS << "\t.cfi_return_column " << Register; + EmitEOL(); +} + +void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) { + MCStreamer::EmitWinCFIStartProc(Symbol, Loc); OS << ".seh_proc "; Symbol->print(OS, MAI); EmitEOL(); } -void MCAsmStreamer::EmitWinCFIEndProc() { - MCStreamer::EmitWinCFIEndProc(); +void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) { + MCStreamer::EmitWinCFIEndProc(Loc); OS << "\t.seh_endproc"; EmitEOL(); } -void MCAsmStreamer::EmitWinCFIStartChained() { - MCStreamer::EmitWinCFIStartChained(); +void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) { + MCStreamer::EmitWinCFIStartChained(Loc); OS << "\t.seh_startchained"; EmitEOL(); } -void MCAsmStreamer::EmitWinCFIEndChained() { - MCStreamer::EmitWinCFIEndChained(); +void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) { + MCStreamer::EmitWinCFIEndChained(Loc); OS << "\t.seh_endchained"; EmitEOL(); } void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, - bool Except) { - MCStreamer::EmitWinEHHandler(Sym, Unwind, Except); + bool Except, SMLoc Loc) { + MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc); OS << "\t.seh_handler "; Sym->print(OS, MAI); @@ -1440,8 +1514,8 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, EmitEOL(); } -void MCAsmStreamer::EmitWinEHHandlerData() { - MCStreamer::EmitWinEHHandlerData(); +void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) { + MCStreamer::EmitWinEHHandlerData(Loc); // Switch sections. Don't call SwitchSection directly, because that will // cause the section switch to be visible in the emitted assembly. @@ -1456,43 +1530,46 @@ void MCAsmStreamer::EmitWinEHHandlerData() { EmitEOL(); } -void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) { - MCStreamer::EmitWinCFIPushReg(Register); +void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) { + MCStreamer::EmitWinCFIPushReg(Register, Loc); OS << "\t.seh_pushreg " << Register; EmitEOL(); } -void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISetFrame(Register, Offset); +void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset, + SMLoc Loc) { + MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc); OS << "\t.seh_setframe " << Register << ", " << Offset; EmitEOL(); } -void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) { - MCStreamer::EmitWinCFIAllocStack(Size); +void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) { + MCStreamer::EmitWinCFIAllocStack(Size, Loc); OS << "\t.seh_stackalloc " << Size; EmitEOL(); } -void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISaveReg(Register, Offset); +void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset, + SMLoc Loc) { + MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc); OS << "\t.seh_savereg " << Register << ", " << Offset; EmitEOL(); } -void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { - MCStreamer::EmitWinCFISaveXMM(Register, Offset); +void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset, + SMLoc Loc) { + MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc); OS << "\t.seh_savexmm " << Register << ", " << Offset; EmitEOL(); } -void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) { - MCStreamer::EmitWinCFIPushFrame(Code); +void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) { + MCStreamer::EmitWinCFIPushFrame(Code, Loc); OS << "\t.seh_pushframe"; if (Code) @@ -1500,8 +1577,8 @@ void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) { EmitEOL(); } -void MCAsmStreamer::EmitWinCFIEndProlog() { - MCStreamer::EmitWinCFIEndProlog(); +void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) { + MCStreamer::EmitWinCFIEndProlog(Loc); OS << "\t.seh_endprologue"; EmitEOL(); @@ -1583,8 +1660,8 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, } } OS << "]"; - // If we are not going to add fixup or schedul comments after this point then - // we have to end the current comment line with "\n". + // If we are not going to add fixup or schedule comments after this point + // then we have to end the current comment line with "\n". if (Fixups.size() || !PrintSchedInfo) OS << "\n"; |
