summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/kallsyms.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index ad2434b26970..6654cbed965b 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -500,6 +500,51 @@ static void optimize_token_table(void)
optimize_result();
}
+/* guess for "linker script provide" symbol */
+static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
+{
+ const char *symbol = (char *)se->sym + 1;
+ int len = se->len - 1;
+
+ if (len < 8)
+ return 0;
+
+ if (symbol[0] != '_' || symbol[1] != '_')
+ return 0;
+
+ /* __start_XXXXX */
+ if (!memcmp(symbol + 2, "start_", 6))
+ return 1;
+
+ /* __stop_XXXXX */
+ if (!memcmp(symbol + 2, "stop_", 5))
+ return 1;
+
+ /* __end_XXXXX */
+ if (!memcmp(symbol + 2, "end_", 4))
+ return 1;
+
+ /* __XXXXX_start */
+ if (!memcmp(symbol + len - 6, "_start", 6))
+ return 1;
+
+ /* __XXXXX_end */
+ if (!memcmp(symbol + len - 4, "_end", 4))
+ return 1;
+
+ return 0;
+}
+
+static int prefix_underscores_count(const char *str)
+{
+ const char *tail = str;
+
+ while (*tail != '_')
+ tail++;
+
+ return tail - str;
+}
+
static int compare_symbols(const void *a, const void *b)
{
const struct sym_entry *sa;
@@ -521,6 +566,18 @@ static int compare_symbols(const void *a, const void *b)
if (wa != wb)
return wa - wb;
+ /* sort by "linker script provide" type */
+ wa = may_be_linker_script_provide_symbol(sa);
+ wb = may_be_linker_script_provide_symbol(sb);
+ if (wa != wb)
+ return wa - wb;
+
+ /* sort by the number of prefix underscores */
+ wa = prefix_underscores_count((const char *)sa->sym + 1);
+ wb = prefix_underscores_count((const char *)sb->sym + 1);
+ if (wa != wb)
+ return wa - wb;
+
/* sort by initial order, so that other symbols are left undisturbed */
return sa->start_pos - sb->start_pos;
}