From patchwork Sat Oct 1 06:20:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fangrui Song X-Patchwork-Id: 1627 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp123488wrs; Fri, 30 Sep 2022 23:21:20 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7CDWCBLYjIaEtg+vnow/cwg2JAwdpArT8Yx5Qd+AOsmC0Z4ClDfdQrqnn+mX1w3/U7pzHS X-Received: by 2002:a05:6402:28a1:b0:458:81c0:a379 with SMTP id eg33-20020a05640228a100b0045881c0a379mr5207255edb.388.1664605280066; Fri, 30 Sep 2022 23:21:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664605280; cv=none; d=google.com; s=arc-20160816; b=Z0dZ9H12F63i0Gy+1J9aRQxENF7luOVsFVyl8lpPLgf7r+ciMmmy5DYN1RQiflf2Bu Nsy+X8CAnaxP9dVHUjm9LgDLA1TnR4EFiU7yic3hbC2eEqxuvpZyCiebvJrSDHKuN6CT 9W1zlhL0ZyzXduqFuEt1nd0WKxbBzfwyvndNG8Ayae6ZuDZMpf+U2V1rnYNQBGGZVNAH 6vHRRAqclvuGEek4HELUPcJOrPxYDeN8R9viqF4CxXVf+jKKLM4+f0RP+UPxifBaZlMg zU3hTrUbwYSoAWs02aS+so2GRfoYwIeJgVxvBnDQT7PHntOmE9kYkKA7esPr1i8XX/y2 VXGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:to :subject:message-id:mime-version:date:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=V2XI2G5oaWtCeW5PgmE/o0lastdBScVHTlk3MV6rmVU=; b=MTiXhQZTKURxjPJ1ZHhtx8LzNghDSaRZclrNscSqfALPakFcBdBo9Xj/om50LoIWaO +DN+y9fg9ppwWKpQX7KN7OD5PT5IOnbLS4I8iEgxmcA3HutyMbtFVRfokNSLeLLNBhYK 9uS0vgCg5eRPTq+6p96bcQPc5sokTzj3KnLFCS3XbbpufHWYwPIhiOs/RZZHnSeHCTzD gqvLOQ7C5nfO+IPTP4L3Gay//y9AQjcZvK6BipmfU7AsB/fRYu8Cm/FjcVGIJr+TxklH FDtEkRoW4hNJEqJrP2NejzIP7KFhSEVPLE2vHfV0EUzDk9DVEryX+gziDQkKEppM6QlW uH4w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=SU3HQtWV; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id z9-20020a05640235c900b00453eecfd69dsi4350539edc.431.2022.09.30.23.21.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Sep 2022 23:21:20 -0700 (PDT) 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=@sourceware.org header.s=default header.b=SU3HQtWV; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D68F43857B9D for ; Sat, 1 Oct 2022 06:21:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D68F43857B9D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1664605278; bh=V2XI2G5oaWtCeW5PgmE/o0lastdBScVHTlk3MV6rmVU=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=SU3HQtWVEy/epbZtGK2rVRHY6DDXf+pZjPf6G74HylPVMZp4o39k19UkX78TlsmRr CkdZjAENV0kLaD5hpaAhpZonM/0XLNFAhihIOQMfqBcS8eBsipiEKlv9sO5C32C/VE 1L+LaQkcMbxiBpKYN04e9JEOHAczZeju1CZOoCs8= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by sourceware.org (Postfix) with ESMTPS id 79B633858D1E for ; Sat, 1 Oct 2022 06:21:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 79B633858D1E Received: by mail-yb1-xb4a.google.com with SMTP id b14-20020a056902030e00b006a827d81fd8so5613747ybs.17 for ; Fri, 30 Sep 2022 23:21:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date; bh=V2XI2G5oaWtCeW5PgmE/o0lastdBScVHTlk3MV6rmVU=; b=ln3v8w+h63aR3477KqrSMFiFL5QulOxnEPLrXrvayD2hziPYOom8jAZChbFOpjOh7d 0GtzBXC05j7asD7uvOcsYKsFGiusVk6VN9vrNl9t/Q3KRdJNo+sGXbe2yZLaY8MCLrCI V/ISpAZXHGRyP5GFixrsG0nXbhqZcng7HRKaHHW6k09JLUjgz9nTAtx2UbqhJEDqJr3p yVObhRah6/SRlCeUwCTpQushdenYXkYAu5DD5lXy9CGL4DfHtlPzug7tWTWFFtDDS83v o9k3zoYGidm7eG0j3C2OHFDMoRzQNO+Tjpg/f2DK+QRdRkLoAiI2alJEY3Y4GZEi1RMq DiuA== X-Gm-Message-State: ACrzQf3UEizWpqZ0pHANvTbysMJ6RhjFODCAw35GnVk2JQOds0D0wtOn CLn8XpXqMDf/aaL2LhRmrmIvglBG81FsH4DkMKwHGbaeLnmDYbVd7ccdKm0m8NYG7e59UQY1Zer iNNBLG3PUcgTzhMDlAtNjvWA/bqiZLzPsrbWk04fiIY/zizWxfEwzgjraLggsllWNpw== X-Received: from maskray1.svl.corp.google.com ([2620:15c:2ce:200:3a85:8afb:786d:5a2a]) (user=maskray job=sendgmr) by 2002:a25:8a0e:0:b0:692:8410:1a8e with SMTP id g14-20020a258a0e000000b0069284101a8emr10830600ybl.621.1664605264841; Fri, 30 Sep 2022 23:21:04 -0700 (PDT) Date: Fri, 30 Sep 2022 23:20:57 -0700 Mime-Version: 1.0 Message-ID: <20221001062057.681440-1-maskray@google.com> Subject: [PATCH] readelf: support zstd compressed debug sections [PR 29640] To: binutils@sourceware.org X-Spam-Status: No, score=-19.8 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL 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: , X-Patchwork-Original-From: Fangrui Song via Binutils From: Fangrui Song Reply-To: Fangrui Song Cc: Fangrui Song 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?1745465146004948557?= X-GMAIL-MSGID: =?utf-8?q?1745465146004948557?= --- binutils/Makefile.am | 6 +-- binutils/Makefile.in | 6 +-- binutils/readelf.c | 112 +++++++++++++++++++++++++++---------------- 3 files changed, 78 insertions(+), 46 deletions(-) diff --git a/binutils/Makefile.am b/binutils/Makefile.am index 751fbacce12..b249af721ae 100644 --- a/binutils/Makefile.am +++ b/binutils/Makefile.am @@ -54,8 +54,8 @@ DEBUGINFOD_LIBS = @DEBUGINFOD_LIBS@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@ NO_WERROR = @NO_WERROR@ -AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) -AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC) +AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS) +AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC) $(ZSTD_CFLAGS) LIBICONV = @LIBICONV@ # these two are almost the same program @@ -256,7 +256,7 @@ objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS) strings_SOURCES = strings.c $(BULIBS) readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS) -readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) +readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) elfedit_SOURCES = elfedit.c version.c $(ELFLIBS) elfedit_LDADD = $(LIBINTL) $(LIBIBERTY) diff --git a/binutils/Makefile.in b/binutils/Makefile.in index 6de4e239408..7d9039e0f2f 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -651,8 +651,8 @@ am__skipyacc = # case both are empty. ZLIB = @zlibdir@ -lz ZLIBINC = @zlibinc@ -AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) -AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC) +AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS) +AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC) $(ZSTD_CFLAGS) # these two are almost the same program AR_PROG = ar @@ -790,7 +790,7 @@ size_SOURCES = size.c $(BULIBS) objcopy_SOURCES = objcopy.c not-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS) strings_SOURCES = strings.c $(BULIBS) readelf_SOURCES = readelf.c version.c unwind-ia64.c dwarf.c demanguse.c $(ELFLIBS) -readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) +readelf_LDADD = $(LIBCTF_NOBFD) $(LIBINTL) $(LIBIBERTY) $(ZLIB) $(ZSTD_LIBS) $(DEBUGINFOD_LIBS) $(MSGPACK_LIBS) elfedit_SOURCES = elfedit.c version.c $(ELFLIBS) elfedit_LDADD = $(LIBINTL) $(LIBIBERTY) strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS) diff --git a/binutils/readelf.c b/binutils/readelf.c index 351571c8abb..04cda213f33 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -44,6 +44,9 @@ #include #include #include +#ifdef HAVE_ZSTD +#include +#endif #include #if defined HAVE_MSGPACK @@ -15170,48 +15173,56 @@ get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata) _("section contents")); } -/* Uncompresses a section that was compressed using zlib, in place. */ +/* Uncompresses a section that was compressed using zlib/zstd, in place. */ static bool -uncompress_section_contents (unsigned char **buffer, - uint64_t uncompressed_size, - uint64_t *size) +uncompress_section_contents (bool is_zstd, unsigned char **buffer, + uint64_t uncompressed_size, uint64_t *size) { uint64_t compressed_size = *size; unsigned char *compressed_buffer = *buffer; - unsigned char *uncompressed_buffer; + unsigned char *uncompressed_buffer = xmalloc (uncompressed_size); z_stream strm; int rc; - /* It is possible the section consists of several compressed - buffers concatenated together, so we uncompress in a loop. */ - /* PR 18313: The state field in the z_stream structure is supposed - to be invisible to the user (ie us), but some compilers will - still complain about it being used without initialisation. So - we first zero the entire z_stream structure and then set the fields - that we need. */ - memset (& strm, 0, sizeof strm); - strm.avail_in = compressed_size; - strm.next_in = (Bytef *) compressed_buffer; - strm.avail_out = uncompressed_size; - uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size); + if (is_zstd) + { +#ifdef HAVE_ZSTD + size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size, + compressed_buffer, compressed_size); + if (ZSTD_isError (ret)) + goto fail; +#endif + } + else + { + /* It is possible the section consists of several compressed + buffers concatenated together, so we uncompress in a loop. */ + /* PR 18313: The state field in the z_stream structure is supposed + to be invisible to the user (ie us), but some compilers will + still complain about it being used without initialisation. So + we first zero the entire z_stream structure and then set the fields + that we need. */ + memset (&strm, 0, sizeof strm); + strm.avail_in = compressed_size; + strm.next_in = (Bytef *)compressed_buffer; + strm.avail_out = uncompressed_size; - rc = inflateInit (& strm); - while (strm.avail_in > 0) - { - if (rc != Z_OK) - break; - strm.next_out = ((Bytef *) uncompressed_buffer - + (uncompressed_size - strm.avail_out)); - rc = inflate (&strm, Z_FINISH); - if (rc != Z_STREAM_END) - break; - rc = inflateReset (& strm); + rc = inflateInit (&strm); + while (strm.avail_in > 0) + { + if (rc != Z_OK) + break; + strm.next_out = ((Bytef *)uncompressed_buffer + + (uncompressed_size - strm.avail_out)); + rc = inflate (&strm, Z_FINISH); + if (rc != Z_STREAM_END) + break; + rc = inflateReset (&strm); + } + if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0) + goto fail; } - if (inflateEnd (& strm) != Z_OK - || rc != Z_OK - || strm.avail_out != 0) - goto fail; *buffer = uncompressed_buffer; *size = uncompressed_size; @@ -15254,6 +15265,7 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) { uint64_t new_size = num_bytes; uint64_t uncompressed_size = 0; + bool is_zstd = false; if ((section->sh_flags & SHF_COMPRESSED) != 0) { @@ -15266,7 +15278,13 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) by get_compression_header. */ goto error_out; - if (chdr.ch_type != ELFCOMPRESS_ZLIB) + if (chdr.ch_type == ELFCOMPRESS_ZLIB) + ; +#ifdef HAVE_ZSTD + else if (chdr.ch_type == ELFCOMPRESS_ZSTD) + is_zstd = true; +#endif + else { warn (_("section '%s' has unsupported compress type: %d\n"), printable_section_name (filedata, section), chdr.ch_type); @@ -15295,8 +15313,8 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) if (uncompressed_size) { - if (uncompress_section_contents (& start, - uncompressed_size, & new_size)) + if (uncompress_section_contents (is_zstd, &start, uncompressed_size, + &new_size)) num_bytes = new_size; else { @@ -15470,6 +15488,7 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, { uint64_t new_size = section_size; uint64_t uncompressed_size = 0; + bool is_zstd = false; if ((section->sh_flags & SHF_COMPRESSED) != 0) { @@ -15482,7 +15501,13 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, by get_compression_header. */ goto error_out; - if (chdr.ch_type != ELFCOMPRESS_ZLIB) + if (chdr.ch_type == ELFCOMPRESS_ZLIB) + ; +#ifdef HAVE_ZSTD + else if (chdr.ch_type == ELFCOMPRESS_ZSTD) + is_zstd = true; +#endif + else { warn (_("section '%s' has unsupported compress type: %d\n"), printable_section_name (filedata, section), chdr.ch_type); @@ -15511,8 +15536,8 @@ dump_section_as_bytes (Elf_Internal_Shdr *section, if (uncompressed_size) { - if (uncompress_section_contents (& start, uncompressed_size, - & new_size)) + if (uncompress_section_contents (is_zstd, &start, uncompressed_size, + &new_size)) { section_size = new_size; } @@ -15848,6 +15873,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, unsigned char *start = section->start; uint64_t size = sec->sh_size; uint64_t uncompressed_size = 0; + bool is_zstd = false; if ((sec->sh_flags & SHF_COMPRESSED) != 0) { @@ -15869,7 +15895,13 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, by get_compression_header. */ return false; - if (chdr.ch_type != ELFCOMPRESS_ZLIB) + if (chdr.ch_type == ELFCOMPRESS_ZLIB) + ; +#ifdef HAVE_ZSTD + else if (chdr.ch_type == ELFCOMPRESS_ZSTD) + is_zstd = true; +#endif + else { warn (_("section '%s' has unsupported compress type: %d\n"), section->name, chdr.ch_type); @@ -15898,7 +15930,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, if (uncompressed_size) { - if (uncompress_section_contents (&start, uncompressed_size, + if (uncompress_section_contents (is_zstd, &start, uncompressed_size, &size)) { /* Free the compressed buffer, update the section buffer