2023-06-23 02:28:14 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "orbis/module/Module.hpp"
|
|
|
|
|
#include "orbis/utils/Rc.hpp"
|
|
|
|
|
#include <cstddef>
|
2023-06-29 12:51:08 +02:00
|
|
|
#include <filesystem>
|
2023-06-30 16:14:05 +02:00
|
|
|
#include <optional>
|
2023-06-23 02:28:14 +02:00
|
|
|
#include <span>
|
|
|
|
|
|
|
|
|
|
namespace rx::linker {
|
|
|
|
|
inline constexpr char nidLookup[] =
|
|
|
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
|
|
|
|
|
|
2023-06-30 16:14:05 +02:00
|
|
|
constexpr std::optional<std::uint64_t> decodeNid(std::string_view nid) {
|
2023-06-23 02:28:14 +02:00
|
|
|
std::uint64_t result = 0;
|
|
|
|
|
|
|
|
|
|
if (nid.size() > 11) {
|
2023-07-06 18:16:25 +02:00
|
|
|
return {};
|
2023-06-23 02:28:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < nid.size(); ++i) {
|
|
|
|
|
auto it = std::strchr(nidLookup, nid[i]);
|
|
|
|
|
|
|
|
|
|
if (it == nullptr) {
|
2023-07-06 18:16:25 +02:00
|
|
|
return {};
|
2023-06-23 02:28:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto value = static_cast<uint32_t>(it - nidLookup);
|
|
|
|
|
|
|
|
|
|
if (i == 10) {
|
|
|
|
|
result <<= 4;
|
|
|
|
|
result |= (value >> 2);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result <<= 6;
|
|
|
|
|
result |= value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-30 16:14:05 +02:00
|
|
|
struct nid {
|
|
|
|
|
char string[12];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr nid encodeNid(std::uint64_t hash) {
|
|
|
|
|
return {{nidLookup[(hash >> 58) & 0x3f], nidLookup[(hash >> 52) & 0x3f],
|
|
|
|
|
nidLookup[(hash >> 46) & 0x3f], nidLookup[(hash >> 40) & 0x3f],
|
|
|
|
|
nidLookup[(hash >> 34) & 0x3f], nidLookup[(hash >> 28) & 0x3f],
|
|
|
|
|
nidLookup[(hash >> 22) & 0x3f], nidLookup[(hash >> 16) & 0x3f],
|
|
|
|
|
nidLookup[(hash >> 10) & 0x3f], nidLookup[(hash >> 4) & 0x3f],
|
|
|
|
|
nidLookup[(hash & 0xf) * 4], 0}};
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-23 02:28:14 +02:00
|
|
|
std::uint64_t encodeFid(std::string_view fid);
|
|
|
|
|
|
|
|
|
|
struct Symbol {
|
|
|
|
|
orbis::Module *module;
|
|
|
|
|
std::uint64_t address;
|
|
|
|
|
std::uint64_t bindMode;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum OrbisElfType_t {
|
|
|
|
|
kElfTypeNone = 0,
|
|
|
|
|
kElfTypeRel = 1,
|
|
|
|
|
kElfTypeExec = 2,
|
|
|
|
|
kElfTypeDyn = 3,
|
|
|
|
|
kElfTypeCore = 4,
|
|
|
|
|
kElfTypeNum = 5,
|
|
|
|
|
kElfTypeSceExec = 0xfe00,
|
|
|
|
|
kElfTypeSceDynExec = 0xfe10,
|
|
|
|
|
kElfTypeSceDynamic = 0xfe18
|
|
|
|
|
};
|
|
|
|
|
|
2023-07-06 18:16:25 +02:00
|
|
|
void override(std::string originalModuleName,
|
|
|
|
|
std::filesystem::path replacedModulePath);
|
|
|
|
|
orbis::Ref<orbis::Module> loadModule(std::span<std::byte> image,
|
|
|
|
|
orbis::Process *process);
|
|
|
|
|
orbis::Ref<orbis::Module> loadModuleFile(const char *path,
|
|
|
|
|
orbis::Process *process);
|
|
|
|
|
orbis::Ref<orbis::Module> loadModuleByName(std::string_view name,
|
|
|
|
|
orbis::Process *process);
|
|
|
|
|
} // namespace rx::linker
|