int elf32_register(struct edit_file *efile) { char *e_ident = efile->mmap; uint16_t phoff; int elfmach; struct edit_segment *segs; int i; if(efile->flags & FL_NEW) { if(efile->objtype == OBJ_ELF32) { log(LOG_LOW, "Creating a new elf32 file '%s'\n", efile->filename); efile->write_file = elf32_write; efile->pagesize = elfarch_pagesize(efile->arch); return 0; } else { return 1; } } /* Check magic */ if(e_ident[0] != ELF_MAGIC_0 || e_ident[1] != ELF_MAGIC_1 || e_ident[2] != ELF_MAGIC_2 || e_ident[3] != ELF_MAGIC_3) return 1; if(e_ident[EI_CLASS] != ELFCLASS32) return 1; /* Possibly allow for old elf formats */ if(e_ident[EI_VERSION] != EV_CURRENT) return 1; /* Don't care whether or not it is executable. Let the user shoot * themself in the foot, but somebody might want to do it someday */ /* File is a elf32, so set everything up */ efile->objtype = OBJ_ELF32; if(e_ident[EI_DATA] == ELFDATA2LSB) efile->endianness = LSB; else if(e_ident[EI_DATA] == ELFDATA2MSB) efile->endianness = MSB; else { log(LOG_WARNING, "Unknown endianness: %d\n", e_ident[EI_DATA]); return 1; } elfmach = read16(offsetof(Elf32_Ehdr, e_machine) + efile->mmap, efile->endianness); efile->arch = elfmach2arch(elfmach); efile->pagesize = elfarch_pagesize(efile->arch); if(efile->arch == ARCH_INVALID) { log(LOG_WARNING, "Unknown machine type: %d\n", elfmach); return 1; } efile->write_file = elf32_write; /* XXX: If we have an entry point, ignore the one in the file. */ if (efile->entry == 0) efile->entry = read32(offsetof(Elf32_Ehdr, e_entry) + efile->mmap, efile->endianness); efile->nsegments = read16(offsetof(Elf32_Ehdr, e_phnum) + efile->mmap, efile->endianness); phoff = read32(offsetof(Elf32_Ehdr, e_phoff) + efile->mmap, efile->endianness); /* Read all sections in this file */ init_sections(efile); /* Set up segment table */ segs = calloc(efile->nsegments, sizeof(struct edit_segment)); if(segs == NULL) { log(LOG_CRITICAL, "calloc() failed\n"); exit(EXIT_FAILURE); } efile->nsegments = init_segments(efile->nsegments, segs, phoff, efile); efile->segments = segs; /* Align the file to the desired value */ i = efile->nsegments - 1; segs = efile->segments; segs[i].memsize = ALIGN(segs[i].memsize + segs[i].vaddr, efile->alignment) - segs[i].vaddr; efile->size = segs[i].vaddr + segs[i].memsize - segs[0].vaddr; /* Fix the entry point. */ if (efile->flags & FL_PHYS_ENTRY && efile->nsegments) { struct edit_section *current_section; int i, done = 0; for (i = 0; i < efile->nsegments; i++) { edit_addr start = efile->segments[i].vaddr; edit_addr end = efile->segments[i].vaddr + efile->segments[i].memsize; if ((start <= efile->entry) && (efile->entry < end)) { done = 1; efile->entry = efile->segments[i].paddr + (efile->entry - efile->segments[i].vaddr); break; } } /* If not found, just use seg 0 (probably will break) */ if (!done) { efile->entry = efile->segments[0].paddr + (efile->entry - efile->segments[0].vaddr); } /* Fix all section addresses */ for (current_section = efile->first_section; current_section != NULL; current_section = current_section->next) { done = 0; for (i = 0; i < efile->nsegments; i++) { edit_addr start = efile->segments[i].vaddr; edit_addr end = efile->segments[i].vaddr + efile->segments[i].memsize; if ((start <= current_section->addr) && (current_section->addr < end)) { done = 1; current_section->addr -= (efile->segments[i].vaddr - efile->segments[i].paddr); break; } } /* If not found, just use seg 0 (probably will break) */ if (!done) { current_section->addr -= (efile->segments[0].vaddr - efile->segments[0].paddr); } } } /* Set the correct header generator */ efile->elf_create_headers = elf32_create_headers; efile->word_size = arch_to_wordsize(efile->arch); return 0; }
int main(int argc, char **argv) { struct option long_options[] = { {"wordy", no_argument, NULL, 'w'}, {"help", no_argument, NULL, 'h'}, }; struct epoll_event events[10]; int epoll_fd = -1; struct itimerspec it; int ret; int status = EXIT_SUCCESS; if (argc > 0) progname = argv[0]; for (;;) { int c; c = getopt_long(argc, argv, "wh", long_options, NULL); if (c == -1) break; switch (c) { case 'w': wordy = true; break; case 'h': usage(false); default: usage(true); } } if (optind != argc) usage(true); dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "unable to open display '%s'\n", XDisplayName(NULL)); status = EXIT_FAILURE; goto out; } root = DefaultRootWindow(dpy); epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd == -1) { perror("epoll_create1"); status = EXIT_FAILURE; goto out; } ret = signal_fd_init(epoll_fd); if (ret == -1) { status = EXIT_FAILURE; goto out; } ret = timer_fd_init(epoll_fd); if (ret == -1) { status = EXIT_FAILURE; goto out; } ret = ctl_fd_init(epoll_fd); if (ret == -1) { status = EXIT_FAILURE; goto out; } if (init_plugins()) { status = EXIT_FAILURE; goto out; } if (init_sections(epoll_fd, config, sizeof(config) / sizeof(*config))) { status = EXIT_FAILURE; goto out; } if (update_timer_sections()) { status = EXIT_FAILURE; goto out; } it.it_interval.tv_sec = 1; it.it_interval.tv_nsec = 0; it.it_value.tv_sec = 1; it.it_value.tv_nsec = 0; ret = timerfd_settime(timer_cb.fd, 0, &it, NULL); if (ret == -1) { perror("timerfd_settime"); status = EXIT_FAILURE; goto out; } while (!quit) { int i; update = false; ret = epoll_wait(epoll_fd, events, sizeof(events) / sizeof(events[0]), -1); if (ret == -1) { if (errno == EINTR) continue; perror("epoll_wait"); status = EXIT_FAILURE; goto out; } for (i = 0; i < ret; i++) { struct epoll_callback *cb = events[i].data.ptr; ret = cb->callback(cb->fd, cb->data, events[i].events); if (ret) { status = EXIT_FAILURE; goto out; } } if (update) { ret = update_statusbar(); if (ret) { status = EXIT_FAILURE; goto out; } } } status = EXIT_SUCCESS; out: if (epoll_fd != -1) close(epoll_fd); free_sections(); if (ctl_cb.fd != -1) { close(ctl_cb.fd); unlink(ctl_addr.sun_path); } if (timer_cb.fd != -1) close(timer_cb.fd); if (signal_cb.fd != -1) close(signal_cb.fd); str_free(&status_str); if (dpy) { XStoreName(dpy, root, ""); XFlush(dpy); XCloseDisplay(dpy); } return status; }