aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Documentation/release-notes/v0.6.4.rst2
-rw-r--r--dissect.c61
-rw-r--r--options.c5
-rw-r--r--options.h2
-rw-r--r--parse.c5
-rw-r--r--semind.c1
-rw-r--r--sparse.c2
-rw-r--r--target-riscv.c12
-rw-r--r--test-dissect.c5
-rw-r--r--token.h2
-rw-r--r--validation/byte-count-max.c28
-rw-r--r--validation/label-positioning.c22
12 files changed, 140 insertions, 7 deletions
diff --git a/Documentation/release-notes/v0.6.4.rst b/Documentation/release-notes/v0.6.4.rst
index 387870fa..08830bd8 100644
--- a/Documentation/release-notes/v0.6.4.rst
+++ b/Documentation/release-notes/v0.6.4.rst
@@ -1,4 +1,4 @@
-v0.6.4 (2020-09-06)
+v0.6.4 (2021-09-06)
===================
Fixes:
diff --git a/dissect.c b/dissect.c
index 582e8fc3..300d5ca9 100644
--- a/dissect.c
+++ b/dissect.c
@@ -610,6 +610,16 @@ static struct symbol *do_initializer(struct symbol *type, struct expression *exp
return type;
}
+static inline bool is_macro(struct symbol *sym)
+{
+ return (sym->namespace == NS_MACRO || sym->namespace == NS_UNDEF);
+}
+
+static inline bool is_typedef(struct symbol *sym)
+{
+ return (sym->namespace == NS_TYPEDEF);
+}
+
static inline struct symbol *do_symbol(struct symbol *sym)
{
struct symbol *type = base_type(sym);
@@ -652,9 +662,58 @@ static void do_sym_list(struct symbol_list *list)
DO_LIST(list, sym, do_symbol(sym));
}
+static inline bool valid_namespace(enum namespace ns)
+{
+ return (ns == NS_TYPEDEF || ns == NS_MACRO || ns == NS_UNDEF || ns == NS_STRUCT || ns == NS_SYMBOL);
+}
+
+static void do_file(char *file)
+{
+ struct symbol_list *res = sparse_keep_tokens(file);
+
+ if (!dissect_show_all_symbols) {
+ do_sym_list(res);
+ goto end;
+ }
+
+ DO_LIST(file_scope->symbols, sym,
+ if (input_streams[sym->pos.stream].fd != -1 && valid_namespace(sym->namespace)) {
+ if (is_typedef(sym)) {
+ sym->kind = 't';
+ reporter->r_symdef(sym);
+ continue;
+ }
+
+ if (is_macro(sym)) {
+ sym->kind = 'd';
+ reporter->r_symdef(sym);
+ continue;
+ }
+
+ if (sym->type == SYM_STRUCT || sym->type == SYM_UNION) {
+ sym->ctype.base_type = sym;
+ examine_sym_node(sym, NULL);
+ continue;
+ }
+
+ do_symbol(sym);
+ }
+ );
+
+ DO_LIST(global_scope->symbols, sym,
+ if (input_streams[sym->pos.stream].fd != -1 && valid_namespace(sym->namespace)) {
+ do_symbol(sym);
+ }
+ );
+
+end:
+ /* Drop the tokens for this file after parsing */
+ clear_token_alloc();
+}
+
void dissect(struct reporter *rep, struct string_list *filelist)
{
reporter = rep;
- DO_LIST(filelist, file, do_sym_list(__sparse(file)));
+ DO_LIST(filelist, file, do_file(file));
}
diff --git a/options.c b/options.c
index 6704fc8d..b4684357 100644
--- a/options.c
+++ b/options.c
@@ -70,6 +70,8 @@ int dbg_postorder = 0;
int dump_macro_defs = 0;
int dump_macros_only = 0;
+int dissect_show_all_symbols = 0;
+
unsigned long fdump_ir;
int fhosted = 1;
unsigned int fmax_errors = 100;
@@ -958,6 +960,9 @@ static char **handle_param(char *arg, char **next)
if (!value)
die("missing argument for --param option");
+ if (!strcmp(value, "dissect-show-all-symbols"))
+ dissect_show_all_symbols = 1;
+
return next;
}
diff --git a/options.h b/options.h
index 0aec8764..c2a9551a 100644
--- a/options.h
+++ b/options.h
@@ -70,6 +70,8 @@ extern int dbg_postorder;
extern int dump_macro_defs;
extern int dump_macros_only;
+extern int dissect_show_all_symbols;
+
extern unsigned long fdump_ir;
extern int fhosted;
extern unsigned int fmax_errors;
diff --git a/parse.c b/parse.c
index bc1c0602..9f2a3cdf 100644
--- a/parse.c
+++ b/parse.c
@@ -2329,6 +2329,11 @@ static inline struct token *case_statement(struct token *token, struct statement
stmt->type = STMT_CASE;
token = expect(token, ':', "after default/case");
add_case_statement(stmt);
+ if (match_op(token, '}')) {
+ warning(token->pos, "statement expected after case label");
+ stmt->case_statement = alloc_statement(token->pos, STMT_NONE);
+ return token;
+ }
return statement(token, &stmt->case_statement);
}
diff --git a/semind.c b/semind.c
index 911fc747..ad8003ba 100644
--- a/semind.c
+++ b/semind.c
@@ -329,6 +329,7 @@ done:
optind--;
sparse_initialize(argc - optind, argv + optind, &semind_filelist);
+ dissect_show_all_symbols = 1;
}
static void parse_cmdline_rm(int argc, char **argv)
diff --git a/sparse.c b/sparse.c
index 9d62d4fe..e7cc6f55 100644
--- a/sparse.c
+++ b/sparse.c
@@ -165,7 +165,7 @@ static void check_byte_count(struct instruction *insn, pseudo_t count)
static void check_memset(struct instruction *insn)
{
- check_byte_count(insn, ptr_list_nth(insn->arguments, 3));
+ check_byte_count(insn, ptr_list_nth(insn->arguments, 2));
}
#define check_memcpy check_memset
diff --git a/target-riscv.c b/target-riscv.c
index 6d9113c1..3bba7c15 100644
--- a/target-riscv.c
+++ b/target-riscv.c
@@ -16,6 +16,8 @@
#define RISCV_EMBD (1 << 9)
#define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV)
#define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU)
+#define RISCV_ZICSR (1 << 10)
+#define RISCV_ZIFENCEI (1 << 11)
static unsigned int riscv_flags;
@@ -33,8 +35,8 @@ static void parse_march_riscv(const char *arg)
}, extensions[] = {
{ "m", RISCV_MUL|RISCV_DIV },
{ "a", RISCV_ATOMIC },
- { "f", RISCV_FLOAT|RISCV_FDIV },
- { "d", RISCV_DOUBLE|RISCV_FDIV },
+ { "f", RISCV_FLOAT|RISCV_FDIV|RISCV_ZICSR },
+ { "d", RISCV_DOUBLE|RISCV_FDIV|RISCV_ZICSR },
{ "g", RISCV_GENERIC },
{ "q", 0 },
{ "l", 0 },
@@ -47,6 +49,8 @@ static void parse_march_riscv(const char *arg)
{ "n", 0 },
{ "h", 0 },
{ "s", 0 },
+ { "_zicsr", RISCV_ZICSR },
+ { "_zifencei", RISCV_ZIFENCEI },
};
int i;
@@ -127,6 +131,10 @@ static void predefine_riscv(const struct target *self)
predefine("__riscv_mul", 1, "1");
if ((riscv_flags & RISCV_MUL) && (riscv_flags & RISCV_DIV))
predefine("__riscv_muldiv", 1, "1");
+ if (riscv_flags & RISCV_ZICSR)
+ predefine("__riscv_zicsr", 1, "1");
+ if (riscv_flags & RISCV_ZIFENCEI)
+ predefine("__riscv_zifencei", 1, "1");
if (cmodel)
predefine_strong("__riscv_cmodel_%s", cmodel);
diff --git a/test-dissect.c b/test-dissect.c
index 58b3e633..65b205f8 100644
--- a/test-dissect.c
+++ b/test-dissect.c
@@ -57,11 +57,14 @@ static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
show_typename(sym->ctype.base_type));
switch (sym->kind) {
+ case 'd':
+ break;
case 's':
if (sym->type == SYM_STRUCT || sym->type == SYM_UNION)
break;
goto err;
-
+ case 't':
+ break;
case 'f':
if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN)
goto err;
diff --git a/token.h b/token.h
index bccac0e4..9000e0cb 100644
--- a/token.h
+++ b/token.h
@@ -201,7 +201,7 @@ struct token {
static inline struct token *containing_token(struct token **p)
{
- void *addr = (char *)p - ((char *)&((struct token *)0)->next - (char *)0);
+ void *addr = (char *)p - offsetof(struct token, next);
return addr;
}
diff --git a/validation/byte-count-max.c b/validation/byte-count-max.c
new file mode 100644
index 00000000..0555a505
--- /dev/null
+++ b/validation/byte-count-max.c
@@ -0,0 +1,28 @@
+typedef unsigned long int size_t;
+typedef unsigned long ulong;
+
+extern void *memset(void *s, int c, size_t n);
+extern void *memcpy(void *dest, void *src, size_t n);
+extern ulong copy_to_user(void *to, const void *from, ulong count);
+extern ulong copy_from_user(void *to, const void *from, ulong count);
+
+static void func (char *s)
+{
+ char d[250000];
+
+ memset(d, 0, 250000);
+ memcpy(d, s, 250000);
+ copy_to_user(s, d, 250000);
+ copy_from_user(d, s, 250000);
+}
+
+/*
+ * check-name: byte-count-max
+ *
+ * check-error-start
+byte-count-max.c:13:15: warning: memset with byte count of 250000
+byte-count-max.c:14:15: warning: memcpy with byte count of 250000
+byte-count-max.c:15:21: warning: copy_to_user with byte count of 250000
+byte-count-max.c:16:23: warning: copy_from_user with byte count of 250000
+ * check-error-end
+ */
diff --git a/validation/label-positioning.c b/validation/label-positioning.c
new file mode 100644
index 00000000..583661ca
--- /dev/null
+++ b/validation/label-positioning.c
@@ -0,0 +1,22 @@
+extern int someval(void);
+
+static void func (int x)
+{
+ if (x > someval())
+ goto end;
+ switch (x) { case 0: }
+ switch (x) { case 1 ... 9: }
+ switch (x) { default: }
+end:
+}
+
+/*
+ * check-name: label-positioning
+ *
+ * check-error-start
+label-positioning.c:7:30: warning: statement expected after case label
+label-positioning.c:8:36: warning: statement expected after case label
+label-positioning.c:9:31: warning: statement expected after case label
+label-positioning.c:11:1: warning: statement expected after label
+ * check-error-end
+ */