[PATCH] options: allow to specify the desired arch with --arch=<arch>

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

 



Sparse is universal in the sense that the same executable can
be used for all architectures. For this, most arch-specific
setting can be set with an option and the default values
are taken from the host machine.

This is working nicely for native targets. However, for cross-
compilation, while seeming to work relatively well (thanks to
the kernel build system using -m32/-m64 for all archs, for example)
things can never work 100% correctly. For example, in the case
an X86-64 host machine is used for an ARM target, the kernel
build system will call sparse with -m32, Sparse will 'autodetect'
the target arch as i386 (x86-64 + -m32) and will then predefine
the macro __i386__. Most of the time this is not a problem (at
least for the kernel) unless, of course, if the code contains
something like:
	#ifdef __i386__
	...
	#elif  __arm__
	...

So, add an option --arch=<arch> to specify the target architecture.
The native arch is still used if no such flag is given.

Reported-by: Ben Dooks <ben.dooks@xxxxxxxxxxxxxxx>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 lib.c    | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sparse.1 |  8 +++++++
 2 files changed, 76 insertions(+)

diff --git a/lib.c b/lib.c
index 75a4f9870..353d19100 100644
--- a/lib.c
+++ b/lib.c
@@ -1044,6 +1044,73 @@ static char **handle_switch_x(char *arg, char **next)
 }
 
 
+static char **handle_arch(char *arg, char **next)
+{
+	static const struct arch {
+		const char *name;
+		int mach;
+		int bits;
+	} archs[] = {
+		{ "aarch64",	MACH_ARM64,	64 },
+		{ "arm64",	MACH_ARM64,	64 },
+		{ "arm",	MACH_ARM,	32 },
+		{ "i386",	MACH_I386,	32 },
+		{ "m68k",	MACH_M68K,	32 },
+		{ "mips",	MACH_MIPS64 },
+		{ "powerpc",	MACH_PPC64 },
+		{ "ppc",	MACH_PPC64 },
+		{ "riscv",	MACH_RISCV64 },
+		{ "s390",	MACH_S390X,	64 },
+		{ "s390x",	MACH_S390X,	64 },
+		{ "sparc",	MACH_MIPS64 },
+		{ "x86_64",	MACH_X86_64,	64 },
+		{ "x86-64",	MACH_X86_64,	64 },
+		{ "x86",	MACH_X86_64 },
+		{ NULL },
+	};
+	const struct arch *p;
+
+	if (*arg++ != '=')
+		die("missing argument for --arch option");
+
+	for (p = &archs[0]; p->name; p++) {
+		size_t len = strlen(p->name);
+		if (strncmp(p->name, arg, len) == 0) {
+			const char *suf = arg + len;
+			int bits = p->bits;
+
+			arch_mach = p->mach;
+			if (bits == 0) {
+				// guess the size of the architecture
+				if (!strcmp(suf, "")) {
+					if (arch_m64 == ARCH_LP32)
+						bits = 32;
+					else
+						bits = 64;
+				} else if (!strcmp(suf, "64")) {
+					bits = 64;
+				} else if (!strcmp(suf, "32")) {
+					bits = 32;
+				} else {
+					die("invalid architecture: %s", arg);
+				}
+				if (bits == 32)
+					arch_mach -= 1;
+			} else {
+				if (strcmp(suf, ""))
+					die("invalid architecture: %s", arg);
+			}
+			if (p->bits == 32)
+				arch_m64 = ARCH_LP32;
+			else if (p->bits == 64)
+				arch_m64 = ARCH_LP64;
+			break;
+		}
+	}
+
+	return next;
+}
+
 static char **handle_version(char *arg, char **next)
 {
 	printf("%s\n", SPARSE_VERSION);
@@ -1076,6 +1143,7 @@ struct switches {
 static char **handle_long_options(char *arg, char **next)
 {
 	static struct switches cmd[] = {
+		{ "arch", handle_arch, 1 },
 		{ "param", handle_param, 1 },
 		{ "version", handle_version },
 		{ NULL, NULL }
diff --git a/sparse.1 b/sparse.1
index beb484423..be38f6883 100644
--- a/sparse.1
+++ b/sparse.1
@@ -423,6 +423,14 @@ Sparse does not issue these warnings by default.
 .
 .SH MISC OPTIONS
 .TP
+.B \-\-arch=\fIARCH\fR
+Specify the target architecture.
+For architectures having both a 32-bit and a 64-bit variant (mips, powerpc,
+riscv & sparc) the architecture name can be suffixed with \fI32\fR or \fI64\fR.
+
+The default architecture & size is the one of the machine used to build Sparse.
+.
+.TP
 .B \-gcc-base-dir \fIdir\fR
 Look for compiler-provided system headers in \fIdir\fR/include/ and \fIdir\fR/include-fixed/.
 .
-- 
2.23.0




[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