Static con/destruction fix This CL fixes static con/destruction for both C and C++. Change-Id: I6abd4bba90736e9829efc29e1dce5850c8e81772
diff --git a/hello_vec/CMakeLists.txt b/hello_vec/CMakeLists.txt index ee14d41..59efb80 100644 --- a/hello_vec/CMakeLists.txt +++ b/hello_vec/CMakeLists.txt
@@ -5,7 +5,7 @@ set(TARGET hello_vec) set(ELF ${TARGET}.elf) -add_executable(${ELF} main.c) +add_executable(${ELF} main.cpp) target_include_directories(${ELF} PUBLIC include) @@ -26,7 +26,6 @@ target_compile_options(${ELF} PUBLIC -Wall -Werror - -std=c11 -O3 -g3 -ggdb
diff --git a/hello_vec/Makefile b/hello_vec/Makefile index c30c5c7..77015f0 100644 --- a/hello_vec/Makefile +++ b/hello_vec/Makefile
@@ -4,48 +4,47 @@ SRCDIR := $(abspath .) BUILDDIR := $(OUTPREFIX)build -CFLAGS += -Wall -CFLAGS += -Werror CFLAGS += -std=gnu11 -CFLAGS += -march=rv32imfv -CFLAGS += -I${ROOTDIR}/springbok/include -CFLAGS += -O3 -g3 -ggdb -CFLAGS += -ffreestanding -CFLAGS += -ffunction-sections -CFLAGS += -fstack-usage -CFLAGS += -mstrict-align +CCFLAGS += -std=gnu++11 +CCFLAGS += -fno-exceptions + +CXXFLAGS += -Wall +CXXFLAGS += -Werror +CXXFLAGS += -march=rv32imfv +CXXFLAGS += -I${ROOTDIR}/springbok/include +CXXFLAGS += -O3 -g3 -ggdb +CXXFLAGS += -fomit-frame-pointer +CXXFLAGS += -ffreestanding +CXXFLAGS += -fstack-usage +CXXFLAGS += -mstrict-align LDFLAGS += -nostartfiles LDFLAGS += -specs=nano.specs LDFLAGS += -Wl,--gc-sections LDFLAGS += -Wl,--print-memory-usage LDFLAGS += -Wl,-Map=${BUILDDIR}/hello_vec.map -LDFLAGS += -T../springbok/matcha.ld - +LDFLAGS += -T${ROOTDIR}/springbok/matcha.ld CC := ${SHODANROOTDIR}/cache/toolchain_vp/bin/riscv32-unknown-elf-gcc +CPP := ${SHODANROOTDIR}/cache/toolchain_vp/bin/riscv32-unknown-elf-g++ -${BUILDDIR}/hello_vec.elf: ${BUILDDIR}/main.o ${BUILDDIR}/springbok_gloss.o ${BUILDDIR}/Reset_Handler.o ${BUILDDIR}/crt0.o +${BUILDDIR}/hello_vec.elf: ${BUILDDIR}/main.o ${BUILDDIR}/springbok_gloss.o ${BUILDDIR}/crt0.o mkdir -p $(dir $@) - ${CC} ${CFLAGS} $^ ${LDFLAGS} -o $@ + ${CPP} ${CXXFLAGS} ${CPPFLAGS} $^ ${LDFLAGS} -o $@ @cat ${BUILDDIR}/hello_vec.map | awk '/\.heap/ {printf("%16s: %13s\n", "heap (reserved)", int(strtonum($$3)/1024) " KB")} /\.stack/ {printf("%16s: %13s\n", "stack (reserved)", int(strtonum($$3)/1024) " KB")}' -${BUILDDIR}/main.o: ${SRCDIR}/main.c ${MAKEFILE_LIST} +${BUILDDIR}/main.o: ${SRCDIR}/main.cpp ${MAKEFILE_LIST} mkdir -p $(dir $@) - ${CC} ${CFLAGS} -c $< -o $@ + ${CPP} ${CXXFLAGS} ${CPPFLAGS} -c $< -o $@ -${BUILDDIR}/springbok_gloss.o: ${ROOTDIR}/springbok/springbok_gloss.c ${MAKEFILE_LIST} +${BUILDDIR}/springbok_gloss.o: ${ROOTDIR}/springbok/springbok_gloss.cpp ${MAKEFILE_LIST} mkdir -p $(dir $@) - ${CC} ${CFLAGS} -c $< -o $@ - -${BUILDDIR}/Reset_Handler.o: ${ROOTDIR}/springbok/Reset_Handler.c ${MAKEFILE_LIST} - mkdir -p $(dir $@) - ${CC} ${CFLAGS} -c $< -o $@ + ${CPP} ${CXXFLAGS} ${CPPFLAGS} -c $< -o $@ ${BUILDDIR}/crt0.o: ${ROOTDIR}/springbok/crt0.s ${MAKEFILE_LIST} mkdir -p $(dir $@) - ${CC} ${CFLAGS} -c $< -o $@ + ${CC} ${CXXFLAGS} ${CFLAGS} -c $< -o $@ .PHONY: clean clean:
diff --git a/hello_vec/main.c b/hello_vec/main.c deleted file mode 100644 index b1ff42f..0000000 --- a/hello_vec/main.c +++ /dev/null
@@ -1,10 +0,0 @@ -#include <stdio.h> -#include <springbok.h> - -int main(void) { - unsigned int start = springbok_ccount(); - printf("%s(%d): Hello printf!\n", __FILE__, __LINE__); - unsigned int end = springbok_ccount(); - - return end - start; -}
diff --git a/hello_vec/main.cpp b/hello_vec/main.cpp new file mode 100644 index 0000000..598adec --- /dev/null +++ b/hello_vec/main.cpp
@@ -0,0 +1,41 @@ +#include <stdlib.h> +#include <stdio.h> +#include <springbok_intrinsics.h> + +class ExampleStatic { +public: + ExampleStatic() { + springbok_simprint_error("Hello pre-main C++ world.", 0); + value = 1279; + } + + ~ExampleStatic() { + springbok_simprint_error("Goodbye pre-main C++ world.", 0); + } + + unsigned int value; +}; + +ExampleStatic exampleStatic; + +extern "C" __attribute__((constructor)) void boop(void) { + springbok_simprint_error("Hello pre-main C world.", 0); +} + +extern "C" __attribute__((destructor)) void beep(void) { + springbok_simprint_error("Goodbye pre-main C world.", 0); +} + +extern "C" void blerp(void) { + springbok_simprint_error("Fare thee well, atexit.", 0); +} + +extern "C" int main(void) { + static char thingy[10] = {13, 14, 15, 16}; + + atexit(blerp); + + printf("%s(%d): Hello printf!\n", __PRETTY_FUNCTION__, __LINE__); + + return thingy[0] + thingy[1] + thingy[2] + thingy[3] + exampleStatic.value; +}
diff --git a/springbok/CMakeLists.txt b/springbok/CMakeLists.txt index 5cc98c4..41acb68 100644 --- a/springbok/CMakeLists.txt +++ b/springbok/CMakeLists.txt
@@ -6,8 +6,7 @@ add_library(springbok_intrinsic STATIC) target_sources(springbok_intrinsic PRIVATE crt0.s - Reset_Handler.c - springbok_gloss.c) + springbok_gloss.cpp) target_include_directories(springbok_intrinsic PUBLIC include) @@ -21,7 +20,6 @@ target_compile_options(springbok_intrinsic PUBLIC -Wall -Werror - -std=c11 -Os -g3 -ggdb @@ -33,4 +31,4 @@ target_link_options(springbok INTERFACE -Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/libspringbok_intrinsic.a -Wl,--no-whole-archive -) \ No newline at end of file +)
diff --git a/springbok/Reset_Handler.c b/springbok/Reset_Handler.c deleted file mode 100644 index e76a0e8..0000000 --- a/springbok/Reset_Handler.c +++ /dev/null
@@ -1,41 +0,0 @@ -#include <stdlib.h> - -extern int main(void); - -extern void (**__CTOR_LIST__)(void); -extern void (**__DTOR_LIST__)(void); - -void Fini_Handler(void) { - // Destructors are called in forward order. - // The first element can have a few different meanings (always zero, always - // one, number of constructors) depending upon the compiler, but the list is - // guaranteed to be null terminated. So let's just ignore the first element - // and take advantage of the null termination. -// int dtor_count = 1; -// while (__DTOR_LIST__[dtor_count] != NULL) { -// __DTOR_LIST__[dtor_count](); -// dtor_count++; -// } -} - -int Reset_Handler(void) { - // Constructors are called in reverse order - // The first element in the constructor has the same weird meaning as the - // destructor list, so best to just ignore it, too. -// int ctor_count = 0; -// while (__CTOR_LIST__[ctor_count+1] != NULL) { -// ctor_count++; -// } -// while (ctor_count > 0) { -// __CTOR_LIST__[ctor_count](); -// ctor_count--; -// } - - // Call any other C-friendly initialization routines here. - - int retval = main(); - - Fini_Handler(); - - return retval; -}
diff --git a/springbok/crt0.s b/springbok/crt0.s index 654a123..8904159 100644 --- a/springbok/crt0.s +++ b/springbok/crt0.s
@@ -68,17 +68,47 @@ jal ra, _clear_mem jal ra, _setup_stack_sentinels - ############################################################################################## - # Jump to C Reset_Handler, which will perform C initialization calls and then jump into main # - ############################################################################################## - la ra, Reset_Handler - jalr ra, ra + ########################## + # Register fini handlers # + ########################## + la a0, __libc_fini_array + call atexit - ################################################################################################### - # Save main's retval, then verify stack sentinels are unchanged and that sp is where we expect it # - ################################################################################################### - # Save main's return value + ################################## + # Perform C initialization calls # + ################################## + call __libc_init_array + + ############# + # Call main # + ############# + li a0, 0 #argv + li a1, 0 #argc + li a2, 0 #envp + la ra, main + jalr ra, ra + # Save main's return value into s0 mv s0, a0 + + ###################### + # Call C destructors # + ###################### + li a1, 0 + call __call_exitprocs + + # Restore main's return value + mv a0, s0 + + # Don't clear the stack if the program returned from main + j 1f + +_exit: + # Clear the stack + la sp, _stack_ptr +1: + ########################################################################## + # Verify stack sentinels are unchanged and that sp is where we expect it # + ########################################################################## # Check the stack, and fix it if it's broken jal ra, _check_stack # Save check_stack's return value
diff --git a/springbok/include/springbok_intrinsics.h b/springbok/include/springbok_intrinsics.h index 6f18e94..e829416 100644 --- a/springbok/include/springbok_intrinsics.h +++ b/springbok/include/springbok_intrinsics.h
@@ -71,10 +71,10 @@ // none static inline void springbok_hostreq(void) { // hostreq # "-----------------010-----1111011" - __asm__ volatile ("\t.word 0x0000207B\n" : - /* no outputs */ : - /* no inputs */ : - /* no clobbers */); + __asm__ volatile ("\t.word 0x0000207B\n" : + /* no outputs */ : + /* no inputs */ : + /* no clobbers */); } // finish @@ -88,9 +88,9 @@ // none __attribute__((noreturn)) static inline void springbok_finish(void) { // finish # "-----------------011-----1111011" - __asm__ volatile ("\t.word 0x0000307B\n" : - /* no outputs */ : - /* no inputs */ : - /* no clobbers */); + __asm__ volatile ("\t.word 0x0000307B\n" : + /* no outputs */ : + /* no inputs */ : + /* no clobbers */); while(1); }
diff --git a/springbok/matcha.ld b/springbok/matcha.ld index 0cdfae8..81adbc7 100644 --- a/springbok/matcha.ld +++ b/springbok/matcha.ld
@@ -1,4 +1,3 @@ -ENTRY(_start) MEMORY { @@ -29,6 +28,29 @@ _erodata = .; } > DTCM + .preinit_array : + { + PROVIDE(__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE(__preinit_array_end = .); + } > DTCM + + .init_array : + { + PROVIDE(__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE(__init_array_end = .); + } > DTCM + + .fini_array : + { + PROVIDE(__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE(__fini_array_end = .); + } > DTCM + .data : { . = ALIGN(64);
diff --git a/springbok/springbok_gloss.c b/springbok/springbok_gloss.cpp similarity index 71% rename from springbok/springbok_gloss.c rename to springbok/springbok_gloss.cpp index f582fad..1376240 100644 --- a/springbok/springbok_gloss.c +++ b/springbok/springbok_gloss.cpp
@@ -1,29 +1,29 @@ +#include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <unistd.h> +#include <stdint.h> #include <springbok_intrinsics.h> -void _exit(int rc) { - springbok_finish(); +void* __dso_handle = (void*) &__dso_handle; - while (1) { } -} +extern "C" void *_sbrk(int nbytes) { + extern char _sheap, _eheap; + static char *_heap_ptr = &_sheap; -void *_sbrk(int nbytes) { - extern int _sheap, _eheap; - static void *_heap_ptr = (void *)&_sheap; - if ((void*)&_eheap >= _heap_ptr + nbytes) { - void *base = _heap_ptr; - _heap_ptr += nbytes; - return base; - } else { + if ((nbytes < 0) || + (_heap_ptr + nbytes > &_eheap)) { errno = ENOMEM; return (void *)-1; } + + void *base = _heap_ptr; + _heap_ptr += nbytes; + return base; } -int _read(int file, char *ptr, int len) { +extern "C" int _read(int file, char *ptr, int len) { if (file != STDIN_FILENO) { errno = EBADF; return -1; @@ -32,8 +32,7 @@ return 0; } - -int _write(int file, char *buf, int nbytes) { +extern "C" int _write(int file, char *buf, int nbytes) { static int _write_line_buffer_len[2] = {0, 0}; static char _write_line_buffer[2][256]; @@ -75,12 +74,12 @@ return nbytes; } -int _close(int file) { +extern "C" int _close(int file) { errno = EBADF; return -1; } -int _lseek(int file, int offset, int whence) { +extern "C" int _lseek(int file, int offset, int whence) { if (file != STDOUT_FILENO && file != STDERR_FILENO) { errno = EBADF; return -1; @@ -89,7 +88,7 @@ return 0; } -int _fstat(int file, struct stat *st) { +extern "C" int _fstat(int file, struct stat *st) { if (file != STDOUT_FILENO && file != STDERR_FILENO) { errno = EBADF; return -1; @@ -104,7 +103,7 @@ return 0; } -int _isatty(int file) { +extern "C" int _isatty(int file) { if (file != STDOUT_FILENO && file != STDERR_FILENO) { errno = EBADF; return -1; @@ -112,3 +111,11 @@ return 1; } + +void operator delete(void *p) noexcept { + free(p); +} + +extern "C" void operator delete(void *p, unsigned long c) noexcept { + operator delete(p); +}
diff --git a/vector_executive/CMakeLists.txt b/vector_executive/CMakeLists.txt index 326e2c5..1f762cc 100644 --- a/vector_executive/CMakeLists.txt +++ b/vector_executive/CMakeLists.txt
@@ -24,7 +24,6 @@ target_compile_options(${ELF} PUBLIC -Wall -Werror - -std=c11 -O3 -g3 -ggdb
diff --git a/vector_load_tests/CMakeLists.txt b/vector_load_tests/CMakeLists.txt index 4b2820f..7d13871 100644 --- a/vector_load_tests/CMakeLists.txt +++ b/vector_load_tests/CMakeLists.txt
@@ -30,7 +30,6 @@ -ffunction-sections -Wall -Werror - -std=gnu11 -O3 -g)
diff --git a/vector_tests/CMakeLists.txt b/vector_tests/CMakeLists.txt index 554cacd..d7f6bc1 100644 --- a/vector_tests/CMakeLists.txt +++ b/vector_tests/CMakeLists.txt
@@ -12,7 +12,6 @@ target_compile_options(vector_tests PUBLIC -Wall -Werror - -std=c11 -O3 -g3 -ggdb
diff --git a/vector_vadd_vsub_tests/CMakeLists.txt b/vector_vadd_vsub_tests/CMakeLists.txt index 1b7af84..008773a 100644 --- a/vector_vadd_vsub_tests/CMakeLists.txt +++ b/vector_vadd_vsub_tests/CMakeLists.txt
@@ -35,9 +35,8 @@ -Wall -Werror -Wno-unused-value - -std=gnu11 -O3 -g -D=TEST_${OPERAND_TYPE}) -endforeach() \ No newline at end of file +endforeach()
diff --git a/vector_vset_tests/CMakeLists.txt b/vector_vset_tests/CMakeLists.txt index b0efd24..ba64c6b 100644 --- a/vector_vset_tests/CMakeLists.txt +++ b/vector_vset_tests/CMakeLists.txt
@@ -30,7 +30,6 @@ -ffunction-sections -Wall -Werror - -std=gnu11 -O3 -g)