1001 lines · 28.0 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_SECTION(PAGE_SIZE) *	RW_DATA_SECTION(...) *	_edata = .; * *	EXCEPTION_TABLE(...) *	NOTES * *	BSS_SECTION(0, 0, 0) *	_end = .; * *	STABS_DEBUG *	DWARF_DEBUG * *	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 /* 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. * * RODATA_MAIN is not used because existing code already defines .rodata.x * sections to be brought in with rodata. */#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION#define TEXT_MAIN .text .text.[0-9a-zA-Z_]*#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..LPBX*#define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]*#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]*#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]*#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 /* * Align to a 32 byte boundary equal to the * alignment gcc 4.5 uses for a struct */#define STRUCT_ALIGNMENT 32#define STRUCT_ALIGN() . = ALIGN(STRUCT_ALIGNMENT) /* 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#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY#define MCOUNT_REC()	. = ALIGN(8);				\			__start_mcount_loc = .;			\			KEEP(*(__patchable_function_entries))	\			__stop_mcount_loc = .;#else#define MCOUNT_REC()	. = ALIGN(8);				\			__start_mcount_loc = .;			\			KEEP(*(__mcount_loc))			\			__stop_mcount_loc = .;#endif#else#define MCOUNT_REC()#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 #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___verbose = .;						\	KEEP(*(__verbose))                                              \	__stop___verbose = .;						\	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) #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 = .; /* * 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						\	__start_ro_after_init = .;					\	*(.data..ro_after_init)						\	JUMP_TABLE_DATA							\	__end_ro_after_init = .;#endif /* * Read only Data */#define RO_DATA_SECTION(align)						\	. = ALIGN((align));						\	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\		__start_rodata = .;					\		*(.rodata) *(.rodata.*)					\		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) {	\		__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 unused symbols */		\	__ksymtab_unused  : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) {	\		__start___ksymtab_unused = .;				\		KEEP(*(SORT(___ksymtab_unused+*)))			\		__stop___ksymtab_unused = .;				\	}								\									\	/* Kernel symbol table: GPL-only unused symbols */		\	__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \		__start___ksymtab_unused_gpl = .;			\		KEEP(*(SORT(___ksymtab_unused_gpl+*)))			\		__stop___ksymtab_unused_gpl = .;			\	}								\									\	/* Kernel symbol table: GPL-future-only symbols */		\	__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \		__start___ksymtab_gpl_future = .;			\		KEEP(*(SORT(___ksymtab_gpl_future+*)))			\		__stop___ksymtab_gpl_future = .;			\	}								\									\	/* Kernel symbol table: Normal symbols */			\	__kcrctab         : AT(ADDR(__kcrctab) - LOAD_OFFSET) {		\		__start___kcrctab = .;					\		KEEP(*(SORT(___kcrctab+*)))				\		__stop___kcrctab = .;					\	}								\									\	/* Kernel symbol table: GPL-only symbols */			\	__kcrctab_gpl     : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) {	\		__start___kcrctab_gpl = .;				\		KEEP(*(SORT(___kcrctab_gpl+*)))				\		__stop___kcrctab_gpl = .;				\	}								\									\	/* Kernel symbol table: Normal unused symbols */		\	__kcrctab_unused  : AT(ADDR(__kcrctab_unused) - LOAD_OFFSET) {	\		__start___kcrctab_unused = .;				\		KEEP(*(SORT(___kcrctab_unused+*)))			\		__stop___kcrctab_unused = .;				\	}								\									\	/* Kernel symbol table: GPL-only unused symbols */		\	__kcrctab_unused_gpl : AT(ADDR(__kcrctab_unused_gpl) - LOAD_OFFSET) { \		__start___kcrctab_unused_gpl = .;			\		KEEP(*(SORT(___kcrctab_unused_gpl+*)))			\		__stop___kcrctab_unused_gpl = .;			\	}								\									\	/* Kernel symbol table: GPL-future-only symbols */		\	__kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \		__start___kcrctab_gpl_future = .;			\		KEEP(*(SORT(___kcrctab_gpl_future+*)))			\		__stop___kcrctab_gpl_future = .;			\	}								\									\	/* Kernel symbol table: strings */				\        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\		*(__ksymtab_strings)					\	}								\									\	/* __*init sections */						\	__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {		\		*(.ref.rodata)						\		MEM_KEEP(init.rodata)					\		MEM_KEEP(exit.rodata)					\	}								\									\	/* Built-in module parameters. */				\	__param : AT(ADDR(__param) - LOAD_OFFSET) {			\		__start___param = .;					\		KEEP(*(__param))					\		__stop___param = .;					\	}								\									\	/* Built-in module versions. */					\	__modver : AT(ADDR(__modver) - LOAD_OFFSET) {			\		__start___modver = .;					\		KEEP(*(__modver))					\		__stop___modver = .;					\		. = ALIGN((align));					\		__end_rodata = .;					\

Lines 1–500 of 1001.