mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
e21eed118c
This commit uses SET, information about canonical values and labels to detect if an indirect function call is targeting an external symbol. The strings used for the name of external symbols are uniqued global variables. This commit also uses this approach for the disassembly of original instructions, which used to be metadata.
71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
/// \file IRHelpers.cpp
|
|
/// \brief Implementation of IR helper functions
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
// Standard includes
|
|
#include <fstream>
|
|
|
|
// LLVM includes
|
|
#include "llvm/Support/raw_os_ostream.h"
|
|
|
|
// Local libraries includes
|
|
#include "revng/Support/IRHelpers.h"
|
|
|
|
using namespace llvm;
|
|
|
|
void dumpModule(const Module *M, const char *Path) {
|
|
std::ofstream FileStream(Path);
|
|
raw_os_ostream Stream(FileStream);
|
|
M->print(Stream, nullptr, true);
|
|
}
|
|
|
|
GlobalVariable *buildString(Module *M, StringRef String, const Twine &Name) {
|
|
LLVMContext &C = M->getContext();
|
|
auto *Initializer = ConstantDataArray::getString(C, String, true);
|
|
return new GlobalVariable(*M,
|
|
Initializer->getType(),
|
|
true,
|
|
GlobalVariable::InternalLinkage,
|
|
Initializer,
|
|
Name);
|
|
}
|
|
|
|
Constant *buildStringPtr(Module *M, StringRef String, const Twine &Name) {
|
|
LLVMContext &C = M->getContext();
|
|
Type *Int8PtrTy = Type::getInt8Ty(C)->getPointerTo();
|
|
GlobalVariable *NewVariable = buildString(M, String, Name);
|
|
return ConstantExpr::getBitCast(NewVariable, Int8PtrTy);
|
|
}
|
|
|
|
Constant *getUniqueString(Module *M,
|
|
StringRef Namespace,
|
|
StringRef String,
|
|
const Twine &Name) {
|
|
LLVMContext &C = M->getContext();
|
|
Type *Int8PtrTy = Type::getInt8Ty(C)->getPointerTo();
|
|
NamedMDNode *StringsList = M->getOrInsertNamedMetadata(Namespace);
|
|
|
|
for (MDNode *Operand : StringsList->operands()) {
|
|
auto *T = cast<MDTuple>(Operand);
|
|
revng_assert(T->getNumOperands() == 1);
|
|
auto *CAM = cast<ConstantAsMetadata>(T->getOperand(0).get());
|
|
auto *GV = cast<GlobalVariable>(CAM->getValue());
|
|
revng_assert(GV->isConstant() and GV->hasInitializer());
|
|
|
|
const Constant *Initializer = GV->getInitializer();
|
|
StringRef Content = cast<ConstantDataArray>(Initializer)->getAsString();
|
|
|
|
// Ignore the terminator
|
|
if (Content.drop_back() == String)
|
|
return ConstantExpr::getBitCast(GV, Int8PtrTy);
|
|
}
|
|
|
|
GlobalVariable *NewVariable = buildString(M, String, Name);
|
|
auto *CAM = ConstantAsMetadata::get(NewVariable);
|
|
StringsList->addOperand(MDTuple::get(C, { CAM }));
|
|
return ConstantExpr::getBitCast(NewVariable, Int8PtrTy);
|
|
}
|