Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -57,15 +57,30 @@ static OF_INLINE struct cpuid_regs OF_CONST_FUNC cpuid(uint32_t eax, uint32_t ecx) { struct cpuid_regs regs; -#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM) +#if defined(OF_X86_64_ASM) __asm__( "cpuid" : "=a"(regs.eax), "=b"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx) : "a"(eax), "c"(ecx) + ); +#elif defined(OF_X86_ASM) + /* + * This workaround is required by GCC when using -fPIC, as ebx is a + * special register in PIC code. Yes, GCC is indeed not able to just + * push a register onto the stack before the __asm__ block and to pop + * it afterwards. + */ + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %1\n\t" + "popl %%ebx" + : "=a"(regs.eax), "=r"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx) + : "a"(eax), "c"(ecx) ); #else regs.eax = regs.ebx = regs.ecx = regs.edx = 0; #endif