2014-06-28 04:20:57 +08:00
|
|
|
//===--- RuntimeDyldChecker.cpp - RuntimeDyld tester framework --*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-05-27 22:27:24 +08:00
|
|
|
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "RuntimeDyldCheckerImpl.h"
|
|
|
|
#include "RuntimeDyldImpl.h"
|
2016-05-27 22:27:24 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2014-06-28 04:20:57 +08:00
|
|
|
#include "llvm/MC/MCContext.h"
|
2016-01-27 00:44:37 +08:00
|
|
|
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
2014-06-28 04:20:57 +08:00
|
|
|
#include "llvm/MC/MCInst.h"
|
2014-07-30 04:40:37 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2014-06-28 04:37:39 +08:00
|
|
|
#include <cctype>
|
2014-06-28 04:20:57 +08:00
|
|
|
#include <memory>
|
2016-05-27 22:27:24 +08:00
|
|
|
#include <utility>
|
2014-06-28 04:20:57 +08:00
|
|
|
|
|
|
|
#define DEBUG_TYPE "rtdyld"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Helper class that implements the language evaluated by RuntimeDyldChecker.
|
|
|
|
class RuntimeDyldCheckerExprEval {
|
|
|
|
public:
|
|
|
|
RuntimeDyldCheckerExprEval(const RuntimeDyldCheckerImpl &Checker,
|
|
|
|
raw_ostream &ErrStream)
|
|
|
|
: Checker(Checker) {}
|
|
|
|
|
|
|
|
bool evaluate(StringRef Expr) const {
|
|
|
|
// Expect equality expression of the form 'LHS = RHS'.
|
|
|
|
Expr = Expr.trim();
|
|
|
|
size_t EQIdx = Expr.find('=');
|
|
|
|
|
|
|
|
ParseContext OutsideLoad(false);
|
|
|
|
|
|
|
|
// Evaluate LHS.
|
|
|
|
StringRef LHSExpr = Expr.substr(0, EQIdx).rtrim();
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
EvalResult LHSResult;
|
|
|
|
std::tie(LHSResult, RemainingExpr) =
|
|
|
|
evalComplexExpr(evalSimpleExpr(LHSExpr, OutsideLoad), OutsideLoad);
|
|
|
|
if (LHSResult.hasError())
|
|
|
|
return handleError(Expr, LHSResult);
|
|
|
|
if (RemainingExpr != "")
|
|
|
|
return handleError(Expr, unexpectedToken(RemainingExpr, LHSExpr, ""));
|
|
|
|
|
|
|
|
// Evaluate RHS.
|
|
|
|
StringRef RHSExpr = Expr.substr(EQIdx + 1).ltrim();
|
|
|
|
EvalResult RHSResult;
|
|
|
|
std::tie(RHSResult, RemainingExpr) =
|
|
|
|
evalComplexExpr(evalSimpleExpr(RHSExpr, OutsideLoad), OutsideLoad);
|
|
|
|
if (RHSResult.hasError())
|
|
|
|
return handleError(Expr, RHSResult);
|
|
|
|
if (RemainingExpr != "")
|
|
|
|
return handleError(Expr, unexpectedToken(RemainingExpr, RHSExpr, ""));
|
|
|
|
|
|
|
|
if (LHSResult.getValue() != RHSResult.getValue()) {
|
|
|
|
Checker.ErrStream << "Expression '" << Expr << "' is false: "
|
2014-07-30 05:38:20 +08:00
|
|
|
<< format("0x%" PRIx64, LHSResult.getValue())
|
|
|
|
<< " != " << format("0x%" PRIx64, RHSResult.getValue())
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
<< "\n";
|
|
|
|
return false;
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// RuntimeDyldCheckerExprEval requires some context when parsing exprs. In
|
|
|
|
// particular, it needs to know whether a symbol is being evaluated in the
|
|
|
|
// context of a load, in which case we want the linker's local address for
|
|
|
|
// the symbol, or outside of a load, in which case we want the symbol's
|
|
|
|
// address in the remote target.
|
|
|
|
|
|
|
|
struct ParseContext {
|
|
|
|
bool IsInsideLoad;
|
|
|
|
ParseContext(bool IsInsideLoad) : IsInsideLoad(IsInsideLoad) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
const RuntimeDyldCheckerImpl &Checker;
|
|
|
|
|
|
|
|
enum class BinOpToken : unsigned {
|
|
|
|
Invalid,
|
|
|
|
Add,
|
|
|
|
Sub,
|
|
|
|
BitwiseAnd,
|
|
|
|
BitwiseOr,
|
|
|
|
ShiftLeft,
|
|
|
|
ShiftRight
|
|
|
|
};
|
|
|
|
|
|
|
|
class EvalResult {
|
|
|
|
public:
|
|
|
|
EvalResult() : Value(0), ErrorMsg("") {}
|
|
|
|
EvalResult(uint64_t Value) : Value(Value), ErrorMsg("") {}
|
2016-05-27 22:27:24 +08:00
|
|
|
EvalResult(std::string ErrorMsg)
|
|
|
|
: Value(0), ErrorMsg(std::move(ErrorMsg)) {}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
uint64_t getValue() const { return Value; }
|
|
|
|
bool hasError() const { return ErrorMsg != ""; }
|
|
|
|
const std::string &getErrorMsg() const { return ErrorMsg; }
|
2014-06-28 04:20:57 +08:00
|
|
|
|
|
|
|
private:
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
uint64_t Value;
|
|
|
|
std::string ErrorMsg;
|
|
|
|
};
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
StringRef getTokenForError(StringRef Expr) const {
|
|
|
|
if (Expr.empty())
|
|
|
|
return "";
|
|
|
|
|
|
|
|
StringRef Token, Remaining;
|
|
|
|
if (isalpha(Expr[0]))
|
|
|
|
std::tie(Token, Remaining) = parseSymbol(Expr);
|
|
|
|
else if (isdigit(Expr[0]))
|
|
|
|
std::tie(Token, Remaining) = parseNumberString(Expr);
|
|
|
|
else {
|
|
|
|
unsigned TokLen = 1;
|
|
|
|
if (Expr.startswith("<<") || Expr.startswith(">>"))
|
|
|
|
TokLen = 2;
|
|
|
|
Token = Expr.substr(0, TokLen);
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return Token;
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
EvalResult unexpectedToken(StringRef TokenStart, StringRef SubExpr,
|
|
|
|
StringRef ErrText) const {
|
|
|
|
std::string ErrorMsg("Encountered unexpected token '");
|
|
|
|
ErrorMsg += getTokenForError(TokenStart);
|
|
|
|
if (SubExpr != "") {
|
|
|
|
ErrorMsg += "' while parsing subexpression '";
|
|
|
|
ErrorMsg += SubExpr;
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
ErrorMsg += "'";
|
|
|
|
if (ErrText != "") {
|
|
|
|
ErrorMsg += " ";
|
|
|
|
ErrorMsg += ErrText;
|
|
|
|
}
|
|
|
|
return EvalResult(std::move(ErrorMsg));
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
bool handleError(StringRef Expr, const EvalResult &R) const {
|
|
|
|
assert(R.hasError() && "Not an error result.");
|
|
|
|
Checker.ErrStream << "Error evaluating expression '" << Expr
|
|
|
|
<< "': " << R.getErrorMsg() << "\n";
|
|
|
|
return false;
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
std::pair<BinOpToken, StringRef> parseBinOpToken(StringRef Expr) const {
|
|
|
|
if (Expr.empty())
|
|
|
|
return std::make_pair(BinOpToken::Invalid, "");
|
|
|
|
|
|
|
|
// Handle the two 2-character tokens.
|
|
|
|
if (Expr.startswith("<<"))
|
|
|
|
return std::make_pair(BinOpToken::ShiftLeft, Expr.substr(2).ltrim());
|
|
|
|
if (Expr.startswith(">>"))
|
|
|
|
return std::make_pair(BinOpToken::ShiftRight, Expr.substr(2).ltrim());
|
|
|
|
|
|
|
|
// Handle one-character tokens.
|
|
|
|
BinOpToken Op;
|
|
|
|
switch (Expr[0]) {
|
|
|
|
default:
|
|
|
|
return std::make_pair(BinOpToken::Invalid, Expr);
|
|
|
|
case '+':
|
|
|
|
Op = BinOpToken::Add;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
Op = BinOpToken::Sub;
|
|
|
|
break;
|
|
|
|
case '&':
|
|
|
|
Op = BinOpToken::BitwiseAnd;
|
|
|
|
break;
|
|
|
|
case '|':
|
|
|
|
Op = BinOpToken::BitwiseOr;
|
|
|
|
break;
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(Op, Expr.substr(1).ltrim());
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
EvalResult computeBinOpResult(BinOpToken Op, const EvalResult &LHSResult,
|
|
|
|
const EvalResult &RHSResult) const {
|
|
|
|
switch (Op) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Tried to evaluate unrecognized operation.");
|
|
|
|
case BinOpToken::Add:
|
|
|
|
return EvalResult(LHSResult.getValue() + RHSResult.getValue());
|
|
|
|
case BinOpToken::Sub:
|
|
|
|
return EvalResult(LHSResult.getValue() - RHSResult.getValue());
|
|
|
|
case BinOpToken::BitwiseAnd:
|
|
|
|
return EvalResult(LHSResult.getValue() & RHSResult.getValue());
|
|
|
|
case BinOpToken::BitwiseOr:
|
|
|
|
return EvalResult(LHSResult.getValue() | RHSResult.getValue());
|
|
|
|
case BinOpToken::ShiftLeft:
|
|
|
|
return EvalResult(LHSResult.getValue() << RHSResult.getValue());
|
|
|
|
case BinOpToken::ShiftRight:
|
|
|
|
return EvalResult(LHSResult.getValue() >> RHSResult.getValue());
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Parse a symbol and return a (string, string) pair representing the symbol
|
|
|
|
// name and expression remaining to be parsed.
|
|
|
|
std::pair<StringRef, StringRef> parseSymbol(StringRef Expr) const {
|
|
|
|
size_t FirstNonSymbol = Expr.find_first_not_of("0123456789"
|
|
|
|
"abcdefghijklmnopqrstuvwxyz"
|
|
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
2014-08-20 04:04:45 +08:00
|
|
|
":_.$");
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(Expr.substr(0, FirstNonSymbol),
|
|
|
|
Expr.substr(FirstNonSymbol).ltrim());
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Evaluate a call to decode_operand. Decode the instruction operand at the
|
|
|
|
// given symbol and get the value of the requested operand.
|
|
|
|
// Returns an error if the instruction cannot be decoded, or the requested
|
|
|
|
// operand is not an immediate.
|
|
|
|
// On success, retuns a pair containing the value of the operand, plus
|
|
|
|
// the expression remaining to be evaluated.
|
|
|
|
std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const {
|
|
|
|
if (!Expr.startswith("("))
|
|
|
|
return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
|
|
|
|
StringRef RemainingExpr = Expr.substr(1).ltrim();
|
|
|
|
StringRef Symbol;
|
|
|
|
std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
|
|
|
|
|
|
|
|
if (!Checker.isSymbolValid(Symbol))
|
|
|
|
return std::make_pair(
|
|
|
|
EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
|
|
|
|
"");
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (!RemainingExpr.startswith(","))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected ','"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
EvalResult OpIdxExpr;
|
|
|
|
std::tie(OpIdxExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
|
|
|
|
if (OpIdxExpr.hasError())
|
|
|
|
return std::make_pair(OpIdxExpr, "");
|
2014-07-11 07:26:20 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (!RemainingExpr.startswith(")"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
MCInst Inst;
|
|
|
|
uint64_t Size;
|
|
|
|
if (!decodeInst(Symbol, Inst, Size))
|
|
|
|
return std::make_pair(
|
|
|
|
EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
|
|
|
|
"");
|
|
|
|
|
|
|
|
unsigned OpIdx = OpIdxExpr.getValue();
|
|
|
|
if (OpIdx >= Inst.getNumOperands()) {
|
|
|
|
std::string ErrMsg;
|
|
|
|
raw_string_ostream ErrMsgStream(ErrMsg);
|
|
|
|
ErrMsgStream << "Invalid operand index '" << format("%i", OpIdx)
|
|
|
|
<< "' for instruction '" << Symbol
|
|
|
|
<< "'. Instruction has only "
|
|
|
|
<< format("%i", Inst.getNumOperands())
|
|
|
|
<< " operands.\nInstruction is:\n ";
|
2015-02-05 08:58:51 +08:00
|
|
|
Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
const MCOperand &Op = Inst.getOperand(OpIdx);
|
|
|
|
if (!Op.isImm()) {
|
|
|
|
std::string ErrMsg;
|
|
|
|
raw_string_ostream ErrMsgStream(ErrMsg);
|
|
|
|
ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
|
|
|
|
<< Symbol << "' is not an immediate.\nInstruction is:\n ";
|
2015-02-05 08:58:51 +08:00
|
|
|
Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
|
|
|
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(EvalResult(Op.getImm()), RemainingExpr);
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Evaluate a call to next_pc.
|
|
|
|
// Decode the instruction at the given symbol and return the following program
|
|
|
|
// counter.
|
|
|
|
// Returns an error if the instruction cannot be decoded.
|
|
|
|
// On success, returns a pair containing the next PC, plus of the
|
|
|
|
// expression remaining to be evaluated.
|
|
|
|
std::pair<EvalResult, StringRef> evalNextPC(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
if (!Expr.startswith("("))
|
|
|
|
return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
|
|
|
|
StringRef RemainingExpr = Expr.substr(1).ltrim();
|
|
|
|
StringRef Symbol;
|
|
|
|
std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
|
|
|
|
|
|
|
|
if (!Checker.isSymbolValid(Symbol))
|
|
|
|
return std::make_pair(
|
|
|
|
EvalResult(("Cannot decode unknown symbol '" + Symbol + "'").str()),
|
|
|
|
"");
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (!RemainingExpr.startswith(")"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected ')'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
MCInst Inst;
|
|
|
|
uint64_t InstSize;
|
|
|
|
if (!decodeInst(Symbol, Inst, InstSize))
|
|
|
|
return std::make_pair(
|
|
|
|
EvalResult(("Couldn't decode instruction at '" + Symbol + "'").str()),
|
|
|
|
"");
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
uint64_t SymbolAddr = PCtx.IsInsideLoad
|
2015-03-11 08:43:26 +08:00
|
|
|
? Checker.getSymbolLocalAddr(Symbol)
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
: Checker.getSymbolRemoteAddr(Symbol);
|
|
|
|
uint64_t NextPC = SymbolAddr + InstSize;
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(EvalResult(NextPC), RemainingExpr);
|
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Evaluate a call to stub_addr.
|
|
|
|
// Look up and return the address of the stub for the given
|
|
|
|
// (<file name>, <section name>, <symbol name>) tuple.
|
|
|
|
// On success, returns a pair containing the stub address, plus the expression
|
|
|
|
// remaining to be evaluated.
|
|
|
|
std::pair<EvalResult, StringRef> evalStubAddr(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
if (!Expr.startswith("("))
|
|
|
|
return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
|
|
|
|
StringRef RemainingExpr = Expr.substr(1).ltrim();
|
|
|
|
|
|
|
|
// Handle file-name specially, as it may contain characters that aren't
|
|
|
|
// legal for symbols.
|
|
|
|
StringRef FileName;
|
|
|
|
size_t ComaIdx = RemainingExpr.find(',');
|
|
|
|
FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
|
|
|
|
RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
|
|
|
|
|
|
|
|
if (!RemainingExpr.startswith(","))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
StringRef SectionName;
|
|
|
|
std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (!RemainingExpr.startswith(","))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
StringRef Symbol;
|
|
|
|
std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (!RemainingExpr.startswith(")"))
|
2014-06-28 04:20:57 +08:00
|
|
|
return std::make_pair(
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
uint64_t StubAddr;
|
|
|
|
std::string ErrorMsg = "";
|
|
|
|
std::tie(StubAddr, ErrorMsg) = Checker.getStubAddrFor(
|
|
|
|
FileName, SectionName, Symbol, PCtx.IsInsideLoad);
|
|
|
|
|
|
|
|
if (ErrorMsg != "")
|
|
|
|
return std::make_pair(EvalResult(ErrorMsg), "");
|
|
|
|
|
|
|
|
return std::make_pair(EvalResult(StubAddr), RemainingExpr);
|
|
|
|
}
|
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
std::pair<EvalResult, StringRef> evalSectionAddr(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
if (!Expr.startswith("("))
|
|
|
|
return std::make_pair(unexpectedToken(Expr, Expr, "expected '('"), "");
|
|
|
|
StringRef RemainingExpr = Expr.substr(1).ltrim();
|
|
|
|
|
|
|
|
// Handle file-name specially, as it may contain characters that aren't
|
|
|
|
// legal for symbols.
|
|
|
|
StringRef FileName;
|
|
|
|
size_t ComaIdx = RemainingExpr.find(',');
|
|
|
|
FileName = RemainingExpr.substr(0, ComaIdx).rtrim();
|
|
|
|
RemainingExpr = RemainingExpr.substr(ComaIdx).ltrim();
|
|
|
|
|
|
|
|
if (!RemainingExpr.startswith(","))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ','"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
StringRef SectionName;
|
|
|
|
std::tie(SectionName, RemainingExpr) = parseSymbol(RemainingExpr);
|
|
|
|
|
|
|
|
if (!RemainingExpr.startswith(")"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
uint64_t StubAddr;
|
|
|
|
std::string ErrorMsg = "";
|
|
|
|
std::tie(StubAddr, ErrorMsg) = Checker.getSectionAddr(
|
|
|
|
FileName, SectionName, PCtx.IsInsideLoad);
|
|
|
|
|
|
|
|
if (ErrorMsg != "")
|
|
|
|
return std::make_pair(EvalResult(ErrorMsg), "");
|
|
|
|
|
|
|
|
return std::make_pair(EvalResult(StubAddr), RemainingExpr);
|
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Evaluate an identiefer expr, which may be a symbol, or a call to
|
|
|
|
// one of the builtin functions: get_insn_opcode or get_insn_length.
|
|
|
|
// Return the result, plus the expression remaining to be parsed.
|
|
|
|
std::pair<EvalResult, StringRef> evalIdentifierExpr(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
StringRef Symbol;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
std::tie(Symbol, RemainingExpr) = parseSymbol(Expr);
|
|
|
|
|
|
|
|
// Check for builtin function calls.
|
|
|
|
if (Symbol == "decode_operand")
|
|
|
|
return evalDecodeOperand(RemainingExpr);
|
|
|
|
else if (Symbol == "next_pc")
|
|
|
|
return evalNextPC(RemainingExpr, PCtx);
|
|
|
|
else if (Symbol == "stub_addr")
|
|
|
|
return evalStubAddr(RemainingExpr, PCtx);
|
2014-09-03 13:01:46 +08:00
|
|
|
else if (Symbol == "section_addr")
|
|
|
|
return evalSectionAddr(RemainingExpr, PCtx);
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
|
|
|
if (!Checker.isSymbolValid(Symbol)) {
|
|
|
|
std::string ErrMsg("No known address for symbol '");
|
|
|
|
ErrMsg += Symbol;
|
|
|
|
ErrMsg += "'";
|
|
|
|
if (Symbol.startswith("L"))
|
|
|
|
ErrMsg += " (this appears to be an assembler local label - "
|
|
|
|
" perhaps drop the 'L'?)";
|
|
|
|
|
|
|
|
return std::make_pair(EvalResult(ErrMsg), "");
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// The value for the symbol depends on the context we're evaluating in:
|
|
|
|
// Inside a load this is the address in the linker's memory, outside a
|
|
|
|
// load it's the address in the target processes memory.
|
2015-03-11 08:43:26 +08:00
|
|
|
uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
: Checker.getSymbolRemoteAddr(Symbol);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Looks like a plain symbol reference.
|
|
|
|
return std::make_pair(EvalResult(Value), RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse a number (hexadecimal or decimal) and return a (string, string)
|
|
|
|
// pair representing the number and the expression remaining to be parsed.
|
|
|
|
std::pair<StringRef, StringRef> parseNumberString(StringRef Expr) const {
|
|
|
|
size_t FirstNonDigit = StringRef::npos;
|
|
|
|
if (Expr.startswith("0x")) {
|
|
|
|
FirstNonDigit = Expr.find_first_not_of("0123456789abcdefABCDEF", 2);
|
|
|
|
if (FirstNonDigit == StringRef::npos)
|
|
|
|
FirstNonDigit = Expr.size();
|
|
|
|
} else {
|
|
|
|
FirstNonDigit = Expr.find_first_not_of("0123456789");
|
|
|
|
if (FirstNonDigit == StringRef::npos)
|
|
|
|
FirstNonDigit = Expr.size();
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(Expr.substr(0, FirstNonDigit),
|
|
|
|
Expr.substr(FirstNonDigit));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate a constant numeric expression (hexidecimal or decimal) and
|
|
|
|
// return a pair containing the result, and the expression remaining to be
|
|
|
|
// evaluated.
|
|
|
|
std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const {
|
|
|
|
StringRef ValueStr;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
std::tie(ValueStr, RemainingExpr) = parseNumberString(Expr);
|
|
|
|
|
|
|
|
if (ValueStr.empty() || !isdigit(ValueStr[0]))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected number"), "");
|
|
|
|
uint64_t Value;
|
|
|
|
ValueStr.getAsInteger(0, Value);
|
|
|
|
return std::make_pair(EvalResult(Value), RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate an expression of the form "(<expr>)" and return a pair
|
|
|
|
// containing the result of evaluating <expr>, plus the expression
|
|
|
|
// remaining to be parsed.
|
|
|
|
std::pair<EvalResult, StringRef> evalParensExpr(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
assert(Expr.startswith("(") && "Not a parenthesized expression");
|
|
|
|
EvalResult SubExprResult;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
std::tie(SubExprResult, RemainingExpr) =
|
|
|
|
evalComplexExpr(evalSimpleExpr(Expr.substr(1).ltrim(), PCtx), PCtx);
|
|
|
|
if (SubExprResult.hasError())
|
|
|
|
return std::make_pair(SubExprResult, "");
|
|
|
|
if (!RemainingExpr.startswith(")"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
return std::make_pair(SubExprResult, RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate an expression in one of the following forms:
|
|
|
|
// *{<number>}<expr>
|
|
|
|
// Return a pair containing the result, plus the expression remaining to be
|
|
|
|
// parsed.
|
|
|
|
std::pair<EvalResult, StringRef> evalLoadExpr(StringRef Expr) const {
|
|
|
|
assert(Expr.startswith("*") && "Not a load expression");
|
|
|
|
StringRef RemainingExpr = Expr.substr(1).ltrim();
|
|
|
|
|
|
|
|
// Parse read size.
|
|
|
|
if (!RemainingExpr.startswith("{"))
|
|
|
|
return std::make_pair(EvalResult("Expected '{' following '*'."), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
EvalResult ReadSizeExpr;
|
|
|
|
std::tie(ReadSizeExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
|
|
|
|
if (ReadSizeExpr.hasError())
|
|
|
|
return std::make_pair(ReadSizeExpr, RemainingExpr);
|
|
|
|
uint64_t ReadSize = ReadSizeExpr.getValue();
|
|
|
|
if (ReadSize < 1 || ReadSize > 8)
|
|
|
|
return std::make_pair(EvalResult("Invalid size for dereference."), "");
|
|
|
|
if (!RemainingExpr.startswith("}"))
|
|
|
|
return std::make_pair(EvalResult("Missing '}' for dereference."), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
// Evaluate the expression representing the load address.
|
|
|
|
ParseContext LoadCtx(true);
|
|
|
|
EvalResult LoadAddrExprResult;
|
|
|
|
std::tie(LoadAddrExprResult, RemainingExpr) =
|
|
|
|
evalComplexExpr(evalSimpleExpr(RemainingExpr, LoadCtx), LoadCtx);
|
|
|
|
|
|
|
|
if (LoadAddrExprResult.hasError())
|
|
|
|
return std::make_pair(LoadAddrExprResult, "");
|
|
|
|
|
|
|
|
uint64_t LoadAddr = LoadAddrExprResult.getValue();
|
|
|
|
|
|
|
|
return std::make_pair(
|
|
|
|
EvalResult(Checker.readMemoryAtAddr(LoadAddr, ReadSize)),
|
|
|
|
RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate a "simple" expression. This is any expression that _isn't_ an
|
|
|
|
// un-parenthesized binary expression.
|
|
|
|
//
|
|
|
|
// "Simple" expressions can be optionally bit-sliced. See evalSlicedExpr.
|
|
|
|
//
|
|
|
|
// Returns a pair containing the result of the evaluation, plus the
|
|
|
|
// expression remaining to be parsed.
|
|
|
|
std::pair<EvalResult, StringRef> evalSimpleExpr(StringRef Expr,
|
|
|
|
ParseContext PCtx) const {
|
|
|
|
EvalResult SubExprResult;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
|
|
|
|
if (Expr.empty())
|
|
|
|
return std::make_pair(EvalResult("Unexpected end of expression"), "");
|
|
|
|
|
|
|
|
if (Expr[0] == '(')
|
|
|
|
std::tie(SubExprResult, RemainingExpr) = evalParensExpr(Expr, PCtx);
|
|
|
|
else if (Expr[0] == '*')
|
|
|
|
std::tie(SubExprResult, RemainingExpr) = evalLoadExpr(Expr);
|
2014-07-23 07:17:21 +08:00
|
|
|
else if (isalpha(Expr[0]) || Expr[0] == '_')
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
std::tie(SubExprResult, RemainingExpr) = evalIdentifierExpr(Expr, PCtx);
|
|
|
|
else if (isdigit(Expr[0]))
|
|
|
|
std::tie(SubExprResult, RemainingExpr) = evalNumberExpr(Expr);
|
2014-09-03 13:01:46 +08:00
|
|
|
else
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(Expr, Expr,
|
|
|
|
"expected '(', '*', identifier, or number"), "");
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
|
|
|
if (SubExprResult.hasError())
|
|
|
|
return std::make_pair(SubExprResult, RemainingExpr);
|
|
|
|
|
|
|
|
// Evaluate bit-slice if present.
|
|
|
|
if (RemainingExpr.startswith("["))
|
|
|
|
std::tie(SubExprResult, RemainingExpr) =
|
|
|
|
evalSliceExpr(std::make_pair(SubExprResult, RemainingExpr));
|
|
|
|
|
|
|
|
return std::make_pair(SubExprResult, RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate a bit-slice of an expression.
|
|
|
|
// A bit-slice has the form "<expr>[high:low]". The result of evaluating a
|
|
|
|
// slice is the bits between high and low (inclusive) in the original
|
|
|
|
// expression, right shifted so that the "low" bit is in position 0 in the
|
|
|
|
// result.
|
|
|
|
// Returns a pair containing the result of the slice operation, plus the
|
|
|
|
// expression remaining to be parsed.
|
|
|
|
std::pair<EvalResult, StringRef>
|
2016-06-18 04:41:14 +08:00
|
|
|
evalSliceExpr(const std::pair<EvalResult, StringRef> &Ctx) const {
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
EvalResult SubExprResult;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
std::tie(SubExprResult, RemainingExpr) = Ctx;
|
|
|
|
|
|
|
|
assert(RemainingExpr.startswith("[") && "Not a slice expr.");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
EvalResult HighBitExpr;
|
|
|
|
std::tie(HighBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
|
|
|
|
|
|
|
|
if (HighBitExpr.hasError())
|
|
|
|
return std::make_pair(HighBitExpr, RemainingExpr);
|
|
|
|
|
|
|
|
if (!RemainingExpr.startswith(":"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected ':'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
EvalResult LowBitExpr;
|
|
|
|
std::tie(LowBitExpr, RemainingExpr) = evalNumberExpr(RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (LowBitExpr.hasError())
|
|
|
|
return std::make_pair(LowBitExpr, RemainingExpr);
|
|
|
|
|
|
|
|
if (!RemainingExpr.startswith("]"))
|
|
|
|
return std::make_pair(
|
|
|
|
unexpectedToken(RemainingExpr, RemainingExpr, "expected ']'"), "");
|
|
|
|
RemainingExpr = RemainingExpr.substr(1).ltrim();
|
|
|
|
|
|
|
|
unsigned HighBit = HighBitExpr.getValue();
|
|
|
|
unsigned LowBit = LowBitExpr.getValue();
|
|
|
|
uint64_t Mask = ((uint64_t)1 << (HighBit - LowBit + 1)) - 1;
|
|
|
|
uint64_t SlicedValue = (SubExprResult.getValue() >> LowBit) & Mask;
|
|
|
|
return std::make_pair(EvalResult(SlicedValue), RemainingExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evaluate a "complex" expression.
|
|
|
|
// Takes an already evaluated subexpression and checks for the presence of a
|
|
|
|
// binary operator, computing the result of the binary operation if one is
|
|
|
|
// found. Used to make arithmetic expressions left-associative.
|
|
|
|
// Returns a pair containing the ultimate result of evaluating the
|
|
|
|
// expression, plus the expression remaining to be evaluated.
|
|
|
|
std::pair<EvalResult, StringRef>
|
2016-06-18 04:41:14 +08:00
|
|
|
evalComplexExpr(const std::pair<EvalResult, StringRef> &LHSAndRemaining,
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
ParseContext PCtx) const {
|
|
|
|
EvalResult LHSResult;
|
|
|
|
StringRef RemainingExpr;
|
|
|
|
std::tie(LHSResult, RemainingExpr) = LHSAndRemaining;
|
|
|
|
|
|
|
|
// If there was an error, or there's nothing left to evaluate, return the
|
2014-06-28 04:20:57 +08:00
|
|
|
// result.
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
if (LHSResult.hasError() || RemainingExpr == "")
|
|
|
|
return std::make_pair(LHSResult, RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// Otherwise check if this is a binary expressioan.
|
|
|
|
BinOpToken BinOp;
|
|
|
|
std::tie(BinOp, RemainingExpr) = parseBinOpToken(RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// If this isn't a recognized expression just return.
|
|
|
|
if (BinOp == BinOpToken::Invalid)
|
|
|
|
return std::make_pair(LHSResult, RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// This is a recognized bin-op. Evaluate the RHS, then evaluate the binop.
|
|
|
|
EvalResult RHSResult;
|
|
|
|
std::tie(RHSResult, RemainingExpr) = evalSimpleExpr(RemainingExpr, PCtx);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// If there was an error evaluating the RHS, return it.
|
|
|
|
if (RHSResult.hasError())
|
|
|
|
return std::make_pair(RHSResult, RemainingExpr);
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
// This is a binary expression - evaluate and try to continue as a
|
|
|
|
// complex expr.
|
|
|
|
EvalResult ThisResult(computeBinOpResult(BinOp, LHSResult, RHSResult));
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return evalComplexExpr(std::make_pair(ThisResult, RemainingExpr), PCtx);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool decodeInst(StringRef Symbol, MCInst &Inst, uint64_t &Size) const {
|
|
|
|
MCDisassembler *Dis = Checker.Disassembler;
|
|
|
|
StringRef SectionMem = Checker.getSubsectionStartingAt(Symbol);
|
2014-11-12 21:55:27 +08:00
|
|
|
ArrayRef<uint8_t> SectionBytes(
|
2014-11-13 03:43:13 +08:00
|
|
|
reinterpret_cast<const uint8_t *>(SectionMem.data()),
|
2014-11-12 21:55:27 +08:00
|
|
|
SectionMem.size());
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
|
|
|
MCDisassembler::DecodeStatus S =
|
|
|
|
Dis->getInstruction(Inst, Size, SectionBytes, 0, nulls(), nulls());
|
|
|
|
|
|
|
|
return (S == MCDisassembler::Success);
|
|
|
|
}
|
|
|
|
};
|
2015-06-23 17:49:53 +08:00
|
|
|
}
|
2014-06-28 04:20:57 +08:00
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld,
|
|
|
|
MCDisassembler *Disassembler,
|
|
|
|
MCInstPrinter *InstPrinter,
|
|
|
|
raw_ostream &ErrStream)
|
|
|
|
: RTDyld(RTDyld), Disassembler(Disassembler), InstPrinter(InstPrinter),
|
|
|
|
ErrStream(ErrStream) {
|
|
|
|
RTDyld.Checker = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
|
2014-06-28 04:20:57 +08:00
|
|
|
CheckExpr = CheckExpr.trim();
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr << "'...\n");
|
2014-06-28 04:20:57 +08:00
|
|
|
RuntimeDyldCheckerExprEval P(*this, ErrStream);
|
|
|
|
bool Result = P.evaluate(CheckExpr);
|
|
|
|
(void)Result;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "
|
|
|
|
<< (Result ? "passed" : "FAILED") << ".\n");
|
2014-06-28 04:20:57 +08:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
|
|
|
|
MemoryBuffer *MemBuf) const {
|
2014-06-28 04:20:57 +08:00
|
|
|
bool DidAllTestsPass = true;
|
|
|
|
unsigned NumRules = 0;
|
|
|
|
|
|
|
|
const char *LineStart = MemBuf->getBufferStart();
|
|
|
|
|
|
|
|
// Eat whitespace.
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
while (LineStart != MemBuf->getBufferEnd() && std::isspace(*LineStart))
|
2014-06-28 04:20:57 +08:00
|
|
|
++LineStart;
|
|
|
|
|
|
|
|
while (LineStart != MemBuf->getBufferEnd() && *LineStart != '\0') {
|
|
|
|
const char *LineEnd = LineStart;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
while (LineEnd != MemBuf->getBufferEnd() && *LineEnd != '\r' &&
|
|
|
|
*LineEnd != '\n')
|
2014-06-28 04:20:57 +08:00
|
|
|
++LineEnd;
|
|
|
|
|
|
|
|
StringRef Line(LineStart, LineEnd - LineStart);
|
|
|
|
if (Line.startswith(RulePrefix)) {
|
|
|
|
DidAllTestsPass &= check(Line.substr(RulePrefix.size()));
|
|
|
|
++NumRules;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Eat whitespace.
|
|
|
|
LineStart = LineEnd;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
while (LineStart != MemBuf->getBufferEnd() && std::isspace(*LineStart))
|
2014-06-28 04:20:57 +08:00
|
|
|
++LineStart;
|
|
|
|
}
|
|
|
|
return DidAllTestsPass && (NumRules != 0);
|
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
|
2015-10-18 09:41:37 +08:00
|
|
|
if (getRTDyld().getSymbol(Symbol))
|
2015-07-04 09:35:26 +08:00
|
|
|
return true;
|
|
|
|
return !!getRTDyld().Resolver.findSymbol(Symbol);
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
}
|
|
|
|
|
2015-03-11 08:43:26 +08:00
|
|
|
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return static_cast<uint64_t>(
|
2015-03-11 08:43:26 +08:00
|
|
|
reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
|
2015-03-11 08:43:26 +08:00
|
|
|
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
|
|
|
|
return InternalSymbol.getAddress();
|
[MCJIT][Orc] Refactor RTDyldMemoryManager, weave RuntimeDyld::SymbolInfo through
MCJIT.
This patch decouples the two responsibilities of the RTDyldMemoryManager class,
memory management and symbol resolution, into two new classes:
RuntimeDyld::MemoryManager and RuntimeDyld::SymbolResolver.
The symbol resolution interface is modified slightly, from:
uint64_t getSymbolAddress(const std::string &Name);
to:
RuntimeDyld::SymbolInfo findSymbol(const std::string &Name);
The latter passes symbol flags along with symbol addresses, allowing RuntimeDyld
and others to reason about non-strong/non-exported symbols.
The memory management interface removes the following method:
void notifyObjectLoaded(ExecutionEngine *EE,
const object::ObjectFile &) {}
as it is not related to memory management. (Note: Backwards compatibility *is*
maintained for this method in MCJIT and OrcMCJITReplacement, see below).
The RTDyldMemoryManager class remains in-tree for backwards compatibility.
It inherits directly from RuntimeDyld::SymbolResolver, and indirectly from
RuntimeDyld::MemoryManager via the new MCJITMemoryManager class, which
just subclasses RuntimeDyld::MemoryManager and reintroduces the
notifyObjectLoaded method for backwards compatibility).
The EngineBuilder class retains the existing method:
EngineBuilder&
setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager> mcjmm);
and includes two new methods:
EngineBuilder&
setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM);
EngineBuilder&
setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR);
Clients should use EITHER:
A single call to setMCJITMemoryManager with an RTDyldMemoryManager.
OR (exclusive)
One call each to each of setMemoryManager and setSymbolResolver.
This patch should be fully compatible with existing uses of RTDyldMemoryManager.
If it is not it should be considered a bug, and the patch either fixed or
reverted.
If clients find the new API to be an improvement the goal will be to deprecate
and eventually remove the RTDyldMemoryManager class in favor of the new classes.
llvm-svn: 233509
2015-03-30 11:37:06 +08:00
|
|
|
return getRTDyld().Resolver.findSymbol(Symbol).getAddress();
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
|
|
|
|
unsigned Size) const {
|
|
|
|
uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr);
|
|
|
|
assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
|
2014-08-28 01:41:06 +08:00
|
|
|
uint8_t *Src = reinterpret_cast<uint8_t*>(PtrSizedAddr);
|
2014-08-30 07:17:47 +08:00
|
|
|
return getRTDyld().readBytesUnaligned(Src, Size);
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
std::pair<const RuntimeDyldCheckerImpl::SectionAddressInfo*, std::string>
|
|
|
|
RuntimeDyldCheckerImpl::findSectionAddrInfo(StringRef FileName,
|
|
|
|
StringRef SectionName) const {
|
|
|
|
|
|
|
|
auto SectionMapItr = Stubs.find(FileName);
|
|
|
|
if (SectionMapItr == Stubs.end()) {
|
2014-07-23 07:07:52 +08:00
|
|
|
std::string ErrorMsg = "File '";
|
|
|
|
ErrorMsg += FileName;
|
|
|
|
ErrorMsg += "' not found. ";
|
|
|
|
if (Stubs.empty())
|
|
|
|
ErrorMsg += "No stubs registered.";
|
|
|
|
else {
|
|
|
|
ErrorMsg += "Available files are:";
|
|
|
|
for (const auto& StubEntry : Stubs) {
|
|
|
|
ErrorMsg += " '";
|
|
|
|
ErrorMsg += StubEntry.first;
|
|
|
|
ErrorMsg += "'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ErrorMsg += "\n";
|
2014-09-03 13:01:46 +08:00
|
|
|
return std::make_pair(nullptr, ErrorMsg);
|
2014-07-23 07:07:52 +08:00
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
auto SectionInfoItr = SectionMapItr->second.find(SectionName);
|
|
|
|
if (SectionInfoItr == SectionMapItr->second.end())
|
|
|
|
return std::make_pair(nullptr,
|
|
|
|
("Section '" + SectionName + "' not found in file '" +
|
|
|
|
FileName + "'\n").str());
|
|
|
|
|
|
|
|
return std::make_pair(&SectionInfoItr->second, std::string(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
|
|
|
|
StringRef FileName, StringRef SectionName, bool IsInsideLoad) const {
|
|
|
|
|
|
|
|
const SectionAddressInfo *SectionInfo = nullptr;
|
|
|
|
{
|
|
|
|
std::string ErrorMsg;
|
|
|
|
std::tie(SectionInfo, ErrorMsg) =
|
|
|
|
findSectionAddrInfo(FileName, SectionName);
|
|
|
|
if (ErrorMsg != "")
|
|
|
|
return std::make_pair(0, ErrorMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned SectionID = SectionInfo->SectionID;
|
|
|
|
uint64_t Addr;
|
|
|
|
if (IsInsideLoad)
|
2015-11-24 05:47:41 +08:00
|
|
|
Addr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(
|
|
|
|
getRTDyld().Sections[SectionID].getAddress()));
|
2014-09-03 13:01:46 +08:00
|
|
|
else
|
2015-11-24 05:47:41 +08:00
|
|
|
Addr = getRTDyld().Sections[SectionID].getLoadAddress();
|
2014-09-03 13:01:46 +08:00
|
|
|
|
|
|
|
return std::make_pair(Addr, std::string(""));
|
|
|
|
}
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
|
|
|
|
StringRef FileName, StringRef SectionName, StringRef SymbolName,
|
|
|
|
bool IsInsideLoad) const {
|
|
|
|
|
|
|
|
const SectionAddressInfo *SectionInfo = nullptr;
|
|
|
|
{
|
|
|
|
std::string ErrorMsg;
|
|
|
|
std::tie(SectionInfo, ErrorMsg) =
|
|
|
|
findSectionAddrInfo(FileName, SectionName);
|
|
|
|
if (ErrorMsg != "")
|
|
|
|
return std::make_pair(0, ErrorMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned SectionID = SectionInfo->SectionID;
|
|
|
|
const StubOffsetsMap &SymbolStubs = SectionInfo->StubOffsets;
|
|
|
|
auto StubOffsetItr = SymbolStubs.find(SymbolName);
|
|
|
|
if (StubOffsetItr == SymbolStubs.end())
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
return std::make_pair(0,
|
2014-09-12 07:09:22 +08:00
|
|
|
("Stub for symbol '" + SymbolName + "' not found. "
|
|
|
|
"If '" + SymbolName + "' is an internal symbol this "
|
|
|
|
"may indicate that the stub target offset is being "
|
|
|
|
"computed incorrectly.\n").str());
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
uint64_t StubOffset = StubOffsetItr->second;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
|
|
|
|
uint64_t Addr;
|
|
|
|
if (IsInsideLoad) {
|
2015-11-24 05:47:41 +08:00
|
|
|
uintptr_t SectionBase = reinterpret_cast<uintptr_t>(
|
|
|
|
getRTDyld().Sections[SectionID].getAddress());
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
Addr = static_cast<uint64_t>(SectionBase) + StubOffset;
|
2014-07-30 07:43:13 +08:00
|
|
|
} else {
|
2015-11-24 05:47:41 +08:00
|
|
|
uint64_t SectionBase = getRTDyld().Sections[SectionID].getLoadAddress();
|
2014-07-30 07:43:13 +08:00
|
|
|
Addr = SectionBase + StubOffset;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(Addr, std::string(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef
|
|
|
|
RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
|
2015-01-17 07:13:56 +08:00
|
|
|
RTDyldSymbolTable::const_iterator pos =
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
getRTDyld().GlobalSymbolTable.find(Name);
|
|
|
|
if (pos == getRTDyld().GlobalSymbolTable.end())
|
2014-06-28 04:20:57 +08:00
|
|
|
return StringRef();
|
2015-01-17 07:13:56 +08:00
|
|
|
const auto &SymInfo = pos->second;
|
|
|
|
uint8_t *SectionAddr = getRTDyld().getSectionAddress(SymInfo.getSectionID());
|
|
|
|
return StringRef(reinterpret_cast<const char *>(SectionAddr) +
|
2015-11-24 05:47:41 +08:00
|
|
|
SymInfo.getOffset(),
|
|
|
|
getRTDyld().Sections[SymInfo.getSectionID()].getSize() -
|
|
|
|
SymInfo.getOffset());
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
}
|
|
|
|
|
2014-09-03 13:01:46 +08:00
|
|
|
void RuntimeDyldCheckerImpl::registerSection(
|
|
|
|
StringRef FilePath, unsigned SectionID) {
|
|
|
|
StringRef FileName = sys::path::filename(FilePath);
|
|
|
|
const SectionEntry &Section = getRTDyld().Sections[SectionID];
|
2015-11-24 05:47:41 +08:00
|
|
|
StringRef SectionName = Section.getName();
|
2014-09-03 13:01:46 +08:00
|
|
|
|
|
|
|
Stubs[FileName][SectionName].SectionID = SectionID;
|
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
void RuntimeDyldCheckerImpl::registerStubMap(
|
2014-07-30 04:40:37 +08:00
|
|
|
StringRef FilePath, unsigned SectionID,
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
const RuntimeDyldImpl::StubMap &RTDyldStubs) {
|
2014-07-30 04:40:37 +08:00
|
|
|
StringRef FileName = sys::path::filename(FilePath);
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
const SectionEntry &Section = getRTDyld().Sections[SectionID];
|
2015-11-24 05:47:41 +08:00
|
|
|
StringRef SectionName = Section.getName();
|
2014-09-03 13:01:46 +08:00
|
|
|
|
|
|
|
Stubs[FileName][SectionName].SectionID = SectionID;
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
for (auto &StubMapEntry : RTDyldStubs) {
|
|
|
|
std::string SymbolName = "";
|
|
|
|
|
|
|
|
if (StubMapEntry.first.SymbolName)
|
|
|
|
SymbolName = StubMapEntry.first.SymbolName;
|
|
|
|
else {
|
|
|
|
// If this is a (Section, Offset) pair, do a reverse lookup in the
|
|
|
|
// global symbol table to find the name.
|
|
|
|
for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
|
2015-01-17 07:13:56 +08:00
|
|
|
const auto &SymInfo = GSTEntry.second;
|
|
|
|
if (SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
|
|
|
|
SymInfo.getOffset() ==
|
|
|
|
static_cast<uint64_t>(StubMapEntry.first.Offset)) {
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
SymbolName = GSTEntry.first();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SymbolName != "")
|
2014-09-03 13:01:46 +08:00
|
|
|
Stubs[FileName][SectionName].StubOffsets[SymbolName] =
|
|
|
|
StubMapEntry.second;
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RuntimeDyldChecker::RuntimeDyldChecker(RuntimeDyld &RTDyld,
|
|
|
|
MCDisassembler *Disassembler,
|
|
|
|
MCInstPrinter *InstPrinter,
|
|
|
|
raw_ostream &ErrStream)
|
|
|
|
: Impl(make_unique<RuntimeDyldCheckerImpl>(RTDyld, Disassembler,
|
|
|
|
InstPrinter, ErrStream)) {}
|
|
|
|
|
|
|
|
RuntimeDyldChecker::~RuntimeDyldChecker() {}
|
|
|
|
|
2014-09-04 12:19:54 +08:00
|
|
|
RuntimeDyld& RuntimeDyldChecker::getRTDyld() {
|
|
|
|
return Impl->RTDyld;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RuntimeDyld& RuntimeDyldChecker::getRTDyld() const {
|
|
|
|
return Impl->RTDyld;
|
|
|
|
}
|
|
|
|
|
[MCJIT] Refactor and add stub inspection to the RuntimeDyldChecker framework.
This patch introduces a 'stub_addr' builtin that can be used to find the address
of the stub for a given (<file>, <section>, <symbol>) tuple. This address can be
used both to verify the contents of stubs (by loading from the returned address)
and to verify references to stubs (by comparing against the returned address).
Example (1) - Verifying stub contents:
Load 8 bytes (assuming a 64-bit target) from the stub for 'x' in the __text
section of f.o, and compare that value against the addres of 'x'.
# rtdyld-check: *{8}(stub_addr(f.o, __text, x) = x
Example (2) - Verifying references to stubs:
Decode the immediate of the instruction at label 'l', and verify that it's
equal to the offset from the next instruction's PC to the stub for 'y' in the
__text section of f.o (i.e. it's the correct PC-rel difference).
# rtdyld-check: decode_operand(l, 4) = stub_addr(f.o, __text, y) - next_pc(l)
l:
movq y@GOTPCREL(%rip), %rax
Since stub inspection requires cooperation with RuntimeDyldImpl this patch
pimpl-ifies RuntimeDyldChecker. Its implementation is moved in to a new class,
RuntimeDyldCheckerImpl, that has access to the definition of RuntimeDyldImpl.
llvm-svn: 213698
2014-07-23 06:47:39 +08:00
|
|
|
bool RuntimeDyldChecker::check(StringRef CheckExpr) const {
|
|
|
|
return Impl->check(CheckExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
|
|
|
|
MemoryBuffer *MemBuf) const {
|
|
|
|
return Impl->checkAllRulesInBuffer(RulePrefix, MemBuf);
|
2014-06-28 04:20:57 +08:00
|
|
|
}
|
2014-09-04 12:19:54 +08:00
|
|
|
|
|
|
|
std::pair<uint64_t, std::string>
|
|
|
|
RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
|
2015-03-11 08:43:26 +08:00
|
|
|
bool LocalAddress) {
|
|
|
|
return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
|
2014-09-04 12:19:54 +08:00
|
|
|
}
|