Mailing List Archive

i386 get_cpuid() function looks wrong
Hello,

I built libgcrypt for 32-bit x86, and it reports wrong CPU hardware
features. After some debugging, I found the get_cpuid() function go
wrong. This function use some inline assembly code:

asm volatile
("movl %%ebx, %%edi\n\t" /* Save GOT register. */
"xorl %%ebx, %%ebx\n\t"
"cpuid\n\t"
"movl %%ebx, %1\n\t"
"movl %%edi, %%ebx\n\t" /* Restore GOT register. */
: "=a" (regs[0]), "=g" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
: "0" (in), "2" (0), "3" (0)
: "cc", "edi"
);

When I build libgcrypt with CFLAGS '-m32 -march=i686 -Os', '%1' in the
above assembly code can be assigned to ebx, thus the code go wrong.
After checking the GCC manual, "=g" means any register, so the compiler
can allocate ebx to it.

Regards,
Iru

_______________________________________________
Gcrypt-devel mailing list
Gcrypt-devel@gnupg.org
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Re: i386 get_cpuid() function looks wrong [ In reply to ]
Hello,

On 28.4.2021 4.27, Iru Cai via Gcrypt-devel wrote:
> Hello,
>
> I built libgcrypt for 32-bit x86, and it reports wrong CPU hardware features. After some debugging, I found the get_cpuid() function go wrong. This function use some inline assembly code:
>
>   asm volatile
>     ("movl %%ebx, %%edi\n\t"     /* Save GOT register.  */
>      "xorl %%ebx, %%ebx\n\t"
>      "cpuid\n\t"
>      "movl %%ebx, %1\n\t"
>      "movl %%edi, %%ebx\n\t"     /* Restore GOT register. */
>      : "=a" (regs[0]), "=g" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
>      : "0" (in), "2" (0), "3" (0)
>      : "cc", "edi"
>      );
>
> When I build libgcrypt with CFLAGS '-m32 -march=i686 -Os', '%1' in the above assembly code can be assigned to ebx, thus the code go wrong. After checking the GCC manual, "=g" means any register, so the compiler can allocate ebx to it.
>

Thanks for reporting this.

You're right, that "=g" is wrong there. I've attached patch that fixes issue by using %edi register operand instead and swapping %ebx contents with %edi before and after cpuid.

-Jussi