Skip to content

Commit

Permalink
add initial support for OpenBSD (JuliaLang#53633)
Browse files Browse the repository at this point in the history
These commits add initial support of OpenBSD in julia.

It isn't strictly enough to make julia runable on OpenBSD (see JuliaLang#53632),
but it covers the larger part.

---------

Co-authored-by: Max Horn <[email protected]>
Co-authored-by: Oscar Smith <[email protected]>
  • Loading branch information
3 people authored Mar 29, 2024
1 parent 09b356f commit e26d140
Show file tree
Hide file tree
Showing 27 changed files with 194 additions and 30 deletions.
19 changes: 16 additions & 3 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ JL_MAJOR_SHLIB_EXT := $(SHLIB_EXT).$(SOMAJOR)
endif
endif

ifeq ($(OS), FreeBSD)
ifneq ($(findstring $(OS),FreeBSD OpenBSD),)
LOCALBASE ?= /usr/local
else
LOCALBASE ?= /usr
Expand Down Expand Up @@ -726,7 +726,7 @@ SANITIZE_LDFLAGS :=
ifeq ($(SANITIZE_MEMORY),1)
SANITIZE_OPTS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
SANITIZE_LDFLAGS += $(SANITIZE_OPTS)
ifneq ($(findstring $(OS),Linux FreeBSD),)
ifneq ($(findstring $(OS),Linux FreeBSD OpenBSD),)
SANITIZE_LDFLAGS += -Wl,--warn-unresolved-symbols
endif # OS Linux or FreeBSD
endif # SANITIZE_MEMORY=1
Expand Down Expand Up @@ -1069,7 +1069,7 @@ JCFLAGS+=-DSYSTEM_LIBUNWIND
JCPPFLAGS+=-DSYSTEM_LIBUNWIND
endif
else
ifeq ($(OS),Darwin)
ifneq ($(findstring $(OS),Darwin OpenBSD),)
LIBUNWIND:=-lunwind
JCPPFLAGS+=-DLLVMLIBUNWIND
else
Expand Down Expand Up @@ -1380,6 +1380,19 @@ OSLIBS += -Wl,--export-dynamic -Wl,--version-script=$(BUILDROOT)/src/julia.expma
$(NO_WHOLE_ARCHIVE)
endif

ifeq ($(OS), OpenBSD)
JLDFLAGS += -Wl,--Bdynamic
ifneq ($(SANITIZE),1)
JLDFLAGS += -Wl,-no-undefined
endif

JLIBLDFLAGS += -Wl,-Bsymbolic-functions

OSLIBS += -Wl,--no-as-needed -lpthread -lm -lc++abi -lc
OSLIBS += -Wl,--whole-archive -lcompiler_rt -Wl,--no-whole-archive
OSLIBS += -Wl,--export-dynamic,--as-needed,--version-script=$(BUILDROOT)/src/julia.expmap
endif

ifeq ($(OS), Darwin)
SHLIB_EXT := dylib
OSLIBS += -framework CoreFoundation
Expand Down
18 changes: 14 additions & 4 deletions base/binaryplatforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ function validate_tags(tags::Dict)
throw_invalid_key("arch")
end
# Validate `os`
if tags["os"] ("linux", "macos", "freebsd", "windows")
if tags["os"] ("linux", "macos", "freebsd", "openbsd", "windows")
throw_invalid_key("os")
end
# Validate `os`/`arch` combination
Expand Down Expand Up @@ -375,8 +375,10 @@ function os()
return "windows"
elseif Sys.isapple()
return "macos"
elseif Sys.isbsd()
elseif Sys.isfreebsd()
return "freebsd"
elseif Sys.isopenbsd()
return "openbsd"
else
return "linux"
end
Expand Down Expand Up @@ -422,6 +424,7 @@ const platform_names = Dict(
"macos" => "macOS",
"windows" => "Windows",
"freebsd" => "FreeBSD",
"openbsd" => "OpenBSD",
nothing => "Unknown",
)

Expand Down Expand Up @@ -556,6 +559,8 @@ function os_str(p::AbstractPlatform)
else
return "-unknown-freebsd"
end
elseif os(p) == "openbsd"
return "-unknown-openbsd"
else
return "-unknown"
end
Expand All @@ -581,7 +586,8 @@ Sys.isapple(p::AbstractPlatform) = os(p) == "macos"
Sys.islinux(p::AbstractPlatform) = os(p) == "linux"
Sys.iswindows(p::AbstractPlatform) = os(p) == "windows"
Sys.isfreebsd(p::AbstractPlatform) = os(p) == "freebsd"
Sys.isbsd(p::AbstractPlatform) = os(p) ("freebsd", "macos")
Sys.isopenbsd(p::AbstractPlatform) = os(p) == "openbsd"
Sys.isbsd(p::AbstractPlatform) = os(p) ("freebsd", "openbsd", "macos")
Sys.isunix(p::AbstractPlatform) = Sys.isbsd(p) || Sys.islinux(p)

const arch_mapping = Dict(
Expand Down Expand Up @@ -632,6 +638,7 @@ end
const os_mapping = Dict(
"macos" => "-apple-darwin[\\d\\.]*",
"freebsd" => "-(.*-)?freebsd[\\d\\.]*",
"openbsd" => "-(.*-)?openbsd[\\d\\.]*",
"windows" => "-w64-mingw32",
"linux" => "-(.*-)?linux",
)
Expand Down Expand Up @@ -745,6 +752,9 @@ function Base.parse(::Type{Platform}, triplet::String; validate_strict::Bool = f
if os == "freebsd"
os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)"sa)
end
if os == "openbsd"
os_version = extract_os_version("openbsd", r".*openbsd([\d.]+)"sa)
end
tags["os_version"] = os_version

return Platform(arch, os, tags; validate_strict)
Expand Down Expand Up @@ -802,7 +812,7 @@ function parse_dl_name_version(path::String, os::String)
# On OSX, libraries look like `libnettle.6.3.dylib`
dlregex = r"^(.*?)((?:\.[\d]+)*)\.dylib$"sa
else
# On Linux and FreeBSD, libraries look like `libnettle.so.6.3.0`
# On Linux and others BSD, libraries look like `libnettle.so.6.3.0`
dlregex = r"^(.*?)\.so((?:\.[\d]+)*)$"sa
end

Expand Down
2 changes: 1 addition & 1 deletion base/sysinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ end
Get the maximum resident set size utilized in bytes.
See also:
- man page of `getrusage`(2) on Linux and FreeBSD.
- man page of `getrusage`(2) on Linux and BSD.
- Windows API `GetProcessMemoryInfo`.
"""
maxrss() = ccall(:jl_maxrss, Csize_t, ())
Expand Down
4 changes: 3 additions & 1 deletion cli/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ else ifeq ($(OS),Linux)
LOADER_LDFLAGS += -Wl,--no-as-needed -ldl -lpthread -rdynamic -lc -Wl,--as-needed -Wl,-z,notext
else ifeq ($(OS),FreeBSD)
LOADER_LDFLAGS += -Wl,--no-as-needed -ldl -lpthread -rdynamic -lc -Wl,--as-needed
else ifeq ($(OS),OpenBSD)
LOADER_LDFLAGS += -Wl,--no-as-needed -lpthread -rdynamic -lc -Wl,--as-needed
else ifeq ($(OS),Darwin)
LOADER_LDFLAGS += -lSystem
endif
Expand Down Expand Up @@ -107,7 +109,7 @@ julia-debug: $(build_bindir)/julia-debug$(EXE)
libjulia-release: $(build_shlibdir)/libjulia.$(SHLIB_EXT)
libjulia-debug: $(build_shlibdir)/libjulia-debug.$(SHLIB_EXT)

ifneq (,$(filter $(OS), Linux FreeBSD))
ifneq (,$(filter $(OS), Linux FreeBSD OpenBSD))
VERSIONSCRIPT := -Wl,--version-script=$(BUILDDIR)/julia.expmap
endif

Expand Down
2 changes: 1 addition & 1 deletion cli/loader_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) {
(*jl_codegen_exported_func_addrs[symbol_idx]) = addr;
}
// Next, if we're on Linux/FreeBSD, set up fast TLS.
#if !defined(_OS_WINDOWS_) && !defined(_OS_DARWIN_)
#if !defined(_OS_WINDOWS_) && !defined(_OS_DARWIN_) && !defined(_OS_OPENBSD_)
void (*jl_pgcstack_setkey)(void*, void*(*)(void)) = lookup_symbol(libjulia_internal, "jl_pgcstack_setkey");
if (jl_pgcstack_setkey == NULL) {
jl_loader_print_stderr("ERROR: Cannot find jl_pgcstack_setkey() function within libjulia-internal!\n");
Expand Down
2 changes: 2 additions & 0 deletions contrib/normalize_triplet.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
platform_mapping = {
'darwin': "-apple-darwin[\\d\\.]*",
'freebsd': "-(.*-)?freebsd[\\d\\.]*",
'openbsd': "-(.*-)?openbsd[\\d\\.]*",
'windows': "-w64-mingw32",
'linux': "-(.*-)?linux",
}
Expand Down Expand Up @@ -96,6 +97,7 @@ def p(x):
'darwin': 'apple-darwin',
'windows': 'w64-mingw32',
'freebsd': 'unknown-freebsd',
'openbsd': 'unknown-openbsd',
}
x = r(x)
if x:
Expand Down
4 changes: 3 additions & 1 deletion deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ ifeq ($(OS), Linux)
DEP_LIBS += unwind
else ifeq ($(OS), FreeBSD)
DEP_LIBS += unwind
else ifeq ($(OS), OpenBSD)
DEP_LIBS += llvmunwind
else ifeq ($(OS), Darwin)
DEP_LIBS += llvmunwind
endif
endif
endif

ifneq (,$(findstring $(OS),Linux FreeBSD))
ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD))
ifeq ($(USE_SYSTEM_PATCHELF), 0)
DEP_LIBS += patchelf
PATCHELF:=$(build_depsbindir)/patchelf
Expand Down
6 changes: 5 additions & 1 deletion deps/libgit2.mk
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ LIBGIT2_OPTS += -DBUILD_TESTS=OFF -DDLLTOOL=`which $(CROSS_COMPILE)dlltool`
LIBGIT2_OPTS += -DCMAKE_FIND_ROOT_PATH=/usr/$(XC_HOST) -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY
endif
endif
ifeq ($(OS),OpenBSD)
# iconv.h is third-party
LIBGIT2_OPTS += -DCMAKE_C_FLAGS="-I/usr/local/include"
endif

ifneq (,$(findstring $(OS),Linux FreeBSD))
ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD))
LIBGIT2_OPTS += -DUSE_HTTPS="mbedTLS" -DUSE_SHA1="CollisionDetection" -DCMAKE_INSTALL_RPATH="\$$ORIGIN"
endif

Expand Down
6 changes: 5 additions & 1 deletion deps/libssh2.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ endif
LIBSSH2_OPTS := $(CMAKE_COMMON) -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF \
-DCMAKE_BUILD_TYPE=Release

ifneq ($(fPIC),)
LIBSSH2_OPTS += -DCMAKE_C_FLAGS="-fPIC"
endif

ifeq ($(OS),WINNT)
LIBSSH2_OPTS += -DCRYPTO_BACKEND=WinCNG -DENABLE_ZLIB_COMPRESSION=OFF
ifeq ($(BUILD_OS),WINNT)
Expand All @@ -20,7 +24,7 @@ else
LIBSSH2_OPTS += -DCRYPTO_BACKEND=mbedTLS -DENABLE_ZLIB_COMPRESSION=OFF
endif

ifneq (,$(findstring $(OS),Linux FreeBSD))
ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD))
LIBSSH2_OPTS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN"
endif

Expand Down
6 changes: 3 additions & 3 deletions deps/libsuitesparse.mk
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ else
LIBSUITESPARSE_CMAKE_FLAGS += -DSUITESPARSE_USE_64BIT_BLAS=NO
endif

ifneq (,$(findstring $(OS),Linux FreeBSD))
ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD))
LIBSUITESPARSE_CMAKE_FLAGS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN"
endif

Expand All @@ -59,8 +59,8 @@ $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-compiled: | $(build_prefix)/

$(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/build-compiled: $(BUILDDIR)/SuiteSparse-$(LIBSUITESPARSE_VER)/source-patched
cd $(dir $<) && $(CMAKE) . $(LIBSUITESPARSE_CMAKE_FLAGS)
make -C $(dir $<)
make -C $(dir $<) install
$(MAKE) -C $(dir $<)
$(MAKE) -C $(dir $<) install
echo 1 > $@

ifeq ($(OS),WINNT)
Expand Down
2 changes: 1 addition & 1 deletion deps/mbedtls.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ifeq ($(BUILD_OS),WINNT)
MBEDTLS_OPTS += -G"MSYS Makefiles"
endif

ifneq (,$(findstring $(OS),Linux FreeBSD))
ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD))
MBEDTLS_OPTS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN"
endif

Expand Down
2 changes: 1 addition & 1 deletion deps/patchelf.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ $(BUILDDIR)/patchelf-$(PATCHELF_VER)/build-configured: XC_HOST:=$(BUILD_MACHINE)
$(BUILDDIR)/patchelf-$(PATCHELF_VER)/build-configured: $(SRCCACHE)/patchelf-$(PATCHELF_VER)/source-extracted
mkdir -p $(dir $@)
cd $(dir $@) && \
$(dir $<)/configure $(CONFIGURE_COMMON) LDFLAGS="$(CXXLDFLAGS)" CPPFLAGS="$(CPPFLAGS)"
$(dir $<)/configure $(CONFIGURE_COMMON) LDFLAGS="$(CXXLDFLAGS)" CPPFLAGS="$(CPPFLAGS)" MAKE=$(MAKE)
echo 1 > $@

$(BUILDDIR)/patchelf-$(PATCHELF_VER)/build-compiled: $(BUILDDIR)/patchelf-$(PATCHELF_VER)/build-configured
Expand Down
3 changes: 3 additions & 0 deletions deps/pcre.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ PCRE_LDFLAGS := $(RPATH_ESCAPED_ORIGIN)
ifeq ($(OS),emscripten)
PCRE_CFLAGS += -fPIC
PCRE_JIT = --disable-jit
else ifeq ($(OS),OpenBSD)
# jit will need RWX memory
PCRE_JIT = --disable-jit
else
PCRE_JIT = --enable-jit
endif
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,8 @@ $(build_shlibdir)/lib%Plugin.$(SHLIB_EXT): $(SRCDIR)/clangsa/%.cpp $(LLVM_CONFIG
ANALYSIS_DEPS := llvm clang llvm-tools libuv utf8proc
ifeq ($(OS),Darwin)
ANALYSIS_DEPS += llvmunwind
else ifeq ($(OS),OpenBSD)
ANALYSIS_DEPS += llvmunwind
else ifneq ($(OS),WINNT)
ANALYSIS_DEPS += unwind
endif
Expand Down
2 changes: 1 addition & 1 deletion src/aotcompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,7 @@ void jl_dump_native_impl(void *native_code,
TheTriple.setOSName(Str);
}
Optional<Reloc::Model> RelocModel;
if (TheTriple.isOSLinux() || TheTriple.isOSFreeBSD()) {
if (TheTriple.isOSLinux() || TheTriple.isOSFreeBSD() || TheTriple.isOSOpenBSD()) {
RelocModel = Reloc::PIC_;
}

Expand Down
3 changes: 3 additions & 0 deletions src/cgmemmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
# include <sys/types.h>
# include <sys/resource.h>
#endif
#ifdef _OS_OPENBSD_
# include <sys/resource.h>
#endif
#include "julia_assert.h"

namespace {
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static bool jl_fpo_disabled(const Triple &TT) {
// MSAN doesn't support FPO
return true;
#endif
if (TT.isOSLinux() || TT.isOSWindows() || TT.isOSFreeBSD()) {
if (TT.isOSLinux() || TT.isOSWindows() || TT.isOSFreeBSD() || TT.isOSOpenBSD()) {
return true;
}
return false;
Expand Down
11 changes: 11 additions & 0 deletions src/gc-stacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ static void free_stack(void *stkbuf, size_t bufsz)

#else

# ifdef _OS_OPENBSD_
static void *malloc_stack(size_t bufsz) JL_NOTSAFEPOINT
{
void* stk = mmap(0, bufsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (stk == MAP_FAILED)
return MAP_FAILED;
jl_atomic_fetch_add(&num_stack_mappings, 1);
return stk;
}
# else
static void *malloc_stack(size_t bufsz) JL_NOTSAFEPOINT
{
void* stk = mmap(0, bufsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Expand All @@ -65,6 +75,7 @@ static void *malloc_stack(size_t bufsz) JL_NOTSAFEPOINT
jl_atomic_fetch_add_relaxed(&num_stack_mappings, 1);
return stk;
}
# endif

static void free_stack(void *stkbuf, size_t bufsz)
{
Expand Down
22 changes: 21 additions & 1 deletion src/jitlayers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ static void *getTLSAddress(void *control)
}
#endif

#ifdef _OS_OPENBSD_
extern "C" {
__int128 __divti3(__int128, __int128);
__int128 __modti3(__int128, __int128);
unsigned __int128 __udivti3(unsigned __int128, unsigned __int128);
unsigned __int128 __umodti3(unsigned __int128, unsigned __int128);
}
#endif

// Snooping on which functions are being compiled, and how long it takes
extern "C" JL_DLLEXPORT_CODEGEN
void jl_dump_compiles_impl(void *s)
Expand Down Expand Up @@ -1732,6 +1741,17 @@ JuliaOJIT::JuliaOJIT()
};
cantFail(GlobalJD.define(orc::symbolAliases(jl_crt)));

#ifdef _OS_OPENBSD_
orc::SymbolMap i128_crt;

i128_crt[mangle("__divti3")] = JITEvaluatedSymbol::fromPointer(&__divti3, JITSymbolFlags::Exported);
i128_crt[mangle("__modti3")] = JITEvaluatedSymbol::fromPointer(&__modti3, JITSymbolFlags::Exported);
i128_crt[mangle("__udivti3")] = JITEvaluatedSymbol::fromPointer(&__udivti3, JITSymbolFlags::Exported);
i128_crt[mangle("__umodti3")] = JITEvaluatedSymbol::fromPointer(&__umodti3, JITSymbolFlags::Exported);

cantFail(GlobalJD.define(orc::absoluteSymbols(i128_crt)));
#endif

#ifdef MSAN_EMUTLS_WORKAROUND
orc::SymbolMap msan_crt;
msan_crt[mangle("__emutls_get_address")] = JITEvaluatedSymbol::fromPointer(msan_workaround::getTLSAddress, JITSymbolFlags::Exported);
Expand Down Expand Up @@ -1808,7 +1828,7 @@ void JuliaOJIT::addModule(orc::ThreadSafeModule TSM)
auto Lookups = ES.lookup({{&JD, orc::JITDylibLookupFlags::MatchExportedSymbolsOnly}}, NewExports);
if (!Lookups) {
ES.reportError(Lookups.takeError());
errs() << "Failed to lookup symbols in module!";
errs() << "Failed to lookup symbols in module!\n";
if (CurrentlyCompiling) {
CurrentlyCompiling.withModuleDo([](Module &M) JL_NOTSAFEPOINT { errs() << "Dumping failing module\n" << M << "\n"; });
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/julia.expmap.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@JULIA_SHLIB_SYMBOL_VERSION@ {
global:
pthread*;
__stack_chk_guard;
__stack_chk_*;
asprintf;
bitvector_*;
ios_*;
Expand Down
Loading

0 comments on commit e26d140

Please sign in to comment.