summaryrefslogtreecommitdiffstats
path: root/cpukit/libdl/rtl-unwind-arm.c
blob: 35361fe8d5bb3ad34af2caa8a9644230f0b7e5ff (plain) (blame)
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
#include "rtl-unwind-arm.h"

bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
                            const char*          name,
                            uint32_t             flags)
{
  /*
   * We location the EH sections in section flags.
   */
  return false;
}

bool
rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj)
{
  return true;
}

bool
rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj)
{
  obj->loader = NULL;
  return true;
}

/*
 * A weak reference is in libgcc, provide a real version and provide a way to
 * manage loaded modules.
 *
 * Passed in the return address and a reference to the number of records
 * found. We set the start of the exidx data and the number of records.
 */
_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
                                     int*        nrec) __attribute__ ((__noinline__,
                                                                       __used__,
                                                                       __noclone__));

_Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr return_address,
                                     int*        nrec)
{
  rtems_rtl_data*   rtl;
  rtems_chain_node* node;
  __EIT_entry*      exidx_start = &__exidx_start;
  __EIT_entry*      exidx_end = &__exidx_end;

  rtl = rtems_rtl_lock ();

  node = rtems_chain_first (&rtl->objects);
  while (!rtems_chain_is_tail (&rtl->objects, node)) {
    rtems_rtl_obj* obj = (rtems_rtl_obj*) node;
    if (rtems_rtl_obj_text_inside (obj, (void*) return_address)) {
      exidx_start = (__EIT_entry*) obj->eh_base;
      exidx_end = (__EIT_entry*) (obj->eh_base + obj->eh_size);
      break;
    }
    node = rtems_chain_next (node);
  }

  rtems_rtl_unlock ();

  *nrec = exidx_end - exidx_start;

  return (_Unwind_Ptr) exidx_start;
}