Will Swift ever really be available on FreeBSD?

Hello,

simple question is: Will Swift ever really be available on FreeBSD?

In extension, wich FreeBSD version will be supported? Which Swift Version can we use on FreeBSD?

It seems like a little year Apple annonced Swift runs on FreeBSD and without some issues on Swift github project, it is all hided like an Appletree in a dark night. I see Fosdem 2026 will be used to take a spotlight on the Swift@FreeBSD Project or maybe only to the speakers?

With regards

Sebastian

1 Like

Have you tried the existing Swift on FreeBSD preview? I hope that would answer some of your questions.

1 Like

We are working toward making it a fully supported platform.

Issues are primarily tracked in the Swift on FreeBSD project board on GitHub. I can't seem to add issues to the swiftlang project board that are made against the apple org, so issues and PRs filed against things like swift-collections and swift-system are a bit harder to track.

We also have CI while we work through the test failures [main] OSS - Swift Package - FreeBSD 14 [Jenkins]. Once that turns green, we should be able to start shipping nightly packages with the other supported platforms.

Before the break, things were mostly blocked on issues with LLDB and how Swift stores/finds the runtime metadata on ELF. It looks like things regressed a bit over the holiday break and the stdlib has some new build failures now, but that should be fairly easy to track down.

3 Likes

Out of curiosity, do you have an issue reference for this?

I haven't written it out yet, I was digging through it over the break.

The gist of it is, the metadata contains relative offsets, so it's really only applicable after relocations are applied. swiftrt.o pulls out the start/stop symbols and fills out a table at runtime, and of course the data is fine since the loader relocates everything.

At least with swift-reflection-dump, we're not working with a loaded image though.
The static mirror ObjectFileContext applies the relocations and turns it into segments:

That "loaded image" memory buffer is then passed through to readELFSections in ReflectionContext.h:

This is where things go wrong. readELFSections tries to look up the sections by name, using the section headers and section header string table, which with ld.gold, happened to be mapped into the segments that were pulled up from the object file. With ld.lld on FreeBSD, only half of the section header for swift5_fieldmd is actually mapped into a segment it seems, so we end up with this as our section header that we try using to look up the name:

(const ELFTraits<'\x02'>::SectionHeader) {
  sh_name = 4294967295                    // 0xffffffff
  sh_type = 4294967295                    // 0xffffffff
  sh_flags = 0
  sh_addr = 0
  sh_offset = 0
  sh_size = 0
  sh_link = 29
  sh_info = 0
  sh_addralign = 182
  sh_entsize = 1
}

Really, we need a scheme that doesn't involve section headers or walking the section header string table since besides being inefficient, the string table can be stripped out of the binary, and the section headers aren't guaranteed to be mapped into segments at all and shouldn't be relied upon in the relocated memory buffer.

I think putting a table with pointers to the metadata in an allocated note segment with a magic might work since that would be guaranteed to be loaded, and we could look it up by walking the program headers and pulling out the appropriate PT_NOTE segment.
I believe that this would also allow us to mark it as a readonly segment, which would be good from a security standpoint. It would be an ABI break, but we don't have ABI guarantees on any of the ELF platforms, so that should be fine.

2 Likes

in result of only emulated FreeBSD it is too slow on ARM mac

As a minor correction, relative offsets should not require relocations to be applied by the loader; in fact, that's most of the point of them. Ordinary pointers do require relocations to be applied, though, and the non-constant parts of metadata do use those in places.

As I recall, PT_NOTE is problematic because it is allowed to be stripped (which is, in part, why we didn't end up using it to store Swift Testing's metadata.)

2 Likes