diff --git a/Makefile b/Makefile index 09ce55b..4c4396f 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,11 @@ libc: $(Q)echo Building libc $(Q)make -C examples/libc +.PHONY: libcpp +libcpp: + $(Q)echo Building libcpp + $(Q)make -C examples/libcpp + .PHONY: clean clean: $(Q)echo Cleaning Build Output @@ -43,4 +48,5 @@ clean: $(Q)make -C interview clean $(Q)make -C examples/cpp clean $(Q)make -C examples/c clean + $(Q)make -C examples/libcpp clean diff --git a/examples/libcpp/Makefile b/examples/libcpp/Makefile new file mode 100644 index 0000000..e326103 --- /dev/null +++ b/examples/libcpp/Makefile @@ -0,0 +1,37 @@ +ifeq ($(VERBOSE),1) +export Q := +export VERBOSE := 1 +else +export Q := @ +export VERBOSE := 0 +endif + +BUILDTOP ?= ../.. +BUILDRESULTS ?= buildresults + +include $(BUILDTOP)/build/compiler.mk + +# Compiler.mk defines these rules, need to add to them after +#ARCH := -arch armv7 +CPPFLAGS += -D_LIBCPP_HAS_NO_THREADS -D_LIBCPP_NO_EXCEPTIONS +CXXFLAGS += -fno-rtti -fno-exceptions +CXXFLAGS += $(ARCH) -fno-builtin -fno-stack-protector -ffreestanding -static -nodefaultlibs +LDFLAGS += $(ARCH) -L$(shell pwd)/$(BUILDRESULTS) -L$(BUILDTOP)/buildresults/ -nodefaultlibs -nostartfiles +#CFLAGS += -pipe -fPIC? -ffreestanding? + +include $(BUILDTOP)/build/rules.mk + +all: libcpp example + +libcpp: new.o + $(Q)[ -d "$(BUILDRESULTS)" ] || mkdir -p $(BUILDRESULTS) + $(Q)echo Generating libcpp.a + $(Q)$(AR) crs $(BUILDRESULTS)/libcpp.a $(addprefix $(BUILDRESULTS)/,$^) + +example: main.o libcpp + $(Q)echo Building libcpp example + $(Q) $(CXX) -v $(LDFLAGS) -lcpp -lc $(BUILDRESULTS)/main.o -o $(BUILDRESULTS)/$@ + +.PHONY: clean +clean: + $(Q)rm -rf $(BUILDRESULTS) diff --git a/examples/libcpp/main.cpp b/examples/libcpp/main.cpp new file mode 100644 index 0000000..99dbcd0 --- /dev/null +++ b/examples/libcpp/main.cpp @@ -0,0 +1,13 @@ + +void start(void); +int main(void); + +void start(void) +{ + main(); +} + +int main(void) +{ + return 0; +} diff --git a/examples/libcpp/new.cpp b/examples/libcpp/new.cpp new file mode 100644 index 0000000..75f4eea --- /dev/null +++ b/examples/libcpp/new.cpp @@ -0,0 +1,184 @@ +//===--------------------------- new.cpp ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#if 0 //PJ: Need to remove +#include +#else +//PJ: from libc +#include +#endif + +#include "new" + +static std::new_handler __new_handler; + +// Implement all new and delete operators as weak definitions +// in this shared library, so that they can be overriden by programs +// that define non-weak copies of the functions. + +__attribute__((__weak__, __visibility__("default"))) +void * +operator new(std::size_t size) +#if !__has_feature(cxx_noexcept) + throw(std::bad_alloc) +#endif +{ + if (size == 0) + size = 1; + void* p; + while ((p = ::malloc(size)) == 0) + { + // If malloc fails and there is a new_handler, + // call it to try free up memory. + std::new_handler nh = std::get_new_handler(); + if (nh) + nh(); + else +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + break; +#endif + } + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new(size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new(size); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new[](size_t size) +#if !__has_feature(cxx_noexcept) + throw(std::bad_alloc) +#endif +{ + return ::operator new(size); +} + +__attribute__((__weak__, __visibility__("default"))) +void* +operator new[](size_t size, const std::nothrow_t& nothrow) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new[](size); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete(void* ptr) _NOEXCEPT +{ + if (ptr) + ::free(ptr); +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr); +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete[] (void* ptr) _NOEXCEPT +{ + ::operator delete (ptr); +} + +__attribute__((__weak__, __visibility__("default"))) +void +operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr); +} + +namespace std +{ + +const nothrow_t nothrow = {}; + +#if 0 //TODO +new_handler +set_new_handler(new_handler handler) _NOEXCEPT +{ + return __sync_lock_test_and_set(&__new_handler, handler); +} + +new_handler +get_new_handler() _NOEXCEPT +{ + return __sync_fetch_and_add(&__new_handler, (new_handler)0); +} +#endif + +bad_alloc::bad_alloc() _NOEXCEPT +{ +} + +bad_alloc::~bad_alloc() _NOEXCEPT +{ +} + +const char* +bad_alloc::what() const _NOEXCEPT +{ + return "std::bad_alloc"; +} + +bad_array_new_length::bad_array_new_length() _NOEXCEPT +{ +} + +bad_array_new_length::~bad_array_new_length() _NOEXCEPT +{ +} + +const char* +bad_array_new_length::what() const _NOEXCEPT +{ + return "bad_array_new_length"; +} + +void +__throw_bad_alloc() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_alloc(); +#endif +} + +} // std diff --git a/examples/libcpp/typeinfo.cpp b/examples/libcpp/typeinfo.cpp new file mode 100644 index 0000000..0d5cfbf --- /dev/null +++ b/examples/libcpp/typeinfo.cpp @@ -0,0 +1,39 @@ +//===------------------------- typeinfo.cpp -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include + +#include "typeinfo" + +std::bad_cast::bad_cast() _NOEXCEPT +{ +} + +std::bad_cast::~bad_cast() _NOEXCEPT +{ +} + +const char* +std::bad_cast::what() const _NOEXCEPT +{ + return "std::bad_cast"; +} + +std::bad_typeid::bad_typeid() _NOEXCEPT +{ +} + +std::bad_typeid::~bad_typeid() _NOEXCEPT +{ +} + +const char* +std::bad_typeid::what() const _NOEXCEPT +{ + return "std::bad_typeid"; +}