alsa-project / alsa-lib

The Advanced Linux Sound Architecture (ALSA) - library
GNU Lesser General Public License v2.1
366 stars 177 forks source link

pcm_old.h does not work with LTO #281

Closed kkofler closed 1 year ago

kkofler commented 1 year ago

Applications using ALSA_PCM_OLD_HW_PARAMS_API and/or ALSA_PCM_OLD_SW_PARAMS_API get miscompiled if they are compiled with -flto (GCC link-time optimization (LTO)). See https://bugzilla.redhat.com/show_bug.cgi?id=1910437 and in particular https://bugzilla.redhat.com/show_bug.cgi?id=1910437#c23 .

The issue is that the pcm_old.h header uses constructs like:

asm(".symver snd_pcm_hw_params_set_rate_near,snd_pcm_hw_params_set_rate_near@ALSA_0.9");

which do not seem to work with LTO enabled. Maybe this needs to use the symver attribute instead?

In any case, what happens is that the caller in the application attempts to call the new function snd_pcm_hw_params_set_rate_near@ALSA_0.9.0rc4 with the ABI of the old one snd_pcm_hw_params_set_rate_near@ALSA_0.9, so an integer is passed where ALSA expects a pointer, leading to a segfault (or worse).

The workaround is to compile the application without LTO enabled (which makes it work fine), but I believe that this is an upstream ALSA issue and should be fixed in the ALSA header files.

kkofler commented 1 year ago

Also filed downstream in Fedora as: https://bugzilla.redhat.com/show_bug.cgi?id=2140999

geraldog commented 1 year ago

Maybe this needs to use the symver attribute instead?

This is a GCC >= 10 exclusive attribute, hence if using it we need to keep compatibility with Clang at least, something like https://github.com/OpenMandrivaAssociation/kernel-rc/blob/master/linux-5.16-clang-no-attribute-symver.patch

perexg commented 1 year ago

I cannot confirm. Trying code https://raw.githubusercontent.com/alsa-project/alsa-lib/master/test/oldapi.c:

$ gcc -flto -lasound -o oldapi oldapi.c $ nm oldapi | grep get_access U snd_pcm_hw_params_get_access@ALSA_0.9

So .symver does work as expected. Also checked the snd_pcm_hw_params_set_rate_near function.

Also, I don't know other way to to tell gcc which symbol is wanted. The symver function attribute is for the function definition (code in the library). It cannot be used in the header files (we need to keep the .symver asm code).

Some cleanup are in 161f47da5f196c291ac0e11d066fa5ff5f79fa04 and 152983f01b0bc1178ea0d461ebf66e2d2a8e2e02, but this should not change anything for this problem.

perexg commented 1 year ago

Stale and probably gcc related.