Added patchcompile module handling
This commit is contained in:
parent
447431ae45
commit
30be283e15
@ -48,12 +48,15 @@ static bool global_target_cmp(const TARGET& a, const TARGET& b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::size_t accumulate_global_target(TARGET&& target) {
|
||||
static std::size_t accumulate_global_target(TARGET&& target, bool& was_new) {
|
||||
was_new = false;
|
||||
for (const auto& [guid, gtarget] : targets) {
|
||||
if (global_target_cmp(gtarget, target))
|
||||
return guid;
|
||||
}
|
||||
|
||||
was_new = true;
|
||||
|
||||
std::size_t guid = next_global_target_uid++;
|
||||
targets.emplace(guid, std::move(target));
|
||||
return guid;
|
||||
@ -75,7 +78,7 @@ dpin <symbol> <offset> <level> <target uid>
|
||||
dpin <symbol> <offset> <level> <target uid>
|
||||
...
|
||||
*/
|
||||
static bool accumulate_file(const fs::path& path) {
|
||||
static bool accumulate_file(const fs::path& path, bool no_new_targets) {
|
||||
std::ifstream infile(path);
|
||||
if (!infile)
|
||||
return false;
|
||||
@ -169,7 +172,14 @@ static bool accumulate_file(const fs::path& path) {
|
||||
fit++;
|
||||
}
|
||||
|
||||
std::size_t global_target_uid = accumulate_global_target(std::move(target));
|
||||
bool was_new = false;
|
||||
std::size_t global_target_uid = accumulate_global_target(std::move(target), was_new);
|
||||
|
||||
if (no_new_targets && was_new) {
|
||||
std::cerr << "Encountered new target but --no-new-targets is set!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
cu.local_targets.emplace(local_uid, global_target_uid);
|
||||
continue;
|
||||
} else if (type == "ipin") {
|
||||
@ -223,7 +233,7 @@ static bool accumulate_file(const fs::path& path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool accumulate(const std::vector<std::string>& spslr_files) {
|
||||
bool accumulate(const std::vector<std::string>& spslr_files, bool no_new_targets) {
|
||||
for (const std::string& spslr_file : spslr_files) {
|
||||
fs::path p { spslr_file };
|
||||
|
||||
@ -237,7 +247,7 @@ bool accumulate(const std::vector<std::string>& spslr_files) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!accumulate_file(p)) {
|
||||
if (!accumulate_file(p, no_new_targets)) {
|
||||
std::cerr << "Failed to parse metadata file " << p << "!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
@ -245,3 +255,116 @@ bool accumulate(const std::vector<std::string>& spslr_files) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dump_target_map(const std::string& path) {
|
||||
std::filesystem::path p{path};
|
||||
if (p.has_parent_path()) {
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(p.parent_path(), ec);
|
||||
if (ec) {
|
||||
std::cerr << "Failed to create target-map directory: " << ec.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream out(p);
|
||||
if (!out)
|
||||
return false;
|
||||
|
||||
out << "SPSLR_TARGETS 1\n";
|
||||
|
||||
for (const auto& [uid, t] : targets) {
|
||||
out << "target " << t.name << " " << uid << " " << t.size << " " << t.fields.size() << "\n";
|
||||
|
||||
for (const auto& [off, f] : t.fields) {
|
||||
(void)off;
|
||||
out << "f " << f.offset << " " << f.size << " " << f.alignment << " " << f.flags << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return !!out;
|
||||
}
|
||||
|
||||
bool load_target_map(const std::string& path) {
|
||||
std::ifstream in(path);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
std::string magic;
|
||||
std::size_t version = 0;
|
||||
if (!(in >> magic >> version) || magic != "SPSLR_TARGETS" || version != 1) {
|
||||
std::cerr << "Invalid target map header\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::getline(in, line); // consume rest of header line
|
||||
|
||||
std::size_t max_uid = 0;
|
||||
bool have_any = false;
|
||||
|
||||
while (std::getline(in, line)) {
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
std::istringstream iss(line);
|
||||
std::string tag;
|
||||
iss >> tag;
|
||||
|
||||
if (tag != "target") {
|
||||
std::cerr << "Expected target entry in target map\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
TARGET t{};
|
||||
std::size_t uid = 0;
|
||||
std::size_t field_count = 0;
|
||||
|
||||
if (!(iss >> t.name >> uid >> t.size >> field_count)) {
|
||||
std::cerr << "Malformed target entry in target map\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < field_count; ++i) {
|
||||
std::string fline;
|
||||
if (!std::getline(in, fline)) {
|
||||
std::cerr << "Missing field entry in target map\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::istringstream fiss(fline);
|
||||
std::string ftag;
|
||||
FIELD f{};
|
||||
|
||||
if (!(fiss >> ftag) || ftag != "f" || !(fiss >> f.offset >> f.size >> f.alignment >> f.flags)) {
|
||||
std::cerr << "Malformed field entry in target map\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
f.idx = i;
|
||||
if (t.fields.contains(f.offset)) {
|
||||
std::cerr << "Duplicate field offset in target map\n";
|
||||
return false;
|
||||
}
|
||||
t.fields.emplace(f.offset, f);
|
||||
}
|
||||
|
||||
if (targets.contains(uid)) {
|
||||
std::cerr << "Duplicate target uid in target map\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
targets.emplace(uid, std::move(t));
|
||||
|
||||
if (!have_any || uid > max_uid) {
|
||||
max_uid = uid;
|
||||
have_any = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_any)
|
||||
next_global_target_uid = (max_uid + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -49,4 +49,6 @@ struct CU {
|
||||
extern std::unordered_map<std::size_t, TARGET> targets;
|
||||
extern std::unordered_map<std::string, CU> units;
|
||||
|
||||
bool accumulate(const std::vector<std::string>& spslr_files);
|
||||
bool accumulate(const std::vector<std::string>& spslr_files, bool no_new_targets);
|
||||
bool dump_target_map(const std::string& path);
|
||||
bool load_target_map(const std::string& path);
|
||||
|
||||
@ -101,6 +101,13 @@ static bool emit_header(std::ostream& out) {
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_module_header(std::ostream& out) {
|
||||
// Shared objects with read-only relocations cause warnings
|
||||
out << ".section .data.rel.ro.spslr,\"aw\",@progbits\n";
|
||||
out << ".balign 8\n";
|
||||
return !!out;
|
||||
}
|
||||
|
||||
static bool emit_u32_object(std::ostream& out, const char* name, uint32_t value) {
|
||||
out << ".globl " << name << "\n";
|
||||
out << ".type " << name << ", @object\n";
|
||||
@ -112,6 +119,9 @@ static bool emit_u32_object(std::ostream& out, const char* name, uint32_t value)
|
||||
}
|
||||
|
||||
static bool emit_targets(std::ostream& out, const std::vector<TARGET_REC>& targets) {
|
||||
if (!emit_u32_object(out, "spslr_target_cnt", static_cast<uint32_t>(targets.size())))
|
||||
return false;
|
||||
|
||||
out << ".globl spslr_targets\n";
|
||||
out << ".type spslr_targets, @object\n";
|
||||
out << ".balign 4\n";
|
||||
@ -128,6 +138,9 @@ static bool emit_targets(std::ostream& out, const std::vector<TARGET_REC>& targe
|
||||
}
|
||||
|
||||
static bool emit_target_fields(std::ostream& out, const std::vector<TARGET_FIELD_REC>& fields) {
|
||||
if (!emit_u32_object(out, "spslr_target_field_cnt", static_cast<uint32_t>(fields.size())))
|
||||
return false;
|
||||
|
||||
out << ".globl spslr_target_fields\n";
|
||||
out << ".type spslr_target_fields, @object\n";
|
||||
out << ".balign 4\n";
|
||||
@ -145,6 +158,9 @@ static bool emit_target_fields(std::ostream& out, const std::vector<TARGET_FIELD
|
||||
}
|
||||
|
||||
static bool emit_ipins(std::ostream& out, const std::vector<IPIN_REC>& ipins) {
|
||||
if (!emit_u32_object(out, "spslr_ipin_cnt", static_cast<uint32_t>(ipins.size())))
|
||||
return false;
|
||||
|
||||
out << ".globl spslr_ipins\n";
|
||||
out << ".type spslr_ipins, @object\n";
|
||||
out << ".balign 8\n";
|
||||
@ -161,6 +177,9 @@ static bool emit_ipins(std::ostream& out, const std::vector<IPIN_REC>& ipins) {
|
||||
}
|
||||
|
||||
static bool emit_ipin_ops(std::ostream& out, const std::vector<IPIN_OP_REC>& ops) {
|
||||
if (!emit_u32_object(out, "spslr_ipin_op_cnt", static_cast<uint32_t>(ops.size())))
|
||||
return false;
|
||||
|
||||
out << ".globl spslr_ipin_ops\n";
|
||||
out << ".type spslr_ipin_ops, @object\n";
|
||||
out << ".balign 4\n";
|
||||
@ -177,6 +196,9 @@ static bool emit_ipin_ops(std::ostream& out, const std::vector<IPIN_OP_REC>& ops
|
||||
}
|
||||
|
||||
static bool emit_dpins(std::ostream& out, const std::vector<DPIN_REC>& dpins) {
|
||||
if (!emit_u32_object(out, "spslr_dpin_cnt", static_cast<uint32_t>(dpins.size())))
|
||||
return false;
|
||||
|
||||
out << ".globl spslr_dpins\n";
|
||||
out << ".type spslr_dpins, @object\n";
|
||||
out << ".balign 8\n";
|
||||
@ -193,13 +215,20 @@ static bool emit_dpins(std::ostream& out, const std::vector<DPIN_REC>& dpins) {
|
||||
|
||||
}
|
||||
|
||||
bool emit_patcher_program_asm(std::ostream& out) {
|
||||
bool emit_patcher_program_asm(std::ostream& out, bool is_module) {
|
||||
if (!is_module) {
|
||||
if (!emit_header(out))
|
||||
return false;
|
||||
} else {
|
||||
if (!emit_module_header(out))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Important: target UID == index in spslr_targets[] for the new interface.
|
||||
std::vector<TARGET_REC> target_recs(targets.size());
|
||||
std::vector<TARGET_FIELD_REC> field_recs;
|
||||
|
||||
if (!is_module) {
|
||||
field_recs.reserve(64);
|
||||
|
||||
for (uint32_t uid = 0; uid < static_cast<uint32_t>(targets.size()); ++uid) {
|
||||
@ -225,6 +254,7 @@ bool emit_patcher_program_asm(std::ostream& out) {
|
||||
|
||||
target_recs[uid] = trec;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<IPIN_REC> ipin_recs;
|
||||
std::vector<IPIN_OP_REC> ipin_ops;
|
||||
@ -289,28 +319,17 @@ bool emit_patcher_program_asm(std::ostream& out) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!emit_u32_object(out, "spslr_target_cnt", static_cast<uint32_t>(target_recs.size())))
|
||||
return false;
|
||||
if (!is_module) {
|
||||
if (!emit_targets(out, target_recs))
|
||||
return false;
|
||||
|
||||
if (!emit_u32_object(out, "spslr_target_field_cnt", static_cast<uint32_t>(field_recs.size())))
|
||||
return false;
|
||||
if (!emit_target_fields(out, field_recs))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emit_u32_object(out, "spslr_ipin_cnt", static_cast<uint32_t>(ipin_recs.size())))
|
||||
return false;
|
||||
if (!emit_ipins(out, ipin_recs))
|
||||
return false;
|
||||
|
||||
if (!emit_u32_object(out, "spslr_ipin_op_cnt", static_cast<uint32_t>(ipin_ops.size())))
|
||||
return false;
|
||||
if (!emit_ipin_ops(out, ipin_ops))
|
||||
return false;
|
||||
|
||||
if (!emit_u32_object(out, "spslr_dpin_cnt", static_cast<uint32_t>(dpin_recs.size())))
|
||||
return false;
|
||||
if (!emit_dpins(out, dpin_recs))
|
||||
return false;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
|
||||
bool emit_patcher_program_asm(std::ostream& out);
|
||||
bool emit_patcher_program_asm(std::ostream& out, bool is_module);
|
||||
|
||||
@ -14,58 +14,91 @@ Notes:
|
||||
Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together
|
||||
*/
|
||||
|
||||
struct OPTIONS {
|
||||
std::string out_file;
|
||||
std::string load_targets_file;
|
||||
std::string dump_targets_file;
|
||||
std::vector<std::string> spslr_files;
|
||||
bool no_new_targets = false;
|
||||
bool is_module = false;
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
static option long_options[] = {
|
||||
{ "help", no_argument, 0, 0 },
|
||||
{ "out", required_argument, 0, 0 },
|
||||
{ "load-targets", required_argument, 0, 0 },
|
||||
{ "dump-targets", required_argument, 0, 0 },
|
||||
{ "no-new-targets", no_argument, 0, 0 },
|
||||
{ "module", no_argument, 0, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
OPTIONS opts{};
|
||||
int option_index = 0;
|
||||
int c;
|
||||
|
||||
std::vector<std::string> spslr_files;
|
||||
std::string out_file;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h:o:", long_options, &option_index)) == 0) {
|
||||
const option& opt = long_options[option_index];
|
||||
std::string optname { opt.name };
|
||||
|
||||
if (optname == "help") {
|
||||
std::cout << "To use spslr_patchcompile, supply these arguments:" << std::endl;
|
||||
std::cout << " --out=<file> (the compiled asm file to be written)" << std::endl;
|
||||
std::cout << " <file>... (one or more .spslr metadata files)" << std::endl;
|
||||
std::cout
|
||||
<< "Usage:\n"
|
||||
<< " spslr_patchcompile --out=<file> [options] <file>...\n\n"
|
||||
<< "Options:\n"
|
||||
<< " --read-targets=<file>\n"
|
||||
<< " --emit-targets=<file>\n"
|
||||
<< " --no-new-targets\n"
|
||||
<< " --module\n";
|
||||
return 0;
|
||||
} else if (optname == "out") {
|
||||
out_file = std::string{ optarg };
|
||||
opts.out_file = optarg;
|
||||
} else if (optname == "load-targets") {
|
||||
opts.load_targets_file = optarg;
|
||||
} else if (optname == "dump-targets") {
|
||||
opts.dump_targets_file = optarg;
|
||||
} else if (optname == "no-new-targets") {
|
||||
opts.no_new_targets = true;
|
||||
} else if (optname == "module") {
|
||||
opts.is_module = true;
|
||||
} else {
|
||||
std::cerr << "Invalid option, try \"--help\"!" << std::endl;
|
||||
std::cerr << "Invalid option, try \"--help\"!\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (out_file.empty()) {
|
||||
std::cerr << "Missing output file path, supply it via --out=<file>!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = optind; i < argc; ++i)
|
||||
spslr_files.emplace_back(argv[i]);
|
||||
opts.spslr_files.emplace_back(argv[i]);
|
||||
|
||||
if (spslr_files.empty()) {
|
||||
std::cerr << "Missing spslr files! Pass one or more .spslr files as positional arguments." << std::endl;
|
||||
if (opts.out_file.empty()) {
|
||||
std::cerr << "Missing output file path, supply it via --out=<file>!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!accumulate(spslr_files)) {
|
||||
if (opts.spslr_files.empty()) {
|
||||
std::cerr << "Missing spslr files! Pass one or more .spslr metadata files as positional arguments.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (opts.no_new_targets && opts.load_targets_file.empty()) {
|
||||
std::cerr << "--no-new-targets requires --load-targets\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!opts.load_targets_file.empty()) {
|
||||
if (!load_target_map(opts.load_targets_file)) {
|
||||
std::cerr << "Failed to load target map: " << opts.load_targets_file << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!accumulate(opts.spslr_files, opts.no_new_targets)) {
|
||||
std::cerr << "Failed to accumulate data from spslr directory!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Gathered a total of " << targets.size() << " distinct targets from "
|
||||
<< units.size() << " compilation units!" << std::endl;
|
||||
|
||||
std::filesystem::path out_path { out_file };
|
||||
std::filesystem::path out_path { opts.out_file };
|
||||
if (out_path.has_parent_path()) {
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(out_path.parent_path(), ec);
|
||||
@ -83,11 +116,18 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!emit_patcher_program_asm(out)) {
|
||||
if (!emit_patcher_program_asm(out, opts.is_module)) {
|
||||
std::cerr << "Failed to write emit patcher program!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!opts.dump_targets_file.empty()) {
|
||||
if (!dump_target_map(opts.dump_targets_file)) {
|
||||
std::cerr << "Failed to write target map: " << opts.dump_targets_file << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,22 @@
|
||||
#ifndef SPSLR_SELFPATCH_H
|
||||
#define SPSLR_SELFPATCH_H
|
||||
|
||||
#define SPSLR_MODULE_SYM_IPIN_CNT "spslr_ipin_cnt"
|
||||
#define SPSLR_MODULE_SYM_IPINS "spslr_ipins"
|
||||
#define SPSLR_MODULE_SYM_IPIN_OP_CNT "spslr_ipin_op_cnt"
|
||||
#define SPSLR_MODULE_SYM_IPIN_OPS "spslr_ipin_ops"
|
||||
#define SPSLR_MODULE_SYM_DPIN_CNT "spslr_dpin_cnt"
|
||||
#define SPSLR_MODULE_SYM_DPINS "spslr_dpins"
|
||||
|
||||
struct spslr_module {
|
||||
const void* ipin_cnt;
|
||||
const void* ipins;
|
||||
const void* ipin_op_cnt;
|
||||
const void* ipin_ops;
|
||||
const void* dpin_cnt;
|
||||
const void* dpins;
|
||||
};
|
||||
|
||||
void spslr_selfpatch(void);
|
||||
|
||||
#endif
|
||||
|
||||
@ -32,17 +32,25 @@ endforeach()
|
||||
set(SUBJECT_SPSLR_ASM "${CMAKE_CURRENT_BINARY_DIR}/subject_spslr_program.S")
|
||||
set(SUBJECT_SPSLR_OBJ "${CMAKE_CURRENT_BINARY_DIR}/subject_spslr_program.o")
|
||||
|
||||
set(SUBJECT_TARGET_MAP "${CMAKE_CURRENT_BINARY_DIR}/subject.spslr_targets")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${SUBJECT_SPSLR_ASM}"
|
||||
OUTPUT "${SUBJECT_SPSLR_ASM}" "${SUBJECT_TARGET_MAP}"
|
||||
COMMAND $<TARGET_FILE:spslr_patchcompile>
|
||||
--out=${SUBJECT_SPSLR_ASM}
|
||||
--dump-targets=${SUBJECT_TARGET_MAP}
|
||||
${SUBJECT_SPSLR_FILES}
|
||||
DEPENDS
|
||||
spslr_patchcompile
|
||||
$<TARGET_OBJECTS:subject_objs>
|
||||
subject_objs
|
||||
${SUBJECT_SPSLR_FILES}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(subject_spslr_metadata
|
||||
DEPENDS "${SUBJECT_SPSLR_ASM}" "${SUBJECT_TARGET_MAP}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${SUBJECT_SPSLR_OBJ}"
|
||||
COMMAND ${CMAKE_C_COMPILER}
|
||||
@ -104,10 +112,15 @@ add_custom_command(
|
||||
OUTPUT "${MODULE_SPSLR_ASM}"
|
||||
COMMAND $<TARGET_FILE:spslr_patchcompile>
|
||||
--out=${MODULE_SPSLR_ASM}
|
||||
--load-targets=${SUBJECT_TARGET_MAP}
|
||||
--no-new-targets
|
||||
--module
|
||||
${MODULE_SPSLR_FILES}
|
||||
DEPENDS
|
||||
spslr_patchcompile
|
||||
$<TARGET_OBJECTS:spslr_module_objs>
|
||||
subject_spslr_metadata
|
||||
spslr_module_objs
|
||||
${MODULE_SPSLR_FILES}
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
||||
@ -22,6 +22,37 @@ struct task_struct global = { .pid = 42, .comm = "main_global", .arrfun = {
|
||||
|
||||
EXPORT_SYMBOL(global);
|
||||
|
||||
static int fetch_module_spslr_symbols(void* handle, struct spslr_module* mod) {
|
||||
if (!handle || !mod)
|
||||
return -1;
|
||||
|
||||
mod->ipin_cnt = dlsym(handle, SPSLR_MODULE_SYM_IPIN_CNT);
|
||||
if (!mod->ipin_cnt)
|
||||
return -1;
|
||||
|
||||
mod->ipins = dlsym(handle, SPSLR_MODULE_SYM_IPINS);
|
||||
if (!mod->ipins)
|
||||
return -1;
|
||||
|
||||
mod->ipin_op_cnt = dlsym(handle, SPSLR_MODULE_SYM_IPIN_OP_CNT);
|
||||
if (!mod->ipin_op_cnt)
|
||||
return -1;
|
||||
|
||||
mod->ipin_ops = dlsym(handle, SPSLR_MODULE_SYM_IPIN_OPS);
|
||||
if (!mod->ipin_ops)
|
||||
return -1;
|
||||
|
||||
mod->dpin_cnt = dlsym(handle, SPSLR_MODULE_SYM_DPIN_CNT);
|
||||
if (!mod->dpin_cnt)
|
||||
return -1;
|
||||
|
||||
mod->dpins = dlsym(handle, SPSLR_MODULE_SYM_DPINS);
|
||||
if (!mod->dpins)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_module_test_access_pid(const char *path, const struct task_struct *t) {
|
||||
typedef int (*module_test_access_fn)(const struct task_struct *t);
|
||||
|
||||
@ -33,6 +64,15 @@ static int do_module_test_access_pid(const char *path, const struct task_struct
|
||||
|
||||
dlerror();
|
||||
|
||||
struct spslr_module mod;
|
||||
if (fetch_module_spslr_symbols(handle, &mod) < 0) {
|
||||
fprintf(stderr, "failed to fetch spslr symbols in test module\n");
|
||||
dlclose(handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO -> Patch module
|
||||
|
||||
module_test_access_fn fn = (module_test_access_fn)dlsym(handle, "module_test_access_pid");
|
||||
|
||||
const char *err = dlerror();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user