From 2ab0082d1ae0cf20de4c92ce9beb5908e677cc76 Mon Sep 17 00:00:00 2001 From: Kurt Miller Date: Mon, 16 Feb 2026 19:17:42 -0500 Subject: [PATCH] Add debugger support for OpenBSD. --- .../src/main/py/src/ghidragdb/arch.py | 2 + .../src/main/py/src/ghidralldb/arch.py | 1 + Ghidra/Features/FunctionID/build.gradle | 10 +++-- .../src/main/java/ghidra/pty/PtyFactory.java | 3 ++ .../ghidra/pty/openbsd/OpenBSDIoctls.java | 38 ++++++++++++++++++ .../ghidra/pty/openbsd/OpenBSDPtyFactory.java | 40 +++++++++++++++++++ .../pty/openbsd/OpenBSDPtySessionLeader.java | 33 +++++++++++++++ 7 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDIoctls.java create mode 100644 Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtyFactory.java create mode 100644 Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtySessionLeader.java diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py index 28d40395a7..0cdfa5639d 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/arch.py @@ -103,6 +103,7 @@ data64_compiler_map: Dict[Optional[str], str] = { x86_compiler_map: Dict[Optional[str], str] = { 'GNU/Linux': 'gcc', + 'OpenBSD': 'gcc', 'Windows': 'windows', # This may seem wrong, but Ghidra cspecs really describe the ABI 'Cygwin': 'windows', @@ -110,6 +111,7 @@ x86_compiler_map: Dict[Optional[str], str] = { riscv_compiler_map: Dict[Optional[str], str] = { 'GNU/Linux': 'gcc', + 'OpenBSD': 'gcc', 'Cygwin': 'gcc', } diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/arch.py b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/arch.py index 4b4a12baa8..66f0d6046a 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/arch.py +++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/arch.py @@ -135,6 +135,7 @@ default_compiler_map: Dict[Optional[str], str] = { 'freebsd': 'gcc', 'linux': 'gcc', 'netbsd': 'gcc', + 'openbsd': 'gcc', 'ps4': 'gcc', 'ios': 'gcc', 'macosx': 'gcc', diff --git a/Ghidra/Features/FunctionID/build.gradle b/Ghidra/Features/FunctionID/build.gradle index 51c575ded4..e10f30ca4d 100644 --- a/Ghidra/Features/FunctionID/build.gradle +++ b/Ghidra/Features/FunctionID/build.gradle @@ -113,9 +113,10 @@ task buildFidHelpPdf(type: Exec) { // Check the OS before executing command. doFirst { if ( !(org.gradle.internal.os.OperatingSystem.current().isLinux() - || org.gradle.internal.os.OperatingSystem.current().isMacOsX())) { + || org.gradle.internal.os.OperatingSystem.current().isMacOsX() + || org.gradle.internal.os.OperatingSystem.current().isOpenBSD())) { throw new TaskExecutionException( it, - new Exception( "The '$it.name' task only works on Linux or Mac Os X" )) + new Exception( "The '$it.name' task only works on Linux, Mac Os X or OpenBSD" )) } } @@ -177,8 +178,9 @@ task buildFidHelpHtml(type: Exec) { // Check the OS before executing command. doFirst { - if (!getCurrentPlatformName().startsWith("linux")) { - throw new TaskExecutionException( it, new Exception("The '$it.name' task only works on Linux.")) + if (!(getCurrentPlatformName().startsWith("linux") + || getCurrentPlatformName().startsWith("openbsd"))) { + throw new TaskExecutionException( it, new Exception("The '$it.name' task only works on Linux or OpenBSD.")) } } diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyFactory.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyFactory.java index b9d77e44e8..ea30b93a20 100644 --- a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyFactory.java +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/PtyFactory.java @@ -19,6 +19,7 @@ import java.io.IOException; import ghidra.framework.OperatingSystem; import ghidra.pty.linux.LinuxPtyFactory; +import ghidra.pty.openbsd.OpenBSDPtyFactory; import ghidra.pty.macos.MacosPtyFactory; import ghidra.pty.windows.ConPtyFactory; @@ -40,6 +41,8 @@ public interface PtyFactory { return MacosPtyFactory.INSTANCE; case LINUX: return LinuxPtyFactory.INSTANCE; + case OPEN_BSD: + return OpenBSDPtyFactory.INSTANCE; case WINDOWS: return ConPtyFactory.INSTANCE; default: diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDIoctls.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDIoctls.java new file mode 100644 index 0000000000..82264e65f3 --- /dev/null +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDIoctls.java @@ -0,0 +1,38 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pty.openbsd; + +import ghidra.pty.unix.PosixC.Ioctls; +import ghidra.pty.unix.UnixPtySessionLeader; + +public enum OpenBSDIoctls implements Ioctls { + INSTANCE; + + @Override + public Class leaderClass() { + return OpenBSDPtySessionLeader.class; + } + + @Override + public long TIOCSCTTY() { + return 0x20007461L; + } + + @Override + public long TIOCSWINSZ() { + return 0x80087467L; + } +} diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtyFactory.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtyFactory.java new file mode 100644 index 0000000000..a5fc108793 --- /dev/null +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtyFactory.java @@ -0,0 +1,40 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pty.openbsd; + +import java.io.IOException; + +import ghidra.pty.Pty; +import ghidra.pty.PtyFactory; +import ghidra.pty.unix.UnixPty; + +public enum OpenBSDPtyFactory implements PtyFactory { + INSTANCE; + + @Override + public Pty openpty(short cols, short rows) throws IOException { + UnixPty pty = UnixPty.openpty(OpenBSDIoctls.INSTANCE); + if (cols != 0 && rows != 0) { + pty.getChild().setWindowSize(cols, rows); + } + return pty; + } + + @Override + public String getDescription() { + return "local (OpenBSD)"; + } +} diff --git a/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtySessionLeader.java b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtySessionLeader.java new file mode 100644 index 0000000000..3e960981b2 --- /dev/null +++ b/Ghidra/Framework/Pty/src/main/java/ghidra/pty/openbsd/OpenBSDPtySessionLeader.java @@ -0,0 +1,33 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.pty.openbsd; + +import ghidra.pty.unix.PosixC.Ioctls; +import ghidra.pty.unix.UnixPtySessionLeader; + +public class OpenBSDPtySessionLeader extends UnixPtySessionLeader { + + public static void main(String[] args) throws Exception { + OpenBSDPtySessionLeader leader = new OpenBSDPtySessionLeader(); + leader.parseArgs(args); + leader.run(); + } + + @Override + protected Ioctls ioctls() { + return OpenBSDIoctls.INSTANCE; + } +}