diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 5f1f6c9..87b2368 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -18,21 +18,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.idea/misc.xml b/.idea/misc.xml
index d460235..35bf185 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/.idea/runConfigurations/Xploit_JAR.xml b/.idea/runConfigurations/Xploit_JAR.xml
new file mode 100644
index 0000000..4062ea9
--- /dev/null
+++ b/.idea/runConfigurations/Xploit_JAR.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 9cb996d..57fea38 100644
--- a/README.md
+++ b/README.md
@@ -46,8 +46,8 @@ Either modify the POM directly, or pass the new values from command line, exampl
8. Once execution is complete, the loader will wait for a new JAR. Do the necessary modifications in `xploit` project, recompile using `mvn package` and re-execute #7 to retry as many times as necessary.
## Notes
-1. To use with IntelliJ, simply point `File -> Open` dialog to the root of the project.
-2. If any of POMs are modified, it's necessary to do `Maven -> Reload Project` in IntelliJ to sync the project files. Syncing Maven project unfortunately modifies [.idea/compiler.xml](.idea/compiler.xml) to contain absolute system paths. Simply replace those with `$PROJECT_DIR$` macro again. IntelliJ also modifies classpaths of the modules defined in various `*.iml` files. These modifications should also mostly be reverted.
+1. To use with IntelliJ, point `File -> Open` dialog to the root of the project. Maven import will occur. Then follow manual steps in [IntelliJ Project Structure](#intellij-project-structure) to adjust the dependencies so that IntelliJ sees BD-J classes ahead of JDK classes.
+2. If any of POMs are modified, it's necessary to do `Maven -> Reload Project` in IntelliJ to sync the project files.
3. To generate Javadocs, use `mvn verify` rather than `mvn package`. The Javadocs are enabled for [sdk](sdk), [xlet](xlet) and [xploit](xploit) modules and are generated in the `target/site/apidocs` directory of each module.
4. The JAR in the `xploit` module accesses some internal JDK classes by reflection. This will result in warnings which can be safely ignored. To mute the warnings, add the following switch after `java` executable when sending the JAR: `--add-opens java.base/jdk.internal.loader=ALL-UNNAMED`.
5. If the `xploit` JAR does not have PS5 specific dependencies, it can be tested locally. The important part is to have `xlet`, `stubs` and `xploit` JARs all in the same folder. If the payload refers to GEM, BD-J or Java TV API, the corresponding JAR files generated in [lib](lib) directory should also be present in the same folder. Maven build automatically creates this arrangement in `xploit/target` directory so the command to run the payload on development machine is very similar to the one that sends the JAR to PS5:
@@ -59,5 +59,11 @@ Either modify the POM directly, or pass the new values from command line, exampl
* The `xlet` version is independent and will only be incremented when new disc needs to be burned with the updated JAR loader classes. If the PS5 shows a version different from the one produced by the code of this repo, payloads are not guaranteed to be compatible, so it's best to burn a new loader disc. This version is not expected to be incremented often as the loader is pretty stable. To increment this version, change the value of `xlet.version` property in [pom.xml](pom.xml).
* The rest of the modules use the version from the parent POM. This version will be incremented with the new release and reflects that either the SDK or the payloads have changed. If the loader version remained the same, these new versions of payloads can still be sent to the JAR loader without re-burning the disc. This version can be incremented by executing `mvn versions:set -DnewVersion=[version]`, then refreshing the IntelliJ Maven project as described in bullet point number 2.
+## IntelliJ Project Structure
+IntelliJ Maven project files are located in a private local folder of IntelliJ. Initial opening and the following reloads of the Maven project incorrectly import some of the settings. In particular, BD-J stack JARs are completely ignored or are imported with a wrong scope. Unfortunately, due to this fact, the following steps need to be performed every time a Maven project reload occurs:
+* Syncing Maven project modifies [.idea/compiler.xml](.idea/compiler.xml) to contain absolute system paths. Simply replace those with `$PROJECT_DIR$` macro again.
+* Go to `Project Structure` window and switch to `Modules` tab. Go through every module and make sure that the modules `bdj-api`, `javatv-api` and `gem-api` have "Provided" scope.
+* In addition, for all the modules that have the above-mentioned dependencies, click on `+ (Add) -> Library` button and add `bdjstack` library dependency. Make sure it is moved in the top position above SDK 11 entry. This setting used to be commited to version control and could be simply reverted, but in recent updates, it has to be performed every time.
+
## Credits
There are so many who decided to share the knowledge with the community to make this project possible. Please see the Credits section in the [Webkit PS5 Exploit repo](https://github.com/Cryptogenic/PS5-IPV6-Kernel-Exploit#contributors--special-thanks). None of this would be possible without all these contributors. Additionally, big thanks to [psxdev](https://github.com/psxdev) and [John Törnblom](https://github.com/john-tornblom) for their work specifically on BD-J. Finally, the FTP payload is based off work from [pReya](https://github.com/pReya/ftpServer).
diff --git a/bdj-tools/bdjo/pom.xml b/bdj-tools/bdjo/pom.xml
index fdebdea..a3548d6 100644
--- a/bdj-tools/bdjo/pom.xml
+++ b/bdj-tools/bdjo/pom.xml
@@ -23,6 +23,10 @@
and what should be launched when.
+
+ ${project.basedir}/../../lib
+
+
com.hdcookbook
diff --git a/bdj-tools/grin/pom.xml b/bdj-tools/grin/pom.xml
index b331954..5f3cb21 100644
--- a/bdj-tools/grin/pom.xml
+++ b/bdj-tools/grin/pom.xml
@@ -16,4 +16,8 @@
jar
This is sort of a lightweight SMIL: it provides a simple timeline, and an extensible presentation engine for certain kinds of animations.
+
+ ${project.basedir}/../../lib
+
+
\ No newline at end of file
diff --git a/bdj-tools/id/pom.xml b/bdj-tools/id/pom.xml
index 6c5d6a7..b4c945e 100644
--- a/bdj-tools/id/pom.xml
+++ b/bdj-tools/id/pom.xml
@@ -16,6 +16,10 @@
jar
ID tool converts an id.bdmv file to an xml format and back. File id.bdmv includes the disc ID and org ID for a given BD image, and required to be present under the CERTIFICATE dir.
+
+ ${project.basedir}/../../lib
+
+
com.hdcookbook
diff --git a/bdj-tools/index/pom.xml b/bdj-tools/index/pom.xml
index cd2ebb0..93e242f 100644
--- a/bdj-tools/index/pom.xml
+++ b/bdj-tools/index/pom.xml
@@ -16,6 +16,10 @@
jar
Index tool converts an index.bdmv file to an xml format and back. File index.bdmv is located in the BDMV directory and contains information about the first playback, topmenu and titles on the disc.
+
+ ${project.basedir}/../../lib
+
+
jakarta.xml.bind
diff --git a/bdj-tools/movieobject/pom.xml b/bdj-tools/movieobject/pom.xml
index 9c0d2a2..5a763b9 100644
--- a/bdj-tools/movieobject/pom.xml
+++ b/bdj-tools/movieobject/pom.xml
@@ -16,6 +16,10 @@
jar
MovieObject tool converts MovieObject.bdmv file to an xml format and back. MovieObject.bdmv is a file located in the same directory as index.bdmv and contains information and code for HDMV titles. See BD spec 3-1 section 10.3.2.2 for the file syntax.
+
+ ${project.basedir}/../../lib
+
+
jakarta.xml.bind
diff --git a/bdj-tools/pom.xml b/bdj-tools/pom.xml
index 2adc889..f9bd9cf 100644
--- a/bdj-tools/pom.xml
+++ b/bdj-tools/pom.xml
@@ -16,6 +16,10 @@
pom
Tools from HD Cookbook that were adapted to work with JDK 11 and embedded into the build process of the project without any additional steps.
+
+ ${project.basedir}/../lib
+
+
security
grin
diff --git a/bdj-tools/security/pom.xml b/bdj-tools/security/pom.xml
index 97a7c7a..e2b4ee8 100644
--- a/bdj-tools/security/pom.xml
+++ b/bdj-tools/security/pom.xml
@@ -21,6 +21,10 @@
* BDCredentialSigner - This tool is for signing the application along with generating the credentials in the permission request file, for across disc access of the local storage.
+
+ ${project.basedir}/../../lib
+
+
org.bouncycastle
diff --git a/pom.xml b/pom.xml
index d6d872d..6de9a69 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,8 +28,8 @@
org.ps5jb.loader.LoaderXlet
-
- 1.1.1
+
+ 1.1.2
9025
@@ -81,25 +81,25 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.11.1-SNAPSHOT
+ 3.13.0
org.apache.maven.plugins
maven-clean-plugin
- 3.3.2
+ 3.4.0
org.apache.maven.plugins
maven-assembly-plugin
- 3.6.0
+ 3.7.1
org.apache.maven.plugins
maven-dependency-plugin
- 3.6.1
+ 3.8.0
@@ -114,7 +114,7 @@
org.apache.maven.plugins
maven-jar-plugin
- 3.3.0
+ 3.4.2
@@ -130,7 +130,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.6.0
+ 3.10.0
@@ -142,7 +142,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.5.1
+ 3.6.0
false
@@ -151,7 +151,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.2.1
+ 3.5.0
true
@@ -161,13 +161,13 @@
org.codehaus.mojo
exec-maven-plugin
- 3.1.0
+ 3.4.1
org.codehaus.mojo
versions-maven-plugin
- 2.16.1
+ 2.17.1
false
@@ -175,17 +175,4 @@
-
-
-
-
- apache-snapshots
- Apache Snapshots
- https://repository.apache.org/content/repositories/snapshots/
-
- true
-
-
-
-
\ No newline at end of file
diff --git a/sdk/src/main/java/org/ps5jb/sdk/core/Pointer.java b/sdk/src/main/java/org/ps5jb/sdk/core/Pointer.java
index 69f8d4d..a837a3b 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/core/Pointer.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/core/Pointer.java
@@ -115,6 +115,7 @@ public static Pointer fromString(String string) {
* native string is null-terminated.
*
* @param string String to convert to a native null-terminated string.
+ * @param charset Character set to use to convert from native bytes to a Java string.
* @return Pointer to the allocated buffer.
* @throws OutOfMemoryError if the allocation is refused by the system.
*/
@@ -212,6 +213,7 @@ public Pointer(long addr) {
* Constructor of a pointer where the size is known.
*
* @param addr Memory address of the pointer.
+ * @param size Size of the memory.
*/
public Pointer(long addr, Long size) {
this.addr = addr;
@@ -301,6 +303,7 @@ public long read8() {
/**
* Read the given number of bytes from the address pointed to by this pointer instance.
*
+ * @param size Number of bytes to read.
* @return Value read from the memory as an array of bytes.
*/
public byte[] read(int size) {
@@ -507,6 +510,23 @@ public void writeString(String string) {
writeString(0, string, Charset.defaultCharset().name());
}
+ /**
+ * Copies values in native memory associated with this pointer to a pointer specified by dest
.
+ *
+ * @param dest Pointer to copy the data to. The data will always be copied starting at offset 0 in dest
.
+ * @param offset Offset in this memory to read the data from.
+ * @param size Size of data to copy.
+ * @throws IndexOutOfBoundsException If the read or the write beyond one of the two pointers' sizes occurs.
+ */
+ public void copyTo(Pointer dest, long offset, int size) {
+ overflow(this, offset, size);
+ overflow(dest, 0, size);
+
+ byte[] data = new byte[size];
+ read(offset, data, 0, size);
+ dest.write(0, data, 0, size);
+ }
+
/**
* Free the native memory associated with this pointer.
*/
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/PThread.java b/sdk/src/main/java/org/ps5jb/sdk/include/PThread.java
new file mode 100644
index 0000000..a04da8c
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/PThread.java
@@ -0,0 +1,32 @@
+package org.ps5jb.sdk.include;
+
+import org.ps5jb.sdk.include.sys.ErrNo;
+import org.ps5jb.sdk.include.sys.pthreadtypes.PThreadType;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/pthread.h
from FreeBSD source.
+ */
+public class PThread {
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public PThread(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ /**
+ * Get thread ID of the calling thread.
+ *
+ * @return Thread ID of the calling thread.
+ */
+ public PThreadType self() {
+ return new PThreadType(libKernel.pthread_self());
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/PThreadNp.java b/sdk/src/main/java/org/ps5jb/sdk/include/PThreadNp.java
new file mode 100644
index 0000000..6035dea
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/PThreadNp.java
@@ -0,0 +1,46 @@
+package org.ps5jb.sdk.include;
+
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.core.SdkRuntimeException;
+import org.ps5jb.sdk.include.sys.ErrNo;
+import org.ps5jb.sdk.include.sys.errno.NotFoundException;
+import org.ps5jb.sdk.include.sys.pthreadtypes.PThreadType;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/pthread_np.h
from FreeBSD source.
+ */
+public class PThreadNp {
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public PThreadNp(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ /**
+ * Sets internal name for thread specified by tid argument
+ * to string value specified by name argument.
+ *
+ * @param tid Thread to rename.
+ * @param name New thread name.
+ * @throws NotFoundException Thread with given tid not found.
+ */
+ public void rename(PThreadType tid, String name) throws NotFoundException {
+ int ret = libKernel.pthread_rename_np(tid.getPthread(), name);
+ if (ret != 0) {
+ SdkException ex = errNo.getLastException(getClass(), "pthread_rename_np");
+ if (ex instanceof NotFoundException) {
+ throw (NotFoundException) ex;
+ } else {
+ throw new SdkRuntimeException(ex.getMessage(), ex);
+ }
+ }
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/UniStd.java b/sdk/src/main/java/org/ps5jb/sdk/include/UniStd.java
index 4bb9a5c..b784619 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/UniStd.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/UniStd.java
@@ -1,9 +1,14 @@
package org.ps5jb.sdk.include;
+import org.ps5jb.sdk.core.Pointer;
import org.ps5jb.sdk.core.SdkException;
import org.ps5jb.sdk.core.SdkRuntimeException;
+import org.ps5jb.sdk.include.sys.errno.BadFileDescriptorException;
+import org.ps5jb.sdk.include.sys.errno.InvalidValueException;
import org.ps5jb.sdk.include.sys.errno.OperationNotPermittedException;
import org.ps5jb.sdk.include.sys.ErrNo;
+import org.ps5jb.sdk.include.sys.errno.OutOfMemoryException;
+import org.ps5jb.sdk.include.sys.rtprio.RtPrioType;
import org.ps5jb.sdk.lib.LibKernel;
/**
@@ -38,4 +43,38 @@ public void setuid(int uid) throws OperationNotPermittedException {
}
}
}
+
+ public int getpid() {
+ return libKernel.getpid();
+ }
+
+ public int[] pipe() throws SdkException {
+ Pointer fildes = Pointer.calloc(8);
+ try {
+ int ret = libKernel.pipe(fildes);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "pipe");
+ }
+
+ return new int[] { fildes.read4(), fildes.read4(4) };
+ } finally {
+ fildes.free();
+ }
+ }
+
+ public void ftruncate(int fd, long length) throws InvalidValueException, BadFileDescriptorException, OutOfMemoryException {
+ int ret = libKernel.ftruncate(fd, length);
+ if (ret == -1) {
+ SdkException ex = errNo.getLastException(getClass(), "ftruncate");
+ if (ex instanceof InvalidValueException) {
+ throw (InvalidValueException) ex;
+ } else if (ex instanceof BadFileDescriptorException) {
+ throw (BadFileDescriptorException) ex;
+ } else if (ex instanceof OutOfMemoryException) {
+ throw (OutOfMemoryException) ex;
+ } else {
+ throw new SdkRuntimeException(ex.getMessage(), ex);
+ }
+ }
+ }
}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/machine/Param.java b/sdk/src/main/java/org/ps5jb/sdk/include/machine/Param.java
new file mode 100644
index 0000000..4fb775e
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/machine/Param.java
@@ -0,0 +1,23 @@
+package org.ps5jb.sdk.include.machine;
+
+/**
+ * This class represents include/machine/param.h
from FreeBSD source.
+ */
+public class Param {
+ public static final long PHYS_PAGE_SHIFT = 12L;
+ public static final long PHYS_PAGE_SIZE = 1L << PHYS_PAGE_SHIFT;
+ public static final long PHYS_PAGE_MASK = PHYS_PAGE_SIZE - 1L;
+ public static final long PAGE_SHIFT = 14L;
+ public static final long PAGE_SIZE = 1L << PAGE_SHIFT;
+ public static final long PAGE_MASK = PAGE_SIZE - 1L;
+
+ public static final long KSTACK_PAGES = 1L;
+
+ public static long atop(long x) {
+ return x >> PAGE_SHIFT;
+ }
+
+ public static long ptoa(long x) {
+ return x << PAGE_SHIFT;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/CpuSet.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/CpuSet.java
index 587f70c..8c0d647 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/CpuSet.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/CpuSet.java
@@ -1,6 +1,7 @@
package org.ps5jb.sdk.include.sys;
import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.core.SdkRuntimeException;
import org.ps5jb.sdk.include.sys.cpuset.CpuLevelType;
import org.ps5jb.sdk.include.sys.cpuset.CpuSetType;
import org.ps5jb.sdk.include.sys.cpuset.CpuWhichType;
@@ -23,10 +24,33 @@ public CpuSet(LibKernel libKernel) {
this.errNo = new ErrNo(this.libKernel);
}
+ public CpuSetType getAffinity(CpuLevelType cpuLevel, CpuWhichType cpuWhich, int id) throws SdkException {
+ CpuSetType result = new CpuSetType();
+ try {
+ int ret = libKernel.cpuset_getaffinity(cpuLevel.value(), cpuWhich.value(), id, result.getSize(), result.getPointer());
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "getAffinity");
+ }
+ result.refresh();
+ return result;
+ } catch (SdkException | SdkRuntimeException e) {
+ result.free();
+ throw e;
+ }
+ }
+
public void setAffinity(CpuLevelType cpuLevel, CpuWhichType cpuWhich, int id, CpuSetType cpuSetType) throws SdkException {
int ret = libKernel.cpuset_setaffinity(cpuLevel.value(), cpuWhich.value(), id, cpuSetType.getSize(), cpuSetType.getPointer());
if (ret == -1) {
throw errNo.getLastException(getClass(), "setAffinity");
}
}
+
+ public CpuSetType getCurrentThreadAffinity() throws SdkException {
+ return getAffinity(CpuLevelType.CPU_LEVEL_WHICH, CpuWhichType.CPU_WHICH_TID, -1);
+ }
+
+ public void setCurrentThreadAffinity(CpuSetType affinity) throws SdkException {
+ setAffinity(CpuLevelType.CPU_LEVEL_WHICH, CpuWhichType.CPU_WHICH_TID, -1, affinity);
+ }
}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/ErrNo.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/ErrNo.java
index 9509b6b..f9c7a49 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/ErrNo.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/ErrNo.java
@@ -1,12 +1,16 @@
package org.ps5jb.sdk.include.sys;
+import java.util.Arrays;
+
import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.include.sys.errno.BadFileDescriptorException;
import org.ps5jb.sdk.include.sys.errno.DeadlockException;
import org.ps5jb.sdk.include.sys.errno.InvalidSizeException;
import org.ps5jb.sdk.include.sys.errno.InvalidValueException;
import org.ps5jb.sdk.include.sys.errno.MemoryFaultException;
import org.ps5jb.sdk.include.sys.errno.NotFoundException;
import org.ps5jb.sdk.include.sys.errno.OperationNotPermittedException;
+import org.ps5jb.sdk.include.sys.errno.OutOfMemoryException;
import org.ps5jb.sdk.lib.LibKernel;
import org.ps5jb.sdk.res.ErrorMessages;
@@ -215,6 +219,23 @@ public class ErrNo {
EOWNERDEAD
};
+ /**
+ * Returns the numeric value from the string error constant.
+ *
+ * @param errNo One of the error constants defined in this class.
+ * @return Numeric value for the error constant. If constant cannot be found, 0 is returned.
+ */
+ public static int ord(String errNo) {
+ int result = 0;
+ for (int i = 0; i < errorCodes.length; ++i) {
+ if (errorCodes[i].equals(errNo)) {
+ result = i + 1;
+ break;
+ }
+ }
+ return result;
+ }
+
private final LibKernel libKernel;
/**
@@ -291,6 +312,10 @@ public SdkException getLastException(Class clazz, String keySuffix, Object ... f
result = new InvalidSizeException(errorMessage);
} else if (lastError == ErrNo.EPERM || lastError == ErrNo.EACCES) {
result = new OperationNotPermittedException(errorMessage);
+ } else if (lastError == ErrNo.EBADF) {
+ result = new BadFileDescriptorException(errorMessage);
+ } else if (lastError == ErrNo.ENOMEM) {
+ result = new OutOfMemoryException(errorMessage);
} else {
result = new SdkException(ErrorMessages.getClassErrorMessage(clazz, errorMessageKey, lastError));
}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/IocCom.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/IocCom.java
new file mode 100644
index 0000000..18a2fac
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/IocCom.java
@@ -0,0 +1,50 @@
+package org.ps5jb.sdk.include.sys;
+
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.include.sys.fcntl.OpenFlag;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/sys/ioccom.h
from FreeBSD source.
+ */
+public class IocCom {
+ /** Number of bits for ioctl size. */
+ public static final long IOCPARM_SHIFT = 13;
+ public static final long IOCPARM_MASK = (1 << IOCPARM_SHIFT) - 1;
+
+ /** No parameters. */
+ public static final long IOC_VOID = 0x20000000;
+ /** Copy out parameters. */
+ public static final long IOC_OUT = 0x40000000;
+ /** Copy in parameters. */
+ public static final long IOC_IN = 0x80000000;
+
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public IocCom(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ public static long _IOC(long inout, long group, long num, long len) {
+ return inout | ((len & IOCPARM_MASK) << 16) | (group << 8) | num;
+ }
+
+ public static long _IOW(long group, long num, long type_size) {
+ return _IOC(IOC_IN, group, num, type_size);
+ }
+
+ public int ioctl(int fd, long request, long argp) throws SdkException {
+ int ret = libKernel.ioctl(fd, request, argp);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "ioctl");
+ }
+ return ret;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/MMan.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/MMan.java
new file mode 100644
index 0000000..8293b4b
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/MMan.java
@@ -0,0 +1,139 @@
+package org.ps5jb.sdk.include.sys;
+
+import org.ps5jb.sdk.core.Pointer;
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.core.SdkRuntimeException;
+import org.ps5jb.sdk.include.sys.errno.InvalidValueException;
+import org.ps5jb.sdk.include.sys.errno.MemoryFaultException;
+import org.ps5jb.sdk.include.sys.errno.OperationNotPermittedException;
+import org.ps5jb.sdk.include.sys.fcntl.OpenFlag;
+import org.ps5jb.sdk.include.sys.mman.MappingFlag;
+import org.ps5jb.sdk.include.sys.mman.ProtectionFlag;
+import org.ps5jb.sdk.include.sys.rtprio.RtPrioType;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/sys/mman.h
from FreeBSD source.
+ */
+public class MMan {
+ /** Constant used internally to create anonymous shared memory. */
+ private static final Pointer SHM_ANON = Pointer.valueOf(1);
+ /** Constant used internally to check for error when mapping memory. */
+ private static final Pointer MAP_FAILED = Pointer.valueOf(-1);
+
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public MMan(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ /**
+ * Opens (or optionally creates) a POSIX shared memory object named path.
+ *
+ * @param path Name of the shared memory.
+ * @param mode The shared memory object is created with mode mode
, subject to the process' umask value.
+ * @param flags An access mode of either {@link OpenFlag#O_RDONLY} or {@link OpenFlag#O_RDWR} must be included in flags.
+ * The optional flags {@link OpenFlag#O_CREAT}, {@link OpenFlag#O_EXCL}, and {@link OpenFlag#O_TRUNC}
+ * may also be specified.
+ * @return Returns a non-negative integer.
+ * @throws SdkException Shared memory opening failed.
+ */
+ public int sharedMemoryOpen(String path, int mode, OpenFlag ... flags) throws SdkException {
+ Pointer pathPtr = Pointer.fromString(path);
+ try {
+ return shmOpen(pathPtr, flags, mode);
+ } finally {
+ pathPtr.free();
+ }
+ }
+
+ /**
+ * Create an anonymous shared memory. In this case, an unnamed shared
+ * memory object is created. Since the object has no name, it cannot be
+ * removed via a subsequent call to {@link #sharedMemoryUnlink(String)}.
+ * Instead, the shared memory object will be garbage collected
+ * when the last reference to the shared memory object is removed.
+ *
+ * @param mode The shared memory object is created with mode mode
,
+ * subject to the process' umask value.
+ * @param flags An access mode of either {@link OpenFlag#O_RDONLY} or {@link OpenFlag#O_RDWR} must be included in flags.
+ * The optional flags {@link OpenFlag#O_CREAT}, {@link OpenFlag#O_EXCL}, and {@link OpenFlag#O_TRUNC}
+ * may also be specified.
+ * @return Returns a non-negative integer.
+ * @throws SdkException Shared memory opening failed.
+ */
+ public int sharedMemoryOpenAnonymous(int mode, OpenFlag ... flags) throws SdkException {
+ return shmOpen(SHM_ANON, flags, mode);
+ }
+
+ private int shmOpen(Pointer path, OpenFlag[] flags, int mode) throws SdkException {
+ int ret = this.libKernel.shm_open(path, OpenFlag.or(flags), mode);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "shmOpen");
+ }
+
+ return ret;
+ }
+
+ /**
+ * Removes a shared memory object named path.
+ *
+ * @param path Path to remove.
+ * @throws MemoryFaultException The path argument points outside the process' allocated address space.
+ * @throws OperationNotPermittedException The required permissions are denied. This function
+ * requires write permission to the shared memory object.
+ * @throws SdkException Shared memory removal failed.
+ */
+ public void sharedMemoryUnlink(String path) throws SdkException {
+ Pointer pathPtr = Pointer.fromString(path);
+ try {
+ int ret = this.libKernel.shm_unlink(pathPtr);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "sharedMemoryUnlink");
+ }
+ } finally {
+ pathPtr.free();
+ }
+ }
+
+ public Pointer memoryMap(Pointer addr, long len, ProtectionFlag[] prot, MappingFlag[] flags, int fd, long offset) throws SdkException {
+ Pointer ret = this.libKernel.mmap(addr, len, ProtectionFlag.or(prot), MappingFlag.or(flags), fd, offset);
+ if (MAP_FAILED.equals(ret)) {
+ throw errNo.getLastException(getClass(), "memoryMap");
+ }
+ return ret;
+ }
+
+ public void memoryUnmap(Pointer addr, long len) throws InvalidValueException {
+ long ret = this.libKernel.munmap(addr, len);
+ if (ret == -1) {
+ SdkException ex = errNo.getLastException(getClass(), "memoryUnmap");
+ if (ex instanceof InvalidValueException) {
+ throw (InvalidValueException) ex;
+ } else {
+ throw new SdkRuntimeException(ex.getMessage(), ex);
+ }
+ }
+ }
+
+ public void memoryProtect(Pointer addr, long len, ProtectionFlag ... prot) throws InvalidValueException, OperationNotPermittedException {
+ long ret = this.libKernel.mprotect(addr, len, ProtectionFlag.or(prot));
+ if (ret == -1) {
+ SdkException ex = errNo.getLastException(getClass(), "memoryUnmap");
+ if (ex instanceof InvalidValueException) {
+ throw (InvalidValueException) ex;
+ } else if (ex instanceof OperationNotPermittedException) {
+ throw (OperationNotPermittedException) ex;
+ } else {
+ throw new SdkRuntimeException(ex.getMessage(), ex);
+ }
+ }
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/Pipe.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/Pipe.java
new file mode 100644
index 0000000..ecfe8f2
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/Pipe.java
@@ -0,0 +1,24 @@
+package org.ps5jb.sdk.include.sys;
+
+import org.ps5jb.sdk.core.Pointer;
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.include.machine.Param;
+import org.ps5jb.sdk.include.sys.rtprio.RtPrioType;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/sys/pipe.h
from FreeBSD source.
+ */
+public class Pipe {
+ /** Pipe buffer size, keep moderate in value, pipes take kva space. */
+ public static final long PIPE_SIZE = 16384;
+
+ public static final long BIG_PIPE_SIZE = 64 * 1024;
+
+ public static final long SMALL_PIPE_SIZE = Param.PAGE_SIZE;
+
+ /** PIPE_MINDIRECT MUST be smaller than PIPE_SIZE and MUST be bigger than PIPE_BUF. */
+ public static final long PIPE_MINDIRECT = 8192;
+
+ public static final long PIPENPAGES = (BIG_PIPE_SIZE / Param.PAGE_SIZE + 1);
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/RtPrio.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/RtPrio.java
new file mode 100644
index 0000000..a757ae9
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/RtPrio.java
@@ -0,0 +1,53 @@
+package org.ps5jb.sdk.include.sys;
+
+import org.ps5jb.sdk.core.Pointer;
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.include.sys.rtprio.RtPrioType;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/sys/rtprio.h
from FreeBSD source.
+ */
+public class RtPrio {
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public RtPrio(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ public org.ps5jb.sdk.include.sys.rtprio.RtPrio lookupRtPrio(int lwpid) throws SdkException {
+ Pointer buf = Pointer.calloc(4);
+ try {
+ int ret = libKernel.rtprio_thread(org.ps5jb.sdk.include.sys.rtprio.RtPrio.RTP_LOOKUP, lwpid, buf);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "lookupRtPrio");
+ }
+
+ return new org.ps5jb.sdk.include.sys.rtprio.RtPrio(RtPrioType.valueOf(buf.read2()), buf.read2(2));
+ } finally {
+ buf.free();
+ }
+ }
+
+ public void setRtPrio(int lwpid, org.ps5jb.sdk.include.sys.rtprio.RtPrio rtp) throws SdkException {
+ Pointer buf = Pointer.calloc(4);
+ try {
+ buf.write2(rtp.getType().value());
+ buf.write2(2, rtp.getPriority());
+
+ int ret = libKernel.rtprio_thread(org.ps5jb.sdk.include.sys.rtprio.RtPrio.RTP_SET, lwpid, buf);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "setRtPrio");
+ }
+ } finally {
+ buf.free();
+ }
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/Umtx.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/Umtx.java
new file mode 100644
index 0000000..f242860
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/Umtx.java
@@ -0,0 +1,57 @@
+package org.ps5jb.sdk.include.sys;
+
+import org.ps5jb.sdk.core.Pointer;
+import org.ps5jb.sdk.core.SdkException;
+import org.ps5jb.sdk.include.sys.errno.NotFoundException;
+import org.ps5jb.sdk.include.sys.fcntl.OpenFlag;
+import org.ps5jb.sdk.include.sys.umtx.UmtxOpcodeType;
+import org.ps5jb.sdk.include.sys.umtx.UmtxShmFlag;
+import org.ps5jb.sdk.lib.LibKernel;
+
+/**
+ * This class represents include/sys/umtx.h
from FreeBSD source.
+ */
+public class Umtx {
+ private final LibKernel libKernel;
+ private final ErrNo errNo;
+
+ /**
+ * Constructor.
+ *
+ * @param libKernel Instance of the 'libkernel' native library wrapper.
+ */
+ public Umtx(LibKernel libKernel) {
+ this.libKernel = libKernel;
+ this.errNo = new ErrNo(this.libKernel);
+ }
+
+ public int userMutexOperation(Pointer obj, UmtxOpcodeType operation, UmtxShmFlag flag, Pointer uaddr, Pointer uaddr2) throws SdkException {
+ int ret = this.libKernel._umtx_op(obj, operation.value(), flag.value(), uaddr, uaddr2);
+ if (ret == -1) {
+ throw errNo.getLastException(getClass(), "userMutexOperation");
+ }
+
+ return ret;
+ }
+
+ public int userMutexCreate(Pointer key) throws SdkException {
+ return userMutexOperation(Pointer.NULL, UmtxOpcodeType.UMTX_OP_SHM, UmtxShmFlag.UMTX_SHM_CREAT, key, Pointer.NULL);
+ }
+
+ /**
+ * Find the shared memory object by key.
+ *
+ * @param key Key of the shared memory object for find.
+ * @return Found shared memory object.
+ *
+ * @throws NotFoundException If the key is not found.
+ * @throws SdkException If the lookup operation failed.
+ */
+ public int userMutexLookup(Pointer key) throws SdkException {
+ return userMutexOperation(Pointer.NULL, UmtxOpcodeType.UMTX_OP_SHM, UmtxShmFlag.UMTX_SHM_LOOKUP, key, Pointer.NULL);
+ }
+
+ public int userMutexDestroy(Pointer key) throws SdkException {
+ return userMutexOperation(Pointer.NULL, UmtxOpcodeType.UMTX_OP_SHM, UmtxShmFlag.UMTX_SHM_DESTROY, key, Pointer.NULL);
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/bitset/BitSetType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/bitset/BitSetType.java
index 1227923..e5e41b1 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/bitset/BitSetType.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/bitset/BitSetType.java
@@ -23,9 +23,7 @@ public BitSetType(Pointer pointer, int size) {
this.ptr = pointer;
this.__bitset_words = (size + (_BITSET_BITS - 1)) / _BITSET_BITS;
this.__bits = new long[this.__bitset_words];
- for (int i = 0; i < this.__bitset_words; ++i) {
- this.__bits[i] = ptr.read8(i * 8);
- }
+ this.refresh();
}
private long __bitset_mask(int n) {
@@ -101,7 +99,7 @@ public void zero() {
/**
* Counts the number of set bits.
*
- * @return
+ * @return Number of set bits.
*/
public int getCount() {
int count = 0;
@@ -119,4 +117,22 @@ public int getCount() {
public Pointer getPointer() {
return this.ptr;
}
+
+ /**
+ * Updates the value of this bitset in case the native memory was changed externally.
+ */
+ public void refresh() {
+ for (int i = 0; i < this.__bitset_words; ++i) {
+ this.__bits[i] = ptr.read8(i * 8);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < this.__bitset_words; ++i) {
+ sb.append(Long.toHexString(this.__bits[i]));
+ }
+ return sb.toString();
+ }
}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuLevelType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuLevelType.java
index 7933a05..f988b41 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuLevelType.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuLevelType.java
@@ -59,7 +59,7 @@ public static CpuLevelType valueOf(int value) {
}
}
- throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(CpuLevelType.class,"invalidValue",Integer.toString(value)));
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(CpuLevelType.class,"invalidValue", Integer.toString(value)));
}
/**
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuWhichType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuWhichType.java
index fa36b45..ddde405 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuWhichType.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/cpuset/CpuWhichType.java
@@ -68,7 +68,7 @@ public static CpuWhichType valueOf(int value) {
}
}
- throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(CpuWhichType.class,"invalidValue",Integer.toString(value)));
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(CpuWhichType.class,"invalidValue", Integer.toString(value)));
}
/**
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/dirent/DirType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/dirent/DirType.java
index 3afae62..5770087 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/dirent/DirType.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/dirent/DirType.java
@@ -78,7 +78,7 @@ public static DirType valueOf(int value) {
}
}
- throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(DirType.class,"invalidValue",Integer.toString(value)));
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(DirType.class,"invalidValue", Integer.toString(value)));
}
/**
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/BadFileDescriptorException.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/BadFileDescriptorException.java
new file mode 100644
index 0000000..f19d789
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/BadFileDescriptorException.java
@@ -0,0 +1,45 @@
+package org.ps5jb.sdk.include.sys.errno;
+
+import org.ps5jb.sdk.core.SdkException;
+
+/**
+ * Exception corresponding to FreeBSD EBADF
error code.
+ */
+public class BadFileDescriptorException extends SdkException {
+ private static final long serialVersionUID = -6609560787806393785L;
+
+ /**
+ * Default constructor with no message or cause.
+ */
+ public BadFileDescriptorException() {
+ super();
+ }
+
+ /**
+ * Constructor with an error message.
+ *
+ * @param message Message corresponding to the error condition.
+ */
+ public BadFileDescriptorException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor with a cause.
+ *
+ * @param cause Original exception that prompted this exception to be raised.
+ */
+ public BadFileDescriptorException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructor with error message and cause.
+ *
+ * @param message Message corresponding to the error condition.
+ * @param cause Original exception that prompted this exception to be raised.
+ */
+ public BadFileDescriptorException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/OutOfMemoryException.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/OutOfMemoryException.java
new file mode 100644
index 0000000..00b2f37
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/OutOfMemoryException.java
@@ -0,0 +1,45 @@
+package org.ps5jb.sdk.include.sys.errno;
+
+import org.ps5jb.sdk.core.SdkException;
+
+/**
+ * Exception corresponding to FreeBSD ENOMEM
error code.
+ */
+public class OutOfMemoryException extends SdkException {
+ private static final long serialVersionUID = 2381337152984935037L;
+
+ /**
+ * Default constructor with no message or cause.
+ */
+ public OutOfMemoryException() {
+ super();
+ }
+
+ /**
+ * Constructor with an error message.
+ *
+ * @param message Message corresponding to the error condition.
+ */
+ public OutOfMemoryException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor with a cause.
+ *
+ * @param cause Original exception that prompted this exception to be raised.
+ */
+ public OutOfMemoryException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructor with error message and cause.
+ *
+ * @param message Message corresponding to the error condition.
+ * @param cause Original exception that prompted this exception to be raised.
+ */
+ public OutOfMemoryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/package-info.java
index c1437aa..ac13c8e 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/package-info.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/errno/package-info.java
@@ -1,4 +1,4 @@
/**
- * CContains Java data type wrappers for C types declared in FreeBSD include/sys/errno.h
header.
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/errno.h
header.
*/
package org.ps5jb.sdk.include.sys.errno;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/fcntl/OpenFlag.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/fcntl/OpenFlag.java
index a4d199d..caeda76 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/include/sys/fcntl/OpenFlag.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/fcntl/OpenFlag.java
@@ -101,7 +101,7 @@ public static OpenFlag valueOf(int value) {
}
}
- throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(OpenFlag.class,"invalidValue",Integer.toString(value)));
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(OpenFlag.class,"invalidValue", Integer.toString(value)));
}
/**
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/IoVecType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/IoVecType.java
new file mode 100644
index 0000000..b7c4d5e
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/IoVecType.java
@@ -0,0 +1,103 @@
+package org.ps5jb.sdk.include.sys.iovec;
+
+import org.ps5jb.sdk.core.Pointer;
+
+/**
+ * Wrapper for FreeBSD iovec
structure.
+ */
+public class IoVecType {
+ public static final long SIZE = 16L;
+ public static final long OFFSET_BASE = 0;
+ public static final long OFFSET_LENGTH = 8;
+
+ private final Pointer ptr;
+ private final boolean ownPtr;
+
+ /**
+ * IoVecType default constructor.
+ */
+ public IoVecType() {
+ this.ptr = Pointer.calloc(SIZE);
+ this.ownPtr = false;
+ }
+
+ /**
+ * IoVecType constructor from existing pointer.
+ *
+ * @param ptr Existing pointer to native memory containing IoVecType data.
+ */
+ public IoVecType(Pointer ptr) {
+ this.ptr = ptr;
+ this.ownPtr = true;
+ }
+
+ /**
+ * Base address.
+ *
+ * @return Returns the value of iov_base
field of iovec
structure.
+ */
+ public Pointer getBase() {
+ return Pointer.valueOf(this.ptr.read8(OFFSET_BASE));
+ }
+
+ /**
+ * Set base address.
+ *
+ * @param val New base address value.
+ */
+ public void setBase(Pointer val) {
+ this.ptr.write8(OFFSET_BASE, val.addr());
+ }
+
+ /**
+ * Length.
+ *
+ * @return Returns the value of iov_len
field of iovec
structure.
+ */
+ public long getLength() {
+ return this.ptr.read8(OFFSET_LENGTH);
+ }
+
+ /**
+ * Set length.
+ *
+ * @param val New length.
+ */
+ public void setLength(long val) {
+ this.ptr.write8(OFFSET_LENGTH, val);
+ }
+
+ /**
+ * Make sure to free the IoVecType buffer during garbage collection.
+ *
+ * @throws Throwable If finalization failed.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ free();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Frees the native memory needed for the IoVecType, if it was allocated by the constructor.
+ * After free()
is called on such IoVecType,
+ * using this Java wrapper instance will no longer be possible.
+ */
+ public void free() {
+ if (this.ownPtr && this.ptr != null && this.ptr.addr() != 0) {
+ this.ptr.free();
+ }
+ }
+
+ /**
+ * Gets the native memory pointer where this IoVecType's data is stored.
+ *
+ * @return IoVecType memory pointer.
+ */
+ public Pointer getPointer() {
+ return this.ptr;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/package-info.java
new file mode 100644
index 0000000..6d53a28
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/iovec/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/_iovec.h
header.
+ */
+package org.ps5jb.sdk.include.sys.iovec;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/MappingFlag.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/MappingFlag.java
new file mode 100644
index 0000000..caeebe1
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/MappingFlag.java
@@ -0,0 +1,147 @@
+package org.ps5jb.sdk.include.sys.mman;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Constants for memory mapping flags.
+ */
+public final class MappingFlag implements Comparable {
+ /** Map from file (default). */
+ public static final MappingFlag MAP_FILE = new MappingFlag(0x00000, "MAP_FILE");
+ /** Share changes. */
+ public static final MappingFlag MAP_SHARED = new MappingFlag(0x00001, "MAP_SHARED");
+ /** Changes are private. */
+ public static final MappingFlag MAP_PRIVATE = new MappingFlag(0x00002, "MAP_PRIVATE");
+ /** @deprecated Use {@link #MAP_PRIVATE}. */
+ @Deprecated
+ public static final MappingFlag MAP_COPY = new MappingFlag(MAP_PRIVATE.value(), "MAP_COPY");
+ /** Map addr must be exactly as requested. */
+ public static final MappingFlag MAP_FIXED = new MappingFlag(0x00010, "MAP_FIXED");
+ /** Region may contain semaphores. */
+ public static final MappingFlag MAP_HASSEMAPHORE = new MappingFlag(0x00200, "MAP_HASSEMAPHORE");
+ /** Region grows down, like a stack. */
+ public static final MappingFlag MAP_STACK = new MappingFlag(0x00400, "MAP_STACK");
+ /** Page to but do not sync underlying file. */
+ public static final MappingFlag MAP_NOSYNC = new MappingFlag(0x00800, "MAP_NOSYNC");
+ /** Allocated from memory, swap space. */
+ public static final MappingFlag MAP_ANON = new MappingFlag(0x01000, "MAP_ANON");
+ /** For compatibility, same as {@link #MAP_ANON}. */
+ public static final MappingFlag MAP_ANONYMOUS = new MappingFlag(MAP_ANON.value(), "MAP_ANONYMOUS");
+ /** For {@link #MAP_FIXED}, fail if address is used. */
+ public static final MappingFlag MAP_EXCL = new MappingFlag(0x04000, "MAP_EXCL");
+ /** Do not include these pages in a coredump. */
+ public static final MappingFlag MAP_NOCORE = new MappingFlag(0x20000, "MAP_NOCORE");
+ /** Prefault mapping for reading. */
+ public static final MappingFlag MAP_PREFAULT_READ = new MappingFlag(0x40000, "MAP_PREFAULT_READ");
+ /** Map in the low 2GB of address space (kernel-mode only flag). */
+ public static final MappingFlag MAP_32BIT = new MappingFlag(0x80000, "MAP_32BIT");
+
+ /** All possible MappingFlag values. */
+ private static final MappingFlag[] values = new MappingFlag[] {
+ MAP_FILE,
+ MAP_SHARED,
+ MAP_PRIVATE,
+ MAP_COPY,
+ MAP_FIXED,
+ MAP_HASSEMAPHORE,
+ MAP_STACK,
+ MAP_NOSYNC,
+ MAP_ANON,
+ MAP_ANONYMOUS,
+ MAP_EXCL,
+ MAP_NOCORE,
+ MAP_PREFAULT_READ,
+ MAP_32BIT
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private MappingFlag(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for MappingFlags.
+ *
+ * @return Array of MappingFlag possible values.
+ */
+ public static MappingFlag[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a MappingFlag constant.
+ *
+ * @param value Number to convert
+ * @return MappingFlag constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any MappingFlag.
+ */
+ public static MappingFlag valueOf(int value) {
+ for (MappingFlag openFlag : values) {
+ if (value == openFlag.value()) {
+ return openFlag;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(MappingFlag.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ /**
+ * Combines an array of flags using a bitwise OR operator.
+ *
+ * @param flags Flags to combine.
+ * @return Result of taking {@link #value()} of each flag and doing a bitwise OR operator on them.
+ */
+ public static int or(MappingFlag... flags) {
+ int result = 0;
+ for (MappingFlag flag : flags) {
+ result |= flag.value;
+ }
+ return result;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((MappingFlag) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof MappingFlag) {
+ result = value == ((MappingFlag) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/ProtectionFlag.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/ProtectionFlag.java
new file mode 100644
index 0000000..d6616e0
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/ProtectionFlag.java
@@ -0,0 +1,116 @@
+package org.ps5jb.sdk.include.sys.mman;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Constants for memory protection flags.
+ */
+public final class ProtectionFlag implements Comparable {
+ /** Pages may not be accessed */
+ public static final ProtectionFlag PROT_NONE = new ProtectionFlag(0x0000, "PROT_NONE");
+ /** Pages may be read */
+ public static final ProtectionFlag PROT_READ = new ProtectionFlag(0x0001, "PROT_READ");
+ /** Pages may be written */
+ public static final ProtectionFlag PROT_WRITE = new ProtectionFlag(0x0002, "PROT_WRITE");
+ /** Pages may be executed */
+ public static final ProtectionFlag PROT_EXEC = new ProtectionFlag(0x0004, "PROT_EXEC");
+
+ /** All possible ProtectionFlag values. */
+ private static final ProtectionFlag[] values = new ProtectionFlag[] {
+ PROT_NONE,
+ PROT_READ,
+ PROT_WRITE,
+ PROT_EXEC
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private ProtectionFlag(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for ProtectionFlag.
+ *
+ * @return Array of ProtectionFlag possible values.
+ */
+ public static ProtectionFlag[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a ProtectionFlag constant.
+ *
+ * @param value Number to convert
+ * @return ProtectionFlag constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any ProtectionFlag.
+ */
+ public static ProtectionFlag valueOf(int value) {
+ for (ProtectionFlag openFlag : values) {
+ if (value == openFlag.value()) {
+ return openFlag;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(ProtectionFlag.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ /**
+ * Combines an array of flags using a bitwise OR operator.
+ *
+ * @param flags Flags to combine.
+ * @return Result of taking {@link #value()} of each flag and doing a bitwise OR operator on them.
+ */
+ public static int or(ProtectionFlag... flags) {
+ int result = 0;
+ for (ProtectionFlag flag : flags) {
+ result |= flag.value;
+ }
+ return result;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((ProtectionFlag) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof ProtectionFlag) {
+ result = value == ((ProtectionFlag) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/package-info.java
new file mode 100644
index 0000000..ffa7f24
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/mman/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/mman.h
header.
+ */
+package org.ps5jb.sdk.include.sys.mman;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/PriorityType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/PriorityType.java
new file mode 100644
index 0000000..a740807
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/PriorityType.java
@@ -0,0 +1,106 @@
+package org.ps5jb.sdk.include.sys.priority;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Process priority specifications.
+ */
+public final class PriorityType implements Comparable {
+ /** Interrupt thread. */
+ public static final PriorityType PRI_ITHD = new PriorityType(1, "PRI_ITHD");
+ /** Real time process. */
+ public static final PriorityType PRI_REALTIME = new PriorityType(2, "PRI_REALTIME");
+ /** Time sharing process. */
+ public static final PriorityType PRI_TIMESHARE = new PriorityType(3, "PRI_TIMESHARE");
+ /** Idle process. */
+ public static final PriorityType PRI_IDLE = new PriorityType(4, "PRI_IDLE");
+
+ public static final PriorityType PRI_FIFO_BIT = new PriorityType(8, "PRI_FIFO_BIT");
+ public static final PriorityType PRI_FIFO = new PriorityType(PRI_FIFO_BIT.value() | PRI_REALTIME.value(), "PRI_FIFO");
+
+ /** All possible PriorityType values. */
+ private static final PriorityType[] values = new PriorityType[] {
+ PRI_ITHD,
+ PRI_REALTIME,
+ PRI_TIMESHARE,
+ PRI_IDLE,
+ PRI_FIFO
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private PriorityType(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for PriorityType.
+ *
+ * @return Array of PriorityType possible values.
+ */
+ public static PriorityType[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a PriorityType constant.
+ *
+ * @param value Number to convert
+ * @return PriorityType constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any PriorityType.
+ */
+ public static PriorityType valueOf(int value) {
+ for (PriorityType priorityType : values) {
+ if (value == priorityType.value()) {
+ return priorityType;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(PriorityType.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((PriorityType) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof PriorityType) {
+ result = value == ((PriorityType) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/package-info.java
new file mode 100644
index 0000000..cb801ca
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/priority/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/priority.h
header.
+ */
+package org.ps5jb.sdk.include.sys.priority;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/PThreadType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/PThreadType.java
new file mode 100644
index 0000000..b0a1fac
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/PThreadType.java
@@ -0,0 +1,26 @@
+package org.ps5jb.sdk.include.sys.pthreadtypes;
+
+import org.ps5jb.sdk.core.Pointer;
+
+/**
+ * Wrapper for FreeBSD pthread_t
structure.
+ */
+public class PThreadType {
+ private Pointer pthread;
+
+ /**
+ * DirEnt constructor.
+ *
+ * @param pthread Native address of pthread_t
structure.
+ */
+ public PThreadType(Pointer pthread) {
+ this.pthread = pthread;
+ }
+
+ /**
+ * @return PThread structure native memory address.
+ */
+ public Pointer getPthread() {
+ return pthread;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/package-info.java
new file mode 100644
index 0000000..d5ed2ad
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/pthreadtypes/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/_pthreadtypes.h
header.
+ */
+package org.ps5jb.sdk.include.sys.pthreadtypes;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrio.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrio.java
new file mode 100644
index 0000000..906e2e7
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrio.java
@@ -0,0 +1,45 @@
+package org.ps5jb.sdk.include.sys.rtprio;
+
+/**
+ * Wrapper for FreeBSD rtprio
structure.
+ */
+public class RtPrio {
+ public static final short RTP_PRIO_MIN = 0;
+ public static final short RTP_PRIO_MAX = 31;
+
+ public static final int RTP_LOOKUP = 0;
+ public static final int RTP_SET = 1;
+
+ private RtPrioType type;
+ private short priority;
+
+ /**
+ * RtPrio constructor.
+ *
+ * @param type Scheduling class.
+ * @param priority Priority value.
+ */
+ public RtPrio(RtPrioType type, short priority) {
+ this.type = type;
+ this.priority = priority;
+ }
+
+ /**
+ * @return Scheduling class.
+ */
+ public RtPrioType getType() {
+ return type;
+ }
+
+ /**
+ * @return Priority value.
+ */
+ public short getPriority() {
+ return priority;
+ }
+
+ @Override
+ public String toString() {
+ return getType().toString() + ": " + getPriority();
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrioType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrioType.java
new file mode 100644
index 0000000..64a4fcd
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/RtPrioType.java
@@ -0,0 +1,104 @@
+package org.ps5jb.sdk.include.sys.rtprio;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Process realtime-priority specifications to rtprio.
+ */
+public final class RtPrioType implements Comparable {
+ /** Real time process. */
+ public static final RtPrioType RTP_PRIO_REALTIME = new RtPrioType((short) 1, "RTP_PRIO_REALTIME");
+ /** Time sharing process. */
+ public static final RtPrioType RTP_PRIO_NORMAL = new RtPrioType((short) 2, "RTP_PRIO_NORMAL");
+ /** Idle process. */
+ public static final RtPrioType RTP_PRIO_IDLE = new RtPrioType((short) 3, "RTP_PRIO_IDLE");
+
+ public static final RtPrioType RTP_PRIO_FIFO_BIT = new RtPrioType((short) 4, "RTP_PRIO_FIFO_BIT");
+ public static final RtPrioType RTP_PRIO_FIFO = new RtPrioType((short) 5, "RTP_PRIO_FIFO");
+
+ /** All possible RtPrioType values. */
+ private static final RtPrioType[] values = new RtPrioType[] {
+ RTP_PRIO_REALTIME,
+ RTP_PRIO_NORMAL,
+ RTP_PRIO_IDLE,
+ RTP_PRIO_FIFO_BIT,
+ RTP_PRIO_FIFO
+ };
+
+ private short value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private RtPrioType(short value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for RtPrioType.
+ *
+ * @return Array of RtPrioType possible values.
+ */
+ public static RtPrioType[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a RtPrioType constant.
+ *
+ * @param value Number to convert
+ * @return RtPrioType constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any CpuWhichType.
+ */
+ public static RtPrioType valueOf(short value) {
+ for (RtPrioType rtPrioType : values) {
+ if (value == rtPrioType.value()) {
+ return rtPrioType;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(RtPrioType.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public short value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((RtPrioType) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof RtPrioType) {
+ result = value == ((RtPrioType) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/package-info.java
new file mode 100644
index 0000000..52e8e18
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/rtprio/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/rtprio.h
header.
+ */
+package org.ps5jb.sdk.include.sys.rtprio;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/stat/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/stat/package-info.java
new file mode 100644
index 0000000..a4e9464
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/stat/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/stat.h
header.
+ */
+package org.ps5jb.sdk.include.sys.stat;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/TimespecType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/TimespecType.java
new file mode 100644
index 0000000..f213fc3
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/TimespecType.java
@@ -0,0 +1,105 @@
+package org.ps5jb.sdk.include.sys.timespec;
+
+import org.ps5jb.sdk.core.Pointer;
+import org.ps5jb.sdk.include.sys.uio.UioReadWrite;
+import org.ps5jb.sdk.include.sys.uio.UioSegmentFlag;
+
+/**
+ * Wrapper for FreeBSD Kernel timespec
structure.
+ */
+public class TimespecType {
+ public static final long SIZE = 16L;
+ public static final long OFFSET_TV_SEC = 0L;
+ public static final long OFFSET_TV_NSEC = 8L;
+
+ private final Pointer ptr;
+ private final boolean ownPtr;
+
+ /**
+ * TimespecType default constructor.
+ */
+ public TimespecType() {
+ this.ptr = Pointer.calloc(SIZE);
+ this.ownPtr = true;
+ }
+
+ /**
+ * TimespecType constructor from existing pointer.
+ *
+ * @param ptr Existing pointer to native memory containing TimespecType data.
+ */
+ public TimespecType(Pointer ptr) {
+ this.ptr = ptr;
+ this.ownPtr = false;
+ }
+
+ /**
+ * Seconds.
+ *
+ * @return Returns the value of tv_sec
field of timespec
structure.
+ */
+ public long getSec() {
+ return this.ptr.read8(OFFSET_TV_SEC);
+ }
+
+ /**
+ * Nanoseconds.
+ *
+ * @return Returns the value of tv_nsec
field of timespec
structure.
+ */
+ public long getNsec() {
+ return this.ptr.read8(OFFSET_TV_NSEC);
+ }
+
+ /**
+ * Set seconds.
+ *
+ * @param val New seconds.
+ */
+ public void setSec(long val) {
+ this.ptr.write8(OFFSET_TV_SEC, val);
+ }
+
+ /**
+ * Set nanoseconds.
+ *
+ * @param val New nanoseconds.
+ */
+ public void setNsec(long val) {
+ this.ptr.write8(OFFSET_TV_NSEC, val);
+ }
+
+ /**
+ * Make sure to free the TimespecType buffer during garbage collection.
+ *
+ * @throws Throwable If finalization failed.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ free();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Frees the native memory needed for the TimespecType, if it was allocated by the constructor.
+ * After free()
is called on such TimespecType,
+ * using this Java wrapper instance will no longer be possible.
+ */
+ public void free() {
+ if (this.ownPtr && this.ptr != null && this.ptr.addr() != 0) {
+ this.ptr.free();
+ }
+ }
+
+ /**
+ * Gets the native memory pointer where this Timespec's data is stored.
+ *
+ * @return Timespec memory pointer.
+ */
+ public Pointer getPointer() {
+ return this.ptr;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/package-info.java
new file mode 100644
index 0000000..02d2454
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timespec/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/timespec.h
header.
+ */
+package org.ps5jb.sdk.include.sys.timespec;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/TimevalType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/TimevalType.java
new file mode 100644
index 0000000..7ae650f
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/TimevalType.java
@@ -0,0 +1,103 @@
+package org.ps5jb.sdk.include.sys.timeval;
+
+import org.ps5jb.sdk.core.Pointer;
+
+/**
+ * Wrapper for FreeBSD Kernel timeval
structure.
+ */
+public class TimevalType {
+ public static final long SIZE = 16L;
+ public static final long OFFSET_TV_SEC = 0L;
+ public static final long OFFSET_TV_USEC = 8L;
+
+ private final Pointer ptr;
+ private final boolean ownPtr;
+
+ /**
+ * TimevalType default constructor.
+ */
+ public TimevalType() {
+ this.ptr = Pointer.calloc(SIZE);
+ this.ownPtr = true;
+ }
+
+ /**
+ * TimevalType constructor from existing pointer.
+ *
+ * @param ptr Existing pointer to native memory containing TimevalType data.
+ */
+ public TimevalType(Pointer ptr) {
+ this.ptr = ptr;
+ this.ownPtr = false;
+ }
+
+ /**
+ * Seconds.
+ *
+ * @return Returns the value of tv_sec
field of timeval
structure.
+ */
+ public long getSec() {
+ return this.ptr.read8(OFFSET_TV_SEC);
+ }
+
+ /**
+ * Microseconds.
+ *
+ * @return Returns the value of tv_usec
field of timeval
structure.
+ */
+ public long getUsec() {
+ return this.ptr.read8(OFFSET_TV_USEC);
+ }
+
+ /**
+ * Set seconds.
+ *
+ * @param val New seconds.
+ */
+ public void setSec(long val) {
+ this.ptr.write8(OFFSET_TV_SEC, val);
+ }
+
+ /**
+ * Set microseconds.
+ *
+ * @param val New microseconds.
+ */
+ public void setUsec(long val) {
+ this.ptr.write8(OFFSET_TV_USEC, val);
+ }
+
+ /**
+ * Make sure to free the TimevalType buffer during garbage collection.
+ *
+ * @throws Throwable If finalization failed.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ free();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Frees the native memory needed for the TimevalType, if it was allocated by the constructor.
+ * After free()
is called on such TimevalType,
+ * using this Java wrapper instance will no longer be possible.
+ */
+ public void free() {
+ if (this.ownPtr && this.ptr != null && this.ptr.addr() != 0) {
+ this.ptr.free();
+ }
+ }
+
+ /**
+ * Gets the native memory pointer where this TimevalType's data is stored.
+ *
+ * @return TimevalType memory pointer.
+ */
+ public Pointer getPointer() {
+ return this.ptr;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/package-info.java
new file mode 100644
index 0000000..5934344
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/timeval/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/_timeval.h
header.
+ */
+package org.ps5jb.sdk.include.sys.timeval;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioReadWrite.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioReadWrite.java
new file mode 100644
index 0000000..741861c
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioReadWrite.java
@@ -0,0 +1,96 @@
+package org.ps5jb.sdk.include.sys.uio;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Uio operation values.
+ */
+public final class UioReadWrite implements Comparable {
+ /** Read operation. */
+ public static final UioReadWrite UIO_READ = new UioReadWrite(0, "UIO_READ");
+ /** Write operation. */
+ public static final UioReadWrite UIO_WRITE = new UioReadWrite(1, "UIO_WRITE");
+
+ /** All possible UioReadWrite values. */
+ private static final UioReadWrite[] values = new UioReadWrite[] {
+ UIO_READ,
+ UIO_WRITE
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private UioReadWrite(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for UioReadWrite.
+ *
+ * @return Array of UioReadWrite possible values.
+ */
+ public static UioReadWrite[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a UioReadWrite constant.
+ *
+ * @param value Number to convert
+ * @return OpenFlag constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any UioReadWrite.
+ */
+ public static UioReadWrite valueOf(int value) {
+ for (UioReadWrite segFlag : values) {
+ if (value == segFlag.value()) {
+ return segFlag;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(UioReadWrite.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((UioReadWrite) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof UioReadWrite) {
+ result = value == ((UioReadWrite) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioSegmentFlag.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioSegmentFlag.java
new file mode 100644
index 0000000..45084c0
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioSegmentFlag.java
@@ -0,0 +1,99 @@
+package org.ps5jb.sdk.include.sys.uio;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Segment flag values.
+ */
+public final class UioSegmentFlag implements Comparable {
+ /** From user data space. */
+ public static final UioSegmentFlag UIO_USERSPACE = new UioSegmentFlag(0, "UIO_USERSPACE");
+ /** From system space. */
+ public static final UioSegmentFlag UIO_SYSSPACE = new UioSegmentFlag(1, "UIO_SYSSPACE");
+ /** Don't copy, already in object. */
+ public static final UioSegmentFlag UIO_NOCOPY = new UioSegmentFlag(2, "UIO_NOCOPY");
+
+ /** All possible UioSegmentFlag values. */
+ private static final UioSegmentFlag[] values = new UioSegmentFlag[] {
+ UIO_USERSPACE,
+ UIO_SYSSPACE,
+ UIO_NOCOPY
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private UioSegmentFlag(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for UioSegmentFlag.
+ *
+ * @return Array of UioSegmentFlag possible values.
+ */
+ public static UioSegmentFlag[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a UioSegmentFlag constant.
+ *
+ * @param value Number to convert
+ * @return OpenFlag constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any UioSegmentFlag.
+ */
+ public static UioSegmentFlag valueOf(int value) {
+ for (UioSegmentFlag segFlag : values) {
+ if (value == segFlag.value()) {
+ return segFlag;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(UioSegmentFlag.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((UioSegmentFlag) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof UioSegmentFlag) {
+ result = value == ((UioSegmentFlag) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioType.java
new file mode 100644
index 0000000..7bbf1c6
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/UioType.java
@@ -0,0 +1,145 @@
+package org.ps5jb.sdk.include.sys.uio;
+
+import org.ps5jb.sdk.core.Pointer;
+
+/**
+ * Wrapper for FreeBSD Kernel uio
structure.
+ */
+public class UioType {
+ public static final long SIZE = 48L;
+ public static final long OFFSET_IOV = 0L;
+ public static final long OFFSET_IOV_COUNT = 8L;
+ public static final long OFFSET_OFFSET = 16L;
+ public static final long OFFSET_RESIDUAL_SIZE = 24L;
+ public static final long OFFSET_SEGMENT_FLAG = 32L;
+ public static final long OFFSET_READ_WRITE = 36L;
+ public static final long OFFSET_OWNER = 40L;
+
+ private final Pointer ptr;
+ private final boolean ownPtr;
+
+ /**
+ * UioType default constructor.
+ */
+ public UioType() {
+ this.ptr = Pointer.calloc(SIZE);
+ this.ownPtr = true;
+ }
+
+ /**
+ * UioType constructor from existing pointer.
+ *
+ * @param ptr Existing pointer to native memory containing UioType data.
+ */
+ public UioType(Pointer ptr) {
+ this.ptr = ptr;
+ this.ownPtr = false;
+ }
+
+ /**
+ * Scatter/gather list.
+ *
+ * @return Returns the value of uio_iov
field of uio
structure,
+ * which is a pointer to a list of {@link org.ps5jb.sdk.include.sys.iovec.IoVecType} structures.
+ */
+ public Pointer getIov() {
+ return Pointer.valueOf(this.ptr.read8(OFFSET_IOV));
+ }
+
+ /**
+ * Length of scatter/gather list.
+ *
+ * @return Returns the value of uio_iovcnt
field of uio
structure.
+ */
+ public int getIovCount() {
+ return this.ptr.read4(OFFSET_IOV_COUNT);
+ }
+
+ /**
+ * Offset in target object.
+ *
+ * @return Returns the value of uio_offset
field of uio
structure.
+ */
+ public long getOffset() {
+ return this.ptr.read8(OFFSET_OFFSET);
+ }
+
+ /**
+ * Remaining bytes to process.
+ *
+ * @return Returns the value of uio_resid
field of uio
structure.
+ */
+ public long getResidualSize() {
+ return this.ptr.read8(OFFSET_RESIDUAL_SIZE);
+ }
+
+ /**
+ * Address space.
+ *
+ * @return Returns the value of uio_segflg
field of uio
structure.
+ */
+ public UioSegmentFlag getSegmentFlag() {
+ return UioSegmentFlag.valueOf(this.ptr.read4(OFFSET_SEGMENT_FLAG));
+ }
+
+ /**
+ * Set address space.
+ *
+ * @param val New length.
+ */
+ public void setSegmentFlag(UioSegmentFlag val) {
+ this.ptr.write4(OFFSET_SEGMENT_FLAG, val.value());
+ }
+
+ /**
+ * Operation.
+ *
+ * @return Returns the value of uio_rw
field of uio
structure.
+ */
+ public UioReadWrite getReadWrite() {
+ return UioReadWrite.valueOf(this.ptr.read4(OFFSET_READ_WRITE));
+ }
+
+ /**
+ * Owner thread.
+ *
+ * @return Returns the value of uio_td
field of uio
structure.
+ */
+ public Pointer getOwner() {
+ return Pointer.valueOf(this.ptr.read8(OFFSET_OWNER));
+ }
+
+ /**
+ * Make sure to free the UioType buffer during garbage collection.
+ *
+ * @throws Throwable If finalization failed.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ free();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Frees the native memory needed for the UioType, if it was allocated by the constructor.
+ * After free()
is called on such UioType,
+ * using this Java wrapper instance will no longer be possible.
+ */
+ public void free() {
+ if (this.ownPtr && this.ptr != null && this.ptr.addr() != 0) {
+ this.ptr.free();
+ }
+ }
+
+ /**
+ * Gets the native memory pointer where this UioType's data is stored.
+ *
+ * @return UioType memory pointer.
+ */
+ public Pointer getPointer() {
+ return this.ptr;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/package-info.java
new file mode 100644
index 0000000..04b4d50
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/uio/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/uio.h
header.
+ */
+package org.ps5jb.sdk.include.sys.uio;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxOpcodeType.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxOpcodeType.java
new file mode 100644
index 0000000..df003f5
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxOpcodeType.java
@@ -0,0 +1,96 @@
+package org.ps5jb.sdk.include.sys.umtx;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * (Partial) op codes for _umtx_op
syscall.
+ */
+public final class UmtxOpcodeType implements Comparable {
+ /**
+ * Manage anonymous POSIX shared memory objects (see shm_open
).
+ * On FreeBSD, the value of this constant is 25
.
+ */
+ public static final UmtxOpcodeType UMTX_OP_SHM = new UmtxOpcodeType(26, "UMTX_OP_SHM");
+
+ /** All possible UmtxOpcodeType values. */
+ private static final UmtxOpcodeType[] values = new UmtxOpcodeType[] {
+ UMTX_OP_SHM
+ };
+
+ private int value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private UmtxOpcodeType(int value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for UmtxOpcodeType.
+ *
+ * @return Array of UmtxOpcodeType possible values.
+ */
+ public static UmtxOpcodeType[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a UmtxOpcodeType constant.
+ *
+ * @param value Number to convert
+ * @return UmtxOpcodeType constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any UmtxOpcodeType.
+ */
+ public static UmtxOpcodeType valueOf(int value) {
+ for (UmtxOpcodeType priorityType : values) {
+ if (value == priorityType.value()) {
+ return priorityType;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(UmtxOpcodeType.class,"invalidValue", Integer.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public int value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.value - ((UmtxOpcodeType) o).value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof UmtxOpcodeType) {
+ result = value == ((UmtxOpcodeType) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxShmFlag.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxShmFlag.java
new file mode 100644
index 0000000..d40f365
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/UmtxShmFlag.java
@@ -0,0 +1,111 @@
+package org.ps5jb.sdk.include.sys.umtx;
+
+import org.ps5jb.sdk.res.ErrorMessages;
+
+/**
+ * Flags for {@link UmtxOpcodeType#UMTX_OP_SHM} opcode.
+ */
+public final class UmtxShmFlag implements Comparable {
+ /**
+ * Creates the anonymous shared memory object. If the object associated with the key already exists,
+ * it is returned instead of creating a new object.
+ */
+ public static final UmtxShmFlag UMTX_SHM_CREAT = new UmtxShmFlag(0x0001, "UMTX_SHM_CREAT");
+ /**
+ * Same as {@link #UMTX_SHM_CREAT}, but if there is no shared memory object associated with the specified key,
+ * an error is returned, and no new object is created.
+ */
+ public static final UmtxShmFlag UMTX_SHM_LOOKUP = new UmtxShmFlag(0x0002, "UMTX_SHM_LOOKUP");
+ /**
+ * De-associates the shared object with the specified key. The object is destroyed after
+ * the last open file descriptor is closed and the last mapping for it is destroyed.
+ */
+ public static final UmtxShmFlag UMTX_SHM_DESTROY = new UmtxShmFlag(0x0004, "UMTX_SHM_DESTROY");
+ /** Checks whether there is a live shared object associated with the supplied key. */
+ public static final UmtxShmFlag UMTX_SHM_ALIVE = new UmtxShmFlag(0x0008, "UMTX_SHM_ALIVE");
+
+ /** All possible UmtxShmFlag values. */
+ private static final UmtxShmFlag[] values = new UmtxShmFlag[] {
+ UMTX_SHM_CREAT,
+ UMTX_SHM_LOOKUP,
+ UMTX_SHM_DESTROY,
+ UMTX_SHM_ALIVE
+ };
+
+ private long value;
+
+ private String name;
+
+ /**
+ * Default constructor. This class should not be instantiated manually,
+ * use provided constants instead.
+ *
+ * @param value Numeric value of this instance.
+ * @param name String representation of the constant.
+ */
+ private UmtxShmFlag(long value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ /**
+ * Get all possible values for UmtxShmFlag.
+ *
+ * @return Array of UmtxShmFlag possible values.
+ */
+ public static UmtxShmFlag[] values() {
+ return values;
+ }
+
+ /**
+ * Convert a numeric value into a UmtxShmFlag constant.
+ *
+ * @param value Number to convert
+ * @return UmtxShmFlag constant corresponding to the given value.
+ * @throws IllegalArgumentException If value does not correspond to any UmtxShmFlag.
+ */
+ public static UmtxShmFlag valueOf(long value) {
+ for (UmtxShmFlag openFlag : values) {
+ if (value == openFlag.value()) {
+ return openFlag;
+ }
+ }
+
+ throw new IllegalArgumentException(ErrorMessages.getClassErrorMessage(UmtxShmFlag.class,"invalidValue", Long.toString(value)));
+ }
+
+ /**
+ * Numeric value of this instance.
+ *
+ * @return Numeric value of the instance.
+ */
+ public long value() {
+ return this.value;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return ((int) this.value) - ((int) ((UmtxShmFlag) o).value);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean result;
+ if (o instanceof UmtxShmFlag) {
+ result = value == ((UmtxShmFlag) o).value;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) value;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/package-info.java b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/package-info.java
new file mode 100644
index 0000000..a1da891
--- /dev/null
+++ b/sdk/src/main/java/org/ps5jb/sdk/include/sys/umtx/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Java data type wrappers for C types declared in FreeBSD include/sys/umtx.h
header.
+ */
+package org.ps5jb.sdk.include.sys.umtx;
diff --git a/sdk/src/main/java/org/ps5jb/sdk/lib/LibKernel.java b/sdk/src/main/java/org/ps5jb/sdk/lib/LibKernel.java
index 0b9c175..c466943 100644
--- a/sdk/src/main/java/org/ps5jb/sdk/lib/LibKernel.java
+++ b/sdk/src/main/java/org/ps5jb/sdk/lib/LibKernel.java
@@ -22,15 +22,35 @@
*/
public class LibKernel extends Library {
private Pointer __error;
+ private Pointer cpuset_getaffinity;
private Pointer cpuset_setaffinity;
private Pointer sceKernelSendNotificationRequest;
private Pointer getuid;
private Pointer setuid;
+ private Pointer getpid;
private Pointer open;
private Pointer close;
private Pointer getdents;
private Pointer stat;
+ private Pointer fstat;
private Pointer sceKernelCheckReachability;
+ private Pointer pthread_rename_np;
+ private Pointer pthread_self;
+ private Pointer rtprio_thread;
+ private Pointer pipe;
+ private Pointer shm_open;
+ private Pointer shm_unlink;
+ private Pointer mmap;
+ private Pointer munmap;
+ private Pointer ftruncate;
+ private Pointer select;
+ private Pointer ioctl;
+ private Pointer read;
+ private Pointer write;
+ private Pointer _umtx_op;
+ private Pointer mprotect;
+ private Pointer sched_yield;
+ private Pointer sceKernelGetCurrentCpu;
/**
* Constructor.
@@ -56,6 +76,31 @@ public int sceKernelSendNotificationRequest(String msg) {
}
}
+ /**
+ * Retrieves the mask from the object specified by level
, which
and id
+ * and stores it in the space provided by mask
.
+ *
+ * @param level One of {@link org.ps5jb.sdk.include.sys.cpuset.CpuLevelType} values.
+ * See FreeBSD documentation for possible combinations of level
and which
.
+ * @param which One of {@link org.ps5jb.sdk.include.sys.cpuset.CpuWhichType} values.
+ * See FreeBSD documentation for possible combinations of level
and which
.
+ * @param id The id of -1 may be used with a which
of
+ * {@link org.ps5jb.sdk.include.sys.cpuset.CpuWhichType#CPU_WHICH_TID CPU_WHICH_TID},
+ * {@link org.ps5jb.sdk.include.sys.cpuset.CpuWhichType#CPU_WHICH_PID CPU_WHICH_PID}, or
+ * {@link org.ps5jb.sdk.include.sys.cpuset.CpuWhichType#CPU_WHICH_CPUSET CPU_WHICH_CPUSET}
+ * to mean the current thread, process, or current thread's cpuset.
+ * @param setsize Size of the native memory allocated by {@link org.ps5jb.sdk.include.sys.cpuset.CpuSetType}.
+ * @param mask Pointer to the native memory allocated by {@link org.ps5jb.sdk.include.sys.cpuset.CpuSetType}.
+ * @return Upon successful completion, the value 0 is returned; otherwise the value -1 is returned
+ * and the global variable {@link ErrNo#errno() errno} is set to indicate the error.
+ */
+ public int cpuset_getaffinity(int level, int which, long id, long setsize, Pointer mask) {
+ if (cpuset_getaffinity == null) {
+ cpuset_getaffinity = addrOf("cpuset_getaffinity");
+ }
+ return (int) call(cpuset_getaffinity, level, which, id, setsize, mask.addr());
+ }
+
/**
* Manipulate the sets of CPUs available to processes, threads, interrupts, jails and other resources.
* These functions may manipulate sets of CPUs that contain many processes or per-object anonymous masks that
@@ -87,7 +132,6 @@ public int cpuset_setaffinity(int level, int which, long id, long setsize, Point
* the initial thread. For the initial theread and non-threaded processes, __errno()
* returns a pointer to a global errno
variable that is compatible with the previous
* definition.
- *
* When a system call detects an error, it returns an integer value indicating faulure (usually -1)
* and sets the variable errno
accordingly. Successful calls never set errno
;
* once set it remains unil another error occurs. it should only be examined after an error.
@@ -131,6 +175,18 @@ public int setuid(int uid) {
return (int) call(setuid, uid);
}
+ /**
+ * Return the process ID of the calling process.
+ *
+ * @return Process ID
+ */
+ public int getpid() {
+ if (getpid == null) {
+ getpid = addrOf("getpid");
+ }
+ return (int) call(getpid);
+ }
+
/**
* Open or create a file for reading, writing or executing.
*
@@ -206,6 +262,22 @@ public int stat(String path, Pointer sb) {
}
}
+ /**
+ * Get status of an open file known by the file descriptor.
+ *
+ * @param fd File descriptor.
+ * @param sb Buffer where the status is stored.
+ * @return Upon successful completion, the value 0 is returned; otherwise the value -1 is returned
+ * and the global variable {@link ErrNo#errno() errno} is set to indicate the error.
+ */
+ public int fstat(int fd, Pointer sb) {
+ if (fstat == null) {
+ fstat = addrOf("fstat");
+ }
+
+ return (int) call(fstat, fd, sb.addr());
+ }
+
public int sceKernelCheckReachability(String path) {
if (sceKernelCheckReachability == null) {
sceKernelCheckReachability = addrOf("sceKernelCheckReachability");
@@ -218,4 +290,144 @@ public int sceKernelCheckReachability(String path) {
buf.free();
}
}
+
+ public int pthread_rename_np(Pointer thread, String name) {
+ if (pthread_rename_np == null) {
+ pthread_rename_np = addrOf("pthread_rename_np");
+ }
+
+ Pointer buf = Pointer.fromString(name);
+ try {
+ return (int) call(pthread_rename_np, thread.addr(), buf.addr());
+ } finally {
+ buf.free();
+ }
+ }
+
+ public Pointer pthread_self() {
+ if (pthread_self == null) {
+ pthread_self = addrOf("pthread_self");
+ }
+
+ return Pointer.valueOf(call(pthread_self));
+ }
+
+ public int rtprio_thread(int function, int lwpid, Pointer rtprio) {
+ if (rtprio_thread == null) {
+ rtprio_thread = addrOf("rtprio_thread");
+ }
+
+ return (int) call(rtprio_thread, function, lwpid, rtprio.addr());
+ }
+
+ public int pipe(Pointer fildes) {
+ if (pipe == null) {
+ pipe = addrOf("pipe");
+ }
+
+ return (int) call(pipe, fildes.addr());
+ }
+
+ public int shm_open(Pointer path, int flags, int mode) {
+ if (shm_open == null) {
+ shm_open = addrOf("shm_open");
+ }
+
+ return (int) call(shm_open, path.addr(), flags, mode);
+ }
+
+ public int shm_unlink(Pointer path) {
+ if (shm_unlink == null) {
+ shm_unlink = addrOf("shm_unlink");
+ }
+
+ return (int) call(shm_unlink);
+ }
+
+ public Pointer mmap(Pointer addr, long len, int prot, int flags, int fd, long offset) {
+ if (mmap == null) {
+ mmap = addrOf("mmap");
+ }
+
+ return Pointer.valueOf(call(mmap, addr.addr(), len, prot, flags, fd, offset));
+ }
+
+ public int munmap(Pointer addr, long len) {
+ if (munmap == null) {
+ munmap = addrOf("munmap");
+ }
+
+ return (int) call(munmap);
+ }
+
+ public int ftruncate(int fd, long length) {
+ if (ftruncate == null) {
+ ftruncate = addrOf("ftruncate");
+ }
+
+ return (int) call(ftruncate, fd, length);
+ }
+
+ public int select(int nfds, Pointer readfds, Pointer writefds, Pointer exceptfds, Pointer timeout) {
+ if (select == null) {
+ select = addrOf("select");
+ }
+
+ return (int) call(select, nfds, readfds.addr(), writefds.addr(), exceptfds.addr(), timeout.addr());
+ }
+
+ public int ioctl(int fd, long request, long argp) {
+ if (ioctl == null) {
+ ioctl = addrOf("ioctl");
+ }
+
+ return (int) call(ioctl, fd, request, argp);
+ }
+
+ public long read(int fd, Pointer buf, long nbytes) {
+ if (read == null) {
+ read = addrOf("read");
+ }
+
+ return (int) call(read, fd, buf.addr(), nbytes);
+ }
+
+ public int write(int fd, Pointer buf, long nbytes) {
+ if (write == null) {
+ write = addrOf("write");
+ }
+
+ return (int) call(write);
+ }
+
+ public int _umtx_op(Pointer obj, int op, long val, Pointer uaddr, Pointer uaddr2) {
+ if (_umtx_op == null) {
+ _umtx_op = addrOf("_umtx_op");
+ }
+
+ return (int) call(_umtx_op, obj.addr(), op, val, uaddr.addr(), uaddr2.addr());
+ }
+
+ public int mprotect(Pointer addr, long len, int prot) {
+ if (mprotect == null) {
+ mprotect = addrOf("mprotect");
+ }
+
+ return (int) call(mprotect, addr.addr(), len, prot);
+ }
+
+ public int sched_yield(long unused) {
+ if (sched_yield == null) {
+ sched_yield = addrOf("sched_yield");
+ }
+
+ return (int) call(sched_yield, unused);
+ }
+
+ public int sceKernelGetCurrentCpu() {
+ if (sceKernelGetCurrentCpu == null) {
+ sceKernelGetCurrentCpu = addrOf("sceKernelGetCurrentCpu");
+ }
+ return (int) call(sceKernelGetCurrentCpu);
+ }
}
diff --git a/xlet/pom.xml b/xlet/pom.xml
index a0f29be..079d4f6 100644
--- a/xlet/pom.xml
+++ b/xlet/pom.xml
@@ -28,14 +28,17 @@
org.ps5jb
bdj-api
+ ${project.parent.version}
org.ps5jb
javatv-api
+ ${project.parent.version}
org.ps5jb
gem-api
+ ${project.parent.version}
org.ps5jb
diff --git a/xlet/src/main/java/org/ps5jb/loader/RemoteLogger.java b/xlet/src/main/java/org/ps5jb/loader/RemoteLogger.java
index 74f456b..98217e6 100644
--- a/xlet/src/main/java/org/ps5jb/loader/RemoteLogger.java
+++ b/xlet/src/main/java/org/ps5jb/loader/RemoteLogger.java
@@ -1,13 +1,10 @@
package org.ps5jb.loader;
-import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
-import java.util.Arrays;
import java.util.StringTokenizer;
/**
diff --git a/xlet/src/main/java/org/ps5jb/loader/Status.java b/xlet/src/main/java/org/ps5jb/loader/Status.java
index a06dd47..bb8978d 100644
--- a/xlet/src/main/java/org/ps5jb/loader/Status.java
+++ b/xlet/src/main/java/org/ps5jb/loader/Status.java
@@ -71,7 +71,7 @@ public static void println(String msg, boolean replaceLast) {
// Remote logger does not seem to work before jailbreak
if (System.getSecurityManager() == null) {
initLogger();
- LOGGER.info(msg);
+ LOGGER.info(finalMsg);
}
}
diff --git a/xploit/src/main/java/org/ps5jb/client/payloads/DumpClasses.java b/xploit/src/main/java/org/ps5jb/client/payloads/DumpClasses.java
index 9b43145..0529c6d 100644
--- a/xploit/src/main/java/org/ps5jb/client/payloads/DumpClasses.java
+++ b/xploit/src/main/java/org/ps5jb/client/payloads/DumpClasses.java
@@ -33,12 +33,12 @@
*
*
* To use, simply send this class to the PS5 for execution in the JAR Loader.
- * Then use nc or another tool to connect to the PS5:
+ * Then use `nc` or another tool to connect to the PS5:
* nc [PS5 IP] 9125 > classpath.zip
*
*
* Upon connection, the classpath will be dumped and sent back to `nc`.
- * Depending on OS `nc` may not terminate by itself. When PS5 reports that
+ * Depending on OS, `nc` may not terminate by itself. When PS5 reports that
* the dump is finished, simply terminate it by force.
*
*/
@@ -208,7 +208,7 @@ protected boolean tryDumpBuiltinClassLoader(ClassLoader cl, Class clClass, ZipOu
OpenModuleAction.execute("java.lang.module.ModuleReference");
OpenModuleAction.execute("jdk.internal.module.SystemModuleFinders");
- // On PS5, stream API is put away in jdk.internal.utl package.
+ // On PS5, stream API is put away in jdk.internal.util package.
// Because of this, all the calls to iterate over modules below have to use reflection.
try {
OpenModuleAction.execute("jdk.internal.util.Optional");
@@ -237,15 +237,12 @@ protected boolean tryDumpBuiltinClassLoader(ClassLoader cl, Class clClass, ZipOu
final ModuleReader mr = mref.open();
try {
- Method listMethod = mr.getClass().getMethod("list", new Class[0]);
- listMethod.setAccessible(true);
+ Method listMethod = getMethod(mr.getClass(), "list", new Class[0]);
- Method openMethod = mr.getClass().getMethod("open", new Class[] { String.class });
- openMethod.setAccessible(true);
+ Method openMethod = getMethod(mr.getClass(), "open", new Class[] { String.class });
Object resourceStream = listMethod.invoke(mr, new Object[0]);
- Method toArrayMethod = resourceStream.getClass().getMethod("toArray", new Class[0]);
- toArrayMethod.setAccessible(true);
+ Method toArrayMethod = getMethod(resourceStream.getClass(), "toArray", new Class[0]);
Object[] resources = (Object[]) toArrayMethod.invoke(resourceStream, new Object[0]);
for (Object res : resources) {
@@ -253,13 +250,11 @@ protected boolean tryDumpBuiltinClassLoader(ClassLoader cl, Class clClass, ZipOu
if (!dumpedEntries.contains(resName)) {
Object isOptional = openMethod.invoke(mr, new Object[] { res });
- Method isPresentMethod = isOptional.getClass().getMethod("isPresent", new Class[0]);
- isPresentMethod.setAccessible(true);
- Method getMethod = isOptional.getClass().getMethod("get", new Class[0]);
- getMethod.setAccessible(true);
+ Method Optional_isPresentMethod = getMethod(isOptional.getClass(), "isPresent", new Class[0]);
+ Method Optional_getMethod = getMethod(isOptional.getClass(), "get", new Class[0]);
- if (((Boolean) isPresentMethod.invoke(isOptional, new Object[0])).booleanValue()) {
- InputStream is = (InputStream) getMethod.invoke(isOptional, new Object[0]);
+ if (((Boolean) Optional_isPresentMethod.invoke(isOptional, new Object[0])).booleanValue()) {
+ InputStream is = (InputStream) Optional_getMethod.invoke(isOptional, new Object[0]);
try {
createZipEntry(is, resName, zip);
dumpedEntries.add(resName);
@@ -287,6 +282,52 @@ protected boolean tryDumpBuiltinClassLoader(ClassLoader cl, Class clClass, ZipOu
return false;
}
+ /**
+ * Returns the method by reflection and makes it accessible. If method is not found,
+ * prints the existing methods of the class for debugging purposes.
+ *
+ * @param cl Class whose method to return.
+ * @param methodName Name of the method.
+ * @param parameterTypes Parameter types of the method.
+ * @return Reflective reference to the method.
+ * @throws NoSuchMethodException If the method could not be found.
+ * @see Class#getMethod(String, Class[])
+ * @see Method#setAccessible(boolean)
+ */
+ protected Method getMethod(Class cl, String methodName, Class[] parameterTypes) throws NoSuchMethodException {
+ try {
+ Method result = cl.getMethod(methodName, new Class[0]);
+ result.setAccessible(true);
+
+ return result;
+ } catch (NoSuchMethodException e) {
+ // Print methods to debug why its not found
+ printClassMethods(cl, "");
+ throw e;
+ }
+ }
+
+ /**
+ * Prints the all the methods of the given class and its descendants.
+ *
+ * @param cl Class whose methods to print.
+ * @param indent Indent to use when printing.
+ */
+ protected void printClassMethods(Class cl, String indent) {
+ Method[] methods = cl.getDeclaredMethods();
+ String nextIndent = indent + " ";
+ if (methods.length > 0) {
+ Status.println(indent + cl.getName() + ":");
+ for (Method method : methods) {
+ Status.println(nextIndent + method.toString());
+ }
+ }
+
+ if (cl.getSuperclass() != null) {
+ printClassMethods(cl.getSuperclass(), nextIndent);
+ }
+ }
+
/**
* Dumps a JarFile to the zip output stream.
*
diff --git a/xploit/src/main/java/org/ps5jb/client/payloads/MiniTennisGame.java b/xploit/src/main/java/org/ps5jb/client/payloads/MiniTennisGame.java
new file mode 100644
index 0000000..8fd1634
--- /dev/null
+++ b/xploit/src/main/java/org/ps5jb/client/payloads/MiniTennisGame.java
@@ -0,0 +1,237 @@
+package org.ps5jb.client.payloads;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+
+import org.dvb.event.EventManager;
+import org.dvb.event.OverallRepository;
+import org.dvb.event.UserEvent;
+import org.dvb.event.UserEventListener;
+import org.havi.ui.HContainer;
+import org.havi.ui.HScene;
+import org.havi.ui.HSceneFactory;
+import org.havi.ui.event.HRcEvent;
+import org.ps5jb.loader.Config;
+import org.ps5jb.loader.Status;
+
+/**
+ * Implementation of a Mini-Tennis game on PS5. Originally from:
+ * Edu4Java .
+ */
+public class MiniTennisGame extends HContainer implements Runnable, UserEventListener {
+ private static final int RACQUET_WIDTH = 150;
+ private static final int RACQUET_HEIGHT = 10;
+ private static final int RAQUET_SPEED = 10;
+
+ private static final int BALL_DIAMETER = 30;
+ private static int BALL_SPEED = 15;
+
+ /** Ball x position */
+ private int x = 0;
+ /** Ball y position */
+ private int y = 0;
+ /** Ball horizontal shift per frame */
+ int xa = BALL_DIAMETER / BALL_SPEED;
+ /** Ball vertical shift per frame */
+ int ya = BALL_DIAMETER / BALL_SPEED;
+
+ /** Raquet x position */
+ int rx = 0;
+ /** Raquet horizontal shift per frame */
+ int rxa = 0;
+ /** Raquet y position */
+ int ry = 0;
+
+ /** Indicates whether to terminate the game */
+ private boolean terminated = false;
+
+ /** Indicates that the ball did not hit the raquet and game is over */
+ private boolean isGameOver = false;
+
+ /** Start time of the current game round. */
+ private long startTime;
+
+ /** All the rendering happens into this image off-screen. Then the main rendering loop just shows this image. */
+ private BufferedImage offscreenBuffer;
+ /** Graphics object associated with the off-screen buffer. */
+ private Graphics2D offscreenGraphics;
+ /** Scale of the off-screen buffer. The final image is scaled to 1 to simulate anti-aliasing. */
+ private int offscreenScale = 3;
+
+ /** Game entry point. */
+ @Override
+ public void run() {
+ EventManager.getInstance().addUserEventListener(this, new OverallRepository());
+ try {
+ setSize(Config.getLoaderResolutionWidth(), Config.getLoaderResolutionHeight());
+ setBackground(Color.darkGray);
+ setForeground(Color.lightGray);
+ setVisible(true);
+
+ HScene scene = HSceneFactory.getInstance().getDefaultHScene();
+ scene.add(this, BorderLayout.CENTER, 0);
+ try {
+ scene.validate();
+
+ Graphics2D g2d = (Graphics2D) getGraphics();
+ offscreenBuffer = g2d.getDeviceConfiguration().createCompatibleImage(offscreenScale * getWidth(), offscreenScale * getHeight());
+ offscreenGraphics = offscreenBuffer.createGraphics();
+ try {
+ startTime = System.currentTimeMillis();
+ while (!terminated) {
+ moveBall();
+ moveRacquet();
+ repaint();
+
+ try {
+ Thread.sleep(isGameOver ? 5000L : 10);
+ } catch (InterruptedException e) {
+ Status.printStackTrace(e.getMessage(), e);
+ terminated = true;
+ }
+
+ if (isGameOver) {
+ x = 0;
+ y = 0;
+ xa = BALL_DIAMETER / BALL_SPEED;
+ ya = BALL_DIAMETER / BALL_SPEED;
+ rx = 0;
+ rxa = 0;
+ ry = 0;
+ isGameOver = false;
+ startTime = System.currentTimeMillis();
+ BALL_SPEED = 15;
+ } else {
+ BALL_SPEED = Math.max(5, 15 - (int) ((System.currentTimeMillis() - startTime) / 1000 / 10));
+ }
+ }
+ } finally {
+ setVisible(false);
+ scene.remove(this);
+ }
+ } finally {
+ if (offscreenGraphics != null) {
+ offscreenGraphics.dispose();
+ }
+ }
+ } finally {
+ EventManager.getInstance().removeUserEventListener(this);
+ }
+
+ Status.println("Mini-Tennis Terminated");
+ }
+
+ /**
+ * Paint a scaled image of this container using the given Graphics object.
+ *
+ * @param g Graphics to use for paining.
+ * @param scale Scale at which to paint.
+ */
+ private synchronized void paintTo(Graphics g, int scale) {
+ g.setColor(getBackground());
+ g.fillRect(0, 0, scale * getWidth(), scale * getHeight());
+
+ g.setColor(getForeground());
+ g.fillOval(scale * x, scale * y, scale * BALL_DIAMETER, scale * BALL_DIAMETER);
+ g.fillRect(scale * rx, scale * ry, scale * RACQUET_WIDTH, scale * RACQUET_HEIGHT);
+
+ if (isGameOver) {
+ g.setColor(Color.red);
+ g.setFont(new Font(null, Font.BOLD, scale * 25));
+
+ String text = "Game over, restarting in 5 seconds unless RED button is pressed...";
+ int height = g.getFontMetrics().getHeight();
+ int width = g.getFontMetrics().stringWidth(text);
+ g.drawString(text, (scale * getWidth() - width) / 2, (scale * getHeight() - height) / 2);
+ }
+ }
+
+ /**
+ * Paint this component with the given Graphics object.
+ *
+ * @param g Graphics to paint with.
+ */
+ @Override
+ public synchronized void paint(Graphics g) {
+ paintTo(offscreenGraphics, offscreenScale);
+ g.drawImage(offscreenBuffer, 0, 0, getWidth(), getHeight(), 0, 0, offscreenBuffer.getWidth(), offscreenBuffer.getHeight(), null);
+ }
+
+ /**
+ * Move th ball position.
+ */
+ private void moveBall() {
+ if (x + xa < 0)
+ xa = BALL_DIAMETER / BALL_SPEED;
+ if (x + xa > getWidth() - BALL_DIAMETER)
+ xa = -(BALL_DIAMETER / BALL_SPEED);
+ if (y + ya < 0)
+ ya = BALL_DIAMETER / BALL_SPEED;
+ if (y + ya > getHeight() - BALL_DIAMETER)
+ isGameOver = true;
+ if (isCollision()) {
+ ya = -(BALL_DIAMETER / BALL_SPEED);
+ y = ry - BALL_DIAMETER;
+ }
+ x = Math.min(x + xa, getWidth() - BALL_DIAMETER);
+ y = Math.min(y + ya, getHeight() - BALL_DIAMETER);
+ }
+
+ /**
+ * Move the raquet position based on whether user key is pressed or no.
+ */
+ public void moveRacquet() {
+ ry = getHeight() - 50;
+
+ if (rx + rxa > 0 && rx + rxa < getWidth() - RACQUET_WIDTH)
+ rx = rx + rxa;
+ }
+
+ /**
+ * Check if the ball collided with the racquet.
+ *
+ * @return True of ball has collided with the racquet.
+ */
+ private boolean isCollision() {
+ Rectangle rBounds = new Rectangle(rx, ry, RACQUET_WIDTH, RACQUET_HEIGHT);
+ Rectangle bBounds = new Rectangle(x, y, BALL_DIAMETER, BALL_DIAMETER);
+
+ return rBounds.intersects(bBounds);
+ }
+
+ /**
+ * Handler for key press events.
+ *
+ * @param userEvent Event associated with user pressing/de-pressing the controller buttons.
+ */
+ @Override
+ public void userEventReceived(UserEvent userEvent) {
+ if (userEvent.getFamily() == UserEvent.UEF_KEY_EVENT) {
+ if (userEvent.getType() == HRcEvent.KEY_PRESSED) {
+ switch (userEvent.getCode()) {
+ case HRcEvent.VK_LEFT:
+ rxa = -(RACQUET_WIDTH / RAQUET_SPEED);
+ break;
+ case HRcEvent.VK_RIGHT:
+ rxa = (RACQUET_WIDTH / RAQUET_SPEED);
+ break;
+ }
+ } else if (userEvent.getType() == HRcEvent.KEY_RELEASED) {
+ switch (userEvent.getCode()) {
+ case HRcEvent.VK_LEFT:
+ case HRcEvent.VK_RIGHT:
+ rxa = 0;
+ break;
+ case HRcEvent.VK_COLORED_KEY_0:
+ terminated = true;
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpServer.java b/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpServer.java
index e781ec0..ad9b28a 100644
--- a/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpServer.java
+++ b/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpServer.java
@@ -24,8 +24,10 @@ of this software and associated documentation files (the "Software"), to deal
package org.ps5jb.client.payloads.ftp;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.Socket;
import java.net.SocketException;
+import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -37,13 +39,13 @@ of this software and associated documentation files (the "Software"), to deal
import org.havi.ui.event.HRcEvent;
import org.ps5jb.loader.SocketListener;
import org.ps5jb.loader.Status;
+import org.ps5jb.sdk.core.OpenModuleAction;
/**
* A very simple FTP Server class. On receiving a new connection it creates a
* new worker thread.
*
* @author Moritz Stueckler
- *
*/
public class FtpServer extends SocketListener implements UserEventListener {
private List workers;
@@ -85,8 +87,42 @@ public void acceptClient(Socket clientSocket) throws Exception {
w.start();
}
+ /**
+ * PS5 BDJ runtime includes a mechanism to proxy all instances of key I/O classes
+ * such as {@link java.io.File} to restrict access to sensitive information.
+ * This method disables the proxying.
+ *
+ * @author astrelsky
+ */
+ protected void disableIOProxyFactory() {
+ final String BDJ_FACTORY_CLASS_NAME = "com.oracle.orbis.io.BDJFactory";
+
+ try {
+ OpenModuleAction.execute(BDJ_FACTORY_CLASS_NAME);
+ } catch (PrivilegedActionException e) {
+ Status.println("Error while opening PS5-specific com.oracle.orbis.io package. " +
+ "Assuming this package does not exist in the current execution environment. " +
+ "Error: " + e.getException().getClass() + "; " +
+ "Message: " + e.getException().getMessage());
+ return;
+ }
+
+ try {
+ Class bdjFactoryClass = Class.forName(BDJ_FACTORY_CLASS_NAME);
+ Field bdjFactoryInstance = bdjFactoryClass.getDeclaredField("instance");
+ bdjFactoryInstance.setAccessible(true);
+ bdjFactoryInstance.set(null, null);
+ } catch (Throwable e) {
+ handleException(e);
+ }
+ }
+
@Override
public void run() {
+ // Disable I/O proxies
+ disableIOProxyFactory();
+
+ // Execute the socket listener
super.run();
// Unsubscribe from events
diff --git a/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpWorker.java b/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpWorker.java
index 8fafab1..de917dd 100644
--- a/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpWorker.java
+++ b/xploit/src/main/java/org/ps5jb/client/payloads/ftp/FtpWorker.java
@@ -125,6 +125,7 @@ private static final class userStatus {
* @param server The server instance.
* @param client The socket for the current client.
* @param dataPort The port for the data connection.
+ * @param name Name of the worker thread.
* @throws IOException If any I/O errors occur.
*/
public FtpWorker(FtpServer server, Socket client, int dataPort, String name) throws IOException {