[PATCH] [RFC] determine specifics using gcc -dumpmachine instead of uname -m

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



uname -m is unreliable as the host architecture might not match the
target architecture. This can happen when cross compiling or (more
common) if you are running a 32 bit userspace on a 64 bit kernel. The
latter makes sparse fail to build on some machines of the Debian build
farm as for example some armhf builder run on arm64 kernels.

This patch is only lightly tested and also misses details for mips* and
so marked as RFC.

Signed-off-by: Uwe Kleine-König <uwe@xxxxxxxxxxxxxxxxx>
---
 cgcc | 87 +++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 65 insertions(+), 22 deletions(-)

diff --git a/cgcc b/cgcc
index 629124b9412e..176c14c35adb 100755
--- a/cgcc
+++ b/cgcc
@@ -339,28 +339,71 @@ sub add_specs {
 	chomp $os;
 	return &add_specs (lc $os);
     } elsif ($spec eq 'host_arch_specs') {
-	my $arch = `uname -m`;
-	chomp $arch;
-	if ($arch =~ /^(i.?86|athlon)$/i) {
-	    return &add_specs ('i386');
-	} elsif ($arch =~ /^(sun4u)$/i) {
-	    return &add_specs ('sparc');
-	} elsif ($arch =~ /^(x86_64)$/i) {
-	    return &add_specs ('x86_64');
-	} elsif ($arch =~ /^(ppc)$/i) {
-	    return &add_specs ('ppc');
-	} elsif ($arch =~ /^(ppc64)$/i) {
-	    return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1';
-	} elsif ($arch =~ /^(ppc64le)$/i) {
-	    return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2';
-	} elsif ($arch =~ /^(s390x)$/i) {
-	    return &add_specs ('s390x');
-	} elsif ($arch =~ /^(sparc64)$/i) {
-	    return &add_specs ('sparc64');
-	} elsif ($arch =~ /^arm(?:v[78]l)?$/i) {
-	    return &add_specs ('arm');
-	} elsif ($arch =~ /^(aarch64)$/i) {
-	    return &add_specs ('aarch64');
+	chomp(my $gccmachine = `$cc -dumpmachine`);
+
+	if ($gccmachine eq 'aarch64-linux-gnu') {
+	    return (' -m64' . &float_types (1, 1, 36, [24, 8], [53, 11], [113, 15]));
+
+	} elsif ($gccmachine eq 'arm-linux-gnueabi') {
+	    return (' -m32' .  &float_types (1, 1, 36, [24, 8], [53,11], [53, 11]));
+
+	} elsif ($gccmachine eq 'arm-linux-gnueabihf') {
+	    return (' -m32 -D__ARM_PCS_VFP=1' .  &float_types (1, 1, 36, [24,8], [53,11], [53, 11]));
+
+	} elsif ($gccmachine eq 'i686-linux-gnu') {
+	    return &float_types (1, 1, 21, [24, 8], [53, 11], [64, 15]);
+
+	} elsif ($gccmachine eq 'mips-linux-gnu') {
+	    # ???
+
+	} elsif ($gccmachine eq 'mipsel-linux-gnu') {
+	    # ???
+
+	} elsif ($gccmachine eq 'mips64el-linux-gnuabi64') {
+	    # ???
+
+	} elsif ($gccmachine eq 'powerpc64le-linux-gnu') {
+	    return (' -D_STRING_ARCH_unaligned=1 -m64 -mlittle-endian -D_CALL_ELF=2' .  &float_types (1, 1, 21, [24,8], [53,11], [113,15]));
+
+	} elsif ($gccmachine eq 's390x') {
+
+	    return (' -D_BIG_ENDIAN' .
+		&integer_types (8, 16, 32, $m64 ? 64 : 32, 64) .
+		&float_types (1, 1, 36, [24,8], [53,11], [113,15]) .
+		&define_size_t ("long unsigned int") .
+		' -D__SIZEOF_POINTER__=' . ($m64 ? '8' : '4'));
+
+	} elsif ($gccmachine eq 'x86_64-linux-gnu') {
+	    return &float_types (1, 1, 33, [24, 8], [53, 11], [113, 15]);
+
+	} else {
+	    # fall back to uname -m to determine the specifics. Note this is
+	    # unstable as we might run an i386 compiler on an amd64 box or even
+	    # a hppa compiler on s390x.
+
+	    my $arch = `uname -m`;
+	    chomp $arch;
+	    if ($arch =~ /^(i.?86|athlon)$/i) {
+		return &add_specs ('i386');
+	    } elsif ($arch =~ /^(sun4u)$/i) {
+		return &add_specs ('sparc');
+	    } elsif ($arch =~ /^(x86_64)$/i) {
+		return &add_specs ('x86_64');
+	    } elsif ($arch =~ /^(ppc)$/i) {
+		return &add_specs ('ppc');
+	    } elsif ($arch =~ /^(ppc64)$/i) {
+		return &add_specs ('ppc64') . ' -mbig-endian -D_CALL_ELF=1';
+	    } elsif ($arch =~ /^(ppc64le)$/i) {
+		return &add_specs ('ppc64') . ' -mlittle-endian -D_CALL_ELF=2';
+	    } elsif ($arch =~ /^(s390x)$/i) {
+		return &add_specs ('s390x');
+	    } elsif ($arch =~ /^(sparc64)$/i) {
+		return &add_specs ('sparc64');
+	    } elsif ($arch =~ /^arm(?:v[78]l)?$/i) {
+		return &add_specs ('arm');
+	    } elsif ($arch =~ /^(aarch64)$/i) {
+		return &add_specs ('aarch64');
+	    }
 	}
     } else {
 	die "$0: invalid specs: $spec\n";
-- 
2.20.1




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux