rpcsx/orbis-kernel/include/orbis/module/Module.hpp

142 lines
2.9 KiB
C++
Raw Normal View History

2023-07-03 13:10:16 +02:00
#pragma once
#include "ModuleHandle.hpp"
#include "ModuleSegment.hpp"
2023-07-04 18:19:17 +02:00
#include "../KernelAllocator.hpp"
2023-07-06 18:16:25 +02:00
#include "../utils/Rc.hpp"
2023-07-03 13:10:16 +02:00
#include "orbis-config.hpp"
#include <cstddef>
#include <string>
2023-07-06 18:16:25 +02:00
#include <vector>
2023-07-03 13:10:16 +02:00
namespace orbis {
struct Thread;
struct Process;
struct ModuleNeeded {
utils::kstring name;
2023-07-03 13:10:16 +02:00
std::uint16_t version;
std::uint16_t attr;
bool isExport;
};
2023-07-06 18:16:25 +02:00
enum class SymbolBind : std::uint8_t { Local, Global, Weak, Unique = 10 };
2023-07-03 13:10:16 +02:00
enum class SymbolVisibility : std::uint8_t {
Default,
Internal,
Hidden,
Protected
};
enum class SymbolType : std::uint8_t {
NoType,
Object,
Function,
Section,
File,
Common,
Tls,
IFunc = 10,
};
struct Symbol {
std::int32_t moduleIndex;
std::uint32_t libraryIndex;
std::uint64_t id;
std::uint64_t address;
std::uint64_t size;
SymbolVisibility visibility;
SymbolBind bind;
SymbolType type;
};
struct Relocation {
std::uint64_t offset;
std::uint32_t relType;
std::uint32_t symbolIndex;
std::int64_t addend;
};
2023-07-04 18:19:17 +02:00
struct Module final {
2023-07-03 13:10:16 +02:00
Process *proc{};
utils::kstring vfsPath;
2023-07-03 13:10:16 +02:00
char moduleName[256]{};
char soName[256]{};
ModuleHandle id{};
uint32_t tlsIndex{};
ptr<void> tlsInit{};
uint32_t tlsInitSize{};
uint32_t tlsSize{};
uint32_t tlsOffset{};
uint32_t tlsAlign{};
ptr<void> initProc{};
ptr<void> finiProc{};
ptr<void> ehFrameHdr{};
ptr<void> ehFrame{};
uint32_t ehFrameHdrSize{};
uint32_t ehFrameSize{};
ModuleSegment segments[4]{};
uint32_t segmentCount{};
std::uint8_t fingerprint[20]{};
ptr<void> base{};
uint64_t size{};
ptr<void> stackStart{};
ptr<void> stackEnd{};
ptr<void> processParam{};
uint64_t processParamSize{};
ptr<void> moduleParam{};
uint64_t moduleParamSize{};
ptr<uint64_t> pltGot{};
uint16_t version{};
uint16_t attributes{};
uint16_t type{};
uint16_t flags{};
uint64_t entryPoint{};
uint32_t phNum{};
uint64_t phdrAddress{};
bool isTlsDone = false;
2023-07-04 18:19:17 +02:00
utils::kvector<Symbol> symbols;
utils::kvector<Relocation> pltRelocations;
utils::kvector<Relocation> nonPltRelocations;
utils::kvector<ModuleNeeded> neededModules;
utils::kvector<ModuleNeeded> neededLibraries;
utils::kvector<utils::Ref<Module>> importedModules;
utils::kvector<utils::Ref<Module>> namespaceModules;
utils::kvector<utils::kstring> needed;
2023-07-03 13:10:16 +02:00
std::atomic<unsigned> references{0};
2023-07-04 18:19:17 +02:00
unsigned _total_size = 0;
2023-07-03 13:10:16 +02:00
void incRef() {
2023-07-05 10:38:31 +02:00
if (_total_size != sizeof(Module))
std::abort();
2023-07-03 13:10:16 +02:00
if (references.fetch_add(1, std::memory_order::relaxed) > 512) {
assert(!"too many references");
}
}
void decRef() {
2023-07-06 18:16:25 +02:00
if (references.fetch_sub(1, std::memory_order::relaxed) == 1 &&
proc != nullptr) {
2023-07-03 13:10:16 +02:00
destroy();
}
}
orbis::SysResult relocate(Process *process);
private:
void destroy();
};
2023-07-06 18:16:25 +02:00
utils::Ref<Module> createModule(Thread *p, std::string vfsPath,
const char *name);
2023-07-03 13:10:16 +02:00
} // namespace orbis