127 lines
2.4 KiB
C++
127 lines
2.4 KiB
C++
/**
|
|
* \brief Debugger support
|
|
* \author Sebastian Sumpf
|
|
* \date 2015-03-10
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2015 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__DEBUG_H_
|
|
#define _INCLUDE__DEBUG_H_
|
|
|
|
#include <base/printf.h>
|
|
#include <elf.h>
|
|
|
|
constexpr bool verbose_link_map = false;
|
|
|
|
namespace Linker {
|
|
struct Debug;
|
|
struct Link_map;
|
|
}
|
|
|
|
/**
|
|
* LIBC debug support
|
|
*/
|
|
extern "C" void brk(Linker::Debug *, Linker::Link_map *);
|
|
|
|
struct Linker::Debug
|
|
{
|
|
/*
|
|
* This state value describes the mapping change taking place when
|
|
* the brk address is called.
|
|
*/
|
|
enum State {
|
|
CONSISTENT, /* mapping change is complete */
|
|
ADD, /* beginning to add a new object */
|
|
DELETE /* beginning to remove an object mapping */
|
|
};
|
|
|
|
Debug() : Brk(brk) { }
|
|
|
|
int version = 1; /* unused */
|
|
struct Link_map *map = nullptr;; /* start of link map */
|
|
|
|
/*
|
|
* This is the address of a function internal to the run-time linker, that
|
|
* will always be called when the linker begins to map in a library or unmap
|
|
* it, and again when the mapping change is complete. The debugger can set a
|
|
* breakpoint at this address if it wants to notice shared object mapping
|
|
* changes.
|
|
*/
|
|
void (*Brk)(Debug *, Link_map *);
|
|
State state = CONSISTENT;
|
|
|
|
static void state_change(State s, Link_map *m)
|
|
{
|
|
d()->state = s;
|
|
d()->Brk(d(), m);
|
|
}
|
|
|
|
static Debug *d()
|
|
{
|
|
static Debug _d;
|
|
return &_d;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Link map
|
|
*/
|
|
struct Linker::Link_map
|
|
{
|
|
Elf::Addr addr; /* base address of library */
|
|
char const *path; /* path */
|
|
void const *dynamic; /* DYNAMIC section */
|
|
|
|
Link_map *next = nullptr;
|
|
Link_map *prev = nullptr;
|
|
|
|
static Link_map *first;
|
|
|
|
static void add(Link_map *map)
|
|
{
|
|
map->next = nullptr;;
|
|
if (!first) {
|
|
first = map;
|
|
Debug::d()->map = map;
|
|
return;
|
|
}
|
|
|
|
Link_map *m;
|
|
for (m = first; m->next; m = m->next) ;
|
|
|
|
m->next = map;
|
|
map->prev = m;
|
|
}
|
|
|
|
static void remove(Link_map *map)
|
|
{
|
|
if (map->prev)
|
|
map->prev->next = map->next;
|
|
|
|
if (map->next)
|
|
map->next->prev = map->prev;
|
|
|
|
if (map == first)
|
|
first = map->next;
|
|
}
|
|
|
|
static void dump()
|
|
{
|
|
if (!verbose_link_map)
|
|
return;
|
|
|
|
for (Link_map *m = first; m; m = m->next)
|
|
PINF("MAP: addr: " EFMT " dynamic: %p %s m: %p p: %p n: %p",
|
|
m->addr, m->dynamic, m->path, m, m->prev, m->next);
|
|
}
|
|
};
|
|
|
|
#endif /* _INCLUDE__DEBUG_H_ */
|