1/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
2/* Modified for i386/x86-64 Xen by Keir Fraser */
3/* Modified for ARM Xen by Ian Campbell */
4
5#include <xen/cache.h>
6#include <asm/page.h>
7#include <asm/percpu.h>
8#undef ENTRY
9#undef ALIGN
10
11ENTRY(start)
12
13#if defined(__arm__)
14#define FORMAT arm
15#elif defined(__aarch64__)
16#define FORMAT aarch64
17#endif
18
19OUTPUT_ARCH(FORMAT)
20
21PHDRS
22{
23  text PT_LOAD ;
24#if defined(BUILD_ID)
25  note PT_NOTE ;
26#endif
27}
28SECTIONS
29{
30  . = XEN_VIRT_START;
31  _start = .;
32  .text : {
33        _stext = .;            /* Text section */
34       *(.text)
35       *(.text.cold)
36       *(.text.unlikely)
37       *(.fixup)
38       *(.gnu.warning)
39       _etext = .;             /* End of text section */
40  } :text = 0x9090
41
42  . = ALIGN(PAGE_SIZE);
43  .rodata : {
44        _srodata = .;          /* Read-only data */
45        /* Bug frames table */
46       __start_bug_frames = .;
47       *(.bug_frames.0)
48       __stop_bug_frames_0 = .;
49       *(.bug_frames.1)
50       __stop_bug_frames_1 = .;
51       *(.bug_frames.2)
52       __stop_bug_frames_2 = .;
53       *(.rodata)
54       *(.rodata.*)
55       *(.data.rel.ro)
56       *(.data.rel.ro.*)
57
58#ifdef CONFIG_LOCK_PROFILE
59       . = ALIGN(POINTER_ALIGN);
60       __lock_profile_start = .;
61       *(.lockprofile.data)
62       __lock_profile_end = .;
63#endif
64       . = ALIGN(POINTER_ALIGN);
65       __param_start = .;
66       *(.data.param)
67       __param_end = .;
68  } :text
69
70#if defined(BUILD_ID)
71  . = ALIGN(4);
72  .note.gnu.build-id : {
73       __note_gnu_build_id_start = .;
74       *(.note.gnu.build-id)
75       __note_gnu_build_id_end = .;
76  } :note :text
77#endif
78  _erodata = .;                /* End of read-only data */
79
80  .data : {                    /* Data */
81       . = ALIGN(PAGE_SIZE);
82       *(.data.page_aligned)
83       *(.data)
84       . = ALIGN(8);
85       __start_schedulers_array = .;
86       *(.data.schedulers)
87       __end_schedulers_array = .;
88       *(.data.rel)
89       *(.data.rel.*)
90       CONSTRUCTORS
91  } :text
92
93  . = ALIGN(SMP_CACHE_BYTES);
94  .data.read_mostly : {
95       /* Exception table */
96       __start___ex_table = .;
97       *(.ex_table)
98       __stop___ex_table = .;
99
100       /* Pre-exception table */
101       __start___pre_ex_table = .;
102       *(.ex_table.pre)
103       __stop___pre_ex_table = .;
104
105       *(.data.read_mostly)
106  } :text
107
108  . = ALIGN(8);
109  .arch.info : {
110      _splatform = .;
111      *(.arch.info)
112      _eplatform = .;
113  } :text
114
115  . = ALIGN(8);
116  .dev.info : {
117      _sdevice = .;
118      *(.dev.info)
119      _edevice = .;
120  } :text
121
122  . = ALIGN(8);
123  .adev.info : {
124      _asdevice = .;
125      *(.adev.info)
126      _aedevice = .;
127  } :text
128
129  . = ALIGN(PAGE_SIZE);             /* Init code and data */
130  __init_begin = .;
131  .init.text : {
132       _sinittext = .;
133       *(.init.text)
134       _einittext = .;
135  } :text
136  . = ALIGN(PAGE_SIZE);
137  .init.data : {
138       *(.init.rodata)
139       *(.init.rodata.rel)
140       *(.init.rodata.str*)
141
142       . = ALIGN(POINTER_ALIGN);
143       __setup_start = .;
144       *(.init.setup)
145       __setup_end = .;
146
147       __proc_info_start = .;
148       *(.init.proc.info)
149       __proc_info_end = .;
150
151       __initcall_start = .;
152       *(.initcallpresmp.init)
153       __presmp_initcall_end = .;
154       *(.initcall1.init)
155       __initcall_end = .;
156
157#ifdef CONFIG_HAS_ALTERNATIVE
158       . = ALIGN(4);
159       __alt_instructions = .;
160       *(.altinstructions)
161       __alt_instructions_end = .;
162       . = ALIGN(4);
163       *(.altinstr_replacement)
164#endif
165
166       *(.init.data)
167       *(.init.data.rel)
168       *(.init.data.rel.*)
169
170       . = ALIGN(8);
171       __ctors_start = .;
172       *(.ctors)
173       *(.init_array)
174       *(SORT(.init_array.*))
175       __ctors_end = .;
176  } :text
177  __init_end_efi = .;
178  . = ALIGN(STACK_SIZE);
179  __init_end = .;
180
181  .bss : {                     /* BSS */
182       __bss_start = .;
183       *(.bss.stack_aligned)
184       . = ALIGN(PAGE_SIZE);
185       *(.bss.page_aligned)
186       *(.bss)
187       . = ALIGN(SMP_CACHE_BYTES);
188       __per_cpu_start = .;
189       *(.bss.percpu)
190       . = ALIGN(SMP_CACHE_BYTES);
191       *(.bss.percpu.read_mostly)
192       . = ALIGN(SMP_CACHE_BYTES);
193       __per_cpu_data_end = .;
194       __bss_end = .;
195  } :text
196  _end = . ;
197
198#ifdef CONFIG_DTB_FILE
199  /* Section for the device tree blob (if any). */
200  _sdtb = .;
201  .dtb : { *(.dtb) } :text
202#endif
203
204  /* Sections to be discarded */
205  /DISCARD/ : {
206       *(.exit.text)
207       *(.exit.data)
208       *(.exitcall.exit)
209       *(.eh_frame)
210  }
211
212  /* Stabs debugging sections.  */
213  .stab 0 : { *(.stab) }
214  .stabstr 0 : { *(.stabstr) }
215  .stab.excl 0 : { *(.stab.excl) }
216  .stab.exclstr 0 : { *(.stab.exclstr) }
217  .stab.index 0 : { *(.stab.index) }
218  .stab.indexstr 0 : { *(.stab.indexstr) }
219  .comment 0 : { *(.comment) }
220}
221
222/*
223 * We require that Xen is loaded at a 4K boundary, so this ensures that any
224 * code running on the boot time identity map cannot cross a section boundary.
225 */
226ASSERT( _end_boot - start <= PAGE_SIZE, "Boot code is larger than 4K")
227/*
228 * __init_[begin|end] MUST be at word size boundary otherwise we cannot
229 * write fault instructions in the space properly.
230 */
231ASSERT(IS_ALIGNED(__init_begin,     4), "__init_begin is misaligned")
232ASSERT(IS_ALIGNED(__init_end,       4), "__init_end is misaligned")
233