-
Notifications
You must be signed in to change notification settings - Fork 0
/
rtl-debugger.c
96 lines (82 loc) · 2.29 KB
/
rtl-debugger.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* COPYRIGHT (c) 2012 Chris Johns <[email protected]>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtl
*
* @brief RTEMS Module Loading Debugger Interface.
*
* Inspection of run-time linkers in NetBSD and Android show a common type of
* structure that is used to interface to GDB. The NetBSD definition of this
* interface is being used and is defined in <link.h>. It defines a protocol
* that is used by GDB to inspect the state of dynamic libraries. I have not
* checked GDB code at when writing this comment but I suspect GDB sets a break
* point on the r_brk field of _rtld_debug and it has code that detects this
* break point being hit. When this happens it reads the state and performs the
* operation based on the r_state field.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <link.h>
#include <rtl.h>
#include <rtl-trace.h>
#include "rtl-obj-fwd.h"
struct r_debug _rtld_debug;
void
_rtld_debug_state (void)
{
/*
* Empty. GDB only needs to hit this location.
*/
}
int
_rtld_linkmap_add (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
struct link_map* prev;
uint32_t obj_num = obj->obj_num;
int i;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_DETAIL))
printf ("rtl: linkmap_add\n");
for (i = 0; i < obj_num; ++i)
{
l[i].sec_addr[rap_text] = obj->text_base;
l[i].sec_addr[rap_const] = obj->const_base;
l[i].sec_addr[rap_data] = obj->data_base;
l[i].sec_addr[rap_bss] = obj->bss_base;
}
if (_rtld_debug.r_map == NULL)
{
_rtld_debug.r_map = l;
return true;
}
for (prev = _rtld_debug.r_map; prev->l_next != NULL; prev = prev->l_next);
l->l_prev = prev;
prev->l_next = l;
return true;
}
void
_rtld_linkmap_delete (rtems_rtl_obj_t* obj)
{
struct link_map* l = (struct link_map*)obj->detail;
/* link_maps are allocated together if not 1 */
struct link_map* e = l + obj->obj_num - 1;
while (e && e->l_next) e = e->l_next;
if (l->l_prev == NULL)
{
if ((_rtld_debug.r_map = e->l_next) != NULL)
e->l_next->l_prev = NULL;
return;
}
if ((l->l_prev->l_next = e->l_next) != NULL)
e->l_next->l_prev = l->l_prev;
return;
}