diff --git a/src/libos/Makefile b/src/libos/Makefile index 6d69932e..6b1ffe77 100644 --- a/src/libos/Makefile +++ b/src/libos/Makefile @@ -63,7 +63,7 @@ EDL_C_SRCS := $(addprefix $(BUILD_DIR)/src/libos/,src/Enclave_t.c src/Enclave_t. EDL_C_OBJS := $(addprefix $(BUILD_DIR)/src/libos/,src/Enclave_t.o) BUILTIN_C_SRCS := $(sort $(wildcard src/builtin/*.c)) BUILTIN_C_OBJS := $(addprefix $(BUILD_DIR)/src/libos/,$(BUILTIN_C_SRCS:.c=.o)) -C_SRCS := $(filter-out $(BUILTIN_C_SRCS),$(sort $(wildcard src/*.c src/*/*.c))) +C_SRCS := $(filter-out $(BUILTIN_C_SRCS),$(sort $(wildcard src/*.c src/*/*.c src/*/*/*.c))) C_OBJS := $(addprefix $(BUILD_DIR)/src/libos/,$(C_SRCS:.c=.o)) CXX_SRCS := $(sort $(wildcard src/*.cpp src/*/*.cpp)) CXX_OBJS := $(addprefix $(BUILD_DIR)/src/libos/,$(CXX_SRCS:.cpp=.o)) @@ -73,6 +73,8 @@ S_OBJS := $(addprefix $(BUILD_DIR)/src/libos/,$(S_SRCS:.S=.o)) ALL_BUILD_SUBDIRS := $(sort $(patsubst %/,%,$(dir $(LIBOS_SO) $(EDL_C_OBJS) $(BUILTIN_C_OBJS) $(C_OBJS) $(CXX_OBJS) $(S_OBJS)) $(RUST_TARGET_DIR) $(RUST_OUT_DIR))) C_COMMON_FLAGS := -fno-stack-protector -I./include/ +# SGX GDB support +C_COMMON_FLAGS += -g C_FLAGS := $(SGX_CFLAGS_T) $(C_COMMON_FLAGS) CXX_FLAGS := $(SGX_CXXFLAGS_T) $(C_COMMON_FLAGS) diff --git a/src/libos/src/process/spawn/gdb_hook_load_elf.c b/src/libos/src/process/spawn/gdb_hook_load_elf.c new file mode 100644 index 00000000..95777038 --- /dev/null +++ b/src/libos/src/process/spawn/gdb_hook_load_elf.c @@ -0,0 +1,21 @@ +#include + +/* + * Providing debug symbol information to GDB. + * + * This function is left empty deliberately and should NOT be removed. + * + * When SGX GDB is attached to the enclave, a break point will be inserted at the beginning + * of this function. So when this function is called at runtime, GDB can capture the arguments + * of this function, which gives the name of a loaded ELF file and the memory location where + * the ELF is loaded in the enclave. With this information, GDB can translate memory addresses + * to symbol names, thus give meaningful debug information. + * + * `__attribute__((optimize("O0")))` is used to prevent the compiler from optimizing this function in + * unexpected way (e.g., eliminating this empty function). + */ +void __attribute__((optimize("O0"))) occlum_gdb_hook_load_elf( + uint64_t elf_base, + const char* elf_path, + uint64_t elf_path_len) { +} diff --git a/src/libos/src/process/spawn/mod.rs b/src/libos/src/process/spawn/mod.rs index 2aad2736..d24c0772 100644 --- a/src/libos/src/process/spawn/mod.rs +++ b/src/libos/src/process/spawn/mod.rs @@ -41,10 +41,6 @@ pub fn do_spawn_without_exec( Ok(new_tid) } -// This function is used to provide information to debugger, so it is empty. Please do not remove it. -#[no_mangle] -pub extern "C" fn occlum_gdb_hook_load_elf(elf_base: u64, elf_path: &str, elf_path_len: usize) {} - fn new_process( elf_path: &str, argv: &[CString], @@ -70,9 +66,21 @@ fn new_process( // Notify debugger to load the symbols from elf file let ldso_elf_base = vm.get_elf_ranges()[1].start() as u64; - occlum_gdb_hook_load_elf(ldso_elf_base, ldso_path, ldso_path.len()); + unsafe { + occlum_gdb_hook_load_elf( + ldso_elf_base, + ldso_path.as_ptr() as *const u8, + ldso_path.len() as u64, + ); + } let exec_elf_base = vm.get_elf_ranges()[0].start() as u64; - occlum_gdb_hook_load_elf(exec_elf_base, elf_path, elf_path.len()); + unsafe { + occlum_gdb_hook_load_elf( + exec_elf_base, + elf_path.as_ptr() as *const u8, + elf_path.len() as u64, + ); + } let task = { let ldso_entry = { @@ -227,4 +235,5 @@ fn parent_adopts_new_child(parent_ref: &ProcessRef, child_ref: &ProcessRef) { extern "C" { fn __occlum_syscall(num: i32, arg0: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64) -> i64; + fn occlum_gdb_hook_load_elf(elf_base: u64, elf_path: *const u8, elf_path_len: u64); }