static yasm_expr * expr_expand_equ(yasm_expr *e, yasm__exprhead *eh) { int i; yasm__exprentry ee; /* traverse terms */ for (i=0; i<e->numterms; i++) { const yasm_expr *equ_expr; /* Expand equ's. */ if (e->terms[i].type == YASM_EXPR_SYM && (equ_expr = yasm_symrec_get_equ(e->terms[i].data.sym))) { yasm__exprentry *np; /* Check for circular reference */ SLIST_FOREACH(np, eh, next) { if (np->e == equ_expr) { yasm_error_set(YASM_ERROR_TOO_COMPLEX, N_("circular reference detected")); return e; } } e->terms[i].type = YASM_EXPR_EXPR; e->terms[i].data.expn = yasm_expr_copy(equ_expr); /* Remember we saw this equ and recurse */ ee.e = equ_expr; SLIST_INSERT_HEAD(eh, &ee, next); e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh); SLIST_REMOVE_HEAD(eh, next); } else if (e->terms[i].type == YASM_EXPR_EXPR)
/*@null@*/ /*@only@*/ yasm_expr * yasm_vp_expr(const yasm_valparam *vp, yasm_symtab *symtab, unsigned long line) { if (!vp) return NULL; switch (vp->type) { case YASM_PARAM_ID: return yasm_expr_create_ident(yasm_expr_sym( yasm_symtab_use(symtab, yasm_vp_id(vp), line)), line); case YASM_PARAM_EXPR: return yasm_expr_copy(vp->param.e); default: return NULL; } }
void yasm_value_init_copy(yasm_value *value, const yasm_value *orig) { value->abs = orig->abs ? yasm_expr_copy(orig->abs) : NULL; value->rel = orig->rel; value->wrt = orig->wrt; value->seg_of = orig->seg_of; value->rshift = orig->rshift; value->curpos_rel = orig->curpos_rel; value->ip_rel = orig->ip_rel; value->jump_target = orig->jump_target; value->section_rel = orig->section_rel; value->no_warn = orig->no_warn; value->sign = orig->sign; value->size = orig->size; }
static int elf_global_helper_valparam(void *obj, yasm_valparam *vp, unsigned long line, void *d) { struct elf_build_global_data *data = (struct elf_build_global_data *)d; const char *s; if (!vp->val && (s = yasm_vp_id(vp))) { yasm_error_set(YASM_ERROR_TYPE, N_("unrecognized symbol type `%s'"), s); return -1; } else if (!vp->val && vp->type == YASM_PARAM_EXPR && !data->size) { data->size = yasm_expr_copy(vp->param.e); return 0; } else return yasm_dir_helper_valparam_warn(obj, vp, line, d); }
static int xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) { /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; yasm_sym_vis vis = yasm_symrec_get_visibility(sym); assert(info != NULL); if (info->all_syms || vis != YASM_SYM_LOCAL) { /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); const yasm_expr *equ_val; const yasm_intnum *intn; size_t len = strlen(name); unsigned long value = 0; long scnum = -3; /* -3 = debugging symbol */ /*@dependent@*/ /*@null@*/ yasm_section *sect; /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; unsigned long flags = 0; unsigned char *localbuf; if (vis & YASM_SYM_GLOBAL) flags = XDF_SYM_GLOBAL; /* Look at symrec for value/scnum/etc. */ if (yasm_symrec_get_label(sym, &precbc)) { if (precbc) sect = yasm_bc_get_section(precbc); else sect = NULL; /* it's a label: get value and offset. * If there is not a section, leave as debugging symbol. */ if (sect) { /*@dependent@*/ /*@null@*/ xdf_section_data *csectd; csectd = yasm_section_get_data(sect, &xdf_section_data_cb); if (csectd) scnum = csectd->scnum; else yasm_internal_error(N_("didn't understand section")); if (precbc) value += yasm_bc_next_offset(precbc); } } else if ((equ_val = yasm_symrec_get_equ(sym))) { yasm_expr *equ_val_copy = yasm_expr_copy(equ_val); intn = yasm_expr_get_intnum(&equ_val_copy, 1); if (!intn) { if (vis & YASM_SYM_GLOBAL) { yasm_error_set(YASM_ERROR_NOT_CONSTANT, N_("global EQU value not an integer expression")); yasm_errwarn_propagate(info->errwarns, equ_val->line); } } else value = yasm_intnum_get_uint(intn); yasm_expr_destroy(equ_val_copy); flags |= XDF_SYM_EQU; scnum = -2; /* -2 = absolute symbol */ } else { if (vis & YASM_SYM_EXTERN) { flags = XDF_SYM_EXTERN; scnum = -1; } } localbuf = info->buf; YASM_WRITE_32_L(localbuf, scnum); /* section number */ YASM_WRITE_32_L(localbuf, value); /* value */ YASM_WRITE_32_L(localbuf, info->strtab_offset); info->strtab_offset += (unsigned long)(len+1); YASM_WRITE_32_L(localbuf, flags); /* flags */ fwrite(info->buf, 16, 1, info->f); yasm_xfree(name); } return 0; }