summaryrefslogtreecommitdiff
path: root/scripts/kallsyms.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kallsyms.c')
-rw-r--r--scripts/kallsyms.c229
1 files changed, 74 insertions, 155 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index a239a87e7bec..0d2db41177b2 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -6,7 +6,7 @@
* of the GNU General Public License, incorporated herein by reference.
*
* Usage: kallsyms [--all-symbols] [--absolute-percpu]
- * [--base-relative] in.map > out.S
+ * [--base-relative] [--lto-clang] in.map > out.S
*
* Table compression uses all the unused char codes on the symbols and
* maps these to the most used substrings (tokens). For instance, it might
@@ -102,86 +102,7 @@ static char *sym_name(const struct sym_entry *s)
static bool is_ignored_symbol(const char *name, char type)
{
- /* Symbol names that exactly match to the following are ignored.*/
- static const char * const ignored_symbols[] = {
- /*
- * Symbols which vary between passes. Passes 1 and 2 must have
- * identical symbol lists. The kallsyms_* symbols below are
- * only added after pass 1, they would be included in pass 2
- * when --all-symbols is specified so exclude them to get a
- * stable symbol list.
- */
- "kallsyms_addresses",
- "kallsyms_offsets",
- "kallsyms_relative_base",
- "kallsyms_num_syms",
- "kallsyms_names",
- "kallsyms_markers",
- "kallsyms_token_table",
- "kallsyms_token_index",
- "kallsyms_seqs_of_names",
- /* Exclude linker generated symbols which vary between passes */
- "_SDA_BASE_", /* ppc */
- "_SDA2_BASE_", /* ppc */
- NULL
- };
-
- /* Symbol names that begin with the following are ignored.*/
- static const char * const ignored_prefixes[] = {
- "__efistub_", /* arm64 EFI stub namespace */
- "__kvm_nvhe_$", /* arm64 local symbols in non-VHE KVM namespace */
- "__kvm_nvhe_.L", /* arm64 local symbols in non-VHE KVM namespace */
- "__AArch64ADRPThunk_", /* arm64 lld */
- "__ARMV5PILongThunk_", /* arm lld */
- "__ARMV7PILongThunk_",
- "__ThumbV7PILongThunk_",
- "__LA25Thunk_", /* mips lld */
- "__microLA25Thunk_",
- "__kcfi_typeid_", /* CFI type identifiers */
- NULL
- };
-
- /* Symbol names that end with the following are ignored.*/
- static const char * const ignored_suffixes[] = {
- "_from_arm", /* arm */
- "_from_thumb", /* arm */
- "_veneer", /* arm */
- NULL
- };
-
- /* Symbol names that contain the following are ignored.*/
- static const char * const ignored_matches[] = {
- ".long_branch.", /* ppc stub */
- ".plt_branch.", /* ppc stub */
- NULL
- };
-
- const char * const *p;
-
- for (p = ignored_symbols; *p; p++)
- if (!strcmp(name, *p))
- return true;
-
- for (p = ignored_prefixes; *p; p++)
- if (!strncmp(name, *p, strlen(*p)))
- return true;
-
- for (p = ignored_suffixes; *p; p++) {
- int l = strlen(name) - strlen(*p);
-
- if (l >= 0 && !strcmp(name + l, *p))
- return true;
- }
-
- for (p = ignored_matches; *p; p++) {
- if (strstr(name, *p))
- return true;
- }
-
- if (type == 'U' || type == 'u')
- return true;
- /* exclude debugging symbols */
- if (type == 'N' || type == 'n')
+ if (type == 'u' || type == 'n')
return true;
if (toupper(type) == 'A') {
@@ -414,19 +335,10 @@ static int symbol_absolute(const struct sym_entry *s)
return s->percpu_absolute;
}
-static char * s_name(char *buf)
-{
- /* Skip the symbol type */
- return buf + 1;
-}
-
static void cleanup_symbol_name(char *s)
{
char *p;
- if (!lto_clang)
- return;
-
/*
* ASCII[.] = 2e
* ASCII[0-9] = 30,39
@@ -445,16 +357,10 @@ static void cleanup_symbol_name(char *s)
static int compare_names(const void *a, const void *b)
{
int ret;
- char sa_namebuf[KSYM_NAME_LEN];
- char sb_namebuf[KSYM_NAME_LEN];
const struct sym_entry *sa = *(const struct sym_entry **)a;
const struct sym_entry *sb = *(const struct sym_entry **)b;
- expand_symbol(sa->sym, sa->len, sa_namebuf);
- expand_symbol(sb->sym, sb->len, sb_namebuf);
- cleanup_symbol_name(s_name(sa_namebuf));
- cleanup_symbol_name(s_name(sb_namebuf));
- ret = strcmp(s_name(sa_namebuf), s_name(sb_namebuf));
+ ret = strcmp(sym_name(sa), sym_name(sb));
if (!ret) {
if (sa->addr > sb->addr)
return 1;
@@ -491,55 +397,6 @@ static void write_src(void)
printf("\t.section .rodata, \"a\"\n");
- if (!base_relative)
- output_label("kallsyms_addresses");
- else
- output_label("kallsyms_offsets");
-
- for (i = 0; i < table_cnt; i++) {
- if (base_relative) {
- /*
- * Use the offset relative to the lowest value
- * encountered of all relative symbols, and emit
- * non-relocatable fixed offsets that will be fixed
- * up at runtime.
- */
-
- long long offset;
- int overflow;
-
- if (!absolute_percpu) {
- offset = table[i]->addr - relative_base;
- overflow = (offset < 0 || offset > UINT_MAX);
- } else if (symbol_absolute(table[i])) {
- offset = table[i]->addr;
- overflow = (offset < 0 || offset > INT_MAX);
- } else {
- offset = relative_base - table[i]->addr - 1;
- overflow = (offset < INT_MIN || offset >= 0);
- }
- if (overflow) {
- fprintf(stderr, "kallsyms failure: "
- "%s symbol value %#llx out of range in relative mode\n",
- symbol_absolute(table[i]) ? "absolute" : "relative",
- table[i]->addr);
- exit(EXIT_FAILURE);
- }
- printf("\t.long\t%#x\n", (int)offset);
- } else if (!symbol_absolute(table[i])) {
- output_address(table[i]->addr);
- } else {
- printf("\tPTR\t%#llx\n", table[i]->addr);
- }
- }
- printf("\n");
-
- if (base_relative) {
- output_label("kallsyms_relative_base");
- output_address(relative_base);
- printf("\n");
- }
-
output_label("kallsyms_num_syms");
printf("\t.long\t%u\n", table_cnt);
printf("\n");
@@ -592,6 +449,15 @@ static void write_src(void)
}
printf("\n");
+ /*
+ * Now that we wrote out the compressed symbol names, restore the
+ * original names, which are needed in some of the later steps.
+ */
+ for (i = 0; i < table_cnt; i++) {
+ expand_symbol(table[i]->sym, table[i]->len, buf);
+ strcpy((char *)table[i]->sym, buf);
+ }
+
output_label("kallsyms_markers");
for (i = 0; i < ((table_cnt + 255) >> 8); i++)
printf("\t.long\t%u\n", markers[i]);
@@ -599,15 +465,6 @@ static void write_src(void)
free(markers);
- sort_symbols_by_name();
- output_label("kallsyms_seqs_of_names");
- for (i = 0; i < table_cnt; i++)
- printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
- (unsigned char)(table[i]->seq >> 16),
- (unsigned char)(table[i]->seq >> 8),
- (unsigned char)(table[i]->seq >> 0));
- printf("\n");
-
output_label("kallsyms_token_table");
off = 0;
for (i = 0; i < 256; i++) {
@@ -622,6 +479,68 @@ static void write_src(void)
for (i = 0; i < 256; i++)
printf("\t.short\t%d\n", best_idx[i]);
printf("\n");
+
+ if (!base_relative)
+ output_label("kallsyms_addresses");
+ else
+ output_label("kallsyms_offsets");
+
+ for (i = 0; i < table_cnt; i++) {
+ if (base_relative) {
+ /*
+ * Use the offset relative to the lowest value
+ * encountered of all relative symbols, and emit
+ * non-relocatable fixed offsets that will be fixed
+ * up at runtime.
+ */
+
+ long long offset;
+ int overflow;
+
+ if (!absolute_percpu) {
+ offset = table[i]->addr - relative_base;
+ overflow = (offset < 0 || offset > UINT_MAX);
+ } else if (symbol_absolute(table[i])) {
+ offset = table[i]->addr;
+ overflow = (offset < 0 || offset > INT_MAX);
+ } else {
+ offset = relative_base - table[i]->addr - 1;
+ overflow = (offset < INT_MIN || offset >= 0);
+ }
+ if (overflow) {
+ fprintf(stderr, "kallsyms failure: "
+ "%s symbol value %#llx out of range in relative mode\n",
+ symbol_absolute(table[i]) ? "absolute" : "relative",
+ table[i]->addr);
+ exit(EXIT_FAILURE);
+ }
+ printf("\t.long\t%#x /* %s */\n", (int)offset, table[i]->sym);
+ } else if (!symbol_absolute(table[i])) {
+ output_address(table[i]->addr);
+ } else {
+ printf("\tPTR\t%#llx\n", table[i]->addr);
+ }
+ }
+ printf("\n");
+
+ if (base_relative) {
+ output_label("kallsyms_relative_base");
+ output_address(relative_base);
+ printf("\n");
+ }
+
+ if (lto_clang)
+ for (i = 0; i < table_cnt; i++)
+ cleanup_symbol_name((char *)table[i]->sym);
+
+ sort_symbols_by_name();
+ output_label("kallsyms_seqs_of_names");
+ for (i = 0; i < table_cnt; i++)
+ printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
+ (unsigned char)(table[i]->seq >> 16),
+ (unsigned char)(table[i]->seq >> 8),
+ (unsigned char)(table[i]->seq >> 0));
+ printf("\n");
}