• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <asm/vdso.h>
3
4#include <linux/page_size_compat.h>
5
6/*
7 * Linker script for vDSO.  This is an ELF shared object prelinked to
8 * its virtual address, and with only one read-only segment.
9 * This script controls its layout.
10 */
11
12SECTIONS
13{
14	/*
15	 * User/kernel shared data is before the vDSO.  This may be a little
16	 * uglier than putting it after the vDSO, but it avoids issues with
17	 * non-allocatable things that dangle past the end of the PT_LOAD
18	 * segment.
19	 */
20
21	vvar_start = . - 4 * __MAX_PAGE_SIZE;
22	vvar_page  = vvar_start;
23
24	/* Place all vvars at the offsets in asm/vvar.h. */
25#define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset;
26#include <asm/vvar.h>
27#undef EMIT_VVAR
28
29	pvclock_page = vvar_start + __MAX_PAGE_SIZE;
30	hvclock_page = vvar_start + 2 * __MAX_PAGE_SIZE;
31	timens_page  = vvar_start + 3 * __MAX_PAGE_SIZE;
32
33#undef _ASM_X86_VVAR_H
34	/* Place all vvars in timens too at the offsets in asm/vvar.h. */
35#define EMIT_VVAR(name, offset) timens_ ## name = timens_page + offset;
36#include <asm/vvar.h>
37#undef EMIT_VVAR
38
39	. = SIZEOF_HEADERS;
40
41	.hash		: { *(.hash) }			:text
42	.gnu.hash	: { *(.gnu.hash) }
43	.dynsym		: { *(.dynsym) }
44	.dynstr		: { *(.dynstr) }
45	.gnu.version	: { *(.gnu.version) }
46	.gnu.version_d	: { *(.gnu.version_d) }
47	.gnu.version_r	: { *(.gnu.version_r) }
48
49	.dynamic	: { *(.dynamic) }		:text	:dynamic
50
51	.rodata		: {
52		*(.rodata*)
53		*(.data*)
54		*(.sdata*)
55		*(.got.plt) *(.got)
56		*(.gnu.linkonce.d.*)
57		*(.bss*)
58		*(.dynbss*)
59		*(.gnu.linkonce.b.*)
60	}						:text
61
62	/*
63	 * Discard .note.gnu.property sections which are unused and have
64	 * different alignment requirement from vDSO note sections.
65	 */
66	/DISCARD/ : {
67		*(.note.gnu.property)
68	}
69	.note		: { *(.note.*) }		:text	:note
70
71	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
72	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
73
74
75	/*
76	 * Text is well-separated from actual data: there's plenty of
77	 * stuff that isn't used at runtime in between.
78	 */
79
80	.text		: {
81		*(.text*)
82	}						:text	=0x90909090,
83
84
85
86	.altinstructions	: { *(.altinstructions) }	:text
87	.altinstr_replacement	: { *(.altinstr_replacement) }	:text
88
89	__ex_table		: { *(__ex_table) }		:text
90
91	/DISCARD/ : {
92		*(.discard)
93		*(.discard.*)
94		*(__bug_table)
95	}
96}
97
98/*
99 * Very old versions of ld do not recognize this name token; use the constant.
100 */
101#define PT_GNU_EH_FRAME	0x6474e550
102
103/*
104 * We must supply the ELF program headers explicitly to get just one
105 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
106 */
107PHDRS
108{
109	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
110	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
111	note		PT_NOTE		FLAGS(4);		/* PF_R */
112	eh_frame_hdr	PT_GNU_EH_FRAME;
113}
114