Skip to content

Commit

Permalink
[snippy] Resolve symlinks when loading plugins via dlopen
Browse files Browse the repository at this point in the history
Update RISCVModel to API version 24.
  • Loading branch information
sizn-sc authored and asi-sc committed Feb 18, 2025
1 parent 5bfc0a7 commit 921d134
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
14 changes: 7 additions & 7 deletions llvm/tools/llvm-snippy/Model/RISCVModel/RVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern "C" {

#define RVMAPI_ENTRY_POINT_SYMBOL RVMVTable
#define RVMAPI_VERSION_SYMBOL RVMInterfaceVersion
#define RVMAPI_CURRENT_INTERFACE_VERSION 22u
#define RVMAPI_CURRENT_INTERFACE_VERSION 24u

typedef uint64_t RVMRegT;

Expand Down Expand Up @@ -152,7 +152,7 @@ typedef enum {
} RVMXExt;
#undef RVM_DEFINE_ENUM_CASE

typedef struct RVMExtDescriptior {
typedef struct RVMExtDescriptor {
size_t ZExtSize; // Set this to sizeof(ZExt)
size_t XExtSize; // Set this to sizeof(XExt)
char ZExt[RVM_ZEXT_NUMBER];
Expand All @@ -171,7 +171,7 @@ typedef struct RVMConfig RVMConfig;
typedef enum { NON_STOP = 0, STOP_BY_PC } RVMStopMode;

typedef enum {
// Simulator stepped successully, no additional event happened.
// Simulator stepped successfully, no additional event happened.
MODEL_SUCCESS,
// Simulator got ebreak or instruction with "StopPC".
MODEL_FINISH,
Expand Down Expand Up @@ -345,9 +345,9 @@ int rvm_readVReg(const RVMState *State, RVMVReg Reg, char *Data,
int rvm_setVReg(RVMState *State, RVMVReg Reg, const char *Data,
size_t DataSize);

void rvm_logMessage(const char *Message);
void rvm_logMessage(const RVMState *State, const char *Message);

int rvm_queryCallbackSupportPresent(void);
int rvm_queryCallbackSupportPresent(const RVMState *State);

typedef void (*MemUpdateCallbackTy)(RVMCallbackHandler *, uint64_t Addr,
const char *Data, size_t Size);
Expand Down Expand Up @@ -404,8 +404,8 @@ typedef RVMRegT (*rvm_readCSRReg_t)(const RVMState *, unsigned);
typedef void (*rvm_setCSRReg_t)(RVMState *, unsigned, RVMRegT);
typedef int (*rvm_readVReg_t)(const RVMState *, RVMVReg, char *, size_t);
typedef int (*rvm_setVReg_t)(RVMState *, RVMVReg, const char *, size_t);
typedef void (*rvm_logMessage_t)(const char *);
typedef int (*rvm_queryCallbackSupportPresent_t)(void);
typedef void (*rvm_logMessage_t)(const RVMState *, const char *);
typedef int (*rvm_queryCallbackSupportPresent_t)(const RVMState *);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-snippy/Model/RISCVModel/RVM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ class State {
}

void logMessage(const char *Message) const {
return getVTable()->logMessage(Message);
return getVTable()->logMessage(get(), Message);
}
};

Expand Down
3 changes: 2 additions & 1 deletion llvm/tools/llvm-snippy/lib/Simulator/RISCVSimulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ class SnippyRISCVSimulator final
}

bool supportsCallbacks() const override {
return ModelState.getVTable()->queryCallbackSupportPresent();
return ModelState.getVTable()->queryCallbackSupportPresent(
ModelState.get());
}
};

Expand Down
27 changes: 26 additions & 1 deletion llvm/tools/llvm-snippy/lib/Support/DynLibLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FormatVariadic.h"

#include <filesystem>

#include <dlfcn.h>

namespace llvm {
Expand All @@ -20,7 +22,30 @@ namespace snippy {
namespace {

void *getPermanentLibrary(const char *Filename, std::string *errMsg = nullptr) {
void *Handle = ::dlopen(Filename, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND);
// Canonicalize path before loading the plugin. This has the effect of
// resolving any symlinks, such that RUNPATH that refers to $ORIGIN is
// relative to the shared object location and NOT relative to the location of
// the symlink.
//
// For example: if llvm-snippy binary is located at
// path/to/package/llvm-snippy, and a symlink to plugin is placed in the same
// directory: path/to/package/plugin.so pointing to the plugin DSO located in
// a subdirectory path/to/package/subdir/plugin.so.SONAME.
// Suppose this plugin has to have RUNPATH set to $ORIGIN to resolve its
// dynamic library dependencies. Then when calling
// ::dlopen(path/to/package/plugin.so) the plugin.so.SONAME DSO will have its
// RUNPATH set to path/to/package and not to path/to/package/subdir as one
// would expect if the linker were to locate the shared object.

auto Path = std::filesystem::path(Filename);
auto EC = std::error_code{};
auto Canonical = canonical(Path, EC);

if (EC)
snippy::fatal(createStringError(EC, Path.c_str()));

void *Handle =
::dlopen(Canonical.c_str(), RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND);
if (!Handle) {
if (errMsg)
*errMsg = ::dlerror();
Expand Down

0 comments on commit 921d134

Please sign in to comment.