diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | arch/Kconfig | 13 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 52 | ||||
-rw-r--r-- | include/linux/compiler.h | 23 | ||||
-rw-r--r-- | include/linux/export.h | 30 | ||||
-rw-r--r-- | include/linux/init.h | 38 | ||||
-rw-r--r-- | init/Makefile | 2 |
7 files changed, 104 insertions, 63 deletions
@@ -622,6 +622,11 @@ include arch/$(SRCARCH)/Makefile | |||
622 | KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) | 622 | KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) |
623 | KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) | 623 | KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) |
624 | 624 | ||
625 | ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | ||
626 | KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) | ||
627 | KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) | ||
628 | endif | ||
629 | |||
625 | ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE | 630 | ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE |
626 | KBUILD_CFLAGS += -Os | 631 | KBUILD_CFLAGS += -Os |
627 | else | 632 | else |
@@ -809,6 +814,10 @@ LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\ | |||
809 | KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID) | 814 | KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID) |
810 | LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) | 815 | LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) |
811 | 816 | ||
817 | ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | ||
818 | LDFLAGS_vmlinux += $(call ld-option, --gc-sections,) | ||
819 | endif | ||
820 | |||
812 | ifeq ($(CONFIG_STRIP_ASM_SYMS),y) | 821 | ifeq ($(CONFIG_STRIP_ASM_SYMS),y) |
813 | LDFLAGS_vmlinux += $(call ld-option, -X,) | 822 | LDFLAGS_vmlinux += $(call ld-option, -X,) |
814 | endif | 823 | endif |
diff --git a/arch/Kconfig b/arch/Kconfig index 6842154813e5..3f948c422d9d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -467,6 +467,19 @@ config THIN_ARCHIVES | |||
467 | Select this if the architecture wants to use thin archives | 467 | Select this if the architecture wants to use thin archives |
468 | instead of ld -r to create the built-in.o files. | 468 | instead of ld -r to create the built-in.o files. |
469 | 469 | ||
470 | config LD_DEAD_CODE_DATA_ELIMINATION | ||
471 | bool | ||
472 | help | ||
473 | Select this if the architecture wants to do dead code and | ||
474 | data elimination with the linker by compiling with | ||
475 | -ffunction-sections -fdata-sections and linking with | ||
476 | --gc-sections. | ||
477 | |||
478 | This requires that the arch annotates or otherwise protects | ||
479 | its external entry points from being discarded. Linker scripts | ||
480 | must also merge .text.*, .data.*, and .bss.* correctly into | ||
481 | output sections. | ||
482 | |||
470 | config HAVE_CONTEXT_TRACKING | 483 | config HAVE_CONTEXT_TRACKING |
471 | bool | 484 | bool |
472 | help | 485 | help |
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 24563970ff7b..ad9d8f94dc7a 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -196,9 +196,14 @@ | |||
196 | *(.dtb.init.rodata) \ | 196 | *(.dtb.init.rodata) \ |
197 | VMLINUX_SYMBOL(__dtb_end) = .; | 197 | VMLINUX_SYMBOL(__dtb_end) = .; |
198 | 198 | ||
199 | /* .data section */ | 199 | /* |
200 | * .data section | ||
201 | * -fdata-sections generates .data.identifier which needs to be pulled in | ||
202 | * with .data, but don't want to pull in .data..stuff which has its own | ||
203 | * requirements. Same for bss. | ||
204 | */ | ||
200 | #define DATA_DATA \ | 205 | #define DATA_DATA \ |
201 | *(.data) \ | 206 | *(.data .data.[0-9a-zA-Z_]*) \ |
202 | *(.ref.data) \ | 207 | *(.ref.data) \ |
203 | *(.data..shared_aligned) /* percpu related */ \ | 208 | *(.data..shared_aligned) /* percpu related */ \ |
204 | MEM_KEEP(init.data) \ | 209 | MEM_KEEP(init.data) \ |
@@ -320,76 +325,76 @@ | |||
320 | /* Kernel symbol table: Normal symbols */ \ | 325 | /* Kernel symbol table: Normal symbols */ \ |
321 | __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ | 326 | __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ |
322 | VMLINUX_SYMBOL(__start___ksymtab) = .; \ | 327 | VMLINUX_SYMBOL(__start___ksymtab) = .; \ |
323 | *(SORT(___ksymtab+*)) \ | 328 | KEEP(*(SORT(___ksymtab+*))) \ |
324 | VMLINUX_SYMBOL(__stop___ksymtab) = .; \ | 329 | VMLINUX_SYMBOL(__stop___ksymtab) = .; \ |
325 | } \ | 330 | } \ |
326 | \ | 331 | \ |
327 | /* Kernel symbol table: GPL-only symbols */ \ | 332 | /* Kernel symbol table: GPL-only symbols */ \ |
328 | __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ | 333 | __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ |
329 | VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ | 334 | VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \ |
330 | *(SORT(___ksymtab_gpl+*)) \ | 335 | KEEP(*(SORT(___ksymtab_gpl+*))) \ |
331 | VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ | 336 | VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ |
332 | } \ | 337 | } \ |
333 | \ | 338 | \ |
334 | /* Kernel symbol table: Normal unused symbols */ \ | 339 | /* Kernel symbol table: Normal unused symbols */ \ |
335 | __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ | 340 | __ksymtab_unused : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) { \ |
336 | VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ | 341 | VMLINUX_SYMBOL(__start___ksymtab_unused) = .; \ |
337 | *(SORT(___ksymtab_unused+*)) \ | 342 | KEEP(*(SORT(___ksymtab_unused+*))) \ |
338 | VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ | 343 | VMLINUX_SYMBOL(__stop___ksymtab_unused) = .; \ |
339 | } \ | 344 | } \ |
340 | \ | 345 | \ |
341 | /* Kernel symbol table: GPL-only unused symbols */ \ | 346 | /* Kernel symbol table: GPL-only unused symbols */ \ |
342 | __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ | 347 | __ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \ |
343 | VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ | 348 | VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .; \ |
344 | *(SORT(___ksymtab_unused_gpl+*)) \ | 349 | KEEP(*(SORT(___ksymtab_unused_gpl+*))) \ |
345 | VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ | 350 | VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .; \ |
346 | } \ | 351 | } \ |
347 | \ | 352 | \ |
348 | /* Kernel symbol table: GPL-future-only symbols */ \ | 353 | /* Kernel symbol table: GPL-future-only symbols */ \ |
349 | __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ | 354 | __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \ |
350 | VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ | 355 | VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \ |
351 | *(SORT(___ksymtab_gpl_future+*)) \ | 356 | KEEP(*(SORT(___ksymtab_gpl_future+*))) \ |
352 | VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ | 357 | VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \ |
353 | } \ | 358 | } \ |
354 | \ | 359 | \ |
355 | /* Kernel symbol table: Normal symbols */ \ | 360 | /* Kernel symbol table: Normal symbols */ \ |
356 | __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ | 361 | __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ |
357 | VMLINUX_SYMBOL(__start___kcrctab) = .; \ | 362 | VMLINUX_SYMBOL(__start___kcrctab) = .; \ |
358 | *(SORT(___kcrctab+*)) \ | 363 | KEEP(*(SORT(___kcrctab+*))) \ |
359 | VMLINUX_SYMBOL(__stop___kcrctab) = .; \ | 364 | VMLINUX_SYMBOL(__stop___kcrctab) = .; \ |
360 | } \ | 365 | } \ |
361 | \ | 366 | \ |
362 | /* Kernel symbol table: GPL-only symbols */ \ | 367 | /* Kernel symbol table: GPL-only symbols */ \ |
363 | __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ | 368 | __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ |
364 | VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ | 369 | VMLINUX_SYMBOL(__start___kcrctab_gpl) = .; \ |
365 | *(SORT(___kcrctab_gpl+*)) \ | 370 | KEEP(*(SORT(___kcrctab_gpl+*))) \ |
366 | VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ | 371 | VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ |
367 | } \ | 372 | } \ |
368 | \ | 373 | \ |
369 | /* Kernel symbol table: Normal unused symbols */ \ | 374 | /* Kernel symbol table: Normal unused symbols */ \ |
370 | __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ | 375 | __kcrctab_unused : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) { \ |
371 | VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \ | 376 | VMLINUX_SYMBOL(__start___kcrctab_unused) = .; \ |
372 | *(SORT(___kcrctab_unused+*)) \ | 377 | KEEP(*(SORT(___kcrctab_unused+*))) \ |
373 | VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \ | 378 | VMLINUX_SYMBOL(__stop___kcrctab_unused) = .; \ |
374 | } \ | 379 | } \ |
375 | \ | 380 | \ |
376 | /* Kernel symbol table: GPL-only unused symbols */ \ | 381 | /* Kernel symbol table: GPL-only unused symbols */ \ |
377 | __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ | 382 | __kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \ |
378 | VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ | 383 | VMLINUX_SYMBOL(__start___kcrctab_unused_gpl) = .; \ |
379 | *(SORT(___kcrctab_unused_gpl+*)) \ | 384 | KEEP(*(SORT(___kcrctab_unused_gpl+*))) \ |
380 | VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ | 385 | VMLINUX_SYMBOL(__stop___kcrctab_unused_gpl) = .; \ |
381 | } \ | 386 | } \ |
382 | \ | 387 | \ |
383 | /* Kernel symbol table: GPL-future-only symbols */ \ | 388 | /* Kernel symbol table: GPL-future-only symbols */ \ |
384 | __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ | 389 | __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \ |
385 | VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ | 390 | VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \ |
386 | *(SORT(___kcrctab_gpl_future+*)) \ | 391 | KEEP(*(SORT(___kcrctab_gpl_future+*))) \ |
387 | VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ | 392 | VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \ |
388 | } \ | 393 | } \ |
389 | \ | 394 | \ |
390 | /* Kernel symbol table: strings */ \ | 395 | /* Kernel symbol table: strings */ \ |
391 | __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ | 396 | __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ |
392 | *(__ksymtab_strings) \ | 397 | KEEP(*(__ksymtab_strings)) \ |
393 | } \ | 398 | } \ |
394 | \ | 399 | \ |
395 | /* __*init sections */ \ | 400 | /* __*init sections */ \ |
@@ -424,7 +429,7 @@ | |||
424 | #define SECURITY_INIT \ | 429 | #define SECURITY_INIT \ |
425 | .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ | 430 | .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \ |
426 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ | 431 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ |
427 | *(.security_initcall.init) \ | 432 | KEEP(*(.security_initcall.init)) \ |
428 | VMLINUX_SYMBOL(__security_initcall_end) = .; \ | 433 | VMLINUX_SYMBOL(__security_initcall_end) = .; \ |
429 | } | 434 | } |
430 | 435 | ||
@@ -432,7 +437,7 @@ | |||
432 | * during second ld run in second ld pass when generating System.map */ | 437 | * during second ld run in second ld pass when generating System.map */ |
433 | #define TEXT_TEXT \ | 438 | #define TEXT_TEXT \ |
434 | ALIGN_FUNCTION(); \ | 439 | ALIGN_FUNCTION(); \ |
435 | *(.text.hot .text .text.fixup .text.unlikely) \ | 440 | *(.text.hot .text .text.fixup .text.unlikely .text.*) \ |
436 | *(.ref.text) \ | 441 | *(.ref.text) \ |
437 | MEM_KEEP(init.text) \ | 442 | MEM_KEEP(init.text) \ |
438 | MEM_KEEP(exit.text) \ | 443 | MEM_KEEP(exit.text) \ |
@@ -527,6 +532,7 @@ | |||
527 | 532 | ||
528 | /* init and exit section handling */ | 533 | /* init and exit section handling */ |
529 | #define INIT_DATA \ | 534 | #define INIT_DATA \ |
535 | KEEP(*(SORT(___kentry+*))) \ | ||
530 | *(.init.data) \ | 536 | *(.init.data) \ |
531 | MEM_DISCARD(init.data) \ | 537 | MEM_DISCARD(init.data) \ |
532 | KERNEL_CTORS() \ | 538 | KERNEL_CTORS() \ |
@@ -593,7 +599,7 @@ | |||
593 | BSS_FIRST_SECTIONS \ | 599 | BSS_FIRST_SECTIONS \ |
594 | *(.bss..page_aligned) \ | 600 | *(.bss..page_aligned) \ |
595 | *(.dynbss) \ | 601 | *(.dynbss) \ |
596 | *(.bss) \ | 602 | *(.bss .bss.[0-9a-zA-Z_]*) \ |
597 | *(COMMON) \ | 603 | *(COMMON) \ |
598 | } | 604 | } |
599 | 605 | ||
@@ -676,12 +682,12 @@ | |||
676 | 682 | ||
677 | #define INIT_CALLS_LEVEL(level) \ | 683 | #define INIT_CALLS_LEVEL(level) \ |
678 | VMLINUX_SYMBOL(__initcall##level##_start) = .; \ | 684 | VMLINUX_SYMBOL(__initcall##level##_start) = .; \ |
679 | *(.initcall##level##.init) \ | 685 | KEEP(*(.initcall##level##.init)) \ |
680 | *(.initcall##level##s.init) \ | 686 | KEEP(*(.initcall##level##s.init)) \ |
681 | 687 | ||
682 | #define INIT_CALLS \ | 688 | #define INIT_CALLS \ |
683 | VMLINUX_SYMBOL(__initcall_start) = .; \ | 689 | VMLINUX_SYMBOL(__initcall_start) = .; \ |
684 | *(.initcallearly.init) \ | 690 | KEEP(*(.initcallearly.init)) \ |
685 | INIT_CALLS_LEVEL(0) \ | 691 | INIT_CALLS_LEVEL(0) \ |
686 | INIT_CALLS_LEVEL(1) \ | 692 | INIT_CALLS_LEVEL(1) \ |
687 | INIT_CALLS_LEVEL(2) \ | 693 | INIT_CALLS_LEVEL(2) \ |
@@ -695,21 +701,21 @@ | |||
695 | 701 | ||
696 | #define CON_INITCALL \ | 702 | #define CON_INITCALL \ |
697 | VMLINUX_SYMBOL(__con_initcall_start) = .; \ | 703 | VMLINUX_SYMBOL(__con_initcall_start) = .; \ |
698 | *(.con_initcall.init) \ | 704 | KEEP(*(.con_initcall.init)) \ |
699 | VMLINUX_SYMBOL(__con_initcall_end) = .; | 705 | VMLINUX_SYMBOL(__con_initcall_end) = .; |
700 | 706 | ||
701 | #define SECURITY_INITCALL \ | 707 | #define SECURITY_INITCALL \ |
702 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ | 708 | VMLINUX_SYMBOL(__security_initcall_start) = .; \ |
703 | *(.security_initcall.init) \ | 709 | KEEP(*(.security_initcall.init)) \ |
704 | VMLINUX_SYMBOL(__security_initcall_end) = .; | 710 | VMLINUX_SYMBOL(__security_initcall_end) = .; |
705 | 711 | ||
706 | #ifdef CONFIG_BLK_DEV_INITRD | 712 | #ifdef CONFIG_BLK_DEV_INITRD |
707 | #define INIT_RAM_FS \ | 713 | #define INIT_RAM_FS \ |
708 | . = ALIGN(4); \ | 714 | . = ALIGN(4); \ |
709 | VMLINUX_SYMBOL(__initramfs_start) = .; \ | 715 | VMLINUX_SYMBOL(__initramfs_start) = .; \ |
710 | *(.init.ramfs) \ | 716 | KEEP(*(.init.ramfs)) \ |
711 | . = ALIGN(8); \ | 717 | . = ALIGN(8); \ |
712 | *(.init.ramfs.info) | 718 | KEEP(*(.init.ramfs.info)) |
713 | #else | 719 | #else |
714 | #define INIT_RAM_FS | 720 | #define INIT_RAM_FS |
715 | #endif | 721 | #endif |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 1bb954842725..86130cded110 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -182,6 +182,29 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | |||
182 | # define unreachable() do { } while (1) | 182 | # define unreachable() do { } while (1) |
183 | #endif | 183 | #endif |
184 | 184 | ||
185 | /* | ||
186 | * KENTRY - kernel entry point | ||
187 | * This can be used to annotate symbols (functions or data) that are used | ||
188 | * without their linker symbol being referenced explicitly. For example, | ||
189 | * interrupt vector handlers, or functions in the kernel image that are found | ||
190 | * programatically. | ||
191 | * | ||
192 | * Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those | ||
193 | * are handled in their own way (with KEEP() in linker scripts). | ||
194 | * | ||
195 | * KENTRY can be avoided if the symbols in question are marked as KEEP() in the | ||
196 | * linker script. For example an architecture could KEEP() its entire | ||
197 | * boot/exception vector code rather than annotate each function and data. | ||
198 | */ | ||
199 | #ifndef KENTRY | ||
200 | # define KENTRY(sym) \ | ||
201 | extern typeof(sym) sym; \ | ||
202 | static const unsigned long __kentry_##sym \ | ||
203 | __used \ | ||
204 | __attribute__((section("___kentry" "+" #sym ), used)) \ | ||
205 | = (unsigned long)&sym; | ||
206 | #endif | ||
207 | |||
185 | #ifndef RELOC_HIDE | 208 | #ifndef RELOC_HIDE |
186 | # define RELOC_HIDE(ptr, off) \ | 209 | # define RELOC_HIDE(ptr, off) \ |
187 | ({ unsigned long __ptr; \ | 210 | ({ unsigned long __ptr; \ |
diff --git a/include/linux/export.h b/include/linux/export.h index c565f87f005e..337cb90f3668 100644 --- a/include/linux/export.h +++ b/include/linux/export.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #ifndef _LINUX_EXPORT_H | 1 | #ifndef _LINUX_EXPORT_H |
2 | #define _LINUX_EXPORT_H | 2 | #define _LINUX_EXPORT_H |
3 | |||
3 | /* | 4 | /* |
4 | * Export symbols from the kernel to modules. Forked from module.h | 5 | * Export symbols from the kernel to modules. Forked from module.h |
5 | * to reduce the amount of pointless cruft we feed to gcc when only | 6 | * to reduce the amount of pointless cruft we feed to gcc when only |
@@ -42,27 +43,26 @@ extern struct module __this_module; | |||
42 | #ifdef CONFIG_MODVERSIONS | 43 | #ifdef CONFIG_MODVERSIONS |
43 | /* Mark the CRC weak since genksyms apparently decides not to | 44 | /* Mark the CRC weak since genksyms apparently decides not to |
44 | * generate a checksums for some symbols */ | 45 | * generate a checksums for some symbols */ |
45 | #define __CRC_SYMBOL(sym, sec) \ | 46 | #define __CRC_SYMBOL(sym, sec) \ |
46 | extern __visible void *__crc_##sym __attribute__((weak)); \ | 47 | extern __visible void *__crc_##sym __attribute__((weak)); \ |
47 | static const unsigned long __kcrctab_##sym \ | 48 | static const unsigned long __kcrctab_##sym \ |
48 | __used \ | 49 | __used \ |
49 | __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ | 50 | __attribute__((section("___kcrctab" sec "+" #sym), used)) \ |
50 | = (unsigned long) &__crc_##sym; | 51 | = (unsigned long) &__crc_##sym; |
51 | #else | 52 | #else |
52 | #define __CRC_SYMBOL(sym, sec) | 53 | #define __CRC_SYMBOL(sym, sec) |
53 | #endif | 54 | #endif |
54 | 55 | ||
55 | /* For every exported symbol, place a struct in the __ksymtab section */ | 56 | /* For every exported symbol, place a struct in the __ksymtab section */ |
56 | #define ___EXPORT_SYMBOL(sym, sec) \ | 57 | #define ___EXPORT_SYMBOL(sym, sec) \ |
57 | extern typeof(sym) sym; \ | 58 | extern typeof(sym) sym; \ |
58 | __CRC_SYMBOL(sym, sec) \ | 59 | __CRC_SYMBOL(sym, sec) \ |
59 | static const char __kstrtab_##sym[] \ | 60 | static const char __kstrtab_##sym[] \ |
60 | __attribute__((section("__ksymtab_strings"), aligned(1))) \ | 61 | __attribute__((section("__ksymtab_strings"), aligned(1))) \ |
61 | = VMLINUX_SYMBOL_STR(sym); \ | 62 | = VMLINUX_SYMBOL_STR(sym); \ |
62 | extern const struct kernel_symbol __ksymtab_##sym; \ | 63 | static const struct kernel_symbol __ksymtab_##sym \ |
63 | __visible const struct kernel_symbol __ksymtab_##sym \ | 64 | __used \ |
64 | __used \ | 65 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ |
65 | __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ | ||
66 | = { (unsigned long)&sym, __kstrtab_##sym } | 66 | = { (unsigned long)&sym, __kstrtab_##sym } |
67 | 67 | ||
68 | #if defined(__KSYM_DEPS__) | 68 | #if defined(__KSYM_DEPS__) |
diff --git a/include/linux/init.h b/include/linux/init.h index 6935d02474aa..e571fec4bb28 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -150,24 +150,8 @@ extern bool initcall_debug; | |||
150 | 150 | ||
151 | #ifndef __ASSEMBLY__ | 151 | #ifndef __ASSEMBLY__ |
152 | 152 | ||
153 | #ifdef CONFIG_LTO | 153 | /* |
154 | /* Work around a LTO gcc problem: when there is no reference to a variable | 154 | * initcalls are now grouped by functionality into separate |
155 | * in a module it will be moved to the end of the program. This causes | ||
156 | * reordering of initcalls which the kernel does not like. | ||
157 | * Add a dummy reference function to avoid this. The function is | ||
158 | * deleted by the linker. | ||
159 | */ | ||
160 | #define LTO_REFERENCE_INITCALL(x) \ | ||
161 | ; /* yes this is needed */ \ | ||
162 | static __used __exit void *reference_##x(void) \ | ||
163 | { \ | ||
164 | return &x; \ | ||
165 | } | ||
166 | #else | ||
167 | #define LTO_REFERENCE_INITCALL(x) | ||
168 | #endif | ||
169 | |||
170 | /* initcalls are now grouped by functionality into separate | ||
171 | * subsections. Ordering inside the subsections is determined | 155 | * subsections. Ordering inside the subsections is determined |
172 | * by link order. | 156 | * by link order. |
173 | * For backwards compatibility, initcall() puts the call in | 157 | * For backwards compatibility, initcall() puts the call in |
@@ -175,12 +159,16 @@ extern bool initcall_debug; | |||
175 | * | 159 | * |
176 | * The `id' arg to __define_initcall() is needed so that multiple initcalls | 160 | * The `id' arg to __define_initcall() is needed so that multiple initcalls |
177 | * can point at the same handler without causing duplicate-symbol build errors. | 161 | * can point at the same handler without causing duplicate-symbol build errors. |
162 | * | ||
163 | * Initcalls are run by placing pointers in initcall sections that the | ||
164 | * kernel iterates at runtime. The linker can do dead code / data elimination | ||
165 | * and remove that completely, so the initcall sections have to be marked | ||
166 | * as KEEP() in the linker script. | ||
178 | */ | 167 | */ |
179 | 168 | ||
180 | #define __define_initcall(fn, id) \ | 169 | #define __define_initcall(fn, id) \ |
181 | static initcall_t __initcall_##fn##id __used \ | 170 | static initcall_t __initcall_##fn##id __used \ |
182 | __attribute__((__section__(".initcall" #id ".init"))) = fn; \ | 171 | __attribute__((__section__(".initcall" #id ".init"))) = fn; |
183 | LTO_REFERENCE_INITCALL(__initcall_##fn##id) | ||
184 | 172 | ||
185 | /* | 173 | /* |
186 | * Early initcalls run before initializing SMP. | 174 | * Early initcalls run before initializing SMP. |
@@ -216,15 +204,15 @@ extern bool initcall_debug; | |||
216 | 204 | ||
217 | #define __initcall(fn) device_initcall(fn) | 205 | #define __initcall(fn) device_initcall(fn) |
218 | 206 | ||
219 | #define __exitcall(fn) \ | 207 | #define __exitcall(fn) \ |
220 | static exitcall_t __exitcall_##fn __exit_call = fn | 208 | static exitcall_t __exitcall_##fn __exit_call = fn |
221 | 209 | ||
222 | #define console_initcall(fn) \ | 210 | #define console_initcall(fn) \ |
223 | static initcall_t __initcall_##fn \ | 211 | static initcall_t __initcall_##fn \ |
224 | __used __section(.con_initcall.init) = fn | 212 | __used __section(.con_initcall.init) = fn |
225 | 213 | ||
226 | #define security_initcall(fn) \ | 214 | #define security_initcall(fn) \ |
227 | static initcall_t __initcall_##fn \ | 215 | static initcall_t __initcall_##fn \ |
228 | __used __section(.security_initcall.init) = fn | 216 | __used __section(.security_initcall.init) = fn |
229 | 217 | ||
230 | struct obs_kernel_param { | 218 | struct obs_kernel_param { |
diff --git a/init/Makefile b/init/Makefile index 7bc47ee31c36..c4fb45525d08 100644 --- a/init/Makefile +++ b/init/Makefile | |||
@@ -2,6 +2,8 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | ccflags-y := -fno-function-sections -fno-data-sections | ||
6 | |||
5 | obj-y := main.o version.o mounts.o | 7 | obj-y := main.o version.o mounts.o |
6 | ifneq ($(CONFIG_BLK_DEV_INITRD),y) | 8 | ifneq ($(CONFIG_BLK_DEV_INITRD),y) |
7 | obj-y += noinitramfs.o | 9 | obj-y += noinitramfs.o |