From f187ac5a23213f85c3c1f0f80b3592295ee6441d Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Mon, 28 Jun 2010 21:45:58 +0000 Subject: [PATCH] Added the darwin .secure_log_unique and .secure_log_reset directives. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107077 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCContext.h | 22 ++++++++++ include/llvm/MC/MCParser/AsmParser.h | 4 ++ lib/MC/MCContext.cpp | 7 ++++ lib/MC/MCParser/AsmParser.cpp | 63 ++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 03b5fb0c1fe..a57b5bf745d 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -14,6 +14,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { class MCAsmInfo; @@ -54,6 +55,17 @@ namespace llvm { /// for the LocalLabelVal and adds it to the map if needed. unsigned GetInstance(int64_t LocalLabelVal); + /// The file name of the log file from the enviromment variable + /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique + /// directive is used or it is an error. + char *SecureLogFile; + /// The stream that gets written to for the .secure_log_unique directive. + raw_ostream *SecureLog; + /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to + /// catch errors if .secure_log_unique appears twice without + /// .secure_log_reset appearing between them. + bool SecureLogUsed; + /// Allocator - Allocator object used for creating machine code objects. /// /// We use a bump pointer allocator to avoid the need to track all allocated @@ -127,6 +139,16 @@ namespace llvm { /// @} + char *getSecureLogFile() { return SecureLogFile; } + raw_ostream *getSecureLog() { return SecureLog; } + bool getSecureLogUsed() { return SecureLogUsed; } + void setSecureLog(raw_ostream *Value) { + SecureLog = Value; + } + void setSecureLogUsed(bool Value) { + SecureLogUsed = Value; + } + void *Allocate(unsigned Size, unsigned Align = 8) { return Allocator.Allocate(Size, Align); } diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index e929fd101df..99b48bb8a44 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -143,6 +143,10 @@ private: bool ParseDirectiveDarwinSubsectionsViaSymbols(); // Darwin specific .dump and .load bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump); + // Darwin specific .secure_log_unique + bool ParseDirectiveDarwinSecureLogUnique(SMLoc IDLoc); + // Darwin specific .secure_log_reset + bool ParseDirectiveDarwinSecureLogReset(SMLoc IDLoc); bool ParseDirectiveAbort(); // ".abort" bool ParseDirectiveInclude(); // ".include" diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 53ffc9409a6..2044a93b377 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -27,6 +27,10 @@ MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) { MachOUniquingMap = 0; ELFUniquingMap = 0; COFFUniquingMap = 0; + + SecureLogFile = getenv("AS_SECURE_LOG_FILE"); + SecureLog = 0; + SecureLogUsed = false; } MCContext::~MCContext() { @@ -37,6 +41,9 @@ MCContext::~MCContext() { delete (MachOUniqueMapTy*)MachOUniquingMap; delete (ELFUniqueMapTy*)ELFUniquingMap; delete (COFFUniqueMapTy*)COFFUniquingMap; + + // If the stream for the .secure_log_unique directive was created free it. + delete (raw_ostream*)SecureLog; } //===----------------------------------------------------------------------===// diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 4523eabb637..dea71ddf19c 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetAsmParser.h" using namespace llvm; @@ -780,6 +781,10 @@ bool AsmParser::ParseStatement() { return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true); if (IDVal == ".load") return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false); + if (IDVal == ".secure_log_unique") + return ParseDirectiveDarwinSecureLogUnique(IDLoc); + if (IDVal == ".secure_log_reset") + return ParseDirectiveDarwinSecureLogReset(IDLoc); // Look up the handler in the handler table, bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal]; @@ -1735,6 +1740,64 @@ bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) { return false; } +/// ParseDirectiveDarwinSecureLogUnique +/// ::= .secure_log_unique "log message" +bool AsmParser::ParseDirectiveDarwinSecureLogUnique(SMLoc IDLoc) { + std::string LogMessage; + + if (Lexer.isNot(AsmToken::String)) + LogMessage = ""; + else{ + LogMessage = getTok().getString(); + Lex(); + } + + if (Lexer.isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.secure_log_unique' directive"); + + if (getContext().getSecureLogUsed() != false) + return Error(IDLoc, ".secure_log_unique specified multiple times"); + + char *SecureLogFile = getContext().getSecureLogFile(); + if (SecureLogFile == NULL) + return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " + "environment variable unset."); + + raw_ostream *OS = getContext().getSecureLog(); + if (OS == NULL) { + std::string Err; + OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append); + if (!Err.empty()) { + delete OS; + return Error(IDLoc, Twine("can't open secure log file: ") + + SecureLogFile + " (" + Err + ")"); + } + getContext().setSecureLog(OS); + } + + int CurBuf = SrcMgr.FindBufferContainingLoc(IDLoc); + *OS << SrcMgr.getBufferInfo(CurBuf).Buffer->getBufferIdentifier() << ":" + << SrcMgr.FindLineNumber(IDLoc, CurBuf) << ":" + << LogMessage + "\n"; + + getContext().setSecureLogUsed(true); + + return false; +} + +/// ParseDirectiveDarwinSecureLogReset +/// ::= .secure_log_reset +bool AsmParser::ParseDirectiveDarwinSecureLogReset(SMLoc IDLoc) { + if (Lexer.isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.secure_log_reset' directive"); + + Lex(); + + getContext().setSecureLogUsed(false); + + return false; +} + /// ParseDirectiveIf /// ::= .if expression bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {