[llvm] 0548d1c - [ms] [llvm-ml] Add support for "alias" directive

Eric Astor via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 14:00:04 PDT 2020


Author: Eric Astor
Date: 2020-09-29T16:59:50-04:00
New Revision: 0548d1ca24b72d28e50fbd8a456b1fd36beacb07

URL: https://github.com/llvm/llvm-project/commit/0548d1ca24b72d28e50fbd8a456b1fd36beacb07
DIFF: https://github.com/llvm/llvm-project/commit/0548d1ca24b72d28e50fbd8a456b1fd36beacb07.diff

LOG: [ms] [llvm-ml] Add support for "alias" directive

Support the "alias" directive.

Required support for emitWeakReference in MCWinCOFFStreamer.

Reviewed By: thakis

Differential Revision: https://reviews.llvm.org/D87403

Added: 
    llvm/test/tools/llvm-ml/alias.test
    llvm/test/tools/llvm-ml/alias_errors.test

Modified: 
    llvm/include/llvm/MC/MCWinCOFFStreamer.h
    llvm/lib/MC/MCParser/COFFMasmParser.cpp
    llvm/lib/MC/MCWinCOFFStreamer.cpp
    llvm/test/tools/llvm-ml/proc.test
    llvm/test/tools/llvm-ml/proc_frame.test

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h
index 1236304b9e5d..53b2ef0bd96e 100644
--- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h
@@ -58,6 +58,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
                         unsigned ByteAlignment) override;
   void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                              unsigned ByteAlignment) override;
+  void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
   void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                     unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
   void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,

diff  --git a/llvm/lib/MC/MCParser/COFFMasmParser.cpp b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
index 575e6ee265c8..94146683e8a1 100644
--- a/llvm/lib/MC/MCParser/COFFMasmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFMasmParser.cpp
@@ -21,6 +21,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbolCOFF.h"
 #include "llvm/MC/SectionKind.h"
 #include "llvm/Support/SMLoc.h"
 #include <cassert>
@@ -53,6 +54,8 @@ class COFFMasmParser : public MCAsmParserExtension {
   bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
   bool ParseDirectiveIncludelib(StringRef, SMLoc);
 
+  bool ParseDirectiveAlias(StringRef, SMLoc);
+
   bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
   bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
 
@@ -124,7 +127,7 @@ class COFFMasmParser : public MCAsmParserExtension {
     // purge
 
     // Miscellaneous directives
-    // alias
+    addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
     // assume
     // .fpo
     addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
@@ -343,13 +346,11 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
       nextLoc = getTok().getLoc();
     }
   }
-  MCSymbol *Sym = getContext().getOrCreateSymbol(Label);
+  MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
 
-  // Define symbol as simple function
-  getStreamer().BeginCOFFSymbolDef(Sym);
-  getStreamer().EmitCOFFSymbolStorageClass(2);
-  getStreamer().EmitCOFFSymbolType(0x20);
-  getStreamer().EndCOFFSymbolDef();
+  // Define symbol as simple external function
+  Sym->setExternal(true);
+  Sym->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);
 
   bool Framed = false;
   if (getLexer().is(AsmToken::Identifier) &&
@@ -384,6 +385,25 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
   return false;
 }
 
+bool COFFMasmParser::ParseDirectiveAlias(StringRef Directive, SMLoc Loc) {
+  std::string AliasName, ActualName;
+  if (getTok().isNot(AsmToken::Less) ||
+      getParser().parseAngleBracketString(AliasName))
+    return Error(getTok().getLoc(), "expected <aliasName>");
+  if (getParser().parseToken(AsmToken::Equal))
+    return addErrorSuffix(" in " + Directive + " directive");
+  if (getTok().isNot(AsmToken::Less) ||
+      getParser().parseAngleBracketString(ActualName))
+    return Error(getTok().getLoc(), "expected <actualName>");
+
+  MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
+  MCSymbol *Actual = getContext().getOrCreateSymbol(ActualName);
+
+  getStreamer().emitWeakReference(Alias, Actual);
+
+  return false;
+}
+
 bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
                                                  SMLoc Loc) {
   int64_t Size;

diff  --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index 520d4a024691..97cceac74ac2 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -308,6 +308,16 @@ void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
   PopSection();
 }
 
