OUTPUT_FORMAT(elf64-x86-64)

MEMORY
{
    MBR    (wx) : org = 0x0e00, l = 512
    STAGE1 (wx) : org = 0x1000, l = 4K
    PHYMEM (w)  : org = 0xffffff0000000000, len = 512 * 1024M
    PARRAY (w)  : org = 0xffffff8000000000, len = 128 * 1024M
    KBSS   (w)  : org = 0xffffffffc0200000, len = 2M
    KIMAGE (wx) : org = 0xffffffffffc00000, len = 2M
}

SECTIONS
{
    .mbr : AT(0)
    {
        KEEP(*(.mbr));

        . = 510;
        BYTE(0x55);
        BYTE(0xaa);
    } > MBR

    .stage1 : AT(LOADADDR(.mbr) + SIZEOF(.mbr))
    {
        __stage1_start = .;
        *(.stage1)

        . = ALIGN(0x1000);
        __stage1_end = .;
    } > STAGE1

    .kinit :
        AT(LOADADDR(.stage1) + SIZEOF(.stage1))
    {
        KIMAGE_START = .;
        KINIT_START = .;

        *(.text.kinit)

        . = ALIGN(16);
        *(.rodata.kinit)

        KINIT_START_ADDR = .;
        QUAD(ABSOLUTE(KINIT_START));

        KINIT_END_ADDR = .;
        QUAD(ABSOLUTE(KINIT_END));

        KINIT_PAGES = .;
        QUAD((KINIT_END - KINIT_START) / 0x1000);

        . = ALIGN(16);
        start_ctors = .;
        KEEP(*(.init_array));
        KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*)));
        KEEP(*(.ctors));
        KEEP(*(SORT_BY_INIT_PRIORITY(.ctors*)));
        end_ctors = .;

        . = ALIGN(16);
        *(.data.kinit)

        . = ALIGN(16);
        *(.bss.kinit)

        . = ALIGN(0x1000);
        KINIT_END = .;
    } > KIMAGE

    .text :
        AT(LOADADDR(.kinit) + SIZEOF(.kinit))
    {
        TEXT_START = .;
        *(.text)
        *(.text*)

        . = ALIGN(0x1000);
        TEXT_END = .;
    } > KIMAGE

    .rodata :
        AT(LOADADDR(.text) + SIZEOF(.text))
    {
        RODATA_START = .;
        *(.rodata)
        *(.rodata*)

        . = ALIGN(16);
        KMOD_LOADERS_START = .;

        KEEP(*(.kmods));
        QUAD(0);

        . = ALIGN(16);
        late_init_start = .;
        KEEP(*(.late_init));
        QUAD(0);
        late_init_end = .;

        . = ALIGN(16);

        BSS_ADDR = .;
        QUAD(ABSOLUTE(BSS_START));
        BSS_LENGTH = .;
        QUAD(BSS_END - BSS_START);

        . = ALIGN(0x1000);
        RODATA_END = .;
    } > KIMAGE

    .data :
        AT(LOADADDR(.rodata) + SIZEOF(.rodata))
    {
        DATA_START = .;
        *(.data)
        *(.data*)

        *(.got)
        *(.got.plt)

        . = ALIGN(0x1000);
        DATA_END = .;
        KIMAGE_END = .;
    } > KIMAGE

    .sentry :
        AT(0x78000 - 0x4)
    { LONG(0x01145140); } > KIMAGE

    .bss :
    {
        BSS_START = .;
        *(.bss)
        *(.bss*)

        . = ALIGN(0x1000);
        BSS_END = .;
    } > KBSS

    KIMAGE_PAGES = (KIMAGE_END - KIMAGE_START) / 0x1000;
    BSS_PAGES = (BSS_END - BSS_START) / 0x1000;

    .eh_frame :
        AT(LOADADDR(.sentry) + SIZEOF(.sentry))
    {
        __eh_frame_start = .;
        KEEP(*(.eh_frame*))
        . = ALIGN(0x1000);
        __eh_frame_end = .;
    } > KIMAGE

    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
    /* DWARF debug sections.
       Symbols in the DWARF debugging sections are relative to the beginning
       of the section so we begin them at 0.  */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }

    /* DWARF Other */
    .debug_ranges  0 : { *(.debug_ranges) }
    .debug_line_str 0 : { *(.debug_line_str) }
    /* Rust stuff */

    /DISCARD/ :
    {
        *(.fini_array*)
        *(.note*)
        *(.dtors*)
        *(.debug_gdb_scripts*)
    }
}
