|
|
|
|
@@ -5,7 +5,7 @@
|
|
|
|
|
* This software may be used and distributed according to the terms
|
|
|
|
|
* of the GNU General Public License, incorporated herein by reference.
|
|
|
|
|
*
|
|
|
|
|
* Usage: kallsyms [--all-symbols] [--absolute-percpu] in.map > out.S
|
|
|
|
|
* Usage: kallsyms [--all-symbols] in.map > out.S
|
|
|
|
|
*
|
|
|
|
|
* Table compression uses all the unused char codes on the symbols and
|
|
|
|
|
* maps these to the most used substrings (tokens). For instance, it might
|
|
|
|
|
@@ -37,7 +37,6 @@ struct sym_entry {
|
|
|
|
|
unsigned long long addr;
|
|
|
|
|
unsigned int len;
|
|
|
|
|
unsigned int seq;
|
|
|
|
|
bool percpu_absolute;
|
|
|
|
|
unsigned char sym[];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -55,14 +54,9 @@ static struct addr_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;
|
|
|
|
|
static int absolute_percpu;
|
|
|
|
|
|
|
|
|
|
static int token_profit[0x10000];
|
|
|
|
|
|
|
|
|
|
@@ -73,7 +67,7 @@ static unsigned char best_table_len[256];
|
|
|
|
|
|
|
|
|
|
static void usage(void)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] in.map > out.S\n");
|
|
|
|
|
fprintf(stderr, "Usage: kallsyms [--all-symbols] in.map > out.S\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -164,7 +158,6 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
|
|
|
|
|
check_symbol_range(name, addr, &percpu_range, 1);
|
|
|
|
|
|
|
|
|
|
/* include the type field in the symbol name, so that it gets
|
|
|
|
|
* compressed together */
|
|
|
|
|
@@ -175,7 +168,6 @@ static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len)
|
|
|
|
|
sym->len = len;
|
|
|
|
|
sym->sym[0] = type;
|
|
|
|
|
strcpy(sym_name(sym), name);
|
|
|
|
|
sym->percpu_absolute = false;
|
|
|
|
|
|
|
|
|
|
return sym;
|
|
|
|
|
}
|
|
|
|
|
@@ -319,11 +311,6 @@ static int expand_symbol(const unsigned char *data, int len, char *result)
|
|
|
|
|
return total;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool symbol_absolute(const struct sym_entry *s)
|
|
|
|
|
{
|
|
|
|
|
return s->percpu_absolute;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int compare_names(const void *a, const void *b)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
@@ -455,22 +442,11 @@ static void write_src(void)
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
long long offset;
|
|
|
|
|
bool overflow;
|
|
|
|
|
|
|
|
|
|
if (!absolute_percpu) {
|
|
|
|
|
offset = table[i]->addr - relative_base;
|
|
|
|
|
overflow = offset < 0 || offset > UINT_MAX;
|
|
|
|
|
} else if (symbol_absolute(table[i])) {
|
|
|
|
|
offset = table[i]->addr;
|
|
|
|
|
overflow = offset < 0 || offset > INT_MAX;
|
|
|
|
|
} else {
|
|
|
|
|
offset = relative_base - table[i]->addr - 1;
|
|
|
|
|
overflow = offset < INT_MIN || offset >= 0;
|
|
|
|
|
}
|
|
|
|
|
if (overflow) {
|
|
|
|
|
offset = table[i]->addr - relative_base;
|
|
|
|
|
if (offset < 0 || offset > UINT_MAX) {
|
|
|
|
|
fprintf(stderr, "kallsyms failure: "
|
|
|
|
|
"%s symbol value %#llx out of range in relative mode\n",
|
|
|
|
|
symbol_absolute(table[i]) ? "absolute" : "relative",
|
|
|
|
|
"relative symbol value %#llx out of range\n",
|
|
|
|
|
table[i]->addr);
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
@@ -725,36 +701,15 @@ static void sort_symbols(void)
|
|
|
|
|
qsort(table, table_cnt, sizeof(table[0]), 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)) {
|
|
|
|
|
/*
|
|
|
|
|
* 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 = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* find the minimum non-absolute symbol address */
|
|
|
|
|
static void record_relative_base(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < table_cnt; i++)
|
|
|
|
|
if (!symbol_absolute(table[i])) {
|
|
|
|
|
/*
|
|
|
|
|
* The table is sorted by address.
|
|
|
|
|
* Take the first non-absolute symbol value.
|
|
|
|
|
*/
|
|
|
|
|
relative_base = table[i]->addr;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* The table is sorted by address.
|
|
|
|
|
* Take the first symbol value.
|
|
|
|
|
*/
|
|
|
|
|
if (table_cnt)
|
|
|
|
|
relative_base = table[0]->addr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
|
@@ -762,7 +717,6 @@ int main(int argc, char **argv)
|
|
|
|
|
while (1) {
|
|
|
|
|
static const struct option long_options[] = {
|
|
|
|
|
{"all-symbols", no_argument, &all_symbols, 1},
|
|
|
|
|
{"absolute-percpu", no_argument, &absolute_percpu, 1},
|
|
|
|
|
{},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -779,8 +733,6 @@ int main(int argc, char **argv)
|
|
|
|
|
|
|
|
|
|
read_map(argv[optind]);
|
|
|
|
|
shrink_table();
|
|
|
|
|
if (absolute_percpu)
|
|
|
|
|
make_percpus_absolute();
|
|
|
|
|
sort_symbols();
|
|
|
|
|
record_relative_base();
|
|
|
|
|
optimize_token_table();
|
|
|
|
|
|