Skip to content

Commit

Permalink
kallsyms: don't overload absolute symbol type for percpu symbols
Browse files Browse the repository at this point in the history
Commit c6bda7c ("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 <[email protected]>
Tested-by: Guenter Roeck <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Tested-by: Kees Cook <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Michal Marek <[email protected]>
Acked-by: Rusty Russell <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Ard Biesheuvel authored and torvalds committed Mar 15, 2016
1 parent 4d5d566 commit 8c99694
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions scripts/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct sym_entry {
unsigned int len;
unsigned int start_pos;
unsigned char *sym;
unsigned int percpu_absolute;
};

struct addr_range {
Expand Down Expand Up @@ -171,6 +172,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
strcpy((char *)s->sym + 1, str);
s->sym[0] = stype;

s->percpu_absolute = 0;

/* Record if we've found __per_cpu_start/end. */
check_symbol_range(sym, s->addr, &percpu_range, 1);

Expand Down Expand Up @@ -325,7 +328,7 @@ static int expand_symbol(unsigned char *data, int len, char *result)

static int symbol_absolute(struct sym_entry *s)
{
return toupper(s->sym[0]) == 'A';
return s->percpu_absolute;
}

static void write_src(void)
Expand Down Expand Up @@ -681,8 +684,15 @@ 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))
if (symbol_in_range(&table[i], &percpu_range, 1)) {
/*
* Keep the 'A' override for percpu symbols to
* ensure consistent behavior compared to older
* versions of this tool.
*/
table[i].sym[0] = 'A';
table[i].percpu_absolute = 1;
}
}

int main(int argc, char **argv)
Expand Down

0 comments on commit 8c99694

Please sign in to comment.