summaryrefslogtreecommitdiff
path: root/src/lib/rmodule.ld
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rmodule.ld')
-rw-r--r--src/lib/rmodule.ld115
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);
+ }
+}