mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-28 00:35:47 +00:00
80 lines
2.8 KiB
C++
80 lines
2.8 KiB
C++
#include <nid/NidResolver.hpp>
|
|
#include <nid/ExportExclusions.hpp>
|
|
#include <nid/NidCompute.hpp>
|
|
#include <nid/NidPatcherUtils.hpp>
|
|
#include <cstdint>
|
|
#include <cctype>
|
|
#include <stdexcept>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
namespace Nid {
|
|
|
|
bool IsSceImport(const std::string& name) {
|
|
return name.ends_with(Internal::kNidPostfix) || (name.size() >= 3 &&
|
|
std::tolower(static_cast<unsigned char>(name[0])) == 's' &&
|
|
std::tolower(static_cast<unsigned char>(name[1])) == 'c' &&
|
|
std::tolower(static_cast<unsigned char>(name[2])) == 'e');
|
|
}
|
|
|
|
std::unordered_map<std::string, std::string> ResolveImportNids(const std::vector<std::string>& names, const std::unordered_set<std::string>& excluded, const PatchOptions& options) {
|
|
const std::unordered_set<std::string> unique(names.begin(), names.end());
|
|
auto result = ResolveNids(std::vector<std::string>(unique.begin(), unique.end()), "", excluded);
|
|
for (const auto& name : unique) {
|
|
if ((!options.executable || options.onlySce) && !IsSceImport(name)) result.at(name) = name;
|
|
else if (!options.executable) result.at(name) = ResolveOneName(name);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string ResolveOneName(const std::string& funcName) {
|
|
return ResolveNids({funcName}, "", {}).at(funcName);
|
|
}
|
|
|
|
std::unordered_map<std::string, std::string> ResolveNids(const std::vector<std::string>& exportedNames, const std::string& libraryName, const std::unordered_set<std::string>& excludedExports) {
|
|
using namespace Internal;
|
|
|
|
std::unordered_set<std::string> nameSet(exportedNames.begin(), exportedNames.end());
|
|
|
|
if (nameSet.size() != exportedNames.size()) {
|
|
for (std::size_t i = 0u; i < exportedNames.size(); ++i) {
|
|
for (std::size_t j = i + 1u; j < exportedNames.size(); ++j) {
|
|
if (exportedNames[i] == exportedNames[j])
|
|
throw std::runtime_error("duplicate exported symbol \"" + exportedNames[i] + "\" in library \"" + libraryName + "\"");
|
|
}
|
|
}
|
|
}
|
|
|
|
std::unordered_map<std::string, std::string> result;
|
|
result.reserve(exportedNames.size());
|
|
|
|
for (const std::string& name : exportedNames) {
|
|
if (excludedExports.contains(NormalizeExportName(name))) {
|
|
result[name] = name;
|
|
continue;
|
|
}
|
|
if (IsNidNoPatchCut(name)) {
|
|
result[name] = StripNidNoPatchCut(name);
|
|
continue;
|
|
}
|
|
if (IsNidNoPatch(name)) {
|
|
result[name] = name;
|
|
continue;
|
|
}
|
|
|
|
const std::string stripped = StripNidPostfix(name);
|
|
const bool hasPostfix = stripped != name;
|
|
|
|
if (!hasPostfix && nameSet.count(name + kNidPostfix)) {
|
|
result[name] = name;
|
|
continue;
|
|
}
|
|
|
|
result[name] = ComputeNid(stripped, libraryName);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|