OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [sysdep/] [i386/] [backtrace.h] - Blame information for rev 764

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 764 jeremybenn
// backtrace.h - Fallback backtrace implementation. i386 implementation.
2
 
3
/* Copyright (C) 2005, 2006  Free Software Foundation
4
 
5
   This file is part of libgcj.
6
 
7
This software is copyrighted work licensed under the terms of the
8
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9
details.  */
10
 
11
#ifndef __SYSDEP_BACKTRACE_H__
12
#define __SYSDEP_BACKTRACE_H__
13
 
14
#include <java-stack.h>
15
 
16
#ifdef __CYGWIN__
17
/* To allow this to link as a DLL.  */
18
#define MAIN_FUNC dll_crt0__FP11per_process
19
extern "C" int MAIN_FUNC () __declspec(dllimport);
20
#elif defined (_WIN32)
21
#define MAIN_FUNC DllMain
22
extern "C" int __stdcall MAIN_FUNC (void *, unsigned long, void *);
23
#else /* !__CYGWIN__ && !_WIN32 */
24
#define MAIN_FUNC main
25
extern int MAIN_FUNC (int, char **);
26
#endif /* ?__CYGWIN__ */
27
 
28
/* The context used to keep track of our position while unwinding through
29
   the call stack.  */
30
struct _Unwind_Context
31
{
32
  /* The starting address of the method.  */
33
  _Jv_uintptr_t meth_addr;
34
 
35
  /* The return address in the method.  */
36
  _Jv_uintptr_t ret_addr;
37
};
38
 
39
#ifdef SJLJ_EXCEPTIONS
40
 
41
#undef _Unwind_GetIPInfo
42
#define _Unwind_GetIPInfo(ctx,ip_before_insn) \
43
  (*(ip_before_insn) = 1, (ctx)->ret_addr)
44
 
45
#undef _Unwind_GetRegionStart
46
#define _Unwind_GetRegionStart(ctx) \
47
  ((ctx)->meth_addr)
48
 
49
#undef _Unwind_Backtrace
50
#define _Unwind_Backtrace(trace_fn,state_ptr) \
51
  (fallback_backtrace (trace_fn, state_ptr))
52
 
53
#endif /* SJLJ_EXCEPTIONS */
54
 
55
/* Unwind through the call stack calling TRACE_FN with STATE for each stack
56
   frame.  Returns the reason why the unwinding was stopped.  */
57
_Unwind_Reason_Code
58
fallback_backtrace (_Unwind_Trace_Fn trace_fn, _Jv_UnwindState *state)
59
{
60
  register _Jv_uintptr_t *_ebp __asm__ ("ebp");
61
  register _Jv_uintptr_t _esp __asm__ ("esp");
62
  _Jv_uintptr_t rfp;
63
  _Unwind_Context ctx;
64
 
65
  for (rfp = *_ebp; rfp; rfp = *(_Jv_uintptr_t *)rfp)
66
    {
67
      /* Sanity checks to eliminate dubious-looking frame pointer chains.
68
         The frame pointer should be a 32-bit word-aligned stack address.
69
         Since the stack grows downwards on x86, the frame pointer must have
70
         a value greater than the current value of the stack pointer, it
71
         should not be below the supposed next frame pointer and it should
72
         not be too far off from the supposed next frame pointer.  */
73
      int diff = *(_Jv_uintptr_t *)rfp - rfp;
74
      if ((rfp & 0x00000003) != 0 || rfp < _esp
75
          || diff > 4 * 1024 || diff < 0)
76
        break;
77
 
78
      /* Get the return address in the calling function.  This is stored on
79
         the stack just before the value of the old frame pointer.  */
80
      ctx.ret_addr = *(_Jv_uintptr_t *)(rfp + sizeof (_Jv_uintptr_t));
81
 
82
      /* Try to locate a "pushl %ebp; movl %esp, %ebp" function prologue
83
         by scanning backwards at even addresses below the return address.
84
         This instruction sequence is encoded either as 0x55 0x89 0xE5 or as
85
         0x55 0x8B 0xEC.  We give up if we do not find this sequence even
86
         after scanning 1024K of memory.
87
         FIXME: This is not robust and will probably give us false positives,
88
         but this is about the best we can do if we do not have DWARF-2 unwind
89
         information based exception handling.  */
90
      ctx.meth_addr = (_Jv_uintptr_t)NULL;
91
      _Jv_uintptr_t scan_addr = (ctx.ret_addr & 0xFFFFFFFE) - 2;
92
      _Jv_uintptr_t limit_addr
93
        = (scan_addr > 1024 * 1024) ? (scan_addr - 1024 * 1024) : 2;
94
      for ( ; scan_addr >= limit_addr; scan_addr -= 2)
95
        {
96
          unsigned char *scan_bytes = (unsigned char *)scan_addr;
97
          if (scan_bytes[0] == 0x55
98
              && ((scan_bytes[1] == 0x89 && scan_bytes[2] == 0xE5)
99
                  || (scan_bytes[1] == 0x8B && scan_bytes[2] == 0xEC)))
100
            {
101
              ctx.meth_addr = scan_addr;
102
              break;
103
            }
104
        }
105
 
106
      /* Now call the unwinder callback function. */
107
      if (trace_fn != NULL)
108
        (*trace_fn) (&ctx, state);
109
 
110
      /* No need to unwind beyond _Jv_RunMain(), _Jv_ThreadStart or
111
         main().  */
112
      void *jv_runmain
113
        = (void *)(void (*)(JvVMInitArgs *, jclass, const char *, int,
114
                            const char **, bool))_Jv_RunMain;
115
      if (ctx.meth_addr == (_Jv_uintptr_t)jv_runmain
116
          || ctx.meth_addr == (_Jv_uintptr_t)_Jv_ThreadStart
117
          || (ctx.meth_addr - (_Jv_uintptr_t)MAIN_FUNC) < 16)
118
        break;
119
    }
120
 
121
  return _URC_NO_REASON;
122
}
123
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.