Skip to content

Commit fd2ab2f

Browse files
committed
scripts/kallsyms: fix offset overflow of kallsyms_relative_base
Since commit 5e5c4fa ("scripts/kallsyms: shrink table before sorting it"), kallsyms_relative_base can be larger than _text, which causes overflow when building the 32-bit kernel. https://lkml.org/lkml/2019/12/7/156 This is because _text is, unless --all-symbols is specified, now trimmed from the symbol table before record_relative_base() is called. Handle the offset signedness also for kallsyms_relative_base. Introduce a new helper, output_address(), to reduce the code duplication. Fixes: 5e5c4fa ("scripts/kallsyms: shrink table before sorting it") Reported-by: Olof Johansson <[email protected]> Signed-off-by: Masahiro Yamada <[email protected]>
1 parent c8f3dea commit fd2ab2f

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

scripts/kallsyms.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@ static void output_label(const char *label)
310310
printf("%s:\n", label);
311311
}
312312

313+
/* Provide proper symbols relocatability by their '_text' relativeness. */
314+
static void output_address(unsigned long long addr)
315+
{
316+
if (_text <= addr)
317+
printf("\tPTR\t_text + %#llx\n", addr - _text);
318+
else
319+
printf("\tPTR\t_text - %#llx\n", _text - addr);
320+
}
321+
313322
/* uncompress a compressed symbol. When this function is called, the best table
314323
* might still be compressed itself, so the function needs to be recursive */
315324
static int expand_symbol(const unsigned char *data, int len, char *result)
@@ -360,26 +369,20 @@ static void write_src(void)
360369

361370
printf("\t.section .rodata, \"a\"\n");
362371

363-
/* Provide proper symbols relocatability by their relativeness
364-
* to a fixed anchor point in the runtime image, either '_text'
365-
* for absolute address tables, in which case the linker will
366-
* emit the final addresses at build time. Otherwise, use the
367-
* offset relative to the lowest value encountered of all relative
368-
* symbols, and emit non-relocatable fixed offsets that will be fixed
369-
* up at runtime.
370-
*
371-
* The symbol names cannot be used to construct normal symbol
372-
* references as the list of symbols contains symbols that are
373-
* declared static and are private to their .o files. This prevents
374-
* .tmp_kallsyms.o or any other object from referencing them.
375-
*/
376372
if (!base_relative)
377373
output_label("kallsyms_addresses");
378374
else
379375
output_label("kallsyms_offsets");
380376

381377
for (i = 0; i < table_cnt; i++) {
382378
if (base_relative) {
379+
/*
380+
* Use the offset relative to the lowest value
381+
* encountered of all relative symbols, and emit
382+
* non-relocatable fixed offsets that will be fixed
383+
* up at runtime.
384+
*/
385+
383386
long long offset;
384387
int overflow;
385388

@@ -402,12 +405,7 @@ static void write_src(void)
402405
}
403406
printf("\t.long\t%#x\n", (int)offset);
404407
} else if (!symbol_absolute(&table[i])) {
405-
if (_text <= table[i].addr)
406-
printf("\tPTR\t_text + %#llx\n",
407-
table[i].addr - _text);
408-
else
409-
printf("\tPTR\t_text - %#llx\n",
410-
_text - table[i].addr);
408+
output_address(table[i].addr);
411409
} else {
412410
printf("\tPTR\t%#llx\n", table[i].addr);
413411
}
@@ -416,7 +414,7 @@ static void write_src(void)
416414

417415
if (base_relative) {
418416
output_label("kallsyms_relative_base");
419-
printf("\tPTR\t_text - %#llx\n", _text - relative_base);
417+
output_address(relative_base);
420418
printf("\n");
421419
}
422420

0 commit comments

Comments
 (0)