summaryrefslogblamecommitdiffstats
path: root/src/arch/i386/scripts/i386.lds
blob: 71a7f74df88be0f2d5ab58a314be747ea27244e5 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                     


                                                                      

                                   
                                   















                                                                      














                                                                              
                              




                 
                                      

       















                                                     
 





















                                                         

     
                 

      
                          





                                                                        







                                               

              
                                                   



                     
                                               


                   
                                                                           
                            
     
                                             






                  
                                                 

































                                                                       















                                                                        




                                                                  



                                                                    
 
                                             










                                                                    
                                              
                                                     
                                                    
 
                                              
                                                     
                                                    
 
                                          
                                                     
                                                  

      
                                                   
       
                                              
 
/* -*- sh -*- */

/*
 * Linker script for i386 images
 *
 */

OUTPUT_FORMAT ( "elf32-i386", "elf32-i386", "elf32-i386" )
OUTPUT_ARCH ( i386 )
ENTRY ( _entry )

SECTIONS {

    /* All sections in the resulting file have consecutive load
     * addresses, but may have individual link addresses depending on
     * the memory model being used.
     *
     * The linker symbols {prefix,text}_link_addr, load_addr, and
     * _max_align may be specified explicitly.  If not specified, they
     * will default to:
     *
     *   _prefix_link_addr	= 0
     *   _text_link_addr	= 0
     *   _load_addr		= 0
     *   _max_align		= 16
     * 
     * We guarantee alignment of virtual addresses to any alignment
     * specified by the constituent object files (e.g. via
     * __attribute__((aligned(x)))).  Load addresses are guaranteed
     * only up to _max_align.  Provided that all loader and relocation
     * code honours _max_align, this means that physical addresses are
     * also guaranteed up to _max_align.
     *
     * Note that when using -DKEEP_IT_REAL, the UNDI segments are only
     * guaranteed to be loaded on a paragraph boundary (i.e. 16-byte
     * alignment).  Using _max_align>16 will therefore not guarantee
     * >16-byte alignment of physical addresses when -DKEEP_IT_REAL is
     * used (though virtual addresses will still be fully aligned).
     *
     */

    /*
     * The prefix
     */

    _prefix_link_addr = DEFINED ( _prefix_link_addr ) ? _prefix_link_addr : 0;
    . = _prefix_link_addr;
    _prefix = .;

    .prefix : AT ( _prefix_load_offset + __prefix ) {
	__prefix = .;
	_entry = .;
	*(.prefix)
	*(.prefix.*)
	_eprefix_progbits = .;
    }
    
    _eprefix = .;

    /*
     * The 16-bit sections, if present
     */

    _text16_link_addr = 0;
    . = _text16_link_addr;
    _text16 = .;

    .text16 : AT ( _text16_load_offset + __text16 ) {
	__text16 = .;
	*(.text16)
	*(.text16.*)
	_etext16_progbits = .;
    } = 0x9090

    _etext16 = .;

    _data16_link_addr = 0;
    . = _data16_link_addr;
    _data16 = .;

    .rodata16 : AT ( _data16_load_offset + __rodata16 ) {
	__rodata16 = .;
	*(.rodata16)
	*(.rodata16.*)
    }
    .data16 : AT ( _data16_load_offset + __data16 ) {
	__data16 = .;
	*(.data16)
	*(.data16.*)
	_edata16_progbits = .;
    }
    .bss16 : AT ( _data16_load_offset + __bss16 ) {
	__bss16 = .;
	_bss16 = .;
	*(.bss16)
	*(.bss16.*)
	_ebss16 = .;
    }
    .stack16 : AT ( _data16_load_offset + __stack16 ) {
	__stack16 = .;
	*(.stack16)
	*(.stack16.*)
    }

    _edata16 = .;

    /*
     * The 32-bit sections
     */

    _text_link_addr = DEFINED ( _text_link_addr ) ? _text_link_addr : 0;
    . = _text_link_addr;
    _text = .;

    .text : AT ( _text_load_offset + __text ) {
	__text = .;
	*(.text)
	*(.text.*)
    } = 0x9090

    _etext = .;

    _data = .;

    .rodata : AT ( _text_load_offset + __rodata ) {
	__rodata = .;
	*(.rodata)
	*(.rodata.*)
    }
    .data : AT ( _text_load_offset + __data ) {
	__data = .;
	*(.data)
	*(.data.*)
	*(SORT(.tbl.*))		/* Various tables.  See include/tables.h */
	_etext_progbits = .;
    }
    .bss : AT ( _text_load_offset + __bss ) {
	__bss = .;
	_bss = .;
	*(.bss)
	*(.bss.*)
	*(COMMON)
	_ebss = .;
    }
    .stack : AT ( _text_load_offset + __stack ) {
	__stack = .;
	*(.stack)
	*(.stack.*)
    }

    _edata = .;

    _end = .;

    /*
     * Dispose of the comment and note sections to make the link map
     * easier to read
     */

    /DISCARD/ : {
	*(.comment)
	*(.note)
    }

    /*
     * Load address calculations.  The slightly obscure nature of the
     * calculations is because ALIGN(x) can only operate on the
     * location counter.
     */

    _max_align		    = DEFINED ( _max_align ) ? _max_align : 16;
    _load_addr		    = DEFINED ( _load_addr ) ? _load_addr : 0;

    .			    = _load_addr;

    .			   -= _prefix_link_addr;
    _prefix_load_offset	    = ALIGN ( _max_align );
    _prefix_load_addr	    = _prefix_link_addr + _prefix_load_offset;
    _prefix_size	    = _eprefix - _prefix;
    _prefix_progbits_size   = _eprefix_progbits - _prefix;
    .			    = _prefix_load_addr + _prefix_progbits_size;

    .			   -= _text16_link_addr;
    _text16_load_offset	    = ALIGN ( _max_align );
    _text16_load_addr	    = _text16_link_addr + _text16_load_offset;
    _text16_size	    = _etext16 - _text16;
    _text16_progbits_size   = _etext16_progbits - _text16;
    .			    = _text16_load_addr + _text16_progbits_size;

    .			   -= _data16_link_addr;
    _data16_load_offset	    = ALIGN ( _max_align );
    _data16_load_addr	    = _data16_link_addr + _data16_load_offset;
    _data16_size	    = _edata16 - _data16;
    _data16_progbits_size   = _edata16_progbits - _data16;
    .			    = _data16_load_addr + _data16_progbits_size;

    .			   -= _text_link_addr;
    _text_load_offset	    = ALIGN ( _max_align );
    _text_load_addr	    = _text_link_addr + _text_load_offset;
    _text_size		    = _etext - _text;
    _text_progbits_size	    = _etext_progbits - _text;
    .			    = _text_load_addr + _text_progbits_size;

    .			    = ALIGN ( _max_align );

    _load_size		    = . - _load_addr;

    /*
     * Alignment checks.  ALIGN() can only operate on the location
     * counter, so we set the location counter to each value we want
     * to check.
     */

    . = _prefix_load_addr - _prefix_link_addr;
    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
		       "_prefix is badly aligned" );

    . = _text16_load_addr - _text16_link_addr;
    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
		       "_text16 is badly aligned" );

    . = _data16_load_addr - _data16_link_addr;
    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
		       "_data16 is badly aligned" );

    . = _text_load_addr - _text_link_addr;
    _assert = ASSERT ( ( . == ALIGN ( _max_align ) ),
		       "_text is badly aligned" );

    /*
     * Values calculated to save code from doing it
     */
    _load_size_pgh	= ( _load_size / 16 );
}