forked from OSchip/llvm-project
[RuntimeDyldChecker] Support offset in decode_operand expr
In RISCV's relocations, some relocations are comprised of two relocation types. For example, R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO12_I compose a PC relative relocation. In general the compiler will set a label in the position of R_RISCV_PCREL_HI20. So, to test the R_RISCV_PCREL_LO12_I relocation, we need decode instruction at position of the label points to R_RISCV_PCREL_HI20 plus 4 (the size of a riscv non-compress instruction). Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D105528
This commit is contained in:
parent
18d10fbe87
commit
f4e418ac1e
|
@ -232,6 +232,26 @@ private:
|
|||
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: {
|
||||
EvalResult Number;
|
||||
std::tie(Number, RemainingExpr) = evalNumberExpr(RemainingExpr);
|
||||
Offset = Number.getValue();
|
||||
break;
|
||||
}
|
||||
case BinOpToken::Invalid:
|
||||
break;
|
||||
default:
|
||||
return std::make_pair(
|
||||
unexpectedToken(RemainingExpr, RemainingExpr,
|
||||
"expected '+' for offset or ',' if no offset"),
|
||||
"");
|
||||
}
|
||||
|
||||
if (!RemainingExpr.startswith(","))
|
||||
return std::make_pair(
|
||||
unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), "");
|
||||
|
@ -249,7 +269,7 @@ private:
|
|||
|
||||
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 +327,7 @@ private:
|
|||
|
||||
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()),
|
||||
"");
|
||||
|
@ -664,10 +684,14 @@ private:
|
|||
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<uint8_t> SymbolBytes(SymbolMem.bytes_begin(), SymbolMem.size());
|
||||
if (SymbolMem.size() <= Offset)
|
||||
return false;
|
||||
ArrayRef<uint8_t> SymbolBytes(SymbolMem.bytes_begin() + Offset,
|
||||
SymbolMem.size() - Offset);
|
||||
|
||||
MCDisassembler::DecodeStatus S =
|
||||
Dis->getInstruction(Inst, Size, SymbolBytes, 0, nulls());
|
||||
|
@ -675,7 +699,7 @@ private:
|
|||
return (S == MCDisassembler::Success);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace llvm
|
||||
|
||||
RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(
|
||||
IsSymbolValidFunction IsSymbolValid, GetSymbolInfoFunction GetSymbolInfo,
|
||||
|
|
|
@ -21,7 +21,8 @@ main:
|
|||
.size main, .-main
|
||||
|
||||
# Test R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO
|
||||
# jitlink-check: decode_operand(test_pcrel32, 1) = ((named_data - test_pcrel32) + 0x800)[31:12]
|
||||
# jitlink-check: decode_operand(test_pcrel32, 1) = ((named_data - test_pcrel32) + 0x800)[31:12]
|
||||
# jitlink-check: decode_operand(test_pcrel32+4, 2)[11:0] = (named_data - test_pcrel32)[11:0]
|
||||
.globl test_pcrel32
|
||||
.p2align 1
|
||||
.type test_pcrel32,@function
|
||||
|
|
Loading…
Reference in New Issue