/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */ /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */ /* Copyright (C) 2014 Stony Brook University This file is part of Graphene Library OS. Graphene Library OS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Graphene Library OS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* * shim_debug.c * * This file contains codes for registering libraries to GDB. */ #include #include #include #include #include #include #include #include #include #ifndef DEBUG void clean_link_map_list (void) { /* do nothing */ } void remove_r_debug (void * addr) { /* do nothing */ } void append_r_debug (const char * uri, void * addr, void * dyn_addr) { /* do nothing */ } #else /* !DEBUG */ struct gdb_link_map { void * l_addr; char * l_name; void * l_ld; struct gdb_link_map *l_next, *l_prev; }; static struct gdb_link_map * link_map_list = NULL; void clean_link_map_list (void) { if (!link_map_list) return; if (link_map_list->l_prev) link_map_list->l_prev->l_next = NULL; struct gdb_link_map * m = link_map_list; for ( ; m ; m = m->l_next) { DkDebugDetachBinary(m->l_addr); free(m); } link_map_list = NULL; } void remove_r_debug (void * addr) { struct gdb_link_map * m = link_map_list; for ( ; m ; m = m->l_next) if (m->l_addr == addr) break; if (!m) return; debug("remove a library for gdb: %s\n", m->l_name); if (m->l_prev) m->l_prev->l_next = m->l_next; if (m->l_next) m->l_next->l_prev = m->l_prev; DkDebugDetachBinary(addr); } void append_r_debug (const char * uri, void * addr, void * dyn_addr) { struct gdb_link_map * new = malloc(sizeof(struct gdb_link_map)); int uri_len = strlen(uri); char * new_uri = malloc(uri_len + 1); memcpy(new_uri, uri, uri_len + 1); new->l_addr = addr; new->l_ld = dyn_addr; new->l_name = new_uri; struct gdb_link_map *prev = NULL; struct gdb_link_map **tail = &link_map_list; while (*tail) { prev = *tail; tail = &(*tail)->l_next; } debug("add a library for gdb: %s\n", uri); new->l_prev = prev; new->l_next = NULL; *tail = new; DkDebugAttachBinary(uri, addr); } BEGIN_CP_FUNC(gdb_map) { struct gdb_link_map *m = link_map_list; struct gdb_link_map *newm = NULL; while (m) { ptr_t off = ADD_CP_OFFSET(sizeof(struct gdb_link_map)); newm = (struct gdb_link_map *) (base + off); memcpy(newm, m, sizeof(struct gdb_link_map)); newm->l_prev = newm->l_next = NULL; int len = strlen(newm->l_name); newm->l_name = (char *) (base + ADD_CP_OFFSET(len + 1)); memcpy(newm->l_name, m->l_name, len + 1); ADD_CP_FUNC_ENTRY(off); m = m->l_next; } } END_CP_FUNC(gdb_map) BEGIN_RS_FUNC(gdb_map) { struct gdb_link_map * map = (void *) (base + GET_CP_FUNC_ENTRY()); CP_REBASE(map->l_name); CP_REBASE(map->l_prev); CP_REBASE(map->l_next); struct gdb_link_map *prev = NULL; struct gdb_link_map **tail = &link_map_list; while (*tail) { prev = *tail; tail = &(*tail)->l_next; } map->l_prev = prev; *tail = map; DkDebugAttachBinary(map->l_name, map->l_addr); DEBUG_RS("base=%p,name=%s", map->l_addr, map->l_name); } END_RS_FUNC(gdb_map) #endif