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);
    }
}
Example #2
0
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;
}
Example #3
0
/*@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;
    }
}
Example #4
0
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;
}
Example #5
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;
}