aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-03-15 17:58:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 19:55:16 -0400
commit8c996940b3be9c3ac40ce558c270817e1722a95b (patch)
treef5f456733ff33bdab7a61ee0c82a8f5628e1a25a
parent4d5d5664c9008c30ade92a56f722223d251883d7 (diff)
kallsyms: don't overload absolute symbol type for percpu symbols
Commit c6bda7c988a5 ("kallsyms: fix percpu vars on x86-64 with relocation") overloaded the 'A' (absolute) symbol type to signify that a symbol is not subject to dynamic relocation. However, the original A type does not imply that at all, and depending on the version of the toolchain, many A type symbols are emitted that are in fact relative to the kernel text, i.e., if the kernel is relocated at runtime, these symbols should be updated as well. For instance, on sparc32, the following symbols are emitted as absolute (kindly provided by Guenter Roeck): f035a420 A _etext f03d9000 A _sdata f03de8c4 A jiffies f03f8860 A _edata f03fc000 A __init_begin f041bdc8 A __init_text_end f0423000 A __bss_start f0423000 A __init_end f044457d A __bss_stop f044457d A _end On x86_64, similar behavior can be observed: ffffffff81a00000 A __end_rodata_hpage_align ffffffff81b19000 A __vvar_page ffffffff81d3d000 A _end Even if only a couple of them pass the symbol range check that results in them to be taken into account for the final kallsyms symbol table, it is obvious that 'A' does not mean the symbol does not need to be updated at relocation time, and overloading its meaning to signify that is perhaps not a good idea. So instead, add a new percpu_absolute member to struct sym_entry, and when --absolute-percpu is in effect, use it to record symbols whose addresses should be emitted as final values rather than values that still require relocation at runtime. That way, we can drop the check against the 'A' type. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Kees Cook <keescook@chromium.org> Tested-by: Kees Cook <keescook@chromium.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Ingo Molnar <mingo@kernel.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Michal Marek <mmarek@suse.cz> Acked-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--scripts/kallsyms.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 8fa81e84e295..d39a1eeb080e 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -34,6 +34,7 @@ struct sym_entry {
34 unsigned int len; 34 unsigned int len;
35 unsigned int start_pos; 35 unsigned int start_pos;
36 unsigned char *sym; 36 unsigned char *sym;
37 unsigned int percpu_absolute;
37}; 38};
38 39
39struct addr_range { 40struct addr_range {
@@ -171,6 +172,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
171 strcpy((char *)s->sym + 1, str); 172 strcpy((char *)s->sym + 1, str);
172 s->sym[0] = stype; 173 s->sym[0] = stype;
173 174
175 s->percpu_absolute = 0;
176
174 /* Record if we've found __per_cpu_start/end. */ 177 /* Record if we've found __per_cpu_start/end. */
175 check_symbol_range(sym, s->addr, &percpu_range, 1); 178 check_symbol_range(sym, s->addr, &percpu_range, 1);
176 179
@@ -325,7 +328,7 @@ static int expand_symbol(unsigned char *data, int len, char *result)
325 328
326static int symbol_absolute(struct sym_entry *s) 329static int symbol_absolute(struct sym_entry *s)
327{ 330{
328 return toupper(s->sym[0]) == 'A'; 331 return s->percpu_absolute;
329} 332}
330 333
331static void write_src(void) 334static void write_src(void)
@@ -681,8 +684,15 @@ static void make_percpus_absolute(void)
681 unsigned int i; 684 unsigned int i;
682 685
683 for (i = 0; i < table_cnt; i++) 686 for (i = 0; i < table_cnt; i++)
684 if (symbol_in_range(&table[i], &percpu_range, 1)) 687 if (symbol_in_range(&table[i], &percpu_range, 1)) {
688 /*
689 * Keep the 'A' override for percpu symbols to
690 * ensure consistent behavior compared to older
691 * versions of this tool.
692 */
685 table[i].sym[0] = 'A'; 693 table[i].sym[0] = 'A';
694 table[i].percpu_absolute = 1;
695 }
686} 696}
687 697
688int main(int argc, char **argv) 698int main(int argc, char **argv)