mirror of
https://github.com/clearlinux/graphene.git
synced 2026-08-28 13:25:43 +00:00
5ef9bdc861
- Use the same mechanism (debug_map) in Pal/Linux and Pal/Linux-SGX. Previously, Pal/Linux emulated the _r_debug structure, normally maintained by ld.so, but that cannot be done in SGX outer PAL, because it's loaded by ld.so already. - Maintain the debug maps outside of SGX enclave. This allows initializing them before enclave start, and potentially makes them easier to use. - Initialize PAL debug map before enclave start. Previously, this was done from inside the enclave, so you couldn't set a breakpoint too early (e.g. in pal_linux_main). - Store only load address, without list of sections. This is to avoid parsing the list of sections just to report them to the debugger. Unfortunately, the GDB version that we support still needs these sections, but we can retrieve them in GDB plugin. - Move Python GDB code related to debug maps to a common file.
87 lines
2.0 KiB
C
87 lines
2.0 KiB
C
/* SPDX-License-Identifier: LGPL-3.0-or-later */
|
|
/* Copyright (C) 2020 Intel Corporation
|
|
* Paweł Marczewski <pawel@invisiblethingslab.com>
|
|
*/
|
|
|
|
#include "debug_map.h"
|
|
|
|
#include <asm/errno.h>
|
|
|
|
#include "spinlock.h"
|
|
|
|
struct debug_map* _Atomic g_debug_map = NULL;
|
|
|
|
/* Lock for modifying g_debug_map on our end. Even though the list can be read at any
|
|
* time, we need to prevent concurrent modification. */
|
|
static spinlock_t g_debug_map_lock = INIT_SPINLOCK_UNLOCKED;
|
|
|
|
static struct debug_map* debug_map_new(const char* name, void* addr) {
|
|
struct debug_map* map;
|
|
|
|
if (!(map = malloc(sizeof(*map))))
|
|
return NULL;
|
|
|
|
if (!(map->name = strdup(name))) {
|
|
free(map);
|
|
return NULL;
|
|
}
|
|
|
|
map->addr = addr;
|
|
map->next = NULL;
|
|
return map;
|
|
}
|
|
|
|
/* This function is hooked by our gdb integration script and should be left as is. */
|
|
__attribute__((__noinline__)) void debug_map_update_debugger(void) {
|
|
__asm__ volatile(""); // Required in addition to __noinline__ to prevent deleting this function.
|
|
// See GCC docs.
|
|
}
|
|
|
|
int debug_map_add(const char* name, void* addr) {
|
|
struct debug_map* map = debug_map_new(name, addr);
|
|
if (!map)
|
|
return -ENOMEM;
|
|
|
|
spinlock_lock(&g_debug_map_lock);
|
|
|
|
map->next = g_debug_map;
|
|
g_debug_map = map;
|
|
|
|
spinlock_unlock(&g_debug_map_lock);
|
|
|
|
debug_map_update_debugger();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int debug_map_remove(void* addr) {
|
|
spinlock_lock(&g_debug_map_lock);
|
|
|
|
struct debug_map* prev = NULL;
|
|
struct debug_map* map = g_debug_map;
|
|
while (map) {
|
|
if (map->addr == addr)
|
|
break;
|
|
prev = map;
|
|
map = map->next;
|
|
}
|
|
if (!map) {
|
|
spinlock_unlock(&g_debug_map_lock);
|
|
return -EINVAL;
|
|
}
|
|
if (prev) {
|
|
prev->next = map->next;
|
|
} else {
|
|
g_debug_map = map->next;
|
|
}
|
|
|
|
spinlock_unlock(&g_debug_map_lock);
|
|
|
|
debug_map_update_debugger();
|
|
|
|
free(map->name);
|
|
free(map);
|
|
|
|
return 0;
|
|
}
|