Skip to content

[RISCV] Replace @plt/@gotpcrel in data directives with %pltpcrel %gotpcrel #132569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lld/test/ELF/riscv-reloc-plt32.s
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
.globl _start
_start:
.data
.word foo@PLT - .
.word foo@PLT - . + 1
.word foo@PLT - . - 1
.word %plt(foo - .)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would %plt(foo) - . not be the saner syntax? PLT of an offset is a bit nonsensical...

Copy link
Member Author

@MaskRay MaskRay Mar 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core principle is that relocation specifiers must operate on the full expression, not just a part of it. (semantically closer to gas https://maskray.me/blog/2025-03-16-relocation-generation-in-assemblers#gnu-assembler-internals)
This would avoid a lot of complexity/ambiguity in parsing and expression folding.

.word %plt(foo - .) might look unusual. It describes a PC-relative relocatable expression.
We evaluate it to a relocatable expression (relocation_specifier(sym_a - sym_b + offset)), and allows the referenced "addend" (sym_a) to be a PLT.

.word %plt(foo) describes an absolute reference to foo's PLT, which we don't support.

Branch instructions have an implicit PC-relative operand, so call foo@plt (legacy syntax) could be viewed as call %plt(foo) (conceptually, we shouldn't add the syntax), which is internally
converted to PC-relative as %plt(foo - .).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I know, but it's pretty weird and confusing syntax. It's not really written that way because it makes sense, it's just written that way because it aligns with how implementations think about it.

Perhaps %pltpcrel, to mirror %gotpcrel, would be the right thing to do here that sidesteps the issue?

Copy link
Member Author

@MaskRay MaskRay Mar 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's challenging to use an inherent PC-relative specifier (e.g. %pltpcrel; which I actually thought about).... This is because
in the code block around llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:3477 (AsmPrinter::lowerConstant), the function doesn't actually know its current address. The function call needs a subtrahend. (llvm/test/CodeGen/X86/x86-64-plt-relative-reloc.ll contains a better test that demonstrates this: the subtrahend vtable might be a few bytes before the current address (that feature might be obsoleted by the dsolocal equivalent feature))

(If we adopt %pltpcrel and if we ever decide to support .word %plt(foo), we would introduce another specifier. While with %plt(foo - .), we won't need a new specifier.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have %(got_)pcrel_hi and now %gotpcrel, what's so different about this one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I don't like %plt(foo - .), because the thing being put into the instruction is really the difference between foo's PLT entry's address, and the current address (rather than a PLT entry for the difference between foo and the current address). I would much prefer %pltpcrel(foo) if %plt(foo)-. is not a direction you are happy with, given the existing %gotpcrel(foo) means the difference between the current address and foo's GOT entry's address.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IR doesn't model the current location (DOT). Instead, It computes SymA-SymB+offset.
SymB might not be the current location, but it and the current location must be in the same section.

Let's use llvm/test/CodeGen/X86/x86-64-plt-relative-reloc.ll (legacy; but slightly better than dso_local_equivalent.ll):

@vtable = constant [5 x i32] [i32 0,
    i32 trunc (i64 sub (i64 ptrtoint (ptr @fn1 to i64), i64 ptrtoint (ptr getelementptr ([5 x i32], ptr @vtable, i32 0, i32 1) to i64)) to i32),
    i32 trunc (i64 sub (i64 ptrtoint (ptr @fn2 to i64), i64 ptrtoint (ptr getelementptr ([5 x i32], ptr @vtable, i32 0, i32 1) to i64)) to i32),
    i32 trunc (i64 sub (i64 ptrtoint (ptr @fn3 to i64), i64 ptrtoint (ptr getelementptr ([5 x i32], ptr @vtable, i32 0, i32 1) to i64)) to i32),
    i32 trunc (i64 sub (i64 ptrtoint (ptr @global4 to i64), i64 ptrtoint (ptr getelementptr ([5 x i32], ptr @vtable, i32 0, i32 1) to i64)) to i32)
]

If we need to emit %pltpcrel, we will have to change AsmPrinter::lowerConstant to know the base GlobalVariable, which might be possible...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well my overarching point would be that user-facing syntax should not be beholden to arbitrary historic implementation choices. If it's truly impossible to make it work then that's one thing, but I doubt that to be the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented %pltpcrel, while a bit complex, I am happy with the result. (As in RISCVMCExpr::evaluateAsRelocatableImpl, we don't need an exception for VK_PLT, if we go with %plt. This might be difficult to explain without playing with it.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not looked at the implementation in detail, but thank you for taking the time to do so, I know from experience it can be quite painful getting the MC code to do things that weren't previously expected of it

.word %plt(foo - . + 1)
.word %plt(foo - . - 1)
2 changes: 1 addition & 1 deletion lld/test/ELF/riscv-undefined-weak.s
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,4 @@ branch:
# PC-NOT: .plt:
# PLT: .plt:

.word target@plt - .
.word %plt(target - .)
16 changes: 8 additions & 8 deletions lld/test/ELF/riscv64-reloc-got32-pcrel.s
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ bar:

.globl _start
_start: // PC = 0x33a8
// bar@GOTPCREL = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
// bar@GOTPCREL+4 = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
// bar@GOTPCREL-4 = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
// %gotpcrel(bar) = 0x2398 (got entry for `bar`) - 0x33a8 (.) = 0xf0efffff
// %gotpcrel(bar+4) = 0x2398 (got entry for `bar`) - 0x33ac (.) + 4 = 0xf0efffff
// %gotpcrel(bar-4) = 0x2398 (got entry for `bar`) - 0x33b0 (.) - 4 = 0xe4efffff
// CHECK: Contents of section .data:
// CHECK-NEXT: {{.*}} f0efffff f0efffff e4efffff
.word bar@GOTPCREL
.word bar@GOTPCREL+4
.word bar@GOTPCREL-4
.word %gotpcrel(bar)
.word %gotpcrel(bar+4)
.word %gotpcrel(bar-4)

// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
// WARN: relocation R_RISCV_GOT32_PCREL out of range: {{.*}} is not in [-2147483648, 2147483647]; references 'baz'
.word baz@GOTPCREL+0xffffffff
.word baz@GOTPCREL-0xffffffff
.word %gotpcrel(baz+0xffffffff)
.word %gotpcrel(baz-0xffffffff)
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {

protected:
uint8_t PLTRelativeSpecifier = 0;
bool UseTargetMCExprForPLTRelative = true;

public:
TargetLoweringObjectFileELF();
Expand Down Expand Up @@ -112,11 +113,16 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
MCSection *getStaticDtorSection(unsigned Priority,
const MCSymbol *KeySym) const override;

virtual const MCExpr *createTargetMCExpr(const MCExpr *Expr,
uint8_t Specifier) const {
return nullptr;
}
const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
const GlobalValue *RHS,
const TargetMachine &TM) const override;

const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
const MCSymbolRefExpr *RHS,
const TargetMachine &TM) const override;

MCSection *getSectionForCommandLines() const override;
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ class MCTargetAsmParser : public MCAsmParserExtension {
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
}
// Parse an expression in a data directive, possibly with a relocation
// specifier.
virtual bool parseDataExpr(const MCExpr *&Res) {
SMLoc EndLoc;
return getParser().parseExpression(Res, EndLoc);
}

virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/TargetLoweringObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
}

virtual const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
const MCSymbolRefExpr *RHS,
const TargetMachine &TM) const {
return nullptr;
}
Expand Down
11 changes: 6 additions & 5 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3382,7 +3382,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
return lowerBlockAddressConstant(*BA);

if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);
return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, nullptr, TM);

