mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[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
This commit is contained in:
parent
91cac48098
commit
5230c79252
@ -58,6 +58,7 @@ public:
|
||||
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,
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
92
test/tools/llvm-ml/alias.test
Normal file
92
test/tools/llvm-ml/alias.test
Normal file
@ -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
|
36
test/tools/llvm-ml/alias_errors.test
Normal file
36
test/tools/llvm-ml/alias_errors.test
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user