summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp142
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp155
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp4
-rw-r--r--lib/MC/MCParser/WasmAsmParser.cpp1
4 files changed, 136 insertions, 166 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 084f6a7a2e141..b59ac08ad6cc4 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeView.h"
#include "llvm/MC/MCContext.h"
@@ -524,6 +525,19 @@ private:
/// directives parsed by this class.
StringMap<DirectiveKind> DirectiveKindMap;
+ // Codeview def_range type parsing.
+ enum CVDefRangeType {
+ CVDR_DEFRANGE = 0, // Placeholder
+ CVDR_DEFRANGE_REGISTER,
+ CVDR_DEFRANGE_FRAMEPOINTER_REL,
+ CVDR_DEFRANGE_SUBFIELD_REGISTER,
+ CVDR_DEFRANGE_REGISTER_REL
+ };
+
+ /// Maps Codeview def_range types --> CVDefRangeType enum, for
+ /// Codeview def_range types parsed by this class.
+ StringMap<CVDefRangeType> CVDefRangeTypeMap;
+
// ".ascii", ".asciz", ".string"
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
@@ -671,6 +685,7 @@ private:
bool parseDirectiveAddrsigSym();
void initializeDirectiveKindMap();
+ void initializeCVDefRangeTypeMap();
};
} // end anonymous namespace
@@ -714,12 +729,14 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
PlatformParser.reset(createWasmAsmParser());
break;
case MCObjectFileInfo::IsXCOFF:
- // TODO: Need to implement createXCOFFAsmParser for XCOFF format.
+ report_fatal_error(
+ "Need to implement createXCOFFAsmParser for XCOFF format.");
break;
}
PlatformParser->Initialize(*this);
initializeDirectiveKindMap();
+ initializeCVDefRangeTypeMap();
NumOfMacroInstantiations = 0;
}
@@ -1142,7 +1159,9 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
}
- MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
+ MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
+ if (!Sym)
+ Sym = getContext().getOrCreateSymbol(SymbolName);
// If this is an absolute variable reference, substitute it now to preserve
// semantics in the face of reassignment.
@@ -1737,6 +1756,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
StringMap<DirectiveKind>::const_iterator DirKindIt =
DirectiveKindMap.find(IDVal);
DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
+
? DK_NO_DIRECTIVE
: DirKindIt->getValue();
switch (DirKind) {
@@ -2895,11 +2915,27 @@ bool AsmParser::parseEscapedString(std::string &Data) {
}
// Recognize escaped characters. Note that this escape semantics currently
- // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
+ // loosely follows Darwin 'as'.
++i;
if (i == e)
return TokError("unexpected backslash at end of string");
+ // Recognize hex sequences similarly to GNU 'as'.
+ if (Str[i] == 'x' || Str[i] == 'X') {
+ size_t length = Str.size();
+ if (i + 1 >= length || !isHexDigit(Str[i + 1]))
+ return TokError("invalid hexadecimal escape sequence");
+
+ // Consume hex characters. GNU 'as' reads all hexadecimal characters and
+ // then truncates to the lower 16 bits. Seems reasonable.
+ unsigned Value = 0;
+ while (i + 1 < length && isHexDigit(Str[i + 1]))
+ Value = Value * 16 + hexDigitValue(Str[++i]);
+
+ Data += (unsigned char)(Value & 0xFF);
+ continue;
+ }
+
// Recognize octal sequences.
if ((unsigned)(Str[i] - '0') <= 7) {
// Consume up to three octal characters.
@@ -3825,6 +3861,13 @@ bool AsmParser::parseDirectiveCVInlineLinetable() {
return false;
}
+void AsmParser::initializeCVDefRangeTypeMap() {
+ CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
+ CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
+ CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
+ CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
+}
+
/// parseDirectiveCVDefRange
/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
bool AsmParser::parseDirectiveCVDefRange() {
@@ -3846,13 +3889,92 @@ bool AsmParser::parseDirectiveCVDefRange() {
Ranges.push_back({GapStartSym, GapEndSym});
}
- std::string FixedSizePortion;
- if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
- parseEscapedString(FixedSizePortion))
- return true;
-
- getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
- return false;
+ StringRef CVDefRangeTypeStr;
+ if (parseToken(
+ AsmToken::Comma,
+ "expected comma before def_range type in .cv_def_range directive") ||
+ parseIdentifier(CVDefRangeTypeStr))
+ return Error(Loc, "expected def_range type in directive");
+
+ StringMap<CVDefRangeType>::const_iterator CVTypeIt =
+ CVDefRangeTypeMap.find(CVDefRangeTypeStr);
+ CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
+ ? CVDR_DEFRANGE
+ : CVTypeIt->getValue();
+ switch (CVDRType) {
+ case CVDR_DEFRANGE_REGISTER: {
+ int64_t DRRegister;
+ if (parseToken(AsmToken::Comma, "expected comma before register number in "
+ ".cv_def_range directive") ||
+ parseAbsoluteExpression(DRRegister))
+ return Error(Loc, "expected register number");
+
+ codeview::DefRangeRegisterHeader DRHdr;
+ DRHdr.Register = DRRegister;
+ DRHdr.MayHaveNoName = 0;
+ getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
+ break;
+ }
+ case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
+ int64_t DROffset;
+ if (parseToken(AsmToken::Comma,
+ "expected comma before offset in .cv_def_range directive") ||
+ parseAbsoluteExpression(DROffset))
+ return Error(Loc, "expected offset value");
+
+ codeview::DefRangeFramePointerRelHeader DRHdr;
+ DRHdr.Offset = DROffset;
+ getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
+ break;
+ }
+ case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
+ int64_t DRRegister;
+ int64_t DROffsetInParent;
+ if (parseToken(AsmToken::Comma, "expected comma before register number in "
+ ".cv_def_range directive") ||
+ parseAbsoluteExpression(DRRegister))
+ return Error(Loc, "expected register number");
+ if (parseToken(AsmToken::Comma,
+ "expected comma before offset in .cv_def_range directive") ||
+ parseAbsoluteExpression(DROffsetInParent))
+ return Error(Loc, "expected offset value");
+
+ codeview::DefRangeSubfieldRegisterHeader DRHdr;
+ DRHdr.Register = DRRegister;
+ DRHdr.MayHaveNoName = 0;
+ DRHdr.OffsetInParent = DROffsetInParent;
+ getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
+ break;
+ }
+ case CVDR_DEFRANGE_REGISTER_REL: {
+ int64_t DRRegister;
+ int64_t DRFlags;
+ int64_t DRBasePointerOffset;
+ if (parseToken(AsmToken::Comma, "expected comma before register number in "
+ ".cv_def_range directive") ||
+ parseAbsoluteExpression(DRRegister))
+ return Error(Loc, "expected register value");
+ if (parseToken(
+ AsmToken::Comma,
+ "expected comma before flag value in .cv_def_range directive") ||
+ parseAbsoluteExpression(DRFlags))
+ return Error(Loc, "expected flag value");
+ if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
+ "in .cv_def_range directive") ||
+ parseAbsoluteExpression(DRBasePointerOffset))
+ return Error(Loc, "expected base pointer offset value");
+
+ codeview::DefRangeRegisterRelHeader DRHdr;
+ DRHdr.Register = DRRegister;
+ DRHdr.Flags = DRFlags;
+ DRHdr.BasePointerOffset = DRBasePointerOffset;
+ getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
+ break;
+ }
+ default:
+ return Error(Loc, "unexpected def_range type in .cv_def_range directive");
+ }
+ return true;
}
/// parseDirectiveCVString
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index 1217ea99e4656..06f8310ae0615 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -69,6 +69,7 @@ class COFFAsmParser : public MCAsmParserExtension {
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(".rva");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
// Win64 EH directives.
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
@@ -83,21 +84,10 @@ class COFFAsmParser : public MCAsmParserExtension {
".seh_handler");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
".seh_handlerdata");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
- ".seh_pushreg");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
- ".seh_setframe");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
".seh_stackalloc");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
- ".seh_savereg");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
- ".seh_savexmm");
- addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
- ".seh_pushframe");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
".seh_endprologue");
- addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
}
bool ParseSectionDirectiveText(StringRef, SMLoc) {
@@ -143,12 +133,7 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
bool ParseSEHDirectiveHandler(StringRef, SMLoc);
bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
- bool ParseSEHDirectivePushReg(StringRef, SMLoc);
- bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
- bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
- bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
- bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
@@ -682,39 +667,6 @@ bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
- unsigned Reg = 0;
- if (ParseSEHRegisterNumber(Reg))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
-
- Lex();
- getStreamer().EmitWinCFIPushReg(Reg, Loc);
- return false;
-}
-
-bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
- unsigned Reg = 0;
- int64_t Off;
- if (ParseSEHRegisterNumber(Reg))
- return true;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("you must specify a stack pointer offset");
-
- Lex();
- if (getParser().parseAbsoluteExpression(Off))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
-
- Lex();
- getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
- return false;
-}
-
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
int64_t Size;
if (getParser().parseAbsoluteExpression(Size))
@@ -728,71 +680,6 @@ bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
return false;
}
-bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
- unsigned Reg = 0;
- int64_t Off;
- if (ParseSEHRegisterNumber(Reg))
- return true;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("you must specify an offset on the stack");
-
- Lex();
- if (getParser().parseAbsoluteExpression(Off))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
-
- Lex();
- // FIXME: Err on %xmm* registers
- getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
- return false;
-}
-
-// FIXME: This method is inherently x86-specific. It should really be in the
-// x86 backend.
-bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) {
- unsigned Reg = 0;
- int64_t Off;
- if (ParseSEHRegisterNumber(Reg))
- return true;
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("you must specify an offset on the stack");
-
- Lex();
- if (getParser().parseAbsoluteExpression(Off))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
-
- Lex();
- // FIXME: Err on non-%xmm* registers
- getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
- return false;
-}
-
-bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
- bool Code = false;
- StringRef CodeID;
- if (getLexer().is(AsmToken::At)) {
- SMLoc startLoc = getLexer().getLoc();
- Lex();
- if (!getParser().parseIdentifier(CodeID)) {
- if (CodeID != "code")
- return Error(startLoc, "expected @code");
- Code = true;
- }
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in directive");
-
- Lex();
- getStreamer().EmitWinCFIPushFrame(Code, Loc);
- return false;
-}
-
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
Lex();
getStreamer().EmitWinCFIEndProlog(Loc);
@@ -816,46 +703,6 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
return false;
}
-bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
- SMLoc startLoc = getLexer().getLoc();
- if (getLexer().is(AsmToken::Percent)) {
- const MCRegisterInfo *MRI = getContext().getRegisterInfo();
- SMLoc endLoc;
- unsigned LLVMRegNo;
- if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
- return true;
-
-#if 0
- // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
- // violation so this validation code is disabled.
-
- // Check that this is a non-volatile register.
- const unsigned *NVRegs = TAI.getCalleeSavedRegs();
- unsigned i;
- for (i = 0; NVRegs[i] != 0; ++i)
- if (NVRegs[i] == LLVMRegNo)
- break;
- if (NVRegs[i] == 0)
- return Error(startLoc, "expected non-volatile register");
-#endif
-
- int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
- if (SEHRegNo < 0)
- return Error(startLoc,"register can't be represented in SEH unwind info");
- RegNo = SEHRegNo;
- }
- else {
- int64_t n;
- if (getParser().parseAbsoluteExpression(n))
- return true;
- if (n > 15)
- return Error(startLoc, "register number is too high");
- RegNo = n;
- }
-
- return false;
-}
-
namespace llvm {
MCAsmParserExtension *createCOFFAsmParser() {
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 1160934dc62c4..bd66e5f39c0d2 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -778,8 +778,8 @@ bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
raw_fd_ostream *OS = getContext().getSecureLog();
if (!OS) {
std::error_code EC;
- auto NewOS = llvm::make_unique<raw_fd_ostream>(
- StringRef(SecureLogFile), EC, sys::fs::F_Append | sys::fs::F_Text);
+ auto NewOS = std::make_unique<raw_fd_ostream>(
+ StringRef(SecureLogFile), EC, sys::fs::OF_Append | sys::fs::OF_Text);
if (EC)
return Error(IDLoc, Twine("can't open secure log file: ") +
SecureLogFile + " (" + EC.message() + ")");
diff --git a/lib/MC/MCParser/WasmAsmParser.cpp b/lib/MC/MCParser/WasmAsmParser.cpp
index 28d4459fecd44..0c242aed706d1 100644
--- a/lib/MC/MCParser/WasmAsmParser.cpp
+++ b/lib/MC/MCParser/WasmAsmParser.cpp
@@ -123,6 +123,7 @@ public:
// See use of .init_array in WasmObjectWriter and
// TargetLoweringObjectFileWasm
.StartsWith(".init_array", SectionKind::getData())
+ .StartsWith(".debug_", SectionKind::getMetadata())
.Default(Optional<SectionKind>());
if (!Kind.hasValue())
return Parser->Error(Lexer->getLoc(), "unknown section kind: " + Name);