if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(CV))
return MCSymbolRefExpr::create(getSymbol(NC->getGlobalValue()), Ctx);
Expand Down Expand Up @@ -3481,12 +3481,13 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
if (!RelocExpr) {
const MCExpr *LHSExpr =
MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx);
auto *RHSExpr = MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx);
if (DSOEquiv &&
getObjFileLowering().supportDSOLocalEquivalentLowering())
LHSExpr =
getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM);
RelocExpr = MCBinaryExpr::createSub(
LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);
RelocExpr = getObjFileLowering().lowerDSOLocalEquivalent(
DSOEquiv, RHSExpr, TM);
else
RelocExpr = MCBinaryExpr::createSub(LHSExpr, RHSExpr, Ctx);
}
int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
if (Addend != 0)
Expand Down
30 changes: 23 additions & 7 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,18 +1194,34 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
Copy link
Member Author

@MaskRay MaskRay Mar 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowerRelativeReference uses MCSymbolRefExpr but I do not intend to touch it. It seems legacy (probably should be removed).

}

// Reference the function or its PLT entry (`Equiv`), optionally with a
// subtrahend (`RHS`).
const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent(
const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const {
const DSOLocalEquivalent *Equiv, const MCSymbolRefExpr *RHS,
const TargetMachine &TM) const {
assert(supportDSOLocalEquivalentLowering());

// If GV is dso_local, reference the function itself. Return GV or GV-RHS.
const auto *GV = Equiv->getGlobalValue();

// A PLT entry is not needed for dso_local globals.
const MCExpr *Res = MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());
if (RHS)
Res = MCBinaryExpr::createSub(Res, RHS, getContext());
if (GV->isDSOLocal() || GV->isImplicitDSOLocal())
return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext());

