1152 lines · 31.7 KB · C
RawDownload
/* * Helper macros to support writing architecture specific * linker scripts. * * A minimal linker scripts has following content: * [This is a sample, architectures may have special requiriements] * * OUTPUT_FORMAT(...) * OUTPUT_ARCH(...) * ENTRY(...) * SECTIONS * { *	. = START; *	__init_begin = .; *	HEAD_TEXT_SECTION *	INIT_TEXT_SECTION(PAGE_SIZE) *	INIT_DATA_SECTION(...) *	PERCPU_SECTION(CACHELINE_SIZE) *	__init_end = .; * *	_stext = .; *	TEXT_SECTION = 0 *	_etext = .; * *      _sdata = .; *	RO_DATA(PAGE_SIZE) *	RW_DATA(...) *	_edata = .; * *	EXCEPTION_TABLE(...) * *	BSS_SECTION(0, 0, 0) *	_end = .; * *	STABS_DEBUG *	DWARF_DEBUG *	ELF_DETAILS * *	DISCARDS		// must be the last * } * * [__init_begin, __init_end] is the init section that may be freed after init * 	// __init_begin and __init_end should be page aligned, so that we can *	// free the whole .init memory * [_stext, _etext] is the text section * [_sdata, _edata] is the data section * * Some of the included output section have their own set of constants. * Examples are: [__initramfs_start, __initramfs_end] for initramfs and *               [__nosave_begin, __nosave_end] for the nosave data */ #ifndef LOAD_OFFSET#define LOAD_OFFSET 0#endif /* * Only some architectures want to have the .notes segment visible in * a separate PT_NOTE ELF Program Header. When this happens, it needs * to be visible in both the kernel text's PT_LOAD and the PT_NOTE * Program Headers. In this case, though, the PT_LOAD needs to be made * the default again so that all the following sections don't also end * up in the PT_NOTE Program Header. */#ifdef EMITS_PT_NOTE#define NOTES_HEADERS		:text :note#define NOTES_HEADERS_RESTORE	__restore_ph : { *(.__restore_ph) } :text#else#define NOTES_HEADERS#define NOTES_HEADERS_RESTORE#endif /* * Some architectures have non-executable read-only exception tables. * They can be added to the RO_DATA segment by specifying their desired * alignment. */#ifdef RO_EXCEPTION_TABLE_ALIGN#define RO_EXCEPTION_TABLE	EXCEPTION_TABLE(RO_EXCEPTION_TABLE_ALIGN)#else#define RO_EXCEPTION_TABLE#endif /* Align . to a 8 byte boundary equals to maximum function alignment. */#define ALIGN_FUNCTION()  . = ALIGN(8) /* * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections, which * generates .data.identifier sections, which need to be pulled in with * .data. We don't want to pull in .data..other sections, which Linux * has defined. Same for text and bss. * * With LTO_CLANG, the linker also splits sections by default, so we need * these macros to combine the sections during the final link. * * RODATA_MAIN is not used because existing code already defines .rodata.x * sections to be brought in with rodata. */#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG)#define TEXT_MAIN .text .text.[0-9a-zA-Z_]*#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L*#define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]*#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L*#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..compoundliteral*#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*#else#define TEXT_MAIN .text#define DATA_MAIN .data#define SDATA_MAIN .sdata#define RODATA_MAIN .rodata#define BSS_MAIN .bss#define SBSS_MAIN .sbss#endif /* * GCC 4.5 and later have a 32 bytes section alignment for structures. * Except GCC 4.9, that feels the need to align on 64 bytes. */#if __GNUC__ == 4 && __GNUC_MINOR__ == 9#define STRUCT_ALIGNMENT 64#else#define STRUCT_ALIGNMENT 32#endif#define STRUCT_ALIGN() . = ALIGN(STRUCT_ALIGNMENT) /* * The order of the sched class addresses are important, as they are * used to determine the order of the priority of each sched class in * relation to each other. */#define SCHED_DATA				\	STRUCT_ALIGN();				\	__begin_sched_classes = .;		\	*(__idle_sched_class)			\	*(__fair_sched_class)			\	*(__rt_sched_class)			\	*(__dl_sched_class)			\	*(__stop_sched_class)			\	__end_sched_classes = .; /* The actual configuration determine if the init/exit sections * are handled as text/data or they can be discarded (which * often happens at runtime) */#ifdef CONFIG_HOTPLUG_CPU#define CPU_KEEP(sec)    *(.cpu##sec)#define CPU_DISCARD(sec)#else#define CPU_KEEP(sec)#define CPU_DISCARD(sec) *(.cpu##sec)#endif #if defined(CONFIG_MEMORY_HOTPLUG)#define MEM_KEEP(sec)    *(.mem##sec)#define MEM_DISCARD(sec)#else#define MEM_KEEP(sec)#define MEM_DISCARD(sec) *(.mem##sec)#endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD/* * The ftrace call sites are logged to a section whose name depends on the * compiler option used. A given kernel image will only use one, AKA * FTRACE_CALLSITE_SECTION. We capture all of them here to avoid header * dependencies for FTRACE_CALLSITE_SECTION's definition. * * Need to also make ftrace_stub_graph point to ftrace_stub * so that the same stub location may have different protocols * and not mess up with C verifiers. */#define MCOUNT_REC()	. = ALIGN(8);				\			__start_mcount_loc = .;			\			KEEP(*(__mcount_loc))			\			KEEP(*(__patchable_function_entries))	\			__stop_mcount_loc = .;			\			ftrace_stub_graph = ftrace_stub;#else# ifdef CONFIG_FUNCTION_TRACER#  define MCOUNT_REC()	ftrace_stub_graph = ftrace_stub;# else#  define MCOUNT_REC()# endif#endif #ifdef CONFIG_TRACE_BRANCH_PROFILING#define LIKELY_PROFILE()	__start_annotated_branch_profile = .;	\				KEEP(*(_ftrace_annotated_branch))	\				__stop_annotated_branch_profile = .;#else#define LIKELY_PROFILE()#endif #ifdef CONFIG_PROFILE_ALL_BRANCHES#define BRANCH_PROFILE()	__start_branch_profile = .;		\				KEEP(*(_ftrace_branch))			\				__stop_branch_profile = .;#else#define BRANCH_PROFILE()#endif #ifdef CONFIG_KPROBES#define KPROBE_BLACKLIST()	. = ALIGN(8);				      \				__start_kprobe_blacklist = .;		      \				KEEP(*(_kprobe_blacklist))		      \				__stop_kprobe_blacklist = .;#else#define KPROBE_BLACKLIST()#endif #ifdef CONFIG_FUNCTION_ERROR_INJECTION#define ERROR_INJECT_WHITELIST()	STRUCT_ALIGN();			      \			__start_error_injection_whitelist = .;		      \			KEEP(*(_error_injection_whitelist))		      \			__stop_error_injection_whitelist = .;#else#define ERROR_INJECT_WHITELIST()#endif #ifdef CONFIG_EVENT_TRACING#define FTRACE_EVENTS()	. = ALIGN(8);					\			__start_ftrace_events = .;			\			KEEP(*(_ftrace_events))				\			__stop_ftrace_events = .;			\			__start_ftrace_eval_maps = .;			\			KEEP(*(_ftrace_eval_map))			\			__stop_ftrace_eval_maps = .;#else#define FTRACE_EVENTS()#endif #ifdef CONFIG_TRACING#define TRACE_PRINTKS()	 __start___trace_bprintk_fmt = .;      \			 KEEP(*(__trace_printk_fmt)) /* Trace_printk fmt' pointer */ \			 __stop___trace_bprintk_fmt = .;#define TRACEPOINT_STR() __start___tracepoint_str = .;	\			 KEEP(*(__tracepoint_str)) /* Trace_printk fmt' pointer */ \			 __stop___tracepoint_str = .;#else#define TRACE_PRINTKS()#define TRACEPOINT_STR()#endif #ifdef CONFIG_FTRACE_SYSCALLS#define TRACE_SYSCALLS() . = ALIGN(8);					\			 __start_syscalls_metadata = .;			\			 KEEP(*(__syscalls_metadata))			\			 __stop_syscalls_metadata = .;#else#define TRACE_SYSCALLS()#endif #ifdef CONFIG_BPF_EVENTS#define BPF_RAW_TP() STRUCT_ALIGN();					\			 __start__bpf_raw_tp = .;			\			 KEEP(*(__bpf_raw_tp_map))			\			 __stop__bpf_raw_tp = .;#else#define BPF_RAW_TP()#endif #ifdef CONFIG_SERIAL_EARLYCON#define EARLYCON_TABLE() . = ALIGN(8);				\			 __earlycon_table = .;			\			 KEEP(*(__earlycon_table))		\			 __earlycon_table_end = .;#else#define EARLYCON_TABLE()#endif #ifdef CONFIG_SECURITY#define LSM_TABLE()	. = ALIGN(8);					\			__start_lsm_info = .;				\			KEEP(*(.lsm_info.init))				\			__end_lsm_info = .;#define EARLY_LSM_TABLE()	. = ALIGN(8);				\			__start_early_lsm_info = .;			\			KEEP(*(.early_lsm_info.init))			\			__end_early_lsm_info = .;#else#define LSM_TABLE()#define EARLY_LSM_TABLE()#endif #define ___OF_TABLE(cfg, name)	_OF_TABLE_##cfg(name)#define __OF_TABLE(cfg, name)	___OF_TABLE(cfg, name)#define OF_TABLE(cfg, name)	__OF_TABLE(IS_ENABLED(cfg), name)#define _OF_TABLE_0(name)#define _OF_TABLE_1(name)						\	. = ALIGN(8);							\	__##name##_of_table = .;					\	KEEP(*(__##name##_of_table))					\	KEEP(*(__##name##_of_table_end)) #define TIMER_OF_TABLES()	OF_TABLE(CONFIG_TIMER_OF, timer)#define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)#define CLK_OF_TABLES()		OF_TABLE(CONFIG_COMMON_CLK, clk)#define RESERVEDMEM_OF_TABLES()	OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)#define CPU_METHOD_OF_TABLES()	OF_TABLE(CONFIG_SMP, cpu_method)#define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) #ifdef CONFIG_ACPI#define ACPI_PROBE_TABLE(name)						\	. = ALIGN(8);							\	__##name##_acpi_probe_table = .;				\	KEEP(*(__##name##_acpi_probe_table))				\	__##name##_acpi_probe_table_end = .;#else#define ACPI_PROBE_TABLE(name)#endif #ifdef CONFIG_THERMAL#define THERMAL_TABLE(name)						\	. = ALIGN(8);							\	__##name##_thermal_table = .;					\	KEEP(*(__##name##_thermal_table))				\	__##name##_thermal_table_end = .;#else#define THERMAL_TABLE(name)#endif #ifdef CONFIG_DTPM#define DTPM_TABLE()							\	. = ALIGN(8);							\	__dtpm_table = .;						\	KEEP(*(__dtpm_table))						\	__dtpm_table_end = .;#else#define DTPM_TABLE()#endif #define KERNEL_DTB()							\	STRUCT_ALIGN();							\	__dtb_start = .;						\	KEEP(*(.dtb.init.rodata))					\	__dtb_end = .; /* * .data section */#define DATA_DATA							\	*(.xiptext)							\	*(DATA_MAIN)							\	*(.ref.data)							\	*(.data..shared_aligned) /* percpu related */			\	MEM_KEEP(init.data*)						\	MEM_KEEP(exit.data*)						\	*(.data.unlikely)						\	__start_once = .;						\	*(.data.once)							\	__end_once = .;							\	STRUCT_ALIGN();							\	*(__tracepoints)						\	/* implement dynamic printk debug */				\	. = ALIGN(8);							\	__start___dyndbg = .;						\	KEEP(*(__dyndbg))						\	__stop___dyndbg = .;						\	LIKELY_PROFILE()		       				\	BRANCH_PROFILE()						\	TRACE_PRINTKS()							\	BPF_RAW_TP()							\	TRACEPOINT_STR() /* * Data section helpers */#define NOSAVE_DATA							\	. = ALIGN(PAGE_SIZE);						\	__nosave_begin = .;						\	*(.data..nosave)						\	. = ALIGN(PAGE_SIZE);						\	__nosave_end = .; #define PAGE_ALIGNED_DATA(page_align)					\	. = ALIGN(page_align);						\	*(.data..page_aligned)						\	. = ALIGN(page_align); #define READ_MOSTLY_DATA(align)						\	. = ALIGN(align);						\	*(.data..read_mostly)						\	. = ALIGN(align); #define CACHELINE_ALIGNED_DATA(align)					\	. = ALIGN(align);						\	*(.data..cacheline_aligned) #define INIT_TASK_DATA(align)						\	. = ALIGN(align);						\	__start_init_task = .;						\	init_thread_union = .;						\	init_stack = .;							\	KEEP(*(.data..init_task))					\	KEEP(*(.data..init_thread_info))				\	. = __start_init_task + THREAD_SIZE;				\	__end_init_task = .; #define JUMP_TABLE_DATA							\	. = ALIGN(8);							\	__start___jump_table = .;					\	KEEP(*(__jump_table))						\	__stop___jump_table = .; #define STATIC_CALL_DATA						\	. = ALIGN(8);							\	__start_static_call_sites = .;					\	KEEP(*(.static_call_sites))					\	__stop_static_call_sites = .;					\	__start_static_call_tramp_key = .;				\	KEEP(*(.static_call_tramp_key))					\	__stop_static_call_tramp_key = .; /* * Allow architectures to handle ro_after_init data on their * own by defining an empty RO_AFTER_INIT_DATA. */#ifndef RO_AFTER_INIT_DATA#define RO_AFTER_INIT_DATA						\	. = ALIGN(8);							\	__start_ro_after_init = .;					\	*(.data..ro_after_init)						\	JUMP_TABLE_DATA							\	STATIC_CALL_DATA						\	__end_ro_after_init = .;#endif /* * Read only Data */#define RO_DATA(align)							\	. = ALIGN((align));						\	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\		__start_rodata = .;					\		*(.rodata) *(.rodata.*)					\		SCHED_DATA						\		RO_AFTER_INIT_DATA	/* Read only after init */	\		. = ALIGN(8);						\		__start___tracepoints_ptrs = .;				\		KEEP(*(__tracepoints_ptrs)) /* Tracepoints: pointer array */ \		__stop___tracepoints_ptrs = .;				\		*(__tracepoints_strings)/* Tracepoints: strings */	\	}								\									\	.rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {		\		*(.rodata1)						\	}								\									\	/* PCI quirks */						\	.pci_fixup        : AT(ADDR(.pci_fixup) - LOAD_OFFSET) {	\		__start_pci_fixups_early = .;				\		KEEP(*(.pci_fixup_early))				\		__end_pci_fixups_early = .;				\		__start_pci_fixups_header = .;				\		KEEP(*(.pci_fixup_header))				\		__end_pci_fixups_header = .;				\		__start_pci_fixups_final = .;				\		KEEP(*(.pci_fixup_final))				\		__end_pci_fixups_final = .;				\		__start_pci_fixups_enable = .;				\		KEEP(*(.pci_fixup_enable))				\		__end_pci_fixups_enable = .;				\		__start_pci_fixups_resume = .;				\		KEEP(*(.pci_fixup_resume))				\		__end_pci_fixups_resume = .;				\		__start_pci_fixups_resume_early = .;			\		KEEP(*(.pci_fixup_resume_early))			\		__end_pci_fixups_resume_early = .;			\		__start_pci_fixups_suspend = .;				\		KEEP(*(.pci_fixup_suspend))				\		__end_pci_fixups_suspend = .;				\		__start_pci_fixups_suspend_late = .;			\		KEEP(*(.pci_fixup_suspend_late))			\		__end_pci_fixups_suspend_late = .;			\	}								\									\	/* Built-in firmware blobs */					\	.builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) {	\		__start_builtin_fw = .;					\		KEEP(*(.builtin_fw))					\		__end_builtin_fw = .;					\	}								\									\	TRACEDATA							\									\	/* Kernel symbol table: Normal symbols */			\	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\		__start___ksymtab = .;					\		KEEP(*(SORT(___ksymtab+*)))				\		__stop___ksymtab = .;					\	}								\									\	/* Kernel symbol table: GPL-only symbols */			\	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\		__start___ksymtab_gpl = .;				\		KEEP(*(SORT(___ksymtab_gpl+*)))				\		__stop___ksymtab_gpl = .;				\	}								\									\	/* Kernel symbol table: Normal symbols */			\

Lines 1–500 of 1152.