Pass PlainMetaAddress by pointer

This commit is contained in:
Alessandro Di Federico
2023-12-06 18:21:45 +01:00
parent 7d4eefcecc
commit 0c1b5ac569
10 changed files with 100 additions and 94 deletions
+4 -4
View File
@@ -39,10 +39,10 @@ provide a quick summary of the required functions as they are implemented in
possible to catch attempts to open ``/proc/self/map`` and redirect it
somewhere else transparently.
:unknownPC: Function handling the situation in which the code at an address that
should be executed has not been translated (see
`GeneratedIRReference.rst`_). It is basically an error handling
function that is supposed to never return.
:unknown_pc: Function handling the situation in which the code at an address that
should be executed has not been translated (see
`GeneratedIRReference.rst`_). It is basically an error handling
function that is supposed to never return.
:newpc: As seen in `GeneratedIRReference.rst`_, each input instruction is
delimited by a call to a ``newpc`` function. This function is not just a
+2 -2
View File
@@ -294,7 +294,7 @@ program to the first basic block containing the code generated due to A.
counter might be actually invalid or it could belong
to a function in a dynamic library. In this case, we
simply leave the translated realm and jump there.
:``dispatcher.default``: calls the ``unknownPC`` function, whose definition is
:``dispatcher.default``: calls the ``unknown_pc`` function, whose definition is
left to the user. The default implementation in
``support.c`` aborts the program execution.
:``anypc``: handles the situation in which we were not able to fully enumerate
@@ -342,7 +342,7 @@ Here's how it looks like in our example:
br i1 %46, label %dispatcher.default, label %setjmp
dispatcher.default: ; preds = %dispatcher.entry
call void @unknownPC()
call void @unknown_pc()
unreachable
anypc: ; preds = %entrypoint
+5 -5
View File
@@ -14,8 +14,8 @@ typedef struct {
} PlainMetaAddress;
// NOLINTNEXTLINE
PlainMetaAddress build_PlainMetaAddress(uint32_t Epoch,
uint16_t AddressSpace,
uint16_t Type,
uint64_t Address)
__attribute__((const));
void set_PlainMetaAddress(PlainMetaAddress *This,
uint32_t Epoch,
uint16_t AddressSpace,
uint16_t Type,
uint64_t Address);
+11 -13
View File
@@ -55,10 +55,10 @@ protected:
protected:
unsigned Alignment;
llvm::GlobalVariable *AddressCSV;
llvm::GlobalVariable *EpochCSV;
llvm::GlobalVariable *AddressSpaceCSV;
llvm::GlobalVariable *TypeCSV;
llvm::GlobalVariable *AddressCSV = nullptr;
llvm::GlobalVariable *EpochCSV = nullptr;
llvm::GlobalVariable *AddressSpaceCSV = nullptr;
llvm::GlobalVariable *TypeCSV = nullptr;
std::set<llvm::GlobalVariable *> CSVsAffectingPC;
@@ -67,12 +67,7 @@ public:
using DispatcherTargets = std::vector<DispatcherTarget>;
protected:
ProgramCounterHandler(unsigned Alignment) :
Alignment(Alignment),
AddressCSV(nullptr),
EpochCSV(nullptr),
AddressSpaceCSV(nullptr),
TypeCSV(nullptr) {}
ProgramCounterHandler(unsigned Alignment) : Alignment(Alignment) {}
public:
virtual ~ProgramCounterHandler() {}
@@ -124,9 +119,12 @@ public:
setPC(Builder, Address);
}
llvm::Value *buildCurrentPCPlainMetaAddress(llvm::IRBuilder<> &Builder) const;
llvm::Value *buildPlainMetaAddress(llvm::IRBuilder<> &Builder,
const MetaAddress &Address) const;
void setCurrentPCPlainMetaAddress(llvm::IRBuilder<> &Builder) const;
void setLastPCPlainMetaAddress(llvm::IRBuilder<> &Builder,
const MetaAddress &Address) const;
void setPlainMetaAddress(llvm::IRBuilder<> &Builder,
llvm::StringRef GlobalName,
const MetaAddress &Address) const;
protected:
virtual void initializePCInternal(llvm::IRBuilder<> &Builder,
+2 -5
View File
@@ -234,11 +234,8 @@ void IFI::emitCall(IRBuilder<> &Builder,
auto *PCH = GCBI.programCounterHandler();
auto AddArguments = [&Arguments, &Builder](llvm::Value *V) {
llvm::copy(unpack(Builder, V), std::back_inserter(Arguments));
};
AddArguments(PCH->buildPlainMetaAddress(Builder, SourcePC));
AddArguments(PCH->buildCurrentPCPlainMetaAddress(Builder));
PCH->setLastPCPlainMetaAddress(Builder, SourcePC);
PCH->setCurrentPCPlainMetaAddress(Builder);
auto *NewCall = Builder.CreateCall(Callee, Arguments);
NewCall->setDebugLoc(DbgLocation);
+5 -4
View File
@@ -965,15 +965,16 @@ void JumpTargetManager::prepareDispatcher() {
TheFunction);
Builder.SetInsertPoint(DispatcherFail);
FunctionCallee UnknownPC = TheModule.getFunction("unknownPC");
FunctionCallee UnknownPC = TheModule.getFunction("unknown_pc");
{
auto *UnknownPCFunction = cast<Function>(skipCasts(UnknownPC.getCallee()));
FunctionTags::Exceptional.addTo(UnknownPCFunction);
}
Builder.CreateCall(UnknownPC,
unpack(Builder,
PCH->buildCurrentPCPlainMetaAddress(Builder)));
PCH->setCurrentPCPlainMetaAddress(Builder);
Builder.CreateCall(UnknownPC);
auto *FailUnreachable = Builder.CreateUnreachable();
setBlockType(FailUnreachable, BlockType::DispatcherFailureBlock);
+41 -27
View File
@@ -7,6 +7,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/ModRef.h"
#include "revng/Support/Assert.h"
#include "revng/Support/ProgramCounterHandler.h"
using namespace llvm;
@@ -360,49 +361,62 @@ bool PCH::isPCAffectingHelper(Instruction *I) const {
return false;
}
static llvm::Value *buildPlainMetaAddressImpl(llvm::IRBuilder<> &Builder,
Value *Epoch,
Value *AddressSpace,
Value *Type,
Value *Address) {
static void setPlainMetaAddressImpl(IRBuilder<> &Builder,
StringRef GlobalName,
Value *Epoch,
Value *AddressSpace,
Value *Type,
Value *Address) {
using namespace llvm;
BasicBlock *BB = Builder.GetInsertBlock();
Module *M = BB->getParent()->getParent();
Function *MetaAddressConstuctor = M->getFunction("build_PlainMetaAddress");
MetaAddressConstuctor->setMemoryEffects(MemoryEffects::none());
GlobalVariable *Global = M->getGlobalVariable(GlobalName);
revng_assert(Global != nullptr);
Function *MetaAddressConstuctor = M->getFunction("set_PlainMetaAddress");
auto WriteArguments = MemoryEffects::argMemOnly(ModRefInfo::Mod);
MetaAddressConstuctor->setMemoryEffects(WriteArguments);
MetaAddressConstuctor->addFnAttr(Attribute::WillReturn);
MetaAddressConstuctor->addFnAttr(Attribute::NoUnwind);
auto *FT = MetaAddressConstuctor->getFunctionType();
return Builder
.CreateCall(MetaAddressConstuctor,
{ Builder.CreateZExt(Epoch, FT->getParamType(0)),
Builder.CreateZExt(AddressSpace, FT->getParamType(1)),
Builder.CreateZExt(Type, FT->getParamType(2)),
Builder.CreateZExt(Address, FT->getParamType(3)) });
Builder.CreateCall(MetaAddressConstuctor,
{ Global,
Builder.CreateZExt(Epoch, FT->getParamType(1)),
Builder.CreateZExt(AddressSpace, FT->getParamType(2)),
Builder.CreateZExt(Type, FT->getParamType(3)),
Builder.CreateZExt(Address, FT->getParamType(4)) });
}
Value *PCH::buildCurrentPCPlainMetaAddress(IRBuilder<> &Builder) const {
return buildPlainMetaAddressImpl(Builder,
createLoad(Builder, EpochCSV),
createLoad(Builder, AddressSpaceCSV),
createLoad(Builder, TypeCSV),
createLoad(Builder, AddressCSV));
void PCH::setCurrentPCPlainMetaAddress(IRBuilder<> &Builder) const {
setPlainMetaAddressImpl(Builder,
"current_pc",
createLoad(Builder, EpochCSV),
createLoad(Builder, AddressSpaceCSV),
createLoad(Builder, TypeCSV),
createLoad(Builder, AddressCSV));
}
llvm::Value *
ProgramCounterHandler::buildPlainMetaAddress(llvm::IRBuilder<> &Builder,
const MetaAddress &Address) const {
void PCH::setLastPCPlainMetaAddress(IRBuilder<> &Builder,
const MetaAddress &Address) const {
setPlainMetaAddress(Builder, "last_pc", Address);
}
void ProgramCounterHandler::setPlainMetaAddress(llvm::IRBuilder<> &Builder,
StringRef GlobalName,
const MetaAddress &Address)
const {
auto CI = [](llvm::GlobalVariable *Example, uint64_t Value) -> ConstantInt * {
auto *Type = Example->getValueType();
return ConstantInt::get(cast<IntegerType>(Type), Value);
};
return buildPlainMetaAddressImpl(Builder,
CI(EpochCSV, Address.Epoch),
CI(AddressSpaceCSV, Address.AddressSpace),
CI(TypeCSV, Address.Type),
CI(AddressCSV, Address.Address));
setPlainMetaAddressImpl(Builder,
GlobalName,
CI(EpochCSV, Address.Epoch),
CI(AddressSpaceCSV, Address.AddressSpace),
CI(TypeCSV, Address.Type),
CI(AddressCSV, Address.Address));
}
std::pair<NextJumpTarget::Values, MetaAddress>
+13 -11
View File
@@ -8,24 +8,26 @@
#include "support.h"
PlainMetaAddress last_pc;
PlainMetaAddress current_pc;
// The only purpose of this function is keeping alive the references to some
// symbols that are needed by revng
intptr_t ignore(void);
intptr_t ignore(void) {
return (intptr_t) &saved_registers + (intptr_t) &setjmp
+ (intptr_t) &jmp_buffer + (intptr_t) &is_executable
+ (intptr_t) &unknownPC + (intptr_t) &_abort
+ (intptr_t) &unknown_pc + (intptr_t) &_abort
+ (intptr_t) &_unreachable;
}
PlainMetaAddress build_PlainMetaAddress(uint32_t Epoch,
uint16_t AddressSpace,
uint16_t Type,
uint64_t Address) {
PlainMetaAddress Result;
Result.Epoch = Epoch;
Result.AddressSpace = AddressSpace;
Result.Type = Type;
Result.Address = Address;
return Result;
void set_PlainMetaAddress(PlainMetaAddress *This,
uint32_t Epoch,
uint16_t AddressSpace,
uint16_t Type,
uint64_t Address) {
This->Epoch = Epoch;
This->AddressSpace = AddressSpace;
This->Type = Type;
This->Address = Address;
}
+11 -16
View File
@@ -252,10 +252,10 @@ void g_assertion_message_expr(const char *domain,
const char *expr) {
}
void unknownPC(PlainMetaAddress PC) {
void unknown_pc() {
int arg;
fprintf(stderr, "Unknown PC:");
fprint_metaaddress(stderr, &PC);
fprint_metaaddress(stderr, &current_pc);
fprintf(stderr, "\n");
for (arg = 0; arg < saved_argc; arg++) {
@@ -268,8 +268,7 @@ void unknownPC(PlainMetaAddress PC) {
}
void jump_to_symbol(char *Symbol) {
PlainMetaAddress Empty = { 0 };
_abort(Symbol, Empty, Empty);
_abort(Symbol);
}
#ifdef TRACE
@@ -467,14 +466,14 @@ int main(int argc, char *argv[]) {
}
static noreturn void fail(const char *reason,
PlainMetaAddress source,
PlainMetaAddress destination) {
PlainMetaAddress *source,
PlainMetaAddress *destination) {
// Dump information about the exception
fprintf(stderr, "Exception: %s", reason);
fprintf(stderr, " (");
fprint_metaaddress(stderr, &source);
fprint_metaaddress(stderr, source);
fprintf(stderr, " -> ");
fprint_metaaddress(stderr, &destination);
fprint_metaaddress(stderr, destination);
fprintf(stderr, ")\n");
// Declare the exception object
@@ -486,14 +485,10 @@ static noreturn void fail(const char *reason,
abort();
}
noreturn void _abort(const char *reason,
PlainMetaAddress source,
PlainMetaAddress destination) {
fail(reason, source, destination);
noreturn void _abort(const char *reason) {
fail(reason, &last_pc, &current_pc);
}
noreturn void _unreachable(const char *reason,
PlainMetaAddress source,
PlainMetaAddress destination) {
fail(reason, source, destination);
noreturn void _unreachable(const char *reason) {
fail(reason, &last_pc, &current_pc);
}
+6 -7
View File
@@ -93,6 +93,9 @@ typedef uint64_t target_reg;
#endif
extern PlainMetaAddress last_pc;
extern PlainMetaAddress current_pc;
// Register values before the signal was triggered
extern target_reg *saved_registers;
@@ -109,12 +112,8 @@ extern jmp_buf jmp_buffer;
bool is_executable(uint64_t pc);
void set_register(uint32_t register_id, uint64_t value);
void unknownPC(PlainMetaAddress PC);
void unknown_pc();
noreturn void _abort(const char *reason,
PlainMetaAddress source,
PlainMetaAddress destination);
noreturn void _abort(const char *reason);
noreturn void _unreachable(const char *reason,
PlainMetaAddress source,
PlainMetaAddress destination);
noreturn void _unreachable(const char *reason);