OUTPUT_ARCH( "riscv" )
ENTRY( _entry )

SECTIONS
{
  /*
   * ensure that entry.S / _entry is at 0x80000000,
   * where qemu's -kernel jumps.
   */
  . = 0x80000000;

  /*
   * This section contains the code. This is, the machine language instructions
   * that will be executed by the processor. In here we will find symbols
   * that reference the functions in your object file.
   */
  .text : {
    /* Match any section that starts with .text. */
    *(.text .text.*)

    /* Align the next section to a 4KB (page) boundary. */
    . = ALIGN(0x1000);

    /* Put the trampoline code here. */
    _trampoline = .;

    /* Match any section that starts with .trampsec. */
    *(trampsec)

    /* Align the next section to a 4KB (page) boundary. */
    . = ALIGN(0x1000);

    /* Assert that the trampoline code is exactly 4KB (page) in size. */
    ASSERT(. - _trampoline == 0x1000, "error: trampoline larger than one page");

    /* Define symbol etext to be the current location. */
    PROVIDE(etext = .);
  }

  /*
   * This contains any data that is marked as read only.
   * It is not unusual to find this data interleaved with the text section.
   */
  .rodata : {
    /* Align on quadword boundary. */
    . = ALIGN(16);
    *(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
    . = ALIGN(16);
    *(.rodata .rodata.*)
  }

  /*
   * This section contains initialized global and static variables.
   * Any global object that has been explicitly initialized to a value different than zero.
   */
  .data : {
    . = ALIGN(16);
    *(.sdata .sdata.*) /* do not need to distinguish this from .data */
    . = ALIGN(16);
    *(.data .data.*)
  }

  /*
   * Contains all uninitialized global and static var iables. These are usually
   * zeroed out by the startup code before we reach the main function. However,
   * In an embedded system we usually provide our own startup code, which means
   * we need to remember to do this ourselves.
   */
  .bss : {
    . = ALIGN(16);
    *(.sbss .sbss.*) /* do not need to distinguish this from .bss */
    . = ALIGN(16);
    *(.bss .bss.*)
  }

  /* Define symbol end as current location, note that this is not aligned, see vm.c */
  PROVIDE(end = .);
}