Files
revng-revng/include/revng/BasicAnalyses/MaterializedValue.h
T
Alessandro Di Federico d10178483d Introduce the new MetaAddress
Unlike the previous iteration of `MetaAddress`, which tried to stuff all
the parts of `MetaAddress` within the existing `PC` CSV, this
implementation adds a set of new CSVs (or marks some existing ones as) to
represent the four portions of the current PC's `MetaAddress`.

* Introduce `ProgramCounterHandler`: a class responsible to maintain the
  PC-related CSVs. This class is also used to manipulate the new
  dispatcher.
* `AdvancedValueInfo`: update for new MetaAddress.
* External jump handler: do not clobber registers.
  When introducing support for dynamic binaries, we didn't realize that
  in x86-64 we were clobbering `r11`. To avoid this, we have to jump to
  an address stored in memory. However, due to the new `MetaAddress`,
  obtaining a *jumpable* address from the PC-related CSVs might require
  some computations (and it does in ARM). Therefore, we introduce a new
  global variable, `jumpablepc`, whose only role is to contain the
  jumpable version of the program counter and then be the target of the
  memory-indirect jump instruction.
* Labels care only about absolute addresses.
* CSAA: mark call site, even if no accesses.
2020-06-02 10:57:02 +02:00

83 lines
2.1 KiB
C++

#ifndef REVNG_MATERIALIZEDVALUE_H
#define REVNG_MATERIALIZEDVALUE_H
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// Standard includes
#include <set>
// LLVM includes
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
// Local libraries includes
#include "revng/Support/Debug.h"
/// \brief Class representing either a constant value or an offset from a symbol
class MaterializedValue {
private:
bool IsValid;
llvm::Optional<llvm::StringRef> SymbolName;
llvm::APInt Value;
public:
MaterializedValue() : IsValid(false), Value() {}
MaterializedValue(const llvm::APInt &Value) : IsValid(true), Value(Value) {}
MaterializedValue(llvm::StringRef Name, const llvm::APInt &Offset) :
IsValid(true), SymbolName(Name), Value(Offset) {}
public:
static MaterializedValue invalid() { return MaterializedValue(); }
public:
bool operator==(const MaterializedValue &Other) const {
auto This = std::tie(IsValid, SymbolName, Value);
auto That = std::tie(Other.IsValid, Other.SymbolName, Other.Value);
return This == That;
}
bool operator<(const MaterializedValue &Other) const {
if (Value.ult(Other.Value))
return true;
auto This = std::tie(IsValid, SymbolName);
auto That = std::tie(Other.IsValid, Other.SymbolName);
return This < That;
}
const llvm::APInt &value() const {
revng_assert(isValid());
return Value;
}
bool isValid() const { return IsValid; }
bool hasSymbol() const { return SymbolName.hasValue(); }
llvm::StringRef symbolName() const {
revng_assert(isValid());
revng_assert(hasSymbol());
return *SymbolName;
}
void dump() const debug_function { dump(dbg); }
template<typename T>
void dump(T &Output) const {
if (not isValid()) {
Output << "(invalid)";
} else {
if (hasSymbol())
Output << symbolName().data() << "+";
llvm::SmallString<40> String;
value().toStringUnsigned(String, 16);
Output << "0x" << String.c_str();
}
}
};
using MaterializedValues = std::vector<MaterializedValue>;
#endif // REVNG_MATERIALIZEDVALUE_H