return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeSpecifier,
getContext());
return Res;

// Otherwise, reference the PLT. Return a relocatable expression with the PLT
// specifier, %plt(GV) or %plt(GV-RHS).
Res = createTargetMCExpr(Res, PLTRelativeSpecifier);
if (Res)
return Res;

// If the target only supports the legacy syntax @plt, return GV@plt or
// GV@plt - RHS.
Res = MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeSpecifier,
getContext());
if (RHS)
Res = MCBinaryExpr::createSub(Res, RHS, getContext());
return Res;
}

MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/MC/MCAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// A linker relaxation target may emit ADD/SUB relocations for A-B+C. Let
// recordRelocation handle non-VK_None cases like A@plt-B+C.
if (!IsResolved && Target.getSymA() && Target.getSymB() &&
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None &&
Target.getRefKind() == 0 &&
getBackend().handleAddSubRelocations(*this, *DF, Fixup, Target, Value))
return true;

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/MC/MCParser/AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3144,7 +3144,7 @@ bool AsmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
auto parseOp = [&]() -> bool {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
if (checkForValidSection() || parseExpression(Value))
if (checkForValidSection() || getTargetParser().parseDataExpr(Value))
return true;
// Special case constant expressions to match code generator.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
Expand Down
57 changes: 37 additions & 20 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false);
ParseStatus parseMemOpBaseReg(OperandVector &Operands);
ParseStatus parseZeroOffsetMemOp(OperandVector &Operands);
ParseStatus parseOperandWithModifier(OperandVector &Operands);
ParseStatus parseOperandWithSpecifier(OperandVector &Operands);
ParseStatus parseBareSymbol(OperandVector &Operands);
ParseStatus parseCallSymbol(OperandVector &Operands);
ParseStatus parsePseudoJumpSymbol(OperandVector &Operands);
Expand All @@ -225,6 +225,8 @@ class RISCVAsmParser : public MCTargetAsmParser {
}

bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);
bool parseDataExpr(const MCExpr *&Res) override;

bool parseDirectiveOption();
bool parseDirectiveAttribute();
Expand Down Expand Up @@ -1746,7 +1748,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
"operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
"operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
"integer in the range");
case Match_InvalidSImm12Lsb0:
return generateImmOutOfRangeError(
Expand All @@ -1765,17 +1767,19 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
"immediate must be non-zero in the range");
case Match_InvalidUImm20LUI:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
"operand must be a symbol with "
"%hi/%tprel_hi modifier or an integer in "
"the range");
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1,
"operand must be a symbol with "
"%hi/%tprel_hi specifier or an integer in "
"the range");
case Match_InvalidUImm20:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
case Match_InvalidUImm20AUIPC:
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1,
"operand must be a symbol with a "
"%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
"%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
"or "
"an integer in the range");
case Match_InvalidSImm21Lsb0JAL:
return generateImmOutOfRangeError(
Expand Down Expand Up @@ -2220,38 +2224,51 @@ ParseStatus RISCVAsmParser::parseImmediate(OperandVector &Operands) {
return ParseStatus::Failure;
break;
case AsmToken::Percent:
return parseOperandWithModifier(Operands);
return parseOperandWithSpecifier(Operands);
}

Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
return ParseStatus::Success;
}

ParseStatus RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
ParseStatus RISCVAsmParser::parseOperandWithSpecifier(OperandVector &Operands) {
SMLoc S = getLoc();
SMLoc E;

if (parseToken(AsmToken::Percent, "expected '%' for operand modifier"))
return ParseStatus::Failure;
if (!parseOptionalToken(AsmToken::Percent))
return Error(getLoc(), "expected '%' relocation specifier");
const MCExpr *Expr = nullptr;
bool Failed = parseExprWithSpecifier(Expr, E);
if (!Failed)
Operands.push_back(RISCVOperand::createImm(Expr, S, E, isRV64()));
return Failed;
}

