Exemple #1
0
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;
}
Exemple #2
0
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);
}