/* See bytecode.h comments on bc_calc_len() */
unsigned long (*bc_calc_len) (bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
} bc;
};
}
unsigned long
-bc_calc_len(bytecode *bc,
- intnum *(*resolve_label) (section *sect, /*@null@*/ bytecode *bc))
+bc_calc_len(bytecode *bc, intnum *(*resolve_label) (symrec *sym))
{
switch (bc->type) {
case BC_EMPTY:
* in-file label (eg, not an EXTERN variable, which is indeterminate).
*/
unsigned long bc_calc_len(bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
/* void bcs_initialize(bytecodehead *headp); */
#define bcs_initialize(headp) STAILQ_INIT(headp)
return expr_traverse_leaves_in(e, &t, expr_contains_callback);
}
+/* NOTE: This can't be passed through *d because of data/function pointer
+ * portability issues.
+ */
+static intnum *(*labelequ_resolve_label) (symrec *sym);
+
static int
-expr_expand_equ_callback(ExprItem *ei, /*@unused@*/ void *d)
+expr_expand_labelequ_callback(ExprItem *ei, /*@unused@*/ void *d)
{
const expr *equ_expr;
+ intnum *intn;
if (ei->type == EXPR_SYM) {
equ_expr = symrec_get_equ(ei->data.sym);
if (equ_expr) {
ei->type = EXPR_EXPR;
ei->data.expn = expr_copy(equ_expr);
+ } else {
+ intn = labelequ_resolve_label(ei->data.sym);
+ if (intn) {
+ ei->type = EXPR_INT;
+ ei->data.intn = intn;
+ }
}
}
return 0;
}
void
-expr_expand_equ(expr *e)
+expr_expand_labelequ(expr *e, intnum *(*resolve_label) (symrec *sym))
{
- expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+ labelequ_resolve_label = resolve_label;
+ expr_traverse_leaves_in(e, NULL, expr_expand_labelequ_callback);
}
/* Traverse over expression tree, calling func for each operation AFTER the
void expr_delete(/*@only@*/ /*@null@*/ expr *e);
/* Expands all (symrec) equ's in the expression into full expression
- * instances.
+ * instances. Also resolves labels, if possible.
*/
-void expr_expand_equ(expr *e);
+void expr_expand_labelequ(expr *e, intnum *(*resolve_label) (symrec *sym));
/* Simplifies the expression e as much as possible, eliminating extraneous
* branches and simplifying integer-only subexpressions.
void x86_bc_delete(bytecode *bc);
void x86_bc_print(FILE *f, const bytecode *bc);
unsigned long x86_bc_calc_len(bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
int x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
unsigned char nosplit, unsigned char *displen,
static unsigned long
x86_bc_calc_len_insn(x86_insn *insn, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc))
+ intnum *(*resolve_label) (symrec *sym))
{
effaddr *ea = insn->ea;
x86_effaddr_data *ead = ea_get_data(ea);
if ((ea->disp) && ((!ead->valid_sib && ead->need_sib) ||
(!ead->valid_modrm && ead->need_modrm))) {
/* First expand equ's */
- expr_expand_equ(ea->disp);
+ expr_expand_labelequ(ea->disp, resolve_label);
/* Check validity of effective address and calc R/M bits of
* Mod/RM byte and SIB byte. We won't know the Mod field
const intnum *num;
if (imm->val) {
- expr_expand_equ(imm->val);
+ expr_expand_labelequ(imm->val, resolve_label);
imm->val = expr_simplify(imm->val);
}
/* TODO: check imm f_len vs. len? */
unsigned long
x86_bc_calc_len(bytecode *bc,
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc))
+ intnum *(*resolve_label) (symrec *sym))
{
x86_insn *insn;
#include "util.h"
RCSID("$IdPath$");
+#include "symrec.h"
+
#include "bytecode.h"
#include "section.h"
#define BCFLAG_DONE (1<<1)
static /*@only@*/ /*@null@*/ intnum *
-basic_optimize_resolve_label(section *sect, bytecode *bc)
+basic_optimize_resolve_label(symrec *sym)
{
unsigned long flags;
- flags = section_get_opt_flags(sect);
+ flags = symrec_get_opt_flags(sym);
return NULL;
}
/* See bytecode.h comments on bc_calc_len() */
unsigned long (*bc_calc_len) (bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
} bc;
};
void x86_bc_delete(bytecode *bc);
void x86_bc_print(FILE *f, const bytecode *bc);
unsigned long x86_bc_calc_len(bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
int x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
unsigned char nosplit, unsigned char *displen,
static unsigned long
x86_bc_calc_len_insn(x86_insn *insn, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc))
+ intnum *(*resolve_label) (symrec *sym))
{
effaddr *ea = insn->ea;
x86_effaddr_data *ead = ea_get_data(ea);
if ((ea->disp) && ((!ead->valid_sib && ead->need_sib) ||
(!ead->valid_modrm && ead->need_modrm))) {
/* First expand equ's */
- expr_expand_equ(ea->disp);
+ expr_expand_labelequ(ea->disp, resolve_label);
/* Check validity of effective address and calc R/M bits of
* Mod/RM byte and SIB byte. We won't know the Mod field
const intnum *num;
if (imm->val) {
- expr_expand_equ(imm->val);
+ expr_expand_labelequ(imm->val, resolve_label);
imm->val = expr_simplify(imm->val);
}
/* TODO: check imm f_len vs. len? */
unsigned long
x86_bc_calc_len(bytecode *bc,
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc))
+ intnum *(*resolve_label) (symrec *sym))
{
x86_insn *insn;
}
unsigned long
-bc_calc_len(bytecode *bc,
- intnum *(*resolve_label) (section *sect, /*@null@*/ bytecode *bc))
+bc_calc_len(bytecode *bc, intnum *(*resolve_label) (symrec *sym))
{
switch (bc->type) {
case BC_EMPTY:
* in-file label (eg, not an EXTERN variable, which is indeterminate).
*/
unsigned long bc_calc_len(bytecode *bc, /*@only@*/ /*@null@*/
- intnum *(*resolve_label) (section *sect,
- /*@null@*/ bytecode *bc));
+ intnum *(*resolve_label) (symrec *sym));
/* void bcs_initialize(bytecodehead *headp); */
#define bcs_initialize(headp) STAILQ_INIT(headp)
return expr_traverse_leaves_in(e, &t, expr_contains_callback);
}
+/* NOTE: This can't be passed through *d because of data/function pointer
+ * portability issues.
+ */
+static intnum *(*labelequ_resolve_label) (symrec *sym);
+
static int
-expr_expand_equ_callback(ExprItem *ei, /*@unused@*/ void *d)
+expr_expand_labelequ_callback(ExprItem *ei, /*@unused@*/ void *d)
{
const expr *equ_expr;
+ intnum *intn;
if (ei->type == EXPR_SYM) {
equ_expr = symrec_get_equ(ei->data.sym);
if (equ_expr) {
ei->type = EXPR_EXPR;
ei->data.expn = expr_copy(equ_expr);
+ } else {
+ intn = labelequ_resolve_label(ei->data.sym);
+ if (intn) {
+ ei->type = EXPR_INT;
+ ei->data.intn = intn;
+ }
}
}
return 0;
}
void
-expr_expand_equ(expr *e)
+expr_expand_labelequ(expr *e, intnum *(*resolve_label) (symrec *sym))
{
- expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+ labelequ_resolve_label = resolve_label;
+ expr_traverse_leaves_in(e, NULL, expr_expand_labelequ_callback);
}
/* Traverse over expression tree, calling func for each operation AFTER the
void expr_delete(/*@only@*/ /*@null@*/ expr *e);
/* Expands all (symrec) equ's in the expression into full expression
- * instances.
+ * instances. Also resolves labels, if possible.
*/
-void expr_expand_equ(expr *e);
+void expr_expand_labelequ(expr *e, intnum *(*resolve_label) (symrec *sym));
/* Simplifies the expression e as much as possible, eliminating extraneous
* branches and simplifying integer-only subexpressions.
#include "util.h"
RCSID("$IdPath$");
+#include "symrec.h"
+
#include "bytecode.h"
#include "section.h"
#define BCFLAG_DONE (1<<1)
static /*@only@*/ /*@null@*/ intnum *
-basic_optimize_resolve_label(section *sect, bytecode *bc)
+basic_optimize_resolve_label(symrec *sym)
{
unsigned long flags;
- flags = section_get_opt_flags(sect);
+ flags = symrec_get_opt_flags(sym);
return NULL;
}