cpufrequtils: handle i386 -fPIC case

One problem with the cpuid instruction is that it uses %ebx which,
when code is compiled as PIC for i386, is used as the PIC base register.
This patch tries to handle this case by replacing the second register (%1)
constraint with "=r", i.e. any (other) register, and swapping %ebx and %1
around the cpuid instruction.

This patch could use a test, preferably on real i686 hardware.
At least it needs some review and perhaps inspection of the generated
assembler output.

The idea and reasoning was taken from this comment:
http://gcc.gnu.org/ml/gcc-patches/2007-09/msg00324.html
This commit is contained in:
Jürgen Buchmüller 2016-10-13 22:35:24 +02:00
parent cd4263ead7
commit 973b27b91d
2 changed files with 36 additions and 4 deletions

View File

@ -0,0 +1,33 @@
--- utils/cpuid.h 2010-07-05 17:43:17.000000000 +0200
+++ utils/cpuid.h 2016-10-13 22:31:26.988374329 +0200
@@ -1,6 +1,21 @@
#ifndef _CPUFREQ_CPUID_H
#define _CPUFREQ_CPUID_H
+#if defined(__i386__) && defined(__PIC__)
+static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
+{
+ /* ecx is often an input as well as an output. */
+ asm volatile("xchgl\t%%ebx, %1\n\t" \
+ "cpuid\n\t" \
+ "xchgl\t%%ebx, %1"
+ : "=a" (*eax),
+ "=r" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (*eax), "2" (*ecx));
+}
+#else
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
@@ -12,6 +27,8 @@
"=d" (*edx)
: "0" (*eax), "2" (*ecx));
}
+#endif
+
static inline void cpuid(unsigned int op,
unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)

View File

@ -1,14 +1,13 @@
# Template file for 'cpufrequtils'
pkgname=cpufrequtils
version=008
revision=10
revision=11
short_desc="Userspace tools for the Linux kernel cpufreq subsystem"
homepage="ftp://ftp.archlinux.org/other/cpufrequtils/"
license="GPL-2"
maintainer="Juan RP <xtraeme@voidlinux.eu>"
distfiles="https://www.kernel.org/pub/linux/utils/kernel/cpufreq/${pkgname}-${version}.tar.xz"
distfiles="${KERNEL_SITE}/utils/kernel/cpufreq/${pkgname}-${version}.tar.xz"
checksum=a2149db551f83112209b1a8e79bd50d386979bbf64edbc69126f4e0b4f0a4cab
nopie=yes
only_for_archs="i686 i686-musl x86_64 x86_64-musl"
@ -29,7 +28,7 @@ libcpufreq_package() {
libcpufreq-devel_package() {
conflicts="libcpupower-devel>=0"
depends="libcpufreq>=${version}_${revision}"
short_desc="libcpufreq - development tools"
short_desc="Library for the kernel cpufreq subsystem - development tools"
pkg_install() {
vmove usr/include
vmove "usr/lib/*.so"