Skip to content

Port bootstrap build on OpenBSD#129080

Open
am11 wants to merge 4 commits into
dotnet:mainfrom
am11:feature/port/openbsd-bootstrap-misc-fixes
Open

Port bootstrap build on OpenBSD#129080
am11 wants to merge 4 commits into
dotnet:mainfrom
am11:feature/port/openbsd-bootstrap-misc-fixes

Conversation

@am11

@am11 am11 commented Jun 6, 2026

Copy link
Copy Markdown
Member

Contributes to #124911.

@am11 am11 requested a review from MichalStrehovsky as a code owner June 6, 2026 19:33
@am11 am11 added area-VM-coreclr port os-openbsd OpenBSD OS, currently not officially supported and removed area-NativeAOT-coreclr labels Jun 6, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jun 6, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke
See info in area-owners.md if you want to be subscribed.

Comment thread src/native/minipal/thread.h
@am11 am11 force-pushed the feature/port/openbsd-bootstrap-misc-fixes branch from 12c4799 to a0f6b36 Compare June 8, 2026 14:39
list(APPEND _heimdal_hints
"${CMAKE_SYSROOT}/heimdal/lib"
"${CMAKE_SYSROOT}/usr/heimdal/lib")
"${CMAKE_SYSROOT}/usr/local/heimdal/lib")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These path updates in src/native/libs are compatible with dotnet/arcade#16990 and the real OpenBSD system where pkg_add icu4c openssl etc. install libs and headers.

@am11

am11 commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

With dotnet/arcade#16990, #129124, #129103 and #129078, we can build runtime native src/coreclr/build-runtime.sh and with -component paltests on the OpenBSD system and get all PAL tests passing.

Also cross-build succeeds with these changes and hello world works with coreclr as well as NativeAOT. OpenBSD has similarities with Android, OSX and FreeBSD, so not much "new" here just needed to run a series of trail and error with AI to get the right balance without significant amount of new code.

add_linker_flag("-Wl,--build-id=sha1")
# OpenBSD's ld.so can't resolve native TLS relocs in a .so; rely on clang's default
# emulated TLS (don't pass -fno-emulated-tls).
# Allow W+X mappings (JIT) via the PT_OPENBSD_WXNEEDED note; needs a wxallowed mount.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to enable this? Is W^X broken on OpenBSD?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Short: One or two PAL tests were failing on OpenBSD due to W^X restrictions, so I remounted the /home filesystem with wxallowed and added this linker flag to make them pass.

Long:
This is OpenBSD-specific. Unlike Linux or FreeBSD, OpenBSD enforces W^X strictly and requires both a binary opt-in (-z wxneeded) and a filesystem opt-in (wxallowed) for W+X mappings to be permitted.

The reason for -z wxneeded is that parts of the PAL/JIT may need to create mappings that are temporarily W+X.

With wxneeded, the kernel allows those mappings only when the process is running on a filesystem mounted with wxallowed. If it is not, the mapping request fails at runtime when that code path is reached (i.e., when JIT/codegen tries to allocate executable memory). It does not affect process startup by itself.

So in practice we expect two modes:

  • On systems with wxallowed: app will use W+X mappings when needed.
  • On systems without wxallowed: user will set DOTNET_EnableWriteXorExecute=0, and the app will avoid W+X mappings entirely.

In a follow-up, for systems without wxallowed, we could detect this automatically on OpenBSD using filesystem mount flags, for example:

bool EnableWriteXorExecute(void)
{
    struct statfs buf;
    return statfs(minipal_getexepath(), &buf) == 0 &&
       (buf.f_flags & MNT_WXALLOWED);
}

(I had too many patches in flight and this was getting long, so I skipped doing this right away)

// are stored directly in it.
#if defined(__OpenBSD__)
#define MCONTEXT_FROM_PTR(nativeContext) (*(nativeContext))
#define MCONTEXT_FROM_REF(nativeContext) (nativeContext)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the usages of the _REF one, it seems it is not worth having two separate macros. How about naming it MCONTEXT_FROM_NATIVE or something like that so that it is clearer what the macro does, and passing address of ctx in the few cases where you have added the _REF one usage?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-VM-coreclr community-contribution Indicates that the PR has been added by a community member os-openbsd OpenBSD OS, currently not officially supported port

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants