Initial release of Intel SGX for Linux.

This release is used in conjunction with the linux-sgx-driver Intial release:
https://github.com/01org/linux-sgx-driver
commit-id: 0e865ce5e6b297a787bcdc12d98bada8174be6d7

Intel-id: 33399

Signed-off-by: Angie Chinchilla <angie.v.chinchilla@intel.com>
This commit is contained in:
Angie Chinchilla
2016-06-23 18:51:53 -04:00
parent ba82cfcbb0
commit 9441de4c38
2767 changed files with 820699 additions and 0 deletions

91
sdk/trts/linux/Makefile Normal file
View File

@ -0,0 +1,91 @@
#
# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
include ../../../buildenv.mk
CFLAGS += -Werror $(ENCLAVE_CFLAGS) \
-I$(LINUX_SDK_DIR)/trts \
-I$(COMMON_DIR)/inc \
-I$(COMMON_DIR)/inc/internal \
-I$(COMMON_DIR)/inc/internal/linux \
-I$(LINUX_SDK_DIR)/simulation/assembly/
CXXFLAGS += -Werror $(ENCLAVE_CXXFLAGS) \
-I$(LINUX_SDK_DIR)/trts \
-I$(COMMON_DIR)/inc \
-I$(COMMON_DIR)/inc/internal/
TCFLAGS += -nostdinc \
-I$(COMMON_DIR)/inc/tlibc/
LDCFLAGS := -shared -nostdlib -nodefaultlibs -nostartfiles
CPP_SRCS := $(wildcard ../*.cpp)
C_SRCS := $(wildcard *.c)
ASM_SRCS := $(wildcard *.S)
OBJS := $(CPP_SRCS:.cpp=.o)
OBJS += $(C_SRCS:.c=.o)
OBJS += $(ASM_SRCS:.S=.o)
LIBTRTS = libsgx_trts.a
.PHONY: all
all: $(LIBTRTS) | $(BUILD_DIR)
$(CP) $(LIBTRTS) $|
$(LIBTRTS): $(OBJS) setcontext.o
$(AR) rsD $@ $(OBJS)
$(AR) rsD $@ $(ARCH)/setcontext.o
%.o: %.S
$(CC) $(CFLAGS) $(TCFLAGS) -c $< -o $@
%.o: %.c
$(CC) $(CFLAGS) $(TCFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(TCFLAGS) -c $< -o $@
$(BUILD_DIR):
@$(MKDIR) $@
.PHONY: setcontext.o
setcontext.o:
$(MAKE) -C $(ARCH)
.PHONY: clean
clean:
@$(RM) $(OBJS) $(LIBTRTS) $(BUILD_DIR)/$(LIBTRTS)
$(MAKE) -C $(ARCH) clean
.PHONY: rebuild
rebuild: clean all

419
sdk/trts/linux/elf_parser.c Normal file
View File

@ -0,0 +1,419 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* This file is part of trusted loader for tRTS.
*/
#include "elf_parser.h"
#include "rts.h"
#include "util.h"
#include "elf_util.h"
#include "global_data.h"
static int elf_tls_aligned_virtual_size(const void *enclave_base,
size_t *aligned_virtual_size);
static ElfW(Phdr)* get_phdr(const ElfW(Ehdr)* ehdr)
{
if (ehdr == NULL)
return NULL; /* Invalid image. */
/* Check the ElfW Magic number. */
if ((ehdr->e_ident[EI_MAG0] != ELFMAG0) ||
(ehdr->e_ident[EI_MAG1] != ELFMAG1) ||
(ehdr->e_ident[EI_MAG2] != ELFMAG2) ||
(ehdr->e_ident[EI_MAG3] != ELFMAG3))
return NULL;
/* Enclave image should be a shared object file. */
if (ehdr->e_type != ET_DYN)
return NULL;
return GET_PTR(ElfW(Phdr), ehdr, ehdr->e_phoff);
}
static ElfW(Sym)* get_sym(ElfW(Sym)* symtab, size_t idx)
{
if(STB_WEAK == ELFW(ST_BIND)(symtab[idx].st_info)
&& 0 == symtab[idx].st_value)
{
return NULL;
}
return &symtab[idx];
}
#ifdef __x86_64__
/* Relocation for x64 (with addend) */
static int do_relocs(const ElfW(Addr) enclave_base,
ElfW(Addr) rela_offset,
ElfW(Addr) sym_offset,
size_t nr_relocs)
{
ElfW(Rela)* rela = GET_PTR(ElfW(Rela), enclave_base, rela_offset);
ElfW(Sym)* symtab = GET_PTR(ElfW(Sym), enclave_base, sym_offset);
ElfW(Sym)* sym;
size_t i;
size_t aligned_virtual_size = 0;
for (i = 0; i < nr_relocs; ++i, ++rela)
{
ElfW(Addr)* reloc_addr = GET_PTR(ElfW(Addr), enclave_base, rela->r_offset);
switch (ELF64_R_TYPE(rela->r_info))
{
case R_X86_64_RELATIVE:
*reloc_addr = enclave_base + (uintptr_t)rela->r_addend;
break;
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
case R_X86_64_64:
sym = get_sym(symtab, ELF64_R_SYM(rela->r_info));
if(!sym)
break;
*reloc_addr = enclave_base + sym->st_value + (uintptr_t)rela->r_addend;
break;
case R_X86_64_DTPMOD64:
*reloc_addr = 1;
break;
case R_X86_64_DTPOFF64:
sym = get_sym(symtab, ELF64_R_SYM(rela->r_info));
if(!sym)
break;
*reloc_addr = sym->st_value + (uintptr_t)rela->r_addend;
break;
case R_X86_64_TPOFF64:
sym = get_sym(symtab, ELF64_R_SYM(rela->r_info));
if(!sym)
break;
if ((0 == elf_tls_aligned_virtual_size((void *)enclave_base, &aligned_virtual_size)) && (aligned_virtual_size))
{
*reloc_addr = sym->st_value + (uintptr_t)rela->r_addend - aligned_virtual_size;
break;
}
else
return -1;
case R_X86_64_NONE:
break;
default: /* unsupported relocs */
return -1;
}
}
return 0;
}
#elif defined(__i386__)
/* Relocation for x86 (without addend) */
static int do_relocs(const ElfW(Addr) enclave_base,
ElfW(Addr) rel_offset,
ElfW(Addr) sym_offset,
size_t nr_relocs)
{
ElfW(Rel)* rel = GET_PTR(ElfW(Rel), enclave_base, rel_offset);
ElfW(Sym)* symtab = GET_PTR(ElfW(Sym), enclave_base, sym_offset);
ElfW(Sym)* sym = NULL;
size_t i;
size_t aligned_virtual_size = 0;
for (i = 0; i < nr_relocs; ++i, ++rel)
{
ElfW(Addr)* reloc_addr = GET_PTR(ElfW(Addr), enclave_base, rel->r_offset);
if(R_386_RELATIVE == ELF32_R_TYPE(rel->r_info))
{
*reloc_addr += enclave_base; /* B+A */
continue;
}
sym = get_sym(symtab, ELF32_R_SYM(rel->r_info));
if(!sym) /* when the weak symbol is not implemented, sym is NULL */
continue;
switch (ELF32_R_TYPE(rel->r_info))
{
case R_386_GLOB_DAT:
case R_386_JMP_SLOT: /* S */
*reloc_addr = enclave_base + sym->st_value;
break;
case R_386_32: /* S+A */
*reloc_addr += enclave_base + sym->st_value;
break;
case R_386_PC32: /* S+A-P */
*reloc_addr += (enclave_base + sym->st_value - (ElfW(Addr))reloc_addr);
break;
case R_386_NONE:
break;
case R_386_TLS_DTPMOD32:
*reloc_addr = 1;
break;
case R_386_TLS_DTPOFF32:
*reloc_addr = sym->st_value;
break;
case R_386_TLS_TPOFF:
if ((0 == elf_tls_aligned_virtual_size((void *)enclave_base, &aligned_virtual_size)) && (aligned_virtual_size))
{
*reloc_addr += sym->st_value - aligned_virtual_size;
break;
}
else
return -1;
case R_386_TLS_TPOFF32:
if ((0 == elf_tls_aligned_virtual_size((void *)enclave_base, &aligned_virtual_size)) && (aligned_virtual_size))
{
*reloc_addr += aligned_virtual_size - sym->st_value;
break;
}
else
return -1;
default: /* unsupported relocs */
return -1;
}
}
return 0;
}
#endif
#define DO_REL(base_addr, rel_offset, sym_offset, total_sz, rel_entry_sz) \
do { \
if (rel_offset) \
{ \
size_t n; \
if (rel_entry_sz == 0) \
return -1; \
n = total_sz/rel_entry_sz; \
if (do_relocs((ElfW(Addr))enclave_base, rel_offset, sym_offset, n)) \
return -1; \
} \
} while (0)
/* By default all symbol is linked as global symbol by link editor. When call global symbol,
* we first call .plt entry. It should have problems if the call goloal symbol when relocation
* is not done.
* Declare relocate_enclave as .hidden is to make it local symbol.
* Since this function is called before relocation is done, we must make
* it local symbol, so the code is like "fce3: e8 98 12 00 00 call 10f80 <relocate_enclave>"
* 0x9812=0x10f80-0xfce8
*/
__attribute__ ((visibility ("hidden")))
int relocate_enclave(void* enclave_base)
{
ElfW(Half) phnum = 0;
ElfW(Ehdr) *ehdr = (ElfW(Ehdr)*)enclave_base;
ElfW(Phdr) *phdr = get_phdr(ehdr);
if (phdr == NULL)
return -1; /* Invalid image. */
for (; phnum < ehdr->e_phnum; phnum++, phdr++)
{
/* Search for dynamic segment */
if (phdr->p_type == PT_DYNAMIC)
{
size_t count;
size_t n_dyn = phdr->p_filesz/sizeof(ElfW(Dyn));
ElfW(Dyn) *dyn = GET_PTR(ElfW(Dyn), ehdr, phdr->p_paddr);
ElfW(Addr) sym_offset = 0;
ElfW(Addr) rel_offset = 0;
ElfW(Addr) plt_offset = 0;
size_t rel_total_sz = 0;
size_t rel_entry_sz = 0;
size_t plt_total_sz = 0;
for (count = 0; count < n_dyn; count++, dyn++)
{
if (dyn->d_tag == DT_NULL) /* End */
break;
switch (dyn->d_tag)
{
case DT_SYMTAB: /* symbol table */
sym_offset = dyn->d_un.d_ptr;
break;
case RTS_DT_REL:/* Rel (x86) or Rela (x64) relocs */
rel_offset = dyn->d_un.d_ptr;
break;
case RTS_DT_RELSZ:
rel_total_sz = dyn->d_un.d_val;
break;
case RTS_DT_RELENT:
rel_entry_sz = dyn->d_un.d_val;
break;
case DT_JMPREL: /* PLT relocs */
plt_offset = dyn->d_un.d_ptr;
break;
case DT_PLTRELSZ:
plt_total_sz = dyn->d_un.d_val;
break;
}
}
DO_REL(enclave_base, rel_offset, sym_offset, rel_total_sz, rel_entry_sz);
DO_REL(enclave_base, plt_offset, sym_offset, plt_total_sz, rel_entry_sz);
}
}
return 0;
}
int elf_tls_info(const void* enclave_base,
uintptr_t *tls_addr, size_t *tdata_size)
{
ElfW(Half) phnum = 0;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr)*)enclave_base;
ElfW(Phdr) *phdr = get_phdr(ehdr);
if (!tls_addr || !tdata_size)
return -1;
if (phdr == NULL)
return -1; /* Invalid image. */
/* Search for TLS segment */
*tls_addr = 0;
*tdata_size = 0;
for (; phnum < ehdr->e_phnum; phnum++, phdr++)
{
if (phdr->p_type == PT_TLS)
{
/* tls_addr here is got from the program header, the address
* need to be added by the enclave base.
*/
*tls_addr = (size_t)enclave_base + phdr->p_vaddr;
*tdata_size = phdr->p_filesz;
break;
}
}
return 0;
}
static int elf_tls_aligned_virtual_size(const void *enclave_base,
size_t *aligned_virtual_size)
{
ElfW(Half) phnum = 0;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr)*)enclave_base;
ElfW(Phdr) *phdr = get_phdr(ehdr);
size_t virtual_size =0, align = 0;
if (phdr == NULL)
return -1;
if (!aligned_virtual_size)
return -1;
*aligned_virtual_size = 0;
for (; phnum < ehdr->e_phnum; phnum++, phdr++)
{
if (phdr->p_type == PT_TLS)
{
virtual_size = phdr->p_memsz;
align = phdr->p_align;
/* p_align == 0 or p_align == 1 means no alignment is required */
if (align == 0 || align == 1)
*aligned_virtual_size = virtual_size;
else
*aligned_virtual_size = (virtual_size + align - 1) & (~(align - 1));
break;
}
}
return 0;
}
int elf_get_init_array(const void* enclave_base,
uintptr_t *init_array_addr, size_t *init_array_size)
{
ElfW(Half) phnum = 0;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr)*)enclave_base;
ElfW(Phdr) *phdr = get_phdr(ehdr);
if (!init_array_addr || !init_array_size)
return -1;
if (phdr == NULL)
return -1; /* Invalid image. */
*init_array_addr = 0;
*init_array_size = 0;
/* Search for Dynamic segment */
for (; phnum < ehdr->e_phnum; phnum++, phdr++)
{
if (phdr->p_type == PT_DYNAMIC)
{
size_t count;
size_t n_dyn = phdr->p_filesz/sizeof(ElfW(Dyn));
ElfW(Dyn) *dyn = GET_PTR(ElfW(Dyn), ehdr, phdr->p_paddr);
for (count = 0; count < n_dyn; count++, dyn++)
{
switch (dyn->d_tag)
{
case DT_INIT_ARRAY:
*init_array_addr = dyn->d_un.d_ptr;
break;
case DT_INIT_ARRAYSZ:
*init_array_size = dyn->d_un.d_val;
break;
}
}
}
}
return 0;
}
/* vim: set ts=4 sw=4 et cin: */

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* File: elf_parser.h
* Description:
* Header file for tRTS ELF parser.
*/
#ifndef _PE_PARSER_H_
#define _PE_PARSER_H_
#include "se_types.h"
#ifdef __cplusplus
extern "C" {
#endif
int relocate_enclave(void* enclave_base);
int elf_tls_info(const void* enclave_base,
uintptr_t *tls_addr, size_t *tdata_size);
int elf_get_init_array(const void* enclave_base,
uintptr_t *init_array_addr, size_t *init_array_size);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "internal/global_init.h"
#include "linux/elf_parser.h"
#include "global_data.h"
#include "internal/util.h"
#include "thread_data.h"
#include "sgx_trts.h"
#include <assert.h>
#include <stdlib.h>
typedef void (*fp_t)(void);
/* required by global constructor when -fuse-cxa-atexit is enabled */
void *__dso_handle __attribute__((weak)) = &(__dso_handle);
int __cxa_atexit(void (*fun)(void *), void *para, void *dso)
{
(void)(fun);
(void)(para);
(void)(dso);
return 0;
}
/* auxiliary routines */
static void do_ctors_aux(void)
{
/* SGX RTS does not support .ctors currently */
fp_t *p = NULL;
uintptr_t init_array_addr;
size_t init_array_size;
const void *enclave_start = (const void*)&__ImageBase;
elf_get_init_array(enclave_start, &init_array_addr, &init_array_size);
if (init_array_addr == 0 || init_array_size == 0)
return;
fp_t *fp_start = (fp_t*)(init_array_addr + (uintptr_t)(enclave_start));
fp_t *fp_end = fp_start + (init_array_size / sizeof(fp_t));
/* traverse .init_array in forward order */
for (p = fp_start; p < fp_end; p++)
{
(*p)();
}
}
void init_global_object(void)
{
do_ctors_aux();
}
void init_stack_guard(void)
{
thread_data_t *thread_data = get_thread_data();
assert(thread_data != NULL);
if (SGX_SUCCESS != sgx_read_rand(
(unsigned char*)&thread_data->stack_guard,
sizeof(thread_data->stack_guard)))
abort();
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
.file "metadata_sec.S"
#define METADATA_SIZE 4096
.section ".note.sgxmeta", "", @note
.p2align 0 /* section no alignment */
.long 1f - 0f /* name size (not including padding) */
.long 2f - 1f /* desc size (not including padding) */
.long 0x01 /* type */
0: .asciz "sgx_metadata" /* name */
1: .fill METADATA_SIZE, 1, 0 /* desc - stand for metadata which is initialized with 0 */
2: .p2align 0

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* File: tls_support.c
* Description:
* TLS support in the enclave.
*/
#include "thread_data.h"
typedef struct
{
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
#if defined SE_GNU32
void * __attribute__((__regparm__(1))) ___tls_get_addr(tls_index *ti)
#elif defined SE_GNU64
void *__tls_get_addr(tls_index *ti)
#endif
{
thread_data_t *thread_data = get_thread_data();
return (unsigned char *)thread_data->tls_addr + ti->ti_offset;
}

494
sdk/trts/linux/trts_pic.S Normal file
View File

@ -0,0 +1,494 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* Description:
* The file provides `enclave_entry' function to switch code between
* trusted and untrusted envronment.
*/
.file "trts_pic.S"
#include "trts_pic.h"
.text
DECLARE_LOCAL_FUNC get_enclave_base
lea_pic __ImageBase, %xax
ret
DECLARE_LOCAL_FUNC get_enclave_state
lea_pic g_enclave_state, %xcx
xor %xax, %xax
movl (%xcx), %eax
ret
DECLARE_LOCAL_FUNC set_enclave_state
lea_pic g_enclave_state, %xax
#ifdef LINUX32
mov SE_WORDSIZE(%esp), %edi
#endif
movl %edi, (%xax)
ret
DECLARE_LOCAL_FUNC lock_enclave
lea_pic g_enclave_state, %xdx
xor %xax, %xax
mov $ENCLAVE_INIT_NOT_STARTED, %eax
xor %xcx, %xcx
mov $ENCLAVE_INIT_IN_PROGRESS, %ecx /* if (g_global_data.enclave_state == ENCLAVE_INIT_NOT_STARTED) */
lock cmpxchgl %ecx, (%xdx) /* g_global_data.enclave_state == ENCLAVE_INIT_IN_PROGRESS */
ret /* xax: the initial value of enclave state */
/*
* ---------------------------------------------------------------------
* Function: thread_data_t* get_thread_data(void);
*
* Get the address of thread_data
* ---------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC get_thread_data
READ_TD_DATA self_addr
ret
/*
* ---------------------------------------------------------------------
* Function: enclave_entry
* The entry point of the enclave.
*
* Registers:
* XAX - TCS.CSSA
* XBX - the address of a TCS
* XCX - the address of the instruction following the EENTER
* XDI - the reason of entering the enclave
* XSI - the pointer to the marshalling structure
*/
DECLARE_GLOBAL_FUNC enclave_entry
/*
* ----------------------------------------------------------------------
* Dispatch code according to CSSA and the reason of EENTER
* eax > 0 - exception handler
* edi >= 0 - ecall
* edi == -1 - do_init_enclave
* edi == -2 - oret
* Registers
* No need to use any register during the dipatch
* ----------------------------------------------------------------------
*/
.cfi_startproc
cmp $0, %xax
jne .Ldo_handler /* handle exception state */
xor %xdx, %xdx
READ_TD_DATA last_sp
cmp $0, %xax
jne .Lswitch_stack
GET_STACK_BASE %xbx /* if last_sp == 0, set sp to stack base */
sub $STATIC_STACK_SIZE, %xax /* give space for static stack */
.Lswitch_stack:
xchg %xsp, %xax
push %xcx
push %xbp
.cfi_def_cfa_offset 2 * SE_WORDSIZE
.cfi_offset xbp, -2 * SE_WORDSIZE
mov %xsp, %xbp
.cfi_def_cfa_register xbp
/* Save the registers */
sub $(6*SE_WORDSIZE), %xsp
mov %xax, -1*SE_WORDSIZE(%xbp) /* xsp_u */
mov %xdx, -3*SE_WORDSIZE(%xbp) /* cssa */
mov %xbx, -4*SE_WORDSIZE(%xbp) /* TCS */
mov %xsi, -5*SE_WORDSIZE(%xbp) /* XSI */
mov %xdi, -6*SE_WORDSIZE(%xbp) /* XDI */
#ifdef LINUX64
mov %rdx, %rcx
mov %rbx, %rdx
#endif
call enter_enclave
.Lexit_enclave:
mov -1*SE_WORDSIZE(%xbp), %xdx /* xdx: xsp_u */
mov %xbp, %xsp
pop %xbp /* xbp_u */
pop %xbx /* ret_u */
mov %xdx, %xsp /* xsp_u */
mov $OCMD_ERET, %xdi
mov %xax, %xsi
.Lclear_and_exit_enclave:
/* Clear all GPRs, except xax, xbx, xdi and xsi */
xor %xcx, %xcx
xor %xdx, %xdx
#if defined(LINUX64)
xor %r8, %r8
xor %r9, %r9
xor %r10, %r10
xor %r11, %r11
xor %r12, %r12
xor %r13, %r13
xor %r14, %r14
xor %r15, %r15
#endif
/* Set status flags to pre-defined values */
add %xdx, %xdx /* OF = SF = AF = CF = 0; ZF = PF = 1 */
/* EEXIT */
mov $SE_EEXIT, %xax /* EEXIT leaf */
ENCLU
/* Should not come here */
ud2
.Ldo_handler:
mov %xax, %xdx /* XDX: cssa */
GET_STACK_BASE %xbx /* XAX: static stack, set sp to stack base */
jmp .Lswitch_stack
/* Should not come here */
ud2
.cfi_endproc
/*
* -------------------------------------------------------------------------
* sgx_status_t do_ocall(unsigned int index, void *ms);
*
* Function: do_ocall
* The entry point of the enclave
* Parameters:
* func_addr - target function address
* ms - marshalling structure
*
* Stack: (same as do_oret)
* bottom of stack ->
* -----------------
* | ECALL/OCALL |
* previous TD.last_sp -> | frames |
* -----------------
* | ECALL frame |
* | do_ocall param 2| 21
* | do_ocall param 1| 20
* |do_ocall ret_addr| 19
* | ocall_depth | 18
* | reserved | 17
* | reserved | 16
* | reserved | 15
* | rbx | 14
* | rsi | 13
* | rdi | 12
* | rbp | 11
* | r12 | 10
* | r13 | 9
* | r14 | 8
* | r15 | 7
* | prev TD.last_sp | 6
* | ocall_index | 5
* | OCALL FLAG | 4
* | shadow | 3
* | shadow | 2
* | shadow | 1
* TD.last_sp -> | shadow | 0
* -----------------
* -------------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC do_ocall
/*
* 8 for GPR, 1 for TD.last_sp, 1 for ocall_index
* 1 for OCALL_FLAG, 4 for shadow space.
* Stack Pointer is 16-byte aligned under x86_64.
*/
sub $(19*SE_WORDSIZE), %xsp
/* save non-volatile registers, except xsp */
mov %xbx, SE_WORDSIZE*14(%xsp)
mov %xsi, SE_WORDSIZE*13(%xsp)
mov %xdi, SE_WORDSIZE*12(%xsp)
mov %xbp, SE_WORDSIZE*11(%xsp)
#ifdef LINUX64
mov %r12, SE_WORDSIZE*10(%rsp)
mov %r13, SE_WORDSIZE* 9(%rsp)
mov %r14, SE_WORDSIZE* 8(%rsp)
mov %r15, SE_WORDSIZE* 7(%rsp)
#endif
/* set xdi and xsi using the input parameters */
#ifdef LINUX64
mov %edi, %edi /* it should clear the high 32bit word of RDI */
/*
* rdi - param 1 (index), rsi - param 2 (ms)
* only use lower 32bit of rdi, rsi remains unchanged.
*/
#endif
#ifdef LINUX32
mov SE_WORDSIZE*20(%esp), %edi
mov SE_WORDSIZE*21(%esp), %esi
#endif
/* save ocall index to the stack */
mov $OCALL_FLAG, %xax
mov %xax, SE_WORDSIZE*4(%xsp) /* save OCALL_FLAG */
mov %xdi, SE_WORDSIZE*5(%xsp) /* save ocall_index */
/*
* save the inside stack context
* push TD.last_sp
* set TD.last_sp = xsp
*/
READ_TD_DATA self_addr
mov %xax, %xbx
/* call update_ocall_lastsp */
#ifdef LINUX32
mov %xsp, (%xsp)
#else
mov %xsp, %xdi
#endif
call update_ocall_lastsp /* xax: td.last_sp */
#ifdef LINUX64
mov SE_WORDSIZE*12(%xsp), %xdi /* restore xdi */
mov SE_WORDSIZE*13(%xsp), %xsi /* restore xdi */
#endif
/* restore outside stack context */
mov first_ssa_gpr(%xbx), %xdx
mov ssa_bp_u(%xdx), %xbp
mov ssa_sp_u(%xdx), %xsp
/*
* set EEXIT registers
* return address can be read from the ECALL frame:
* TD.last_sp ->
* -------------
* | ret_addr |
* | xbp_u |
* | xsp_u |
* | ... |
*/
mov -1*SE_WORDSIZE(%xax), %xbx /* return address */
mov $SE_EEXIT, %xax /* EEXIT leaf */
/* Clear all GPRs, except xax, xbx, xdi, and xsi*/
xor %xcx, %xcx
xor %xdx, %xdx
#ifdef LINUX64
xor %r8, %r8
xor %r9, %r9
xor %r10, %r10
xor %r11, %r11
xor %r12, %r12
xor %r13, %r13
xor %r14, %r14
xor %r15, %r15
#endif
/* Set status flags to pre-defined values */
add %xdx, %xdx /* OF = SF = AF = CF = 0; ZF = PF = 1 */
ENCLU
/*
* ------------------------------------------------------------------
* this function is the wrapper of do_ocall, which is used to
* stick ocall bridge and proxy frame together
* ------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC __morestack
.cfi_startproc
push %xbp
.cfi_def_cfa_offset 2*SE_WORDSIZE
.cfi_offset xbp,-2*SE_WORDSIZE
mov %xsp, %xbp
.cfi_def_cfa_register xbp
sub $(4*SE_WORDSIZE), %xsp
#ifdef LINUX32
/* save the 2 parameters */
mov (2*SE_WORDSIZE)(%xbp), %xax
mov %xax, (0*SE_WORDSIZE)(%xsp)
mov (3*SE_WORDSIZE)(%xbp), %xax
mov %xax, (1*SE_WORDSIZE)(%xsp)
#endif
call do_ocall
leave
ret
.cfi_endproc
DECLARE_GLOBAL_FUNC asm_oret
#ifdef LINUX32
mov SE_WORDSIZE(%xsp), %xdi
mov 2*SE_WORDSIZE(%xsp), %xsi
#endif
mov %xdi, %xsp /* restore thread_data.last_sp */
mov %xsi, %xax /* ocall return value */
#ifdef LINUX64
mov 7*SE_WORDSIZE(%xsp), %r15
mov 8*SE_WORDSIZE(%xsp), %r14
mov 9*SE_WORDSIZE(%xsp), %r13
mov 10*SE_WORDSIZE(%xsp), %r12
#endif
mov 11*SE_WORDSIZE(%xsp), %xbp
mov 12*SE_WORDSIZE(%xsp), %xdi
mov 13*SE_WORDSIZE(%xsp), %xsi
mov 14*SE_WORDSIZE(%xsp), %xbx
add $(19*SE_WORDSIZE), %xsp
ret
/* should not come here */
ud2
/*
* ------------------------------------------------------------------------
* extern "C" int do_egetkey(key_request_t *key_request, key_128bit_t *key)
* return value:
* 0 - success
* none-zeor - EGETKEY error code
* EGETKEY: rbx - the address of KEYREQUEST structure
* rcx - the address where the key is outputted
* ------------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC do_egetkey
SE_PROLOG
mov $SE_EGETKEY, %xax /* EGETKEY leaf */
ENCLU
#ifdef SE_SIM
cmp $SGX_SUCCESS, %xax /* In simulation mode, ZF flag will not be set */
jnz .Legetkey_done /* because the stack clean operation will always clean ZF flag */
#else
jz .Legetkey_done /* if EGETKEY error, ZF flag is set and error code is set to xax */
#endif
xor %xax, %xax
.Legetkey_done:
SE_EPILOG
ret
/*
* -------------------------------------------------------------------------
* extern "C" void do_ereport(sgx_target_info_t *target_info, sgx_report_data_t *report_data, sgx_report_t *report);
* EREPORT: rbx - the address of TARGETINFO;
* rcx - the address of REPORTDATA;
* rdx - the address where REPORT is outputted
* -------------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC do_ereport
SE_PROLOG
mov $SE_EREPORT, %xax /* EREPORT leaf */
ENCLU
SE_EPILOG
ret
#define _RDRAND_RETRY_TIMES 10
/*
* -------------------------------------
* extern "C" uint32_t do_rdrand(uint32_t *rand);
* return value:
* non-zero: rdrand succeeded
* zero: rdrand failed
* -------------------------------------
*/
DECLARE_LOCAL_FUNC do_rdrand
mov $_RDRAND_RETRY_TIMES, %ecx
.Lrdrand_retry:
.byte 0x0F, 0xC7, 0xF0 /* rdrand %eax */
jc .Lrdrand_return
dec %ecx
jnz .Lrdrand_retry
xor %xax, %xax
ret
.Lrdrand_return:
#ifdef LINUX32
mov SE_WORDSIZE(%esp), %ecx
#else
mov %rdi, %rcx
#endif
movl %eax, (%xcx)
mov $1, %xax
ret
/*
* -------------------------------------------------------------------------
* extern "C" void abort(void) __attribute__(__noreturn__);
* -------------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC abort
lea_pic g_enclave_state, %xax
movl $ENCLAVE_CRASHED, (%xax)
ud2
/*
* -------------------------------------------------------------------------
* extern "C" __attribute__((regparm(1))) void continue_execution(sgx_exception_info_t *info);
* -------------------------------------------------------------------------
*/
DECLARE_LOCAL_FUNC continue_execution
#ifdef LINUX32
mov %xax, %xcx
#else
mov %xdi, %xcx
#endif
mov SE_WORDSIZE*4(%xcx), %xdx
mov %xdx, %xsp
sub $(SE_WORDSIZE), %xsp
#ifdef LINUX64
mov SE_WORDSIZE*17(%xcx), %xax
#else
mov SE_WORDSIZE*9(%xcx), %xax
#endif
mov %xax, (%xsp)
mov SE_WORDSIZE*0(%xcx), %xax
mov SE_WORDSIZE*2(%xcx), %xdx
mov SE_WORDSIZE*3(%xcx), %xbx
mov SE_WORDSIZE*5(%xcx), %xbp
mov SE_WORDSIZE*6(%xcx), %xsi
mov SE_WORDSIZE*7(%xcx), %xdi
#ifdef LINUX64
mov SE_WORDSIZE*8(%xcx), %xsi
mov SE_WORDSIZE*9(%xcx), %xsi
mov SE_WORDSIZE*10(%xcx), %xsi
mov SE_WORDSIZE*11(%xcx), %xsi
mov SE_WORDSIZE*12(%xcx), %xsi
mov SE_WORDSIZE*13(%xcx), %xsi
mov SE_WORDSIZE*14(%xcx), %xsi
mov SE_WORDSIZE*15(%xcx), %xsi
push SE_WORDSIZE*16(%xcx)
popf
#else
push SE_WORDSIZE*8(%xcx)
popf
#endif
mov SE_WORDSIZE*1(%xcx), %xcx
ret

113
sdk/trts/linux/trts_pic.h Normal file
View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* This header contains constant definitions for tRTS.
*/
#ifndef TRTS_PIC_H__
#define TRTS_PIC_H__
#include "linux/linux-regs.h"
#include "rts_cmd.h"
#define SE_GUARD_PAGE_SIZE 0x1000
#define ENCLAVE_INIT_NOT_STARTED 0
#define ENCLAVE_INIT_IN_PROGRESS 1
#define ENCLAVE_INIT_DONE 2
#define ENCLAVE_CRASHED 3
/* Status */
#define SGX_SUCCESS 0
#define SGX_ERROR_UNEXPECTED 0x000000001 // Unexpected error
#define SGX_ERROR_INVALID_FUNCTION 0x000001001 // Invalid ecall/ocall function
#define SGX_ERROR_INVALID_ENCLAVE 0x000002001 // The enclave image is incorrect
#define SGX_ERROR_ENCLAVE_CRASHED 0x000001006 // enclave is crashed
#define SGX_ERROR_STACK_OVERRUN 0x000001009 // enclave is running out of stack
#define STATIC_STACK_SIZE (SE_WORDSIZE * 100)
/* Thread Data
* c.f. data structure defintion for thread_data_t in `rts.h'.
*/
#define last_sp (SE_WORDSIZE * 1)
#define stack_base_addr (SE_WORDSIZE * 2)
#define stack_limit_addr (SE_WORDSIZE * 3)
#define first_ssa_gpr (SE_WORDSIZE * 4)
#define self_addr 0
/* SSA GPR */
#define ssa_sp_t 32
#define ssa_sp_u 144
#define ssa_bp_u 152
#define ssa_exit_info 160
#endif
#define EXIT_INFO_VALID 0x80000000
/* OCALL command */
#define OCALL_FLAG 0x04F434944
#define dtv SE_WORDSIZE
#define tls 0
.macro READ_TD_DATA offset
#ifdef SE_SIM
/* TLS support in simulation mode
* see "sdk/simulation/uinst/linux/set_tls.c"
* and "sdk/simulation/assembly/linux/gnu_tls.h"
* TD address (tcs->ofs_base) is set to tcb_head->dtv->value.
* The offset of tcb_head->dtv->value is SE_WORDSIZE.
*/
#if defined(LINUX32)
mov %gs:dtv, %xax
#elif defined(LINUX64)
mov %fs:dtv, %xax
#endif
mov tls(%xax), %xax
mov \offset(%xax), %xax
#else /* SE_SIM */
#if defined(LINUX32)
mov %fs:\offset, %xax
#elif defined(LINUX64)
mov %gs:\offset, %xax
#endif
#endif /* !SE_SIM */
.endm
.macro GET_STACK_BASE tcs
mov \tcs, %xax
sub $SE_GUARD_PAGE_SIZE, %xax
.endm

View File

@ -0,0 +1,45 @@
#
# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
include ../../../../buildenv.mk
CPPFLAGS += -I$(LINUX_SDK_DIR)/cpprt/linux/libunwind/src/x86
OBJS := setcontext.o
.PHONY: all
all: $(OBJS)
$(OBJS): %.o: %.S
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
.PHONY: clean
clean:
@$(RM) *.o

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "offsets.h"
.global setcontext
.type setcontext, @function
setcontext:
movl 4(%esp),%eax /* ucontext_t* */
/* restore FP state */
movl LINUX_UC_FPREGS_PTR_OFF(%eax), %ecx
fldenv (%ecx)
#ifdef SE_SIM
/* restore FS */
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_FS_OFF)(%eax), %ecx
movl %ecx, %fs
#endif
/* new stack */
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESP_OFF)(%eax), %esp
/* push the return address on the stack */
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EIP_OFF)(%eax), %ecx
pushl %ecx
/* restore GPRs */
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDI_OFF)(%eax), %edi
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ESI_OFF)(%eax), %esi
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBP_OFF)(%eax), %ebp
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EBX_OFF)(%eax), %ebx
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EDX_OFF)(%eax), %edx
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_ECX_OFF)(%eax), %ecx
movl (LINUX_UC_MCONTEXT_OFF+LINUX_SC_EAX_OFF)(%eax), %eax
ret

