1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +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:
Eric Astor 2020-09-29 16:59:42 -04:00
parent 91cac48098
commit 5230c79252
7 changed files with 166 additions and 17 deletions

View File

@ -58,6 +58,7 @@ public:
unsigned ByteAlignment) override; unsigned ByteAlignment) override;
void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override; unsigned ByteAlignment) override;
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, SMLoc Loc = SMLoc()) override; unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,

View File

@ -21,6 +21,7 @@
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/SectionKind.h" #include "llvm/MC/SectionKind.h"
#include "llvm/Support/SMLoc.h" #include "llvm/Support/SMLoc.h"
#include <cassert> #include <cassert>
@ -53,6 +54,8 @@ class COFFMasmParser : public MCAsmParserExtension {
bool ParseDirectiveSegmentEnd(StringRef, SMLoc); bool ParseDirectiveSegmentEnd(StringRef, SMLoc);
bool ParseDirectiveIncludelib(StringRef, SMLoc); bool ParseDirectiveIncludelib(StringRef, SMLoc);
bool ParseDirectiveAlias(StringRef, SMLoc);
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc); bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
@ -124,7 +127,7 @@ class COFFMasmParser : public MCAsmParserExtension {
// purge // purge
// Miscellaneous directives // Miscellaneous directives
// alias addDirectiveHandler<&COFFMasmParser::ParseDirectiveAlias>("alias");
// assume // assume
// .fpo // .fpo
addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>( addDirectiveHandler<&COFFMasmParser::ParseDirectiveIncludelib>(
@ -343,13 +346,11 @@ bool COFFMasmParser::ParseDirectiveProc(StringRef Directive, SMLoc Loc) {
nextLoc = getTok().getLoc(); nextLoc = getTok().getLoc();
} }
} }
MCSymbol *Sym = getContext().getOrCreateSymbol(Label); MCSymbolCOFF *Sym = cast<MCSymbolCOFF>(getContext().getOrCreateSymbol(Label));
// Define symbol as simple function // Define symbol as simple external function
getStreamer().BeginCOFFSymbolDef(Sym); Sym->setExternal(true);
getStreamer().EmitCOFFSymbolStorageClass(2); Sym->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT);
getStreamer().EmitCOFFSymbolType(0x20);
getStreamer().EndCOFFSymbolDef();
bool Framed = false; bool Framed = false;
if (getLexer().is(AsmToken::Identifier) && if (getLexer().is(AsmToken::Identifier) &&
@ -384,6 +385,25 @@ bool COFFMasmParser::ParseDirectiveEndProc(StringRef Directive, SMLoc Loc) {
return false; 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, bool COFFMasmParser::ParseSEHDirectiveAllocStack(StringRef Directive,
SMLoc Loc) { SMLoc Loc) {
int64_t Size; int64_t Size;

View File

@ -308,6 +308,16 @@ void MCWinCOFFStreamer::emitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
PopSection(); 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, void MCWinCOFFStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment, uint64_t Size, unsigned ByteAlignment,
SMLoc Loc) { SMLoc Loc) {

View 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

View 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

View File

@ -7,11 +7,6 @@ t1 PROC
ret ret
t1 ENDP t1 ENDP
; CHECK: .def t1
; CHECK-NEXT: .scl 2
; CHECK-NEXT: .type 32
; CHECK-NEXT: .endef
; CHECK: t1: ; CHECK: t1:
; CHECK: ret ; CHECK: ret

View File

@ -13,11 +13,6 @@ t1 PROC FRAME
ret ret
t1 ENDP t1 ENDP
; CHECK: .def t1
; CHECK-NEXT: .scl 2
; CHECK-NEXT: .type 32
; CHECK-NEXT: .endef
; CHECK: .seh_proc t1 ; CHECK: .seh_proc t1
; CHECK: t1: ; CHECK: t1: