From patchwork Thu Mar 2 08:14:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: WANG Xuerui X-Patchwork-Id: 63267 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp4110581wrd; Thu, 2 Mar 2023 00:15:10 -0800 (PST) X-Google-Smtp-Source: AK7set/CkInD95Xjo18EO0P/kOb44yi7WWuLbLHMPe4YcF2ix/4rFKMOEb5aUfG8t7QHwfi7L8Ns X-Received: by 2002:a17:906:3983:b0:88a:b6ca:7d3d with SMTP id h3-20020a170906398300b0088ab6ca7d3dmr9336243eje.8.1677744910365; Thu, 02 Mar 2023 00:15:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677744910; cv=none; d=google.com; s=arc-20160816; b=uUPY3GTjEq+OQNXSfEwhwwiyffoTpcaj20ubF8/mDHbogKfnkvYliApg2DIJZrwfKp sjaSxeX8Rps331CV4Dx4gD5858eGX5FjXF6JlbDwRqLM3xxvF41kfUB2Ql9iapsENmwj k/45GMToPhTfwUhCkp5HaBKDU6TU3sQu8oyK6mN9u4mBOYUlcyqEDwT7T4LMcZgjjyBM pB2Ub264ijZI+yy6hP1hiOWe2RtzfNZBz7nnUoC6I8sbDbCVFXp3obdwo0knIM/g7YvM ptXF+4i4QNUgU7G578tlXGJNW16MFVSeBeosk80iYoq2VpdYFs9qnygn7KKULs8R+14L F2Ig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature :dmarc-filter:delivered-to; bh=kHECH0eWvaDXy801Yw1xORTLcILdMYyXrOoj01yMQvY=; b=A7FuL+wDr44zne20KiAOIBkk9BBEDxJI71dLLtuByv0mU+FCegh8uxyTs41d5q9KVg lh0yF4OrzobEkU0sBlC6roxEgIA+/COJBHm+/1jCxGpYi4Shj6ZEy5eZM1Yknos7xzFp RVr3wbFOIA1P0ORnkRi+wCNmRn8jaqsO+rLfycTRNpgPd6Jt/Onf84MThH5P0CvO0mEb j0Givbkj8y/j0QsvB/lD19bsffZBg0Vdw29zSH2DCq2JGbwhZjeoYfZjd+Lgl8mE3/F4 gER+xiuNB/zyCfYUD1p1+WiM3HpGWSRluXTkX6vfJ+WsAMwricp0Kny0Jg+/QnR16C8j 3guw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xen0n.name header.s=mail header.b=wEA7pqao; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id fi1-20020a170906da0100b008b31de19e7dsi2260342ejb.265.2023.03.02.00.15.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Mar 2023 00:15:10 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@xen0n.name header.s=mail header.b=wEA7pqao; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9411F385841D for ; Thu, 2 Mar 2023 08:15:08 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mailbox.box.xen0n.name (mail.xen0n.name [115.28.160.31]) by sourceware.org (Postfix) with ESMTPS id A4E823858D33 for ; Thu, 2 Mar 2023 08:15:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A4E823858D33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=xen0n.name Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xen0n.name DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xen0n.name; s=mail; t=1677744897; bh=0hRsYkuTFip7QJpXylDRbN+gsTXP+nCRIrPLvgcH/cM=; h=From:To:Cc:Subject:Date:From; b=wEA7pqaonTPgJekLwsktJps5draoQ7BnYWIVvdnY8Fr5vOt+IjF8UJhCWtb7NxTZX V6AwSb6TZZOfywrrw0c/5s1JiKkq1/2Ubh5pVZgO8bYcVH5NGK/vDyU72GCM4vrjRH HmrvOQT/rQ/XqfzBsGWWsRK9/qL3BUpzW4QfpOx8= Received: from ld50.lan (unknown [114.93.192.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mailbox.box.xen0n.name (Postfix) with ESMTPSA id 8EF8F600BD; Thu, 2 Mar 2023 16:14:57 +0800 (CST) From: WANG Xuerui To: binutils@sourceware.org Cc: Chenghua Xu , Zhensong Liu , Qinggang Meng , Xi Ruoyao , WANG Xuerui Subject: [PATCH RESEND] elfedit: add support for editing e_flags Date: Thu, 2 Mar 2023 16:14:52 +0800 Message-Id: <20230302081452.3429908-1-i.swmail@xen0n.name> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1759242224277538853?= X-GMAIL-MSGID: =?utf-8?q?1759243047179845108?= From: WANG Xuerui Add a pair of elfedit options (--{input,output}-flags) for manipulating files' e_flags field. This is useful in certain cases, e.g. if you know what you are doing and have to make some object files look as if compiled for a different architecture or ABI variant. --- (Resending because I've overlooked sizeof(output_elf_flags). I wondered how BYTE_PUT is so smart to figure out the sizes until I've discovered its *local* definition *after* hitting send...) I have to pick up the work because I was trying to make AMDGPU DCN work on LoongArch, but that piece of code requires hard-float support while the LoongArch Linux kernel is compiled in the soft-float ABI, leading to link-time failures intermixing the two. Since the hard-float code in question doesn't pass around FP arguments across the boundary between object files, but rather only internally, it is safe to just edit the e_flags of the hard-float objects to make their ABI look like LP64S. Which led to me discovering the previous similar work [1] has stalled... And that's why a bunch of LoongArch-related folks are on the CC list. [1]: https://sourceware.org/pipermail/binutils/2022-April/120413.html binutils/doc/binutils.texi | 13 ++++- binutils/elfedit.c | 55 +++++++++++++++++++-- binutils/testsuite/binutils-all/elfedit-7.d | 10 ++++ binutils/testsuite/binutils-all/elfedit-8.d | 10 ++++ binutils/testsuite/binutils-all/elfedit.exp | 2 + 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 binutils/testsuite/binutils-all/elfedit-7.d create mode 100644 binutils/testsuite/binutils-all/elfedit-8.d diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index b1982a95704..a261af48254 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -5297,10 +5297,12 @@ elfedit [@option{--input-mach=}@var{machine}] [@option{--input-type=}@var{type}] [@option{--input-osabi=}@var{osabi}] [@option{--input-abiversion=}@var{version}] + [@option{--input-flags=}@var{flags}] @option{--output-mach=}@var{machine} @option{--output-type=}@var{type} @option{--output-osabi=}@var{osabi} @option{--output-abiversion=}@var{version} + @option{--output-flags=}@var{flags} @option{--enable-x86-feature=}@var{feature} @option{--disable-x86-feature=}@var{feature} [@option{-v}|@option{--version}] @@ -5325,7 +5327,7 @@ should be updated. The long and short forms of options, shown here as alternatives, are equivalent. At least one of the @option{--output-mach}, @option{--output-type}, @option{--output-osabi}, -@option{--output-abiversion}, +@option{--output-abiversion}, @option{--output-flags}, @option{--enable-x86-feature} and @option{--disable-x86-feature} options must be given. @@ -5376,6 +5378,15 @@ isn't specified, it will match any ELF ABIVERSIONs. Change the ELF ABIVERSION in the ELF header to @var{version}. @var{version} must be between 0 and 255. +@item --input-flags=@var{flags} +Set the matching input ELF file @var{e_flags} value to @var{flags}. +@var{flags} must be an unsigned 32-bit integer. If @option{--input-flags} +isn't specified, it will match any e_flags value. + +@item --output-flags=@var{flags} +Change the @var{e_flags} field in the ELF header to @var{flags}. +@var{version} must be an unsigned 32-bit integer. + @item --enable-x86-feature=@var{feature} Set the @var{feature} bit in program property in @var{exec} or @var{dyn} ELF files with machine types of @var{i386} or @var{x86-64}. The diff --git a/binutils/elfedit.c b/binutils/elfedit.c index 117e67639a0..8939198c415 100644 --- a/binutils/elfedit.c +++ b/binutils/elfedit.c @@ -68,6 +68,10 @@ enum elfclass }; static enum elfclass input_elf_class = ELF_CLASS_UNKNOWN; static enum elfclass output_elf_class = ELF_CLASS_BOTH; +static int check_elf_flags = 0; +static unsigned int input_elf_flags = 0; +static int write_elf_flags = 0; +static unsigned int output_elf_flags = 0; #ifdef HAVE_MMAP #include @@ -394,7 +398,16 @@ update_elf_header (const char *file_name, FILE *file) return 0; } - /* Update e_machine, e_type and EI_OSABI. */ + /* Skip if e_flags doesn't match. */ + if (check_elf_flags && elf_header.e_flags != input_elf_flags) + { + error + (_("%s: Unmatched e_flags: 0x%lx is not 0x%x\n"), + file_name, elf_header.e_flags, input_elf_flags); + return 0; + } + + /* Update e_machine, e_type, OSABI, ABIVERSION and e_flags. */ switch (class) { default: @@ -410,6 +423,8 @@ update_elf_header (const char *file_name, FILE *file) ehdr32.e_ident[EI_OSABI] = output_elf_osabi; if (output_elf_abiversion != -1) ehdr32.e_ident[EI_ABIVERSION] = output_elf_abiversion; + if (write_elf_flags) + BYTE_PUT (ehdr32.e_flags, output_elf_flags); status = fwrite (&ehdr32, sizeof (ehdr32), 1, file) == 1; break; case ELFCLASS64: @@ -421,6 +436,8 @@ update_elf_header (const char *file_name, FILE *file) ehdr64.e_ident[EI_OSABI] = output_elf_osabi; if (output_elf_abiversion != -1) ehdr64.e_ident[EI_ABIVERSION] = output_elf_abiversion; + if (write_elf_flags) + BYTE_PUT (ehdr64.e_flags, output_elf_flags); status = fwrite (&ehdr64, sizeof (ehdr64), 1, file) == 1; break; } @@ -904,6 +921,8 @@ enum command_line_switch OPTION_OUTPUT_OSABI, OPTION_INPUT_ABIVERSION, OPTION_OUTPUT_ABIVERSION, + OPTION_INPUT_FLAGS, + OPTION_OUTPUT_FLAGS, #ifdef HAVE_MMAP OPTION_ENABLE_X86_FEATURE, OPTION_DISABLE_X86_FEATURE, @@ -920,6 +939,8 @@ static struct option options[] = {"output-osabi", required_argument, 0, OPTION_OUTPUT_OSABI}, {"input-abiversion", required_argument, 0, OPTION_INPUT_ABIVERSION}, {"output-abiversion", required_argument, 0, OPTION_OUTPUT_ABIVERSION}, + {"input-flags", required_argument, 0, OPTION_INPUT_FLAGS}, + {"output-flags", required_argument, 0, OPTION_OUTPUT_FLAGS}, #ifdef HAVE_MMAP {"enable-x86-feature", required_argument, 0, OPTION_ENABLE_X86_FEATURE}, @@ -958,7 +979,11 @@ usage (FILE *stream, int exit_status) --output-osabi [%s]\n\ Set output OSABI\n\ --input-abiversion [0-255] Set input ABIVERSION\n\ - --output-abiversion [0-255] Set output ABIVERSION\n"), + --output-abiversion [0-255] Set output ABIVERSION\n\ + --input-flags [32-bit unsigned integer]\n\ + Set input e_flags\n\ + --output-flags [32-bit unsigned integer]\n\ + Set output e_flags\n"), osabi, osabi); #ifdef HAVE_MMAP fprintf (stream, _("\ @@ -983,6 +1008,7 @@ main (int argc, char ** argv) { int c, status; char *end; + unsigned long tmp; #ifdef HAVE_LC_MESSAGES setlocale (LC_MESSAGES, ""); @@ -1062,6 +1088,28 @@ main (int argc, char ** argv) } break; + case OPTION_INPUT_FLAGS: + check_elf_flags = 1; + tmp = strtoul (optarg, &end, 0); + if (*end != '\0' || tmp > 0xffffffff) + { + error (_("Invalid e_flags: %s\n"), optarg); + return 1; + } + input_elf_flags = (unsigned int) tmp; + break; + + case OPTION_OUTPUT_FLAGS: + write_elf_flags = 1; + tmp = strtoul (optarg, &end, 0); + if (*end != '\0' || tmp > 0xffffffff) + { + error (_("Invalid e_flags: %s\n"), optarg); + return 1; + } + output_elf_flags = (unsigned int) tmp; + break; + #ifdef HAVE_MMAP case OPTION_ENABLE_X86_FEATURE: if (elf_x86_feature (optarg, 1) < 0) @@ -1094,7 +1142,8 @@ main (int argc, char ** argv) #endif && output_elf_type == -1 && output_elf_osabi == -1 - && output_elf_abiversion == -1)) + && output_elf_abiversion == -1 + && ! write_elf_flags)) usage (stderr, 1); status = 0; diff --git a/binutils/testsuite/binutils-all/elfedit-7.d b/binutils/testsuite/binutils-all/elfedit-7.d new file mode 100644 index 00000000000..8e5a8b7d019 --- /dev/null +++ b/binutils/testsuite/binutils-all/elfedit-7.d @@ -0,0 +1,10 @@ +#PROG: elfedit +#elfedit: --output-flags 0xfedcba98 +#source: empty.s +#readelf: -h +#name: Update ELF header 7 (hexadecimal e_flags value) +#target: *-*-linux* *-*-gnu* + +#... + Flags:[ \t]+0xfedcba98.* +#... diff --git a/binutils/testsuite/binutils-all/elfedit-8.d b/binutils/testsuite/binutils-all/elfedit-8.d new file mode 100644 index 00000000000..9538f4486b8 --- /dev/null +++ b/binutils/testsuite/binutils-all/elfedit-8.d @@ -0,0 +1,10 @@ +#PROG: elfedit +#elfedit: --output-flags 12345678 +#source: empty.s +#readelf: -h +#name: Update ELF header 8 (decimal e_flags value) +#target: *-*-linux* *-*-gnu* + +#... + Flags:[ \t]+0xbc614e.* +#... diff --git a/binutils/testsuite/binutils-all/elfedit.exp b/binutils/testsuite/binutils-all/elfedit.exp index 33f4bb05529..47e94e5a775 100644 --- a/binutils/testsuite/binutils-all/elfedit.exp +++ b/binutils/testsuite/binutils-all/elfedit.exp @@ -26,3 +26,5 @@ run_dump_test "elfedit-3" run_dump_test "elfedit-4" run_dump_test "elfedit-5" run_dump_test "elfedit-6" +run_dump_test "elfedit-7" +run_dump_test "elfedit-8"