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