diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-10-28 21:29:09 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-10-28 22:30:25 +0100 |
commit | c8a963b2450d739e6fb9f1a4c7485bfb458cc65b (patch) | |
tree | 0c270037957621f880116413984cfbc49f1b7a0f | |
parent | 2db11f1f818b7577363f9fe9289d0cb40adc2e29 (diff) | |
download | sparse-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.c | 86 | ||||
-rw-r--r-- | lib.h | 13 |
2 files changed, 99 insertions, 0 deletions
@@ -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) @@ -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); |