# Adapted from mips.sc
#
# Copyright (C) 2014 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 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
