/* -*- 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