Browse Source

Fix header installation for recent 64-only arch

Recent arch do not support Legacy.

But this led to per-arch headers not being installed and common-generic ones taking precedence.

So it was impossible to declare arch-specific statfs.h for instance, to force 64-bit mode only.

This was leading to the following situation to happen:
1/ an application compiles (say without -D_FILE_OFFSET_BITS set)
   it therefore uses struct statfs from libc/sysdeps/linux/common-generic/bits/statfs.h
   where f_type and f_bsize fields are U32:
2/ application calls "statfs"
3/ uClibc issues "statfs64" syscall (because __NR_statfs64 is defined and __NR_statfs is undefined):
4/ if Linux kernel port is not defining CONFIG_COMPAT, it calls do_statfs_native
5/ it does copy_to_user of the size of struct statfs defined in the kernel source tree:
6/ Generic struct statfs in the kernel is defined like this:
f_type and f_bsize fields are long (64 bits) for 64-bit archs.
7/ memory corruption occurs because of this mismatch

Allow to not define __ARCH_HAS_DEPRECATED_SYSCALLS__ *and* declare its own arch-specific statfs.h header, matching the kernel one.
(for instance with f_type and f_bsize defined as long)

Does this change break other archs?
This change allows headers in libc/sysdeps/linux/<ARCH>/bits/ to override ones in libc/sysdeps/linux/common-generic/bits/
The only arch which does not define __ARCH_HAS_DEPRECATED_SYSCALLS__ *and* has a header in libc/sysdeps/linux/<ARCH>/bits/ which can conflict with one in libc/sysdeps/linux/common-generic/bits/
is c6x.
The file that can override is ../libc/sysdeps/linux/c6x/bits/kernel_stat.h
  This, btw, means that, today, this file is there and is not used (during compilation, GNU Make overrides the rule): warning: overriding recipe for target `include/bits/kernel_stat.h' warning: ignoring old recipe for target `include/bits/kernel_stat.h'
I was not able to compile uClibc with the only binary toolchain I found for c6x arch (gcc-4.5.1 from code sourcery:
However, I can tell that c6x's kernel_stat.h only defines two structs: kernel_stat and kernel_stat64:
And I can also tell that those structs are only used when using xstat conversion functions (__xstat32_conv / xstat_conv) which are only used and present in the __ARCH_HAS_DEPRECATED_SYSCALLS__ == y case.
However, c6x does not define __ARCH_HAS_DEPRECATED_SYSCALLS__
So I think I can say that this change does not affect c6x nor other archs.
Yann Sionneau 1 year ago
1 changed files with 3 additions and 3 deletions
  1. 3 3

+ 3 - 3

@@ -144,14 +144,14 @@ $(top_builddir)include/dl-osinfo.h $(top_builddir)include/not-cancel.h:
 	$(do_ln) $(call rel_srcdir)libc/sysdeps/linux/common/bits/$(@F) $@
-	$(do_ln) $(call rel_srcdir)libc/sysdeps/linux/$(TARGET_ARCH)/bits/$(@F) $@
 	$(do_ln) $(call rel_srcdir)libc/sysdeps/linux/common-generic/bits/$(@F) $@
+	$(do_ln) $(call rel_srcdir)libc/sysdeps/linux/$(TARGET_ARCH)/bits/$(@F) $@
 ifneq ($(TARGET_SUBARCH),)
 	$(do_ln) $(call rel_srcdir)libc/sysdeps/linux/$(TARGET_ARCH)/bits/$(TARGET_SUBARCH)/$(@F) $@