Add back the MC bits of 126425. Original patch by Nathan Jeffords. I added the
authorRafael Espindola <rafael.espindola@gmail.com>
Sat, 17 Dec 2011 01:14:52 +0000 (01:14 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sat, 17 Dec 2011 01:14:52 +0000 (01:14 +0000)
asm parsing and testcase.

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

12 files changed:
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCLoggingStreamer.cpp
lib/MC/MCNullStreamer.cpp
lib/MC/MCParser/COFFAsmParser.cpp
lib/MC/MCStreamer.cpp
lib/MC/WinCOFFObjectWriter.cpp
lib/MC/WinCOFFStreamer.cpp
lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
lib/Target/X86/MCTargetDesc/X86FixupKinds.h
test/MC/COFF/secrel32.s [new file with mode: 0644]

index 1c1fe027989be82b292a5bc89bd171532aac9ec8..9ba50b1a263a427b3f06b29d997e2f47df32f8d2 100644 (file)
@@ -334,6 +334,11 @@ namespace llvm {
     /// EndCOFFSymbolDef - Marks the end of the symbol definition.
     virtual void EndCOFFSymbolDef() = 0;
 
+    /// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
+    ///
+    /// @param Symbol - Symbol the section relative realocation should point to.
+    virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
+
     /// EmitELFSize - Emit an ELF .size directive.
     ///
     /// This corresponds to an assembler statement such as:
index 605b775502b6270128a28559d6fbbc4ff71694f5..c166946989954512d5907baac2ae186023ec06c1 100644 (file)
@@ -144,9 +144,8 @@ void AsmPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
 void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
                                    const MCSymbol *SectionLabel) const {
   // On COFF targets, we have to emit the special .secrel32 directive.
-  if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
-    // FIXME: MCize.
-    OutStreamer.EmitRawText(SecOffDir + Twine(Label->getName()));
+  if (MAI->getDwarfSectionOffsetDirective()) {
+    OutStreamer.EmitCOFFSecRel32(Label);
     return;
   }
   
index c785c032231c646b28231d3156fd3af2f20b1326..630a104b1292b163aada91ad4d2ecbbb15ccd0ac 100644 (file)
@@ -154,6 +154,7 @@ public:
   virtual void EmitCOFFSymbolStorageClass(int StorageClass);
   virtual void EmitCOFFSymbolType(int Type);
   virtual void EndCOFFSymbolDef();
+  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
   virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                                 unsigned ByteAlignment);
@@ -470,6 +471,11 @@ void MCAsmStreamer::EndCOFFSymbolDef() {
   EmitEOL();
 }
 
+void MCAsmStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+  OS << "\t.secrel32\t" << *Symbol << '\n';
+  EmitEOL();
+}
+
 void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
   assert(MAI.hasDotTypeDotSizeDirective());
   OS << "\t.size\t" << *Symbol << ", " << *Value << '\n';
index a7b794767675e63b7e9ce2ed697f32b8bcc27c35..d59b6d7acafe87386d90cfb2ec70d3b87b90bf79 100644 (file)
@@ -122,6 +122,11 @@ public:
     return Child->EndCOFFSymbolDef();
   }
 
+  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol) {
+    LogCall("EmitCOFFSecRel32");
+    return Child->EmitCOFFSecRel32(Symbol);
+  }
+
   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
     LogCall("EmitELFSize");
     return Child->EmitELFSize(Symbol, Value);
index d178b507a0f6c43263658b9d943a7a5025a8feaf..ca74663693d63f6f2e8ca4f69c62d212e6a1998a 100644 (file)
@@ -55,6 +55,7 @@ namespace {
     virtual void EmitCOFFSymbolStorageClass(int StorageClass) {}
     virtual void EmitCOFFSymbolType(int Type) {}
     virtual void EndCOFFSymbolDef() {}
+    virtual void EmitCOFFSecRel32(MCSymbol const *Symbol) {}
 
     virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
     virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
index 185b5168bd6cc1a641e2531045bbeac70d66db3d..c4cdc3c9f96fb61512c84e7d75b4e2338017f551 100644 (file)
@@ -45,6 +45,7 @@ class COFFAsmParser : public MCAsmParserExtension {
     AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
     AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
     AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
 
     // Win64 EH directives.
     AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
@@ -102,6 +103,7 @@ class COFFAsmParser : public MCAsmParserExtension {
   bool ParseDirectiveScl(StringRef, SMLoc);
   bool ParseDirectiveType(StringRef, SMLoc);
   bool ParseDirectiveEndef(StringRef, SMLoc);
+  bool ParseDirectiveSecRel32(StringRef, SMLoc);
 
   // Win64 EH directives.
   bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -217,6 +219,21 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
   return false;
 }
 
+bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
+  StringRef SymbolID;
+  if (getParser().ParseIdentifier(SymbolID))
+    return true;
+
+  if (getLexer().isNot(AsmToken::EndOfStatement))
+    return TokError("unexpected token in directive");
+
+  MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID);
+
+  Lex();
+  getStreamer().EmitCOFFSecRel32(Symbol);
+  return false;
+}
+
 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
   StringRef SymbolID;
   if (getParser().ParseIdentifier(SymbolID))
