From owner-dev-commits-src-all@freebsd.org Fri May 21 13:34:49 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 630B46326A3; Fri, 21 May 2021 13:34:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Fmnf12MlPz4qHm; Fri, 21 May 2021 13:34:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3979311FC7; Fri, 21 May 2021 13:34:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 14LDYnbS004274; Fri, 21 May 2021 13:34:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14LDYnkB004273; Fri, 21 May 2021 13:34:49 GMT (envelope-from git) Date: Fri, 21 May 2021 13:34:49 GMT Message-Id: <202105211334.14LDYnkB004273@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Marcin Wojtas Subject: git: 4a27bf128b10 - main - usr.bin/elfctl: Allow for cross-endian operations. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mw X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4a27bf128b108d90412190c06a54ebac36a8ca2e Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 May 2021 13:34:49 -0000 The branch main has been updated by mw: URL: https://cgit.FreeBSD.org/src/commit/?id=4a27bf128b108d90412190c06a54ebac36a8ca2e commit 4a27bf128b108d90412190c06a54ebac36a8ca2e Author: Marcin Wojtas AuthorDate: 2021-05-21 09:19:31 +0000 Commit: Marcin Wojtas CommitDate: 2021-05-21 13:32:04 +0000 usr.bin/elfctl: Allow for cross-endian operations. Detect if host endian is different than target endian and swap byte order of ELF note fields instead of failing. Submitted by: Dawid Gorecki Reviewed by: imp Obtained from: Semihalf Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D29550 --- usr.bin/elfctl/elfctl.c | 55 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/usr.bin/elfctl/elfctl.c b/usr.bin/elfctl/elfctl.c index bcdd1be394a9..41660fc4acd5 100644 --- a/usr.bin/elfctl/elfctl.c +++ b/usr.bin/elfctl/elfctl.c @@ -52,10 +52,10 @@ __FBSDID("$FreeBSD$"); static bool convert_to_feature_val(char *, uint32_t *); -static bool edit_file_features(Elf *, int, int, char *); -static bool get_file_features(Elf *, int, int, uint32_t *, uint64_t *); +static bool edit_file_features(Elf *, int, int, char *, bool); +static bool get_file_features(Elf *, int, int, uint32_t *, uint64_t *, bool); static void print_features(void); -static bool print_file_features(Elf *, int, int, char *); +static bool print_file_features(Elf *, int, int, char *, bool); static void usage(void); struct ControlFeatures { @@ -81,9 +81,11 @@ static struct option long_opts[] = { }; #if BYTE_ORDER == LITTLE_ENDIAN -#define SUPPORTED_ENDIAN ELFDATA2LSB +#define HOST_ENDIAN ELFDATA2LSB +#define SWAP_ENDIAN ELFDATA2MSB #else -#define SUPPORTED_ENDIAN ELFDATA2MSB +#define HOST_ENDIAN ELFDATA2MSB +#define SWAP_ENDIAN ELFDATA2LSB #endif static bool iflag; @@ -96,7 +98,7 @@ main(int argc, char **argv) Elf_Kind kind; int ch, fd, retval; char *features; - bool editfeatures, lflag; + bool editfeatures, lflag, endian_swap; lflag = 0; editfeatures = false; @@ -165,24 +167,25 @@ main(int argc, char **argv) retval = 1; goto fail; } - /* - * XXX need to support cross-endian operation, but for now - * exit on error rather than misbehaving. - */ - if (ehdr.e_ident[EI_DATA] != SUPPORTED_ENDIAN) { - warnx("file endianness must match host"); + + if (ehdr.e_ident[EI_DATA] == HOST_ENDIAN) { + endian_swap = false; + } else if (ehdr.e_ident[EI_DATA] == SWAP_ENDIAN) { + endian_swap = true; + } else { + warnx("file endianness unknown"); retval = 1; goto fail; } if (!editfeatures) { if (!print_file_features(elf, ehdr.e_phnum, fd, - argv[0])) { + argv[0], endian_swap)) { retval = 1; goto fail; } } else if (!edit_file_features(elf, ehdr.e_phnum, fd, - features)) { + features, endian_swap)) { retval = 1; goto fail; } @@ -286,12 +289,13 @@ convert_to_feature_val(char *feature_str, uint32_t *feature_val) } static bool -edit_file_features(Elf *elf, int phcount, int fd, char *val) +edit_file_features(Elf *elf, int phcount, int fd, char *val, bool endian_swap) { uint32_t features; uint64_t off; - if (!get_file_features(elf, phcount, fd, &features, &off)) { + if (!get_file_features(elf, phcount, fd, &features, &off, + endian_swap)) { warnx("NT_FREEBSD_FEATURE_CTL note not found"); return (false); } @@ -299,6 +303,9 @@ edit_file_features(Elf *elf, int phcount, int fd, char *val) if (!convert_to_feature_val(val, &features)) return (false); + if (endian_swap) + features = bswap32(features); + if (lseek(fd, off, SEEK_SET) == -1 || write(fd, &features, sizeof(features)) < (ssize_t)sizeof(features)) { @@ -320,12 +327,14 @@ print_features(void) } static bool -print_file_features(Elf *elf, int phcount, int fd, char *filename) +print_file_features(Elf *elf, int phcount, int fd, char *filename, + bool endian_swap) { uint32_t features; unsigned long i; - if (!get_file_features(elf, phcount, fd, &features, NULL)) { + if (!get_file_features(elf, phcount, fd, &features, NULL, + endian_swap)) { return (false); } @@ -344,7 +353,7 @@ print_file_features(Elf *elf, int phcount, int fd, char *filename) static bool get_file_features(Elf *elf, int phcount, int fd, uint32_t *features, - uint64_t *off) + uint64_t *off, bool endian_swap) { GElf_Phdr phdr; Elf_Note note; @@ -379,6 +388,12 @@ get_file_features(Elf *elf, int phcount, int fd, uint32_t *features, } read_total += sizeof(note); + if (endian_swap) { + note.n_namesz = bswap32(note.n_namesz); + note.n_descsz = bswap32(note.n_descsz); + note.n_type = bswap32(note.n_type); + } + /* * XXX: Name and descriptor are 4 byte aligned, however, * the size given doesn't include the padding. @@ -430,6 +445,8 @@ get_file_features(Elf *elf, int phcount, int fd, uint32_t *features, free(name); return (false); } + if (endian_swap) + *features = bswap32(*features); if (off != NULL) *off = phdr.p_offset + read_total; free(name);