diff options
Diffstat (limited to 'src/lib/rmodule.ld')
-rw-r--r-- | src/lib/rmodule.ld | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/lib/rmodule.ld b/src/lib/rmodule.ld new file mode 100644 index 0000000000..4c13c84666 --- /dev/null +++ b/src/lib/rmodule.ld @@ -0,0 +1,115 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) + +/* + * This linker script is used to link rmodules (relocatable modules). It + * links at zero so that relocation fixups are easy when placing the binaries + * anywhere in the address space. + * + * NOTE: The program's loadable sections (text, module_params, and data) are + * packed into the flat blob using the AT directive. The rmodule loader assumes + * the entire program resides in one contiguous address space. Therefore, + * alignment for a given section (if required) needs to be done at the end of + * the preceeding section. e.g. if the data section should be aligned to an 8 + * byte address the text section should have ALIGN(8) at the end of its section. + * Otherwise there won't be a consistent mapping between the flat blob and the + * loaded program. + */ + +BASE_ADDRESS = 0x00000; + +SECTIONS +{ + . = BASE_ADDRESS; + + .header : AT (0) { + *(.module_header); + . = ALIGN(8); + } + + /* Align the start of the module program to a large enough alignment + * so that any data in the program with an alignement property is met. + * Essentially, this alignment is the maximum possible data alignment + * property a program can have. */ + . = ALIGN(4096); + _module_link_start_addr = .; + _payload_begin_offset = LOADADDR(.header) + SIZEOF(.header); + + .text : AT (_payload_begin_offset) { + /* C code of the module. */ + *(.text); + *(.text.*); + /* C read-only data. */ + . = ALIGN(16); + *(.rodata); + *(.rodata.*); + . = ALIGN(4); + } + + .module_params : AT (LOADADDR(.text) + SIZEOF(.text)) { + /* The parameters section can be used to pass parameters + * to a module, however there has to be an prior agreement + * on how to interpret the parameters. */ + _module_params_begin = .; + *(.module_parameters); + _module_params_end = .; + . = ALIGN(4); + } + + .data : AT (LOADADDR(.module_params) + SIZEOF(.module_params)) { + _sdata = .; + *(.data); + . = ALIGN(4); + _edata = .; + } + + /* _payload_end marks the end of the module's code and data. */ + _payload_end_offset = LOADADDR(.data) + SIZEOF(.data); + + .bss (NOLOAD) : { + /* C uninitialized data of the SMM handler */ + _bss_begin = .; + *(.bss); + *(.sbss); + *(COMMON); + . = ALIGN(8); + _bss_end = .; + } + + .heap (NOLOAD) : { + /* + * Place the heap after BSS. The heap size is passed in by + * by way of ld --defsym=__heap_size=<> + */ + _heap = .; + . = . + __heap_size; + _eheap = .; + } + + /* _module_program_size is the total memory used by the program. */ + _module_program_size = _eheap - _module_link_start_addr; + + /* The relocation information is linked on top of the BSS section + * because the BSS section takes no space on disk. The relocation data + * resides directly after the data section in the flat binary. */ + .relocations ADDR(.bss) : AT (_payload_end_offset) { + *(.rel.*); + } + _relocations_begin_offset = LOADADDR(.relocations); + _relocations_end_offset = _relocations_begin_offset + + SIZEOF(.relocations); + + /DISCARD/ : { + /* Drop unnecessary sections. Since these modules are linked + * as shared objects there are dynamic sections. These sections + * aren't needed so drop them. */ + *(.comment); + *(.note); + *(.note.*); + *(.dynamic); + *(.dynsym); + *(.dynstr); + *(.gnu.hash); + *(.eh_frame); + } +} |