Esempio n. 1
0
/* level range scale */
static bool ga_expose_event(RobWidget* handle, cairo_t* cr, cairo_rectangle_t *ev) {
	MF2UI* ui = (MF2UI*)GET_HANDLE(handle);

	if (ui->update_annotations) {
		update_annotations(ui);
		ui->update_annotations = false;
	}

	cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height);
	cairo_clip (cr);

	cairo_set_source_surface(cr, ui->sf_gain, 0, 0);
	cairo_paint (cr);

	return TRUE;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    FILE *exe;
    FILE *patch;
    unsigned int exe_length;
    unsigned int patch_length;
    char *exe_data;
    char *patch_data;

    char label[256];
    unsigned int address = 0;
    unsigned int a;
    char *l;
    int i;
    char *map_buf;
    FILE *fh;
    char *source;
    char *nasm = "nasm";
    char nasm_flags[1024] = { '\0' };
    char *tmp_name;
    char *out_name;
    char *inc_name;
    char *exe_name;
    char buf[1024];

    memset(&annotations, 0, sizeof annotations);

    if (argc < 3)
    {
        fprintf(stderr, "linker for ra303p git~%s (c) 2012 Toni Spets\n\n", REV);
        fprintf(stderr, "usage: %s <source file> <out include file> <target executable> [nasm [nasm flags]]\n", argv[0]);
        return 1;
    }

    inc_name = argv[2];
    exe_name = argv[3];
    tmp_name = tempnam(NULL, "lnkr-");
    out_name = tempnam(NULL, "lnkr-");

    if (argc > 3)
    {
        nasm = argv[4];
    }

    if (argc > 4)
    {
        int i = 5;
        for (; i < argc; i++)
        {
            strncat(nasm_flags, " ", sizeof nasm_flags);
            strncat(nasm_flags, argv[i], sizeof nasm_flags);
        }
    }

    snprintf(buf, 1024, "%s%s -e %s", nasm, nasm_flags, argv[1]);

    if ((fh = popen(buf, "r")) == NULL)
    {
        fprintf(stderr, "%s\n", buf);
        perror(nasm);
        return 1;
    }

    source = read_stream(fh);

    if (pclose(fh) != 0)
    {
        return 1;
    }

    get_annotations(source);

    if ((fh = fopen(tmp_name, "w")) == NULL)
    {
        perror(tmp_name);
        return 1;
    }

    /* always working with 32 bit images and need to map all for linking */
    fprintf(fh, "[bits 32]\n[map all]\n");
    fwrite(source, strlen(source), 1, fh);
    fclose(fh);

    snprintf(buf, 1024, "%s%s -f bin %s -o %s", nasm, nasm_flags, tmp_name, out_name);

    if ((fh = popen(buf, "r")) == NULL)
    {
        fprintf(stderr, "%s\n", buf);
        perror(nasm);
        unlink(tmp_name);
        return 1;
    }

    map_buf = read_stream(fh);

    if (pclose(fh) != 0)
    {
        unlink(tmp_name);
        return 1;
    }

    unlink(tmp_name);

    fh = fopen(inc_name, "w");
    fprintf(fh, "; generated by linker\r\n");

    l = strtok(map_buf, "\n");
    i = 0;
    do {
        if (l == NULL)
            break;

        if (address == 0)
            sscanf(l, "%X", &address);

        if (strstr(l, "Section .text"))
            i = 1;

        if (i && sscanf(l, "%*X %X  %s", &a, label) == 2)
        {
            if (strstr(l, ".") == NULL)
            {
                fprintf(fh, "%%define %-32s 0x%08X\r\n", label, a);
                update_annotations(label, a);
            }
        }
    } while((l = strtok(NULL, "\n")));

    fclose(fh);

    free(map_buf);

    if (!address)
    {
        fprintf(stderr, "linker: ORG not found in map\n");
        return 1;
    }

    exe = fopen(exe_name, "rb+");
    if (!exe)
    {
        perror(exe_name);
        return 1;
    }

    fseek(exe, 0L, SEEK_END);
    exe_length = ftell(exe);
    rewind(exe);

    exe_data = malloc(exe_length);

    if (fread(exe_data, exe_length, 1, exe) != 1)
    {
        fclose(exe);
        perror("linker: error reading executable");
        return 1;
    }

    rewind(exe);

    patch = fopen(out_name, "rb");
    if (!patch)
    {
        fclose(exe);
        perror(out_name);
        unlink(out_name);
        return 1;
    }

    fseek(patch, 0L, SEEK_END);
    patch_length = ftell(patch);
    rewind(patch);

    /* ignore empty patches */
    if (patch_length == 0)
    {
        free(exe_data);
        fclose(exe);
        return 0;
    }

    patch_data = malloc(patch_length);

    if (fread(patch_data, patch_length, 1, patch) != 1)
    {
        fclose(exe);
        fclose(patch);
        unlink(out_name);
        perror("linker: error reading patch");
        return 1;
    }

    fclose(patch);
    unlink(out_name);

    if (!patch_image(exe_data, (unsigned int)address, patch_data, patch_length))
    {
        fprintf(stderr, "linker: memory address 0x%08X not found in %s\n", (unsigned int)address, exe_name);
        return 1;
    }

    printf("PATCH  %8d bytes -> %8X\n", patch_length, address);

    /* create annotation patches */
    for (i = 0; i < 512; i++)
    {
        struct annotation *ann = &annotations[i];
        if (ann->type == NULL)
            break;

        if ((strcmp(ann->type, "hook") == 0 || strcmp(ann->type, "jmp") == 0) && ann->argc >= 2)
        {
            unsigned int from = strtol(ann->argv[0], NULL, 0);
            unsigned int to = strtol(ann->argv[1], NULL, 0);

            if (abs(to - from) < 128)
            {
                unsigned char buf[] = { 0xEB, 0x00 };
                *(signed char *)(buf + 1) = to - from - 2;
                if (!patch_image(exe_data, from, buf, sizeof buf))
                {
                    fprintf(stderr, "linker: memory address 0x%08X not found in %s\n", (unsigned int)address, exe_name);
                    return 1;
                }

                printf("%-12s %8X -> %8X\n", "JMP SHORT", from, to);
            }
            else
            {
                unsigned char buf[] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
                *(signed int *)(buf + 1) = to - from - 5;
                if (!patch_image(exe_data, from, buf, sizeof buf))
                {
                    fprintf(stderr, "linker: memory address 0x%08X not found in %s\n", (unsigned int)address, exe_name);
                    return 1;
                }

                printf("%-12s %8X -> %8X\n", "JMP", from, to);
            }
        }
        else if (strcmp(ann->type, "call") == 0 && ann->argc >= 2)
        {
            unsigned int from = strtol(ann->argv[0], NULL, 0);
            unsigned int to = strtol(ann->argv[1], NULL, 0);
            unsigned char buf[] = { 0xE8, 0x00, 0x00, 0x00, 0x00 };
            *(signed int *)(buf + 1) = to - from - 5;
            if (!patch_image(exe_data, from, buf, sizeof buf))
            {
                fprintf(stderr, "linker: memory address 0x%08X not found in %s\n", (unsigned int)address, exe_name);
                return 1;
            }

            printf("%-12s %8X -> %8X\n", "CALL", from, to);
        }
        else if (strcmp(ann->type, "clear") == 0 && ann->argc >= 3)
        {
            unsigned int from = strtol(ann->argv[0], NULL, 0);
            unsigned int character = strtol(ann->argv[1], NULL, 0);
            unsigned int to = strtol(ann->argv[2], NULL, 0);
            unsigned int length = to - from;
            char *zbuf = malloc(length);

            if (!zbuf)
            {
                fprintf(stderr, "linker: out of memory when allocating %d for zbuf\n", length);
                return 1;
            }

            memset(zbuf, (char)character, length);

            if (!patch_image(exe_data, from, zbuf, length))
            {
                fprintf(stderr, "linker: memory address 0x%08X not found in %s\n", (unsigned int)from, exe_name);
                return 1;
            }

            free(zbuf);

            printf("CLEAR  %8d bytes -> %8X\n", length, from);
        }
        else
        {
            fprintf(stderr, "linker: warning: unknown annotation \"%s\"\n", ann->type);
        }
    }

    if (fwrite(exe_data, exe_length, 1, exe) != 1)
    {
        perror("linker: error writing to executable file");
        return 1;
    }

    free(exe_data);
    free(patch_data);

    fclose(exe);

    return 0;
}
Esempio n. 3
0
static RobWidget * toplevel(MF2UI* ui, void * const top)
{
	/* main widget: layout */
	ui->rw = rob_vbox_new(FALSE, 0);
	robwidget_make_toplevel(ui->rw, top);

	ui->hbox1 = rob_hbox_new(FALSE, 0);
	ui->hbox2 = rob_hbox_new(FALSE, 0);
	ui->hbox3 = rob_hbox_new(FALSE, 0);
	ui->sep2 = robtk_sep_new(true);

	rob_vbox_child_pack(ui->rw, ui->hbox1, TRUE, TRUE);
	rob_vbox_child_pack(ui->rw, ui->hbox2, FALSE, TRUE);
	rob_vbox_child_pack(ui->rw, robtk_sep_widget(ui->sep2), FALSE, TRUE);
	rob_vbox_child_pack(ui->rw, ui->hbox3, FALSE, TRUE);

	ui->font[0] = pango_font_description_from_string("Mono 9px");
	ui->font[1] = pango_font_description_from_string("Mono 10px");
	get_color_from_theme(0, ui->c_fg);
	get_color_from_theme(1, ui->c_bg);
	m1_create_surfaces(ui);
	m2_create_surfaces(ui);

	/* main drawing area */
	ui->m0 = robwidget_new(ui);
	ROBWIDGET_SETNAME(ui->m0, "mphase (m0)");
	robwidget_set_expose_event(ui->m0, expose_event);
	robwidget_set_size_request(ui->m0, size_request);
	robwidget_set_size_allocate(ui->m0, m0_size_allocate);
	rob_hbox_child_pack(ui->hbox1, ui->m0, TRUE, TRUE);

	/* phase correlation */
	ui->m1 = robwidget_new(ui);
	ROBWIDGET_SETNAME(ui->m1, "phase (m1)");
	robwidget_set_expose_event(ui->m1, pc_expose_event);
	robwidget_set_size_request(ui->m1, pc_size_request);
	robwidget_set_size_allocate(ui->m1, pc_size_allocate);
	rob_hbox_child_pack(ui->hbox1, ui->m1, FALSE, TRUE);

	/* gain box */
	ui->sep3 = robtk_sep_new(true);
	ui->sep4 = robtk_sep_new(true);
	robtk_sep_set_linewidth(ui->sep3, 0);
	robtk_sep_set_linewidth(ui->sep4, 0);

	/* gain annotation */
	ui->m2 = robwidget_new(ui);
	ROBWIDGET_SETNAME(ui->m2, "gain (m2)");
	robwidget_set_expose_event(ui->m2, ga_expose_event);
	robwidget_set_size_request(ui->m2, ga_size_request);

	rob_hbox_child_pack(ui->hbox2, robtk_sep_widget(ui->sep3), TRUE, TRUE);
	rob_hbox_child_pack(ui->hbox2, ui->m2, FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox2, robtk_sep_widget(ui->sep4), TRUE, TRUE);

	robwidget_set_mousedown(ui->m2, m2_mousedown);
	robwidget_set_mouseup(ui->m2, m2_mouseup);
	robwidget_set_mousemove(ui->m2, m2_mousemove);
	robwidget_set_enter_notify(ui->m2, m2_enter);
	robwidget_set_leave_notify(ui->m2, m2_leave);

	/* gain dial */
	ui->gain = robtk_dial_new_with_size(-40.0, 40.0, .01,
			60, 40, 30.5, 16.5, 10);
	robtk_dial_set_alignment(ui->gain, 1.0, 0.5);
	robtk_dial_set_value(ui->gain, 0);
	robtk_dial_set_default(ui->gain, 20.0);
	robtk_dial_set_callback(ui->gain, cb_set_gain, ui);
	robtk_dial_set_surface(ui->gain,ui->sf_dial);
	robtk_dial_annotation_callback(ui->gain, dial_annotation_db, ui);
	rob_hbox_child_pack(ui->hbox2, robtk_dial_widget(ui->gain), FALSE, FALSE);

	/* fft bins */
	ui->lbl_fft = robtk_lbl_new("FFT:");
	ui->sel_fft = robtk_select_new();
	robtk_select_add_item(ui->sel_fft,   64, "128");
	robtk_select_add_item(ui->sel_fft,  128, "256");
	robtk_select_add_item(ui->sel_fft,  256, "512");
	robtk_select_add_item(ui->sel_fft,  512, "1024");
	robtk_select_add_item(ui->sel_fft, 1024, "2048");
	robtk_select_add_item(ui->sel_fft, 2048, "4096");
	robtk_select_add_item(ui->sel_fft, 4096, "8192");
	robtk_select_add_item(ui->sel_fft, 6144, "12288");
	robtk_select_add_item(ui->sel_fft, 8192, "16384");
	robtk_select_set_default_item(ui->sel_fft, 3);
	robtk_select_set_value(ui->sel_fft, 512);
	robtk_select_set_callback(ui->sel_fft, cb_set_fft, ui);

	/* N/octave */
	ui->btn_oct = robtk_cbtn_new("N/Octave Bands", GBT_LED_LEFT, false);
	robtk_cbtn_set_active(ui->btn_oct, false);
	robtk_cbtn_set_callback(ui->btn_oct, cb_set_oct, ui);

	robtk_cbtn_set_color_on(ui->btn_oct,  .2, .8, .1);
	robtk_cbtn_set_color_off(ui->btn_oct, .1, .3, .1);

	/* Normalize */
	ui->btn_norm = robtk_cbtn_new("Normalize", GBT_LED_LEFT, false);
	robtk_cbtn_set_active(ui->btn_norm, false);
	robtk_cbtn_set_callback(ui->btn_norm, cb_set_norm, ui);

	robtk_cbtn_set_color_on(ui->btn_norm,  .2, .8, .1);
	robtk_cbtn_set_color_off(ui->btn_norm, .1, .3, .1);

	/* screen persistence dial */
	ui->lbl_screen = robtk_lbl_new("Persistence:");
	ui->screen = robtk_dial_new_with_size(0.0, 100.0, 1,
			22, 22, 10.5, 10.5, 10);
	robtk_dial_set_alignment(ui->screen, 1.0, 0.5);
	robtk_dial_set_value(ui->screen, 33);
	robtk_dial_set_default(ui->screen, 33.0);
	robtk_dial_set_callback(ui->screen, cb_set_persistence, ui);

	/* explicit alignment */
	ui->sep0 = robtk_sep_new(true);
	robtk_sep_set_linewidth(ui->sep0, 0);
	ui->sep1 = robtk_sep_new(true);
	robtk_sep_set_linewidth(ui->sep1, 0);

	rob_hbox_child_pack(ui->hbox3, robtk_lbl_widget(ui->lbl_screen), FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_dial_widget(ui->screen), FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_lbl_widget(ui->lbl_fft), FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_select_widget(ui->sel_fft), FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_sep_widget(ui->sep0), TRUE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_cbtn_widget(ui->btn_oct), FALSE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_sep_widget(ui->sep1), TRUE, FALSE);
	rob_hbox_child_pack(ui->hbox3, robtk_cbtn_widget(ui->btn_norm), FALSE, FALSE);

	update_annotations(ui);
	return ui->rw;
}