summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/exception.cc7
-rw-r--r--src/typeinfo.cc38
-rw-r--r--test/test.cc30
-rw-r--r--test/test_exception.cc2
-rw-r--r--test/test_guard.cc5
-rw-r--r--test/test_typeinfo.cc11
8 files changed, 81 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 403d43f..7da13f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,5 +7,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
add_subdirectory(src)
+IF(BUILD_TESTS)
add_subdirectory(test)
+ENDIF()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d30da28..7633f03 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,6 +8,8 @@ set(CXXRT_SOURCES
stdexcept.cc
memory.cc
aux.cc
+ libelftc_dem_gnu3.c
+ libelftc_vstr.c
)
diff --git a/src/exception.cc b/src/exception.cc
index 749f743..0ecc679 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -443,18 +443,17 @@ static void report_failure(_Unwind_Reason_Code err, void *thrown_exception)
fprintf(stderr, "Fatal error during phase 2 unwinding\n");
break;
case _URC_END_OF_STACK:
- fprintf(stderr, "Terminating due to uncaught exception %p:\n",
+ fprintf(stderr, "Terminating due to uncaught exception %p",
thrown_exception);
-/* TODO: Uncomment this when __cxa_demangle() is implemented.
size_t bufferSize = 128;
char *demangled = (char*)malloc(bufferSize);
const char *mangled = __cxa_current_exception_type()->name();
int status;
__cxa_demangle(mangled, demangled, &bufferSize, &status);
- fprintf(stderr, "Terminating due to uncaught of type %s:\n",
+ fprintf(stderr, " of type %s\n",
status == 0 ? (const char*)demangled : mangled);
-*/
+ if (status == 0) { free(demangled); }
// Print a back trace if no handler is found.
// TODO: Make this optional
_Unwind_Backtrace(trace, 0);
diff --git a/src/typeinfo.cc b/src/typeinfo.cc
index cc2b3c7..6d16668 100644
--- a/src/typeinfo.cc
+++ b/src/typeinfo.cc
@@ -1,4 +1,7 @@
#include "typeinfo.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
using std::type_info;
@@ -39,3 +42,38 @@ ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {}
ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {}
ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {}
ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {}
+
+// From libelftc
+extern "C" char *cpp_demangle_gnu3(const char *);
+extern "C" bool is_cpp_mangled_gnu3(const char *);
+
+extern "C" char* __cxa_demangle(const char* mangled_name,
+ char* buf,
+ size_t* n,
+ int* status)
+{
+ char *demangled = cpp_demangle_gnu3(mangled_name);
+ if (NULL != demangled)
+ {
+ size_t len = strlen(demangled);
+ buf = (char*)realloc(buf, len+1);
+ if (0 != buf)
+ {
+ memcpy(buf, demangled, len);
+ buf[len] = 0;
+ *n = len;
+ *status = 0;
+ }
+ else
+ {
+ *status = -1;
+ }
+ free(demangled);
+ }
+ else
+ {
+ *status = -2;
+ return NULL;
+ }
+ return buf;
+}
diff --git a/test/test.cc b/test/test.cc
index 13bad95..520286c 100644
--- a/test/test.cc
+++ b/test/test.cc
@@ -1,13 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+
static int succeeded;
static int failed;
+static bool verbose;
void log_test(bool predicate, const char *file, int line, const char *message)
{
if (predicate)
{
+ if (verbose)
+ {
+ printf("Test passed: %s:%d: %s\n", file, line, message);
+ }
succeeded++;
return;
}
@@ -24,3 +31,26 @@ static void __attribute__((constructor)) init(void)
{
atexit(log_totals);
}
+
+void test_type_info(void);
+void test_exceptions();
+void test_guards(void);
+int main(int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "v")) != -1)
+ {
+ switch (ch)
+ {
+ case 'v':
+ verbose = true;
+ default: break;
+ }
+ }
+
+ test_type_info();
+ test_guards();
+ test_exceptions();
+ return 0;
+}
diff --git a/test/test_exception.cc b/test/test_exception.cc
index 5042b64..8149fbf 100644
--- a/test/test_exception.cc
+++ b/test/test_exception.cc
@@ -5,6 +5,8 @@
#include <exception>
+#define fprintf(...)
+
void log(void* ignored)
{
printf("Cleanup called on %s\n", *(char**)ignored);
diff --git a/test/test_guard.cc b/test/test_guard.cc
index 5f8521d..1ad5a2f 100644
--- a/test/test_guard.cc
+++ b/test/test_guard.cc
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include "test.h"
static int static_count;
struct static_struct
@@ -6,7 +7,6 @@ struct static_struct
int i;
static_struct()
{
- fprintf(stderr, "Initialized static\n");
static_count++;
i = 12;
};
@@ -23,4 +23,7 @@ int init_static(void)
void test_guards(void)
{
init_static();
+ int i = init_static();
+ TEST(i == 12, "Static initialized");
+ TEST(static_count == 2, "Each static only initialized once");
}
diff --git a/test/test_typeinfo.cc b/test/test_typeinfo.cc
index 7e9e308..6d2fbdd 100644
--- a/test/test_typeinfo.cc
+++ b/test/test_typeinfo.cc
@@ -2,9 +2,6 @@
#include "test.h"
#include <stdio.h>
-// FIXME: Move this and main() to a different file.
-void test_exceptions();
-
struct Virt1;
struct Virt2;
struct Diamond;
@@ -110,11 +107,3 @@ void test_type_info(void)
TEST(0 == dynamic_cast<Sub1*>(b2), "Casting Root to Sub1 (0 expected)");
}
-void test_guards(void);
-int main(void)
-{
- test_type_info();
- test_guards();
- test_exceptions();
- return 0;
-}