llvm.org GIT mirror llvm / 58692f8
[RISCV] Support assembling @plt symbol operands This patch allows symbols appended with @plt to parse and assemble with the R_RISCV_CALL_PLT relocation. Differential Revision: https://reviews.llvm.org/D55335 Patch by Lewis Revill. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357470 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 7 months ago
11 changed file(s) with 49 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
290290 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
291291 return false;
292292 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
293 VK == RISCVMCExpr::VK_RISCV_CALL;
293 (VK == RISCVMCExpr::VK_RISCV_CALL ||
294 VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
294295 }
295296
296297 bool isCSRSystemRegister() const { return isSystemRegister(); }
11411142 if (getParser().parseIdentifier(Identifier))
11421143 return MatchOperand_ParseFail;
11431144
1145 if (Identifier.consume_back("@plt")) {
1146 Error(getLoc(), "'@plt' operand not valid for instruction");
1147 return MatchOperand_ParseFail;
1148 }
1149
11441150 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
11451151
11461152 if (Sym->isVariable()) {
11681174 if (getParser().parseIdentifier(Identifier))
11691175 return MatchOperand_ParseFail;
11701176
1177 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL;
1178 if (Identifier.consume_back("@plt"))
1179 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
1180
11711181 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
11721182 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1173 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1183 Res = RISCVMCExpr::create(Res, Kind, getContext());
11741184 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
11751185 return MatchOperand_Success;
11761186 }
229229 Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
230230 return Value;
231231 }
232 case RISCV::fixup_riscv_call: {
232 case RISCV::fixup_riscv_call:
233 case RISCV::fixup_riscv_call_plt: {
233234 // Jalr will add UpperImm with the sign-extended 12-bit LowerImm,
234235 // we need to add 0x800ULL before extract upper bits to reflect the
235236 // effect of the sign extension.
109109 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
110110 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
111111 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
112 { "fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
112113 { "fixup_riscv_relax", 0, 0, 0 },
113114 { "fixup_riscv_align", 0, 0, 0 }
114115 };
9494 return ELF::R_RISCV_RVC_BRANCH;
9595 case RISCV::fixup_riscv_call:
9696 return ELF::R_RISCV_CALL;
97 case RISCV::fixup_riscv_call_plt:
98 return ELF::R_RISCV_CALL_PLT;
9799 case RISCV::fixup_riscv_relax:
98100 return ELF::R_RISCV_RELAX;
99101 case RISCV::fixup_riscv_align:
5151 // fixup_riscv_call - A fixup representing a call attached to the auipc
5252 // instruction in a pair composed of adjacent auipc+jalr instructions.
5353 fixup_riscv_call,
54 // fixup_riscv_call_plt - A fixup representing a procedure linkage table call
55 // attached to the auipc instruction in a pair composed of adjacent auipc+jalr
56 // instructions.
57 fixup_riscv_call_plt,
5458 // fixup_riscv_relax - Used to generate an R_RISCV_RELAX relocation type,
5559 // which indicates the linker may relax the instruction pair.
5660 fixup_riscv_relax,
241241 FixupKind = RISCV::fixup_riscv_call;
242242 RelaxCandidate = true;
243243 break;
244 case RISCVMCExpr::VK_RISCV_CALL_PLT:
245 FixupKind = RISCV::fixup_riscv_call_plt;
246 RelaxCandidate = true;
247 break;
244248 }
245249 } else if (Kind == MCExpr::SymbolRef &&
246250 cast(Expr)->getKind() == MCSymbolRefExpr::VK_None) {
3232 }
3333
3434 void RISCVMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
35 bool HasVariant =
36 ((getKind() != VK_RISCV_None) && (getKind() != VK_RISCV_CALL));
35 VariantKind Kind = getKind();
36 bool HasVariant = ((Kind != VK_RISCV_None) && (Kind != VK_RISCV_CALL) &&
37 (Kind != VK_RISCV_CALL_PLT));
38
3739 if (HasVariant)
3840 OS << '%' << getVariantKindName(getKind()) << '(';
3941 Expr->print(OS, MAI);
42 if (Kind == VK_RISCV_CALL_PLT)
43 OS << "@plt";
4044 if (HasVariant)
4145 OS << ')';
4246 }
199203 MCValue Value;
200204
201205 if (Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO ||
202 Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_CALL)
206 Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_CALL ||
207 Kind == VK_RISCV_CALL_PLT)
203208 return false;
204209
205210 if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
2929 VK_RISCV_PCREL_HI,
3030 VK_RISCV_GOT_HI,
3131 VK_RISCV_CALL,
32 VK_RISCV_CALL_PLT,
3233 VK_RISCV_Invalid
3334 };
3435
4242 # INSTR: auipc ra, 0
4343 # INSTR: jalr ra
4444 # FIXUP: fixup A - offset: 0, value: mstatus, kind: fixup_riscv_call
45
46 # Ensure that calls to procedure linkage table symbols work.
47
48 call foo@plt
49 # RELOC: R_RISCV_CALL_PLT foo 0x0
50 # INSTR: auipc ra, 0
51 # INSTR: jalr ra
52 # FIXUP: fixup A - offset: 0, value: foo@plt, kind: fixup_riscv_call_plt
33 # Non bare symbols must be rejected
44 lla a2, %lo(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name
55 lla a2, %hi(a_symbol) # CHECK: :[[@LINE]]:9: error: operand must be a bare symbol name
6 lla a2, foo@plt # CHECK: :[[@LINE]]:17: error: '@plt' operand not valid for instruction
4444 # INSTR: auipc t1, 0
4545 # INSTR: jr t1
4646 # FIXUP: fixup A - offset: 0, value: ra, kind:
47
48 tail foo@plt
49 # RELOC: R_RISCV_CALL_PLT foo 0x0
50 # INSTR: auipc t1, 0
51 # INSTR: jr t1
52 # FIXUP: fixup A - offset: 0, value: foo@plt, kind: