From fd157806283bd97a98fdcd89ae3d3a706d4ffa92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kowalczyk?= Date: Sat, 12 Sep 2020 15:52:52 +0200 Subject: [PATCH] [Pal] Rewrite GDB integration, part 1 For now only gdb-script and Python parts. This is mostly a clean-up of both Linux and Linux-SGX integration which additionally removes some annoying user prompts we had in the old scripts. --- .ci/prfilter | 2 +- .ci/run-shellcheck | 1 - Pal/src/Makefile | 13 +--- Pal/src/host/Linux-SGX/Makefile | 18 ++--- Pal/src/host/Linux-SGX/Makefile.am | 1 - Pal/src/host/Linux-SGX/debugger/gdb | 10 --- Pal/src/host/Linux-SGX/debugger/pal-gdb.py | 49 ------------- .../gdb_integration/graphene_sgx.gdb | 63 ++++++++++++++++ .../gdb_integration/graphene_sgx_gdb.py | 71 +++++++++++++++++++ .../{debugger => gdb_integration}/sgx_gdb.c | 6 +- .../{debugger => gdb_integration}/sgx_gdb.h | 0 Pal/src/host/Linux-SGX/sgx_enclave.c | 2 +- Pal/src/host/Linux-SGX/sgx_gdb_info.c | 14 ++++ Pal/src/host/Linux-SGX/sgx_internal.h | 2 +- Pal/src/host/Linux-SGX/sgx_main.c | 2 +- Pal/src/host/Linux-SGX/sgx_rtld.c | 27 ------- Pal/src/host/Linux-SGX/sgx_thread.c | 2 +- Pal/src/host/Linux/Makefile.am | 1 - Pal/src/host/Linux/db_main.c | 9 --- .../host/Linux/gdb_integration/graphene.gdb | 38 ++++++++++ .../Linux/gdb_integration/graphene_gdb.py | 15 ++++ Pal/src/host/Linux/pal-gdb.py | 16 ----- Pal/src/host/Linux/pal.gdb | 27 ------- Pal/src/host/Skeleton/Makefile.am | 1 - Runtime/.gitignore | 1 - Runtime/Makefile | 2 +- Runtime/pal_loader | 34 +++++---- .../Dockerfile.ubuntu18.04.build.template | 8 ++- 28 files changed, 242 insertions(+), 193 deletions(-) delete mode 100755 Pal/src/host/Linux-SGX/debugger/gdb delete mode 100644 Pal/src/host/Linux-SGX/debugger/pal-gdb.py create mode 100644 Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx.gdb create mode 100644 Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx_gdb.py rename Pal/src/host/Linux-SGX/{debugger => gdb_integration}/sgx_gdb.c (99%) rename Pal/src/host/Linux-SGX/{debugger => gdb_integration}/sgx_gdb.h (100%) create mode 100644 Pal/src/host/Linux-SGX/sgx_gdb_info.c delete mode 100644 Pal/src/host/Linux-SGX/sgx_rtld.c create mode 100644 Pal/src/host/Linux/gdb_integration/graphene.gdb create mode 100644 Pal/src/host/Linux/gdb_integration/graphene_gdb.py delete mode 100644 Pal/src/host/Linux/pal-gdb.py delete mode 100644 Pal/src/host/Linux/pal.gdb diff --git a/.ci/prfilter b/.ci/prfilter index 73d4396e..0caa68e3 100755 --- a/.ci/prfilter +++ b/.ci/prfilter @@ -33,7 +33,7 @@ THE_BIG_LIST_OF_NAUGHTY_FILES = list(map(pathlib.Path, [ 'LibOS/shim/test/regression/test_libos.py', 'Pal/regression/test_pal.py', 'Pal/src/host/Linux-SGX/sgx-driver/link-intel-driver.py', - 'Pal/src/host/Linux/pal-gdb.py', + 'Pal/src/host/Linux/gdb_integration/graphene_gdb.py', 'Scripts/regression.py', 'Tools', ])) diff --git a/.ci/run-shellcheck b/.ci/run-shellcheck index a8b4df2c..ee304aef 100755 --- a/.ci/run-shellcheck +++ b/.ci/run-shellcheck @@ -8,7 +8,6 @@ shellcheck "$@" \ Examples/bash/scripts/bash_test.sh \ Examples/common_tools/benchmark-http.sh \ Examples/python-simple/run-tests.sh \ - Pal/src/host/Linux-SGX/debugger/gdb \ Runtime/pal_loader \ Scripts/clean-check \ Scripts/clean-check-prepare \ diff --git a/Pal/src/Makefile b/Pal/src/Makefile index 53e4433b..dbd194da 100644 --- a/Pal/src/Makefile +++ b/Pal/src/Makefile @@ -11,7 +11,6 @@ pal_lib = pal_lib_deps = pal_lib_post = pal_static = -pal_gdb = HOST_DIR = host/$(PAL_HOST) LIB_DIR = $(HOST_DIR)/.lib @@ -63,7 +62,6 @@ host_lib = $(HOST_DIR)/libpal-$(PAL_HOST).a # Install Targets (all in RUNTIME_DIR): # pal-{Host Name}: loader for PAL (as an executable) # libpal-{Host Name}.so: dynamic-linking library -# pal_gdb-{Host Name}: debugger for PAL (as an executable) ifneq ($(pal_loader),) runtime_loader += $(RUNTIME_DIR)/pal-$(PAL_HOST) @@ -73,11 +71,7 @@ ifneq ($(pal_lib),) runtime_lib += $(RUNTIME_DIR)/libpal-$(PAL_HOST)$(suffix $(pal_lib)) endif -ifneq ($(pal_gdb),) - runtime_gdb += $(RUNTIME_DIR)/pal_gdb-$(PAL_HOST) -endif - -files_to_install = $(runtime_loader) $(runtime_lib) $(runtime_sec) $(runtime_gdb) +files_to_install = $(runtime_loader) $(runtime_lib) $(runtime_sec) ########################### @@ -117,11 +111,6 @@ $(runtime_lib): $(pal_lib) $(call cmd,ln_sfr) endif -ifneq ($(pal_gdb),) -$(runtime_gdb): $(pal_gdb) - $(call cmd,ln_sfr) -endif - ifneq ($(pal_lib_post),) $(pal_lib_post): $(pal_lib) @$(MAKE) -C $(HOST_DIR) $@ diff --git a/Pal/src/host/Linux-SGX/Makefile b/Pal/src/host/Linux-SGX/Makefile index 21b18f1e..6a75aa6a 100644 --- a/Pal/src/host/Linux-SGX/Makefile +++ b/Pal/src/host/Linux-SGX/Makefile @@ -23,7 +23,7 @@ ASFLAGS += \ -I../../../include \ -I../../../include/arch/$(ARCH)/Linux -host_files = libpal-Linux-SGX.a pal-sgx debugger/sgx_gdb.so pal.map generated_offsets.py +host_files = libpal-Linux-SGX.a pal-sgx gdb_integration/sgx_gdb.so pal.map generated_offsets.py defs = -DIN_PAL CFLAGS += $(defs) @@ -73,7 +73,7 @@ urts-objs = \ sgx_main.o \ sgx_platform.o \ sgx_process.o \ - sgx_rtld.o \ + sgx_gdb_info.o \ sgx_thread.o \ quote/aesm.pb-c.o \ $(commons_objs_urts) @@ -125,9 +125,9 @@ quote/aesm.pb-c.c quote/aesm.pb-c.h: quote/aesm.proto @echo [ host/Linux-SGX/quote/aesm.pb-c.h ] @protoc-c --c_out=. $< -debugger/sgx_gdb.so: CFLAGS = -CFLAGS-debugger/sgx_gdb.so = -shared -Wall -fPIC -O2 -std=c11 -debugger/sgx_gdb.so: debugger/sgx_gdb.c +gdb_integration/sgx_gdb.so: CFLAGS = +CFLAGS-gdb_integration/sgx_gdb.so = -shared -Wall -fPIC -O2 -std=c11 +gdb_integration/sgx_gdb.so: gdb_integration/sgx_gdb.c $(call cmd,csingle) enclave_entry.o sgx_entry.o: asm-offsets.h @@ -136,7 +136,7 @@ sgx-driver/sgx.h: $(MAKE) -C sgx-driver $(notdir $@) ifeq ($(filter %clean,$(MAKECMDGOALS)),) -include $(wildcard *.d) $(wildcard debugger/*.d) +include $(wildcard *.d) $(wildcard gdb_integration/*.d) endif include ../../../../Scripts/Makefile.rules @@ -146,13 +146,13 @@ tools: $(MAKE) -C tools CLEAN_FILES += $(notdir $(pal_static) $(pal_lib) $(pal_loader)) -CLEAN_FILES += debugger/sgx_gdb.so +CLEAN_FILES += gdb_integration/sgx_gdb.so CLEAN_FILES += quote/aesm.pb-c.c quote/aesm.pb-c.h quote/aesm.pb-c.d quote/aesm.pb-c.o .PHONY: clean_ clean_: - $(RM) -r *.o *.e *.i *.s $(host_files) $(CLEAN_FILES) *.d debugger/*.d signer/*.pyc __pycache__ \ - signer/__pycache__ + $(RM) -r *.o *.e *.i *.s $(host_files) $(CLEAN_FILES) *.d gdb_integration/*.d signer/*.pyc \ + __pycache__ signer/__pycache__ $(RM) -r protected-files/*.o protected-files/*.d .PHONY: clean diff --git a/Pal/src/host/Linux-SGX/Makefile.am b/Pal/src/host/Linux-SGX/Makefile.am index 8dfc6b6c..58eb7c43 100644 --- a/Pal/src/host/Linux-SGX/Makefile.am +++ b/Pal/src/host/Linux-SGX/Makefile.am @@ -18,5 +18,4 @@ pal_loader = $(HOST_DIR)/pal-sgx pal_lib = $(HOST_DIR)/libpal.so pal_lib_deps = pal-symbols $(HOST_DIR)/pal.map.template $(HOST_DIR)/enclave.lds pal_static = $(HOST_DIR)/libpal.a -pal_gdb = $(HOST_DIR)/debugger/gdb pal_signer = pal-sgx-get-token pal-sgx-sign aesm_pb2.py diff --git a/Pal/src/host/Linux-SGX/debugger/gdb b/Pal/src/host/Linux-SGX/debugger/gdb deleted file mode 100755 index 77e6c235..00000000 --- a/Pal/src/host/Linux-SGX/debugger/gdb +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" -GDB_SCRIPT=$DIR/pal-gdb.py -GDB_SO=$DIR/sgx_gdb.so -if [ -z "$INSIDE_EMACS" ]; then - set -x -fi - -LD_PRELOAD=$GDB_SO gdb -iex "add-auto-load-safe-path $GDB_SCRIPT" "$@" diff --git a/Pal/src/host/Linux-SGX/debugger/pal-gdb.py b/Pal/src/host/Linux-SGX/debugger/pal-gdb.py deleted file mode 100644 index 2fef13a4..00000000 --- a/Pal/src/host/Linux-SGX/debugger/pal-gdb.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# pylint: disable=invalid-name - -import gdb # pylint: disable=import-error - -# pylint: enable=invalid-name -# pylint: disable=no-self-use,too-few-public-methods - -class LoadCommandBreakpoint(gdb.Breakpoint): - def __init__(self): - gdb.Breakpoint.__init__(self, spec="load_gdb_command", internal=1) - - def stop(self): - command = gdb.parse_and_eval("(const char *) $rdi").string() - gdb.execute(command) - return False - -def signal_handler(event): - if isinstance(event, gdb.SignalEvent): - if event.stop_signal == 'SIGILL': - # handle CPUINFO and RDTSC - inst = gdb.parse_and_eval("*(const unsigned short *) $rip") - if inst == 0xa20f: - print("CPUID bypassed. Ignore this exception.") - gdb.execute("continue") - return - if inst == 0x310f: - print("RDTSC bypassed. Ignore this exception.") - gdb.execute("continue") - return - -if __name__ == "__main__": - gdb.execute("set env IN_GDB = 1") - gdb.execute("set env LD_PRELOAD = ") - - gdb.execute("handle SIGCONT pass noprint nostop") - gdb.execute("handle SIGKILL pass print stop") - - gdb.execute("set disable-randomization off") - gdb.execute("set detach-on-fork off") - gdb.execute("set schedule-multiple on") - gdb.execute("set follow-exec-mode same") - gdb.execute("set follow-fork-mode child") - - # Need to disable displaced stepping - gdb.execute("set displaced-stepping off") - - LoadCommandBreakpoint() - gdb.events.stop.connect(signal_handler) diff --git a/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx.gdb b/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx.gdb new file mode 100644 index 00000000..e2089a13 --- /dev/null +++ b/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx.gdb @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later */ +# Copyright (C) 2020 Intel Corporation +# Michał Kowalczyk + + +# GDB Python "API" [1] is so wonderful that what we need [2] is not possible to be implemented using +# it, so we have to fall back to raw GDB scripting. But raw GDB scripting is also broken, so we need +# to supply things like `push-pagination` command from Python. +# +# [1] It mostly consists of `gdb.execute()`, there isn't even gdb.continue() API, you need to call +# `gdb.execute('continue')`. +# [2] One of the things we want is to silently pass SIGILLs caused by CPUID and RDTSC to the +# application, but without silencing SIGILLs caused by other reasons. This is impossible to +# implement from GDB Python "API", neither using event handlers nor even executing raw commands +# with gdb.execute() - it doesn't support multiline commands, and gdb.execute('commands') blocks +# for input on the *user terminal*, not giving the script a chance to provide more lines. + + +# Prevent the preloaded sgx_gdb.so from being preloaded to the debuggee. +set env LD_PRELOAD= + +# Tell Graphene to behave more gdb-friendly. +set env IN_GDB=1 + +# Used internally by Graphene, generates a lot of noise if we don't silence it. +handle SIGCONT pass noprint nostop + +# TODO: This block of commands was copied from an older Graphene integration script where they +# didn't have any comments with rationale why they are needed. We should revise and comment them. +handle SIGKILL pass print stop +set disable-randomization off +set detach-on-fork off +set schedule-multiple on +set follow-exec-mode same +set follow-fork-mode child +set displaced-stepping off + + +# CPUID/RDTSC SIGILL skipping. See [2] above. + +catch signal SIGILL + +# break only on CPUID (0fa2) and RDTSC (0f31) +condition $bpnum *(uint16_t*)$rip == 0xa20f || *(uint16_t*)$rip == 0x310f + +commands + silent + + # If we don't disable pagination then successive prints from this handler (even despite it's + # called for different events) will stop and prompt the user for continuation, which is really + # annoying. + push-pagination off + + if *(uint16_t*)$rip == 0xa20f + echo [graphene_sgx.gdb] Passing SIGILL caused by CPUID to the enclave\n + end + if *(uint16_t*)$rip == 0x310f + echo [graphene_sgx.gdb] Passing SIGILL caused by RDTSC to the enclave\n + end + + pop-pagination + continue +end diff --git a/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx_gdb.py b/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx_gdb.py new file mode 100644 index 00000000..8a0f1076 --- /dev/null +++ b/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx_gdb.py @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later */ +# Copyright (C) 2020 Intel Corporation +# Michał Kowalczyk + +import os + +import gdb # pylint: disable=import-error + +# pylint: disable=no-self-use,too-few-public-methods + +_g_paginations = [] + +class PushPagination(gdb.Command): + """Temporarily changing pagination and saving the old state. + + Supplements gdb interface with functionality it's missing and seems to not be possible to + implement from a gdb script. This command is used by graphene_sgx.gdb script. + """ + + def __init__(self): + super(PushPagination, self).__init__("push-pagination", gdb.COMMAND_USER) + + def invoke(self, arg, _from_tty): + self.dont_repeat() + + pagination_str = gdb.execute('show pagination', to_string=True).strip() + assert pagination_str in ('State of pagination is on.', 'State of pagination is off.') + pagination = pagination_str.endswith('on.') + _g_paginations.append(pagination) + + assert arg in ('on', 'off') + gdb.execute('set pagination ' + arg) + + +class PopPagination(gdb.Command): + """Recover pagination state saved by PushPagination""" + + def __init__(self): + super(PopPagination, self).__init__("pop-pagination", gdb.COMMAND_USER) + + def invoke(self, arg, _from_tty): + self.dont_repeat() + + assert arg == '' + pagination = _g_paginations.pop() + gdb.execute('set pagination ' + ('on' if pagination else 'off')) + + +class LoadCommandBreakpoint(gdb.Breakpoint): + def __init__(self): + gdb.Breakpoint.__init__(self, spec="execute_gdb_command", internal=1) + + def stop(self): + command = gdb.parse_and_eval("(const char*)$rdi").string() + gdb.execute(command) + return False + +def main(): + PushPagination() + PopPagination() + + # Some of the things we want to do can't be done using gdb Python API, we need to fall back to a + # standard gdb script. + gdb_script = os.path.dirname(__file__) + "/graphene_sgx.gdb" + print("[%s] Loading %s..." % (os.path.basename(__file__), gdb_script)) + gdb.execute("source " + gdb_script) + + LoadCommandBreakpoint() + +if __name__ == "__main__": + main() diff --git a/Pal/src/host/Linux-SGX/debugger/sgx_gdb.c b/Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.c similarity index 99% rename from Pal/src/host/Linux-SGX/debugger/sgx_gdb.c rename to Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.c index bee5763a..a6211ab1 100644 --- a/Pal/src/host/Linux-SGX/debugger/sgx_gdb.c +++ b/Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.c @@ -333,7 +333,7 @@ static int open_memdevice(pid_t tid, int* memdev, struct enclave_dbginfo** ei) { for (int i = 0; i < g_memdevs_cnt; i++) { if (g_memdevs[i].pid == tid) { *memdev = g_memdevs[i].memdev; - *ei = &g_memdevs[i].ei; + *ei = &g_memdevs[i].ei; return update_thread_tids(*ei); } } @@ -356,7 +356,7 @@ static int open_memdevice(pid_t tid, int* memdev, struct enclave_dbginfo** ei) { for (int i = 0; i < g_memdevs_cnt; i++) { if (g_memdevs[i].pid == eib.pid) { *memdev = g_memdevs[i].memdev; - *ei = &g_memdevs[i].ei; + *ei = &g_memdevs[i].ei; return update_thread_tids(*ei); } } @@ -408,7 +408,7 @@ static int open_memdevice(pid_t tid, int* memdev, struct enclave_dbginfo** ei) { sizeof(g_memdevs[g_memdevs_cnt].ei.thread_stepping)); *memdev = fd; - *ei = &g_memdevs[g_memdevs_cnt].ei; + *ei = &g_memdevs[g_memdevs_cnt].ei; g_memdevs_cnt++; return 0; diff --git a/Pal/src/host/Linux-SGX/debugger/sgx_gdb.h b/Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.h similarity index 100% rename from Pal/src/host/Linux-SGX/debugger/sgx_gdb.h rename to Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.h diff --git a/Pal/src/host/Linux-SGX/sgx_enclave.c b/Pal/src/host/Linux-SGX/sgx_enclave.c index 267b04cf..be8bc69e 100644 --- a/Pal/src/host/Linux-SGX/sgx_enclave.c +++ b/Pal/src/host/Linux-SGX/sgx_enclave.c @@ -632,7 +632,7 @@ static long sgx_ocall_eventfd(void* pms) { static long sgx_ocall_load_debug(void* pms) { const char* command = (const char*)pms; ODEBUG(OCALL_LOAD_DEBUG, (void*)command); - load_gdb_command(command); + execute_gdb_command(command); return 0; } diff --git a/Pal/src/host/Linux-SGX/sgx_gdb_info.c b/Pal/src/host/Linux-SGX/sgx_gdb_info.c new file mode 100644 index 00000000..5c0f1819 --- /dev/null +++ b/Pal/src/host/Linux-SGX/sgx_gdb_info.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* Copyright (C) 2020 Intel Corporation + * Michał Kowalczyk + */ + +#include "pal_debug.h" +#include "sgx_internal.h" + +/* This function is hooked by our gdb integration script and should be left as is. */ +__attribute__((__noinline__)) void execute_gdb_command(const char* command) { + __UNUSED(command); + __asm__ volatile(""); // Required in addition to __noinline__ to prevent deleting this function. + // See GCC docs. +} diff --git a/Pal/src/host/Linux-SGX/sgx_internal.h b/Pal/src/host/Linux-SGX/sgx_internal.h index 5ee16cf8..fdf03ab8 100644 --- a/Pal/src/host/Linux-SGX/sgx_internal.h +++ b/Pal/src/host/Linux-SGX/sgx_internal.h @@ -138,6 +138,6 @@ int sgx_signal_setup(void); int block_signals(bool block, const int* sigs, int nsig); int block_async_signals(bool block); -void load_gdb_command(const char* command); +void execute_gdb_command(const char* command); #endif diff --git a/Pal/src/host/Linux-SGX/sgx_main.c b/Pal/src/host/Linux-SGX/sgx_main.c index a4381a17..5512ac80 100644 --- a/Pal/src/host/Linux-SGX/sgx_main.c +++ b/Pal/src/host/Linux-SGX/sgx_main.c @@ -8,7 +8,7 @@ #include "pal_rtld.h" #include "hex.h" -#include "debugger/sgx_gdb.h" +#include "gdb_integration/sgx_gdb.h" #include "linux_utils.h" #include "rpc_queue.h" #include "sgx_api.h" diff --git a/Pal/src/host/Linux-SGX/sgx_rtld.c b/Pal/src/host/Linux-SGX/sgx_rtld.c deleted file mode 100644 index f536aede..00000000 --- a/Pal/src/host/Linux-SGX/sgx_rtld.c +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ -/* Copyright (C) 2014 Stony Brook University */ - -/* - * db_rtld.c - * - * This file contains utilities to load ELF binaries into the memory - * and link them against each other. - * The source code in this file is imported and modified from the GNU C - * Library. - */ - -#include "api.h" -#include "pal_internal.h" -#include "sgx_internal.h" - -__asm__( - ".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\r\n" - ".byte 1\r\n" - ".asciz \"debugger/pal-gdb.py\"\r\n" - ".popsection\r\n"); - -/* This function is hooked by our gdb integration script and should be - * left as is. */ -void load_gdb_command(const char* command) { - __UNUSED(command); -} diff --git a/Pal/src/host/Linux-SGX/sgx_thread.c b/Pal/src/host/Linux-SGX/sgx_thread.c index 01592c55..fdbce975 100644 --- a/Pal/src/host/Linux-SGX/sgx_thread.c +++ b/Pal/src/host/Linux-SGX/sgx_thread.c @@ -11,7 +11,7 @@ #include #include "assert.h" -#include "debugger/sgx_gdb.h" +#include "gdb_integration/sgx_gdb.h" #include "pal_internal.h" #include "pal_security.h" #include "sgx_enclave.h" diff --git a/Pal/src/host/Linux/Makefile.am b/Pal/src/host/Linux/Makefile.am index 6bc3a557..1d9fb1ce 100644 --- a/Pal/src/host/Linux/Makefile.am +++ b/Pal/src/host/Linux/Makefile.am @@ -17,4 +17,3 @@ pal_lib = $(HOST_DIR)/libpal.so pal_lib_deps = pal-symbols $(HOST_DIR)/pal.map.template $(HOST_DIR)/pal-$(ARCH).lds pal_lib_post = pal_static = $(HOST_DIR)/libpal.a -pal_gdb = diff --git a/Pal/src/host/Linux/db_main.c b/Pal/src/host/Linux/db_main.c index 3d743bfc..11379335 100644 --- a/Pal/src/host/Linux/db_main.c +++ b/Pal/src/host/Linux/db_main.c @@ -30,15 +30,6 @@ /* pal_start is the entry point of libpal.so, which calls pal_main */ #define _ENTRY pal_start -/* use objfile-gdb convention instead of .debug_gdb_scripts */ -#ifdef DEBUG -__asm__( - ".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\r\n" - ".byte 1\r\n" - ".asciz \"pal-gdb.py\"\r\n" - ".popsection\r\n"); -#endif - char* g_pal_loader_path = NULL; /* Currently content of this variable is only passed as an argument while spawning new processes * - this is to keep uniformity with other PALs. */ diff --git a/Pal/src/host/Linux/gdb_integration/graphene.gdb b/Pal/src/host/Linux/gdb_integration/graphene.gdb new file mode 100644 index 00000000..af934839 --- /dev/null +++ b/Pal/src/host/Linux/gdb_integration/graphene.gdb @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later */ +# Copyright (C) 2020 Intel Corporation +# Michał Kowalczyk + +# Tell Graphene to behave more gdb-friendly. +set env IN_GDB=1 + +# Used internally by Graphene, generates a lot of noise if we don't silence it. +handle SIGCONT pass noprint nostop + +# TODO: This block of commands was copied from an older Graphene integration script where they +# didn't have any comments with rationale why they are needed. We should revise and comment them. +set auto-load off +handle SIGKILL pass print stop +set disable-randomization off +set detach-on-fork off +set schedule-multiple on +set follow-fork-mode child + +break pal_start +command + silent + set scheduler-locking off + continue +end + +break thread_start +command + silent + continue +end + +catch vfork +command + silent + set scheduler-locking on + continue +end diff --git a/Pal/src/host/Linux/gdb_integration/graphene_gdb.py b/Pal/src/host/Linux/gdb_integration/graphene_gdb.py new file mode 100644 index 00000000..e67c7ed2 --- /dev/null +++ b/Pal/src/host/Linux/gdb_integration/graphene_gdb.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later */ +# Copyright (C) 2020 Intel Corporation +# Michał Kowalczyk + +import os +import gdb # pylint: disable=import-error + +def main(): + gdb_script = os.path.dirname(__file__) + "/graphene.gdb" + print("[%s] Loading %s..." % (os.path.basename(__file__), gdb_script)) + gdb.execute("source " + gdb_script) + +if __name__ == '__main__': + main() diff --git a/Pal/src/host/Linux/pal-gdb.py b/Pal/src/host/Linux/pal-gdb.py deleted file mode 100644 index 38063348..00000000 --- a/Pal/src/host/Linux/pal-gdb.py +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 - -import os, sys, gdb - -if len(gdb.inferiors()) == 1: - gdb.execute("set env IN_GDB = 1") - gdb.execute("set auto-load off") - - sys.stdout.write("Are you loading the script [Y]/n ? ") - sys.stdout.flush() - ans = sys.stdin.readline() - - if ans[0] != 'n' and ans[0] != 'N': - gdbfile = os.path.dirname(__file__) + "/pal.gdb" - gdb.execute("source " + gdbfile) - sys.stdout.write("script %s loaded\n" % gdbfile) diff --git a/Pal/src/host/Linux/pal.gdb b/Pal/src/host/Linux/pal.gdb deleted file mode 100644 index 3586441d..00000000 --- a/Pal/src/host/Linux/pal.gdb +++ /dev/null @@ -1,27 +0,0 @@ -handle SIGCONT pass noprint nostop -handle SIGKILL pass print stop - -set disable-randomization off -set detach-on-fork off -set schedule-multiple on -set follow-fork-mode child - -break pal_start -command - silent - set scheduler-locking off - continue -end - -break thread_start -command - silent - continue -end - -catch vfork -command - silent - set scheduler-locking on - continue -end diff --git a/Pal/src/host/Skeleton/Makefile.am b/Pal/src/host/Skeleton/Makefile.am index 2137b761..8d39119e 100644 --- a/Pal/src/host/Skeleton/Makefile.am +++ b/Pal/src/host/Skeleton/Makefile.am @@ -16,4 +16,3 @@ pal_lib = $(HOST_DIR)/libpal.so pal_lib_deps = pal-symbols $(HOST_DIR)/pal.map.template $(HOST_DIR)/pal-$(ARCH).lds pal_lib_post = pal_static = -pal_gdb = diff --git a/Runtime/.gitignore b/Runtime/.gitignore index aded7393..13b7ec02 100644 --- a/Runtime/.gitignore +++ b/Runtime/.gitignore @@ -1,3 +1,2 @@ /pal-Linux /pal-Linux-SGX -/pal_gdb-Linux-SGX diff --git a/Runtime/Makefile b/Runtime/Makefile index a2aa93b7..ba9e707b 100644 --- a/Runtime/Makefile +++ b/Runtime/Makefile @@ -3,7 +3,7 @@ all: .PHONY: clean clean: - $(RM) *.a *.o *.so *.so.* pal_gdb* pal-* + $(RM) *.a *.o *.so *.so.* pal-* .PHONY: distclean distclean: clean diff --git a/Runtime/pal_loader b/Runtime/pal_loader index 9e483929..18218f73 100755 --- a/Runtime/pal_loader +++ b/Runtime/pal_loader @@ -1,4 +1,9 @@ #!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-3.0-or-later */ +# Copyright (C) 2014 Stony Brook University +# Copyright (C) 2019 Invisible Things Lab +# Copyright (C) 2020 Intel Corporation +# Michał Kowalczyk while : do @@ -42,28 +47,22 @@ if [ -z "$PAL_HOST" ]; then fi MANIFEST= +ENVS=() PREFIX=() -PAL_CMD=$RUNTIME_DIR/pal-$PAL_HOST +PAL_CMD="$RUNTIME_DIR/pal-$PAL_HOST" LIBPAL_PATH=$(realpath "$RUNTIME_DIR/libpal-$PAL_HOST.so") +HOST_PAL_PATH=$(realpath "$RUNTIME_DIR/../Pal/src/host/$PAL_HOST") if [ "$GDB" == "1" ]; then - GDB=$RUNTIME_DIR/pal_gdb-$PAL_HOST - if [ ! -f "$GDB" ]; then - GDB="gdb" - fi -fi - -if [ "$GDB" != "" ] && [ "$GDB" != "0" ]; then - PREFIX=("$GDB" -q) + PREFIX=("gdb" "-q") if [ -n "$INSIDE_EMACS" ]; then PREFIX+=("-i=mi") fi if [ -v SGX ]; then - PREFIX+=("-iex") - PREFIX+=("dir $RUNTIME_DIR/../Pal/src/host/Linux-SGX") + PREFIX+=("-x" "$HOST_PAL_PATH/gdb_integration/graphene_sgx_gdb.py") + ENVS+=("LD_PRELOAD=$HOST_PAL_PATH/gdb_integration/sgx_gdb.so") else - PREFIX+=("-iex") - PREFIX+=("dir $RUNTIME_DIR/../Pal/src/host/Linux") + PREFIX+=("-x" "$HOST_PAL_PATH/gdb_integration/graphene_gdb.py") fi PREFIX+=("--args") fi @@ -93,8 +92,7 @@ if [ ! -f "$PAL_CMD" ]; then exit 1 fi -if [ ${#PREFIX[@]} -eq 0 ]; then - exec "$PAL_CMD" "$LIBPAL_PATH" init "$MANIFEST" "$@" -else - exec "${PREFIX[@]}" "$PAL_CMD" "$LIBPAL_PATH" init "$MANIFEST" "$@" -fi +CMD=("${ENVS[@]}") +CMD+=("${PREFIX[@]}") +CMD+=("$PAL_CMD" "$LIBPAL_PATH" init "$MANIFEST" "$@") +exec env "${CMD[@]}" diff --git a/Tools/gsc/templates/Dockerfile.ubuntu18.04.build.template b/Tools/gsc/templates/Dockerfile.ubuntu18.04.build.template index 89401083..293ff894 100644 --- a/Tools/gsc/templates/Dockerfile.ubuntu18.04.build.template +++ b/Tools/gsc/templates/Dockerfile.ubuntu18.04.build.template @@ -47,8 +47,12 @@ COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/signer/pal_sgx_sign.py /gr COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/generated_offsets.py /graphene/signer/ COPY --from=graphene /graphene/Tools/argv_serializer /graphene/Tools {% if debug %} -COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/debugger/sgx_gdb.so /graphene/Runtime -COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/debugger/pal-gdb.py /graphene/Runtime +COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/gdb_integration/sgx_gdb.so \ + /graphene/Pal/src/host/Linux-SGX/gdb_integration/ +COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx_gdb.py \ + /graphene/Pal/src/host/Linux-SGX/gdb_integration/ +COPY --from=graphene /graphene/Pal/src/host/Linux-SGX/gdb_integration/graphene_sgx.gdb \ + /graphene/Pal/src/host/Linux-SGX/gdb_integration/ {% endif %} # Copy template scripts and manifests