From nobody Sun Dec 12 18:59:51 2021 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 24D7F18D31A0; Sun, 12 Dec 2021 18:59:52 +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 4JBv8R6Gwnz3qwL; Sun, 12 Dec 2021 18:59:51 +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 B740926566; Sun, 12 Dec 2021 18:59:51 +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 1BCIxpq4019600; Sun, 12 Dec 2021 18:59:51 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BCIxpss019599; Sun, 12 Dec 2021 18:59:51 GMT (envelope-from git) Date: Sun, 12 Dec 2021 18:59:51 GMT Message-Id: <202112121859.1BCIxpss019599@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 7572ddd1671e - stable/13 - usr.bin/elfctl: Allow for cross-endian operations. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 7572ddd1671e13844a470bdfbbfbe15a4b4fbfa2 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639335591; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=KzzfeyIexcGT8OkLFKx6wSeW/TbGL/bUQbe8Urt3K0g=; b=ILo8NKVwgVbPE2M4TF7gddsAqpoQYhhzepsbGwXw9EesKsZU2ozRjezhQ+pMKm+RAZs1hr wulG2Y8dkBITjESBeXZLIblhRh+0xfGz/5vI6CvXMjnGq7GKRva2QkZNcVXnwzGKJEkTKj yAQC7GuBDiuFngSmxYHynTEMvHojW4kXFrloMa8nekUmejfb9V9hoeAurr1gLa0ar5RAm7 X19WVYqr8vBG4XfWSo4mwuzIfduHhROiaZLw2aRJbMP1+YguKAA0e8pv1T37uiZiqOjHl9 uj4OMOawA8pmAjLYnkPtye235NJRdgHkiUaDcWI0D/0ZGWj8bSf2WoIYpLnLqg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639335591; a=rsa-sha256; cv=none; b=jFt+/gN52u+kmUQ9ta1QzqZEVUm3xo2N0d66ueiH7lylDF31tSrSwmB3sZ9FmZGuWc6p1R OR6mciX65kApOgpQbRh7s617VdrxvkKheCaDjFZjlYnWXtXq8fAsNdXNh1WesrTPyXM4XJ r59YNPVjl2fdUsHDmUNOlmuVEYzYZlepqtt1ljE2s37cs44r1MYMSbgUQlr64eU1VsRCUg ww1p5/otmXupbk9ESFFMMsT2QJbE8ugslsS0aY0cybjtAg/MoVx59LyiInWU6Iex6fZUgZ RRhp4ejoqmghzlqPABJSkPP8fPD/7MGeoAXXsOLOPaWJiR64JcDxCK9lZcWmTw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=7572ddd1671e13844a470bdfbbfbe15a4b4fbfa2 commit 7572ddd1671e13844a470bdfbbfbe15a4b4fbfa2 Author: Marcin Wojtas AuthorDate: 2021-05-21 09:19:31 +0000 Commit: Ed Maste CommitDate: 2021-12-12 18:59:30 +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 (cherry picked from commit 4a27bf128b108d90412190c06a54ebac36a8ca2e) --- 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 04719b487613..ef7f915ded30 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, prev_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); } @@ -303,6 +307,9 @@ edit_file_features(Elf *elf, int phcount, int fd, char *val) if (features == prev_features) return (true); + if (endian_swap) + features = bswap32(features); + if (lseek(fd, off, SEEK_SET) == -1 || write(fd, &features, sizeof(features)) < (ssize_t)sizeof(features)) { @@ -324,12 +331,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); } @@ -348,7 +357,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; @@ -383,6 +392,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. @@ -434,6 +449,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);