forked from google/snappy-start
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathelf_loader_linker_script.x
143 lines (128 loc) · 4.35 KB
/
elf_loader_linker_script.x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright (c) 2011 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
* This file is based on nacl_bootstrap.x from Native Client:
* https://chromium.googlesource.com/native_client/src/native_client/+/287c0fffd7d3b7f38b887324f261ddb724d38f26/src/trusted/service_runtime/linux/nacl_bootstrap.x
*/
/*
* This is a custom linker script used to build nacl_helper_bootstrap.
* It has a very special layout. This script will only work with input
* that is kept extremely minimal. If there are unexpected input sections
* not named here, the result will not be correct.
*
* We need to use a standalone loader program rather than just using a
* dynamically-linked program here because its entire address space will be
* taken over for the NaCl untrusted address space. A normal program would
* cause dynamic linker data structures to point to its .dynamic section,
* which is no longer available after startup.
*
* We need this special layout (and the nacl_helper_bootstrap_munge_phdr
* step) because simply having bss space large enough to reserve the
* address space would cause the kernel loader to think we're using that
* much anonymous memory and refuse to execute the program on a machine
* with not much memory available.
*/
/*
* Set the entry point to the symbol called _start, which we define in assembly.
*/
ENTRY(_start)
/*
* This is the address where the program text starts.
* We set this as low as we think we can get away with.
* The common settings for sysctl vm.mmap_min_addr range from 4k to 64k.
*/
TEXT_START = 0x10000;
/*
* The symbol RESERVE_TOP is the top of the range we are trying to reserve.
* This is set via --defsym on the linker command line, because the correct
* value differs for each machine. It is defined to be 0x0 if we do not
* actually need any space reserved for this configuration.
*/
/*
* We specify the program headers we want explicitly, to get the layout
* exactly right and to give the "reserve" segment p_flags of zero, so
* that it gets mapped as PROT_NONE.
*/
PHDRS {
text PT_LOAD FILEHDR PHDRS;
data PT_LOAD;
reserve PT_LOAD FLAGS(0);
r_debug PT_LOAD;
note PT_NOTE;
stack PT_GNU_STACK FLAGS(6); /* RW, no E */
}
/*
* Now we lay out the sections across those segments.
*/
SECTIONS {
. = TEXT_START + SIZEOF_HEADERS;
/*
* The build ID note usually comes first.
* It's both part of the text PT_LOAD segment (like other rodata) and
* it's what the PT_NOTE header points to.
*/
.note.gnu.build-id : {
*(.note.gnu.build-id)
} :text :note
/*
* Here is the program itself.
*/
.text : {
*(.text*)
} :text
.rodata : {
*(.rodata*)
*(.eh_frame*)
}
etext = .;
/*
* Adjust the address for the data segment. We want to adjust up to
* the same address within the page on the next page up.
*/
. = (ALIGN(CONSTANT(MAXPAGESIZE)) -
((CONSTANT(MAXPAGESIZE) - .) & (CONSTANT(MAXPAGESIZE) - 1)));
. = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE));
.data : {
*(.data*)
} :data
.bss : {
*(.bss*)
}
/*
* Now we move up to the next p_align increment, and place the dummy
* segment there. The linker emits this segment with the p_vaddr and
* p_memsz we want, which reserves the address space. But the linker
* gives it a p_filesz of zero. We have to edit the phdr after link
* time to give it a p_filesz matching its p_memsz. That way, the
* kernel doesn't think we are preallocating a huge amount of memory.
* It just maps it from the file, i.e. way off the end of the file,
* which is perfect for reserving the address space.
*/
. = ALIGN(CONSTANT(COMMONPAGESIZE));
RESERVE_START = .;
.reserve : {
. += (RESERVE_TOP > RESERVE_START) ? (RESERVE_TOP - RESERVE_START) : 0;
} :reserve
/*
* This must be placed above the reserved address space, so it won't
* be clobbered by NaCl. We want this to be visible at its fixed address
* in the memory image so the debugger can make sense of things.
*/
.r_debug : {
*(.r_debug)
} :r_debug
/*
* These are empty input sections the linker generates.
* If we don't discard them, they pollute the flags in the output segment.
*/
/DISCARD/ : {
*(.iplt)
*(.reginfo)
*(.rel*)
*(.igot.plt)
*(.ARM.exidx)
}
}