ASoC: rockchip: hdmi_dp: add support for 192k
[firefly-linux-kernel-4.4.55.git] / scripts / kallsyms.c
index 9a11f9f799f499f2d34d1dea3dec48feb36db00f..8fa81e84e29510c053e5e52cefc5eb9e1da16887 100644 (file)
@@ -36,13 +36,13 @@ struct sym_entry {
        unsigned char *sym;
 };
 
-struct text_range {
-       const char *stext, *etext;
+struct addr_range {
+       const char *start_sym, *end_sym;
        unsigned long long start, end;
 };
 
 static unsigned long long _text;
-static struct text_range text_ranges[] = {
+static struct addr_range text_ranges[] = {
        { "_stext",     "_etext"     },
        { "_sinittext", "_einittext" },
        { "_stext_l1",  "_etext_l1"  }, /* Blackfin on-chip L1 inst SRAM */
@@ -51,9 +51,14 @@ static struct text_range text_ranges[] = {
 #define text_range_text     (&text_ranges[0])
 #define text_range_inittext (&text_ranges[1])
 
+static struct addr_range percpu_range = {
+       "__per_cpu_start", "__per_cpu_end", -1ULL, 0
+};
+
 static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
 static int all_symbols = 0;
+static int absolute_percpu = 0;
 static char symbol_prefix_char = '\0';
 static unsigned long long kernel_start_addr = 0;
 
@@ -79,23 +84,24 @@ static void usage(void)
  */
 static inline int is_arm_mapping_symbol(const char *str)
 {
-       return str[0] == '$' && strchr("atd", str[1])
+       return str[0] == '$' && strchr("axtd", str[1])
               && (str[2] == '\0' || str[2] == '.');
 }
 
-static int read_symbol_tr(const char *sym, unsigned long long addr)
+static int check_symbol_range(const char *sym, unsigned long long addr,
+                             struct addr_range *ranges, int entries)
 {
        size_t i;
-       struct text_range *tr;
+       struct addr_range *ar;
 
-       for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) {
-               tr = &text_ranges[i];
+       for (i = 0; i < entries; ++i) {
+               ar = &ranges[i];
 
-               if (strcmp(sym, tr->stext) == 0) {
-                       tr->start = addr;
+               if (strcmp(sym, ar->start_sym) == 0) {
+                       ar->start = addr;
                        return 0;
-               } else if (strcmp(sym, tr->etext) == 0) {
-                       tr->end = addr;
+               } else if (strcmp(sym, ar->end_sym) == 0) {
+                       ar->end = addr;
                        return 0;
                }
        }
@@ -115,6 +121,12 @@ static int read_symbol(FILE *in, struct sym_entry *s)
                        fprintf(stderr, "Read error or end of file.\n");
                return -1;
        }
+       if (strlen(str) > KSYM_NAME_LEN) {
+               fprintf(stderr, "Symbol %s too long for kallsyms (%zu vs %d).\n"
+                               "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
+                       str, strlen(str), KSYM_NAME_LEN);
+               return -1;
+       }
 
        sym = str;
        /* skip prefix char */
@@ -124,7 +136,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
        /* Ignore most absolute/undefined (?) symbols. */
        if (strcmp(sym, "_text") == 0)
                _text = s->addr;
-       else if (read_symbol_tr(sym, s->addr) == 0)
+       else if (check_symbol_range(sym, s->addr, text_ranges,
+                                   ARRAY_SIZE(text_ranges)) == 0)
                /* nothing to do */;
        else if (toupper(stype) == 'A')
        {
@@ -158,18 +171,22 @@ static int read_symbol(FILE *in, struct sym_entry *s)
        strcpy((char *)s->sym + 1, str);
        s->sym[0] = stype;
 
+       /* Record if we've found __per_cpu_start/end. */
+       check_symbol_range(sym, s->addr, &percpu_range, 1);
+
        return 0;
 }
 
-static int symbol_valid_tr(struct sym_entry *s)
+static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges,
+                          int entries)
 {
        size_t i;
-       struct text_range *tr;
+       struct addr_range *ar;
 
-       for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) {
-               tr = &text_ranges[i];
+       for (i = 0; i < entries; ++i) {
+               ar = &ranges[i];
 
-               if (s->addr >= tr->start && s->addr <= tr->end)
+               if (s->addr >= ar->start && s->addr <= ar->end)
                        return 1;
        }
 
@@ -195,20 +212,28 @@ static int symbol_valid(struct sym_entry *s)
                "_SDA_BASE_",           /* ppc */
                "_SDA2_BASE_",          /* ppc */
                NULL };
+
+       static char *special_suffixes[] = {
+               "_veneer",              /* arm */
+               NULL };
+
        int i;
-       int offset = 1;
+       char *sym_name = (char *)s->sym + 1;
+
 
        if (s->addr < kernel_start_addr)
                return 0;
 
        /* skip prefix char */
-       if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char)
-               offset++;
+       if (symbol_prefix_char && *sym_name == symbol_prefix_char)
+               sym_name++;
+
 
        /* if --all-symbols is not specified, then symbols outside the text
         * and inittext sections are discarded */
        if (!all_symbols) {
-               if (symbol_valid_tr(s) == 0)
+               if (symbol_in_range(s, text_ranges,
+                                   ARRAY_SIZE(text_ranges)) == 0)
                        return 0;
                /* Corner case.  Discard any symbols with the same value as
                 * _etext _einittext; they can move between pass 1 and 2 when
@@ -217,20 +242,26 @@ static int symbol_valid(struct sym_entry *s)
                 * rules.
                 */
                if ((s->addr == text_range_text->end &&
-                               strcmp((char *)s->sym + offset, text_range_text->etext)) ||
+                               strcmp(sym_name,
+                                      text_range_text->end_sym)) ||
                    (s->addr == text_range_inittext->end &&
-                               strcmp((char *)s->sym + offset, text_range_inittext->etext)))
+                               strcmp(sym_name,
+                                      text_range_inittext->end_sym)))
                        return 0;
        }
 
        /* Exclude symbols which vary between passes. */
