-
Notifications
You must be signed in to change notification settings - Fork 4
/
loc2c.h
138 lines (119 loc) · 5.82 KB
/
loc2c.h
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
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <elfutils/libdw.h>
struct obstack; /* Use <obstack.h> */
struct location; /* Opaque */
/* G++ 3.3 doesn't seem to like the __attribute__ constructs below. */
#if (__GNUG__ == 3) && (__GNUC_MINOR__ == 3)
#define __attribute__(x) /* nothing */
#endif
/* Translate a C fragment for the location expression, using *INPUT
as the starting location, begin from scratch if *INPUT is null.
If DW_OP_fbreg is used, it may have a subfragment computing from
the FB_ATTR location expression. The call_frame might need to be
calculated by the cfa_ops for the given pc_address. If known the
locattr provides the attribute from which the locexpr array was
retrieved.
On errors, call FAIL, which should not return. Any later errors will use
FAIL and FAIL_ARG from the first c_translate_location call.
On success, return the first fragment created, which is also chained
onto (*INPUT)->next. *INPUT is then updated with the new tail of that
chain. */
struct location *c_translate_location (struct obstack *,
void (*fail) (void *arg,
const char *fmt, ...)
__attribute__ ((noreturn,
format (printf, 2, 3))),
void *fail_arg,
void (*emit_address) (void *fail_arg,
struct obstack *,
Dwarf_Addr),
int indent,
Dwarf_Addr bias,
Dwarf_Addr pc_address,
Dwarf_Attribute *attr,
const Dwarf_Op *locexpr,
size_t locexprlen,
struct location **input,
Dwarf_Attribute *fb_attr,
const Dwarf_Op *cfa_ops);
/* Translate a fragment for a compile-time constant from DW_AT_const_value.
*/
struct location *c_translate_constant (struct obstack *,
void (*fail) (void *arg,
const char *fmt, ...)
__attribute__ ((noreturn,
format (printf, 2, 3))),
void *fail_arg,
void (*emit_address) (void *fail_arg,
struct obstack *,
Dwarf_Addr),
int indent, Dwarf_Addr dwbias,
Dwarf_Attribute *attr);
/* Translate a fragment to dereference the given DW_TAG_pointer_type DIE,
where *INPUT is the location of the pointer with that type. */
void c_translate_pointer (struct obstack *pool, int indent,
Dwarf_Addr dwbias, Dwarf_Die *typedie,
struct location **input);
/* Translate a fragment to index a DW_TAG_array_type DIE (turning the location
of the array into the location of an element). If IDX is non-null,
it's a string of C code to emit in the fragment as the array index.
If the index is a known constant, IDX should be null and CONST_IDX
is used instead (this case can handle local arrays in registers). */
void c_translate_array (struct obstack *pool, int indent,
Dwarf_Addr dwbias, Dwarf_Die *typedie,
struct location **input,
const char *idx, Dwarf_Word const_idx);
/* Translate a pointer as if it were an array, for cases where we have an
address and pointee type DIE, but perhaps don't have a pointer DIE. */
void c_translate_array_pointer (struct obstack *pool, int indent,
Dwarf_Die *typedie, struct location **input,
const char *idx, Dwarf_Word const_idx);
/* Translate a fragment to compute the address of the input location
and assign it to the variable TARGET. This doesn't really do anything
(it always emits "TARGET = addr;"), but it will barf if the location
is a register or noncontiguous object. */
void c_translate_addressof (struct obstack *pool, int indent,
Dwarf_Addr dwbias, Dwarf_Die *die,
Dwarf_Die *typedie,
struct location **input, const char *target);
/* Translate a fragment to fetch the value of variable or member DIE
at the *INPUT location and store it in lvalue TARGET.
This handles base integer types and bit fields, i.e. DW_TAG_base_type. */
void c_translate_fetch (struct obstack *pool, int indent,
Dwarf_Addr dwbias __attribute__ ((unused)),
Dwarf_Die *die, Dwarf_Die *typedie,
struct location **input, const char *target);
/* Translate a fragment to locate the value of variable or member DIE
at the *INPUT location and set it to the C expression RVALUE.
This handles base integer types and bit fields, i.e. DW_TAG_base_type. */
void c_translate_store (struct obstack *pool, int indent,
Dwarf_Addr dwbias __attribute__ ((unused)),
Dwarf_Die *die, Dwarf_Die *typedie,
struct location **input, const char *rvalue);
/* Translate a fragment to write the given pointer value,
where *INPUT is the location of the pointer with that type. */
void
c_translate_pointer_store (struct obstack *pool, int indent,
Dwarf_Addr dwbias __attribute__ ((unused)),
Dwarf_Die *typedie, struct location **input,
const char *rvalue);
/* Translate a C fragment for a direct argument VALUE. On errors, call FAIL,
which should not return. Any later errors will use FAIL and FAIL_ARG from
this translate call. On success, return the fragment created. */
struct location *c_translate_argument (struct obstack *,
void (*fail) (void *arg,
const char *fmt, ...)
__attribute__ ((noreturn,
format (printf, 2, 3))),
void *fail_arg,
void (*emit_address) (void *fail_arg,
struct obstack *,
Dwarf_Addr),
int indent, const char *value);
/* Emit the C fragment built up at LOC (i.e., the return value from the
first c_translate_location call made). INDENT should match that
passed to c_translate_* previously.
Writes complete lines of C99, code forming a complete C block, to STREAM.
Return value is true iff that code uses the `deref' runtime macros. */
bool c_emit_location (FILE *stream, struct location *loc, int indent,
unsigned int *max_stack);
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */