summaryrefslogtreecommitdiff
path: root/src/hwf-x86.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2021-04-28 19:19:15 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2021-04-28 21:26:17 +0300
commitec87511d9cd2dc31434e939b6351d74a38d4ceaa (patch)
treeabdf2b75b900714ddab86ed7dc69f106b604eb7c /src/hwf-x86.c
parent060c378c050e7ec6206358c681a313d6e1967dcf (diff)
downloadlibgcrypt-ec87511d9cd2dc31434e939b6351d74a38d4ceaa.tar.gz
hwf-x86: fix use of wrong operand type
* src/hwf-x86.c (get_cpuid): Use xchg for swapping %ebx back and forth between operand register. -- HW feature routine was giving wrong results with certain compiler & compiler flag combinations on i386. Issue was that "=g" operand was used which caused problem if compiler allocated %ebx register for this operand. CPUID assembly block attempts to save %ebx as in older GCC versions this register was fixed for GOT pointer use and could not be modified otherwise (could not be used as operand or clobber). Reported-by: Iru Cai <vimacs@disroot.org> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'src/hwf-x86.c')
-rw-r--r--src/hwf-x86.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/src/hwf-x86.c b/src/hwf-x86.c
index 91e4c411..a1aa02e7 100644
--- a/src/hwf-x86.c
+++ b/src/hwf-x86.c
@@ -83,14 +83,12 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
unsigned int regs[4];
asm volatile
- ("movl %%ebx, %%edi\n\t" /* Save GOT register. */
- "xorl %%ebx, %%ebx\n\t"
+ ("xchgl %%ebx, %1\n\t" /* Save GOT register. */
"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"
+ "xchgl %%ebx, %1\n\t" /* Restore GOT register. */
+ : "=a" (regs[0]), "=D" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+ : "0" (in), "1" (0), "2" (0), "3" (0)
+ : "cc"
);
if (eax)