9#ifndef INCLUDED_BALST_RESOLVER_DWARFREADER
10#define INCLUDED_BALST_RESOLVER_DWARFREADER
78#include <balscm_version.h>
94#include <bsl_cstddef.h>
95#include <bsl_cstring.h>
96#include <bsl_string.h>
101#if defined(BALST_OBJECTFILEFORMAT_RESOLVER_DWARF)
107class Resolver_DwarfReader {
110 typedef bdls::FilesystemUtil::Offset Offset;
127 void reset(Offset offset = 0, Offset size = 0);
133 enum { k_SCRATCH_BUF_LEN =
134 Resolver_FileHelper::k_DEFAULT_SCRATCH_BUF_LEN };
159 e_DW_AT_sibling = 0x01,
160 e_DW_AT_location = 0x02,
162 e_DW_AT_ordering = 0x09,
163 e_DW_AT_byte_size = 0x0b,
164 e_DW_AT_bit_offset = 0x0c,
165 e_DW_AT_bit_size = 0x0d,
166 e_DW_AT_stmt_list = 0x10,
167 e_DW_AT_low_pc = 0x11,
168 e_DW_AT_high_pc = 0x12,
169 e_DW_AT_language = 0x13,
170 e_DW_AT_discr = 0x15,
171 e_DW_AT_discr_value = 0x16,
172 e_DW_AT_visibility = 0x17,
173 e_DW_AT_import = 0x18,
174 e_DW_AT_string_length = 0x19,
175 e_DW_AT_common_reference = 0x1a,
176 e_DW_AT_comp_dir = 0x1b,
177 e_DW_AT_const_value = 0x1c,
178 e_DW_AT_containing_type = 0x1d,
179 e_DW_AT_default_value = 0x1e,
180 e_DW_AT_inline = 0x20,
181 e_DW_AT_is_optional = 0x21,
182 e_DW_AT_lower_bound = 0x22,
183 e_DW_AT_producer = 0x25,
184 e_DW_AT_prototyped = 0x27,
185 e_DW_AT_return_addr = 0x2a,
186 e_DW_AT_start_scope = 0x2c,
187 e_DW_AT_bit_stride = 0x2e,
188 e_DW_AT_upper_bound = 0x2f,
189 e_DW_AT_abstract_origin = 0x31,
190 e_DW_AT_accessibility = 0x32,
191 e_DW_AT_address_class = 0x33,
192 e_DW_AT_artificial = 0x34,
193 e_DW_AT_base_types = 0x35,
194 e_DW_AT_calling_convention = 0x36,
195 e_DW_AT_count = 0x37,
196 e_DW_AT_data_member_location = 0x38,
197 e_DW_AT_decl_column = 0x39,
198 e_DW_AT_decl_file = 0x3a,
199 e_DW_AT_decl_line = 0x3b,
200 e_DW_AT_declaration = 0x3c,
201 e_DW_AT_discr_list = 0x3d,
202 e_DW_AT_encoding = 0x3e,
203 e_DW_AT_external = 0x3f,
204 e_DW_AT_frame_base = 0x40,
205 e_DW_AT_friend = 0x41,
206 e_DW_AT_identifier_case = 0x42,
207 e_DW_AT_macro_info = 0x43,
208 e_DW_AT_namelist_item = 0x44,
209 e_DW_AT_priority = 0x45,
210 e_DW_AT_segment = 0x46,
211 e_DW_AT_specification = 0x47,
212 e_DW_AT_static_link = 0x48,
214 e_DW_AT_use_location = 0x4a,
215 e_DW_AT_variable_parameter = 0x4b,
216 e_DW_AT_virtuality = 0x4c,
217 e_DW_AT_vtable_elem_location = 0x4d,
218 e_DW_AT_allocated = 0x4e,
219 e_DW_AT_associated = 0x4f,
220 e_DW_AT_data_location = 0x50,
221 e_DW_AT_byte_stride = 0x51,
222 e_DW_AT_entry_pc = 0x52,
223 e_DW_AT_use_UTF8 = 0x53,
224 e_DW_AT_extension = 0x54,
225 e_DW_AT_ranges = 0x55,
226 e_DW_AT_trampoline = 0x56,
227 e_DW_AT_call_column = 0x57,
228 e_DW_AT_call_file = 0x58,
229 e_DW_AT_call_line = 0x59,
230 e_DW_AT_description = 0x5a,
231 e_DW_AT_binary_scale = 0x5b,
232 e_DW_AT_decimal_scale = 0x5c,
233 e_DW_AT_small = 0x5d,
234 e_DW_AT_decimal_sign = 0x5e,
235 e_DW_AT_digit_count = 0x5f,
236 e_DW_AT_picture_string = 0x60,
237 e_DW_AT_mutable = 0x61,
238 e_DW_AT_threads_scaled = 0x62,
239 e_DW_AT_explicit = 0x63,
240 e_DW_AT_object_pointer = 0x64,
241 e_DW_AT_endianity = 0x65,
242 e_DW_AT_elemental = 0x66,
244 e_DW_AT_recursive = 0x68,
246 e_DW_CHILDREN_no = 0x00,
247 e_DW_CHILDREN_yes = 0x01,
249 e_DW_FORM_addr = 0x01,
250 e_DW_FORM_block2 = 0x03,
251 e_DW_FORM_block4 = 0x04,
252 e_DW_FORM_data2 = 0x05,
253 e_DW_FORM_data4 = 0x06,
254 e_DW_FORM_data8 = 0x07,
255 e_DW_FORM_string = 0x08,
256 e_DW_FORM_block = 0x09,
257 e_DW_FORM_block1 = 0x0a,
258 e_DW_FORM_data1 = 0x0b,
259 e_DW_FORM_flag = 0x0c,
260 e_DW_FORM_sdata = 0x0d,
261 e_DW_FORM_strp = 0x0e,
262 e_DW_FORM_udata = 0x0f,
263 e_DW_FORM_ref_addr = 0x10,
264 e_DW_FORM_ref1 = 0x11,
265 e_DW_FORM_ref2 = 0x12,
266 e_DW_FORM_ref4 = 0x13,
267 e_DW_FORM_ref8 = 0x14,
268 e_DW_FORM_ref_udata = 0x15,
269 e_DW_FORM_indirect = 0x16,
270 e_DW_FORM_line_strp = 0x1f,
272 e_DW_INL_declared_inlined = 0x03,
274 e_DW_LNCT_path = 0x01,
275 e_DW_LNCT_directory_index = 0x02,
276 e_DW_LNCT_timestamp = 0x03,
277 e_DW_LNCT_size = 0x04,
278 e_DW_LNCT_MD5 = 0x05,
279 e_DW_LNCT_lo_user = 0x2000,
280 e_DW_LNCT_hi_user = 0x3fff,
282 e_DW_LNE_end_sequence = 0x01,
283 e_DW_LNE_set_address = 0x02,
284 e_DW_LNE_define_file = 0x03,
286 e_DW_LNS_copy = 0x01,
287 e_DW_LNS_advance_pc = 0x02,
288 e_DW_LNS_advance_line = 0x03,
289 e_DW_LNS_set_file = 0x04,
290 e_DW_LNS_set_column = 0x05,
291 e_DW_LNS_negate_stmt = 0x06,
292 e_DW_LNS_set_basic_block = 0x07,
293 e_DW_LNS_const_add_pc = 0x08,
294 e_DW_LNS_fixed_advance_pc = 0x09,
295 e_DW_LNS_set_prologue_end = 0x0a,
296 e_DW_LNS_set_epilogue_begin = 0x0b,
297 e_DW_LNS_set_isa = 0x0c,
299 e_DW_TAG_array_type = 0x01,
300 e_DW_TAG_class_type = 0x02,
301 e_DW_TAG_entry_point = 0x03,
302 e_DW_TAG_enumeration_type = 0x04,
303 e_DW_TAG_formal_parameter = 0x05,
304 e_DW_TAG_imported_declaration = 0x08,
305 e_DW_TAG_label = 0x0a,
306 e_DW_TAG_lexical_block = 0x0b,
307 e_DW_TAG_member = 0x0d,
308 e_DW_TAG_pointer_type = 0x0f,
309 e_DW_TAG_reference_type = 0x10,
310 e_DW_TAG_compile_unit = 0x11,
311 e_DW_TAG_string_type = 0x12,
312 e_DW_TAG_structure_type = 0x13,
313 e_DW_TAG_subroutine_type = 0x15,
314 e_DW_TAG_typedef = 0x16,
315 e_DW_TAG_union_type = 0x17,
316 e_DW_TAG_unspecified_parameters = 0x18,
317 e_DW_TAG_variant = 0x19,
318 e_DW_TAG_common_block = 0x1a,
319 e_DW_TAG_common_inclusion = 0x1b,
320 e_DW_TAG_inheritance = 0x1c,
321 e_DW_TAG_inlined_subroutine = 0x1d,
322 e_DW_TAG_module = 0x1e,
323 e_DW_TAG_ptr_to_member_type = 0x1f,
324 e_DW_TAG_set_type = 0x20,
325 e_DW_TAG_subrange_type = 0x21,
326 e_DW_TAG_with_stmt = 0x22,
327 e_DW_TAG_access_declaration = 0x23,
328 e_DW_TAG_base_type = 0x24,
329 e_DW_TAG_catch_block = 0x25,
330 e_DW_TAG_const_type = 0x26,
331 e_DW_TAG_constant = 0x27,
332 e_DW_TAG_enumerator = 0x28,
333 e_DW_TAG_file_type = 0x29,
334 e_DW_TAG_friend = 0x2a,
335 e_DW_TAG_namelist = 0x2b,
336 e_DW_TAG_namelist_item = 0x2c,
337 e_DW_TAG_packed_type = 0x2d,
338 e_DW_TAG_subprogram = 0x2e,
339 e_DW_TAG_template_type_parameter = 0x2f,
340 e_DW_TAG_template_value_parameter = 0x30,
341 e_DW_TAG_thrown_type = 0x31,
342 e_DW_TAG_try_block = 0x32,
343 e_DW_TAG_variant_part = 0x33,
344 e_DW_TAG_variable = 0x34,
345 e_DW_TAG_volatile_type = 0x35,
346 e_DW_TAG_dwarf_procedure = 0x36,
347 e_DW_TAG_restrict_type = 0x37,
348 e_DW_TAG_interface_type = 0x38,
349 e_DW_TAG_namespace = 0x39,
350 e_DW_TAG_imported_module = 0x3a,
351 e_DW_TAG_unspecified_type = 0x3b,
352 e_DW_TAG_partial_unit = 0x3c,
353 e_DW_TAG_imported_unit = 0x3d,
354 e_DW_TAG_condition = 0x3f,
355 e_DW_TAG_shared_type = 0x40,
356 e_DW_TAG_lo_user = 0x4080,
357 e_DW_TAG_hi_user = 0xffff
363 e_DW_AT_signature = 0x69,
364 e_DW_AT_main_subprogram = 0x6a,
365 e_DW_AT_data_bit_offset = 0x6b,
366 e_DW_AT_const_expr = 0x6c,
367 e_DW_AT_enum_class = 0x6d,
368 e_DW_AT_linkage_name = 0x6e,
369 e_DW_AT_lo_user = 0x2000,
370 e_DW_AT_hi_user = 0x3fff,
372 e_DW_FORM_sec_offset = 0x17,
373 e_DW_FORM_exprloc = 0x18,
374 e_DW_FORM_flag_present = 0x19,
375 e_DW_FORM_ref_sig8 = 0x20,
377 e_DW_LNE_set_discriminator = 0x04,
379 e_DW_TAG_mutable_type = 0x3e,
380 e_DW_TAG_type_unit = 0x41,
381 e_DW_TAG_rvalue_reference_type = 0x42,
382 e_DW_TAG_template_alias = 0x43
386 e_DW_UT_compile = 0x1,
388 e_DW_UT_partial = 0x3,
389 e_DW_UT_skeleton = 0x4,
390 e_DW_UT_split_compile = 0x5,
391 e_DW_UT_split_type = 0x6,
392 e_DW_UT_lo_user = 0x80,
393 e_DW_UT_hi_user = 0xff
398 balst::Resolver_FileHelper *d_helper_p;
406 Offset d_beginOffset;
410 const char *d_readPtr;
413 const char *d_endPtr;
424 Resolver_DwarfReader(
const Resolver_DwarfReader&);
425 Resolver_DwarfReader& operator=(
const Resolver_DwarfReader&);
435 int needBytes(bsl::size_t numBytes);
441 int reload(bsl::size_t numBytes);
446 const char *stringForAt(
unsigned id);
450 const char *stringForForm(
unsigned id);
454 const char *stringForInlineState(
unsigned inlineState);
459 const char *stringForLNCT(
unsigned id);
463 const char *stringForLNE(
unsigned id);
467 const char *stringForLNS(
unsigned id);
471 const char *stringForTag(
unsigned tag);
477 Resolver_DwarfReader();
480 ~Resolver_DwarfReader() =
default;
492 int init(balst::Resolver_FileHelper *fileHelper,
494 const Section& section,
495 Offset libraryFileSize);
501 int readAddress(UintPtr *dst);
505 int readAddress(UintPtr *dst,
unsigned form);
511 int readAddressSize();
527 int readInitialLength(Offset *dst);
531 template <
class TYPE>
532 int readLEB128(TYPE *dst);
536 template <
class TYPE>
537 int readULEB128(TYPE *dst);
543 int readOffset(Offset *dst,
544 bsl::size_t offsetSize);
549 int readOffsetFromForm(Offset *dst,
557 int readSectionOffset(Offset *dst);
580 Resolver_DwarfReader *strReader,
581 Resolver_DwarfReader *lineStrReader,
586 template <
class TYPE>
587 int readValue(TYPE *dst);
592 int setAddressSize(
unsigned size);
595 int setEndOffset(Offset newOffset);
598 int skipBytes(Offset bytes);
605 int skipForm(
unsigned form);
609 int skipTo(Offset offset);
618 int addressSize()
const;
622 bool atEndOfSection()
const;
625 Offset offset()
const;
629 Offset offsetSize()
const;
632 bool isEnabled()
const;
637int Resolver_DwarfReader::needBytes(bsl::size_t numBytes)
639 IntPtr diff = d_endPtr - d_readPtr;
641 if (diff <
static_cast<IntPtr
>(numBytes)) {
644 return reload(numBytes);
651int Resolver_DwarfReader::readLEB128(TYPE *dst)
659 unsigned char u = 0x80;
661 enum { k_MAX_SHIFT =
sizeof(*dst) * 8 };
674 const Uint64 masked = 0x7f & u;
676 tmpDst |= masked << shift;
679 if (
static_cast<TYPE
>(-1) < 0) {
682 const Uint64 negFlag =
static_cast<Uint64
>(0x40) << shift;
683 if (negFlag & tmpDst) {
684 tmpDst |= ~(negFlag - 1);
688 *dst =
static_cast<TYPE
>(tmpDst);
694int Resolver_DwarfReader::readULEB128(TYPE *dst)
698 unsigned char u = 0x80;
701 for (; (0x80 & u); shift += 7) {
702 int rc = readValue(&u);
711 const Uint64 masked = 0x7f & u;
712 tmpDst |= masked << shift;
714#if defined(BSLS_ASSERT_LEVEL_ASSERT_SAFE)
715 if (shift >=
sizeof(*dst) * 8 + 7) {
724 *dst =
static_cast<TYPE
>(tmpDst);
731int Resolver_DwarfReader::readValue(TYPE *dst)
733 int rc = needBytes(
sizeof(*dst));
742 bsl::memcpy(dst, d_readPtr,
sizeof(*dst));
743 d_readPtr +=
sizeof(*dst);
749int Resolver_DwarfReader::skipBytes(Offset bytes)
753 if (bytes > d_endPtr - d_readPtr) {
754 Offset off = offset();
756 if (off < d_beginOffset) {
759 if (off + bytes > d_endOffset) {
766 d_offset += bytes + (d_readPtr - d_buffer_p);
767 d_readPtr = d_buffer_p;
768 d_endPtr = d_readPtr;
778int Resolver_DwarfReader::skipString()
781 int rc = needBytes(1);
785 }
while (*d_readPtr++);
792int Resolver_DwarfReader::addressSize()
const
794 return d_addressSize;
798bool Resolver_DwarfReader::atEndOfSection()
const
800 return d_readPtr == d_endPtr &&
801 d_endOffset - d_offset == d_readPtr - d_buffer_p;
805Resolver_DwarfReader::Offset
806Resolver_DwarfReader::offset()
const
808 return d_offset + (d_readPtr - d_buffer_p);
812Resolver_DwarfReader::Offset
813Resolver_DwarfReader::offsetSize()
const
819bool Resolver_DwarfReader::isEnabled()
const
821 return 0 != d_buffer_p;
Definition bslstl_string.h:1252
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balst_objectfileformat.h:152
void reset(TYPE *object)
Reset the value of the specified object to its default value.
std::size_t UintPtr
Definition bsls_types.h:128
unsigned long long Uint64
Definition bsls_types.h:139
std::ptrdiff_t IntPtr
Definition bsls_types.h:132