Since commit 5e5c4fa78745 ("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.
Unified · Split
| @@ -310,6 +310,15 @@ static void output_label(const char *label) · 309 unmodified lines | |||
| 310 | printf("%s:\n", label); | 310 | printf("%s:\n", label); |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 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 | |||
| 313 | /* uncompress a compressed symbol. When this function is called, the best table | 322 | /* uncompress a compressed symbol. When this function is called, the best table |
| 314 | * might still be compressed itself, so the function needs to be recursive */ | 323 | * might still be compressed itself, so the function needs to be recursive */ |
| 315 | static int expand_symbol(const unsigned char *data, int len, char *result) | 324 | static int expand_symbol(const unsigned char *data, int len, char *result) |
| @@ -360,19 +369,6 @@ static void write_src(void) · 44 unmodified lines | |||
| 360 | 369 | ||
| 361 | printf("\t.section .rodata, \"a\"\n"); | 370 | printf("\t.section .rodata, \"a\"\n"); |
| 362 | 371 | ||
| 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 | */ | ||
| 376 | if (!base_relative) | 372 | if (!base_relative) |
| 377 | output_label("kallsyms_addresses"); | 373 | output_label("kallsyms_addresses"); |
| 378 | else | 374 | else |
| @@ -380,6 +376,13 @@ static void write_src(void) · 1 unmodified line | |||
| 380 | 376 | ||
| 381 | for (i = 0; i < table_cnt; i++) { | 377 | for (i = 0; i < table_cnt; i++) { |
| 382 | if (base_relative) { | 378 | 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 | |||
| 383 | long long offset; | 386 | long long offset; |
| 384 | int overflow; | 387 | int overflow; |
| 385 | 388 | ||
| @@ -402,12 +405,7 @@ static void write_src(void) · 16 unmodified lines | |||
| 402 | } | 405 | } |
| 403 | printf("\t.long\t%#x\n", (int)offset); | 406 | printf("\t.long\t%#x\n", (int)offset); |
| 404 | } else if (!symbol_absolute(&table[i])) { | 407 | } else if (!symbol_absolute(&table[i])) { |
| 405 | if (_text <= table[i].addr) | 408 | output_address(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); | ||
| 411 | } else { | 409 | } else { |
| 412 | printf("\tPTR\t%#llx\n", table[i].addr); | 410 | printf("\tPTR\t%#llx\n", table[i].addr); |
| 413 | } | 411 | } |
| @@ -416,7 +414,7 @@ static void write_src(void) · 2 unmodified lines | |||
| 416 | 414 | ||
| 417 | if (base_relative) { | 415 | if (base_relative) { |
| 418 | output_label("kallsyms_relative_base"); | 416 | output_label("kallsyms_relative_base"); |
| 419 | printf("\tPTR\t_text - %#llx\n", _text - relative_base); | 417 | output_address(relative_base); |
| 420 | printf("\n"); | 418 | printf("\n"); |
| 421 | } | 419 | } |
| 422 | 420 | ||