sunnycase 6 anni fa
parent
commit
6f764741ee

+ 2 - 2
cmake/coco_l1.cmake → cmake/coco_aq0.cmake

@@ -13,7 +13,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
 SET(CMAKE_C_COMPILER_WORKS 1)
 SET(CMAKE_CXX_COMPILER_WORKS 1)
 SET(CHINO_ARCH armv7-m)
-SET(CHINO_BOARD coco_l1)
+SET(CHINO_BOARD coco_aq0)
 
 add_compile_options(
     -Wno-multichar
@@ -24,5 +24,5 @@ add_compile_options(
     -flto
     -ffunction-sections
     -fdata-sections
-    -mrelax)
+    -mcpu=cortex-m3)
     

+ 464 - 0
src/Native/arch/armv7-m/crt.S

@@ -0,0 +1,464 @@
+/**
+  ******************************************************************************
+  * @file      startup_stm32f10x_hd.s
+  * @author    MCD Application Team
+  * @version   V3.5.0
+  * @date      11-March-2011
+  * @brief     STM32F10x High Density Devices vector table for RIDE7 toolchain. 
+  *            This module performs:
+  *                - Set the initial SP
+  *                - Set the initial PC == Reset_Handler,
+  *                - Set the vector table entries with the exceptions ISR address
+  *                - Configure the clock system and the external SRAM mounted on 
+  *                  STM3210E-EVAL board to be used as data memory (optional, 
+  *                  to be enabled by user)
+  *                - Branches to main in the C library (which eventually
+  *                  calls main()).
+  *            After Reset the Cortex-M3 processor is in Thread mode,
+  *            priority is Privileged, and the Stack is set to Main.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+    
+  .syntax unified
+  .fpu softvfp
+  .thumb
+
+.global  g_pfnVectors
+.global  Default_Handler
+
+/* start address for the initialization values of the .data section. 
+defined in linker script */
+.word  _sidata
+/* start address for the .data section. defined in linker script */  
+.word  _sdata
+/* end address for the .data section. defined in linker script */
+.word  _edata
+/* start address for the .bss section. defined in linker script */
+.word  _sbss
+/* end address for the .bss section. defined in linker script */
+.word  _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+.equ  BootRAM,        0xF1E0F85F
+/**
+ * @brief  This is the code that gets called when the processor first
+ *          starts execution following a reset event. Only the absolutely
+ *          necessary set is performed, after which the application
+ *          supplied main() routine is called. 
+ * @param  None
+ * @retval : None
+*/
+
+    .section  .text.Reset_Handler
+  .weak  Reset_Handler
+  .type  Reset_Handler, %function
+Reset_Handler:  
+
+/* Copy the data segment initializers from flash to SRAM */  
+  movs  r1, #0
+  b  LoopCopyDataInit
+
+CopyDataInit:
+  ldr  r3, =_sidata
+  ldr  r3, [r3, r1]
+  str  r3, [r0, r1]
+  adds  r1, r1, #4
+    
+LoopCopyDataInit:
+  ldr  r0, =_sdata
+  ldr  r3, =_edata
+  adds  r2, r0, r1
+  cmp  r2, r3
+  bcc  CopyDataInit
+  ldr  r2, =_sbss
+  b  LoopFillZerobss
+/* Zero fill the bss segment. */  
+FillZerobss:
+  movs  r3, #0
+  str  r3, [r2], #4
+    
+LoopFillZerobss:
+  ldr  r3, = _ebss
+  cmp  r2, r3
+  bcc  FillZerobss
+/* Call the clock system intitialization function.*/
+  /*bl  SystemInit   */
+/* Call the application's entry point.*/
+  bl  main
+  bx  lr    
+.size  Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief  This is the code that gets called when the processor receives an 
+ *         unexpected interrupt.  This simply enters an infinite loop, preserving
+ *         the system state for examination by a debugger.
+ * @param  None     
+ * @retval None       
+*/
+    .section  .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+  b  Infinite_Loop
+  .size  Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+* 
+*******************************************************************************/
+   .section  .isr_vector,"a",%progbits
+  .type  g_pfnVectors, %object
+  .size  g_pfnVectors, .-g_pfnVectors
+    
+    
+g_pfnVectors:
+  .word  _estack
+  .word  Reset_Handler
+  .word  NMI_Handler
+  .word  HardFault_Handler
+  .word  MemManage_Handler
+  .word  BusFault_Handler
+  .word  UsageFault_Handler
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  SVC_Handler
+  .word  DebugMon_Handler
+  .word  0
+  .word  PendSV_Handler
+  .word  SysTick_Handler
+  .word  WWDG_IRQHandler
+  .word  PVD_IRQHandler
+  .word  TAMPER_IRQHandler
+  .word  RTC_IRQHandler
+  .word  FLASH_IRQHandler
+  .word  RCC_IRQHandler
+  .word  EXTI0_IRQHandler
+  .word  EXTI1_IRQHandler
+  .word  EXTI2_IRQHandler
+  .word  EXTI3_IRQHandler
+  .word  EXTI4_IRQHandler
+  .word  DMA1_Channel1_IRQHandler
+  .word  DMA1_Channel2_IRQHandler
+  .word  DMA1_Channel3_IRQHandler
+  .word  DMA1_Channel4_IRQHandler
+  .word  DMA1_Channel5_IRQHandler
+  .word  DMA1_Channel6_IRQHandler
+  .word  DMA1_Channel7_IRQHandler
+  .word  ADC1_2_IRQHandler
+  .word  USB_HP_CAN1_TX_IRQHandler
+  .word  USB_LP_CAN1_RX0_IRQHandler
+  .word  CAN1_RX1_IRQHandler
+  .word  CAN1_SCE_IRQHandler
+  .word  EXTI9_5_IRQHandler
+  .word  TIM1_BRK_IRQHandler
+  .word  TIM1_UP_IRQHandler
+  .word  TIM1_TRG_COM_IRQHandler
+  .word  TIM1_CC_IRQHandler
+  .word  TIM2_IRQHandler
+  .word  TIM3_IRQHandler
+  .word  TIM4_IRQHandler
+  .word  I2C1_EV_IRQHandler
+  .word  I2C1_ER_IRQHandler
+  .word  I2C2_EV_IRQHandler
+  .word  I2C2_ER_IRQHandler
+  .word  SPI1_IRQHandler
+  .word  SPI2_IRQHandler
+  .word  USART1_IRQHandler
+  .word  USART2_IRQHandler
+  .word  USART3_IRQHandler
+  .word  EXTI15_10_IRQHandler
+  .word  RTCAlarm_IRQHandler
+  .word  USBWakeUp_IRQHandler
+  .word  TIM8_BRK_IRQHandler
+  .word  TIM8_UP_IRQHandler
+  .word  TIM8_TRG_COM_IRQHandler
+  .word  TIM8_CC_IRQHandler
+  .word  ADC3_IRQHandler
+  .word  FSMC_IRQHandler
+  .word  SDIO_IRQHandler
+  .word  TIM5_IRQHandler
+  .word  SPI3_IRQHandler
+  .word  UART4_IRQHandler
+  .word  UART5_IRQHandler
+  .word  TIM6_IRQHandler
+  .word  TIM7_IRQHandler
+  .word  DMA2_Channel1_IRQHandler
+  .word  DMA2_Channel2_IRQHandler
+  .word  DMA2_Channel3_IRQHandler
+  .word  DMA2_Channel4_5_IRQHandler
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  BootRAM       /* @0x1E0. This is for boot in RAM mode for 
+                         STM32F10x High Density devices. */
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler. 
+* As they are weak aliases, any function with the same name will override 
+* this definition.
+* 
+*******************************************************************************/
+    
+  .weak  NMI_Handler
+  .thumb_set NMI_Handler,Default_Handler
+  
+  .weak  HardFault_Handler
+  .thumb_set HardFault_Handler,Default_Handler
+  
+  .weak  MemManage_Handler
+  .thumb_set MemManage_Handler,Default_Handler
+  
+  .weak  BusFault_Handler
+  .thumb_set BusFault_Handler,Default_Handler
+
+  .weak  UsageFault_Handler
+  .thumb_set UsageFault_Handler,Default_Handler
+
+  .weak  SVC_Handler
+  .thumb_set SVC_Handler,Default_Handler
+
+  .weak  DebugMon_Handler
+  .thumb_set DebugMon_Handler,Default_Handler
+
+  .weak  PendSV_Handler
+  .thumb_set PendSV_Handler,Default_Handler
+
+  .weak  SysTick_Handler
+  .thumb_set SysTick_Handler,Default_Handler
+
+  .weak  WWDG_IRQHandler
+  .thumb_set WWDG_IRQHandler,Default_Handler
+
+  .weak  PVD_IRQHandler
+  .thumb_set PVD_IRQHandler,Default_Handler
+
+  .weak  TAMPER_IRQHandler
+  .thumb_set TAMPER_IRQHandler,Default_Handler
+
+  .weak  RTC_IRQHandler
+  .thumb_set RTC_IRQHandler,Default_Handler
+
+  .weak  FLASH_IRQHandler
+  .thumb_set FLASH_IRQHandler,Default_Handler
+
+  .weak  RCC_IRQHandler
+  .thumb_set RCC_IRQHandler,Default_Handler
+
+  .weak  EXTI0_IRQHandler
+  .thumb_set EXTI0_IRQHandler,Default_Handler
+
+  .weak  EXTI1_IRQHandler
+  .thumb_set EXTI1_IRQHandler,Default_Handler
+
+  .weak  EXTI2_IRQHandler
+  .thumb_set EXTI2_IRQHandler,Default_Handler
+
+  .weak  EXTI3_IRQHandler
+  .thumb_set EXTI3_IRQHandler,Default_Handler
+
+  .weak  EXTI4_IRQHandler
+  .thumb_set EXTI4_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel1_IRQHandler
+  .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel2_IRQHandler
+  .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel3_IRQHandler
+  .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel4_IRQHandler
+  .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel5_IRQHandler
+  .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel6_IRQHandler
+  .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+  .weak  DMA1_Channel7_IRQHandler
+  .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+  .weak  ADC1_2_IRQHandler
+  .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+  .weak  USB_HP_CAN1_TX_IRQHandler
+  .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
+
+  .weak  USB_LP_CAN1_RX0_IRQHandler
+  .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
+
+  .weak  CAN1_RX1_IRQHandler
+  .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+  .weak  CAN1_SCE_IRQHandler
+  .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+  .weak  EXTI9_5_IRQHandler
+  .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+  .weak  TIM1_BRK_IRQHandler
+  .thumb_set TIM1_BRK_IRQHandler,Default_Handler
+
+  .weak  TIM1_UP_IRQHandler
+  .thumb_set TIM1_UP_IRQHandler,Default_Handler
+
+  .weak  TIM1_TRG_COM_IRQHandler
+  .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
+
+  .weak  TIM1_CC_IRQHandler
+  .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+  .weak  TIM2_IRQHandler
+  .thumb_set TIM2_IRQHandler,Default_Handler
+
+  .weak  TIM3_IRQHandler
+  .thumb_set TIM3_IRQHandler,Default_Handler
+
+  .weak  TIM4_IRQHandler
+  .thumb_set TIM4_IRQHandler,Default_Handler
+
+  .weak  I2C1_EV_IRQHandler
+  .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+  .weak  I2C1_ER_IRQHandler
+  .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+  .weak  I2C2_EV_IRQHandler
+  .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+  .weak  I2C2_ER_IRQHandler
+  .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+  .weak  SPI1_IRQHandler
+  .thumb_set SPI1_IRQHandler,Default_Handler
+
+  .weak  SPI2_IRQHandler
+  .thumb_set SPI2_IRQHandler,Default_Handler
+
+  .weak  USART1_IRQHandler
+  .thumb_set USART1_IRQHandler,Default_Handler
+
+  .weak  USART2_IRQHandler
+  .thumb_set USART2_IRQHandler,Default_Handler
+
+  .weak  USART3_IRQHandler
+  .thumb_set USART3_IRQHandler,Default_Handler
+
+  .weak  EXTI15_10_IRQHandler
+  .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+  .weak  RTCAlarm_IRQHandler
+  .thumb_set RTCAlarm_IRQHandler,Default_Handler
+
+  .weak  USBWakeUp_IRQHandler
+  .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+  .weak  TIM8_BRK_IRQHandler
+  .thumb_set TIM8_BRK_IRQHandler,Default_Handler
+
+  .weak  TIM8_UP_IRQHandler
+  .thumb_set TIM8_UP_IRQHandler,Default_Handler
+
+  .weak  TIM8_TRG_COM_IRQHandler
+  .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
+
+  .weak  TIM8_CC_IRQHandler
+  .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+  .weak  ADC3_IRQHandler
+  .thumb_set ADC3_IRQHandler,Default_Handler
+
+  .weak  FSMC_IRQHandler
+  .thumb_set FSMC_IRQHandler,Default_Handler
+
+  .weak  SDIO_IRQHandler
+  .thumb_set SDIO_IRQHandler,Default_Handler
+
+  .weak  TIM5_IRQHandler
+  .thumb_set TIM5_IRQHandler,Default_Handler
+
+  .weak  SPI3_IRQHandler
+  .thumb_set SPI3_IRQHandler,Default_Handler
+
+  .weak  UART4_IRQHandler
+  .thumb_set UART4_IRQHandler,Default_Handler
+
+  .weak  UART5_IRQHandler
+  .thumb_set UART5_IRQHandler,Default_Handler
+
+  .weak  TIM6_IRQHandler
+  .thumb_set TIM6_IRQHandler,Default_Handler
+
+  .weak  TIM7_IRQHandler
+  .thumb_set TIM7_IRQHandler,Default_Handler
+
+  .weak  DMA2_Channel1_IRQHandler
+  .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+  .weak  DMA2_Channel2_IRQHandler
+  .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+  .weak  DMA2_Channel3_IRQHandler
+  .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+  .weak  DMA2_Channel4_5_IRQHandler
+  .thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

