On 28/10/2019 21:43, Luc Van Oostenryck wrote: > 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. How does this interact with the cgcc --target=<spec> and the (otherwise) guessing of the 'native' specs? > > 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 }, I would rather these were explicitly set to 0. > + { "s390", MACH_S390X, 64 }, > + { "s390x", MACH_S390X, 64 }, > + { "sparc", MACH_MIPS64 }, Er, I suppose this should be MACH_SPARC64, right? (also 0 init). > + { "x86_64", MACH_X86_64, 64 }, > + { "x86-64", MACH_X86_64, 64 }, > + { "x86", MACH_X86_64 }, (also 0 init). > + { 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; So, this is a 50-50 bet. ;-) ATB, Ramsay Jones > + } 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/. > . >