# Adapted from mips.sc
#
# Copyright (C) 2014-2016 Free Software Foundation, Inc.
# 
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
#
# These variables may be overridden by the emulation file.  The
# defaults are appropriate for a DECstation running Ultrix.

test -z "$ENTRY" && ENTRY=_start

#test -z "$TEXT_START_ADDR" && TEXT_START_ADDR="0x0"

CTOR=".ctors ${CONSTRUCTING-0} : 
  {
    ${CONSTRUCTING+${CTOR_START}}
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */

    KEEP (*crtbegin.o(.ctors))

    /* We don't want to include the .ctor section from
       from the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */

    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    ${CONSTRUCTING+${CTOR_END}}
  }"

DTOR=" .dtors       ${CONSTRUCTING-0} :
  {
    ${CONSTRUCTING+${DTOR_START}}
    KEEP (*crtbegin.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    ${CONSTRUCTING+${DTOR_END}}
  }"

cat <<EOF
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.

   Copying and distribution of this script, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.  */

OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
	      "${LITTLE_OUTPUT_FORMAT}")
/*${LIB_SEARCH_DIRS}*/
${RELOCATING+${LIB_SEARCH_DIRS}}

${RELOCATING+ENTRY (${ENTRY})}

_TEXT_START_ADDR = DEFINED(_TEXT_START_ADDR) ? _TEXT_START_ADDR : 0x50;		
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0;
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;

