Post-relocation functions use the generic table mechanism.
[people/lynusvaz/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,decompress,text,data}_link_addr,
19      * load_addr, and _max_align may be specified explicitly.  If not
20      * specified, they will default to:
21      *
22      *   _prefix_link_addr      = 0
23      *   _decompress_link_addr  = 0
24      *   _text_link_addr        = 0
25      *   _data_link_addr        = _text_link_addr + sizeof ( text sections )
26      *   _load_addr             = 0
27      *   _max_align             = 16
28      * 
29      * We guarantee alignment of virtual addresses to any alignment
30      * specified by the constituent object files (e.g. via
31      * __attribute__((aligned(x)))).  Load addresses are guaranteed
32      * only up to _max_align.  Provided that all loader and relocation
33      * code honours _max_align, this means that physical addresses are
34      * also guaranteed up to _max_align.
35      *
36      * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
37      * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
38      * alignment).  Using _max_align>16 will therefore not guarantee
39      * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
40      * used (though virtual addresses will still be fully aligned).
41      *
42      * The real-mode prefixes rely on _text_link_addr and
43      * _decompress_link_addr being 0, since they issue far calls into
44      * those sections, thus requiring that symbol_value ==
45      * symbol_offset therein.  Using the linker to calculate
46      * e.g. offset_setup16=setup16-_text will not work, since you then
47      * cannot use the reference from the prefix to setup16 to drag in
48      * setup16.o.  Life is hard.
49      *
50      * If librm is included, then it must go at offset 0 within the
51      * text section.  This is because librm is dual-usage: it is
52      * called from setup16 with %cs:0000 pointing to the start of the
53      * text section, and later it will be copied to base memory and
54      * called with %cs:0000 pointing to the start of librm.
55      *
56      * The decompressor is designed to decompress in-place.  After
57      * calling the decompressor, the image will look exactly the same
58      * as the uncompressed image; the compressed data and the
59      * decompressor code itself will have been overwritten.
60      */
61
62     /*
63      * The prefix
64      */
65
66     _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
67     . = _prefix_link_addr;
68     _prefix = .;
69
70     .prefix : AT ( _prefix_load_offset + __prefix ) {
71         __prefix = .;
72         _entry = .;
73         *(.prefix)
74         *(.prefix.*)
75     }
76     
77     _eprefix = .;
78
79     /*
80      * The decompressor (may be absent)
81      */
82
83     _decompress_link_addr = DEFINED ( _decompress_link_addr ) ?
84                               _decompress_link_addr : 0;
85     . = _decompress_link_addr;
86     _decompress = .;
87
88     .decompress : AT ( _decompress_load_offset + __decompress ) {
89             __decompress = .;
90             *(.decompress)
91             *(.decompress.*)
92     }
93
94     _edecompress = .;
95
96     /*
97      * The text sections
98      */
99
100     _text_link_addr = DEFINED ( _text_link_addr ) ? _text_link_addr : 0;
101     . = _text_link_addr;
102     _text = .;
103
104     .text16 : AT ( _text_load_offset + __text16 ) {
105         __text16 = .;
106
107         /* librm is a special case; it must go at the start of the
108          * text section if it is included.
109          */
110         _assert = ASSERT ( ( . == _text_link_addr ), "librm cannot go first" );
111         *(.librm)
112
113         *(.text16)
114         *(.text16.*)
115     } = 0x9090
116
117     .text : AT ( _text_load_offset + __text ) {
118         __text = .;
119         *(.text)
120         *(.text.*)
121     } = 0x9090
122
123     _etext = .;
124
125     /*
126      * The data sections
127      */
128
129     _data_link_addr = DEFINED ( _data_link_addr ) ? _data_link_addr : .;
130     . = _data_link_addr;
131     _data = .;
132
133     .rodata : AT ( _data_load_offset + __rodata ) {
134         __rodata = .;
135         *(.rodata)
136         *(.rodata.*)
137     }
138
139     .data : AT ( _data_load_offset + __data ) {
140         __data = .;
141         *(.data)
142         *(.data.*)
143
144         /* Various tables.  See include/tables.h for an explanation. */
145         *(SORT(.tbl.*)) 
146
147
148         device_drivers = .;
149         *(.drivers.device)
150         device_drivers_end = .;
151         isa_drivers = . ;
152         *(.drivers.isa)
153         isa_drivers_end = .;
154         bus_drivers = .;
155         *(.drivers.bus)
156         bus_drivers_end = .;
157         type_drivers = .;
158         *(.drivers.type)
159         type_drivers_end = .;
160
161         _progbits_end = .;
162     }
163
164     .bss : AT ( _data_load_offset + __bss ) {
165         __bss = .;
166         _bss = .;
167         *(.bss)
168         *(.bss.*)
169         *(COMMON)
170         _ebss = .;
171     }
172
173     .stack : AT ( _data_load_offset + __stack ) {
174         __stack = .;
175         *(.stack)
176         *(.stack.*)
177     }
178
179     _edata = .;
180
181     _end = .;
182
183     /*
184      * Dispose of the comment and note sections to make the link map
185      * easier to read
186      */
187
188     /DISCARD/ : {
189         *(.comment)
190         *(.note)
191     }
192
193     /*
194      * Load address calculations.  The slightly obscure nature of the
195      * calculations is because ALIGN(x) can only operate on the
196      * location counter.
197      */
198
199     _max_align              = DEFINED ( _max_align ) ? _max_align : 16;
200     _load_addr              = DEFINED ( _load_addr ) ? _load_addr : 0;
201
202     .                       = _load_addr;
203
204     .                      -= _prefix_link_addr;
205     _prefix_load_offset     = ALIGN ( _max_align );
206     _prefix_load_addr       = _prefix_link_addr + _prefix_load_offset;
207     _prefix_size            = _eprefix - _prefix;
208     .                       = _prefix_load_addr + _prefix_size;
209
210     .                      -= _decompress_link_addr;
211     _decompress_load_offset = ALIGN ( _max_align );
212     _decompress_load_addr   = _decompress_link_addr + _decompress_load_offset;
213     _decompress_size        = _edecompress - _decompress;
214     .                       = _decompress_load_addr + _decompress_size;
215
216     .                      -= _text_link_addr;
217     _text_load_offset       = ALIGN ( _max_align );
218     _text_load_addr         = _text_link_addr + _text_load_offset;
219     _text_size              = _etext - _text;
220     .                       = _text_load_addr + _text_size;
221
222     .                      -= _data_link_addr;
223     _data_load_offset       = ALIGN ( _max_align );
224     _data_load_addr         = _data_link_addr + _data_load_offset;
225     _data_size              = _edata - _data;
226     .                       = _data_load_addr + _data_size;
227
228     /*
229      * Alignment checks.  ALIGN() can only operate on the location
230      * counter, so we set the location counter to each value we want
231      * to check.
232      */
233
234     . = _prefix_load_addr - _prefix_link_addr;
235     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
236                        "_prefix is badly aligned" );
237
238     . = _decompress_load_addr - _prefix_link_addr;
239     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
240                        "_decompress is badly aligned" );
241
242     . = _text_load_addr - _text_link_addr;
243     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
244                        "_text is badly aligned" );
245
246     . = _data_load_addr - _data_link_addr;
247     _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
248                        "_data is badly aligned" );
249
250     /*
251      * setup16 needs to know this when KEEP_IT_REAL is used.  There
252      * are no harmful side-effects of calculating it all the time.
253      */
254     _text_load_size_pgh = ( _data_load_addr - _text_load_addr ) / 16 ;
255
256     /*
257      * Useful-to-know values.
258      */
259
260     /* Size of the decompressed runtime image */
261     _runtime_size = _edata - _text;
262     /* Size of the initialised-contents portion of the runtime image */
263     _runtime_progbits_size = _progbits_end - _text;
264     /* Size of the (non-compressed) binary file */
265     _file_size = _prefix_size + _runtime_progbits_size;
266     /* Size of the non-compressed portion of the compressed binary file */
267     _zfile_noncompressed_size = _prefix_size + _decompress_size;
268 }