summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-01-25 01:00:03 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-27 02:17:34 +0200
commit279a25bad3a6868a1fac46501df8311e37eb72a0 (patch)
treec61fbb553e8c251cd67f28e65fd4ff3166d923ff
parent7aeb06b4bff797da4ea85a18738a2fd1f660d744 (diff)
downloadsparse-279a25bad3a6868a1fac46501df8311e37eb72a0.tar.gz
asm: use a specific struct for asm operands
Before commit 756731e9 ("use a specific struct for asm operands") ASM operands where stored as a list of n times 3 expressions. After this commit, the triplets where stored inside a single expression of type EXPR_ASM_OPERAND. However, while this improved the parsing and use of ASM operands it needlessly reuse 'struct expression' for something that is not an expression at all. Fix this by really using a specific struct for ASM operands. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--allocate.c1
-rw-r--r--allocate.h1
-rw-r--r--dissect.c2
-rw-r--r--evaluate.c5
-rw-r--r--expand.c3
-rw-r--r--expression.h13
-rw-r--r--inline.c28
-rw-r--r--lib.h2
-rw-r--r--linearize.c19
-rw-r--r--parse.c6
-rw-r--r--parse.h4
-rw-r--r--show-parse.c3
12 files changed, 40 insertions, 47 deletions
diff --git a/allocate.c b/allocate.c
index 152fa896..bef85192 100644
--- a/allocate.c
+++ b/allocate.c
@@ -141,6 +141,7 @@ ALLOCATOR(ident, "identifiers");
ALLOCATOR(token, "tokens");
ALLOCATOR(context, "contexts");
ALLOCATOR(symbol, "symbols");
+ALLOCATOR(asm_operand, "asmops");
ALLOCATOR(expression, "expressions");
ALLOCATOR(statement, "statements");
ALLOCATOR(string, "strings");
diff --git a/allocate.h b/allocate.h
index 5137ae93..a6d30537 100644
--- a/allocate.h
+++ b/allocate.h
@@ -82,6 +82,7 @@ DECLARE_ALLOCATOR(ident);
DECLARE_ALLOCATOR(token);
DECLARE_ALLOCATOR(context);
DECLARE_ALLOCATOR(symbol);
+DECLARE_ALLOCATOR(asm_operand);
DECLARE_ALLOCATOR(expression);
DECLARE_ALLOCATOR(statement);
DECLARE_ALLOCATOR(string);
diff --git a/dissect.c b/dissect.c
index b50c268b..14d57bf5 100644
--- a/dissect.c
+++ b/dissect.c
@@ -450,7 +450,7 @@ again:
return ret;
}
-static void do_asm_xputs(usage_t mode, struct expression_list *xputs)
+static void do_asm_xputs(usage_t mode, struct asm_operand_list *xputs)
{
DO_LIST(xputs, op, do_expression(U_W_AOF | mode, op->expr));
}
diff --git a/evaluate.c b/evaluate.c
index 634da4b9..7cc695c7 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -3354,9 +3354,6 @@ struct symbol *evaluate_expression(struct expression *expr)
case EXPR_SLICE:
expression_error(expr, "internal front-end error: SLICE re-evaluated");
return NULL;
- case EXPR_ASM_OPERAND:
- expression_error(expr, "internal front-end error: ASM_OPERAND evaluated");
- return NULL;
}
return NULL;
}
@@ -3519,7 +3516,7 @@ static void verify_input_constraint(struct expression *expr, const char *constra
static void evaluate_asm_statement(struct statement *stmt)
{
struct expression *expr;
- struct expression *op;
+ struct asm_operand *op;
struct symbol *sym;
expr = stmt->asm_string;
diff --git a/expand.c b/expand.c
index aba20b8c..487a4494 100644
--- a/expand.c
+++ b/expand.c
@@ -1091,9 +1091,6 @@ static int expand_expression(struct expression *expr)
case EXPR_OFFSETOF:
expression_error(expr, "internal front-end error: sizeof in expansion?");
return UNSAFE;
- case EXPR_ASM_OPERAND:
- expression_error(expr, "internal front-end error: ASM_OPERAND in expansion?");
- return UNSAFE;
}
return SIDE_EFFECTS;
}
diff --git a/expression.h b/expression.h
index 13f35e64..a06bfe13 100644
--- a/expression.h
+++ b/expression.h
@@ -64,7 +64,6 @@ enum expression_type {
EXPR_FVALUE,
EXPR_SLICE,
EXPR_OFFSETOF,
- EXPR_ASM_OPERAND,
};
@@ -136,6 +135,12 @@ enum {
Taint_comma = 1,
}; /* for expr->taint */
+struct asm_operand {
+ struct ident *name;
+ struct expression *constraint;
+ struct expression *expr;
+};
+
struct expression {
enum expression_type type:8;
unsigned flags:8;
@@ -235,12 +240,6 @@ struct expression {
struct expression *index;
};
};
- // EXPR_ASM_OPERAND
- struct {
- struct ident *name;
- struct expression *constraint;
- struct expression *expr;
- };
};
};
diff --git a/inline.c b/inline.c
index fcc43db5..6f73a305 100644
--- a/inline.c
+++ b/inline.c
@@ -274,26 +274,24 @@ static struct expression * copy_expression(struct expression *expr)
}
break;
}
- case EXPR_ASM_OPERAND: {
- expr = dup_expression(expr);
- expr->constraint = copy_expression(expr->constraint);
- expr->expr = copy_expression(expr->expr);
- break;
- }
default:
warning(expr->pos, "trying to copy expression type %d", expr->type);
}
return expr;
}
-static struct expression_list *copy_asm_constraints(struct expression_list *in)
+static struct asm_operand_list *copy_asm_operands(struct asm_operand_list *in)
{
- struct expression_list *out = NULL;
- struct expression *expr;
-
- FOR_EACH_PTR(in, expr) {
- add_expression(&out, copy_expression(expr));
- } END_FOR_EACH_PTR(expr);
+ struct asm_operand_list *out = NULL;
+ struct asm_operand *old;
+
+ FOR_EACH_PTR(in, old) {
+ struct asm_operand *new = __alloc_asm_operand(0);
+ new->name = old->name;
+ new->constraint = copy_expression(old->constraint);
+ new->expr = copy_expression(old->expr);
+ add_ptr_list(&out, new);
+ } END_FOR_EACH_PTR(old);
return out;
}
@@ -445,8 +443,8 @@ static struct statement *copy_one_statement(struct statement *stmt)
}
case STMT_ASM: {
stmt = dup_statement(stmt);
- stmt->asm_inputs = copy_asm_constraints(stmt->asm_inputs);
- stmt->asm_outputs = copy_asm_constraints(stmt->asm_outputs);
+ stmt->asm_inputs = copy_asm_operands(stmt->asm_inputs);
+ stmt->asm_outputs = copy_asm_operands(stmt->asm_outputs);
/* no need to dup "clobbers", since they are all constant strings */
break;
}
diff --git a/lib.h b/lib.h
index 322408be..697c977a 100644
--- a/lib.h
+++ b/lib.h
@@ -67,6 +67,7 @@ struct ident;
struct token;
struct symbol;
struct statement;
+struct asm_operand;
struct expression;
struct basic_block;
struct entrypoint;
@@ -76,6 +77,7 @@ struct pseudo;
DECLARE_PTR_LIST(symbol_list, struct symbol);
DECLARE_PTR_LIST(statement_list, struct statement);
+DECLARE_PTR_LIST(asm_operand_list, struct asm_operand);
DECLARE_PTR_LIST(expression_list, struct expression);
DECLARE_PTR_LIST(basic_block_list, struct basic_block);
DECLARE_PTR_LIST(instruction_list, struct instruction);
diff --git a/linearize.c b/linearize.c
index 415bf7e5..69f2dfe6 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2106,9 +2106,10 @@ static void add_asm_output(struct entrypoint *ep, struct instruction *insn, stru
static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement *stmt)
{
- struct expression *expr;
struct instruction *insn;
+ struct expression *expr;
struct asm_rules *rules;
+ struct asm_operand *op;
const char *constraint;
insn = alloc_instruction(OP_ASM, 0);
@@ -2123,18 +2124,18 @@ static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement
insn->asm_rules = rules;
/* Gather the inputs.. */
- FOR_EACH_PTR(stmt->asm_inputs, expr) {
- constraint = expr->constraint ? expr->constraint->string->data : "";
- add_asm_input(ep, insn, expr->expr, constraint, expr->name);
- } END_FOR_EACH_PTR(expr);
+ FOR_EACH_PTR(stmt->asm_inputs, op) {
+ constraint = op->constraint ? op->constraint->string->data : "";
+ add_asm_input(ep, insn, op->expr, constraint, op->name);
+ } END_FOR_EACH_PTR(op);
add_one_insn(ep, insn);
/* Assign the outputs */
- FOR_EACH_PTR(stmt->asm_outputs, expr) {
- constraint = expr->constraint ? expr->constraint->string->data : "";
- add_asm_output(ep, insn, expr->expr, constraint, expr->name);
- } END_FOR_EACH_PTR(expr);
+ FOR_EACH_PTR(stmt->asm_outputs, op) {
+ constraint = op->constraint ? op->constraint->string->data : "";
+ add_asm_output(ep, insn, op->expr, constraint, op->name);
+ } END_FOR_EACH_PTR(op);
return VOID;
}
diff --git a/parse.c b/parse.c
index 23c0ee01..d132a15a 100644
--- a/parse.c
+++ b/parse.c
@@ -2037,13 +2037,13 @@ static struct token *expression_statement(struct token *token, struct expression
}
static struct token *parse_asm_operands(struct token *token, struct statement *stmt,
- struct expression_list **inout)
+ struct asm_operand_list **inout)
{
/* Allow empty operands */
if (match_op(token->next, ':') || match_op(token->next, ')'))
return token->next;
do {
- struct expression *op = alloc_expression(token->pos, EXPR_ASM_OPERAND);
+ struct asm_operand *op = __alloc_asm_operand(0);
if (match_op(token->next, '[') &&
token_type(token->next->next) == TOKEN_IDENT &&
match_op(token->next->next->next, ']')) {
@@ -2053,7 +2053,7 @@ static struct token *parse_asm_operands(struct token *token, struct statement *s
token = token->next;
token = string_expression(token, &op->constraint, "asm constraint");
token = parens_expression(token, &op->expr, "in asm parameter");
- add_expression(inout, op);
+ add_ptr_list(inout, op);
} while (match_op(token, ','));
return token;
}
diff --git a/parse.h b/parse.h
index 505c91c2..0742a2a8 100644
--- a/parse.h
+++ b/parse.h
@@ -106,8 +106,8 @@ struct statement {
};
struct /* asm */ {
struct expression *asm_string;
- struct expression_list *asm_outputs;
- struct expression_list *asm_inputs;
+ struct asm_operand_list *asm_outputs;
+ struct asm_operand_list *asm_inputs;
struct expression_list *asm_clobbers;
struct symbol_list *asm_labels;
};
diff --git a/show-parse.c b/show-parse.c
index 3aa06e47..37104167 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -1185,9 +1185,6 @@ int show_expression(struct expression *expr)
case EXPR_TYPE:
warning(expr->pos, "unable to show type expression");
return 0;
- case EXPR_ASM_OPERAND:
- warning(expr->pos, "unable to show asm operand expression");
- return 0;
}
return 0;
}