bool RISCVAsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to move these all to ParseStatus, but this PR isn't the right moment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, ParseStatus is preferred for parse* functions generated by TableGen.
However, ParseStatus is used very lightly in AsmParser.cpp, where parseDataExpr is needed. So the bool return value here should be ok.

if (getLexer().getKind() != AsmToken::Identifier)
return Error(getLoc(), "expected valid identifier for operand modifier");
return Error(getLoc(), "expected '%' relocation specifier");
StringRef Identifier = getParser().getTok().getIdentifier();
auto Spec = RISCVMCExpr::getSpecifierForName(Identifier);
if (!Spec)
return Error(getLoc(), "unrecognized operand modifier");
return Error(getLoc(), "invalid relocation specifier");

getParser().Lex(); // Eat the identifier
if (parseToken(AsmToken::LParen, "expected '('"))
return ParseStatus::Failure;
return true;

const MCExpr *SubExpr;
if (getParser().parseParenExpression(SubExpr, E))
return ParseStatus::Failure;
return true;

const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, *Spec, getContext());
Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
return ParseStatus::Success;
Res = RISCVMCExpr::create(SubExpr, *Spec, getContext());
return false;
}

bool RISCVAsmParser::parseDataExpr(const MCExpr *&Res) {
SMLoc E;
if (parseOptionalToken(AsmToken::Percent))
return parseExprWithSpecifier(Res, E);
return getParser().parseExpression(Res);
}

ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
Expand Down Expand Up @@ -3732,7 +3749,7 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
if (Inst.getOperand(2).getReg() != RISCV::X4) {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
"%tprel_add modifier");
"%tprel_add specifier");
}

return false;
Expand All @@ -3745,7 +3762,7 @@ bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
if (Inst.getOperand(0).getReg() != RISCV::X5) {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
return Error(ErrorLoc, "the output operand must be t0/x5 when using "
"%tlsdesc_call modifier");
"%tlsdesc_call specifier");
}

return false;
Expand Down
19 changes: 11 additions & 8 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
assert((!Target.getSymA() ||
Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
"sym@specifier should have been rejected");
const MCExpr *Expr = Fixup.getValue();
// Determine the type of the relocation
unsigned Kind = Fixup.getTargetKind();
Expand All @@ -73,9 +76,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_RISCV_NONE;
case FK_Data_4:
case FK_PCRel_4:
return uint8_t(Target.getAccessVariant()) == RISCVMCExpr::VK_PLT
? ELF::R_RISCV_PLT32
: ELF::R_RISCV_32_PCREL;
return Target.getRefKind() == RISCVMCExpr::VK_PLT ? ELF::R_RISCV_PLT32
: ELF::R_RISCV_32_PCREL;
case RISCV::fixup_riscv_pcrel_hi20:
return ELF::R_RISCV_PCREL_HI20;
case RISCV::fixup_riscv_pcrel_lo12_i:
Expand Down Expand Up @@ -129,11 +131,12 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
return ELF::R_RISCV_NONE;
case FK_Data_4:
if (Expr->getKind() == MCExpr::Target &&
cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_32_PCREL)
return ELF::R_RISCV_32_PCREL;
if (getSpecifier(Target.getSymA()) == RISCVMCExpr::VK_GOTPCREL)
return ELF::R_RISCV_GOT32_PCREL;
if (Expr->getKind() == MCExpr::Target) {
if (cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_32_PCREL)
return ELF::R_RISCV_32_PCREL;
if (cast<RISCVMCExpr>(Expr)->getSpecifier() == RISCVMCExpr::VK_GOTPCREL)
return ELF::R_RISCV_GOT32_PCREL;
}
return ELF::R_RISCV_32;
case FK_Data_8:
return ELF::R_RISCV_64;
Expand Down
7 changes: 0 additions & 7 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@
#include "llvm/TargetParser/Triple.h"
using namespace llvm;

const MCAsmInfo::VariantKindDesc variantKindDescs[] = {
{RISCVMCExpr::VK_GOTPCREL, "GOTPCREL"},
{RISCVMCExpr::VK_PLT, "PLT"},
};

void RISCVMCAsmInfo::anchor() {}

RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
Expand All @@ -33,8 +28,6 @@ RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
ExceptionsType = ExceptionHandling::DwarfCFI;
Data16bitsDirective = "\t.half\t";
Data32bitsDirective = "\t.word\t";

initializeVariantKinds(variantKindDescs);
}

const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
Expand Down
Loading
Loading