void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) { if (bc->callback) bc->callback->finalize(bc, prev_bc); if (bc->multiple) { yasm_value val; if (yasm_value_finalize_expr(&val, bc->multiple, prev_bc, 0)) yasm_error_set(YASM_ERROR_TOO_COMPLEX, N_("multiple expression too complex")); else if (val.rel) yasm_error_set(YASM_ERROR_NOT_ABSOLUTE, N_("multiple expression not absolute")); /* Finalize creates NULL output if value=0, but bc->multiple is NULL * if value=1 (this difference is to make the common case small). * However, this means we need to set bc->multiple explicitly to 0 * here if val.abs is NULL. */ if (val.abs) bc->multiple = val.abs; else bc->multiple = yasm_expr_create_ident( yasm_expr_int(yasm_intnum_create_uint(0)), bc->line); } }
yasm_section * yasm_dwarf2__generate_aranges(yasm_object *object, yasm_section *debug_info) { yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; int new; yasm_section *debug_aranges; yasm_bytecode *bc; dwarf2_head *head; dwarf2_aranges_info info; debug_aranges = yasm_object_get_general(object, ".debug_aranges", 2*dbgfmt_dwarf2->sizeof_address, 0, 0, &new, 0); /* header */ head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_aranges, debug_info, 1, 1); /* align ranges to 2x address size (range size) */ bc = yasm_bc_create_align( yasm_expr_create_ident(yasm_expr_int( yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_address*2)), 0), NULL, NULL, NULL, 0); yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc)); yasm_bc_calc_len(bc, NULL, NULL); info.debug_aranges = debug_aranges; info.object = object; info.dbgfmt_dwarf2 = dbgfmt_dwarf2; yasm_object_sections_traverse(object, (void *)&info, dwarf2_generate_aranges_section); /* Terminate with empty address range descriptor */ dwarf2_append_arange(debug_aranges, yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0), yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0), dbgfmt_dwarf2->sizeof_address); /* mark end of aranges information */ yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_aranges)); return debug_aranges; }
static int dwarf2_generate_aranges_section(yasm_section *sect, /*@null@*/ void *d) { dwarf2_aranges_info *info = (dwarf2_aranges_info *)d; yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; /*@null@*/ dwarf2_section_data *dsd; /*@only@*/ yasm_expr *start, *length; dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb); if (!dsd) return 0; /* no line data for this section */ /* Create address range descriptor */ start = yasm_expr_create_ident( yasm_expr_sym(yasm_dwarf2__bc_sym(info->object->symtab, yasm_section_bcs_first(sect))), 0); length = yasm_expr_create_ident( yasm_expr_int(yasm_calc_bc_dist(yasm_section_bcs_first(sect), yasm_section_bcs_last(sect))), 0); dwarf2_append_arange(info->debug_aranges, start, length, dbgfmt_dwarf2->sizeof_address); return 0; }
static int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, yasm_output_value_func output_value, /*@unused@*/ yasm_output_reloc_func output_reloc) { lc3b_insn *insn = (lc3b_insn *)bc->contents; /*@only@*/ yasm_intnum *delta; unsigned long buf_off = (unsigned long)(*bufp - bufstart); /* Output opcode */ YASM_SAVE_16_L(*bufp, insn->opcode); /* Insert immediate into opcode. */ switch (insn->imm_type) { case LC3B_IMM_NONE: break; case LC3B_IMM_4: insn->imm.size = 4; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_5: insn->imm.size = 5; insn->imm.sign = 1; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_6_WORD: insn->imm.size = 6; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_6_BYTE: insn->imm.size = 6; insn->imm.sign = 1; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_8: insn->imm.size = 8; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_9_PC: /* Adjust relative displacement to end of bytecode */ delta = yasm_intnum_create_int(-1); if (!insn->imm.abs) insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta), bc->line); else insn->imm.abs = yasm_expr_create(YASM_EXPR_ADD, yasm_expr_expr(insn->imm.abs), yasm_expr_int(delta), bc->line); insn->imm.size = 9; insn->imm.sign = 1; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; case LC3B_IMM_9: insn->imm.size = 9; if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) return 1; break; default: yasm_internal_error(N_("Unrecognized immediate type")); } *bufp += 2; /* all instructions are 2 bytes in size */ return 0; }