mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
e759a41442
Currently llvm-rtdyld in -check mode will map sections to back-to-back 4k aligned slabs starting at 0x1000. Automatically remapping sections by default is helpful because it quickly exposes relocation bugs due to use of local addresses rather than load addresses (these would silently pass if the load address was not remapped). These mappings can be explicitly overridden on a per-section basis using llvm-rtdlyd's -map-section option. This patch extends this scheme to also preserve any mappings made by RuntimeDyld itself. Preserving RuntimeDyld's automatic mappings allows us to write test cases to verify that these automatic mappings have been applied. This will allow the fix in https://reviews.llvm.org/D32899 to be tested with llvm-rtdyld -check. llvm-svn: 302372
113 lines
3.7 KiB
C++
113 lines
3.7 KiB
C++
//===---- RuntimeDyldChecker.h - 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
|
|
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
|
|
|
|
#include "llvm/ADT/Optional.h"
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
namespace llvm {
|
|
|
|
class StringRef;
|
|
class MCDisassembler;
|
|
class MemoryBuffer;
|
|
class MCInstPrinter;
|
|
class RuntimeDyld;
|
|
class RuntimeDyldCheckerImpl;
|
|
class raw_ostream;
|
|
|
|
/// \brief RuntimeDyld invariant checker for verifying that RuntimeDyld has
|
|
/// correctly applied relocations.
|
|
///
|
|
/// The RuntimeDyldChecker class evaluates expressions against an attached
|
|
/// RuntimeDyld instance to verify that relocations have been applied
|
|
/// correctly.
|
|
///
|
|
/// The expression language supports basic pointer arithmetic and bit-masking,
|
|
/// and has limited disassembler integration for accessing instruction
|
|
/// operands and the next PC (program counter) address for each instruction.
|
|
///
|
|
/// The language syntax is:
|
|
///
|
|
/// check = expr '=' expr
|
|
///
|
|
/// expr = binary_expr
|
|
/// | sliceable_expr
|
|
///
|
|
/// sliceable_expr = '*{' number '}' load_addr_expr [slice]
|
|
/// | '(' expr ')' [slice]
|
|
/// | ident_expr [slice]
|
|
/// | number [slice]
|
|
///
|
|
/// slice = '[' high-bit-index ':' low-bit-index ']'
|
|
///
|
|
/// load_addr_expr = symbol
|
|
/// | '(' symbol '+' number ')'
|
|
/// | '(' symbol '-' number ')'
|
|
///
|
|
/// ident_expr = 'decode_operand' '(' symbol ',' operand-index ')'
|
|
/// | 'next_pc' '(' symbol ')'
|
|
/// | 'stub_addr' '(' file-name ',' section-name ',' symbol ')'
|
|
/// | symbol
|
|
///
|
|
/// binary_expr = expr '+' expr
|
|
/// | expr '-' expr
|
|
/// | expr '&' expr
|
|
/// | expr '|' expr
|
|
/// | expr '<<' expr
|
|
/// | expr '>>' expr
|
|
///
|
|
class RuntimeDyldChecker {
|
|
public:
|
|
RuntimeDyldChecker(RuntimeDyld &RTDyld, MCDisassembler *Disassembler,
|
|
MCInstPrinter *InstPrinter, raw_ostream &ErrStream);
|
|
~RuntimeDyldChecker();
|
|
|
|
// \brief Get the associated RTDyld instance.
|
|
RuntimeDyld& getRTDyld();
|
|
|
|
// \brief Get the associated RTDyld instance.
|
|
const RuntimeDyld& getRTDyld() const;
|
|
|
|
/// \brief Check a single expression against the attached RuntimeDyld
|
|
/// instance.
|
|
bool check(StringRef CheckExpr) const;
|
|
|
|
/// \brief Scan the given memory buffer for lines beginning with the string
|
|
/// in RulePrefix. The remainder of the line is passed to the check
|
|
/// method to be evaluated as an expression.
|
|
bool checkAllRulesInBuffer(StringRef RulePrefix, MemoryBuffer *MemBuf) const;
|
|
|
|
/// \brief Returns the address of the requested section (or an error message
|
|
/// in the second element of the pair if the address cannot be found).
|
|
///
|
|
/// if 'LocalAddress' is true, this returns the address of the section
|
|
/// within the linker's memory. If 'LocalAddress' is false it returns the
|
|
/// address within the target process (i.e. the load address).
|
|
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
|
|
StringRef SectionName,
|
|
bool LocalAddress);
|
|
|
|
/// \brief If there is a section at the given local address, return its load
|
|
/// address, otherwise return none.
|
|
Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
|
|
|
|
private:
|
|
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|