+ 182 - 0
src/Native/arch/armv7-m/crt.cpp

@@ -0,0 +1,182 @@
+#ifndef _WIN32
+
+#include <cstring>
+#include <memory>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+void *HeapAlloc(size_t wantedSize) noexcept;
+void HeapFree(void *ptr) noexcept;
+
+extern "C"
+{
+    __attribute__((weak)) void *__dso_handle = 0;
+
+    void *malloc(size_t n)
+    {
+        auto p = HeapAlloc(n);
+        return p;
+    }
+
+    void free(void *p)
+    {
+        HeapFree(p);
+    }
+
+    void *realloc(void *p, size_t n)
+    {
+        auto np = malloc(n);
+        if (p)
+        {
+            memcpy(np, p, n);
+            free(p);
+        }
+
+        return np;
+    }
+
+    void *calloc(size_t num, size_t size)
+    {
+        const auto n = num * size;
+        auto p = malloc(n);
+        if (p)
+            memset(p, 0, n);
+        return p;
+    }
+
+    void *_malloc_r(struct _reent *, size_t n)
+    {
+        return malloc(n);
+    }
+
+    void _free_r(struct _reent *, void *p)
+    {
+        free(p);
+    }
+
+    void *_realloc_r(struct _reent *, void *p, size_t n)
+    {
+        return realloc(p, n);
+    }
+
+    void *_calloc_r(struct _reent *, size_t num, size_t size)
+    {
+        return calloc(num, size);
+    }
+
+#define STDIN_FILENO 0 /* standard input file descriptor */
+#define STDOUT_FILENO 1 /* standard output file descriptor */
+#define STDERR_FILENO 2 /* standard error file descriptor */
+
+    int _close(int file) __attribute__((alias("close")));
+    int _fstat(int file, struct stat *st) __attribute__((alias("fstat")));
+    int _getpid() __attribute__((alias("getpid")));
+    int _isatty(int file) __attribute__((alias("isatty")));
+    int _kill(int pid, int sig) __attribute__((alias("kill")));
+    int _lseek(int file, int ptr, int dir) __attribute__((alias("lseek")));
+    int _open(const char *name, int flags, ...) __attribute__((alias("open")));
+    int _read(int file, char *ptr, int len) __attribute__((alias("read")));
+    int _write(int file, char *ptr, int len) __attribute__((alias("write")));
+    int _gettimeofday(struct timeval *__restrict p, void *__restrict tz) __attribute__((alias("gettimeofday")));
+
+    void _exit(int)
+    {
+        while (1)
+            ;
+    }
+
+    int close(int file)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    char **environ; /* pointer to array of char * strings that define the current environment variables */
+    int execve(const char *name, char *const *argv, char *const *env);
+    int fork();
+
+    int fstat(int file, struct stat *st)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int getpid()
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int isatty(int file)
+    {
+        errno = ENOSYS;
+        return 0;
+    }
+
+    int kill(int pid, int sig)
+    {
+        //g_Logger->PutString("kill\n");
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int link(char *old, char *newl);
+
+    int lseek(int file, int ptr, int dir)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int open(const char *name, int flags, ...)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int read(int file, char *ptr, int len)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    caddr_t sbrk(int incr);
+    int stat(const char *file, struct stat *st);
+    clock_t times(struct tms *buf);
+    int unlink(char *name);
+    int wait(int *status);
+
+    int write(int file, char *ptr, int len)
+    {
+        if (file == STDOUT_FILENO || file == STDERR_FILENO)
+        {
+            //g_Logger->PutString({ ptr, size_t(len) });
+            return len;
+        }
+
+        errno = ENOSYS;
+        return -1;
+    }
+
+    int gettimeofday(struct timeval *__restrict p, void *__restrict tz)
+    {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    void *_sbrk(ptrdiff_t incr)
+    {
+        return nullptr;
+    }
+}
+
+namespace __cxxabiv1
+{
+std::terminate_handler __terminate_handler = abort;
+}
+#endif

+ 181 - 0
src/Native/board/armv7-m/coco_aq0/chino.ld

@@ -0,0 +1,181 @@
+/*
+ * linker script for STM32F10x with GNU ld
+ * bernard.xiong 2009-10-14
+ */
+
+/* Program Entry, set to mark it as "used" and avoid gc */
+MEMORY
+{
+    CODE (rx) : ORIGIN = 0x08000000, LENGTH = 256k /* 256KB flash */
+    DATA (rw) : ORIGIN = 0x20000000, LENGTH =  48k /* 48K sram */
+}
+ENTRY(Reset_Handler)
+_system_stack_size = 0x400;
+_ram_end = ORIGIN(DATA) + LENGTH(DATA);
+
+SECTIONS
+{
+	.isr :
+	{
+        KEEP(*(.isr_vector))            /* Startup code */
+	} > CODE = 0
+
+	.init :
+	{
+		KEEP (*(SORT_NONE(.init)))
+	} > CODE = 0
+
+    .text :
+    {
+        . = ALIGN(4);
+        _stext = .;
+        . = ALIGN(4);
+        *(.text)                        /* remaining code */
+        *(.text.*)                      /* remaining code */
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gnu.linkonce.t*)
+
+        . = ALIGN(4);
+        _etext = .;
+    } > CODE = 0
+
+	.fini :
+	{
+	  KEEP (*(SORT_NONE(.fini)))
+	} > CODE = 0
+	
+    /* Read-only data segment */
+    .rodata :
+    {
+      *(.rdata)
+      *(.rodata .rodata.*)
+      *(.gnu.linkonce.r.*)
+    } > CODE = 0
+
+	.ARM.extab : /* exception unwinding information */
+    {
+        *(.ARM.extab*)
+	} > CODE = 0
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > CODE = 0
+    __exidx_end = .;
+
+    /* .data section which is used for initialized data */
+	   /*
+     * Newlib and Eglibc (at least) need these for C++ support.
+     *
+     * (Copied from Sourcery CodeBench Lite: arm-none-eabi-gcc -V)
+     */
+    .preinit_array :
+    {
+        PROVIDE_HIDDEN(__preinit_array_start = .);
+        KEEP(*(.preinit_array*))
+        PROVIDE_HIDDEN(__preinit_array_end = .);
+    } > CODE = 0
+    .init_array :
+    {
+        PROVIDE_HIDDEN(__init_array_start = .);
+        KEEP(*(SORT(.init_array.*)))
+        KEEP(*(.init_array*))
+        PROVIDE_HIDDEN(__init_array_end = .);
+    } > CODE = 0
+    .fini_array :
+    {
+        PROVIDE_HIDDEN(__fini_array_start = .);
+        KEEP(*(SORT(.fini_array.*)))
+        KEEP(*(.fini_array*))
+        PROVIDE_HIDDEN(__fini_array_end = .);
+	} > CODE = 0
+	
+    /* This is used by the startup in order to initialize the .data secion */
+    _sidata = .;
+    .data : AT (_sidata)
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _sdata = . ;
+
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d*)
+		
+        *(.got)
+        *(.got.plt)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .data secion */
+        _edata = . ;
+    } >DATA
+
+    __bss_start = .;
+    .bss :
+    {
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _sbss = .;
+
+        *(.bss)
+        *(.bss.*)
+        *(COMMON)
+
+        . = ALIGN(4);
+        /* This is used by the startup in order to initialize the .bss secion */
+        _ebss = . ;
+        
+        *(.bss.init)
+    } > DATA
+    __bss_end = .;
+
+    .stack : 
+    {
+        . = . + _system_stack_size;
+        . = ALIGN(4);
+        _estack = .;
+    } >DATA
+
+    _end = .;
+    end = .;
+
+	PROVIDE( _heap_start = ABSOLUTE(.) );
+	PROVIDE( _heap_end = _ram_end );
+
+    /* 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 .gnu.linkonce.wi.*) }
+    .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) }
+}

+ 2 - 2
src/Native/natsu.runtime.h

@@ -107,7 +107,7 @@ gc_obj_ref<::System_Private_CorLib::System::Object> gc_alloc(const vtable_t &vta
 template <class T>
 gc_obj_ref<T> gc_new(size_t size)
 {
-    auto obj = gc_alloc(static_holder<typename T::VTable>::get(), size);
+    auto obj = gc_alloc(vtable_holder<typename T::VTable>::get(), size);
     return obj.template cast<T>();
 }
 
@@ -184,7 +184,7 @@ struct runtime_type_holder
     {
         using namespace ::System_Private_CorLib::System;
         static auto type = make_object<RuntimeType>(
-            reinterpret_cast<intptr_t>(&static_holder<typename T::VTable>::get()));
+            reinterpret_cast<intptr_t>(&vtable_holder<typename T::VTable>::get()));
         return type;
     }
 };

+ 15 - 1
src/Native/natsu.typedef.h

@@ -82,9 +82,23 @@ struct static_holder
     }
 };
 
+template <class T>
+struct vtable_holder
+{
+    static const T value;
+
+    static const T &get()
+    {
+        return value;
+    }
+};
+
+template <class T>
+const T vtable_holder<T>::value;
+
 typedef struct _vtable
 {
-    virtual ~_vtable() = default;
+    virtual void dummy() const noexcept {}
 } vtable_t;
 
 enum object_attributes