|
@@ -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;
|
|
|
}
|