aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2022-08-06 01:20:11 +0200
committerBen Hutchings <ben@decadent.org.uk>2022-08-06 01:30:28 +0200
commit05eee5acb41c12ceb6e5e51ccfb2442271128679 (patch)
tree61b98cddf3c6c2447a7868aa2645b669b4da8bc3
parentbb2fde5ddbc18a2e7795ca4d24759230c2aae9d0 (diff)
downloadklibc-05eee5acb41c12ceb6e5e51ccfb2442271128679.tar.gz
[klibc] Work around ELF loader bugs when executables have only BSS
Some of klibc's test programs have BSS but no static data when built to use the shared library. This is apparently very unusual, and existing ELF loaders don't always handle it correctly. I previously found that QEMU's ELF loader rejected such executables, though this was eventually fixed. Now a change in binutils for arm64 has revealed a bug in the kernel ELF loader, that's causing it to reject those same executables. While this might get fixed in one way or another, I think it's a sign that this case is just not tested and it would be best to avoid it. Therefore: - Rename interp.S to shared-stub.S - Add a single byte of static data to it Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--klibc.spec.in4
-rw-r--r--scripts/Kbuild.klibc2
-rw-r--r--usr/klibc/.gitignore2
-rw-r--r--usr/klibc/Kbuild14
-rw-r--r--usr/klibc/shared-stub.S (renamed from usr/klibc/interp.S)9
5 files changed, 20 insertions, 11 deletions
diff --git a/klibc.spec.in b/klibc.spec.in
index 7d78b9ab9d5be5..db10363ed31110 100644
--- a/klibc.spec.in
+++ b/klibc.spec.in
@@ -90,7 +90,7 @@ install -m 444 usr/kinit/README %{buildroot}%{bindocdir}/README.kinit
rm -rf $RPM_BUILD_ROOT
#
-# Note: libc.so and interp.o are technically -devel files, but
+# Note: libc.so and shared-stub.o are technically -devel files, but
# put them in this package until we can make really, really sure
# the dependency system can avoid confusion. (In fact, it would be
# good to eventually get them out of here, so that multiple runtimes
@@ -100,7 +100,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root,-)
/lib/klibc-*.so
%{klibcdir}/lib/*.so
-%{klibcdir}/lib/interp.o
+%{klibcdir}/lib/shared-stub.o
%files devel
%defattr(-,root,root,-)
diff --git a/scripts/Kbuild.klibc b/scripts/Kbuild.klibc
index 64da31ac420f93..accf7f1b1c0e49 100644
--- a/scripts/Kbuild.klibc
+++ b/scripts/Kbuild.klibc
@@ -82,7 +82,7 @@ KLIBCCFLAGS :=
# Defaults for arch to override
KLIBCARCHINCFLAGS =
-KLIBCCRTSHARED := $(KLIBCOBJ)/interp.o
+KLIBCCRTSHARED := $(KLIBCOBJ)/shared-stub.o
LD_IS_LLD := $(shell $(LD) --version 2>&1 | grep LLD)
LD_IMAGE_BASE_OPT := $(if $(LD_IS_LLD),--image-base,-Ttext-segment)
diff --git a/usr/klibc/.gitignore b/usr/klibc/.gitignore
index f24c971efe09bd..5f4a9af713f2b1 100644
--- a/usr/klibc/.gitignore
+++ b/usr/klibc/.gitignore
@@ -1,5 +1,5 @@
errlist.c
-.interp.o.d
+.shared-stub.o.d
klibc*.so
klib.list
.klib.list.cmd
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 5933f89a1a7b14..973b0c8179d85b 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -99,17 +99,17 @@ LIBC := libc.a
SOLIB := libc.so
SOHASH := klibc.so
CRT0 := arch/$(KLIBCARCHDIR)/crt0.o
-INTERP_O := interp.o
+SHARED_STUB := shared-stub.o
always := $(LIBC)
ifdef KLIBCSHAREDFLAGS
-always += $(SOLIB) $(SOHASH) $(INTERP_O)
+always += $(SOLIB) $(SOHASH) $(SHARED_STUB)
endif
LIBC := $(call objectify,$(LIBC))
SOLIB := $(call objectify,$(SOLIB))
SOHASH := $(call objectify,$(SOHASH))
CRT0 := $(call objectify,$(CRT0))
-INTERP_O := $(call objectify,$(INTERP_O))
+SHARED_STUB := $(call objectify,$(SHARED_STUB))
SOLIBHASH = $(shell cat $(SOLIB).hash)
@@ -179,8 +179,8 @@ $(SOHASH): $(SOLIB) $(SOLIB).hash
#####
-# build interp.o
-targets += interp.o
+# build shared-stub.o
+targets += shared-stub.o
quiet_cmd_interp = BUILD $@
cmd_interp = $(KLIBCCC) $(klibccflags) -D__ASSEMBLY__ \
@@ -188,7 +188,7 @@ quiet_cmd_interp = BUILD $@
-DSOHASH=\"$(SOLIBHASH)\" \
-c -o $@ $<
-$(INTERP_O): $(obj)/interp.S $(SOLIB).hash
+$(SHARED_STUB): $(obj)/shared-stub.S $(SOLIB).hash
$(call if_changed,interp)
#####
@@ -199,7 +199,7 @@ install-rule:
$(shell $(install-data) $(f) \
$(INSTALLROOT)$(INSTALLDIR)/$(KLIBCCROSS)lib))
ifdef KLIBCSHAREDFLAGS
- $(Q)$(foreach f, $(SOLIB) $(INTERP_O), \
+ $(Q)$(foreach f, $(SOLIB) $(SHARED_STUB), \
$(shell $(install-data) $(f) \
$(INSTALLROOT)$(INSTALLDIR)/$(KLIBCCROSS)lib))
$(Q)$(install-lib) $(obj)/klibc-$(SOLIBHASH).so \
diff --git a/usr/klibc/interp.S b/usr/klibc/shared-stub.S
index 4b15cfbdac9544..15c0f02af32da1 100644
--- a/usr/klibc/interp.S
+++ b/usr/klibc/shared-stub.S
@@ -11,3 +11,12 @@
.ascii SOHASH
.ascii ".so"
.byte 0
+
+#
+# Ensure that every executable includes some static data, as
+# ELF loaders tend to assume this - see
+# <https://bugs.debian.org/919921>, <https://bugs.debian.org/1016718>.
+#
+
+ .section ".data"
+ .byte 0