Skip to content

Commit 8d60526

Browse files
committed
scripts/kallsyms: change table to store (strcut sym_entry *)
The symbol table is extended every 10000 addition by using realloc(), where data copy might occur to the new buffer. To decrease the amount of possible data copy, let's change the table to store the pointer. The symbol type + symbol name part is appended at the end of (struct sym_entry), and allocated together with the struct body. Signed-off-by: Masahiro Yamada <[email protected]>
1 parent be9f613 commit 8d60526

File tree

1 file changed

+65
-56
lines changed

1 file changed

+65
-56
lines changed

scripts/kallsyms.c

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ struct sym_entry {
3333
unsigned long long addr;
3434
unsigned int len;
3535
unsigned int start_pos;
36-
unsigned char *sym;
3736
unsigned int percpu_absolute;
37+
unsigned char sym[0];
3838
};
3939

4040
struct addr_range {
@@ -55,7 +55,7 @@ static struct addr_range percpu_range = {
5555
"__per_cpu_start", "__per_cpu_end", -1ULL, 0
5656
};
5757

58-
static struct sym_entry *table;
58+
static struct sym_entry **table;
5959
static unsigned int table_size, table_cnt;
6060
static int all_symbols;
6161
static int absolute_percpu;
@@ -174,49 +174,55 @@ static void check_symbol_range(const char *sym, unsigned long long addr,
174174
}
175175
}
176176

177-
static int read_symbol(FILE *in, struct sym_entry *s)
177+
static struct sym_entry *read_symbol(FILE *in)
178178
{
179179
char name[500], type;
180+
unsigned long long addr;
181+
unsigned int len;
182+
struct sym_entry *sym;
180183
int rc;
181184

182-
rc = fscanf(in, "%llx %c %499s\n", &s->addr, &type, name);
185+
rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
183186
if (rc != 3) {
184187
if (rc != EOF && fgets(name, 500, in) == NULL)
185188
fprintf(stderr, "Read error or end of file.\n");
186-
return -1;
189+
return NULL;
187190
}
188191
if (strlen(name) >= KSYM_NAME_LEN) {
189192
fprintf(stderr, "Symbol %s too long for kallsyms (%zu >= %d).\n"
190193
"Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
191194
name, strlen(name), KSYM_NAME_LEN);
192-
return -1;
195+
return NULL;
193196
}
194197

195198
if (is_ignored_symbol(name, type))
196-
return -1;
199+
return NULL;
197200

198201
/* Ignore most absolute/undefined (?) symbols. */
199202
if (strcmp(name, "_text") == 0)
200-
_text = s->addr;
203+
_text = addr;
201204

202-
check_symbol_range(name, s->addr, text_ranges, ARRAY_SIZE(text_ranges));
203-
check_symbol_range(name, s->addr, &percpu_range, 1);
205+
check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
206+
check_symbol_range(name, addr, &percpu_range, 1);
204207

205208
/* include the type field in the symbol name, so that it gets
206209
* compressed together */
207-
s->len = strlen(name) + 1;
208-
s->sym = malloc(s->len + 1);
209-
if (!s->sym) {
210+
211+
len = strlen(name) + 1;
212+
213+
sym = malloc(sizeof(*sym) + len);
214+
if (!sym) {
210215
fprintf(stderr, "kallsyms failure: "
211216
"unable to allocate required amount of memory\n");
212217
exit(EXIT_FAILURE);
213218
}
214-
strcpy(sym_name(s), name);
215-
s->sym[0] = type;
216-
217-
s->percpu_absolute = 0;
219+
sym->addr = addr;
220+
sym->len = len;
221+
sym->sym[0] = type;
222+
memcpy(sym_name(sym), name, len);
223+
sym->percpu_absolute = 0;
218224

219-
return 0;
225+
return sym;
220226
}
221227

222228
static int symbol_in_range(const struct sym_entry *s,
@@ -268,12 +274,12 @@ static void shrink_table(void)
268274

269275
pos = 0;
270276
for (i = 0; i < table_cnt; i++) {
271-
if (symbol_valid(&table[i])) {
277+
if (symbol_valid(table[i])) {
272278
if (pos != i)
273279
table[pos] = table[i];
274280
pos++;
275281
} else {
276-
free(table[i].sym);
282+
free(table[i]);
277283
}
278284
}
279285
table_cnt = pos;
@@ -287,7 +293,15 @@ static void shrink_table(void)
287293

288294
static void read_map(FILE *in)
289295
{
296+
struct sym_entry *sym;
297+
290298
while (!feof(in)) {
299+
sym = read_symbol(in);
300+
if (!sym)
301+
continue;
302+
303+
sym->start_pos = table_cnt;
304+
291305
if (table_cnt >= table_size) {
292306
table_size += 10000;
293307
table = realloc(table, sizeof(*table) * table_size);
@@ -296,10 +310,8 @@ static void read_map(FILE *in)
296310
exit (1);
297311
}
298312
}
299-
if (read_symbol(in, &table[table_cnt]) == 0) {
300-
table[table_cnt].start_pos = table_cnt;
301-
table_cnt++;
302-
}
313+
314+
table[table_cnt++] = sym;
303315
}
304316
}
305317

@@ -387,27 +399,27 @@ static void write_src(void)
387399
int overflow;
388400

389401
if (!absolute_percpu) {
390-
offset = table[i].addr - relative_base;
402+
offset = table[i]->addr - relative_base;
391403
overflow = (offset < 0 || offset > UINT_MAX);
392-
} else if (symbol_absolute(&table[i])) {
393-
offset = table[i].addr;
404+
} else if (symbol_absolute(table[i])) {
405+
offset = table[i]->addr;
394406
overflow = (offset < 0 || offset > INT_MAX);
395407
} else {
396-
offset = relative_base - table[i].addr - 1;
408+
offset = relative_base - table[i]->addr - 1;
397409
overflow = (offset < INT_MIN || offset >= 0);
398410
}
399411
if (overflow) {
400412
fprintf(stderr, "kallsyms failure: "
401413
"%s symbol value %#llx out of range in relative mode\n",
402-
symbol_absolute(&table[i]) ? "absolute" : "relative",
403-
table[i].addr);
414+
symbol_absolute(table[i]) ? "absolute" : "relative",
415+
table[i]->addr);
404416
exit(EXIT_FAILURE);
405417
}
406418
printf("\t.long\t%#x\n", (int)offset);
407-
} else if (!symbol_absolute(&table[i])) {
408-
output_address(table[i].addr);
419+
} else if (!symbol_absolute(table[i])) {
420+
output_address(table[i]->addr);
409421
} else {
410-
printf("\tPTR\t%#llx\n", table[i].addr);
422+
printf("\tPTR\t%#llx\n", table[i]->addr);
411423
}
412424
}
413425
printf("\n");
@@ -437,12 +449,12 @@ static void write_src(void)
437449
if ((i & 0xFF) == 0)
438450
markers[i >> 8] = off;
439451

