aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/lib.c
diff options
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 /lib.c
parent2db11f1f818b7577363f9fe9289d0cb40adc2e29 (diff)
downloadsparse-dev-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>
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c86
1 files changed, 86 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)