aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-10-28 21:29:09 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-10-28 22:30:25 +0100
commitc8a963b2450d739e6fb9f1a4c7485bfb458cc65b (patch)
tree0c270037957621f880116413984cfbc49f1b7a0f
parent2db11f1f818b7577363f9fe9289d0cb40adc2e29 (diff)
downloadsparse-c8a963b2450d739e6fb9f1a4c7485bfb458cc65b.tar.gz
options: add support for -mcmodel
Do the parsing of all models used in the kernel and output the predefines for arm64 & riscv. Reported-by: Paul Walmsley <paul.walmsley@sifive.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--lib.c86
-rw-r--r--lib.h13
2 files changed, 99 insertions, 0 deletions
diff --git a/lib.c b/lib.c
index e9e637d2..84b5be6a 100644
--- a/lib.c
+++ b/lib.c
@@ -328,6 +328,7 @@ static int arch_msize_long = 0;
int arch_m64 = ARCH_M64_DEFAULT;
int arch_big_endian = ARCH_BIG_ENDIAN;
int arch_mach = MACH_NATIVE;
+int arch_cmodel = CMODEL_UNKNOWN;
#define CMDLINE_INCLUDE 20
@@ -470,6 +471,26 @@ static char **handle_switch_m(char *arg, char **next)
arch_big_endian = 1;
} else if (!strcmp(arg, "mlittle-endian")) {
arch_big_endian = 0;
+ } else if (!strncmp(arg, "mcmodel", 7)) {
+ arg += 7;
+ if (*arg++ != '=')
+ die("missing argument for -mcmodel");
+ else if (!strcmp(arg, "kernel"))
+ arch_cmodel = CMODEL_KERNEL;
+ else if (!strcmp(arg, "large"))
+ arch_cmodel = CMODEL_LARGE;
+ else if (!strcmp(arg, "medany"))
+ arch_cmodel = CMODEL_MEDANY;
+ else if (!strcmp(arg, "medium"))
+ arch_cmodel = CMODEL_MEDIUM;
+ else if (!strcmp(arg, "medlow"))
+ arch_cmodel = CMODEL_MEDLOW;
+ else if (!strcmp(arg, "small"))
+ arch_cmodel = CMODEL_SMALL;
+ else if (!strcmp(arg, "tiny"))
+ arch_cmodel = CMODEL_TINY;
+ else
+ die("invalid argument for -mcmodel=%s", arg);
}
return next;
}
@@ -488,6 +509,20 @@ static void handle_arch_finalize(void)
if (fpie > fpic)
fpic = fpie;
+
+ switch (arch_mach) {
+ case MACH_ARM64:
+ if (arch_cmodel == CMODEL_UNKNOWN)
+ arch_cmodel = CMODEL_SMALL;
+ break;
+ case MACH_RISCV32:
+ case MACH_RISCV64:
+ if (arch_cmodel == CMODEL_UNKNOWN)
+ arch_cmodel = CMODEL_MEDLOW;
+ if (fpic)
+ arch_cmodel = CMODEL_PIC;
+ break;
+ }
}
static const char *match_option(const char *arg, const char *prefix)
@@ -1213,6 +1248,55 @@ static void predefined_ctype(const char *name, struct symbol *type, int flags)
predefined_width(name, bits);
}
+static void predefined_cmodel(void)
+{
+ const char *pre, *suf;
+ const char *def = NULL;
+ switch (arch_mach) {
+ case MACH_ARM64:
+ pre = "__AARCH64_CMODEL_";
+ suf = "__";
+ switch (arch_cmodel) {
+ case CMODEL_LARGE:
+ def = "LARGE";
+ break;
+ case CMODEL_SMALL:
+ def = "SMALL";
+ break;
+ case CMODEL_TINY:
+ def = "TINY";
+ break;
+ default:
+ break;
+ }
+ break;
+ case MACH_RISCV32:
+ case MACH_RISCV64:
+ pre = "__riscv_cmodel_";
+ suf = "";
+ switch (arch_cmodel) {
+ case CMODEL_MEDLOW:
+ def = "medlow";
+ break;
+ case CMODEL_MEDANY:
+ def = "medany";
+ break;
+ case CMODEL_PIC:
+ def = "pic";
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!def)
+ return;
+ add_pre_buffer("#weak_define %s%s%s 1\n", pre, def, suf);
+}
+
static void predefined_macros(void)
{
predefine("__CHECKER__", 0, "1");
@@ -1406,6 +1490,8 @@ static void predefined_macros(void)
predefine("__pie__", 0, "%d", fpie);
predefine("__PIE__", 0, "%d", fpie);
}
+
+ predefined_cmodel();
}
static void create_builtin_stream(void)
diff --git a/lib.h b/lib.h
index b3616fd4..f6dea8ca 100644
--- a/lib.h
+++ b/lib.h
@@ -207,6 +207,19 @@ extern int arch_m64;
extern int arch_big_endian;
extern int arch_mach;
+enum {
+ CMODEL_UNKNOWN,
+ CMODEL_KERNEL,
+ CMODEL_LARGE,
+ CMODEL_MEDANY,
+ CMODEL_MEDIUM,
+ CMODEL_MEDLOW,
+ CMODEL_PIC,
+ CMODEL_SMALL,
+ CMODEL_TINY,
+};
+extern int arch_cmodel;
+
extern void dump_macro_definitions(void);
extern struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **files);
extern struct symbol_list *__sparse(char *filename);