summaryrefslogtreecommitdiff
path: root/libdwfl/loc2c-runtime.h
blob: af27f791d04aa18981ae01c776754a9ce5340c34 (plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* target operations */

#include <linux/types.h>
#define intptr_t long
#define uintptr_t unsigned long


/* These three macro definitions are generic, just shorthands
   used by the generated code.  */

#define op_abs(x)	(x < 0 ? -x : x)

#define fetch_bitfield(target, base, higherbits, nbits)			      \
  target = (((base) >> (sizeof (base) * 8 - (higherbits) - (nbits)))	      \
	    & (((__typeof (base)) 1 << (nbits)) - 1))

#define store_bitfield(target, base, higherbits, nbits)			      \
  target = (target							      \
	    &~ ((((__typeof (base)) 1 << (nbits)) - 1)			      \
		<< (sizeof (base) * 8 - (higherbits) - (nbits)))	      \
	    | ((__typeof (base)) (value)				      \
	       << (sizeof (base) * 8 - (higherbits) - (nbits))))


/* These operations are target-specific.  */
#include <asm/uaccess.h>

#define fetch_register(regno) ((intptr_t) regs->dwarf_register_##regno)

#if defined __i386__

#define dwarf_register_0 eax
#define dwarf_register_1 ecx
#define dwarf_register_2 edx
#define dwarf_register_3 ebx
#define dwarf_register_4 esp
#define dwarf_register_5 ebp
#define dwarf_register_6 esi
#define dwarf_register_7 edi

#elif defined __x86_64__

#define dwarf_register_0 eax
#define dwarf_register_1 edx
#define dwarf_register_2 ecx
#define dwarf_register_3 ebx
#define dwarf_register_4 esi
#define dwarf_register_5 edi
#define dwarf_register_6 ebp
#define dwarf_register_7 esp
#define dwarf_register_8 r8
#define dwarf_register_9 r9
#define dwarf_register_10 r10
#define dwarf_register_11 r11
#define dwarf_register_12 r12
#define dwarf_register_13 r13
#define dwarf_register_14 r14
#define dwarf_register_15 r15

#elif defined __powerpc__

#undef fetch_register
#define fetch_register(regno) ((intptr_t) regs->gpr[regno])

#endif

#if defined __i386__ || defined __x86_64__

#define deref(size, addr)						      \
  ({									      \
    int _bad = 0;							      \
    u8 _b; u16 _w; u32 _l; u64 _q;					      \
    intptr_t _v;							      \
    switch (size)							      \
      {									      \
      case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break;    \
      case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break;    \
      case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break;     \
      case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break;     \
      default: _v = __get_user_bad();					      \
      }									      \
    if (_bad)								      \
      goto deref_fault;							      \
    _v;									      \
  })

#elif defined __powerpc64__

#define deref(size, addr)						      \
  ({									      \
    int _bad = 0;							      \
    intptr_t _v;							      \
    switch (size)							      \
      {									      \
      case 1: __get_user_asm(_v,addr,_bad,"lbz",1); break;		      \
      case 2: __get_user_asm(_v,addr,_bad,"lhz",1); break;		      \
      case 4: __get_user_asm(_v,addr,_bad,"lwz",1); break;		      \
      case 8: __get_user_asm(_v,addr,_bad,"ld",1); break;		      \
      default: _v = __get_user_bad();					      \
      }									      \
    if (_bad)								      \
      goto deref_fault;							      \
    _v;									      \
  })

#elif defined __powerpc__

#define deref(size, addr)						      \
  ({									      \
    int _bad = 0;							      \
    intptr_t _v;							      \
    switch (size)							      \
      {									      \
      case 1: __get_user_asm(_v,addr,_bad,"lbz"); break;		      \
      case 2: __get_user_asm(_v,addr,_bad,"lhz"); break;		      \
      case 4: __get_user_asm(_v,addr,_bad,"lwz"); break;		      \
      case 8: __get_user_asm(_v,addr,_bad,"ld"); break;			      \
      default: _v = __get_user_bad();					      \
      }									      \
    if (_bad)								      \
      goto deref_fault;							      \
    _v;									      \
  })

#endif