A program that names an interpreter in PT_INTERP gets it loaded too, at the bottom of the mmap area, and started instead -- with AT_PHDR, AT_PHENT, AT_PHNUM, AT_BASE and AT_ENTRY to find the program by. ET_DYN images are placed at a base: the interpreter there, a PIE program where a fixed one would go. Static musl programs get AT_PHDR now as well, which is how musl finds their TLS template. mmap(MAP_FIXED) of a file handed back zeroed pages whatever the descriptor said, and kept no record of them, so fork() did not copy them. A dynamic linker maps every library segment after the first that way. Fixed mappings now read the file and are recorded wherever no mapping already covers them. musl is built shared as well as static, and libc.so ships as /lib/ld-musl-x86_64.so.1 -- libc and loader in one file. Every port still links -static on purpose. cmd/dynhello is the test: against libc.so and a library of its own, checking TLS, the heap, and a fork whose child still has both. mprotect is accepted and not enforced yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
72 lines
2.5 KiB
Makefile
72 lines
2.5 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# musl libc — MIT-licensed: https://musl.libc.org/
|
|
#
|
|
# Installs into $(PREFIX) (= build/ports/musl/prefix), which port.mk exports
|
|
# to every other port as $(MUSL). Nothing is written into this directory.
|
|
|
|
include ../mk/port.mk
|
|
|
|
MUSL_VERSION := 1.2.5
|
|
MUSL_URL := https://musl.libc.org/releases/musl-$(MUSL_VERSION).tar.gz
|
|
MUSL_SHA256 := a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4
|
|
|
|
TARBALL := $(DISTDIR)/musl-$(MUSL_VERSION).tar.gz
|
|
|
|
$(TARBALL): | $(DISTDIR)
|
|
curl -fsSL -o $@ $(MUSL_URL)
|
|
sh $(SHA256CHECK) "$(MUSL_SHA256)" "$@"
|
|
|
|
download: $(TARBALL)
|
|
|
|
$(SRCDIR): $(TARBALL)
|
|
mkdir -p $(PORTDIR)
|
|
tar -xzf $< -C $(PORTDIR)
|
|
mv $(PORTDIR)/musl-$(MUSL_VERSION) $@
|
|
|
|
# $(SRCDIR) is order-only (|) on purpose. The stamp lives INSIDE $(SRCDIR),
|
|
# so creating it bumps that directory's mtime — making the directory forever
|
|
# newer than the stamp it contains, and re-running this rule on every single
|
|
# build. The second run then fails, because the patch does not apply twice.
|
|
$(SRCDIR)/.patched: patches/0001-schos-tls.patch | $(SRCDIR)
|
|
cd $(SRCDIR) && patch -p1 < $(CURDIR)/patches/0001-schos-tls.patch
|
|
touch $@
|
|
|
|
# Shared as well as static: libc.so is also the dynamic linker, and it is
|
|
# what a dynamically linked program names as its interpreter. Every port
|
|
# still links -static on purpose; this only makes the other kind possible.
|
|
#
|
|
# --syslibdir into the prefix, not the default /lib: `make install` puts a
|
|
# symlink to the loader there, and the default is the *host's* /lib. The copy
|
|
# the OS ships is placed by the sysroot rule below.
|
|
#
|
|
# Reconfigured when this file changes, so a tree configured before shared
|
|
# libraries were turned on does not quietly stay static-only.
|
|
$(BUILDDIR)/config.mak: $(SRCDIR)/.patched Makefile
|
|
rm -rf $(BUILDDIR)
|
|
mkdir -p $(BUILDDIR)
|
|
cd $(BUILDDIR) && $(SRCDIR)/configure \
|
|
--prefix=$(PREFIX) \
|
|
--syslibdir=$(PREFIX)/lib \
|
|
CC=$(CC) \
|
|
CFLAGS="-D__SCHOS__ -fno-stack-protector"
|
|
|
|
$(BUILDDIR)/lib/libc.a: $(BUILDDIR)/config.mak
|
|
$(MAKE) -C $(BUILDDIR)
|
|
|
|
$(PREFIX)/lib/libc.a: $(BUILDDIR)/lib/libc.a
|
|
$(MAKE) -C $(BUILDDIR) install
|
|
|
|
# The dynamic linker, under the name every dynamically linked x86_64 musl
|
|
# program asks for. A copy rather than the prefix's symlink: that one points
|
|
# at a path on the build host.
|
|
$(SYSROOT)/lib/ld-musl-x86_64.so.1: $(PREFIX)/lib/libc.a
|
|
mkdir -p $(SYSROOT)/lib
|
|
cp $(PREFIX)/lib/libc.so $@
|
|
|
|
install: $(PREFIX)/lib/libc.a $(SYSROOT)/lib/ld-musl-x86_64.so.1
|
|
|
|
clean:
|
|
rm -rf $(PORTDIR)
|
|
|
|
distclean: clean
|
|
rm -f $(TARBALL)
|