440-
printf("\t.byte 0x%02x", table[i].len);
441-
for (k = 0; k < table[i].len; k++)
442-
printf(", 0x%02x", table[i].sym[k]);
452+
printf("\t.byte 0x%02x", table[i]->len);
453+
for (k = 0; k < table[i]->len; k++)
454+
printf(", 0x%02x", table[i]->sym[k]);
443455
printf("\n");
444456

445-
off += table[i].len + 1;
457+
off += table[i]->len + 1;
446458
}
447459
printf("\n");
448460

@@ -496,7 +508,7 @@ static void build_initial_tok_table(void)
496508
unsigned int i;
497509

498510
for (i = 0; i < table_cnt; i++)
499-
learn_symbol(table[i].sym, table[i].len);
511+
learn_symbol(table[i]->sym, table[i]->len);
500512
}
501513

502514
static unsigned char *find_token(unsigned char *str, int len,
@@ -520,15 +532,15 @@ static void compress_symbols(const unsigned char *str, int idx)
520532

521533
for (i = 0; i < table_cnt; i++) {
522534

523-
len = table[i].len;
524-
p1 = table[i].sym;
535+
len = table[i]->len;
536+
p1 = table[i]->sym;
525537

526538
/* find the token on the symbol */
527539
p2 = find_token(p1, len, str);
528540
if (!p2) continue;
529541

530542
/* decrease the counts for this symbol's tokens */
531-
forget_symbol(table[i].sym, len);
543+
forget_symbol(table[i]->sym, len);
532544

533545
size = len;
534546

@@ -547,10 +559,10 @@ static void compress_symbols(const unsigned char *str, int idx)
547559

548560
} while (p2);
549561

550-
table[i].len = len;
562+
table[i]->len = len;
551563

552564
/* increase the counts for this symbol's new tokens */
553-
learn_symbol(table[i].sym, len);
565+
learn_symbol(table[i]->sym, len);
554566
}
555567
}
556568

@@ -606,8 +618,8 @@ static void insert_real_symbols_in_table(void)
606618
unsigned int i, j, c;
607619

608620
for (i = 0; i < table_cnt; i++) {
609-
for (j = 0; j < table[i].len; j++) {
610-
c = table[i].sym[j];
621+
for (j = 0; j < table[i]->len; j++) {
622+
c = table[i]->sym[j];
611623
best_table[c][0]=c;
612624
best_table_len[c]=1;
613625
}
@@ -660,13 +672,10 @@ static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
660672

661673
static int compare_symbols(const void *a, const void *b)
662674
{
663-
const struct sym_entry *sa;
664-
const struct sym_entry *sb;
675+
const struct sym_entry *sa = *(const struct sym_entry **)a;
676+
const struct sym_entry *sb = *(const struct sym_entry **)b;
665677
int wa, wb;
666678

667-
sa = a;
668-
sb = b;
669-
670679
/* sort by address first */
671680
if (sa->addr > sb->addr)
672681
return 1;
@@ -697,22 +706,22 @@ static int compare_symbols(const void *a, const void *b)
697706

698707
static void sort_symbols(void)
699708
{
700-
qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols);
709+
qsort(table, table_cnt, sizeof(table[0]), compare_symbols);
701710
}
702711

703712
static void make_percpus_absolute(void)
704713
{
705714
unsigned int i;
706715

707716
for (i = 0; i < table_cnt; i++)
708-
if (symbol_in_range(&table[i], &percpu_range, 1)) {
717+
if (symbol_in_range(table[i], &percpu_range, 1)) {
709718
/*
710719
* Keep the 'A' override for percpu symbols to
711720
* ensure consistent behavior compared to older
712721
* versions of this tool.
713722
*/
714-
table[i].sym[0] = 'A';
715-
table[i].percpu_absolute = 1;
723+
table[i]->sym[0] = 'A';
724+
table[i]->percpu_absolute = 1;
716725
}
717726
}
718727

@@ -722,12 +731,12 @@ static void record_relative_base(void)
722731
unsigned int i;
723732

724733
for (i = 0; i < table_cnt; i++)
725-
if (!symbol_absolute(&table[i])) {
734+
if (!symbol_absolute(table[i])) {
726735
/*
727736
* The table is sorted by address.
728737
* Take the first non-absolute symbol value.
729738
*/
730-
relative_base = table[i].addr;
739+
relative_base = table[i]->addr;
731740
return;
732741
}
733742
}

0 commit comments

Comments
 (0)