示例#1
0
void output_atoms(struct membuf *out, struct vec *atoms)
{
    struct vec_iterator i[1];
    struct vec_iterator i2[1];
    struct atom **atomp;
    struct atom *atom;
    struct expr **exprp;
    struct expr *expr;
    struct membuf *in;
    const char *p;
    i32 value;
    i32 value2;

    dump_sym_table(LOG_DEBUG, s->sym_table);

    vec_get_iterator(atoms, i);
    while((atomp = vec_iterator_next(i)) != NULL)
    {
        atom = *atomp;

        LOG(LOG_DEBUG, ("yadda\n"));

        switch(atom->type)
        {
        case ATOM_TYPE_OP_ARG_NONE:
            LOG(LOG_DEBUG, ("output: $%02X\n", atom->u.op.code));
            membuf_append_char(out, atom->u.op.code);
            break;
        case ATOM_TYPE_OP_ARG_U8:
            /* op with argument */
            value = resolve_expr(atom->u.op.arg);
            if(!is_valid_u8(value))
            {
                LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n",
                                value, atom->u.op.code, (void*)atom));
                exit(1);
            }
            LOG(LOG_DEBUG, ("output: $%02X $%02X\n",
                            atom->u.op.code, value & 255));
            membuf_append_char(out, atom->u.op.code);
            membuf_append_char(out, value);
            break;
        case ATOM_TYPE_OP_ARG_I8:
            /* op with argument */
            value = resolve_expr(atom->u.op.arg);
            if(!is_valid_i8(value))
            {
                LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n",
                                value, atom->u.op.code, (void*)atom));
                exit(1);
            }
            LOG(LOG_DEBUG, ("output: $%02X $%02X\n",
                            atom->u.op.code, value & 255));
            membuf_append_char(out, atom->u.op.code);
            membuf_append_char(out, value);
            break;
        case ATOM_TYPE_OP_ARG_UI8:
            /* op with argument */
            value = resolve_expr(atom->u.op.arg);
            if(!is_valid_ui8(value))
            {
                LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n",
                                value, atom->u.op.code, (void*)atom));
                exit(1);
            }
            LOG(LOG_DEBUG, ("output: $%02X $%02X\n",
                            atom->u.op.code, value & 255));
            membuf_append_char(out, atom->u.op.code);
            membuf_append_char(out, value);
            break;
        case ATOM_TYPE_OP_ARG_U16:
            /* op with argument */
            value = resolve_expr(atom->u.op.arg);
            if(!is_valid_u16(value))
            {
                LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n",
                                value, atom->u.op.code, (void*)atom));
                exit(1);
            }
            value2 = value / 256;
            value = value % 256;
            LOG(LOG_DEBUG, ("output: $%02X $%02X $%02X\n",
                            atom->u.op.code,
                            value, value2));
            membuf_append_char(out, atom->u.op.code);
            membuf_append_char(out, value);
            membuf_append_char(out, value2);
            break;
        case ATOM_TYPE_RES:
            /* reserve memory statement */
            value = resolve_expr(atom->u.res.length);
            if(!is_valid_u16(value))
            {
                LOG(LOG_ERROR, ("length %d for .res(length, value) "
                                "is out of range\n", value));
                exit(1);
            }
            value2 = resolve_expr(atom->u.res.value);
            if(!is_valid_ui8(value2))
            {
                LOG(LOG_ERROR, ("value %d for .res(length, value) "
                                "is out of range\n", value));
                exit(1);
            }
            LOG(LOG_DEBUG, ("output: .RES %d, %d\n", value, value2));
            while(--value >= 0)
            {
                membuf_append_char(out, value2);
            }
            break;
        case ATOM_TYPE_BUFFER:
            /* include binary file statement */
            value = atom->u.buffer.skip;
            if(!is_valid_u16(value))
            {
                LOG(LOG_ERROR, ("value %d for .res(length, value) "
                                "is out of range\n", value));
                exit(1);
            }
            value2 = atom->u.buffer.length;
            if(!is_valid_u16(value2))
            {
                LOG(LOG_ERROR, ("length %d for .incbin(name, skip, length) "
                                "is out of range\n", value2));
                exit(1);
            }
            LOG(LOG_DEBUG, ("output: .INCBIN \"%s\", %d, %d\n",
                            atom->u.buffer.name, value, value2));
            in = get_named_buffer(s->named_buffer, atom->u.buffer.name);
            p = membuf_get(in);
            p += value;
            while(--value2 >= 0)
            {
                membuf_append_char(out, *p++);
            }
            break;
        case ATOM_TYPE_WORD_EXPRS:
            vec_get_iterator(atom->u.exprs, i2);
            while((exprp = vec_iterator_next(i2)) != NULL)
            {
                expr = *exprp;
                value = resolve_expr(expr);
                if(!is_valid_ui16(value))
                {
                    LOG(LOG_ERROR, ("value %d for .word(value, ...) "
                                    "is out of range\n", value));
                }
                value2 = value / 256;
                value = value % 256;
                membuf_append_char(out, value);
                membuf_append_char(out, value2);
            }
            LOG(LOG_DEBUG, ("output: %d words\n", vec_count(atom->u.exprs)));
            break;
        case ATOM_TYPE_BYTE_EXPRS:
            vec_get_iterator(atom->u.exprs, i2);
            while((exprp = vec_iterator_next(i2)) != NULL)
            {
                expr = *exprp;
                value = resolve_expr(expr);
                if(!is_valid_ui8(value))
                {
                    LOG(LOG_ERROR, ("value %d for .byte(value, ...) "
                                    "is out of range\n", value));
                }
                membuf_append_char(out, value);
            }
            LOG(LOG_DEBUG, ("output: %d bytes\n", vec_count(atom->u.exprs)));
            break;
        default:
            LOG(LOG_ERROR, ("invalid atom_type %d @%p\n",
                            atom->type, (void*)atom));
            exit(1);
        }
    }
}
示例#2
0
static
void level(const char *appl, int argc, char *argv[])
{
    char flags_arr[32];
    int forward_mode = 0;
    int literal_sequences_used = 0;
    int max_safety = 0;
    int c;
    int infilec;
    char **infilev;

    struct crunch_options options[1] = { CRUNCH_OPTIONS_DEFAULT };
    struct common_flags flags[1] = {{NULL, DEFAULT_OUTFILE}};

    struct membuf in[1];
    struct membuf out[1];

    flags->options = options;

    LOG(LOG_DUMP, ("flagind %d\n", flagind));
    sprintf(flags_arr, "f%s", CRUNCH_FLAGS);
    while ((c = getflag(argc, argv, flags_arr)) != -1)
    {
        LOG(LOG_DUMP, (" flagind %d flagopt '%c'\n", flagind, c));
        switch (c)
        {
        case 'f':
            forward_mode = 1;
            break;
        default:
            handle_crunch_flags(c, flagarg, print_level_usage, appl, flags);
        }
    }

    membuf_init(in);
    membuf_init(out);

    infilev = argv + flagind;
    infilec = argc - flagind;

    if (infilec == 0)
    {
        LOG(LOG_ERROR, ("Error: no input files to process.\n"));
        print_level_usage(appl, LOG_NORMAL, DEFAULT_OUTFILE);
        exit(1);
    }

    /* append the files instead of merging them */
    for(c = 0; c < infilec; ++c)
    {
        struct crunch_info info[1];
        int in_load;
        int in_len;
        int out_pos;
        out_pos = membuf_memlen(out);

        in_load = do_load(infilev[c], in);
        in_len = membuf_memlen(in);

        if(forward_mode)
        {
            /* append the starting address of decrunching */
            membuf_append_char(out, in_load >> 8);
            membuf_append_char(out, in_load & 255);

            crunch(in, out, options, info);
        }
        else
        {
            crunch_backwards(in, out, options, info);

            /* append the starting address of decrunching */
            membuf_append_char(out, (in_load + in_len) & 255);
            membuf_append_char(out, (in_load + in_len) >> 8);

            /* reverse the just appended segment of the out buffer */
            reverse_buffer((char*)membuf_get(out) + out_pos,
                           membuf_memlen(out) - out_pos);
        }

        if(info->literal_sequences_used)
        {
            literal_sequences_used = 1;
        }
        if(info->needed_safety_offset > max_safety)
        {
            max_safety = info->needed_safety_offset;
        }
    }
示例#3
0
void dec_ctx_decrunch(struct dec_ctx ctx[1])
{
    int bits;
    int val;
    int i;
    int len;
    int offset;
    int src = 0;

    for(;;)
    {
        int literal = 0;
        bits = ctx->bits_read;
        if(get_bits(ctx, 1))
        {
            /* literal */
            len = 1;

            LOG(LOG_DEBUG, ("[%d] literal\n", membuf_memlen(ctx->outbuf)));

            literal = 1;
            goto literal;
        }

        val = get_gamma_code(ctx);
        if(val == 16)
        {
            /* done */
            break;
        }
        if(val == 17)
        {
            len = get_bits(ctx, 16);
            literal = 1;

            LOG(LOG_DEBUG, ("[%d] literal copy len %d\n",
                            membuf_memlen(ctx->outbuf), len));

            goto literal;
        }

        len = get_cooked_code_phase2(ctx, val);

        i = (len > 3 ? 3 : len) - 1;

        val = ctx->t->table_off[i] + get_bits(ctx, ctx->t->table_bit[i]);
        offset = get_cooked_code_phase2(ctx, val);

        LOG(LOG_DEBUG, ("[%d] sequence offset = %d, len = %d\n",
                        membuf_memlen(ctx->outbuf), offset, len));

        src = membuf_memlen(ctx->outbuf) - offset;

    literal:
        do {
            if(literal)
            {
                val = get_byte(ctx);
            }
            else
            {
                val = get(ctx->outbuf)[src++];
            }
            membuf_append_char(ctx->outbuf, val);
        } while (--len > 0);

        LOG(LOG_DEBUG, ("bits read for this iteration %d.\n",
                        ctx->bits_read - bits));
    }
}