]>
Commit | Line | Data |
---|---|---|
86bf665e | 1 | // -*- C++ -*- |
ef36f781 | 2 | // Copyright (C) 2008-2014 Red Hat Inc. |
86bf665e TM |
3 | // |
4 | // This file is part of systemtap, and is free software. You can | |
5 | // redistribute it and/or modify it under the terms of the GNU General | |
6 | // Public License (GPL); either version 2, or (at your option) any | |
7 | // later version. | |
8 | ||
9 | #ifndef DWARF_WRAPPERS_H | |
10 | #define DWARF_WRAPPERS_H 1 | |
6a38401c JS |
11 | |
12 | #include "config.h" | |
13 | ||
14 | extern "C" { | |
86bf665e | 15 | #include <elfutils/libdw.h> |
6a38401c | 16 | #include <elfutils/version.h> |
f450a7e3 | 17 | #include <dwarf.h> |
6a38401c | 18 | } |
86bf665e TM |
19 | |
20 | #include <string> | |
21 | ||
f450a7e3 JS |
22 | #if ! _ELFUTILS_PREREQ(0, 148) |
23 | #define DW_AT_linkage_name 0x6e | |
24 | #endif | |
25 | ||
f94271dc JS |
26 | #if ! _ELFUTILS_PREREQ(0, 153) |
27 | #define DW_TAG_GNU_call_site 0x4109 | |
28 | #define DW_AT_GNU_tail_call 0x2115 | |
29 | #endif | |
30 | ||
6561d8d1 JS |
31 | #if ! _ELFUTILS_PREREQ(0, 155) |
32 | #define DW_ATE_UTF 0x10 | |
33 | #endif | |
34 | ||
e1c3b13a JL |
35 | #define DWFL_ASSERT(desc, arg) \ |
36 | dwfl_assert(desc, arg, __FILE__, __LINE__) | |
55d8c5d4 | 37 | |
86bf665e | 38 | // NB: "rc == 0" means OK in this case |
e1c3b13a JL |
39 | void dwfl_assert(const std::string& desc, int rc, |
40 | const std::string& file, int line); | |
86bf665e | 41 | |
54c2bb84 JS |
42 | // Throw error if pointer is NULL |
43 | inline void | |
e1c3b13a JL |
44 | dwfl_assert(const std::string& desc, const void* ptr, |
45 | const std::string& file, int line) | |
86bf665e TM |
46 | { |
47 | if (!ptr) | |
e1c3b13a | 48 | dwfl_assert(desc, -1, file, line); |
86bf665e TM |
49 | } |
50 | ||
54c2bb84 JS |
51 | // Throw error if condition is false |
52 | inline void | |
e1c3b13a JL |
53 | dwfl_assert(const std::string& desc, bool condition, |
54 | const std::string& file, int line) | |
86bf665e | 55 | { |
54c2bb84 | 56 | if (!condition) |
e1c3b13a | 57 | dwfl_assert(desc, -1, file, line); |
86bf665e TM |
58 | } |
59 | ||
e1c3b13a JL |
60 | #define DWARF_ASSERT(desc, arg) \ |
61 | dwarf_assert(desc, arg, __FILE__, __LINE__) | |
62 | ||
86bf665e | 63 | // NB: "rc == 0" means OK in this case |
e1c3b13a JL |
64 | void dwarf_assert(const std::string& desc, int rc, |
65 | const std::string& file, int line); | |
86bf665e | 66 | |
ba53ea9f | 67 | // Throw error if pointer is NULL |
54c2bb84 | 68 | inline void |
e1c3b13a JL |
69 | dwarf_assert(const std::string& desc, const void* ptr, |
70 | const std::string& file, int line) | |
86bf665e TM |
71 | { |
72 | if (!ptr) | |
e1c3b13a | 73 | dwarf_assert(desc, -1, file, line); |
86bf665e TM |
74 | } |
75 | ||
bf5974d6 JL |
76 | #define DWARF_LINENO(line) \ |
77 | safe_dwarf_lineno(line, __FILE__, __LINE__) | |
78 | ||
de797211 | 79 | inline int |
bf5974d6 JL |
80 | safe_dwarf_lineno(const Dwarf_Line* line, |
81 | const std::string& errfile, int errline) | |
de797211 JL |
82 | { |
83 | int lineno; | |
bf5974d6 JL |
84 | dwarf_assert("dwarf_lineno", |
85 | dwarf_lineno(const_cast<Dwarf_Line*>(line), &lineno), | |
86 | errfile, errline); | |
de797211 JL |
87 | return lineno; |
88 | } | |
89 | ||
bf5974d6 JL |
90 | #define DWARF_LINEADDR(line) \ |
91 | safe_dwarf_lineaddr(line, __FILE__, __LINE__) | |
92 | ||
de797211 | 93 | inline Dwarf_Addr |
bf5974d6 JL |
94 | safe_dwarf_lineaddr(const Dwarf_Line* line, |
95 | const std::string& errfile, int errline) | |
de797211 JL |
96 | { |
97 | Dwarf_Addr addr; | |
bf5974d6 JL |
98 | dwarf_assert("dwarf_lineaddr", |
99 | dwarf_lineaddr(const_cast<Dwarf_Line*>(line), &addr), | |
100 | errfile, errline); | |
de797211 JL |
101 | return addr; |
102 | } | |
86bf665e | 103 | |
bf5974d6 JL |
104 | #define DWARF_LINESRC(line) \ |
105 | safe_dwarf_linesrc(line, NULL, NULL, __FILE__, __LINE__) | |
106 | #define DWARF_LINESRC2(line, mtime) \ | |
107 | safe_dwarf_linesrc(line, mtime, NULL, __FILE__, __LINE__) | |
108 | #define DWARF_LINESRC3(line, mtime, length) \ | |
109 | safe_dwarf_linesrc(line, mtime, length, __FILE__, __LINE__) | |
110 | ||
de797211 JL |
111 | inline const char* |
112 | safe_dwarf_linesrc(const Dwarf_Line* line, | |
bf5974d6 JL |
113 | Dwarf_Word* mtime, |
114 | Dwarf_Word* length, | |
115 | const std::string& errfile, int errline) | |
86bf665e | 116 | { |
de797211 JL |
117 | const char* linesrc = |
118 | dwarf_linesrc(const_cast<Dwarf_Line*>(line), mtime, length); | |
bf5974d6 | 119 | dwarf_assert("dwarf_linesrc", linesrc, errfile, errline); |
de797211 JL |
120 | return linesrc; |
121 | } | |
122 | ||
bf5974d6 JL |
123 | #define DWARF_LINEPROLOGUEEND(line) \ |
124 | safe_dwarf_lineprologueend(line, __FILE__, __LINE__) | |
125 | ||
de797211 | 126 | inline bool |
bf5974d6 JL |
127 | safe_dwarf_lineprologueend(const Dwarf_Line* line, |
128 | const std::string& errfile, int errline) | |
de797211 JL |
129 | { |
130 | bool flag; | |
bf5974d6 JL |
131 | dwarf_assert("is_prologue_end", |
132 | dwarf_lineprologueend(const_cast<Dwarf_Line*>(line), &flag), | |
133 | errfile, errline); | |
de797211 JL |
134 | return flag; |
135 | } | |
86bf665e TM |
136 | |
137 | ||
3d1ad340 JS |
138 | // Look up the DIE for a reference-form attribute name |
139 | inline Dwarf_Die * | |
140 | dwarf_attr_die (Dwarf_Die *die, unsigned int attr, Dwarf_Die *result) | |
141 | { | |
142 | Dwarf_Attribute attr_mem; | |
28a494df MW |
143 | if (dwarf_formref_die (dwarf_attr_integrate (die, attr, &attr_mem), |
144 | result) != NULL) | |
145 | { | |
146 | /* If we want a type make sure we get the actual DIE describing | |
147 | the real type. */ | |
148 | if (attr == DW_AT_type) | |
149 | { | |
150 | Dwarf_Attribute sigm; | |
151 | Dwarf_Attribute *sig = dwarf_attr (result, DW_AT_signature, &sigm); | |
152 | if (sig != NULL) | |
153 | result = dwarf_formref_die (sig, result); | |
154 | ||
155 | /* A DW_AT_signature might point to a type_unit, then | |
156 | the actual type DIE we want is the first child. */ | |
157 | if (result != NULL && dwarf_tag (result) == DW_TAG_type_unit) | |
c92d3b42 | 158 | DWFL_ASSERT("type_unit child", dwarf_child (result, result)); |
28a494df MW |
159 | } |
160 | return result; | |
161 | } | |
162 | return NULL; | |
3d1ad340 JS |
163 | } |
164 | ||
165 | ||
f450a7e3 JS |
166 | // Retrieve the linkage name of a die, either by the MIPS vendor extension or |
167 | // DWARF4's standardized attribute. | |
168 | inline const char * | |
169 | dwarf_linkage_name (Dwarf_Die *die) | |
170 | { | |
171 | Dwarf_Attribute attr_mem; | |
172 | return dwarf_formstring | |
173 | (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name, &attr_mem) | |
174 | ?: dwarf_attr_integrate (die, DW_AT_linkage_name, &attr_mem)); | |
175 | } | |
176 | ||
177 | ||
7f17af5c JS |
178 | #if !_ELFUTILS_PREREQ(0, 143) |
179 | // Elfutils prior to 0.143 didn't use attr_integrate when looking up the | |
180 | // decl_file or decl_line, so the attributes would sometimes be missed. For | |
181 | // those old versions, we define custom implementations to do the integration. | |
182 | ||
183 | const char *dwarf_decl_file_integrate (Dwarf_Die *die); | |
184 | #define dwarf_decl_file dwarf_decl_file_integrate | |
185 | ||
186 | int dwarf_decl_line_integrate (Dwarf_Die *die, int *linep) | |
187 | __nonnull_attribute__ (2); | |
188 | #define dwarf_decl_line dwarf_decl_line_integrate | |
189 | ||
190 | #endif // !_ELFUTILS_PREREQ(0, 143) | |
191 | ||
192 | ||
b6e49c97 JS |
193 | // Resolve a C declaration for dwarf types |
194 | bool dwarf_type_decl(Dwarf_Die *type_die, const std::string& var_name, std::string& decl); | |
195 | ||
f1c8f8a5 JS |
196 | // Resolve a full name for dwarf types |
197 | bool dwarf_type_name(Dwarf_Die *type_die, std::string& type_name); | |
198 | std::string dwarf_type_name(Dwarf_Die *type_die); | |
199 | ||
200 | ||
86bf665e | 201 | #endif |
73267b89 JS |
202 | |
203 | /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |