BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balst_resolverimpl_elf.h
Go to the documentation of this file.
1/// @file balst_resolverimpl_elf.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balst_resolverimpl_elf.h -*-C++-*-
8#ifndef INCLUDED_BALST_RESOLVERIMPL_ELF
9#define INCLUDED_BALST_RESOLVERIMPL_ELF
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balst_resolverimpl_elf balst_resolverimpl_elf
15/// @brief Provide a utility to resolve ELF symbols in a stack trace.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balst
19/// @{
20/// @addtogroup balst_resolverimpl_elf
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balst_resolverimpl_elf-purpose"> Purpose</a>
25/// * <a href="#balst_resolverimpl_elf-classes"> Classes </a>
26/// * <a href="#balst_resolverimpl_elf-description"> Description </a>
27/// * <a href="#balst_resolverimpl_elf-usage"> Usage </a>
28///
29/// # Purpose {#balst_resolverimpl_elf-purpose}
30/// Provide a utility to resolve ELF symbols in a stack trace.
31///
32/// # Classes {#balst_resolverimpl_elf-classes}
33///
34/// - balst::ResolverImpl<Elf>: symbol resolution for ELF objects
35///
36/// @see balst_resolver_dwarfreader,
37/// balst_resolverimpl_windows,
38/// balst_resolverimpl_xcoff
39///
40/// # Description {#balst_resolverimpl_elf-description}
41/// This component provides a class,
42/// `balst::Resolver<Elf>`, that, given a vector of
43/// `balst::StackTraceFrame`s that have only their `address` fields set,
44/// resolves all other fields in those frames. The Elf object file format is
45/// used on Linux and Solaris platforms. The Elf format is described by
46/// documents at:
47/// * `http://en.wikipedia.org/wiki/Executable_and_Linkable_Format`
48/// * `ftp://ftp.openwatcom.org/pub/devel/docs/elf-64-gen.pdf`
49/// * `http://www.sco.com/developers/gabi/latest/contents.html`
50///
51/// ## Usage {#balst_resolverimpl_elf-usage}
52///
53///
54/// This component is an implementation detail of `balst` and is *not* intended
55/// for direct client use. It is subject to change without notice. As such, a
56/// usage example is not provided.
57/// @}
58/** @} */
59/** @} */
60
61/** @addtogroup bal
62 * @{
63 */
64/** @addtogroup balst
65 * @{
66 */
67/** @addtogroup balst_resolverimpl_elf
68 * @{
69 */
70
71#include <balscm_version.h>
72
74
75#if defined(BALST_OBJECTFILEFORMAT_RESOLVER_ELF)
76#include <balst_stacktrace.h>
79
81
82#include <bdls_filesystemutil.h>
83
84#include <bsls_types.h>
85
86#include <bsl_vector.h>
87
88
89namespace balst {
90
91template <class RESOLVER_POLICY>
92class ResolverImpl;
93
94 // =========================================
95 // class ResolverImpl<ObjectFileFormat::Elf>
96 // =========================================
97
98/// This class provides a public static `resolve` method that, given a
99/// vector of `StackTraceFrame`s that have only their `address` fields set,
100/// resolves as many other fields in those frames as possible. The Elf
101/// object file format is used on Linux and Solaris platforms. On Linux,
102/// some Elf sections contain data in the DWARF format, which makes it
103/// possible to resolve line numbers and file names.
104template <>
105class ResolverImpl<ObjectFileFormat::Elf> {
106
107 // TYPES
108 typedef bsls::Types::UintPtr UintPtr; // 32 bit unsigned on 32 bit, 64
109 // bit unsigned on 64 bit.
110 typedef bsls::Types::IntPtr IntPtr; // 32 bit signed on 32 bit, 64
111 // bit signed on 64 bit.
112
113 typedef bdls::FilesystemUtil::Offset
114 Offset; // Usually used for relative
115 // offsets into a file.
116
117 typedef bsl::span<char> Span; // Range of writable characters.
118
119 struct HiddenRec; // 'struct' defined locally in
120 // in the imp file containing
121 // additional information
122
123 // DATA
125 d_hbpAlloc; // heap bypass allocator -- owned
126
127 StackTrace *d_stackTrace_p; // pointer to stack trace object.
128 // The frames contained in this
129 // have their 'address' fields and
130 // nothing else initialized upon
131 // entry to 'resolve', which infers
132 // as many other fields of them as
133 // possible.
134
135 char *d_scratchBufA_p; // scratch buffer A
136
137 char *d_scratchBufB_p; // scratch buffer B
138
139 char *d_scratchBufC_p; // scratch buffer C
140
141 char *d_scratchBufD_p; // scratch buffer D
142
143 char *d_scratchBufE_p; // scratch buffer E
144
145 HiddenRec& d_hidden; // reference to the 'HiddenRec'.
146
147 bool d_demangle; // whether we demangle names
148
149 bool d_isMainExecutable; // 'true' if in main executable
150 // segment, as opposed to a shared
151 // library
152
153 private:
154 // NOT IMPLEMENTED
155 ResolverImpl(const ResolverImpl&);
156 ResolverImpl& operator=(const ResolverImpl&);
157
158 private:
159 // PRIVATE CREATORS
160
161 /// Create an stack trace reolver that can populate other fields of the
162 /// specified `*stackTrace` object given previously populated `address`
163 /// fields. Specify `demangle`, which indicates whether demangling of
164 /// symbols is to occur.
165 ResolverImpl(StackTrace *stackTrace,
166 bool demanglingPreferredFlag);
167
168 /// Destroy this object.
169 ~ResolverImpl() = default;
170
171 // PRIVATE MANIPULATORS
172
173 /// Read the symbols from the symbol table of the current segment and
174 /// update the `mangledSymbolName`, `symbolName`, `offsetFromSymbol`,
175 /// and sometimes the `SourceFileName` fields of stack frames constain
176 /// addresses within the code section of the current segment, where the
177 /// specified `matched` is the number of addresses in the current
178 /// segment. Return 0 on success and a non-zero value otherwise.
179 int loadSymbols(int matched);
180
181 /// Identify which stack trace frames in `*d_stackTrace_p` are in the
182 /// segment pointed at by the specified `segmentPtr` of the specified
183 /// `segmentSize`, and initialize as many fields of those stack trace
184 /// frames as possible. The name of the executable file or shared segment
185 /// in the file system is `libraryFileName`. Return 0 on success and a
186 /// non-zero value otherwise.
187 int resolveSegment(void *segmentBaseAddress,
188 void *segmentPtr,
189 UintPtr segmentSize,
190 const char *libraryFileName);
191
192 // PRIVATE ACCESSORS
193
194 /// Set the `symbolName` field of the specified `frame`, which must already
195 /// have the `mangledSymbolName` field set, to the demangled version of the
196 /// `mangledSymbolName` field. Use the specified `scratchSpan` for
197 /// temporary storage. If `d_demangle` is `false` or we are otherwise
198 /// unable to demangle, just set it to the same as `mangledSymbolName`.
199 void setFrameSymbolName(StackTraceFrame *frame,
200 const Span& scratchSpan) const;
201
202 public:
203 // CLASS METHOD
204
205 /// Populate information for the specified `*stackTrace`, which contains
206 /// a sequence of randomly-accessible stack trace frames. Specify
207 /// `demanglingPreferredFlag`, to determine whether demangling is to occur.
208 ///
209 /// \pre The behavior is undefined unless all the `address` field in
210 /// `*stackTrace` are valid and other fields are invalid.
211 static int resolve(StackTrace *stackTrace,
212 bool demanglingPreferredFlag);
213
214 /// This function is just there to test how code deals with inline
215 /// functions in an include file. It does not provide any otherwise
216 /// useful functionality. Return a line number near the beginning of
217 /// the function in the low-order 14 bits of the result. Other bits of
218 /// the result are to be considered garbage.
219 static int test();
220
221 // MANIPULATOR
222
223 /// Process a loaded image found via the link map, either the main program
224 /// or some shared library. The specified `libraryFileName` is the name of
225 /// the file containing the image. The specified `programHeaders` is a
226 /// pointer to an array of elf program headers and the specified
227 /// `numProgramHeaders` is its length, it is a `void *` because the type
228 /// `ElfProgramHeader` is local to the implementation file. Specify one of
229 /// `textSegPtr` and `baseAddress`, and the other as 0, this method will
230 /// infer the one specified as 0 from the other. Specify
231 /// `isMainExecutable`, indicating whether the image is the main
232 /// executable. Return 0 on success and a non-zero value otherwise.
233 ///
234 /// \note Note that this method is not to be called by external users of this
235 /// component, it is only public so a static routine in the implementation
236 /// file can call it. Also note that if `isMainExecutable` is set,
237 /// `libraryFileName` is ignored and the `argv[0]` the program was called
238 /// with is used in its place.
239 int processLoadedImage(const char *libraryFileName,
240 const void *programHeaders,
241 int numProgramHeaders,
242 void *textSegPtr,
243 void *baseAddress,
244 bool isMainExecutable);
245
246 // ACCESSOR
247
248 /// Return the number of frames in the stack trace that are still
249 /// unmatched.
250 int numUnmatchedFrames() const;
251};
252
253inline
254int ResolverImpl<ObjectFileFormat::Elf>::test()
255{
256
257 StackTrace st;
258
259 int ret = __LINE__;
260 ResolverImpl<ObjectFileFormat::Elf> resolver(&st, true);
261
262 return (resolver.numUnmatchedFrames() << 14) | ret;
263}
264
265} // close package namespace
266
267
268#endif
269#endif
270
271// ----------------------------------------------------------------------------
272// Copyright 2015 Bloomberg Finance L.P.
273//
274// Licensed under the Apache License, Version 2.0 (the "License");
275// you may not use this file except in compliance with the License.
276// You may obtain a copy of the License at
277//
278// http://www.apache.org/licenses/LICENSE-2.0
279//
280// Unless required by applicable law or agreed to in writing, software
281// distributed under the License is distributed on an "AS IS" BASIS,
282// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
283// See the License for the specific language governing permissions and
284// limitations under the License.
285// ----------------------------- END-OF-FILE ----------------------------------
286
287/** @} */
288/** @} */
289/** @} */
Definition bdlma_heapbypassallocator.h:158
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balst_objectfileformat.h:152
std::size_t UintPtr
Definition bsls_types.h:128
std::ptrdiff_t IntPtr
Definition bsls_types.h:132