/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.format;
import jpcsp.AllegrexOpcodes;
import jpcsp.Memory;
import jpcsp.HLE.SyscallHandler;
import jpcsp.HLE.kernel.types.SceModule;
public class DeferredStub {
protected SceModule sourceModule;
private String moduleName;
private int importAddress;
private int nid;
private boolean savedImport;
private int savedImport1;
private int savedImport2;
public DeferredStub(SceModule sourceModule, String moduleName, int importAddress, int nid) {
this.sourceModule = sourceModule;
this.moduleName = moduleName;
this.importAddress = importAddress;
this.nid = nid;
}
public String getModuleName() {
return moduleName;
}
public int getImportAddress() {
return importAddress;
}
public int getNid() {
return nid;
}
public void resolve(Memory mem, int address) {
if (!savedImport) {
savedImport1 = mem.read32(importAddress);
savedImport2 = mem.read32(importAddress + 4);
savedImport = true;
}
// j <address>
int instruction = (AllegrexOpcodes.J << 26) | ((address >> 2) & 0x03FFFFFF);
mem.write32(importAddress, instruction);
mem.write32(importAddress + 4, 0); // write a nop over our "unmapped import detection special syscall"
}
public void unresolve(Memory mem) {
if (savedImport) {
mem.write32(importAddress, savedImport1);
mem.write32(importAddress + 4, savedImport2);
} else {
// syscall <syscallUnmappedImport>
int instruction = (AllegrexOpcodes.SPECIAL << 26) | AllegrexOpcodes.SYSCALL | (SyscallHandler.syscallUnmappedImport << 6);
mem.write32(importAddress + 4, instruction);
}
if (sourceModule != null) {
// Add this stub back to the list of unresolved imports from the source module
sourceModule.unresolvedImports.add(this);
}
}
@Override
public String toString() {
return String.format("0x%08X [0x%08X] Module '%s'", getImportAddress(), getNid(), getModuleName());
}
}