/* 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; }
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; }
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; }