View File

@ -0,0 +1,46 @@
#
# Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
include ../../../../buildenv.mk
CPPFLAGS += -I$(LINUX_SDK_DIR)/cpprt/linux/libunwind/src/x86_64
CFLAGS += -DISE=1
OBJS := setcontext.o
$(OBJS): %.o: %.S
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
.PHONY: all
all: $(OBJS)
.PHONY: clean
clean:
@$(RM) *.o

View File

@ -0,0 +1,117 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2007 Google, Inc
Contributed by Arun Sharma <arun.sharma@google.com>
Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
This file is part of libunwind.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "ucontext_i.h"
#if (!ISE)
#if defined __linux__
#include <asm/unistd.h>
#define SIG_SETMASK 2
#define SIGSET_BYTE_SIZE (64/8)
#elif defined __FreeBSD__
#include <sys/syscall.h>
#endif
#endif
/* int _Ux86_64_setcontext (const ucontext_t *ucp)
Restores the machine context provided.
Unlike the libc implementation, doesn't clobber %rax
*/
.global _Ux86_64_setcontext
.type _Ux86_64_setcontext, @function
_Ux86_64_setcontext:
#if defined __linux__
#if (!ISE)
/* restore signal mask
sigprocmask(SIG_SETMASK, ucp->uc_sigmask, NULL, sizeof(sigset_t)) */
push %rdi
mov $__NR_rt_sigprocmask, %rax
lea UC_SIGMASK(%rdi), %rsi
mov $SIG_SETMASK, %rdi
xor %rdx, %rdx
mov $SIGSET_BYTE_SIZE, %r10
syscall
pop %rdi
#endif
/* restore fp state */
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
fldenv (%r8)
ldmxcsr FPREGS_OFFSET_MXCSR(%r8)
#elif defined __FreeBSD__
#if (!ISE)
/* restore signal mask */
pushq %rdi
xorl %edx,%edx
leaq UC_SIGMASK(%rdi),%rsi
movl $3,%edi/* SIG_SETMASK */
movl $SYS_sigprocmask,%eax
movq %rcx,%r10
syscall
popq %rdi
#endif
/* restore fp state */
cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
jne 1f
cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
jne 1f
fxrstor UC_MCONTEXT_FPSTATE(%rdi)
1:
#else
#error Port me
#endif
/* restore the rest of the state */
mov UC_MCONTEXT_GREGS_R8(%rdi),%r8
mov UC_MCONTEXT_GREGS_R9(%rdi),%r9
mov UC_MCONTEXT_GREGS_RBX(%rdi),%rbx
mov UC_MCONTEXT_GREGS_RBP(%rdi),%rbp
mov UC_MCONTEXT_GREGS_R12(%rdi),%r12
mov UC_MCONTEXT_GREGS_R13(%rdi),%r13
mov UC_MCONTEXT_GREGS_R14(%rdi),%r14
mov UC_MCONTEXT_GREGS_R15(%rdi),%r15
mov UC_MCONTEXT_GREGS_RSI(%rdi),%rsi
mov UC_MCONTEXT_GREGS_RDX(%rdi),%rdx
mov UC_MCONTEXT_GREGS_RAX(%rdi),%rax
mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx
mov UC_MCONTEXT_GREGS_RSP(%rdi),%rsp
/* push the return address on the stack */
mov UC_MCONTEXT_GREGS_RIP(%rdi),%rcx
push %rcx
mov UC_MCONTEXT_GREGS_RCX(%rdi),%rcx
mov UC_MCONTEXT_GREGS_RDI(%rdi),%rdi
retq
.size _Ux86_64_setcontext, . - _Ux86_64_setcontext
/* We do not need executable stack. */
.section .note.GNU-stack,"",@progbits