+void MCWinCOFFStreamer::emitWeakReference(MCSymbol *AliasS,
+                                          const MCSymbol *Symbol) {
+  auto *Alias = cast<MCSymbolCOFF>(AliasS);
+  emitSymbolAttribute(Alias, MCSA_Weak);
+
+  getAssembler().registerSymbol(*Symbol);
+  Alias->setVariableValue(MCSymbolRefExpr::create(
+      Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext()));
+}
+
 void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
                                      uint64_t Size, unsigned ByteAlignment,
                                      SMLoc Loc) {

diff  --git a/llvm/test/tools/llvm-ml/alias.test b/llvm/test/tools/llvm-ml/alias.test
new file mode 100644
index 000000000000..2daaecdbbcc0
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/alias.test
@@ -0,0 +1,92 @@
+; RUN: llvm-ml -filetype=obj %s | llvm-readobj --syms - | FileCheck %s
+
+.code
+
+proc1 PROC
+  ret
+proc1 ENDP
+
+proc2 PROC
+  ret
+proc2 ENDP
+
+alias <t1> = <proc1>
+; CHECK:      Symbol {
+; CHECK:        Name: t1
+; CHECK-NEXT:   Value: 0
+; CHECK-NEXT:   Section: IMAGE_SYM_UNDEFINED (0)
+; CHECK-NEXT:   BaseType: Null
+; CHECK-NEXT:   ComplexType: Null
+; CHECK-NEXT:   StorageClass: WeakExternal
+; CHECK-NEXT:   AuxSymbolCount: 1
+; CHECK-NEXT:   AuxWeakExternal {
+; CHECK-NEXT:     Linked: proc1
+; CHECK-NEXT:     Search: Alias
+; CHECK-NEXT:   }
+; CHECK-NEXT: }
+
+alias <t2> = <proc2>
+; CHECK:      Symbol {
+; CHECK:        Name: t2
+; CHECK-NEXT:   Value: 0
+; CHECK-NEXT:   Section: IMAGE_SYM_UNDEFINED (0)
+; CHECK-NEXT:   BaseType: Null
+; CHECK-NEXT:   ComplexType: Null
+; CHECK-NEXT:   StorageClass: WeakExternal
+; CHECK-NEXT:   AuxSymbolCount: 1
+; CHECK-NEXT:   AuxWeakExternal {
+; CHECK-NEXT:     Linked: proc2
+; CHECK-NEXT:     Search: Alias
+; CHECK-NEXT:   }
+; CHECK-NEXT: }
+
+alias <t3> = <foo>
+; CHECK:      Symbol {
+; CHECK:        Name: t3
+; CHECK-NEXT:   Value: 0
+; CHECK-NEXT:   Section: IMAGE_SYM_UNDEFINED (0)
+; CHECK-NEXT:   BaseType: Null
+; CHECK-NEXT:   ComplexType: Null
+; CHECK-NEXT:   StorageClass: WeakExternal
+; CHECK-NEXT:   AuxSymbolCount: 1
+; CHECK-NEXT:   AuxWeakExternal {
+; CHECK-NEXT:     Linked: foo
+; CHECK-NEXT:     Search: Alias
+; CHECK-NEXT:   }
+; CHECK-NEXT: }
+
+alias <t4> = <bar>
+bar PROC
+  ret
+bar ENDP
+
+; CHECK:      Symbol {
+; CHECK:        Name: t4
+; CHECK-NEXT:   Value: 0
+; CHECK-NEXT:   Section: IMAGE_SYM_UNDEFINED (0)
+; CHECK-NEXT:   BaseType: Null
+; CHECK-NEXT:   ComplexType: Null
+; CHECK-NEXT:   StorageClass: WeakExternal
+; CHECK-NEXT:   AuxSymbolCount: 1
+; CHECK-NEXT:   AuxWeakExternal {
+; CHECK-NEXT:     Linked: bar
+; CHECK-NEXT:     Search: Alias
+; CHECK-NEXT:   }
+; CHECK-NEXT: }
+
+alias <t5> = <t2>
+; CHECK:      Symbol {
+; CHECK:        Name: t5
+; CHECK-NEXT:   Value: 0
+; CHECK-NEXT:   Section: IMAGE_SYM_UNDEFINED (0)
+; CHECK-NEXT:   BaseType: Null
+; CHECK-NEXT:   ComplexType: Null
+; CHECK-NEXT:   StorageClass: WeakExternal
+; CHECK-NEXT:   AuxSymbolCount: 1
+; CHECK-NEXT:   AuxWeakExternal {
+; CHECK-NEXT:     Linked: t2
+; CHECK-NEXT:     Search: Alias
+; CHECK-NEXT:   }
+; CHECK-NEXT: }
+
+END

diff  --git a/llvm/test/tools/llvm-ml/alias_errors.test b/llvm/test/tools/llvm-ml/alias_errors.test
new file mode 100644
index 000000000000..9d51b2a993ac
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/alias_errors.test
@@ -0,0 +1,36 @@
+; RUN: not llvm-ml -filetype=asm %s 2>&1 | FileCheck %s
+
+.code
+
+foo PROC
+  ret
+foo ENDP
+
+bar PROC
+  ret
+bar ENDP
+
+t1:
+alias foo = bar
+alias foo = <bar>
+alias <foo> = bar
+
+; CHECK: error: expected <aliasName>
+; CHECK: error: expected <aliasName>
+; CHECK: error: expected <actualName>
+
+t2:
+alias <foo> <bar>
+alias <foo>, <bar>
+
+; CHECK: error: unexpected token in alias directive
+; CHECK: error: unexpected token in alias directive
+
+t3:
+alias <foo = bar>
+alias <foo = bar
+
+; CHECK: error: unexpected token in alias directive
+; CHECK: error: expected <aliasName>
+
+END
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-ml/proc.test b/llvm/test/tools/llvm-ml/proc.test
index ad117f7fb1dd..15e253a31083 100644
--- a/llvm/test/tools/llvm-ml/proc.test
+++ b/llvm/test/tools/llvm-ml/proc.test
@@ -7,11 +7,6 @@ t1 PROC
   ret
 t1 ENDP
 
-; CHECK: .def t1
-; CHECK-NEXT: .scl 2
-; CHECK-NEXT: .type 32
-; CHECK-NEXT: .endef
-
 ; CHECK: t1:
 ; CHECK: ret
 

diff  --git a/llvm/test/tools/llvm-ml/proc_frame.test b/llvm/test/tools/llvm-ml/proc_frame.test
index 3bf1c3a3ca4b..f98721467474 100644
--- a/llvm/test/tools/llvm-ml/proc_frame.test
+++ b/llvm/test/tools/llvm-ml/proc_frame.test
@@ -13,11 +13,6 @@ t1 PROC FRAME
   ret
 t1 ENDP
 
-; CHECK: .def t1
-; CHECK-NEXT: .scl 2
-; CHECK-NEXT: .type 32
-; CHECK-NEXT: .endef
-
 ; CHECK: .seh_proc t1
 
 ; CHECK: t1:


        


More information about the llvm-commits mailing list