Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / scripts / kallsyms.c
index d591578bd3b209ab8258a814b30727366e8909d8..8b809b264d18356ead4dc3012a2a091e3f423cb5 100644 (file)
@@ -43,7 +43,7 @@ struct sym_entry {
 
 static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
-static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
+static unsigned long long _text, _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
 
@@ -91,7 +91,9 @@ static int read_symbol(FILE *in, struct sym_entry *s)
                sym++;
 
        /* Ignore most absolute/undefined (?) symbols. */
-       if (strcmp(sym, "_stext") == 0)
+       if (strcmp(sym, "_text") == 0)
+               _text = s->addr;
+       else if (strcmp(sym, "_stext") == 0)
                _stext = s->addr;
        else if (strcmp(sym, "_etext") == 0)
                _etext = s->addr;
@@ -124,6 +126,11 @@ static int read_symbol(FILE *in, struct sym_entry *s)
         * compressed together */
        s->len = strlen(str) + 1;
        s->sym = malloc(s->len + 1);
+       if (!s->sym) {
+               fprintf(stderr, "kallsyms failure: "
+                       "unable to allocate required amount of memory\n");
+               exit(EXIT_FAILURE);
+       }
        strcpy((char *)s->sym + 1, str);
        s->sym[0] = stype;
 
@@ -258,11 +265,27 @@ static void write_src(void)
        printf("#define ALGN .align 4\n");
        printf("#endif\n");
 
-       printf(".data\n");
+       printf("\t.section .rodata, \"a\"\n");
 
+       /* Provide proper symbols relocatability by their '_text'
+        * relativeness.  The symbol names cannot be used to construct
+        * normal symbol references as the list of symbols contains
+        * symbols that are declared static and are private to their
+        * .o files.  This prevents .tmp_kallsyms.o or any other
+        * object from referencing them.
+        */
        output_label("kallsyms_addresses");
        for (i = 0; i < table_cnt; i++) {
-               printf("\tPTR\t%#llx\n", table[i].addr);
+               if (toupper(table[i].sym[0]) != 'A') {
+                       if (_text <= table[i].addr)
+                               printf("\tPTR\t_text + %#llx\n",
+                                       table[i].addr - _text);
+                       else
+                               printf("\tPTR\t_text - %#llx\n",
+                                       _text - table[i].addr);
+               } else {
+                       printf("\tPTR\t%#llx\n", table[i].addr);
+               }
        }
        printf("\n");
 
@@ -272,7 +295,12 @@ static void write_src(void)
 
        /* table of offset markers, that give the offset in the compressed stream
         * every 256 symbols */
-       markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256));
+       markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256));
+       if (!markers) {
+               fprintf(stderr, "kallsyms failure: "
+                       "unable to allocate required memory\n");
+               exit(EXIT_FAILURE);
+       }
 
        output_label("kallsyms_names");
        off = 0;