SECTIONS
{
  .vectors.reset 0x0 : { KEEP (*(.vectors.reset)) } = 0
  .vectors.sw_exception 0x8 : { KEEP (*(.vectors.sw_exception)) } = 0
  .vectors.interrupt 0x10 : { KEEP (*(.vectors.interrupt)) } = 0
  .vectors.debug_sw_break 0x18 : { KEEP (*(.vectors.debug_sw_break)) } = 0
  .vectors.hw_exception 0x20 : { KEEP (*(.vectors.hw_exception)) } = 0

  ${RELOCATING+. = _TEXT_START_ADDR;}

  ${RELOCATING+ _ftext  =  .;}
  .text : {
    ${RELOCATING+*(.text)}
    ${RELOCATING+*(.text.*)}
    ${RELOCATING+*(.gnu.linkonce.t.*)}
  }
  ${RELOCATING+ _etext  =  .;}

  .init : { KEEP (*(.init))	} =0
  .fini : { KEEP (*(.fini))	} =0

  ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);}
  ${RELOCATING+PROVIDE (___CTOR_LIST__ = .);}
  ${RELOCATING+${CTOR}}
  ${RELOCATING+PROVIDE (__CTOR_END__ = .);}
  ${RELOCATING+PROVIDE (___CTOR_END__ = .);}

  ${RELOCATING+PROVIDE (__DTOR_LIST__ = .);}
  ${RELOCATING+PROVIDE (___DTOR_LIST__ = .);}
  ${RELOCATING+${DTOR}}
  ${RELOCATING+PROVIDE (__DTOR_END__ = .);}
  ${RELOCATING+PROVIDE (___DTOR_END__ = .);}

  ${RELOCATING+ . = ALIGN(4);}
   ${RELOCATING+ _frodata = . ;}
  .rodata : {
    ${RELOCATING+*(.rodata)}
    ${RELOCATING+*(.rodata.*)}
    ${RELOCATING+*(.gnu.linkonce.r.*)}
    ${CONSTRUCTING+CONSTRUCTORS}; /* Is this needed? */
  }
  ${RELOCATING+ _erodata = .;}

  /* Alignments by 8 to ensure that _SDA2_BASE_ on a word boundary */
  /* Note that .sdata2 and .sbss2 must be contiguous */
  ${RELOCATING+. = ALIGN(8);}
  ${RELOCATING+ _ssrw = .;}
  .sdata2 : {
    ${RELOCATING+*(.sdata2)}
    ${RELOCATING+*(.sdata2.*)}
    ${RELOCATING+*(.gnu.linkonce.s2.*)}
  }
  ${RELOCATING+. = ALIGN(4);}
  .sbss2 : {
    ${RELOCATING+PROVIDE (__sbss2_start = .);}	
    ${RELOCATING+*(.sbss2)}
    ${RELOCATING+*(.sbss2.*)}
    ${RELOCATING+*(.gnu.linkonce.sb2.*)}
    ${RELOCATING+PROVIDE (__sbss2_end = .);}
  }
  ${RELOCATING+. = ALIGN(8);}
  ${RELOCATING+ _essrw = .;}
  ${RELOCATING+ _ssrw_size = _essrw - _ssrw;}
  ${RELOCATING+ PROVIDE (_SDA2_BASE_ = _ssrw + (_ssrw_size / 2 ));}

  ${RELOCATING+ . = ALIGN(4);}
  ${RELOCATING+ _fdata = .;}
  .data : {
    ${RELOCATING+*(.data)}
    ${RELOCATING+*(.gnu.linkonce.d.*)}
    ${CONSTRUCTING+CONSTRUCTORS}; /* Is this needed? */
  }
  ${RELOCATING+ _edata = . ;}
  
   /* Added to handle pic code */
  .got : {  
    ${RELOCATING+*(.got)}
  }

  .got1 : {  
    ${RELOCATING+*(.got1)}
  }

  .got2 : {  
    ${RELOCATING+*(.got2)}
  }

  /* Added by Sathya to handle C++ exceptions */
  .eh_frame : {  
    ${RELOCATING+*(.eh_frame)}
  }
  
  .jcr : {  
    ${RELOCATING+*(.jcr)}
  }

  .gcc_except_table : {  
    ${RELOCATING+*(.gcc_except_table)}
  }

  /* Alignments by 8 to ensure that _SDA_BASE_ on a word boundary */
  /* Note that .sdata and .sbss must be contiguous */
  ${RELOCATING+. = ALIGN(8);}
  ${RELOCATING+ _ssro = .;}
  .sdata : {
    ${RELOCATING+*(.sdata)}
    ${RELOCATING+*(.sdata.*)}
    ${RELOCATING+*(.gnu.linkonce.s.*)}
  }
  ${RELOCATING+. = ALIGN(4);}
  .sbss : {
    ${RELOCATING+PROVIDE (__sbss_start = .);}	
    ${RELOCATING+*(.sbss)}
    ${RELOCATING+*(.sbss.*)}
    ${RELOCATING+*(.gnu.linkonce.sb.*)}
    ${RELOCATING+PROVIDE (__sbss_end = .);}
  }
  ${RELOCATING+. = ALIGN(8);}
  ${RELOCATING+ _essro = .;}
  ${RELOCATING+ _ssro_size = _essro - _ssro;}
  ${RELOCATING+PROVIDE (_SDA_BASE_ = _ssro + (_ssro_size / 2 ));}

  ${RELOCATING+ . = ALIGN(4);}
  ${RELOCATING+ _fbss = .;}
  .bss : {
    ${RELOCATING+PROVIDE (__bss_start = .);}	
    ${RELOCATING+*(.bss)}
    ${RELOCATING+*(.bss.*)}
    ${RELOCATING+*(.gnu.linkonce.b.*)}
    ${RELOCATING+*(COMMON)}
    ${RELOCATING+. = ALIGN(. != 0 ? 4 : 1);}
    
    ${RELOCATING+PROVIDE (__bss_end = .);}

  }

  ${RELOCATING+ . = ALIGN(4);}

  .heap : {
    ${RELOCATING+ _heap = .;}
    ${RELOCATING+ _heap_start = .;}
    ${RELOCATING+ . += _HEAP_SIZE;}
    ${RELOCATING+ _heap_end = .;}
  } 

  ${RELOCATING+ . = ALIGN(4);}

  .stack : {
    ${RELOCATING+ _stack_end = .;}
    ${RELOCATING+ . += _STACK_SIZE;}
    ${RELOCATING+ . = ALIGN(. != 0 ? 8 : 1);}
    ${RELOCATING+ _stack = .;}
    ${RELOCATING+ _end = .;}
  }

  .tdata : {  
    ${RELOCATING+*(.tdata)}
    ${RELOCATING+*(.tdata.*)}
    ${RELOCATING+*(.gnu.linkonce.td.*)}
  }
  .tbss : {  
    ${RELOCATING+*(.tbss)}
    ${RELOCATING+*(.tbss.*)}
    ${RELOCATING+*(.gnu.linkonce.tb.*)}
  }
}
EOF