-       if (strstr((char *)s->sym + offset, "_compiled."))
-               return 0;
-
        for (i = 0; special_symbols[i]; i++)
-               if( strcmp((char *)s->sym + offset, special_symbols[i]) == 0 )
+               if (strcmp(sym_name, special_symbols[i]) == 0)
                        return 0;
 
+       for (i = 0; special_suffixes[i]; i++) {
+               int l = strlen(sym_name) - strlen(special_suffixes[i]);
+
+               if (l >= 0 && strcmp(sym_name + l, special_suffixes[i]) == 0)
+                       return 0;
+       }
+
        return 1;
 }
 
@@ -292,6 +323,11 @@ static int expand_symbol(unsigned char *data, int len, char *result)
        return total;
 }
 
+static int symbol_absolute(struct sym_entry *s)
+{
+       return toupper(s->sym[0]) == 'A';
+}
+
 static void write_src(void)
 {
        unsigned int i, k, off;
@@ -319,7 +355,7 @@ static void write_src(void)
         */
        output_label("kallsyms_addresses");
        for (i = 0; i < table_cnt; i++) {
-               if (toupper(table[i].sym[0]) != 'A') {
+               if (!symbol_absolute(&table[i])) {
                        if (_text <= table[i].addr)
                                printf("\tPTR\t_text + %#llx\n",
                                        table[i].addr - _text);
@@ -640,6 +676,15 @@ static void sort_symbols(void)
        qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols);
 }
 
+static void make_percpus_absolute(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < table_cnt; i++)
+               if (symbol_in_range(&table[i], &percpu_range, 1))
+                       table[i].sym[0] = 'A';
+}
+
 int main(int argc, char **argv)
 {
        if (argc >= 2) {
@@ -647,6 +692,8 @@ int main(int argc, char **argv)
                for (i = 1; i < argc; i++) {
                        if(strcmp(argv[i], "--all-symbols") == 0)
                                all_symbols = 1;
+                       else if (strcmp(argv[i], "--absolute-percpu") == 0)
+                               absolute_percpu = 1;
                        else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
                                char *p = &argv[i][16];
                                /* skip quote */
@@ -663,6 +710,8 @@ int main(int argc, char **argv)
                usage();
 
        read_map(stdin);
+       if (absolute_percpu)
+               make_percpus_absolute();
        sort_symbols();
        optimize_token_table();
        write_src();