]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
kallsyms: support big kernel symbols (2-byte lengths)
authorMiguel Ojeda <ojeda@kernel.org>
Mon, 5 Apr 2021 02:58:39 +0000 (04:58 +0200)
committerMiguel Ojeda <ojeda@kernel.org>
Sun, 4 Jul 2021 18:35:20 +0000 (20:35 +0200)
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, and therefore
we need to introduce 2-byte lengths to the symbol table. We call
these "big" symbols.

In order to avoid increasing all lengths to 2 bytes (since most
of them only require 1 byte, including many Rust ones), we use
length zero to mark "big" symbols in the table.

Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Geoffrey Thomas <geofft@ldpreload.com>
Signed-off-by: Geoffrey Thomas <geofft@ldpreload.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
kernel/kallsyms.c
scripts/kallsyms.c

index c851ca0ed357620f62696674a119b789e3e7dc47..9d0c23e1993c13965bbadc352b0db1c4043281f0 100644 (file)
@@ -73,6 +73,13 @@ static unsigned int kallsyms_expand_symbol(unsigned int off,
         */
        off += len + 1;
 
+       /* If zero, it is a "big" symbol, so a two byte length follows. */
+       if (len == 0) {
+               len = (data[0] << 8) | data[1];
+               data += 2;
+               off += len + 2;
+       }
+
        /*
         * For every byte on the compressed symbol data, copy the table
         * entry for that byte.
index 54ad86d13784995cfb8eb57bd0827204c6c36886..bcdabee13aab5f06d0ef9e67ff3c17951abd02a3 100644 (file)
@@ -470,12 +470,37 @@ 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 -- we use that
+                * to mark a "big" symbol (and it doesn't make sense anyway).
+                */
+               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 bytes are supported. */
+               if (table[i]->len > 0xFFFF) {
+                       fprintf(stderr, "kallsyms failure: "
+                               "unexpected huge symbol length\n");
+                       exit(EXIT_FAILURE);
+               }
+
+               if (table[i]->len <= 0xFF) {
+                       /* 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 a zero and then two bytes. */
+                       printf("\t.byte 0x00, 0x%02x, 0x%02x",
+                               (table[i]->len >> 8) & 0xFF,
+                               table[i]->len & 0xFF);
+                       off += table[i]->len + 3;
+               }
                for (k = 0; k < table[i]->len; k++)
                        printf(", 0x%02x", table[i]->sym[k]);
                printf("\n");
-
-               off += table[i]->len + 1;
        }
        printf("\n");