Received: by 2002:a05:6358:e9c4:b0:b2:91dc:71ab with SMTP id hc4csp1894804rwb; Fri, 5 Aug 2022 09:28:11 -0700 (PDT) X-Google-Smtp-Source: AA6agR7TinrtG1PkOe8mXRjJdTMh3XFcF14NxcaE4DMCXyqqzG/sdWA0K4Z6AX/XbXMxxlf49SqX X-Received: by 2002:a17:902:c40a:b0:16e:cc02:b9ab with SMTP id k10-20020a170902c40a00b0016ecc02b9abmr7477718plk.81.1659716890955; Fri, 05 Aug 2022 09:28:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659716890; cv=none; d=google.com; s=arc-20160816; b=GQP6F4cMvWg3PJb6THVc8UpsR50HIFvluK7yQi8DZjlI0rbZG4FFUkzRmbA91YV5Uy utYUsiDjQV4qFjajhNbJS/Z3OFHk4zeKxCnXQ9gEjWZqL6pqVgX3sbNfYI/efNLRiSn8 t/8PPwMXm8n/pqjyt5K2G01yN9MAzAXCiF04sktxy94zOnxbjvW+qjTqgMDt8pWRgXzZ z+PpxoPuOztZmr07kaVdNQf+yFiWPQQIyVjOZPRiRn8qlfgrZWWvsJ/rarPk+hlF73Bk dBSoKd6cH00wNLkmTlyLm+REdoGFuCvHhouwNSDfjyDm677TmxE4hJlFexwhwrKxTIVh l7Sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Nhii1t/XyNNztYkVw12bOByUgHGve1MKXdIRyWE/gEE=; b=cqlNwIfJgdUBSetWecHIPcY52Xm2XStgHpltCXl4xbjW5/ufhT6BeKdLyj39aJ4j86 IluIHyVMDw2df4w4+vVhIQg8GA2jPGZGePm9nAHLnBsAwxl5/YkWa5p+T/AOkXQj0zm3 xo88Fe9c9aS8JLmm7By7CMNDOHMq+XnEcGoHockhf8UtSitnhPm81ppHFHXRiSDvXa1k PzXN4mPPKPFWowuB6jFynPLt69fvekFU3IPlcVwzgzVD1q0+UnP9U5EGFHA77/nOsTF4 GXG6SjIk4TWlAzMxiXzb8MT2ktormNkWG+umYqmwwh98sZHqFnXM44IE+PSmw1gUZMMH 3fsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="pRRb/uVb"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o26-20020a634e5a000000b0041ccc0ff2b8si3184665pgl.95.2022.08.05.09.27.56; Fri, 05 Aug 2022 09:28:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="pRRb/uVb"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240923AbiHEPnd (ORCPT + 99 others); Fri, 5 Aug 2022 11:43:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241049AbiHEPnM (ORCPT ); Fri, 5 Aug 2022 11:43:12 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B3B732BBE; Fri, 5 Aug 2022 08:43:08 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 8A57EB82757; Fri, 5 Aug 2022 15:43:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1DD29C433C1; Fri, 5 Aug 2022 15:43:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1659714185; bh=Cmqk+Safb+OhqlJuP/ABtXHVHQNIhLizb1za8f0+5uQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pRRb/uVbuENiD43IJjL8RWvXaDxpT5bw3aBrvzcUgIFX7yoUDjYza9mFGGXhcvohr BlZsmhpJQLnc/72Wk643UCsKXvmbl6R7Obo+5T/kLOTADb+fcL4QSWXf0w69gQKnw7 M4Y7cWvkRyb7OsFug7Jy1BFH9dPrQlkgndNCcrlbXwC6Npz3JVCUXmVROr4lv65FDJ 2QUW6SwzAXSlv31/qMKV0UJvD4iix1qZ5GbJrUpY7p2d2jWOSUAzXiy4jqRz91j7+O cRcrdVLRt1OENfoh8r03b7M4LFEeiZG+fAJNsWCTEPgEqXB9goaBeuSmJQXytmcOPO Tqk7jciqTbEKQ== From: Miguel Ojeda To: Linus Torvalds , Greg Kroah-Hartman Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, patches@lists.linux.dev, Jarkko Sakkinen , Miguel Ojeda , Kees Cook , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Boqun Feng , Matthew Wilcox Subject: [PATCH v9 04/27] kallsyms: support "big" kernel symbols Date: Fri, 5 Aug 2022 17:41:49 +0200 Message-Id: <20220805154231.31257-5-ojeda@kernel.org> In-Reply-To: <20220805154231.31257-1-ojeda@kernel.org> References: <20220805154231.31257-1-ojeda@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rust symbols can become quite long due to namespacing introduced by modules, types, traits, generics, etc. Increasing to 255 is not enough in some cases, therefore introduce longer lengths to the symbol table. In order to avoid increasing all lengths to 2 bytes (since most of them are small, including many Rust ones), use ULEB128 to keep smaller symbols in 1 byte, with the rest in 2 bytes. Reviewed-by: Kees Cook Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Co-developed-by: Matthew Wilcox Signed-off-by: Matthew Wilcox Signed-off-by: Miguel Ojeda --- kernel/kallsyms.c | 26 ++++++++++++++++++++++---- scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index fbdf8d3279ac..87e2b1638115 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -70,12 +70,20 @@ static unsigned int kallsyms_expand_symbol(unsigned int off, data = &kallsyms_names[off]; len = *data; data++; + off++; + + /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ + if ((len & 0x80) != 0) { + len = (len & 0x7F) | (*data << 7); + data++; + off++; + } /* * Update the offset to return the offset for the next symbol on * the compressed stream. */ - off += len + 1; + off += len; /* * For every byte on the compressed symbol data, copy the table @@ -128,7 +136,7 @@ static char kallsyms_get_symbol_type(unsigned int off) static unsigned int get_symbol_offset(unsigned long pos) { const u8 *name; - int i; + int i, len; /* * Use the closest marker we have. We have markers every 256 positions, @@ -142,8 +150,18 @@ static unsigned int get_symbol_offset(unsigned long pos) * so we just need to add the len to the current pointer for every * symbol we wish to skip. */ - for (i = 0; i < (pos & 0xFF); i++) - name = name + (*name) + 1; + for (i = 0; i < (pos & 0xFF); i++) { + len = *name; + + /* + * If MSB is 1, it is a "big" symbol, so we need to look into + * the next byte (and skip it, too). + */ + if ((len & 0x80) != 0) + len = ((len & 0x7F) | (name[1] << 7)) + 1; + + name = name + len + 1; + } return name - kallsyms_names; } diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index f543b1c4f99f..9da3b7767e9d 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -481,12 +481,35 @@ static void write_src(void) if ((i & 0xFF) == 0) markers[i >> 8] = off; - printf("\t.byte 0x%02x", table[i]->len); + /* There cannot be any symbol of length zero. */ + if (table[i]->len == 0) { + fprintf(stderr, "kallsyms failure: " + "unexpected zero symbol length\n"); + exit(EXIT_FAILURE); + } + + /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */ + if (table[i]->len > 0x3FFF) { + fprintf(stderr, "kallsyms failure: " + "unexpected huge symbol length\n"); + exit(EXIT_FAILURE); + } + + /* Encode length with ULEB128. */ + if (table[i]->len <= 0x7F) { + /* Most symbols use a single byte for the length. */ + printf("\t.byte 0x%02x", table[i]->len); + off += table[i]->len + 1; + } else { + /* "Big" symbols use two bytes. */ + printf("\t.byte 0x%02x, 0x%02x", + (table[i]->len & 0x7F) | 0x80, + (table[i]->len >> 7) & 0x7F); + off += table[i]->len + 2; + } for (k = 0; k < table[i]->len; k++) printf(", 0x%02x", table[i]->sym[k]); printf("\n"); - - off += table[i]->len + 1; } printf("\n"); -- 2.37.1