[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