index 60a0a9d115ddbb71a5733f2c5a049f822ac18767..74c3e39e3b9d7f14984106600397e3f3cb8c47d8 100644 (file)
@@ -558,6 +558,10 @@ void MCStreamer::EmitWin64EHEndProlog() {
   EmitLabel(CurFrame->PrologEnd);
 }
 
+void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
+  assert(0 && "This file format doesn't support this directive");
+}
+
 void MCStreamer::EmitFnStart() {
   errs() << "Not implemented yet\n";
   abort();
index 4052374c9637f5632a3153b166f2b2cd8f27bc04..484443a69aa1aeefc0e495aec5e9a31012dc103d 100644 (file)
@@ -716,6 +716,10 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
     else
       llvm_unreachable("unsupported relocation type");
     break;
+  case X86::reloc_coff_secrel32:
+    Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_SREL32
+                              : COFF::IMAGE_REL_I386_SECREL;
+    break;
   default:
     llvm_unreachable("unsupported relocation type");
   }
index 7409daf390858332d8d7ef77895965bccf984bc5..3678a589f4ee3bf72c005cd31ade39d22f52b250 100644 (file)
@@ -32,6 +32,9 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
+
+#include "../Target/X86/MCTargetDesc/X86FixupKinds.h"
+
 using namespace llvm;
 
 namespace {
@@ -60,6 +63,7 @@ public:
   virtual void EmitCOFFSymbolStorageClass(int StorageClass);
   virtual void EmitCOFFSymbolType(int Type);
   virtual void EndCOFFSymbolDef();
+  virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
   virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                                 unsigned ByteAlignment);
@@ -293,6 +297,16 @@ void WinCOFFStreamer::EndCOFFSymbolDef() {
   CurSymbol = NULL;
 }
 
+void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol)
+{
+  MCDataFragment *DF = getOrCreateDataFragment();
+
+  DF->addFixup(MCFixup::Create(DF->getContents().size(),
+                               MCSymbolRefExpr::Create (Symbol, getContext ()),
+                               (MCFixupKind)X86::reloc_coff_secrel32));
+  DF->getContents().resize(DF->getContents().size() + 4, 0);
+}
+
 void WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
   llvm_unreachable("not implemented");
 }
index 87b2b055ab27d18fbb8988a3a79982ae70484397..7cbda489b6979aee34a9f5ce0818e9ff6164abcb 100644 (file)
@@ -47,6 +47,7 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
   case X86::reloc_riprel_4byte_movq_load:
   case X86::reloc_signed_4byte:
   case X86::reloc_global_offset_table:
+  case X86::reloc_coff_secrel32:
   case FK_Data_4: return 2;
   case FK_PCRel_8:
   case FK_Data_8: return 3;
@@ -76,7 +77,8 @@ public:
       { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel },
       { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel},
       { "reloc_signed_4byte", 0, 4 * 8, 0},
-      { "reloc_global_offset_table", 0, 4 * 8, 0}
+      { "reloc_global_offset_table", 0, 4 * 8, 0},
+      { "reloc_coff_secrel32", 0, 4 * 8, 0}
     };
 
     if (Kind < FirstTargetFixupKind)
index 17d242ab761e3579a834a1ac653a640df1b39e35..d6cb39ae9a736307e206bc458a9e20df4758c43c 100644 (file)
@@ -23,6 +23,8 @@ enum Fixups {
   reloc_global_offset_table,                 // 32-bit, relative to the start
                                              // of the instruction. Used only
                                              // for _GLOBAL_OFFSET_TABLE_.
+  reloc_coff_secrel32,                       // PE-COFF section relative 32
+                                             // (only valid for win32 COFF)
   // Marker
   LastTargetFixupKind,
   NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
diff --git a/test/MC/COFF/secrel32.s b/test/MC/COFF/secrel32.s
new file mode 100644 (file)
index 0000000..ce148db
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | coff-dump.py | FileCheck %s
+
+// check that we produce the correct relocation for .secrel32
+
+Lfoo:
+       .secrel32       Lfoo
+
+// CHECK:       Relocations              = [
+// CHECK-NEXT:    0 = {
+// CHECK-NEXT:       VirtualAddress           = 0x0
+// CHECK-NEXT:       SymbolTableIndex         = 0
+// CHECK-NEXT:       Type                     = IMAGE_REL_I386_SECREL (11)
+// CHECK-NEXT:       SymbolName               = .text
+// CHECK-NEXT:     }