https://blogs.gentoo.org/ago/2020/07/04/gentoo-tinderbox/ Issue: app-emulation/qemu-9.1.1 has implicit function declarations in configure logs. Discovered on: amd64 (internal ref: ci) Info about the issue: https://wiki.gentoo.org/wiki/Project:Tinderbox/Common_Issues_Helper#QA0072
Created attachment 907412 [details] build.log.xz build log and emerge --info (compressed because it exceeds attachment limit, use 'xzless' to read it)
Found the following implicit function declarations in configure logs: meson-log.txt:3114 - elf_aux_info meson-log.txt:3570 - elf_aux_info
Created attachment 908039 [details, diff] replace-elf_aux_info-with-getauxval.patch In linux, there's no such function as elf_aux_info defined in auxv.h. But there's something else that works - getauxval. Using getauxval instead get's rid of the issue and I think it is the correct approach, but Im not 100% sure, so would be nice if someone could verify this. Issue: implicit function declaration for elf_aux_info function. Reason: Function not defined in linux in sys/auxv.h header. Solution: Replacing elf_aux_info function with getauxval.
One more think I was wondering about is if this patch wouldn't break freebsd implementation, as there probably elf_aux_info works. I'll try to install it in some VM and if it's the case adjust the patch for both. But still please verify if this is the correct way to fix this in linux.
Created attachment 908067 [details, diff] fix_aux_functions_availibility_checks.patch After installing FreeBSD and some tests I think I have a better solution now, which should be universal. So the problem comes down to this few things: - Linux uses getauxval function, while FreeBSD uses elf_aux_info. One of these is defined in sys/auxv.h, depending on the OS. - meson.build have tests that should set config flags CONFIG_ELF_AUX_INFO and CONFIG_GETAUXVAL, based on the availability of these functions - It was doing this by trying to run the code that uses them, and if code failed to compile it set's the flag to false. I have replaced the meson functions, so that instead of building the code, it checks for functions availability using cc.has_function. I've tested this on Gentoo and FreeBSD, and both had flags set correctly in user-build/config-host.h.
Comment on attachment 908067 [details, diff] fix_aux_functions_availibility_checks.patch >-config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' >- #include <sys/auxv.h> >- int main(void) { >- return getauxval(AT_HWCAP) == 0; >- }''')) >- >-config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + ''' >- #include <sys/auxv.h> >- int main(void) { >- unsigned long hwcap = 0; >- elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); >- return hwcap; >- }''')) These existing checks are prone to false positives: if the header exists but doesn't define the function used, then with gcc 13 it succeeds at compiling and fails to *link*, and with gcc 14 it fails to compile at all. It's using a direct function call and the function is simply *not available* in libc. Meson's builtin has_function can do the same thing using generic code that doesn't know what values to try passing to the function -- it just checks if it is defined. That check doesn't fall prey to false positives. >+# Check for getauxval and elf_aux_info function availibility. >+if cc.has_header('sys/auxv.h') >+ config_host_data.set('CONFIG_GETAUXVAL', cc.has_function('getauxval')) >+ config_host_data.set('CONFIG_ELF_AUX_INFO', cc.has_function('elf_aux_info')) >+else >+ config_host_data.set('CONFIG_GETAUXVAL', false) >+ config_host_data.set('CONFIG_ELF_AUX_INFO', false) >+endif You should always use the prefix: '#include <sys/auxv.h>' parameter to has_function, if you know what header it comes from. For two reasons: - it allows you to collapse two compile checks into one. The has_function check will only succeed if the include is valid - you force it to verify that the function is defined in that specific header. It means that you won't end up ever accidentally detecting the function is available in the given header, when in reality it is defined in a *different* header
(In reply to Eli Schwartz from comment #6) > Comment on attachment 908067 [details, diff] [details, diff] > fix_aux_functions_availibility_checks.patch > > >-config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' > >- #include <sys/auxv.h> > >- int main(void) { > >- return getauxval(AT_HWCAP) == 0; > >- }''')) > >- > >-config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + ''' > >- #include <sys/auxv.h> > >- int main(void) { > >- unsigned long hwcap = 0; > >- elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); > >- return hwcap; > >- }''')) > > > These existing checks are prone to false positives: if the header exists but > doesn't define the function used, then with gcc 13 it succeeds at compiling > and fails to *link*, and with gcc 14 it fails to compile at all. > > It's using a direct function call and the function is simply *not available* > in libc. > > Meson's builtin has_function can do the same thing using generic code that > doesn't know what values to try passing to the function -- it just checks if > it is defined. That check doesn't fall prey to false positives. > > > >+# Check for getauxval and elf_aux_info function availibility. > >+if cc.has_header('sys/auxv.h') > >+ config_host_data.set('CONFIG_GETAUXVAL', cc.has_function('getauxval')) > >+ config_host_data.set('CONFIG_ELF_AUX_INFO', cc.has_function('elf_aux_info')) > >+else > >+ config_host_data.set('CONFIG_GETAUXVAL', false) > >+ config_host_data.set('CONFIG_ELF_AUX_INFO', false) > >+endif > > > You should always use the prefix: '#include <sys/auxv.h>' parameter to > has_function, if you know what header it comes from. For two reasons: > > - it allows you to collapse two compile checks into one. The has_function > check will only succeed if the include is valid > > - you force it to verify that the function is defined in that specific > header. It means that you won't end up ever accidentally detecting the > function is available in the given header, when in reality it is defined in > a *different* header Thank you for verifying this Eli Schwartz. So when using has_function I understand that it should be reduced to: > config_host_data.set('CONFIG_GETAUXVAL', cc.has_function('getauxval', prefix : '#include <sys/auxv.h>')) > config_host_data.set('CONFIG_ELF_AUX_INFO', cc.has_function('elf_aux_info', prefix : '#include <sys/auxv.h>')) But since cc.has_function only checks for the function existence and not the parameters it takes, it is not acceptable fix for this, if I understand correctly.
That depends on whether qemu is concerned that this function may exist but take different parameters on different systems. It's entirely possible they simply ported an existing check from their previous build system which didn't have "cc.has_function". Best way to find out is asking upstream qemu developers, I guess. :)
ci has reproduced this issue with version 9.1.2 - Updating summary.
That section was added to meson.build upstream 4 months ago in this commit: util/cpuinfo: Make use of elf_aux_info(3) on OpenBSD https://gitlab.com/qemu-project/qemu/-/commit/27fca0a0d560ae704457c5f89e0be658afef034d It looks like this is just meson checking to see if elf_aux_info() is available and setting CONFIG_ELF_AUX_VAL if it is. Then that and some other defines are used in qemu's getauxval.c and elsewhere to call getauxval() on linux, else elf_aux_val() if it's available, else fail with ENOSYS. If so then this isn't a problem in qemu and any patch would be a mistake, and the real problem is tinderbox reporting normal behavior as an invalid bug?
ci has reproduced this issue with version 9.2.0 - Updating summary.