diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -232,6 +232,23 @@ EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()), ""); + // if there is an offset number expr + int64_t Offset = 0; + BinOpToken BinOp; + std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr); + switch (BinOp) { + case BinOpToken::Add: + case BinOpToken::Sub: { + EvalResult Number; + std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr); + Offset = + BinOp == BinOpToken::Add ? Number.getValue() : -Number.getValue(); + break; + } + default: + break; + } + if (!RemainingExpr.startswith(",")) return std::make_pair( unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), ""); @@ -249,7 +266,7 @@ MCInst Inst; uint64_t Size; - if (!decodeInst(Symbol, Inst, Size)) + if (!decodeInst(Symbol, Inst, Size, Offset)) return std::make_pair( EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()), ""); @@ -307,7 +324,7 @@ MCInst Inst; uint64_t InstSize; - if (!decodeInst(Symbol, Inst, InstSize)) + if (!decodeInst(Symbol, Inst, InstSize, 0)) return std::make_pair( EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()), ""); @@ -392,8 +409,8 @@ uint64_t StubAddr; std::string ErrorMsg; - std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr( - FileName, SectionName, PCtx.IsInsideLoad); + std::tie(StubAddr, ErrorMsg) = + Checker.getSectionAddr(FileName, SectionName, PCtx.IsInsideLoad); if (ErrorMsg != "") return std::make_pair(EvalResult(ErrorMsg), ""); @@ -565,7 +582,8 @@ else return std::make_pair( unexpectedToken(Expr, Expr, - "expected '(', '*', identifier, or number"), ""); + "expected '(', '*', identifier, or number"), + ""); if (SubExprResult.hasError()) return std::make_pair(SubExprResult, RemainingExpr); @@ -664,10 +682,12 @@ return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx); } - bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const { + bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size, + int64_t Offset) const { MCDisassembler *Dis = Checker.Disassembler; StringRef SymbolMem = Checker.getSymbolContent(Symbol); - ArrayRef SymbolBytes(SymbolMem.bytes_begin(), SymbolMem.size()); + ArrayRef SymbolBytes(SymbolMem.bytes_begin() + Offset, + SymbolMem.size()); MCDisassembler::DecodeStatus S = Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls()); @@ -675,7 +695,7 @@ return (S == MCDisassembler::Success); } }; -} +} // namespace llvm RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl( IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo, @@ -775,7 +795,7 @@ unsigned Size) const { uintptr_t PtrSizedAddr = static_cast(SrcAddr); assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range."); - void *Ptr = reinterpret_cast(PtrSizedAddr); + void *Ptr = reinterpret_cast(PtrSizedAddr); switch (Size) { case 1: diff --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s --- a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s +++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_pc_indirect.s @@ -19,6 +19,7 @@ # Test R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO # jitlink-check: decode_operand(test_pcrel32, 1) = ((named_data - test_pcrel32) + 0x800) >> 12 +# jitlink-check: decode_operand(test_pcrel32+4, 2) = (named_data - test_pcrel32) - (((named_data - test_pcrel32 + 0x800) & 0xfffff000)) .globl test_pcrel32 .p2align 4, 0x90 .type test_pcrel32,@function