Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Rust build #1

Closed
2 changes: 1 addition & 1 deletion libunwind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ if (LIBUNWIND_ENABLE_ASSERTIONS)

# On Release builds cmake automatically defines NDEBUG, so we
# explicitly undefine it:
if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE")
if ((uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") AND (NOT RUST_SGX))
list(APPEND LIBUNWIND_COMPILE_FLAGS -UNDEBUG)
endif()
else()
Expand Down
22 changes: 22 additions & 0 deletions libunwind/README_RUST_SGX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Libunwind customizations for linking with x86_64-fortanix-unknown-sgx Rust target.

## Description
### Initial Fork
Initial Fork has been made from 5.0 release of llvm (commit: 6a075b6de4)
### Detailed Description
#### Header files that we do not include for this target
1. pthread.h
#### Library that we do not link to for this target.
1. pthread (Locks used by libunwind is provided by rust stdlib for this target)

## Building unwind for rust-sgx target
### Generate Make files:
* `cd where you want to build libunwind`
* `mkdir build`
* `cd build`
* `cmake -DCMAKE_BUILD_TYPE="RELEASE" -DRUST_SGX=1 -G "Unix Makefiles" -DLLVM_ENABLE_WARNINGS=1 -DLIBUNWIND_ENABLE_WERROR=1 -DLIBUNWIND_ENABLE_PEDANTIC=0 -DLLVM_PATH=<path/to/llvm> <path/to/libunwind>`
* `-DCMAKE_BUILD_TYPE="RELEASE"` could be removed to enable debug logs of libunwind.

### Build:
* `make unwind_static`
* `build/lib/` will have the built library.
5 changes: 5 additions & 0 deletions libunwind/docs/BuildingLibunwind.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,8 @@ libunwind specific options
.. option:: LIBUNWIND_SYSROOT

Sysroot for cross compiling

.. option:: LIBUNWIND_ENABLE_RUST_SGX:BOOL

**Default**: ``OFF``

41 changes: 34 additions & 7 deletions libunwind/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,10 @@ set(LIBUNWIND_C_SOURCES
UnwindLevel1.c
UnwindLevel1-gcc-ext.c
Unwind-sjlj.c)
set_source_files_properties(${LIBUNWIND_C_SOURCES}
PROPERTIES
COMPILE_FLAGS "-std=c99")

set(LIBUNWIND_ASM_SOURCES
UnwindRegistersRestore.S
UnwindRegistersSave.S)
set_source_files_properties(${LIBUNWIND_ASM_SOURCES}
PROPERTIES
LANGUAGE C)

set(LIBUNWIND_HEADERS
AddressSpace.hpp
Expand All @@ -32,6 +26,7 @@ set(LIBUNWIND_HEADERS
Registers.hpp
UnwindCursor.hpp
unwind_ext.h
UnwindRustSgx.h
${CMAKE_CURRENT_SOURCE_DIR}/../include/libunwind.h
${CMAKE_CURRENT_SOURCE_DIR}/../include/unwind.h)

Expand All @@ -44,6 +39,38 @@ if (MSVC_IDE)
source_group("Header Files" FILES ${LIBUNWIND_HEADERS})
endif()

if (RUST_SGX)
# Compile Flags
add_definitions(-DRUST_SGX)
add_definitions(-D__NO_STRING_INLINES)
add_definitions(-D__NO_MATH_INLINES)
add_definitions(-D_LIBUNWIND_IS_BAREMETAL)
# Can't use add_definitions because CMake will reorder these arguments
list(APPEND LIBUNWIND_COMPILE_FLAGS -U_FORTIFY_SOURCE)
list(APPEND LIBUNWIND_COMPILE_FLAGS -D_FORTIFY_SOURCE=0)

list(APPEND LIBUNWIND_COMPILE_FLAGS -fno-stack-protector)
list(APPEND LIBUNWIND_COMPILE_FLAGS -ffreestanding)
list(APPEND LIBUNWIND_COMPILE_FLAGS -fexceptions)
# Avoid too new relocation types being emitted, which might prevent linking
# on older platforms.
#
# See https://github.com/rust-lang/rust/issues/34978
list(APPEND LIBUNWIND_COMPILE_FLAGS -Wa,-mrelax-relocations=no)

# Sources
list(APPEND LIBUNWIND_C_SOURCES UnwindRustSgx.c)
list(APPEND LIBUNWIND_C_SOURCES UnwindRustSgxSnprintf.c)
endif()


set_source_files_properties(${LIBUNWIND_C_SOURCES}
PROPERTIES
COMPILE_FLAGS "-std=c99")
set_source_files_properties(${LIBUNWIND_ASM_SOURCES}
PROPERTIES
LANGUAGE C)

set(LIBUNWIND_SOURCES
${LIBUNWIND_CXX_SOURCES}
${LIBUNWIND_C_SOURCES}
Expand All @@ -53,7 +80,7 @@ set(LIBUNWIND_SOURCES
set(libraries ${LIBUNWINDCXX_ABI_LIBRARIES})
append_if(libraries LIBUNWIND_HAS_C_LIB c)
append_if(libraries LIBUNWIND_HAS_DL_LIB dl)
if (LIBUNWIND_ENABLE_THREADS)
if (LIBUNWIND_ENABLE_THREADS AND (NOT RUST_SGX))
append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread)
endif()

Expand Down
2 changes: 1 addition & 1 deletion libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef _LIBUNWIND_HAS_NO_THREADS
#if !defined(_LIBUNWIND_HAS_NO_THREADS) && !defined(RUST_SGX)
#include <pthread.h>
#endif
#include <unwind.h>
Expand Down
2 changes: 2 additions & 0 deletions libunwind/src/UnwindLevel1-gcc-ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
//
//===----------------------------------------------------------------------===//

#pragma GCC diagnostic ignored "-Wstrict-aliasing"

#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
Expand Down
3 changes: 3 additions & 0 deletions libunwind/src/UnwindLevel1.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
// to export these functions from libunwind.so as well.
#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1

#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wempty-body"

#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
Expand Down
173 changes: 173 additions & 0 deletions libunwind/src/UnwindRustSgx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
//===--------------------- UnwindRustSgx.c ----------------------------------===//
//
//// 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.
////
////
////===----------------------------------------------------------------------===//

#define _GNU_SOURCE
#include <link.h>

#include <elf.h>
#include <stdarg.h>
#include <stdio.h>
#include <stddef.h>
#include "UnwindRustSgx.h"


#define max_log 256


__attribute__((weak)) struct _IO_FILE *stderr = (_IO_FILE *)-1;

static int vwrite_err(const char *format, va_list ap)
{
char s[max_log];
int len = 0;
s[0]='\0';
len = vsnprintf(s, max_log, format, ap);
__rust_print_err((uint8_t *)s, len);
return len;
}

static int write_err(const char *format, ...)
{
int ret;
va_list args;
va_start(args, format);
ret = vwrite_err(format, args);
va_end(args);


return ret;
}

__attribute__((weak)) int fprintf (FILE *__restrict __stream,
const char *__restrict __format, ...)
{

int ret;
if (__stream != stderr) {
write_err("Rust SGX Unwind supports only writing to stderr\n");
return -1;
} else {
va_list args;
ret = 0;
va_start(args, __format);
ret += vwrite_err(__format, args);
va_end(args);
}

return ret;
}

__attribute__((weak)) int fflush (FILE *__stream)
{
// We do not need to do anything here.
return 0;
}




__attribute__((weak)) void __assert_fail(const char * assertion,
const char * file,
unsigned int line,
const char * function)
{
write_err("%s:%d %s %s\n", file, line, function, assertion);
abort();
}



// We do not report stack over flow detected.
// Calling write_err uses more stack due to the way we have implemented it.
// With possible enabling of stack probes, we should not
// get into __stack_chk_fail() at all.
__attribute__((weak)) void __stack_chk_fail() {
abort();
}

/*
* Below are defined for all executibles compiled for
* x86_64-fortanix-unknown-sgx rust target.
* Ref: rust/src/libstd/sys/sgx/abi/entry.S
*/

extern uint64_t TEXT_BASE;
extern uint64_t TEXT_SIZE;
extern uint64_t EH_FRM_HDR_BASE;
extern uint64_t EH_FRM_HDR_SIZE;
extern char IMAGE_BASE;

typedef Elf64_Phdr Elf_Phdr;
int
dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
size_t, void *),
void *data)
{
struct dl_phdr_info info;
struct dl_phdr_info *pinfo = &info;
Elf_Phdr phdr[2];
int ret = 0;


size_t text_size = TEXT_SIZE;
size_t eh_base_size = EH_FRM_HDR_SIZE;

memset(pinfo, 0, sizeof(*pinfo));

pinfo->dlpi_addr = (ElfW(Addr))&IMAGE_BASE;
pinfo->dlpi_phnum = 2;

pinfo->dlpi_phdr = phdr;
memset(phdr, 0, 2*sizeof(*phdr));


phdr[0].p_type = PT_LOAD;
phdr[0].p_vaddr = (size_t)TEXT_BASE;
phdr[0].p_memsz = text_size;

phdr[1].p_type = PT_GNU_EH_FRAME;
phdr[1].p_vaddr = (size_t)EH_FRM_HDR_BASE;
phdr[1].p_memsz = eh_base_size;


ret = callback (&info, sizeof (struct dl_phdr_info), data);
return ret;
}

struct libwu_rs_alloc_meta {
size_t alloc_size;
// Should we put a signatre guard before ptr for oob access?
unsigned char ptr[0];
};

#define META_FROM_PTR(__PTR) (struct libwu_rs_alloc_meta *) \
((unsigned char *)__PTR - offsetof(struct libwu_rs_alloc_meta, ptr))

void *libuw_malloc(size_t size)
{
struct libwu_rs_alloc_meta *meta;
size_t alloc_size = size + sizeof(struct libwu_rs_alloc_meta);
meta = (void *)__rust_c_alloc(alloc_size, sizeof(size_t));
if (!meta) {
return NULL;
}
meta->alloc_size = alloc_size;
return (void *)meta->ptr;
}

void libuw_free(void *p)
{
struct libwu_rs_alloc_meta *meta;
if (!p) {
return;
}
meta = META_FROM_PTR(p);
__rust_c_dealloc((unsigned char *)meta, meta->alloc_size, sizeof(size_t));
}
Loading