int main(int argc, char **argv) { const char *strtype = "FreeBSD"; int type = ELFOSABI_FREEBSD; int retval = 0; int ch, change = 0, force = 0, listed = 0; while ((ch = getopt(argc, argv, "f:lt:v")) != -1) switch (ch) { case 'f': if (change) errx(1, "f option incompatible with t option"); force = 1; type = atoi(optarg); if (errno == ERANGE || type < 0 || type > 255) { warnx("invalid argument to option f: %s", optarg); usage(); } break; case 'l': printelftypes(); listed = 1; break; case 'v': /* does nothing */ break; case 't': if (force) errx(1, "t option incompatible with f option"); change = 1; strtype = optarg; break; default: usage(); } argc -= optind; argv += optind; if (!argc) { if (listed) exit(0); else { warnx("no file(s) specified"); usage(); } } if (!force && (type = elftype(strtype)) == -1) { warnx("invalid ELF type '%s'", strtype); printelftypes(); usage(); } while (argc) { int fd; char buffer[EI_NIDENT]; if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { warn("error opening file %s", argv[0]); retval = 1; goto fail; } if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { warnx("file '%s' too short", argv[0]); retval = 1; goto fail; } if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { warnx("file '%s' is not ELF format", argv[0]); retval = 1; goto fail; } if (!change && !force) { fprintf(stdout, "File '%s' is of brand '%s' (%u).\n", argv[0], iselftype(buffer[EI_OSABI]), buffer[EI_OSABI]); if (!iselftype(type)) { warnx("ELF ABI Brand '%u' is unknown", type); printelftypes(); } } else { buffer[EI_OSABI] = type; lseek(fd, 0, SEEK_SET); if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { warn("error writing %s %d", argv[0], fd); retval = 1; goto fail; } } fail: close(fd); argc--; argv++; } return retval; }
int main(int argc, char **argv) { GElf_Ehdr ehdr; Elf *elf; Elf_Kind kind; int type = ELFOSABI_NONE; int retval = 0; int ch, change = 0, verbose = 0, force = 0, listed = 0; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "elf_version error"); while ((ch = getopt_long(argc, argv, "Vf:hlt:v", brandelf_longopts, NULL)) != -1) switch (ch) { case 'f': if (change) errx(EXIT_FAILURE, "ERROR: the -f option is " "incompatible with the -t option."); force = 1; type = atoi(optarg); if (errno == ERANGE || type < 0 || type > 255) { warnx("ERROR: invalid argument to option " "-f: %s", optarg); usage(); } break; case 'h': usage(); break; case 'l': printelftypes(); listed = 1; break; case 'v': verbose = 1; break; case 't': if (force) errx(EXIT_FAILURE, "the -t option is " "incompatible with the -f option."); if ((type = elftype(optarg)) == -1) { warnx("ERROR: invalid ELF type '%s'", optarg); usage(); } change = 1; break; case 'V': printversion(); break; default: usage(); } argc -= optind; argv += optind; if (!argc) { if (listed) exit(0); else { warnx("no file(s) specified"); usage(); } } while (argc) { int fd; elf = NULL; if ((fd = open(argv[0], (change || force) ? O_RDWR : O_RDONLY, 0)) < 0) { warn("error opening file %s", argv[0]); retval = 1; goto fail; } if ((elf = elf_begin(fd, (change || force) ? ELF_C_RDWR : ELF_C_READ, NULL)) == NULL) { warnx("elf_begin failed: %s", elf_errmsg(-1)); retval = 1; goto fail; } if ((kind = elf_kind(elf)) != ELF_K_ELF) { if (kind == ELF_K_AR) warnx("file '%s' is an archive.", argv[0]); else warnx("file '%s' is not an ELF file.", argv[0]); retval = 1; goto fail; } if (gelf_getehdr(elf, &ehdr) == NULL) { warnx("gelf_getehdr: %s", elf_errmsg(-1)); retval = 1; goto fail; } if (!change && !force) { fprintf(stdout, "File '%s' is of brand '%s' (%u).\n", argv[0], iselftype(ehdr.e_ident[EI_OSABI]), ehdr.e_ident[EI_OSABI]); if (!iselftype(type)) { warnx("ELF ABI Brand '%u' is unknown", type); printelftypes(); } } else { /* * Keep the existing layout of the ELF object. */ if (elf_flagelf(elf, ELF_C_SET, ELF_F_LAYOUT) == 0) { warnx("elf_flagelf failed: %s", elf_errmsg(-1)); retval = 1; goto fail; } /* * Update the ABI type. */ ehdr.e_ident[EI_OSABI] = type; if (gelf_update_ehdr(elf, &ehdr) == 0) { warnx("gelf_update_ehdr error: %s", elf_errmsg(-1)); retval = 1; goto fail; } /* * Write back changes. */ if (elf_update(elf, ELF_C_WRITE) == -1) { warnx("elf_update error: %s", elf_errmsg(-1)); retval = 1; goto fail; } } fail: if (elf) elf_end(elf); if (fd >= 0 && close(fd) == -1) { warnx("%s: close error", argv[0]); retval = 1; } argc--; argv++; } return (retval); }