Use a single _payload_offset linker-defined variable to locate the
[people/adir/gpxe.git] / src / arch / i386 / scripts / i386.lds
1 /* -*- sh -*- */
2
3 /*
4  * Linker script for i386 images
5  *
6  */
7
8 OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
9 OUTPUT_ARCH ( i386 )
10 ENTRY ( _entry )
11
12 SECTIONS {
13
14     /* All sections in the resulting file have consecutive load
15      * addresses, but may have individual link addresses depending on
16      * the memory model being used.
17      *
18      * The linker symbols _{prefix,textdata}_link_addr, load_addr, and
19      * _max_align may be specified explicitly.  If not specified, they
20      * will default to:
21      *
22      *   _prefix_link_addr      = 0
23      *   _textdata_link_addr    = 0
24      *   _load_addr             = 0
25      *   _max_align             = 16
26      * 
27      * We guarantee alignment of virtual addresses to any alignment
28      * specified by the constituent object files (e.g. via
29      * __attribute__((aligned(x)))).  Load addresses are guaranteed
30      * only up to _max_align.  Provided that all loader and relocation
31      * code honours _max_align, this means that physical addresses are
32      * also guaranteed up to _max_align.
33      *
34      * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
35      * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
36      * alignment).  Using _max_align>16 will therefore not guarantee
37      * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
38      * used (though virtual addresses will still be fully aligned).
39      *
40      */
41
42     /*
43      * The prefix
44      */
45
46     _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
47     . = _prefix_link_addr;
48     _prefix = .;
49
50     .prefix : AT ( _prefix_load_offset + __prefix ) {
51         __prefix = .;
52         _entry = .;
53         *(.prefix)
54         *(.prefix.*)
55         _eprefix_progbits = .;
56     }
57     
58     _eprefix = .;
59
60     /*
61      * The 16-bit sections, if present
62      */
63
64     _text16_link_addr = 0;
65     . = _text16_link_addr;
66     _text16 = .;
67
68     . += 1;                     /* Prevent NULL being valid */
69
70     .text16 : AT ( _text16_load_offset + __text16 ) {
71         __text16 = .;
72         *(.text16)
73         *(.text16.*)
74         _etext16_progbits = .;
75     } = 0x9090
76
77     _etext16 = .;
78
79     _data16_link_addr = 0;
80     . = _data16_link_addr;
81     _data16 = .;
82
83     . += 1;                     /* Prevent NULL being valid */
84
85     .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
86         __rodata16 = .;
87         *(.rodata16)
88         *(.rodata16.*)
89     }
90     .data16 : AT ( _data16_load_offset + __data16 ) {
91         __data16 = .;
92         *(.data16)
93         *(.data16.*)
94         _edata16_progbits = .;
95     }
96     .bss16 : AT ( _data16_load_offset + __bss16 ) {
97         __bss16 = .;
98         _bss16 = .;
99         *(.bss16)
100         *(.bss16.*)
101         _ebss16 = .;
102     }
103     .stack16 : AT ( _data16_load_offset + __stack16 ) {
104         __stack16 = .;
105         *(.stack16)
106         *(.stack16.*)
107     }
108
109     _edata16 = .;
110
111     /*
112      * The 32-bit sections
113      */
114
115     _textdata_link_addr = ( DEFINED ( _textdata_link_addr ) ?
116                             _textdata_link_addr : 0 );
117     . = _textdata_link_addr;
118     _textdata = .;
119
120     _text = .;
121
122     . += 1;                     /* Prevent NULL being valid */
123
124     .text : AT ( _textdata_load_offset + __text ) {
125         __text = .;
126         *(.text.null_trap)
127         *(.text)
128         *(.text.*)
129     } = 0x9090
130
131     _etext = .;
132
133     _data = .;
134
135     .rodata : AT ( _textdata_load_offset + __rodata ) {
136         __rodata = .;
137         *(.rodata)
138         *(.rodata.*)
139     }
140     .data : AT ( _textdata_load_offset + __data ) {
141         __data = .;
142         *(.data)
143         *(.data.*)
144         *(SORT(.tbl.*))         /* Various tables.  See include/tables.h */
145         _etextdata_progbits = .;
146     }
147     .bss : AT ( _textdata_load_offset + __bss ) {
148         __bss = .;
149         _bss = .;
150         *(.bss)
151         *(.bss.*)
152         *(COMMON)
153         _ebss = .;
154     }
155     .stack : AT ( _textdata_load_offset + __stack ) {
156         __stack = .;
157         *(.stack)
158         *(.stack.*)
159     }
160
161     _edata = .;
162
163     _etextdata = .;
164
165     _end = .;
166
167     /*
168      * Dispose of the comment and note sections to make the link map
169      * easier to read
170      */
171
172     /DISCARD/ : {
173         *(.comment)
174         *(.note)
175     }
176
177     /*
178      * Load address calculations.  The slightly obscure nature of the
179      * calculations is because ALIGN(x) can only operate on the
180      * location counter.
181      */
182
183     _max_align              = DEFINED ( _max_align ) ? _max_align : 16;
184     _load_addr              = DEFINED ( _load_addr ) ? _load_addr : 0;
185
186     .                       = _load_addr;
187
188     .                      -= _prefix_link_addr;
189     _prefix_load_offset     = ALIGN ( _max_align );
190     _prefix_load_addr       = _prefix_link_addr + _prefix_load_offset;
191     _prefix_size            = _eprefix - _prefix;
192     _prefix_progbits_size   = _eprefix_progbits - _prefix;
193     .                       = _prefix_load_addr + _prefix_progbits_size;
194
195     .                      -= _text16_link_addr;
196     _text16_load_offset     = ALIGN ( _max_align );
197     _text16_load_addr       = _text16_link_addr + _text16_load_offset;
198     _text16_size            = _etext16 - _text16;
199     _text16_progbits_size   = _etext16_progbits - _text16;
200     .                       = _text16_load_addr + _text16_progbits_size;
201
202     .                      -= _data16_link_addr;
203     _data16_load_offset     = ALIGN ( _max_align );
204     _data16_load_addr       = _data16_link_addr + _data16_load_offset;
205     _data16_size            = _edata16 - _data16;
206     _data16_progbits_size   = _edata16_progbits - _data16;
207     .                       = _data16_load_addr + _data16_progbits_size;
208
209     .                      -= _textdata_link_addr;
210     _textdata_load_offset   = ALIGN ( _max_align );
211     _textdata_load_addr     = _textdata_link_addr + _textdata_load_offset;
212     _textdata_size          = _etextdata - _textdata;
213     _textdata_progbits_size = _etextdata_progbits - _textdata;
214     .                       = _textdata_load_addr + _textdata_progbits_size;
215
216     _load_size              = . - _load_addr;
217
218     _payload_offset         = _text16_load_offset;
219
220     /*
221      * Alignment checks.  ALIGN() can only operate on the location
222      * counter, so we set the location counter to each value we want
223      * to check.
224      */
225
226     . = _prefix_load_addr - _prefix_link_addr;
227     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
228                        "_prefix is badly aligned" );
229
230     . = _text16_load_addr - _text16_link_addr;
231     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
232                        "_text16 is badly aligned" );
233
234     . = _data16_load_addr - _data16_link_addr;
235     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
236                        "_data16 is badly aligned" );
237
238     . = _textdata_load_addr - _textdata_link_addr;
239     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
240                        "_text is badly aligned" );
241
242     /*
243      * Values calculated to save code from doing it
244      */
245     _text16_size_pgh    = ( ( _text16_size + 15 ) / 16 );
246     _data16_size_pgh    = ( ( _data16_size + 15 ) / 16 );
247     _load_size_pgh      = ( ( _load_size + 15 ) / 16 );
248     _rom_size           = ( ( _load_size + 511 ) / 512 );
249 }