Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Main fields in `config.toml`:
* `general.patch_cache`: apply configured patches to CACHE instructions.
* `general.stubs`: names to force as stubs. Also accepts `handler@0xADDRESS` to bind a stripped function address directly to a runtime syscall/stub handler. Includes generic handlers `ret0`, `ret1`, `reta0`.
* `general.skip`: names to force as skipped wrappers.
* `general.external_call_target_manifests`: optional array of `external_call_targets.txt` paths emitted by other recompile invocations (e.g. a separately recompiled overlay); their call targets that land inside this invocation's functions are registered as additional entry points. Each invocation writes its own `external_call_targets.txt` into `general.output`.
* `patches.instructions`: raw instruction replacements by address.

Address binding for stripped ELFs:
Expand Down
26 changes: 26 additions & 0 deletions ps2xRecomp/include/ps2recomp/ps2_recompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <filesystem>
#include <memory>
#include <map>
#include <istream>
#include <functional>

namespace ps2recomp
{
Expand Down Expand Up @@ -46,6 +48,27 @@ namespace ps2recomp

static std::string ClampFilenameLength(const std::string& baseName, const std::string& extension, std::size_t maxLength);

// Parses a call-target manifest (one "0x%08x" address per line, blank lines and
// '#' comments ignored) into a sorted, de-duplicated list of addresses. Shared by
// the production manifest loader and unit tests.
static std::vector<uint32_t> ParseCallTargetManifest(std::istream &input);

// Discovers thread entry function pointers embedded in static ThreadParam
// structs passed to the CreateThread syscall (0x20). Returns the entry-pointer
// values read from data memory, sorted and de-duplicated.
static std::vector<uint32_t> DiscoverDataEmbeddedThreadEntries(
const std::unordered_map<uint32_t, std::vector<Instruction>> &decodedFunctions,
const std::function<bool(uint32_t)> &isValidAddress,
const std::function<uint32_t(uint32_t)> &readWord);

// Collects jal/j targets that fall in executable sections but outside every
// recompiled local function range - candidate cross-unit call targets to
// publish in the external call-target manifest. Sorted and de-duplicated.
static std::vector<uint32_t> CollectExternalCallTargets(
const std::unordered_map<uint32_t, std::vector<Instruction>> &decodedFunctions,
const std::vector<Function> &functions,
const std::vector<Section> &sections);

private:
ConfigManager m_configManager;
std::unique_ptr<ElfParser> m_elfParser;
Expand All @@ -68,10 +91,13 @@ namespace ps2recomp
std::map<uint32_t, std::string> m_generatedStubs;
std::unordered_map<uint32_t, std::string> m_functionRenames;
std::unordered_map<uint32_t, std::vector<uint32_t>> m_resumeEntryTargetsByOwner;
std::vector<uint32_t> m_ingestedExternalCallTargets;
CodeGenerator::BootstrapInfo m_bootstrapInfo;

bool decodeFunction(Function &function);
void discoverAdditionalEntryPoints();
void loadExternalCallTargetManifests();
void emitExternalCallTargetManifest();
bool shouldSkipFunction(const Function &function) const;
bool isStubFunction(const Function &function) const;
bool generateFunctionHeader();
Expand Down
1 change: 1 addition & 0 deletions ps2xRecomp/include/ps2recomp/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ namespace ps2recomp
std::vector<std::string> stubImplementations;
std::unordered_map<uint32_t, uint32_t> mmioByInstructionAddress;
std::vector<JumpTable> jumpTables;
std::vector<std::string> externalCallTargetManifests;
};

} // namespace ps2recomp
Expand Down
15 changes: 15 additions & 0 deletions ps2xRecomp/src/lib/config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ namespace ps2recomp
config.skipFunctions = toml::find<std::vector<std::string>>(data, "skip");
}

if (general.contains("external_call_target_manifests") && general.at("external_call_target_manifests").is_array())
{
config.externalCallTargetManifests =
toml::find<std::vector<std::string>>(general, "external_call_target_manifests");
}
else if (data.contains("external_call_target_manifests") && data.at("external_call_target_manifests").is_array())
{
config.externalCallTargetManifests =
toml::find<std::vector<std::string>>(data, "external_call_target_manifests");
}

if (data.contains("patches") && data.at("patches").is_table())
{
const auto &patches = toml::find(data, "patches");
Expand Down Expand Up @@ -276,6 +287,10 @@ namespace ps2recomp
general["patch_cache"] = config.patchCache;
general["skip"] = config.skipFunctions;
general["stubs"] = config.stubImplementations;
if (!config.externalCallTargetManifests.empty())
{
general["external_call_target_manifests"] = config.externalCallTargetManifests;
}
data["general"] = general;

if (!config.mmioByInstructionAddress.empty())
Expand Down
Loading