0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-21 14:56:57 +00:00

[CSKY] Fix CSKYMCCodeEmitter::getTargetFixup and set STT_TLS for TLS relocation specifiers

This commit is contained in:
Fangrui Song 2025-03-23 00:20:41 -07:00
parent 112277eeaf
commit c440563da7
4 changed files with 37 additions and 56 deletions

@ -9,9 +9,11 @@
#include "CSKYFixupKinds.h"
#include "CSKYMCExpr.h"
#include "CSKYMCTargetDesc.h"
#include "MCTargetDesc/CSKYMCExpr.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbolELF.h"
#define DEBUG_TYPE "csky-elf-object-writer"
@ -27,6 +29,8 @@ public:
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup, bool IsPCRel) const override;
bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
unsigned Type) const override;
};
} // namespace
@ -40,6 +44,19 @@ unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
unsigned Kind = Fixup.getTargetKind();
uint8_t Modifier = Target.getAccessVariant();
switch (Target.getRefKind()) {
case CSKYMCExpr::VK_TLSIE:
case CSKYMCExpr::VK_TLSLE:
case CSKYMCExpr::VK_TLSGD:
case CSKYMCExpr::VK_TLSLDM:
case CSKYMCExpr::VK_TLSLDO:
if (auto *S = Target.getSymA())
cast<MCSymbolELF>(S->getSymbol()).setType(ELF::STT_TLS);
break;
default:
break;
}
if (IsPCRel) {
switch (Kind) {
default:
@ -150,6 +167,18 @@ unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
}
}
bool CSKYELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,
const MCSymbol &,
unsigned Type) const {
switch (V.getRefKind()) {
case CSKYMCExpr::VK_PLT:
case CSKYMCExpr::VK_GOT:
return true;
default:
return false;
}
}
std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() {
return std::make_unique<CSKYELFObjectWriter>();
}

@ -294,8 +294,7 @@ unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
MCFixupKind CSKYMCCodeEmitter::getTargetFixup(const MCExpr *Expr) const {
const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);
switch (CSKYExpr->getKind()) {
switch (CSKYExpr->getSpecifier()) {
default:
llvm_unreachable("Unhandled fixup kind!");
case CSKYMCExpr::VK_ADDR:

@ -67,59 +67,12 @@ void CSKYMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << getVariantKindName(getSpecifier());
}
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::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;
}
case MCExpr::Unary:
fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
break;
}
}
bool CSKYMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAssembler *Asm) const {
if (!getSubExpr()->evaluateAsRelocatable(Res, Asm))
return false;
// Some custom fixup types are not valid with symbol difference expressions
if (Res.getSymA() && Res.getSymB()) {
switch (getSpecifier()) {
default:
return true;
case VK_GOT:
case VK_GOT_IMM18_BY4:
case VK_GOTPC:
case VK_GOTOFF:
case VK_PLT:
case VK_PLT_IMM18_BY4:
case VK_TLSIE:
case VK_TLSLE:
case VK_TLSGD:
case VK_TLSLDO:
case VK_TLSLDM:
return false;
}
}
return true;
Res =
MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), specifier);
return !Res.getSymB();
}

@ -5,10 +5,10 @@
# READELF: R_CKCORE_GOT32 00000000 .data + 0
# READELF: R_CKCORE_PLT32 00000000 .data + 0
# READELF: NOTYPE GLOBAL DEFAULT UND gd
# READELF: NOTYPE GLOBAL DEFAULT UND ld
# READELF: NOTYPE GLOBAL DEFAULT UND ie
# READELF: NOTYPE GLOBAL DEFAULT UND le
# READELF: TLS GLOBAL DEFAULT UND gd
# READELF: TLS GLOBAL DEFAULT UND ld
# READELF: TLS GLOBAL DEFAULT UND ie
# READELF: TLS GLOBAL DEFAULT UND le
lrw16 r0, gd@TLSGD32
lrw16 r0, ld@TLSLDM32