]> sourceware.org Git - systemtap.git/blame_incremental - dwarf_wrappers.h
Fix PR20504 by updating xfs/nfs4 tracepoint support for kernel 4.7+.
[systemtap.git] / dwarf_wrappers.h
... / ...
CommitLineData
1// -*- C++ -*-
2// Copyright (C) 2008-2014 Red Hat Inc.
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
11
12#include "config.h"
13
14extern "C" {
15#include <elfutils/libdw.h>
16#include <elfutils/version.h>
17#include <dwarf.h>
18}
19
20#include <string>
21
22#if ! _ELFUTILS_PREREQ(0, 148)
23#define DW_AT_linkage_name 0x6e
24#endif
25
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
31#if ! _ELFUTILS_PREREQ(0, 155)
32#define DW_ATE_UTF 0x10
33#endif
34
35#define DWFL_ASSERT(desc, arg) \
36 dwfl_assert(desc, arg, __FILE__, __LINE__)
37
38// NB: "rc == 0" means OK in this case
39void dwfl_assert(const std::string& desc, int rc,
40 const std::string& file, int line);
41
42// Throw error if pointer is NULL
43inline void
44dwfl_assert(const std::string& desc, const void* ptr,
45 const std::string& file, int line)
46{
47 if (!ptr)
48 dwfl_assert(desc, -1, file, line);
49}
50
51// Throw error if condition is false
52inline void
53dwfl_assert(const std::string& desc, bool condition,
54 const std::string& file, int line)
55{
56 if (!condition)
57 dwfl_assert(desc, -1, file, line);
58}
59
60#define DWARF_ASSERT(desc, arg) \
61 dwarf_assert(desc, arg, __FILE__, __LINE__)
62
63// NB: "rc == 0" means OK in this case
64void dwarf_assert(const std::string& desc, int rc,
65 const std::string& file, int line);
66
67// Throw error if pointer is NULL
68inline void
69dwarf_assert(const std::string& desc, const void* ptr,
70 const std::string& file, int line)
71{
72 if (!ptr)
73 dwarf_assert(desc, -1, file, line);
74}
75
76#define DWARF_LINENO(line) \
77 safe_dwarf_lineno(line, __FILE__, __LINE__)
78
79inline int
80safe_dwarf_lineno(const Dwarf_Line* line,
81 const std::string& errfile, int errline)
82{
83 int lineno;
84 dwarf_assert("dwarf_lineno",
85 dwarf_lineno(const_cast<Dwarf_Line*>(line), &lineno),
86 errfile, errline);
87 return lineno;
88}
89
90#define DWARF_LINEADDR(line) \
91 safe_dwarf_lineaddr(line, __FILE__, __LINE__)
92
93inline Dwarf_Addr
94safe_dwarf_lineaddr(const Dwarf_Line* line,
95 const std::string& errfile, int errline)
96{
97 Dwarf_Addr addr;
98 dwarf_assert("dwarf_lineaddr",
99 dwarf_lineaddr(const_cast<Dwarf_Line*>(line), &addr),
100 errfile, errline);
101 return addr;
102}
103
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
111inline const char*
112safe_dwarf_linesrc(const Dwarf_Line* line,
113 Dwarf_Word* mtime,
114 Dwarf_Word* length,
115 const std::string& errfile, int errline)
116{
117 const char* linesrc =
118 dwarf_linesrc(const_cast<Dwarf_Line*>(line), mtime, length);
119 dwarf_assert("dwarf_linesrc", linesrc, errfile, errline);
120 return linesrc;
121}
122
123#define DWARF_LINEPROLOGUEEND(line) \
124 safe_dwarf_lineprologueend(line, __FILE__, __LINE__)
125
126inline bool
127safe_dwarf_lineprologueend(const Dwarf_Line* line,
128 const std::string& errfile, int errline)
129{
130 bool flag;
131 dwarf_assert("is_prologue_end",
132 dwarf_lineprologueend(const_cast<Dwarf_Line*>(line), &flag),
133 errfile, errline);
134 return flag;
135}
136
137
138// Look up the DIE for a reference-form attribute name
139inline Dwarf_Die *
140dwarf_attr_die (Dwarf_Die *die, unsigned int attr, Dwarf_Die *result)
141{
142 Dwarf_Attribute attr_mem;
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)
158 DWFL_ASSERT("type_unit child", dwarf_child (result, result));
159 }
160 return result;
161 }
162 return NULL;
163}
164
165
166// Retrieve the linkage name of a die, either by the MIPS vendor extension or
167// DWARF4's standardized attribute.
168inline const char *
169dwarf_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
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
183const char *dwarf_decl_file_integrate (Dwarf_Die *die);
184#define dwarf_decl_file dwarf_decl_file_integrate
185
186int 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
193// Resolve a C declaration for dwarf types
194bool dwarf_type_decl(Dwarf_Die *type_die, const std::string& var_name, std::string& decl);
195
196// Resolve a full name for dwarf types
197bool dwarf_type_name(Dwarf_Die *type_die, std::string& type_name);
198std::string dwarf_type_name(Dwarf_Die *type_die);
199
200
201#endif
202
203/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.020832 seconds and 5 git commands to generate.