Beispiel #1
0
ListT* get_loadables(int do_print) {
    DIR* task_dir;
    struct dirent *task_dirent;
    ListT* files;
    int file_idx;

    task_dir = opendir(kTaskDir);
    assert(task_dir != NULL);

    files = List(10, NULL);
    file_idx = 0;

    while ((task_dirent = readdir(task_dir)) != NULL) {
        //
        //make sure we are not looking at . and .. files
        if (is_loadable(task_dirent->d_name)) {

            list_append(files, task_dirent->d_name);

            if (do_print) {
                printf("%d) %s\n", file_idx++, task_dirent->d_name);
            }
        }
    }

    return files;
}
Beispiel #2
0
Datei: emit.c Projekt: xerub/ropc
void
emit_nodes(struct node *n, const char *assignto, BOOL force, BOOL inloop)
{
    char *fast = NULL;

    assert(n);

    if (n->next == NULL && n->type != NODE_CALL && !assignto && !force) {
        /* do not emit single node, unless it is a call or we really need it */
        cry("statement with no effect\n");
        return;
    }
    switch (n->type) {
        case NODE_IMM: {
            fast = AS_IMM(n)->value;
            maybe_symbol_forward(fast);
            if (force) {
                cry("constant expression '%s' in conditional\n", fast);
            }
            assert(!assignto);
            break;
        }
        case NODE_LVAL: {
            struct lval_node *p = AS_LVAL(n);
            int loadable = is_loadable(n, TRUE);
            if (loadable < 0) {
                fast = p->name;
            } else if (loadable > 0) {
                make_symbol_used(p->name);
                emit_load_direct(p->name, p->deref);
            } else {
                emit_load_indirect(p->name, p->deref);
            }
            break;
        }
        case NODE_CALL: {
            struct call_node *p = AS_CALL(n);
            struct node *parm;
            int deref0 = 0;
            char *args[MAX_FUNC_ARGS];
            char *func;
            int i;
            BOOL retval = (n->next != NULL) || force || assignto;
            BOOL direct = FALSE;
            for (i = 0, parm = p->parm; parm; parm = parm->next, i++) {
                BOOL r0 = (i == 0 && arch_regparm);
                assert(i < MAX_FUNC_ARGS);
                if (parm->type == NODE_IMM) {
                    args[i] = xstrdup(AS_IMM(parm)->value);
                    maybe_symbol_forward(args[i]);
                } else if (parm->type == NODE_LVAL && is_loadable(parm, r0)) {
                    struct lval_node *q = AS_LVAL(parm);
                    args[i] = xstrdup(q->name);
                    make_symbol_used(args[i]);
                    if (q->deref) {
                        deref0 = 1;
                    }
                } else if (r0 && parm->next == NULL) {
                    args[i] = NULL;
                    direct = TRUE;
                    emit_nodes(parm, NULL, TRUE, inloop);
                } else if (r0 && parm->type == NODE_LVAL) {
                    struct lval_node *q = AS_LVAL(parm);
                    args[i] = create_address_str(q->name);
                    deref0 = 1;
                    if (q->deref) {
                        deref0++;
                    }
                } else {
                    args[i] = new_name("var");
                    emit_nodes(parm, args[i], FALSE, inloop);
                    make_symbol_used(args[i]);
                }
            }
            func = p->func;
            if (retval && (p->attr & ATTRIB_NORETURN)) {
                cry("function '%s' does not return\n", func);
            }
            if (!is_loadable_sym(func)) {
                char *ptr = new_name("ptr");
                emit_load_indirect(func, FALSE);
                add_symbol_forward(ptr, 0);
                emit_store_indirect(ptr);
                func = ptr;
            } else {
                func = xstrdup(func);
            }
            make_symbol_used(func);
            if (!(p->attr & ATTRIB_NORETURN)) {
                if ((p->attr & ATTRIB_STACK) || inloop) {
                    if (!(p->attr & ATTRIB_STACK)) {
                        cry("reserved [[stack]] for '%s' because of loop\n", func);
                    }
                    mark_all_used(PROTECTED);
                } else {
                    mark_all_used(CLOBBERED);
                }
            }
            if (direct) {
                emit_call(func, NULL, 0, deref0, inloop, retval, p->attr);
            } else {
                emit_call(func, args, i, deref0, inloop, retval, p->attr);
            }
            free(func);
            while (--i >= 0) {
                free(args[i]);
            }
            break;
        }
        case NODE_ADD: {
            struct node *term;
            struct node *prev;
            int deref0 = 0;
            char *prev_tmp;
            prev = AS_ADD(n)->list;
            if (prev->type == NODE_IMM) {
                prev_tmp = xstrdup(AS_IMM(prev)->value);
                maybe_symbol_forward(prev_tmp);
            } else if (prev->type == NODE_LVAL && is_loadable(prev, TRUE)) {
                prev_tmp = xstrdup(AS_LVAL(prev)->name);
                make_symbol_used(prev_tmp);
                if (AS_LVAL(prev)->deref) {
                    deref0 = TRUE;
                }
            } else if (prev->type == NODE_LVAL) {
                prev_tmp = create_address_str(AS_LVAL(prev)->name);
                deref0 = 1;
                if (AS_LVAL(prev)->deref) {
                    deref0++;
                }
            } else {
                prev_tmp = new_name("var");
                emit_nodes(prev, prev_tmp, FALSE, inloop);
                make_symbol_used(prev_tmp);
            }
            for (term = prev->next; term; term = term->next) {
                BOOL swap = FALSE;
                char *tmp;
                char *sum = new_name("sum");
                if (term->type == NODE_IMM) {
                    tmp = xstrdup(AS_IMM(term)->value);
                    maybe_symbol_forward(tmp);
                } else if (term->type == NODE_LVAL && is_loadable(term, !deref0)) {
                    tmp = xstrdup(AS_LVAL(term)->name);
                    make_symbol_used(tmp);
                    if (AS_LVAL(term)->deref) {
                        swap = TRUE;
                        deref0 = 1;
                    }
                } else if (term->type == NODE_LVAL && !deref0) {
                    tmp = create_address_str(AS_LVAL(term)->name);
                    deref0 = 1;
                    if (AS_LVAL(term)->deref) {
                        swap = TRUE;
                        deref0++;
                    }
                } else {
                    tmp = new_name("var");
                    emit_nodes(term, tmp, FALSE, inloop);
                    make_symbol_used(tmp);
                }
                emit_add(prev_tmp, tmp, deref0, swap);
                deref0 = 0;
                if (term->next) {
                    emit_store_indirect(sum);
                }
                free(prev_tmp);
                prev_tmp = sum;
                free(tmp);
            }
            free(prev_tmp);
            break;
        }
    }
    if (assignto) {
        add_symbol_forward(assignto, 0);
        emit_store_indirect(assignto);
    } else {
        BOOL loaded = FALSE;
        for (n = n->next; n; n = n->next) {
            BOOL later = FALSE;
            struct lval_node *p = AS_LVAL(n);
            assert(n->type == NODE_LVAL);
            if (fast) {
                if (optimize_imm && !p->deref && !get_symbol(p->name) && ((p->attr & ATTRIB_CONSTANT) || !inloop)) {
                    emit_fast(p->name, fast);
                    add_symbol_defined(p->name, fast, p->attr);
                    continue;
                }
                if (!loaded) {
                    loaded = TRUE;
                    if (p->deref && !is_loadable_sym(p->name)) {
                        later = TRUE;
                    } else {
                        emit_load_direct(fast, FALSE);
                    }
                }
            }
            if (p->attr & ATTRIB_CONSTANT) {
                cry("useless const for '%s'\n", p->name);
            }
            if (p->deref) {
                /* XXX only addresses (imports/vectors) can be derefed */
                if (!is_loadable_sym(p->name)) {
                    /* XXX ok, this is very very shitty
                     * tip1: store value to tmp_N for each future p->deref at once
                     * tip2: calculate in advance how many derefs we will need and store pointers before calculating r0 (see above)
                     */
                    char *ptr = new_name("ptr");
                    char *tmp;
                    if (!later) {
                        tmp = emit_save();
                    }
                    emit_load_indirect(p->name, FALSE);
                    emit_store_indirect(ptr);
                    if (!later) {
                        emit_restore(tmp);
                    } else {
                        emit_load_direct(fast, FALSE);
                    }
                    add_symbol_forward(ptr, 0);
                    make_symbol_used(ptr);
                    emit_store_direct(ptr);
                    free(ptr);
                } else {
                    make_symbol_used(p->name);
                    emit_store_direct(p->name);
                }
            } else {
                add_symbol_forward(p->name, p->attr);
                if (try_symbol_extern(p->name)) {
                    die("cannot assign to import address '%s'\n", p->name);
                }
                if (optimize_imm && (try_symbol_attr(p->name) & ATTRIB_CONSTANT)) {
                    die("'%s' was declared constant\n", p->name);
                }
                emit_store_indirect(p->name);
            }
        }
        if (force && fast && !loaded) {
            emit_load_direct(fast, FALSE);
        }
    }
}