Add the .incbin directive which takes the binary data from a file and emits
authorKevin Enderby <enderby@apple.com>
Wed, 14 Dec 2011 21:47:48 +0000 (21:47 +0000)
committerKevin Enderby <enderby@apple.com>
Wed, 14 Dec 2011 21:47:48 +0000 (21:47 +0000)
it to the streamer.  rdar://10383898

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146592 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCParser/AsmParser.cpp
test/MC/AsmParser/directive_incbin.s [new file with mode: 0644]
test/MC/AsmParser/incbin_abcd [new file with mode: 0644]

index 943f270a0a719af8daf3f452dacdf41f78e48449..93492377ff0637815566d813cb062f0e7dbe4a82 100644 (file)
@@ -181,6 +181,9 @@ private:
 
   /// 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.
+  /// This returns true on failure.
+  bool ProcessIncbinFile(const std::string &Filename);
 
   /// \brief Reset the current lexer position to that given by \arg Loc. The
   /// current token is not set; clients should ensure Lex() is called
@@ -227,6 +230,7 @@ private:
 
   bool ParseDirectiveAbort(); // ".abort"
   bool ParseDirectiveInclude(); // ".include"
+  bool ParseDirectiveIncbin(); // ".incbin"
 
   bool ParseDirectiveIf(SMLoc DirectiveLoc); // ".if"
   // ".ifdef" or ".ifndef", depending on expect_defined
@@ -429,6 +433,24 @@ bool AsmParser::EnterIncludeFile(const std::string &Filename) {
   return false;
 }
 
+/// Process the specified .incbin file by seaching for it in the include paths
+/// then just emiting the byte contents of the file to the streamer. This 
+/// returns true on failure.
+bool AsmParser::ProcessIncbinFile(const std::string &Filename) {
+  std::string IncludedFile;
+  int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
+  if (NewBuf == -1)
+    return true;
+
+  // Loop picking the bytes from the file and emitting them.
+  const char *BufferStart = SrcMgr.getMemoryBuffer(NewBuf)->getBufferStart();
+  const char *BufferEnd = SrcMgr.getMemoryBuffer(NewBuf)->getBufferEnd();
+  for(const char *p = BufferStart; p < BufferEnd; p++)
+    getStreamer().EmitIntValue(*p, 1, DEFAULT_ADDRSPACE);
+
+  return false;
+}
+
 void AsmParser::JumpToLoc(SMLoc Loc) {
   CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), Loc.getPointer());
@@ -1183,6 +1205,8 @@ bool AsmParser::ParseStatement() {
       return ParseDirectiveAbort();
     if (IDVal == ".include")
       return ParseDirectiveInclude();
+    if (IDVal == ".incbin")
+      return ParseDirectiveIncbin();
 
     if (IDVal == ".code16")
       return TokError(Twine(IDVal) + " not supported yet");
@@ -2206,6 +2230,31 @@ bool AsmParser::ParseDirectiveInclude() {
   return false;
 }
 
+/// ParseDirectiveIncbin
+///  ::= .incbin "filename"
+bool AsmParser::ParseDirectiveIncbin() {
+  if (getLexer().isNot(AsmToken::String))
+    return TokError("expected string in '.incbin' directive");
+
+  std::string Filename = getTok().getString();
+  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)) {
+    Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
+    return true;
+  }
+
+  return false;
+}
+
 /// ParseDirectiveIf
 /// ::= .if expression
 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
diff --git a/test/MC/AsmParser/directive_incbin.s b/test/MC/AsmParser/directive_incbin.s
new file mode 100644 (file)
index 0000000..230573c
--- /dev/null
@@ -0,0 +1,9 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s -I %p | FileCheck %s
+
+.data
+.incbin "incbin_abcd"
+
+# CHECK: .byte 97
+# CHECK: .byte 98
+# CHECK: .byte 99
+# CHECK: .byte 100
diff --git a/test/MC/AsmParser/incbin_abcd b/test/MC/AsmParser/incbin_abcd
new file mode 100644 (file)
index 0000000..acbe86c
--- /dev/null
@@ -0,0 +1 @@
+abcd