Skip to content

Commit

Permalink
[LoongArch] Implement MCTargetExpr::fixELFSymbolsInTLSFixups hook
Browse files Browse the repository at this point in the history
Reviewed By: SixWeining, MaskRay

Differential Revision: https://reviews.llvm.org/D137628
  • Loading branch information
wangleiat committed Nov 12, 2022
1 parent e864ac6 commit 39b1fec
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 1 deletion.
44 changes: 44 additions & 0 deletions llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
Expand Up @@ -16,7 +16,9 @@
#include "LoongArchFixupKinds.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;
Expand Down Expand Up @@ -179,3 +181,45 @@ LoongArchMCExpr::getVariantKindForName(StringRef name) {
.Case("gd_hi20", VK_LoongArch_TLS_GD_HI20)
.Default(VK_LoongArch_Invalid);
}

static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
switch (Expr->getKind()) {
case MCExpr::Target:
llvm_unreachable("Can't handle nested target expression");
break;
case MCExpr::Constant:
break;
case MCExpr::Unary:
fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
break;
case MCExpr::Binary: {
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
break;
}
case MCExpr::SymbolRef: {
// We're known to be under a TLS fixup, so any symbol should be
// modified. There should be only one.
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
break;
}
}
}

void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
switch (getKind()) {
default:
return;
case VK_LoongArch_TLS_LE_HI20:
case VK_LoongArch_TLS_IE_PC_HI20:
case VK_LoongArch_TLS_IE_HI20:
case VK_LoongArch_TLS_LD_PC_HI20:
case VK_LoongArch_TLS_LD_HI20:
case VK_LoongArch_TLS_GD_PC_HI20:
case VK_LoongArch_TLS_GD_HI20:
break;
}
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
}
2 changes: 1 addition & 1 deletion llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.h
Expand Up @@ -86,7 +86,7 @@ class LoongArchMCExpr : public MCTargetExpr {
return getSubExpr()->findAssociatedFragment();
}

void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;

static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
Expand Down
79 changes: 79 additions & 0 deletions llvm/test/MC/LoongArch/Misc/tls-symbols.s
@@ -0,0 +1,79 @@
# RUN: llvm-mc --triple=loongarch64 --filetype=obj %s -o %t
# RUN: llvm-readobj -s %t | FileCheck %s

lu12i.w $a1, %gd_hi20(gd_abs)
# CHECK: Symbol {
# CHECK: Name: gd_abs
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

pcalau12i $a1, %gd_pc_hi20(gd_pcrel)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: gd_pcrel
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

lu12i.w $a1, %ld_hi20(ld_abs)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: ld_abs
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

pcalau12i $a1, %ld_pc_hi20(ld_pcrel)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: ld_pcrel
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

lu12i.w $a1, %ie_hi20(ie_abs)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: ie_abs
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

pcalau12i $a1, %ie_pc_hi20(ie_pcrel)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: ie_pcrel
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

lu12i.w $a1, %le_hi20(le)
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: le
# CHECK-NEXT: Value: 0x0
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Binding: Global
# CHECK-NEXT: Type: TLS
# CHECK-NEXT: Other: 0
# CHECK-NEXT: Section: Undefined
# CHECK-NEXT: }

0 comments on commit 39b1fec

Please sign in to comment.