1/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */
2/* Modified for i386/x86-64 Xen by Keir Fraser */
3
4#include <xen/cache.h>
5#include <asm/page.h>
6#include <asm/percpu.h>
7#undef ENTRY
8#undef ALIGN
9
10#ifdef EFI
11
12#define FORMAT "pei-x86-64"
13#undef __XEN_VIRT_START
14#define __XEN_VIRT_START __image_base__
15#define SECTION_ALIGN MB(2)
16#define DECL_SECTION(x) x :
17
18ENTRY(efi_start)
19
20#else /* !EFI */
21
22#define FORMAT "elf64-x86-64"
23#define SECTION_ALIGN PAGE_SIZE
24#define DECL_SECTION(x) x : AT(ADDR(x) - __XEN_VIRT_START)
25
26ENTRY(start_pa)
27
28#endif /* EFI */
29
30OUTPUT_FORMAT(FORMAT, FORMAT, FORMAT)
31
32OUTPUT_ARCH(i386:x86-64)
33
34PHDRS
35{
36  text PT_LOAD ;
37#if (defined(BUILD_ID) || defined (CONFIG_PVH_GUEST)) && !defined(EFI)
38  note PT_NOTE ;
39#endif
40}
41SECTIONS
42{
43#if !defined(EFI)
44  . = __XEN_VIRT_START;
45  __image_base__ = .;
46#else
47  . = __image_base__;
48#endif
49
50#if 0
51/*
52 * We don't really use this symbol anywhere, and the way it would get defined
53 * here would result in it having a negative (wrapped to huge positive)
54 * offset relative to the .text section. That, in turn, causes an assembler
55 * truncation warning when including all symbols in the symbol table for Live
56 * Patching code.
57 */
58  __2M_text_start = .;         /* Start of 2M superpages, mapped RX. */
59#endif
60
61  start_pa = ABSOLUTE(start - __XEN_VIRT_START);
62
63  . = __XEN_VIRT_START + XEN_IMG_OFFSET;
64  _start = .;
65  DECL_SECTION(.text) {
66        _stext = .;            /* Text and read-only data */
67       *(.text)
68       *(.text.page_aligned)
69       *(.text.cold)
70       *(.text.unlikely)
71       *(.fixup)
72       *(.text.kexec)
73       *(.gnu.warning)
74       _etext = .;             /* End of text section */
75  } :text = 0x9090
76
77  . = ALIGN(SECTION_ALIGN);
78  __2M_text_end = .;
79
80  __2M_rodata_start = .;       /* Start of 2M superpages, mapped RO. */
81  DECL_SECTION(.rodata) {
82       _srodata = .;
83       /* Bug frames table */
84       __start_bug_frames = .;
85       *(.bug_frames.0)
86       __stop_bug_frames_0 = .;
87       *(.bug_frames.1)
88       __stop_bug_frames_1 = .;
89       *(.bug_frames.2)
90       __stop_bug_frames_2 = .;
91       *(.bug_frames.3)
92       __stop_bug_frames_3 = .;
93
94       *(.rodata)
95       *(.rodata.*)
96       *(.data.rel.ro)
97       *(.data.rel.ro.*)
98
99#if defined(BUILD_ID) && defined(EFI) && !defined(BUILD_ID_EFI)
100/*
101 * No mechanism to put an PT_NOTE in the EFI file - so put
102 * it in .rodata section. (notes.o supplies us with .note.gnu.build-id).
103 */
104       . = ALIGN(4);
105       __note_gnu_build_id_start = .;
106       *(.note.gnu.build-id)
107       __note_gnu_build_id_end = .;
108#endif
109       . = ALIGN(8);
110       /* Exception table */
111       __start___ex_table = .;
112       *(.ex_table)
113       __stop___ex_table = .;
114
115       /* Pre-exception table */
116       __start___pre_ex_table = .;
117       *(.ex_table.pre)
118       __stop___pre_ex_table = .;
119
120#ifdef CONFIG_LOCK_PROFILE
121       . = ALIGN(POINTER_ALIGN);
122       __lock_profile_start = .;
123       *(.lockprofile.data)
124       __lock_profile_end = .;
125#endif
126       . = ALIGN(POINTER_ALIGN);
127       __param_start = .;
128       *(.data.param)
129       __param_end = .;
130  } :text
131
132#if defined(CONFIG_PVH_GUEST) && !defined(EFI)
133  DECL_SECTION(.note.Xen) {
134      *(.note.Xen)
135  } :note :text
136#endif
137
138#if defined(BUILD_ID)
139#if !defined(EFI)
140/*
141 * What a strange section name. The reason is that on ELF builds this section
142 * is extracted to notes.o (which then is ingested in the EFI file). But the
143 * compiler may want to inject other things in the .note which we don't care
144 * about - hence this unique name.
145 */
146  DECL_SECTION(.note.gnu.build-id) {
147       __note_gnu_build_id_start = .;
148       *(.note.gnu.build-id)
149       __note_gnu_build_id_end = .;
150  } :note :text
151#elif defined(BUILD_ID_EFI)
152  DECL_SECTION(.buildid) {
153       __note_gnu_build_id_start = .;
154       *(.buildid)
155       __note_gnu_build_id_end = .;
156  } :text
157#endif
158#endif
159  _erodata = .;
160
161  . = ALIGN(SECTION_ALIGN);
162  __2M_rodata_end = .;
163
164  __2M_init_start = .;         /* Start of 2M superpages, mapped RWX (boot only). */
165  . = ALIGN(PAGE_SIZE);             /* Init code and data */
166  __init_begin = .;
167  DECL_SECTION(.init) {
168       _sinittext = .;
169       *(.init.text)
170       /*
171        * Here are the replacement instructions. The linker sticks them
172        * as binary blobs. The .altinstructions has enough data to get
173        * the address and the length of them to patch the kernel safely.
174        */
175       *(.altinstr_replacement)
176       _einittext = .;
177
178       . = ALIGN(SMP_CACHE_BYTES);
179
180       *(.init.rodata)
181       *(.init.rodata.rel)
182       *(.init.rodata.str*)
183
184       . = ALIGN(POINTER_ALIGN);
185       __setup_start = .;
186       *(.init.setup)
187       __setup_end = .;
188
189       __initcall_start = .;
190       *(.initcallpresmp.init)
191       __presmp_initcall_end = .;
192       *(.initcall1.init)
193       __initcall_end = .;
194
195       *(.init.data)
196       *(.init.data.rel)
197       *(.init.data.rel.*)
198       . = ALIGN(4);
199       __trampoline_rel_start = .;
200       *(.trampoline_rel)
201       __trampoline_rel_stop = .;
202       __trampoline_seg_start = .;
203       *(.trampoline_seg)
204       __trampoline_seg_stop = .;
205       /*
206        * struct alt_inst entries. From the header (alternative.h):
207        * "Alternative instructions for different CPU types or capabilities"
208        * Think locking instructions on spinlocks.
209        */
210       . = ALIGN(8);
211        __alt_instructions = .;
212        *(.altinstructions)
213        __alt_instructions_end = .;
214
215       . = ALIGN(8);
216       __ctors_start = .;
217       *(.ctors)
218       *(.init_array)
219       *(SORT(.init_array.*))
220       __ctors_end = .;
221  } :text
222
223  . = ALIGN(SECTION_ALIGN);
224  __init_end = .;
225  __2M_init_end = .;
226
227  __2M_rwdata_start = .;       /* Start of 2M superpages, mapped RW. */
228  . = ALIGN(SMP_CACHE_BYTES);
229  DECL_SECTION(.data.read_mostly) {
230       *(.data.read_mostly)
231       . = ALIGN(8);
232       __start_schedulers_array = .;
233       *(.data.schedulers)
234       __end_schedulers_array = .;
235  } :text
236
237  DECL_SECTION(.data) {
238       *(.data.page_aligned)
239       *(.data)
240       *(.data.rel)
241       *(.data.rel.*)
242       CONSTRUCTORS
243  } :text
244
245  DECL_SECTION(.bss) {
246       __bss_start = .;
247       *(.bss.stack_aligned)
248       *(.bss.page_aligned*)
249       *(.bss)
250       . = ALIGN(SMP_CACHE_BYTES);
251       __per_cpu_start = .;
252       *(.bss.percpu)
253       . = ALIGN(SMP_CACHE_BYTES);
254       *(.bss.percpu.read_mostly)
255       . = ALIGN(SMP_CACHE_BYTES);
256       __per_cpu_data_end = .;
257       __bss_end = .;
258  } :text
259  _end = . ;
260
261  . = ALIGN(SECTION_ALIGN);
262  __2M_rwdata_end = .;
263
264#ifdef EFI
265  . = ALIGN(4);
266  .reloc : {
267    *(.reloc)
268  } :text
269  /* Trick the linker into setting the image size to exactly 16Mb. */
270  . = ALIGN(__section_alignment__);
271  .pad : {
272    . = ALIGN(MB(16));
273  } :text
274#endif
275
276  efi = DEFINED(efi) ? efi : .;
277
278  /* Sections to be discarded */
279  /DISCARD/ : {
280       *(.exit.text)
281       *(.exit.data)
282       *(.exitcall.exit)
283       *(.discard)
284       *(.discard.*)
285       *(.eh_frame)
286#ifdef EFI
287       *(.comment)
288       *(.comment.*)
289       *(.note.Xen)
290#endif
291  }
292
293  /* Stabs debugging sections.  */
294  .stab 0 : { *(.stab) }
295  .stabstr 0 : { *(.stabstr) }
296  .stab.excl 0 : { *(.stab.excl) }
297  .stab.exclstr 0 : { *(.stab.exclstr) }
298  .stab.index 0 : { *(.stab.index) }
299  .stab.indexstr 0 : { *(.stab.indexstr) }
300  .comment 0 : { *(.comment) }
301}
302
303ASSERT(__image_base__ > XEN_VIRT_START ||
304       __2M_rwdata_end <= XEN_VIRT_END - NR_CPUS * PAGE_SIZE,
305       "Xen image overlaps stubs area")
306
307#ifdef CONFIG_KEXEC
308ASSERT(kexec_reloc_size - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large")
309#endif
310
311ASSERT(IS_ALIGNED(__2M_text_end,     SECTION_ALIGN), "__2M_text_end misaligned")
312ASSERT(IS_ALIGNED(__2M_rodata_start, SECTION_ALIGN), "__2M_rodata_start misaligned")
313ASSERT(IS_ALIGNED(__2M_rodata_end,   SECTION_ALIGN), "__2M_rodata_end misaligned")
314ASSERT(IS_ALIGNED(__2M_init_start,   SECTION_ALIGN), "__2M_init_start misaligned")
315ASSERT(IS_ALIGNED(__2M_init_end,     SECTION_ALIGN), "__2M_init_end misaligned")
316ASSERT(IS_ALIGNED(__2M_rwdata_start, SECTION_ALIGN), "__2M_rwdata_start misaligned")
317ASSERT(IS_ALIGNED(__2M_rwdata_end,   SECTION_ALIGN), "__2M_rwdata_end misaligned")
318
319ASSERT(IS_ALIGNED(cpu0_stack, STACK_SIZE), "cpu0_stack misaligned")
320
321ASSERT(IS_ALIGNED(__init_begin, PAGE_SIZE), "__init_begin misaligned")
322ASSERT(IS_ALIGNED(__init_end,   PAGE_SIZE), "__init_end misaligned")
323
324ASSERT(IS_ALIGNED(trampoline_start, 4), "trampoline_start misaligned")
325ASSERT(IS_ALIGNED(trampoline_end,   4), "trampoline_end misaligned")
326ASSERT(IS_ALIGNED(__bss_start,      8), "__bss_start misaligned")
327ASSERT(IS_ALIGNED(__bss_end,        8), "__bss_end misaligned")
328
329ASSERT((trampoline_end - trampoline_start) < TRAMPOLINE_SPACE - MBI_SPACE_MIN,
330    "not enough room for trampoline and mbi data")
331ASSERT((wakeup_stack - wakeup_stack_start) >= WAKEUP_STACK_MIN,
332    "wakeup stack too small")
333