diff options
-rw-r--r-- | docs/defines.txt | 61 | ||||
-rw-r--r-- | docs/sigaction.txt | 249 | ||||
-rw-r--r-- | utils/Makefile.in | 26 |
3 files changed, 320 insertions, 16 deletions
diff --git a/docs/defines.txt b/docs/defines.txt new file mode 100644 index 000000000..677335e2f --- /dev/null +++ b/docs/defines.txt @@ -0,0 +1,61 @@ +Feeble attempt to document the horde of #defines we deal with. +Editors, plese make your descriptions short but informative. + + + +__BEGIN_DECLS, __END_DECLS + Defined to either empty or 'extern "C" {' and '}' if included by C++. + +__USE_GNU, __USE_BSD, __USE_XOPEN[2K], __USE_SVID, __USE_POSIX... + If defined, user program which included us requests compat additions + from relevant standard or Unix flavor. See features.h for full list. + +__USE_FILE_OFFSET64 +__USE_LARGEFILE[64] +_LARGEFILE[64]_SOURCE +_FILE_OFFSET_BITS + ??? + +__NTH(fct) +__THROW +__REDIRECT(name, proto, alias) +__REDIRECT_NTH(name, proto, alias) + ??? + +__BIG_ENDIAN 4321 +__LITTLE_ENDIAN 1234 + Should be always as shown. __PDP_ENDIAN is historic, ignore? +__BYTE_ORDER, __FLOAT_WORD_ORDER + Should be defined to __BIG_ENDIAN or __LITTLE_ENDIAN. + Usage: "#if __BYTE_ORDER == __LITTLE_ENDIAN ..." + __USE_BSD adds versions without leading "__" for above four defines. +_BIG_ENDIAN, __BIG_ENDIAN__ +_LITTLE_ENDIAN, __LITTLE_ENDIAN__ + Defined (to what?) by gcc for some architectures to indicate endianness. + Seems that the fact of defined-ness is an indicator, not the value. + +__USE_EXTERN_INLINES + If defined, headers will supply some function as inlines. + uclibc itself is built with this option off and provides + out-of-line version of every inlined function in case user program + calls it instead of using an inline. +_EXTERN_INLINE + Define it to replace "extern __inline" string in inline definitions + (those enabled by __USE_EXTERN_INLINES) with something else. + A few uclibc .c files use it to create non-inlined functions + by defining it to "". + +_LIBC +UCLIBC_INTERNAL + Defined only at libc build time. _LIBC is probably from glibc, +and UCLIBC_INTERNAL is added by vda (he didn't know about _LIBC). +Both defines are physically deleted from headers (using unifdef tool) +in installed headers ("make install"). + +__UCLIBC_XXX + uclibc-internal and uclibc-specific defines. In particular: +__UCLIBC_HAS_XXX__, __UCLIBC_HAVE_XXX__ + __UCLIBC_HAS_XXX__ are booleans (defined/undefined), defined in + uClibc_config.h and generated from uclibc .config file. + __UCLIBC_HAVE_XXX__ are booleans from bits/uClibc_arch_features.h + (there are more __UCLIBC_XXX defines there) diff --git a/docs/sigaction.txt b/docs/sigaction.txt new file mode 100644 index 000000000..667eeba41 --- /dev/null +++ b/docs/sigaction.txt @@ -0,0 +1,249 @@ + All what you never wanted to know about sigaction(), + struct sigaction, and sigset_t. + + +Before vda started messing with sigset_t, struct sigaction +and sigaction() functions, things looked this way: + + + Structures + +MIPS: + +Ignoring bogus "#if defined(__mips__) ..." block in +libc/sysdeps/linux/common/bits/kernel_sigaction.h +and using +libc/sysdeps/linux/mips/bits/kernel_sigaction.h +as an authoritative source: + +HAVE_SA_RESTORER is #defined +struct old_kernel_sigaction { + unsigned sa_flags; + sighandler_t k_sa_handler; + unsigned long sa_mask; + unsigned pad0[3]; /* reserved, keep size constant */ + /* Abi says here follows reserved int[2] */ + void (*sa_restorer)(void); +#if (_MIPS_SZPTR < 64) + /* For 32 bit code we have to pad struct sigaction to get + * constant size for the ABI */ + int pad1[1]; /* reserved */ +#endif +}; +struct kernel_sigaction { + unsigned int sa_flags; + sighandler_t k_sa_handler; + kernel_sigset_t sa_mask; + void (*sa_restorer)(void); + int s_resv[1]; /* reserved */ +}; +struct sigaction { + unsigned sa_flags; + sighandler_t sa_handler; + sigset_t sa_mask; + /* The ABI says here are two unused ints following. */ + /* Restore handler. */ + void (*sa_restorer)(void); +#if _MIPS_SZPTR < 64 + int sa_resv[1]; +#endif +}; + +IA64: + +Has no old_sigaction. What a relief. + +struct kernel_sigaction { + sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; +struct sigaction { + sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + +Alpha: + +struct old_kernel_sigaction { + sighandler_t k_sa_handler; + unsigned long sa_mask; + unsigned sa_flags; +}; +struct kernel_sigaction { + sighandler_t k_sa_handler; + unsigned sa_flags; + sigset_t sa_mask; +}; +struct sigaction { + sighandler_t sa_handler; + sigset_t sa_mask; + unsigned sa_flags; +}; + +HPPA: + +struct kernel_sigaction { + sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; +struct sigaction { + sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + +The rest, kernel side: + +HAVE_SA_RESTORER #defined +struct old_kernel_sigaction { + sighandler_t k_sa_handler; + unsigned long sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; +struct kernel_sigaction { + sighandler_t k_sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +}; + +On userspace side, Sparc has special struct sigaction: + +struct sigaction { + sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); /* Not used by Linux/Sparc */ +}; + +And finally the rest has: + +struct sigaction { + sighandler_t sa_handler; + sigset_t sa_mask; + int sa_flags; + void (*sa_restorer)(void); +}; + +Userspace sigset_t was uniformly defined as vector of longs +big enough to hold 1024 (!) bits - carried over from glibc. +Since the only arch whose struct kernel_sigaction contains sa_mask +not as a last member is MIPS, MIPS has special kernel_sigset_t, +which is an array of longs long enough for 128 bits. +Other arches still used userspace sigset_t in struct kernel_sigaction, +but it did not really matter because overlong kernel_sigaction +does not hurt in sigaction() [explained below]. +On kernel side, all arches define _NSIG to 65 (meaning +there are 64 signals, 1..64) except MIPS, which define it to 129. + + + Functions + +sigaction() [libc function] usually has two kernel_sigaction's +on stack and copy (userspace) struct sigaction members into +first one, executes syscall, then pulls out the result from +second one. This accomodates differences in layouts of structs. + +The only typically present quirk is what to do with sa_restorer. + + libc/sysdeps/linux/arm/sigaction.c + +if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set, +sets sa_restorer to +(flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer, +and sets SA_RESTORER, +otherwise passes it as-is. Which is kinda strange, because AFAICS +HAVE_SA_RESTORER is *not* defined for ARM. + + libc/sysdeps/linux/i386/sigaction.c + +Forcibly sets SA_RESTORER and sa_restorer: +kact.sa_flags = act->sa_flags | SA_RESTORER; +kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore); + + libc/sysdeps/linux/x86_64/sigaction.c + +Forcibly sets SA_RESTORER and sa_restorer: +kact.sa_flags = act->sa_flags | SA_RESTORER; +kact.sa_restorer = &restore_rt; + + libc/sysdeps/linux/mips/sigaction.c + +# ifdef HAVE_SA_RESTORER +# if _MIPS_SIM == _ABIO32 + kact.sa_restorer = act->sa_restorer; +# else + kact.sa_restorer = &restore_rt; +# endif +# endif +No confusion here, HAVE_SA_RESTORER is #defined for MIPS + + libc/sysdeps/linux/avr32/sigaction.c + +if (kact.sa_flags & SA_RESTORER) { + kact.sa_restorer = act->sa_restorer; +} else { + kact.sa_restorer = __default_rt_sa_restorer; + kact.sa_flags |= SA_RESTORER; +} +Does not check HAVE_SA_RESTORER, but avr32 falls +in "completely ordinary" category on both kernel and +userspace sides, and those have it defined. + + libc/sysdeps/linux/xtensa/sigaction.c + +if (kact.sa_flags & SA_RESTORER) { + kact.sa_restorer = act->sa_restorer; +} else { + kact.sa_restorer = __default_sa_restorer; + kact.sa_flags |= SA_RESTORER; +} +Thus, similar to avr32. + + libc/signal/sigaction.c (i.e. the all other arches) + +# ifdef HAVE_SA_RESTORER + kact.sa_restorer = act->sa_restorer; +# endif +Plain translation, just sa_restorer copy is protected +by HAVE_SA_RESTORER #define check. Looks like here +HAVE_SA_RESTORER will be undef'ed only for IA64, +Alpha an HPPA. + + + Proposed overhaul past 0.9.30 + +Since we can define libc-side structures at will: +make sigset_t and struct sigaction identical on kernel side and libc side +within each arch. If arches do not need special handling of sa_restorer, +then sigaction() can directly use passed struct sigaction as-is. +Otherwise, a copy is still needed, although sigaction() might have +just one struct kernel_sigaction on stack and use it both for passing +data to kernel and for receiving it back. Might save a few bytes. + +To this effect: + +* Make sigset_t size match kernel side on all arches. + This is easy since all arches have 64 signals and only MIPS has 128. + +* Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h + so that its struct sigaction matches kernel's. If sa_restorer + field is present in libc but is missing in kernel_sigaction, + add it at the bottom in order to not mess up kernel_sigaction layout. + +* Modify libc/sysdeps/linux/$ARCH/sigaction.c + to implement the logic above. In "common" pseudo-arch + (libc/signal/sigaction.c file), + we would not even need to do any copying, as described above. + +* Document discovered arch quirks while debugging this mess. + +* struct old_kernel_sigaction can't be disposed of in a similar way, + we need to have userspace struct sigaction unchanged regardless + whether we use "old" or "new" kernel sigaction() syscall. + It's moot anyway because "old" one is long unused, it's from + pre-2.2 kernels. diff --git a/utils/Makefile.in b/utils/Makefile.in index 26ed70058..e3bf4115a 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -5,13 +5,7 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -ifdef UCLIBC_LDSO -ifeq (,$(findstring /,$(UCLIBC_LDSO))) -UCLIBC_LDSO := $(RUNTIME_PREFIX)lib/$(UCLIBC_LDSO) -endif -endif - -CFLAGS-utils := -DNOT_IN_libc $(SSP_ALL_CFLAGS) -B$(top_builddir)lib -Wl,-rpath-link,$(top_builddir)lib -Wl,--dynamic-linker,$(UCLIBC_LDSO) +CFLAGS-utils := -DNOT_IN_libc $(SSP_ALL_CFLAGS) -B$(top_builddir)lib -Wl,-rpath-link,$(top_builddir)lib CFLAGS-utils-common := -I$(top_srcdir)ldso/include -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" -DUCLIBC_LDSO=$(UCLIBC_LDSO) CFLAGS-utils-shared := $(PIEFLAG) $(LDPIEFLAG) @@ -53,9 +47,7 @@ utils_OUT := $(top_builddir)utils DEPS-ldconfig := $(utils_DIR)/chroot_realpath.c DEPS-ldconfig.host := $(DEPS-ldconfig) -# Note: readelf util is provided by binutils -# utils_OBJ := readelf - +utils_OBJ := readelf ifeq ($(HAVE_SHARED),y) utils_OBJ += ldconfig ldd endif @@ -91,15 +83,17 @@ $(hostutils_OBJ): $(utils_OUT)/%.host : $(utils_DIR)/%.c install-y += utils_install -utils_install: utils - #$(Q)$(INSTALL) -D -m 755 $(utils_OUT)/readelf $(PREFIX)$(RUNTIME_PREFIX)usr/bin/readelf +# This installs both utils and hostutils, so doesn't depend on either. + +utils_install: + $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/readelf$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)bin/readelf ifeq ($(HAVE_SHARED),y) - $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldd $(PREFIX)$(RUNTIME_PREFIX)usr/bin/ldd - $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldconfig $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig + $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldd$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)bin/ldd + $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/ldconfig$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)sbin/ldconfig endif ifeq ($(UCLIBC_HAS_LOCALE),y) - $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/iconv $(PREFIX)$(RUNTIME_PREFIX)usr/bin/iconv - $(Q)$(INSTALL) -m 755 $(utils_OUT)/locale $(PREFIX)$(RUNTIME_PREFIX)usr/bin/locale + $(Q)$(INSTALL) -D -m 755 $(utils_OUT)/iconv$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)bin/iconv + $(Q)$(INSTALL) -m 755 $(utils_OUT)/locale$(DOTHOST) $(PREFIX)$(RUNTIME_PREFIX)bin/locale endif objclean-y += utils_clean |