#pragma once #include "ModuleHandle.hpp" #include "ModuleSegment.hpp" #include "../utils/Rc.hpp" #include "orbis-config.hpp" #include #include #include namespace orbis { struct Thread; struct Process; struct ModuleNeeded { std::string name; std::uint16_t version; std::uint16_t attr; bool isExport; }; enum class SymbolBind : std::uint8_t { Local, Global, Weak, Unique = 10 }; 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; }; struct Module { Process *proc{}; std::string vfsPath; char moduleName[256]{}; char soName[256]{}; ModuleHandle id{}; uint32_t tlsIndex{}; ptr tlsInit{}; uint32_t tlsInitSize{}; uint32_t tlsSize{}; uint32_t tlsOffset{}; uint32_t tlsAlign{}; ptr initProc{}; ptr finiProc{}; ptr ehFrameHdr{}; ptr ehFrame{}; uint32_t ehFrameHdrSize{}; uint32_t ehFrameSize{}; ModuleSegment segments[4]{}; uint32_t segmentCount{}; std::uint8_t fingerprint[20]{}; ptr base{}; uint64_t size{}; ptr stackStart{}; ptr stackEnd{}; ptr processParam{}; uint64_t processParamSize{}; ptr moduleParam{}; uint64_t moduleParamSize{}; ptr 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; std::vector symbols; std::vector pltRelocations; std::vector nonPltRelocations; std::vector neededModules; std::vector neededLibraries; std::vector> importedModules; std::vector> namespaceModules; std::vector needed; std::atomic references{0}; void incRef() { if (references.fetch_add(1, std::memory_order::relaxed) > 512) { assert(!"too many references"); } } void decRef() { if (references.fetch_sub(1, std::memory_order::relaxed) == 1 && proc != nullptr) { destroy(); } } orbis::SysResult relocate(Process *process); private: void destroy(); }; utils::Ref createModule(Thread *p, std::string vfsPath, const char *name); } // namespace orbis