valgrind/valgrind-3.16.1-dwarf5.patch
DistroBaker 10aa54a869 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/valgrind.git#d18b4e034833d7f421b96dca5c41513e983a2f61
2021-01-26 02:23:19 +00:00

2411 lines
96 KiB
Diff

From 256a67e6a5a07e37997d3a5ef64204a99b8e5a50 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Mon, 25 Jan 2021 15:33:34 +0100
Subject: [PATCH] DWARF5
---
coregrind/m_debuginfo/d3basics.c | 99 ++++
coregrind/m_debuginfo/priv_d3basics.h | 195 +++++-
coregrind/m_debuginfo/priv_readdwarf.h | 3 +-
coregrind/m_debuginfo/priv_readdwarf3.h | 3 +-
coregrind/m_debuginfo/readdwarf.c | 465 ++++++++++++---
coregrind/m_debuginfo/readdwarf3.c | 748 +++++++++++++++++++-----
coregrind/m_debuginfo/readelf.c | 33 +-
coregrind/m_debuginfo/readmacho.c | 14 +-
8 files changed, 1304 insertions(+), 256 deletions(-)
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index b6d13c118..e1127ffe2 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -128,6 +128,16 @@ const HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
case DW_TAG_type_unit: return "DW_TAG_type_unit";
case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
case DW_TAG_template_alias: return "DW_TAG_template_alias";
+ /* DWARF 5. */
+ case DW_TAG_coarray_type: return "DW_TAG_coarray_type";
+ case DW_TAG_generic_subrange: return "DW_TAG_generic_subrange";
+ case DW_TAG_dynamic_type: return "DW_TAG_dynamic_type";
+ case DW_TAG_atomic_type: return "DW_TAG_atomic_type";
+ case DW_TAG_call_site: return "DW_TAG_call_site";
+ case DW_TAG_call_site_parameter:
+ return "DW_TAG_call_site_parameter";
+ case DW_TAG_skeleton_unit: return "DW_TAG_skeleton_unit";
+ case DW_TAG_immutable_type: return "DW_TAG_immutable_type";
/* SGI/MIPS Extensions. */
case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
/* HP extensions. See:
@@ -140,6 +150,16 @@ const HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
case DW_TAG_class_template: return "DW_TAG_class_template";
case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL";
case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL";
+ case DW_TAG_GNU_template_template_param:
+ return "DW_TAG_GNU_template_template_param";
+ case DW_TAG_GNU_template_parameter_pack:
+ return"DW_TAG_GNU_template_parameter_pack";
+ case DW_TAG_GNU_formal_parameter_pack:
+ return "DW_TAG_GNU_formal_parameter_pack";
+ case DW_TAG_GNU_call_site:
+ return "DW_TAG_GNU_call_site";
+ case DW_TAG_GNU_call_site_parameter:
+ return "DW_TAG_GNU_call_site_parameter";
/* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
@@ -180,6 +200,27 @@ const HChar* ML_(pp_DW_FORM) ( DW_FORM form )
case DW_FORM_exprloc: return "DW_FORM_exprloc";
case DW_FORM_flag_present:return "DW_FORM_flag_present";
case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
+ case DW_FORM_strx: return "DW_FORM_strx";
+ case DW_FORM_addrx: return "DW_FORM_addrx";
+ case DW_FORM_ref_sup4: return "DW_FORM_ref_sup4";
+ case DW_FORM_strp_sup: return "DW_FORM_strp_sup";
+ case DW_FORM_data16: return "DW_FORM_data16";
+ case DW_FORM_line_strp: return "DW_FORM_line_strp";
+ case DW_FORM_implicit_const:return "DW_FORM_implicit_const";
+ case DW_FORM_loclistx: return "DW_FORM_loclistx";
+ case DW_FORM_rnglistx: return "DW_FORM_rnglistx";
+ case DW_FORM_ref_sup8: return "DW_FORM_ref_sup8";
+ case DW_FORM_strx1: return "DW_FORM_strx1";
+ case DW_FORM_strx2: return "DW_FORM_strx2";
+ case DW_FORM_strx3: return "DW_FORM_strx3";
+ case DW_FORM_strx4: return "DW_FORM_strx4";
+ case DW_FORM_addrx1: return "DW_FORM_addrx1";
+ case DW_FORM_addrx2: return "DW_FORM_addrx2";
+ case DW_FORM_addrx3: return "DW_FORM_addrx3";
+ case DW_FORM_addrx4: return "DW_FORM_addrx4";
+ /* GNU Debug Fission extensions. */
+ case DW_FORM_GNU_addr_index:return "DW_FORM_GNU_addr_index";
+ case DW_FORM_GNU_str_index:return "DW_FORM_GNU_str_index";
case DW_FORM_GNU_ref_alt:return "DW_FORM_GNU_ref_alt";
case DW_FORM_GNU_strp_alt:return "DW_FORM_GNU_strp_alt";
}
@@ -286,6 +327,36 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr )
case DW_AT_const_expr: return "DW_AT_const_expr";
case DW_AT_enum_class: return "DW_AT_enum_class";
case DW_AT_linkage_name: return "DW_AT_linkage_name";
+ /* DWARF 5 values. */
+ case DW_AT_string_length_bit_size: return "DW_AT_string_length_bit_size";
+ case DW_AT_string_length_byte_size: return "DW_AT_string_length_byte_size";
+ case DW_AT_rank: return "DW_AT_rank";
+ case DW_AT_str_offsets_base: return "DW_AT_str_offsets_base";
+ case DW_AT_addr_base: return "DW_AT_addr_base";
+ case DW_AT_rnglists_base: return "DW_AT_rnglists_base";
+ case DW_AT_dwo_name: return "DW_AT_dwo_name";
+ case DW_AT_reference: return "DW_AT_reference";
+ case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference";
+ case DW_AT_macros: return "DW_AT_macros";
+ case DW_AT_call_all_calls: return "DW_AT_call_all_calls";
+ case DW_AT_call_all_source_calls: return "DW_AT_call_all_source_calls";
+ case DW_AT_call_all_tail_calls: return "DW_AT_call_all_tail_calls";
+ case DW_AT_call_return_pc: return "DW_AT_call_return_pc";
+ case DW_AT_call_value: return "DW_AT_call_value";
+ case DW_AT_call_origin: return "DW_AT_call_origin";
+ case DW_AT_call_parameter: return "DW_AT_call_parameter";
+ case DW_AT_call_pc: return "DW_AT_call_pc";
+ case DW_AT_call_tail_call: return "DW_AT_call_tail_call";
+ case DW_AT_call_target: return "DW_AT_call_target";
+ case DW_AT_call_target_clobbered: return "DW_AT_call_target_clobbered";
+ case DW_AT_call_data_location: return "DW_AT_call_data_location";
+ case DW_AT_call_data_value: return "DW_AT_call_data_value";
+ case DW_AT_noreturn: return "DW_AT_noreturn";
+ case DW_AT_alignment: return "DW_AT_alignment";
+ case DW_AT_export_symbols: return "DW_AT_export_symbols";
+ case DW_AT_deleted: return "DW_AT_deleted";
+ case DW_AT_defaulted: return "DW_AT_defaulted";
+ case DW_AT_loclists_base: return "DW_AT_loclists_base";
/* SGI/MIPS extensions. */
/* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
/* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */
@@ -322,8 +393,36 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr )
case DW_AT_body_begin: return "DW_AT_body_begin";
case DW_AT_body_end: return "DW_AT_body_end";
case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
+ case DW_AT_GNU_guarded_by: return "DW_AT_GNU_guarded_by";
+ case DW_AT_GNU_pt_guarded_by: return "DW_AT_GNU_pt_guarded_by";
+ case DW_AT_GNU_guarded: return "DW_AT_GNU_guarded";
+ case DW_AT_GNU_pt_guarded: return "DW_AT_GNU_pt_guarded";
+ case DW_AT_GNU_locks_excluded: return "DW_AT_GNU_locks_excluded";
+ case DW_AT_GNU_exclusive_locks_required: return "DW_AT_GNU_exclusive_locks_required";
+ case DW_AT_GNU_shared_locks_required: return "DW_AT_GNU_shared_locks_required";
+ case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature";
+ case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name";
+ case DW_AT_GNU_call_site_value: return "DW_AT_GNU_call_site_value";
+ case DW_AT_GNU_call_site_data_value: return "DW_AT_GNU_call_site_data_value";
+ case DW_AT_GNU_call_site_target: return "DW_AT_GNU_call_site_target";
+ case DW_AT_GNU_call_site_target_clobbered: return "DW_AT_GNU_call_site_target_clobbered";
+ case DW_AT_GNU_tail_call: return "DW_AT_GNU_tail_call";
case DW_AT_GNU_all_tail_call_sites: return "DW_AT_GNU_all_tail_call_sites";
case DW_AT_GNU_all_call_sites: return "DW_AT_GNU_all_call_sites";
+ case DW_AT_GNU_all_source_call_sites: return "DW_AT_GNU_all_source_call_sites";
+ case DW_AT_GNU_locviews: return "DW_AT_GNU_locviews";
+ case DW_AT_GNU_entry_view: return "DW_AT_GNU_entry_view";
+ case DW_AT_GNU_macros: return "DW_AT_GNU_macros";
+ case DW_AT_GNU_deleted: return "DW_AT_GNU_deleted";
+ case DW_AT_GNU_dwo_name: return "DW_AT_GNU_dwo_name";
+ case DW_AT_GNU_dwo_id: return "DW_AT_GNU_dwo_id";
+ case DW_AT_GNU_ranges_base: return "DW_AT_GNU_ranges_base";
+ case DW_AT_GNU_addr_base: return "DW_AT_GNU_addr_base";
+ case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames";
+ case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes";
+ case DW_AT_GNU_numerator: return "DW_AT_GNU_numerator";
+ case DW_AT_GNU_denominator: return "DW_AT_GNU_denominator";
+ case DW_AT_GNU_bias: return "DW_AT_GNU_bias";
/* VMS extensions. */
case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address";
/* UPC extension. */
diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h
index b60e3e8eb..9d825e39e 100644
--- a/coregrind/m_debuginfo/priv_d3basics.h
+++ b/coregrind/m_debuginfo/priv_d3basics.h
@@ -108,6 +108,15 @@ typedef enum
DW_TAG_type_unit = 0x41,
DW_TAG_rvalue_reference_type = 0x42,
DW_TAG_template_alias = 0x43,
+ /* DWARF 5. */
+ DW_TAG_coarray_type = 0x44,
+ DW_TAG_generic_subrange = 0x45,
+ DW_TAG_dynamic_type = 0x46,
+ DW_TAG_atomic_type = 0x47,
+ DW_TAG_call_site = 0x48,
+ DW_TAG_call_site_parameter = 0x49,
+ DW_TAG_skeleton_unit = 0x4a,
+ DW_TAG_immutable_type = 0x4b,
/* SGI/MIPS Extensions. */
DW_TAG_MIPS_loop = 0x4081,
/* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
@@ -118,6 +127,11 @@ typedef enum
DW_TAG_class_template = 0x4103, /* For C++. */
DW_TAG_GNU_BINCL = 0x4104,
DW_TAG_GNU_EINCL = 0x4105,
+ DW_TAG_GNU_template_template_param = 0x4106,
+ DW_TAG_GNU_template_parameter_pack = 0x4107,
+ DW_TAG_GNU_formal_parameter_pack = 0x4108,
+ DW_TAG_GNU_call_site = 0x4109,
+ DW_TAG_GNU_call_site_parameter = 0x410a,
/* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
DW_TAG_upc_shared_type = 0x8765,
DW_TAG_upc_strict_type = 0x8766,
@@ -164,13 +178,23 @@ typedef enum dwarf_source_language
DW_LANG_D = 0x0013,
/* DWARF 4. */
DW_LANG_Python = 0x0014,
- /* DWARF 5-pre. Only what GCC already outputs. */
+ /* DWARF 5. */
DW_LANG_Go = 0x0016,
+ DW_LANG_Modula3 = 0x0017,
+ DW_LANG_Haskell = 0x0018,
+ DW_LANG_C_plus_plus_03 = 0x0019,
DW_LANG_C_plus_plus_11 = 0x001a,
+ DW_LANG_OCaml = 0x001b,
+ DW_LANG_Rust = 0x001c,
DW_LANG_C11 = 0x001d,
+ DW_LANG_Swift = 0x001e,
+ DW_LANG_Julia = 0x001f,
+ DW_LANG_Dylan = 0x0020,
DW_LANG_C_plus_plus_14 = 0x0021,
DW_LANG_Fortran03 = 0x0022,
DW_LANG_Fortran08 = 0x0023,
+ DW_LANG_RenderScript = 0x0024,
+ DW_LANG_BLISS = 0x0025,
/* MIPS. */
DW_LANG_Mips_Assembler = 0x8001,
/* UPC. */
@@ -207,6 +231,28 @@ typedef enum
DW_FORM_exprloc = 0x18,
DW_FORM_flag_present = 0x19,
DW_FORM_ref_sig8 = 0x20,
+ /* DWARF 5 values. */
+ DW_FORM_strx = 0x1a,
+ DW_FORM_addrx = 0x1b,
+ DW_FORM_ref_sup4 = 0x1c,
+ DW_FORM_strp_sup = 0x1d,
+ DW_FORM_data16 = 0x1e,
+ DW_FORM_line_strp = 0x1f,
+ DW_FORM_implicit_const = 0x21,
+ DW_FORM_loclistx = 0x22,
+ DW_FORM_rnglistx = 0x23,
+ DW_FORM_ref_sup8 = 0x24,
+ DW_FORM_strx1 = 0x25,
+ DW_FORM_strx2 = 0x26,
+ DW_FORM_strx3 = 0x27,
+ DW_FORM_strx4 = 0x28,
+ DW_FORM_addrx1 = 0x29,
+ DW_FORM_addrx2 = 0x2a,
+ DW_FORM_addrx3 = 0x2b,
+ DW_FORM_addrx4 = 0x2c,
+ /* GNU Debug Fission extensions. */
+ DW_FORM_GNU_addr_index = 0x1f01,
+ DW_FORM_GNU_str_index = 0x1f02,
/* Extensions for DWZ multifile.
See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . */
DW_FORM_GNU_ref_alt = 0x1f20,
@@ -314,6 +360,36 @@ typedef enum
DW_AT_const_expr = 0x6c,
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
+ DW_AT_string_length_bit_size = 0x6f,
+ DW_AT_string_length_byte_size = 0x70,
+ DW_AT_rank = 0x71,
+ DW_AT_str_offsets_base = 0x72,
+ DW_AT_addr_base = 0x73,
+ DW_AT_rnglists_base = 0x74,
+ /* 0x75 reserved. */
+ DW_AT_dwo_name = 0x76,
+ DW_AT_reference = 0x77,
+ DW_AT_rvalue_reference = 0x78,
+ DW_AT_macros = 0x79,
+ DW_AT_call_all_calls = 0x7a,
+ DW_AT_call_all_source_calls = 0x7b,
+ DW_AT_call_all_tail_calls = 0x7c,
+ DW_AT_call_return_pc = 0x7d,
+ DW_AT_call_value = 0x7e,
+ DW_AT_call_origin = 0x7f,
+ DW_AT_call_parameter = 0x80,
+ DW_AT_call_pc = 0x81,
+ DW_AT_call_tail_call = 0x82,
+ DW_AT_call_target = 0x83,
+ DW_AT_call_target_clobbered = 0x84,
+ DW_AT_call_data_location = 0x85,
+ DW_AT_call_data_value = 0x86,
+ DW_AT_noreturn = 0x87,
+ DW_AT_alignment = 0x88,
+ DW_AT_export_symbols = 0x89,
+ DW_AT_deleted = 0x8a,
+ DW_AT_defaulted = 0x8b,
+ DW_AT_loclists_base = 0x8c,
/* SGI/MIPS extensions. */
DW_AT_MIPS_fde = 0x2001,
DW_AT_MIPS_loop_begin = 0x2002,
@@ -349,8 +425,39 @@ typedef enum
DW_AT_body_begin = 0x2105,
DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107,
+ DW_AT_GNU_guarded_by = 0x2108,
+ DW_AT_GNU_pt_guarded_by = 0x2109,
+ DW_AT_GNU_guarded = 0x210a,
+ DW_AT_GNU_pt_guarded = 0x210b,
+ DW_AT_GNU_locks_excluded = 0x210c,
+ DW_AT_GNU_exclusive_locks_required = 0x210d,
+ DW_AT_GNU_shared_locks_required = 0x210e,
+ DW_AT_GNU_odr_signature = 0x210f,
+ DW_AT_GNU_template_name = 0x2110,
+ DW_AT_GNU_call_site_value = 0x2111,
+ DW_AT_GNU_call_site_data_value = 0x2112,
+ DW_AT_GNU_call_site_target = 0x2113,
+ DW_AT_GNU_call_site_target_clobbered = 0x2114,
+ DW_AT_GNU_tail_call = 0x2115,
DW_AT_GNU_all_tail_call_sites = 0x2116,
DW_AT_GNU_all_call_sites = 0x2117,
+ DW_AT_GNU_all_source_call_sites = 0x2118,
+ DW_AT_GNU_locviews = 0x2137,
+ DW_AT_GNU_entry_view = 0x2138,
+ DW_AT_GNU_macros = 0x2119,
+ DW_AT_GNU_deleted = 0x211a,
+ /* GNU Debug Fission extensions. */
+ DW_AT_GNU_dwo_name = 0x2130,
+ DW_AT_GNU_dwo_id = 0x2131,
+ DW_AT_GNU_ranges_base = 0x2132,
+ DW_AT_GNU_addr_base = 0x2133,
+ DW_AT_GNU_pubnames = 0x2134,
+ DW_AT_GNU_pubtypes = 0x2135,
+ /* https://gcc.gnu.org/wiki/DW_AT_GNU_numerator_denominator */
+ DW_AT_GNU_numerator = 0x2303,
+ DW_AT_GNU_denominator = 0x2304,
+ /* https://gcc.gnu.org/wiki/DW_AT_GNU_bias */
+ DW_AT_GNU_bias = 0x2305,
/* VMS extensions. */
DW_AT_VMS_rtnbeg_pd_address = 0x2201,
/* UPC extension. */
@@ -387,6 +494,9 @@ typedef enum
DW_ATE_decimal_float = 0xf,
/* DWARF 4. */
DW_ATE_UTF = 0x10,
+ /* DWARF 5. */
+ DW_ATE_UCS = 0x11,
+ DW_ATE_ASCII = 0x12,
/* HP extensions. */
DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */
DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */
@@ -558,8 +668,35 @@ typedef enum
/* DWARF 4 extensions. */
DW_OP_implicit_value = 0x9e,
DW_OP_stack_value = 0x9f,
+ /* DWARF 5 extensions. */
+ DW_OP_implicit_pointer = 0xa0,
+ DW_OP_addrx = 0xa1,
+ DW_OP_constx = 0xa2,
+ DW_OP_entry_value = 0xa3,
+ DW_OP_const_type = 0xa4,
+ DW_OP_regval_type = 0xa5,
+ DW_OP_deref_type = 0xa6,
+ DW_OP_xderef_type = 0xa7,
+ DW_OP_convert = 0xa8,
+ DW_OP_reinterpret = 0xa9,
/* GNU extensions. */
DW_OP_GNU_push_tls_address = 0xe0,
+ DW_OP_GNU_uninit = 0xf0,
+ DW_OP_GNU_encoded_addr = 0xf1,
+ DW_OP_GNU_implicit_pointer = 0xf2,
+ DW_OP_GNU_entry_value = 0xf3,
+ DW_OP_GNU_const_type = 0xf4,
+ DW_OP_GNU_regval_type = 0xf5,
+ DW_OP_GNU_deref_type = 0xf6,
+ DW_OP_GNU_convert = 0xf7,
+ DW_OP_GNU_reinterpret = 0xf9,
+ DW_OP_GNU_parameter_ref = 0xfa,
+ /* GNU Debug Fission extensions. */
+ DW_OP_GNU_addr_index = 0xfb,
+ DW_OP_GNU_const_index = 0xfc,
+ /* The GNU variable value extension.
+ See http://dwarfstd.org/ShowIssue.php?issue=161109.2 . */
+ DW_OP_GNU_variable_value = 0xfd,
/* HP extensions. */
DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
DW_OP_HP_is_value = 0xe1,
@@ -571,6 +708,62 @@ typedef enum
}
DW_OP;
+typedef enum
+ {
+ DW_UT_compile = 0x01,
+ DW_UT_type = 0x02,
+ DW_UT_partial = 0x03,
+ DW_UT_skeleton = 0x04,
+ DW_UT_split_compile = 0x05,
+ DW_UT_split_type = 0x06,
+
+ DW_UT_lo_user = 0x80,
+ DW_UT_hi_user = 0xff
+ }
+ DW_UT;
+
+typedef enum
+ {
+ DW_LNCT_path = 0x1,
+ DW_LNCT_directory_index = 0x2,
+ DW_LNCT_timestamp = 0x3,
+ DW_LNCT_size = 0x4,
+ DW_LNCT_MD5 = 0x5,
+
+ DW_LNCT_lo_user = 0x2000,
+ DW_LNCT_hi_user = 0x3fff
+ }
+ DW_LNCT;
+
+typedef enum
+ {
+ DW_RLE_end_of_list = 0x00,
+ DW_RLE_base_addressx = 0x01,
+ DW_RLE_startx_endx = 0x02,
+ DW_RLE_startx_length = 0x03,
+ DW_RLE_offset_pair = 0x04,
+ DW_RLE_base_address = 0x05,
+ DW_RLE_start_end = 0x06,
+ DW_RLE_start_length = 0x07
+ }
+ DW_RLE;
+
+typedef enum
+ {
+ DW_LLE_end_of_list = 0x00,
+ DW_LLE_base_addressx = 0x01,
+ DW_LLE_startx_endx = 0x02,
+ DW_LLE_startx_length = 0x03,
+ DW_LLE_offset_pair = 0x04,
+ DW_LLE_default_location = 0x05,
+ DW_LLE_base_address = 0x06,
+ DW_LLE_start_end = 0x07,
+ DW_LLE_start_length = 0x08,
+
+ DW_LLE_GNU_view_pair = 0x09
+ }
+ DW_LLE;
+
const HChar* ML_(pp_DW_children) ( DW_children hashch );
const HChar* ML_(pp_DW_TAG) ( DW_TAG tag );
const HChar* ML_(pp_DW_FORM) ( DW_FORM form );
diff --git a/coregrind/m_debuginfo/priv_readdwarf.h b/coregrind/m_debuginfo/priv_readdwarf.h
index 1e3f24c2a..302266924 100644
--- a/coregrind/m_debuginfo/priv_readdwarf.h
+++ b/coregrind/m_debuginfo/priv_readdwarf.h
@@ -50,7 +50,8 @@ void ML_(read_debuginfo_dwarf3)
DiSlice escn_debug_abbv, /* .debug_abbrev */
DiSlice escn_debug_line, /* .debug_line */
DiSlice escn_debug_str, /* .debug_str */
- DiSlice escn_debug_str_alt ); /* .debug_str */
+ DiSlice escn_debug_str_alt, /* .debug_str */
+ DiSlice escn_debug_line_str );/* .debug_line_str */
/* --------------------
DWARF1 reader
diff --git a/coregrind/m_debuginfo/priv_readdwarf3.h b/coregrind/m_debuginfo/priv_readdwarf3.h
index 1a5bd61c3..f6d1dd1ee 100644
--- a/coregrind/m_debuginfo/priv_readdwarf3.h
+++ b/coregrind/m_debuginfo/priv_readdwarf3.h
@@ -45,9 +45,10 @@ ML_(new_dwarf3_reader) (
DiSlice escn_debug_info, DiSlice escn_debug_types,
DiSlice escn_debug_abbv, DiSlice escn_debug_line,
DiSlice escn_debug_str, DiSlice escn_debug_ranges,
+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists,
DiSlice escn_debug_loc, DiSlice escn_debug_info_alt,
DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt,
- DiSlice escn_debug_str_alt
+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str
);
#endif /* ndef __PRIV_READDWARF3_H */
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index 5701c504b..88d5d99f1 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -322,6 +322,123 @@ void process_extended_line_op( struct _DebugInfo* di,
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
+static
+HChar * get_line_str (struct _DebugInfo* di, const UnitInfo* ui,
+ DiCursor *data, const UInt form,
+ DiCursor debugstr_img, DiCursor debuglinestr_img)
+{
+ HChar *str = NULL;
+ switch (form) {
+ case DW_FORM_string:
+ str = ML_(cur_step_strdup)(data, "di.gls.string");
+ break;
+ case DW_FORM_strp:
+ if (!ui->dw64)
+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debugstr_img,
+ ML_(cur_step_UInt)(data)),
+ "di.gls.strp.dw32");
+ else
+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debugstr_img,
+ ML_(cur_step_ULong)(data)),
+ "di.gls.strp.dw64");
+ break;
+ case DW_FORM_line_strp:
+ if (!ui->dw64)
+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debuglinestr_img,
+ ML_(cur_step_UInt)(data)),
+ "di.gls.line_strp.dw32");
+ else
+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debuglinestr_img,
+ ML_(cur_step_ULong)(data)),
+ "di.gls.line_strp.dw64");
+ break;
+ default:
+ ML_(symerr)(di, True,
+ "Unknown path string FORM in .debug_line");
+ break;
+ }
+ return str;
+}
+
+static
+Int get_line_ndx (struct _DebugInfo* di,
+ DiCursor *data, const UInt form)
+{
+ Int res = 0;
+ switch (form) {
+ case DW_FORM_data1:
+ res = ML_(cur_step_UChar)(data);
+ break;
+ case DW_FORM_data2:
+ res = ML_(cur_step_UShort)(data);
+ break;
+ case DW_FORM_udata:
+ res = step_leb128U(data);
+ break;
+ default:
+ ML_(symerr)(di, True,
+ "Unknown directory_index value FORM in .debug_line");
+ break;
+ }
+ return res;
+}
+
+static
+DiCursor skip_line_form (struct _DebugInfo* di, const UnitInfo* ui,
+ DiCursor d, const UInt form)
+{
+ switch (form) {
+ case DW_FORM_block: {
+ ULong len = step_leb128U(&d);
+ d = ML_(cur_plus)(d, len);
+ break;
+ }
+ case DW_FORM_block1:
+ d = ML_(cur_plus)(d, ML_(cur_read_UChar)(d) + 1);
+ break;
+ case DW_FORM_block2:
+ d = ML_(cur_plus)(d, ML_(cur_read_UShort)(d) + 2);
+ break;
+ case DW_FORM_block4:
+ d = ML_(cur_plus)(d, ML_(cur_read_UInt)(d) + 4);
+ break;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ d = ML_(cur_plus)(d, 1);
+ break;
+ case DW_FORM_data2:
+ d = ML_(cur_plus)(d, 2);
+ break;
+ case DW_FORM_data4:
+ d = ML_(cur_plus)(d, 4);
+ break;
+ case DW_FORM_data8:
+ d = ML_(cur_plus)(d, 8);
+ break;
+ case DW_FORM_data16:
+ d = ML_(cur_plus)(d, 16);
+ break;
+ case DW_FORM_string:
+ d = ML_(cur_plus)(d, ML_(cur_strlen)(d) + 1);
+ break;
+ case DW_FORM_strp:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ d = ML_(cur_plus)(d, ui->dw64 ? 8 : 4);
+ break;
+ case DW_FORM_udata:
+ (void)step_leb128U(&d);
+ break;
+ case DW_FORM_sdata:
+ (void)step_leb128S(&d);
+ break;
+ default:
+ ML_(symerr)(di, True, "Unknown FORM in .debug_line");
+ break;
+ }
+ return d;
+}
+
/* read a .debug_line section block for a compilation unit
*
* Input: - theBlock must point to the start of the block
@@ -335,7 +452,9 @@ static
void read_dwarf2_lineblock ( struct _DebugInfo* di,
const UnitInfo* ui,
DiCursor theBlock, /* IMAGE */
- Int noLargerThan )
+ Int noLargerThan,
+ DiCursor debugstr_img,
+ DiCursor debuglinestr_img)
{
Int i;
DebugLineInfo info;
@@ -348,6 +467,9 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
DiCursor external = theBlock;
DiCursor data = theBlock;
+ UChar p_ndx = 0, d_ndx = 0; /* DWARF5 path and dir index. */
+ UInt forms[256]; /* DWARF5 forms. */
+
/* fndn_ix_xa is an xarray of fndn_ix (indexes in di->fndnpool) which
are build from file names harvested from the DWARF2
info. Entry [0] is the "null" pool index and is never referred to
@@ -372,17 +494,6 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
fndn_ix_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rd2l.2", ML_(dinfo_free),
sizeof(UInt) );
- /* DWARF2 starts numbering filename entries at 1, so we need to
- add a dummy zeroth entry to the table. */
- fndn_ix = 0; // 0 is the "null" index in a fixed pool.
- VG_(addToXA) (fndn_ix_xa, &fndn_ix);
-
- if (ML_(cur_is_valid)(ui->compdir))
- dirname = ML_(addStrFromCursor)(di, ui->compdir);
- else
- dirname = ML_(addStr)(di, ".", -1);
- VG_(addToXA) (dirname_xa, &dirname);
-
info.li_length = step_initial_length_field( &external, &is64 );
if (di->ddump_line)
VG_(printf)(" Length: %llu\n",
@@ -402,13 +513,19 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
VG_(printf)(" DWARF Version: %d\n",
(Int)info.li_version);
- if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) {
+ if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4
+ && info.li_version != 5) {
ML_(symerr)(di, True,
- "Only DWARF version 2, 3 and 4 line info "
+ "Only DWARF version 2, 3, 4 and 5 line info "
"is currently supported.");
goto out;
}
+ if (info.li_version >= 5) {
+ /* UChar addr_size = */ ML_(cur_step_UChar)(&external);
+ /* UChar seg_size = */ ML_(cur_step_UChar)(&external);
+ }
+
info.li_header_length = is64 ? ML_(cur_step_ULong)(&external)
: (ULong)(ML_(cur_step_UInt)(&external));
if (di->ddump_line)
@@ -485,60 +602,141 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
/* skip over "standard_opcode_lengths" */
data = ML_(cur_plus)(standard_opcodes, info.li_opcode_base - 1);
- /* Read the contents of the Directory table. */
- if (di->ddump_line)
- VG_(printf)(" The Directory Table%s\n",
- ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" );
-
- while (ML_(cur_read_UChar)(data) != 0) {
+ if (ML_(cur_is_valid)(ui->compdir))
+ dirname = ML_(addStrFromCursor)(di, ui->compdir);
+ else
+ dirname = ML_(addStr)(di, ".", -1);
- HChar* data_str = ML_(cur_read_strdup)(data, "di.rd2l.1");
+ if (info.li_version < 5) {
+ /* Read the contents of the Directory table. */
if (di->ddump_line)
- VG_(printf)(" %s\n", data_str);
-
- /* If data[0] is '/', then 'data' is an absolute path and we
- don't mess with it. Otherwise, construct the
- path 'ui->compdir' ++ "/" ++ 'data'. */
-
- if (data_str[0] != '/'
- /* not an absolute path */
- && ML_(cur_is_valid)(ui->compdir)
- /* actually got something sensible for compdir */
- && ML_(cur_strlen)(ui->compdir))
- {
- HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir, "di.rd2l.1b");
- SizeT len = VG_(strlen)(compdir_str) + 1 + VG_(strlen)(data_str);
- HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1);
-
- VG_(strcpy)(buf, compdir_str);
- VG_(strcat)(buf, "/");
- VG_(strcat)(buf, data_str);
-
- dirname = ML_(addStr)(di, buf, len);
- VG_(addToXA) (dirname_xa, &dirname);
- if (0) VG_(printf)("rel path %s\n", buf);
- ML_(dinfo_free)(compdir_str);
- ML_(dinfo_free)(buf);
- } else {
- /* just use 'data'. */
- dirname = ML_(addStr)(di,data_str,-1);
- VG_(addToXA) (dirname_xa, &dirname);
- if (0) VG_(printf)("abs path %s\n", data_str);
+ VG_(printf)("The Directory Table%s\n",
+ ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" );
+
+ /* DWARF2 starts numbering filename entries at 1, so we need to
+ add a dummy zeroth entry to the table. */
+ fndn_ix = 0; // 0 is the "null" index in a fixed pool.
+ VG_(addToXA) (fndn_ix_xa, &fndn_ix);
+ VG_(addToXA) (dirname_xa, &dirname);
+
+ while (ML_(cur_read_UChar)(data) != 0) {
+
+ HChar* data_str = ML_(cur_read_strdup)(data, "di.rd2l.1");
+ if (di->ddump_line)
+ VG_(printf)(" %s\n", data_str);
+
+ /* If data[0] is '/', then 'data' is an absolute path and we
+ don't mess with it. Otherwise, construct the
+ path 'ui->compdir' ++ "/" ++ 'data'. */
+
+ if (data_str[0] != '/'
+ /* not an absolute path */
+ && ML_(cur_is_valid)(ui->compdir)
+ /* actually got something sensible for compdir */
+ && ML_(cur_strlen)(ui->compdir))
+ {
+ HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir,
+ "di.rd2l.1b");
+ SizeT len = VG_(strlen)(compdir_str) + 1 + VG_(strlen)(data_str);
+ HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1);
+
+ VG_(strcpy)(buf, compdir_str);
+ VG_(strcat)(buf, "/");
+ VG_(strcat)(buf, data_str);
+
+ dirname = ML_(addStr)(di, buf, len);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("rel path %s\n", buf);
+ ML_(dinfo_free)(compdir_str);
+ ML_(dinfo_free)(buf);
+ } else {
+ /* just use 'data'. */
+ dirname = ML_(addStr)(di,data_str,-1);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("abs path %s\n", data_str);
+ }
+
+ data = ML_(cur_plus)(data, VG_(strlen)(data_str) + 1);
+ ML_(dinfo_free)(data_str);
}
- data = ML_(cur_plus)(data, VG_(strlen)(data_str) + 1);
- ML_(dinfo_free)(data_str);
- }
+ if (di->ddump_line)
+ VG_(printf)("\n");
- if (di->ddump_line)
- VG_(printf)("\n");
+ if (ML_(cur_read_UChar)(data) != 0) {
+ ML_(symerr)(di, True,
+ "can't find NUL at end of DWARF2 directory table");
+ goto out;
+ }
+ data = ML_(cur_plus)(data, 1);
+ } else {
+ UInt directories_count;
+ UChar directory_entry_format_count = ML_(cur_step_UChar)(&data);
+ UInt n;
+ for (n = 0; n < directory_entry_format_count; n++) {
+ UInt lnct = step_leb128U(&data);
+ UInt form = step_leb128U(&data);
+ if (lnct == DW_LNCT_path)
+ p_ndx = n;
+ forms[n] = form;
+ }
+ directories_count = step_leb128U(&data);
+ /* Read the contents of the Directory table. */
+ if (di->ddump_line)
+ VG_(printf)(" dwarf The Directory Table%s\n",
+ directories_count == 0 ? " is empty." : ":" );
+
+ for (n = 0; n < directories_count; n++) {
+ UInt f;
+ for (f = 0; f < directory_entry_format_count; f++) {
+ UInt form = forms[f];
+ if (f == p_ndx) {
+ HChar *data_str = get_line_str (di, ui, &data, form,
+ debugstr_img,
+ debuglinestr_img);
+ if (di->ddump_line)
+ VG_(printf)(" %s\n", data_str);
+
+ /* If data[0] is '/', then 'data' is an absolute path and we
+ don't mess with it. Otherwise, construct the
+ path 'ui->compdir' ++ "/" ++ 'data'. */
+
+ if (data_str[0] != '/'
+ /* not an absolute path */
+ && ML_(cur_is_valid)(ui->compdir)
+ /* actually got something sensible for compdir */
+ && ML_(cur_strlen)(ui->compdir))
+ {
+ HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir,
+ "di.rd2l.1b");
+ SizeT len = VG_(strlen)(compdir_str) + 1
+ + VG_(strlen)(data_str);
+ HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1);
+
+ VG_(strcpy)(buf, compdir_str);
+ VG_(strcat)(buf, "/");
+ VG_(strcat)(buf, data_str);
+
+ dirname = ML_(addStr)(di, buf, len);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("rel path %s\n", buf);
+ ML_(dinfo_free)(compdir_str);
+ ML_(dinfo_free)(buf);
+ } else {
+ /* just use 'data'. */
+ dirname = ML_(addStr)(di,data_str,-1);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("abs path %s\n", data_str);
+ }
- if (ML_(cur_read_UChar)(data) != 0) {
- ML_(symerr)(di, True,
- "can't find NUL at end of DWARF2 directory table");
- goto out;
+ ML_(dinfo_free)(data_str);
+
+ } else {
+ data = skip_line_form (di, ui, data, form);
+ }
+ }
+ }
}
- data = ML_(cur_plus)(data, 1);
/* Read the contents of the File Name table. This produces a bunch
of fndn_ix in fndn_ix_xa. */
@@ -547,33 +745,76 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di,
VG_(printf)(" Entry Dir Time Size Name\n");
}
- i = 1;
- while (ML_(cur_read_UChar)(data) != 0) {
- HChar* name = ML_(cur_step_strdup)(&data, "di.rd2l.2");
- Int diridx = step_leb128U(&data);
- Int uu_time = step_leb128U(&data); /* unused */
- Int uu_size = step_leb128U(&data); /* unused */
+ if (info.li_version < 5) {
+ i = 1;
+ while (ML_(cur_read_UChar)(data) != 0) {
+ HChar* name = ML_(cur_step_strdup)(&data, "di.rd2l.2");
+ Int diridx = step_leb128U(&data);
+ Int uu_time = step_leb128U(&data); /* unused */
+ Int uu_size = step_leb128U(&data); /* unused */
+
+ dirname = safe_dirname_ix( dirname_xa, diridx );
+ fndn_ix = ML_(addFnDn) (di, name, dirname);
+ VG_(addToXA) (fndn_ix_xa, &fndn_ix);
+ if (0) VG_(printf)("file %s diridx %d\n", name, diridx );
+ if (di->ddump_line)
+ VG_(printf)(" %d\t%d\t%d\t%d\t%s\n",
+ i, diridx, uu_time, uu_size, name);
+ i++;
+ ML_(dinfo_free)(name);
+ }
- dirname = safe_dirname_ix( dirname_xa, diridx );
- fndn_ix = ML_(addFnDn) (di, name, dirname);
- VG_(addToXA) (fndn_ix_xa, &fndn_ix);
- if (0) VG_(printf)("file %s diridx %d\n", name, diridx );
if (di->ddump_line)
- VG_(printf)(" %d\t%d\t%d\t%d\t%s\n",
- i, diridx, uu_time, uu_size, name);
- i++;
- ML_(dinfo_free)(name);
- }
+ VG_(printf)("\n");
- if (di->ddump_line)
- VG_(printf)("\n");
+ if (ML_(cur_read_UChar)(data) != 0) {
+ ML_(symerr)(di, True,
+ "can't find NUL at end of DWARF2 file name table");
+ goto out;
+ }
+ data = ML_(cur_plus)(data, 1);
+ } else {
+ UInt file_names_count;
+ UChar file_names_entry_format_count = ML_(cur_step_UChar)(&data);
+ UInt n;
+ for (n = 0; n < file_names_entry_format_count; n++) {
+ UInt lnct = step_leb128U(&data);
+ UInt form = step_leb128U(&data);
+ if (lnct == DW_LNCT_path)
+ p_ndx = n;
+ if (lnct == DW_LNCT_directory_index)
+ d_ndx = n;
+ forms[n] = form;
+ }
+ file_names_count = step_leb128U(&data);
+ for (n = 0; n < file_names_count; n++) {
+ UInt f;
+ HChar* name = NULL;
+ Int diridx = 0;
+ for (f = 0; f < file_names_entry_format_count; f++) {
+ UInt form = forms[f];
+ if (f == p_ndx)
+ name = get_line_str (di, ui, &data, form,
+ debugstr_img, debuglinestr_img);
+ else if (n == d_ndx)
+ diridx = get_line_ndx (di, &data, form);
+ else
+ data = skip_line_form (di, ui, data, form);
+ }
- if (ML_(cur_read_UChar)(data) != 0) {
- ML_(symerr)(di, True,
- "can't find NUL at end of DWARF2 file name table");
- goto out;
+ dirname = safe_dirname_ix( dirname_xa, diridx );
+ fndn_ix = ML_(addFnDn) (di, name, dirname);
+ VG_(addToXA) (fndn_ix_xa, &fndn_ix);
+ if (0) VG_(printf)("file %s diridx %d\n", name, diridx );
+ if (di->ddump_line)
+ VG_(printf)(" %u\t%d\t%d\t%d\t%s\n",
+ n, diridx, 0, 0, name);
+ ML_(dinfo_free)(name);
+ }
+
+ if (di->ddump_line)
+ VG_(printf)("\n");
}
- data = ML_(cur_plus)(data, 1);
if (di->ddump_line)
VG_(printf)(" Line Number Statements:\n");
@@ -772,9 +1013,12 @@ static DiCursor lookup_abbrev( DiCursor p, ULong acode )
(void)step_leb128U(&p); /* skip tag */
p = ML_(cur_plus)(p,1); /* skip has_children flag */
ULong name;
+ ULong form;
do {
name = step_leb128U(&p); /* name */
- (void)step_leb128U(&p); /* form */
+ form = step_leb128U(&p); /* form */
+ if (form == 0x21) /* DW_FORM_implicit_const */
+ step_leb128S(&p);
}
while (name != 0); /* until name == form == 0 */
}
@@ -804,13 +1048,14 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
DiCursor unitblock_img,
DiCursor debugabbrev_img,
DiCursor debugstr_img,
- DiCursor debugstr_alt_img )
+ DiCursor debugstr_alt_img,
+ DiCursor debuglinestr_img)
{
UInt acode, abcode;
ULong atoffs, blklen;
UShort ver;
- UChar addr_size;
+ UChar addr_size = 0;
DiCursor p = unitblock_img;
DiCursor end_img;
DiCursor abbrev_img;
@@ -823,16 +1068,25 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
/* This block length */
blklen = step_initial_length_field( &p, &ui->dw64 );
- /* version should be 2, 3 or 4 */
+ /* version should be 2, 3, 4 or 5 */
ver = ML_(cur_step_UShort)(&p);
- /* get offset in abbrev */
- atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p)
- : (ULong)(ML_(cur_step_UInt)(&p));
+ if (ver >= 5)
+ /* unit_type for DWARF5 */
+ /* unit_type = */ ML_(cur_step_UChar)(&p);
+ else
+ /* get offset in abbrev */
+ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p)
+ : (ULong)(ML_(cur_step_UInt)(&p));
/* Address size */
addr_size = ML_(cur_step_UChar)(&p);
+ if (ver >= 5)
+ /* get offset in abbrev */
+ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p)
+ : (ULong)(ML_(cur_step_UInt)(&p));
+
/* End of this block */
end_img = ML_(cur_plus)(unitblock_img, blklen + (ui->dw64 ? 12 : 4));
@@ -909,6 +1163,17 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
sval = ML_(cur_plus)(debugstr_img, ML_(cur_read_ULong)(p));
p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4);
break;
+ case 0x1f: /* FORM_line_strp */ /* pointer in .debug_line_str */
+ /* 2006-01-01: only generate a value if a debug_str
+ section was found) */
+ if (ML_(cur_is_valid)(debuglinestr_img) && !ui->dw64)
+ sval = ML_(cur_plus)(debuglinestr_img,
+ ML_(cur_read_UInt)(p));
+ if (ML_(cur_is_valid)(debuglinestr_img) && ui->dw64)
+ sval = ML_(cur_plus)(debuglinestr_img,
+ ML_(cur_read_ULong)(p));
+ p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4);
+ break;
case 0x08: /* FORM_string */
sval = p;
p = ML_(cur_plus)(p, ML_(cur_strlen)(p) + 1);
@@ -928,7 +1193,13 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
p = ML_(cur_plus)(p, 8);
/* perhaps should assign unconditionally to cval? */
break;
+ case 0x21: /* FORM_implicit_const */
+ cval = step_leb128S (&abbrev_img);
+ break;
/* TODO : Following ones just skip data - implement if you need */
+ case 0x1e: /* FORM_data16 */
+ p = ML_(cur_plus)(p, 16);
+ break;
case 0x01: /* FORM_addr */
p = ML_(cur_plus)(p, addr_size);
break;
@@ -1028,7 +1299,8 @@ void ML_(read_debuginfo_dwarf3)
DiSlice escn_debug_abbv, /* .debug_abbrev */
DiSlice escn_debug_line, /* .debug_line */
DiSlice escn_debug_str, /* .debug_str */
- DiSlice escn_debug_str_alt ) /* .debug_str */
+ DiSlice escn_debug_str_alt, /* .debug_str */
+ DiSlice escn_debug_line_str) /* .debug_line_str */
{
UnitInfo ui;
UShort ver;
@@ -1067,9 +1339,9 @@ void ML_(read_debuginfo_dwarf3)
/* version should be 2 */
ver = ML_(cur_read_UShort)( ML_(cur_plus)(block_img, blklen_len) );
- if ( ver != 2 && ver != 3 && ver != 4 ) {
+ if ( ver != 2 && ver != 3 && ver != 4 && ver != 5) {
ML_(symerr)( di, True,
- "Ignoring non-Dwarf2/3/4 block in .debug_info" );
+ "Ignoring non-Dwarf2/3/4/5 block in .debug_info" );
continue;
}
@@ -1082,7 +1354,8 @@ void ML_(read_debuginfo_dwarf3)
read_unitinfo_dwarf2( &ui, block_img,
ML_(cur_from_sli)(escn_debug_abbv),
ML_(cur_from_sli)(escn_debug_str),
- ML_(cur_from_sli)(escn_debug_str_alt) );
+ ML_(cur_from_sli)(escn_debug_str_alt),
+ ML_(cur_from_sli)(escn_debug_line_str));
if (0) {
HChar* str_name = ML_(cur_read_strdup)(ui.name, "di.rdd3.1");
HChar* str_compdir = ML_(cur_read_strdup)(ui.compdir, "di.rdd3.2");
@@ -1107,7 +1380,9 @@ void ML_(read_debuginfo_dwarf3)
read_dwarf2_lineblock(
di, &ui,
ML_(cur_plus)(ML_(cur_from_sli)(escn_debug_line), ui.stmt_list),
- escn_debug_line.szB - ui.stmt_list
+ escn_debug_line.szB - ui.stmt_list,
+ ML_(cur_from_sli)(escn_debug_str),
+ ML_(cur_from_sli)(escn_debug_line_str)
);
}
}
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index c4d529bc6..82bc8f241 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -384,6 +384,7 @@ typedef
struct _name_form {
ULong at_name; // Dwarf Attribute name
ULong at_form; // Dwarf Attribute form
+ Long at_val; // Dwarf Attribute value (for implicit_const)
UInt skip_szB; // Nr of bytes skippable from here ...
UInt next_nf; // ... to reach this attr/form index in the g_abbv.nf
} name_form;
@@ -423,7 +424,7 @@ typedef
void (*barf)( const HChar* ) __attribute__((noreturn));
/* Is this 64-bit DWARF ? */
Bool is_dw64;
- /* Which DWARF version ? (2, 3 or 4) */
+ /* Which DWARF version ? (2, 3, 4 or 5) */
UShort version;
/* Length of this Compilation Unit, as stated in the
.unit_length :: InitialLength field of the CU Header.
@@ -452,12 +453,15 @@ typedef
/* Image information for various sections. */
DiSlice escn_debug_str;
DiSlice escn_debug_ranges;
+ DiSlice escn_debug_rnglists;
+ DiSlice escn_debug_loclists;
DiSlice escn_debug_loc;
DiSlice escn_debug_line;
DiSlice escn_debug_info;
DiSlice escn_debug_types;
DiSlice escn_debug_info_alt;
DiSlice escn_debug_str_alt;
+ DiSlice escn_debug_line_str;
/* How much to add to .debug_types resp. alternate .debug_info offsets
in cook_die*. */
UWord types_cuOff_bias;
@@ -651,25 +655,35 @@ static GExpr* make_singleton_GX ( DiCursor block, ULong nbytes )
__attribute__((noinline))
static GExpr* make_general_GX ( const CUConst* cc,
Bool td3,
- ULong debug_loc_offset,
+ ULong offset,
Addr svma_of_referencing_CU )
{
+ Bool done;
Addr base;
Cursor loc;
XArray* xa; /* XArray of UChar */
GExpr* gx;
Word nbytes;
+ Bool addBase = cc->version < 5;
vg_assert(sizeof(UWord) == sizeof(Addr));
- if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0)
+ if (cc->version < 5 && (!ML_(sli_is_valid)(cc->escn_debug_loc)
+ || cc->escn_debug_loc.szB == 0))
cc->barf("make_general_GX: .debug_loc is empty/missing");
+ if (cc->version >= 5 && (!ML_(sli_is_valid)(cc->escn_debug_loclists)
+ || cc->escn_debug_loclists.szB == 0))
+ cc->barf("make_general_GX: .debug_loclists is empty/missing");
- init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
- "Overrun whilst reading .debug_loc section(2)" );
- set_position_of_Cursor( &loc, debug_loc_offset );
+ if (cc->version < 5)
+ init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
+ "Overrun whilst reading .debug_loc section(2)" );
+ else
+ init_Cursor( &loc, cc->escn_debug_loclists, 0, cc->barf,
+ "Overrun whilst reading .debug_loclists section(2)" );
+ set_position_of_Cursor( &loc, offset );
- TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n",
- debug_loc_offset, get_DiCursor_from_Cursor(&loc).ioff );
+ TRACE_D3("make_general_GX (offset = %llu, ioff = %llu) {\n",
+ offset, get_DiCursor_from_Cursor(&loc).ioff );
/* Who frees this xa? It is freed before this fn exits. */
xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1",
@@ -679,40 +693,86 @@ static GExpr* make_general_GX ( const CUConst* cc,
{ UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
base = 0;
- while (True) {
+ done = False;
+ while (!done) {
Bool acquire;
UWord len;
- /* Read a (host-)word pair. This is something of a hack since
- the word size to read is really dictated by the ELF file;
- however, we assume we're reading a file with the same
- word-sizeness as the host. Reasonably enough. */
- UWord w1 = get_UWord( &loc );
- UWord w2 = get_UWord( &loc );
-
- TRACE_D3(" %08lx %08lx\n", w1, w2);
- if (w1 == 0 && w2 == 0)
- break; /* end of list */
-
- if (w1 == -1UL) {
- /* new value for 'base' */
- base = w2;
- continue;
+ UWord w1;
+ UWord w2;
+ if (cc->version < 5) {
+ /* Read a (host-)word pair. This is something of a hack since
+ the word size to read is really dictated by the ELF file;
+ however, we assume we're reading a file with the same
+ word-sizeness as the host. Reasonably enough. */
+ w1 = get_UWord( &loc );
+ w2 = get_UWord( &loc );
+
+ TRACE_D3(" %08lx %08lx\n", w1, w2);
+ if (w1 == 0 && w2 == 0) {
+ done = True;
+ break; /* end of list */
+ }
+
+ if (w1 == -1UL) {
+ /* new value for 'base' */
+ base = w2;
+ continue;
+ }
+ /* else a location expression follows */
+ len = (UWord)get_UShort( &loc );
+ } else {
+ w1 = 0;
+ w2 = 0;
+ len = 0;
+ DW_LLE r = get_UChar( &loc );
+ switch (r) {
+ case DW_LLE_end_of_list:
+ done = True;
+ break;
+ case DW_LLE_base_address:
+ base = get_UWord( &loc );
+ break;
+ case DW_LLE_start_length:
+ w1 = get_UWord( &loc );
+ w2 = w1 + get_ULEB128( &loc );
+ len = get_ULEB128( &loc );
+ break;
+ case DW_LLE_offset_pair:
+ w1 = base + get_ULEB128( &loc );
+ w2 = base + get_ULEB128( &loc );
+ len = get_ULEB128( &loc );
+ break;
+ case DW_LLE_start_end:
+ w1 = get_UWord ( &loc );
+ w2 = get_UWord ( &loc );
+ len = get_ULEB128( &loc );
+ break;
+ case DW_LLE_GNU_view_pair:
+ get_ULEB128( &loc );
+ get_ULEB128( &loc );
+ break;
+ case DW_LLE_base_addressx:
+ case DW_LLE_startx_endx:
+ case DW_LLE_startx_length:
+ case DW_LLE_default_location:
+ default:
+ cc->barf( "Unhandled or unknown loclists entry" );
+ done = True;
+ }
}
- /* else a location expression follows */
/* else enumerate [w1+base, w2+base) */
/* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
(sec 2.17.2) */
if (w1 > w2) {
TRACE_D3("negative range is for .debug_loc expr at "
"file offset %llu\n",
- debug_loc_offset);
+ offset);
cc->barf( "negative range in .debug_loc section" );
}
/* ignore zero length ranges */
acquire = w1 < w2;
- len = (UWord)get_UShort( &loc );
if (acquire) {
UWord w;
@@ -720,9 +780,9 @@ static GExpr* make_general_GX ( const CUConst* cc,
UChar c;
c = 0; /* !isEnd*/
VG_(addBytesToXA)( xa, &c, sizeof(c) );
- w = w1 + base + svma_of_referencing_CU;
+ w = w1 + (addBase ? base : 0) + svma_of_referencing_CU;
VG_(addBytesToXA)( xa, &w, sizeof(w) );
- w = w2 -1 + base + svma_of_referencing_CU;
+ w = w2 -1 + (addBase ? base : 0) + svma_of_referencing_CU;
VG_(addBytesToXA)( xa, &w, sizeof(w) );
s = (UShort)len;
VG_(addBytesToXA)( xa, &s, sizeof(s) );
@@ -839,45 +899,96 @@ get_range_list ( const CUConst* cc,
XArray* xa; /* XArray of AddrRange */
AddrRange pair;
- if (!ML_(sli_is_valid)(cc->escn_debug_ranges)
- || cc->escn_debug_ranges.szB == 0)
+ if (cc->version < 5 && (!ML_(sli_is_valid)(cc->escn_debug_ranges)
+ || cc->escn_debug_ranges.szB == 0))
cc->barf("get_range_list: .debug_ranges is empty/missing");
+ if (cc->version >= 5 && (!ML_(sli_is_valid)(cc->escn_debug_rnglists)
+ || cc->escn_debug_rnglists.szB == 0))
+ cc->barf("get_range_list: .debug_rnglists is empty/missing");
+
+ if (cc->version < 5)
+ init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
+ "Overrun whilst reading .debug_ranges section(2)" );
+ else
+ init_Cursor( &ranges, cc->escn_debug_rnglists, 0, cc->barf,
+ "Overrun whilst reading .debug_rnglists section(2)" );
- init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
- "Overrun whilst reading .debug_ranges section(2)" );
set_position_of_Cursor( &ranges, debug_ranges_offset );
/* Who frees this xa? varstack_preen() does. */
xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
sizeof(AddrRange) );
base = 0;
- while (True) {
- /* Read a (host-)word pair. This is something of a hack since
- the word size to read is really dictated by the ELF file;
- however, we assume we're reading a file with the same
- word-sizeness as the host. Reasonably enough. */
- UWord w1 = get_UWord( &ranges );
- UWord w2 = get_UWord( &ranges );
-
- if (w1 == 0 && w2 == 0)
- break; /* end of list. */
-
- if (w1 == -1UL) {
- /* new value for 'base' */
- base = w2;
- continue;
- }
+ if (cc->version < 5) {
+ while (True) {
+ /* Read a (host-)word pair. This is something of a hack since
+ the word size to read is really dictated by the ELF file;
+ however, we assume we're reading a file with the same
+ word-sizeness as the host. Reasonably enough. */
+ UWord w1 = get_UWord( &ranges );
+ UWord w2 = get_UWord( &ranges );
- /* else enumerate [w1+base, w2+base) */
- /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
- (sec 2.17.2) */
- if (w1 > w2)
- cc->barf( "negative range in .debug_ranges section" );
- if (w1 < w2) {
- pair.aMin = w1 + base + svma_of_referencing_CU;
- pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
- vg_assert(pair.aMin <= pair.aMax);
- VG_(addToXA)( xa, &pair );
+ if (w1 == 0 && w2 == 0)
+ break; /* end of list. */
+
+ if (w1 == -1UL) {
+ /* new value for 'base' */
+ base = w2;
+ continue;
+ }
+
+ /* else enumerate [w1+base, w2+base) */
+ /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
+ (sec 2.17.2) */
+ if (w1 > w2)
+ cc->barf( "negative range in .debug_ranges section" );
+ if (w1 < w2) {
+ pair.aMin = w1 + base + svma_of_referencing_CU;
+ pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
+ vg_assert(pair.aMin <= pair.aMax);
+ VG_(addToXA)( xa, &pair );
+ }
+ }
+ } else {
+ Bool done = False;
+ while (!done) {
+ UWord w1 = 0;
+ UWord w2 = 0;
+ DW_RLE r = get_UChar( &ranges );
+ switch (r) {
+ case DW_RLE_end_of_list:
+ done = True;
+ break;
+ case DW_RLE_base_address:
+ base = get_UWord( &ranges );
+ break;
+ case DW_RLE_start_length:
+ w1 = get_UWord( &ranges );
+ w2 = w1 + get_ULEB128( &ranges );
+ break;
+ case DW_RLE_offset_pair:
+ w1 = base + get_ULEB128( &ranges );
+ w2 = base + get_ULEB128( &ranges );
+ break;
+ case DW_RLE_start_end:
+ w1 = get_UWord ( &ranges );
+ w2 = get_UWord ( &ranges );
+ break;
+ case DW_RLE_base_addressx:
+ case DW_RLE_startx_endx:
+ case DW_RLE_startx_length:
+ default:
+ cc->barf( "Unhandled or unknown range list entry" );
+ done = True;
+ }
+ if (w1 > w2)
+ cc->barf( "negative range in .debug_rnglists section" );
+ if (w1 < w2) {
+ pair.aMin = w1 + svma_of_referencing_CU;
+ pair.aMax = w2 - 1 + svma_of_referencing_CU;
+ vg_assert(pair.aMin <= pair.aMax);
+ VG_(addToXA)( xa, &pair );
+ }
}
}
return xa;
@@ -930,6 +1041,8 @@ static void init_ht_abbvs (CUConst* cc,
}
ta->nf[ta_nf_n].at_name = get_ULEB128( &c );
ta->nf[ta_nf_n].at_form = get_ULEB128( &c );
+ if (ta->nf[ta_nf_n].at_form == DW_FORM_implicit_const)
+ ta->nf[ta_nf_n].at_val = get_SLEB128( &c );
if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) {
ta_nf_n++;
break;
@@ -1005,7 +1118,7 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
Bool type_unit,
Bool alt_info )
{
- UChar address_size;
+ UChar address_size, unit_type;
ULong debug_abbrev_offset;
VG_(memset)(cc, 0, sizeof(*cc));
@@ -1021,10 +1134,21 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
/* version */
cc->version = get_UShort( c );
- if (cc->version != 2 && cc->version != 3 && cc->version != 4)
- cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
+ if (cc->version != 2 && cc->version != 3 && cc->version != 4
+ && cc->version != 5)
+ cc->barf( "parse_CU_Header: "
+ "is neither DWARF2 nor DWARF3 nor DWARF4 nor DWARF5" );
TRACE_D3(" Version: %d\n", (Int)cc->version );
+ /* unit type */
+ if (cc->version >= 5) {
+ unit_type = get_UChar( c );
+ address_size = get_UChar( c );
+ } else {
+ unit_type = type_unit ? DW_UT_type : DW_UT_compile;
+ address_size = 0; /* Will be read later. */
+ }
+
/* debug_abbrev_offset */
debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
if (debug_abbrev_offset >= escn_debug_abbv.szB)
@@ -1035,7 +1159,9 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
give up. This makes it safe to assume elsewhere that
DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
word. */
- address_size = get_UChar( c );
+ if (cc->version < 5)
+ address_size = get_UChar( c );
+
if (address_size != sizeof(void*))
cc->barf( "parse_CU_Header: invalid address_size" );
TRACE_D3(" Pointer Size: %d\n", (Int)address_size );
@@ -1043,7 +1169,7 @@ void parse_CU_Header ( /*OUT*/CUConst* cc,
cc->is_type_unit = type_unit;
cc->is_alt_info = alt_info;
- if (type_unit) {
+ if (type_unit || (cc->version >= 5 && unit_type == DW_UT_type)) {
cc->type_signature = get_ULong( c );
cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
}
@@ -1130,8 +1256,9 @@ typedef
static
void get_Form_contents ( /*OUT*/FormContents* cts,
const CUConst* cc, Cursor* c,
- Bool td3, DW_FORM form )
+ Bool td3, const name_form *abbv )
{
+ DW_FORM form = abbv->at_form;
VG_(bzero_inline)(cts, sizeof(*cts));
// !!! keep switch in sync with get_Form_szB. The nr of characters read below
// must be computed similarly in get_Form_szB.
@@ -1157,6 +1284,19 @@ void get_Form_contents ( /*OUT*/FormContents* cts,
cts->szB = 8;
TRACE_D3("%llu", cts->u.val);
break;
+ case DW_FORM_data16: {
+ /* This is more like a block than an integral value. */
+ ULong u64b;
+ DiCursor data16 = get_DiCursor_from_Cursor(c);
+ TRACE_D3("data16: ");
+ for (u64b = 16; u64b > 0; u64b--) {
+ UChar u8 = get_UChar(c);
+ TRACE_D3("%x ", (UInt)u8);
+ }
+ cts->u.cur = data16;
+ cts->szB = - (Long)16;
+ break;
+ }
case DW_FORM_sec_offset:
cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
cts->szB = cc->is_dw64 ? 8 : 4;
@@ -1242,6 +1382,26 @@ void get_Form_contents ( /*OUT*/FormContents* cts,
cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
break;
}
+ case DW_FORM_line_strp: {
+ /* this is an offset into .debug_line_str */
+ UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
+ if (!ML_(sli_is_valid)(cc->escn_debug_line_str)
+ || uw >= cc->escn_debug_line_str.szB)
+ cc->barf("get_Form_contents: DW_FORM_line_strp "
+ "points outside .debug_line_str");
+ /* FIXME: check the entire string lies inside debug_line_str,
+ not just the first byte of it. */
+ DiCursor line_str
+ = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_line_str), uw );
+ if (TD3) {
+ HChar* tmp = ML_(cur_read_strdup)(line_str, "di.getFC.1.5");
+ TRACE_D3("(indirect line string, offset: 0x%lx): %s", uw, tmp);
+ ML_(dinfo_free)(tmp);
+ }
+ cts->u.cur = line_str;
+ cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(line_str));
+ break;
+ }
case DW_FORM_string: {
DiCursor str = get_AsciiZ(c);
if (TD3) {
@@ -1307,6 +1467,11 @@ void get_Form_contents ( /*OUT*/FormContents* cts,
cts->u.val = 1;
cts->szB = 1;
break;
+ case DW_FORM_implicit_const:
+ cts->u.val = (ULong)abbv->at_val;
+ cts->szB = 8;
+ TRACE_D3("%llu", cts->u.val);
+ break;
case DW_FORM_block1: {
ULong u64b;
ULong u64 = (ULong)get_UChar(c);
@@ -1396,9 +1561,14 @@ void get_Form_contents ( /*OUT*/FormContents* cts,
cts->szB = sizeof(UWord);
break;
}
- case DW_FORM_indirect:
- get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c));
+ case DW_FORM_indirect: {
+ /* Urgh, this is ugly and somewhat unclear how it works
+ with DW_FORM_implicit_const. HACK. */
+ name_form nfi = *abbv;
+ nfi.at_form = (DW_FORM)get_ULEB128(c);
+ get_Form_contents (cts, cc, c, td3, &nfi);
return;
+ }
case DW_FORM_GNU_ref_alt:
cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
@@ -1471,6 +1641,7 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form )
case DW_FORM_data2: return 2;
case DW_FORM_data4: return 4;
case DW_FORM_data8: return 8;
+ case DW_FORM_data16: return 16;
case DW_FORM_sec_offset:
if (cc->is_dw64)
return 8;
@@ -1488,6 +1659,7 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form )
else
return sizeof_Dwarfish_UWord (cc->is_dw64);
case DW_FORM_strp:
+ case DW_FORM_line_strp:
return sizeof_Dwarfish_UWord (cc->is_dw64);
case DW_FORM_string:
return VARSZ_FORM;
@@ -1522,6 +1694,8 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form )
return sizeof_Dwarfish_UWord(cc->is_dw64);
case DW_FORM_GNU_strp_alt:
return sizeof_Dwarfish_UWord(cc->is_dw64);
+ case DW_FORM_implicit_const:
+ return 0; /* Value inside abbrev. */
default:
VG_(printf)(
"get_Form_szB: unhandled %u (%s)\n",
@@ -1544,13 +1718,13 @@ void skip_DIE (UWord *sibling,
while (True) {
if (abbv->nf[nf_i].at_name == DW_AT_sibling) {
get_Form_contents( &cts, cc, c_die, False /*td3*/,
- (DW_FORM)abbv->nf[nf_i].at_form );
+ &abbv->nf[nf_i] );
if ( cts.szB > 0 )
*sibling = cts.u.val;
nf_i++;
} else if (abbv->nf[nf_i].skip_szB == VARSZ_FORM) {
get_Form_contents( &cts, cc, c_die, False /*td3*/,
- (DW_FORM)abbv->nf[nf_i].at_form );
+ &abbv->nf[nf_i] );
nf_i++;
} else {
advance_position_of_Cursor (c_die, (ULong)abbv->nf[nf_i].skip_szB);
@@ -1778,6 +1952,124 @@ static GExpr* get_GX ( const CUConst* cc, Bool td3, const FormContents* cts )
return gexpr;
}
+static
+HChar * get_line_str (struct _DebugInfo* di, Bool is_dw64,
+ Cursor *data, const UInt form,
+ DiSlice debugstr_img, DiSlice debuglinestr_img)
+{
+ HChar *str = NULL;
+ switch (form) {
+ case DW_FORM_string: {
+ DiCursor distr = get_AsciiZ(data);
+ str = ML_(cur_step_strdup)(&distr, "di.gls.string");
+ break;
+ }
+ case DW_FORM_strp: {
+ UWord uw = (UWord)get_Dwarfish_UWord( data, is_dw64 );
+ DiCursor distr
+ = ML_(cur_plus)( ML_(cur_from_sli)(debugstr_img), uw );
+ str = ML_(cur_read_strdup)(distr, "di.gls.strp");
+ break;
+ }
+ case DW_FORM_line_strp: {
+ UWord uw = (UWord)get_Dwarfish_UWord( data, is_dw64 );
+ DiCursor distr
+ = ML_(cur_plus)( ML_(cur_from_sli)(debuglinestr_img), uw );
+ str = ML_(cur_read_strdup)(distr, "di.gls.line_strp");
+ break;
+ }
+ default:
+ ML_(symerr)(di, True,
+ "Unknown path string FORM in .debug_line");
+ break;
+ }
+ return str;
+}
+
+static
+Int get_line_ndx (struct _DebugInfo* di,
+ Cursor *data, const UInt form)
+{
+ Int res = 0;
+ switch (form) {
+ case DW_FORM_data1:
+ res = get_UChar(data);
+ break;
+ case DW_FORM_data2:
+ res = get_UShort(data);
+ break;
+ case DW_FORM_udata:
+ res = get_ULEB128(data);
+ break;
+ default:
+ ML_(symerr)(di, True,
+ "Unknown directory_index value FORM in .debug_line");
+ break;
+ }
+ return res;
+}
+
+static
+void skip_line_form (struct _DebugInfo* di, Bool is_dw64,
+ Cursor *d, const UInt form)
+{
+ switch (form) {
+ case DW_FORM_block: {
+ ULong len = get_ULEB128(d);
+ advance_position_of_Cursor (d, len);
+ break;
+ }
+ case DW_FORM_block1: {
+ UChar len = get_UChar(d);
+ advance_position_of_Cursor (d, len);
+ break;
+ }
+ case DW_FORM_block2: {
+ UShort len = get_UShort(d);
+ advance_position_of_Cursor (d, len);
+ break;
+ }
+ case DW_FORM_block4: {
+ UInt len = get_UInt(d);
+ advance_position_of_Cursor (d, len);
+ break;
+ }
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ advance_position_of_Cursor (d, 1);
+ break;
+ case DW_FORM_data2:
+ advance_position_of_Cursor (d, 2);
+ break;
+ case DW_FORM_data4:
+ advance_position_of_Cursor (d, 4);
+ break;
+ case DW_FORM_data8:
+ advance_position_of_Cursor (d, 8);
+ break;
+ case DW_FORM_data16:
+ advance_position_of_Cursor (d, 16);
+ break;
+ case DW_FORM_string:
+ (void)get_AsciiZ (d);
+ break;
+ case DW_FORM_strp:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ advance_position_of_Cursor (d, is_dw64 ? 8 : 4);
+ break;
+ case DW_FORM_udata:
+ (void)get_ULEB128(d);
+ break;
+ case DW_FORM_sdata:
+ (void)get_SLEB128(d);
+ break;
+ default:
+ ML_(symerr)(di, True, "Unknown FORM in .debug_line");
+ break;
+ }
+}
+
/* Returns an xarray* of directory names (indexed by the dwarf dirname
integer).
If 'compdir' is NULL, entry [0] will be set to "."
@@ -1786,8 +2078,8 @@ static GExpr* get_GX ( const CUConst* cc, Bool td3, const FormContents* cts )
whatever that means, according to the DWARF3 spec.
FIXME??? readdwarf3.c/readdwarf.c have a lot of duplicated code */
static
-XArray* read_dirname_xa (DebugInfo* di, const HChar *compdir,
- Cursor *c,
+XArray* read_dirname_xa (DebugInfo* di, UShort version, const HChar *compdir,
+ Cursor *c, const CUConst *cc,
Bool td3 )
{
XArray* dirname_xa; /* xarray of HChar* dirname */
@@ -1804,51 +2096,121 @@ XArray* read_dirname_xa (DebugInfo* di, const HChar *compdir,
dirname = compdir;
compdir_len = VG_(strlen)(compdir);
}
- VG_(addToXA) (dirname_xa, &dirname);
-
- TRACE_D3(" The Directory Table%s\n",
- peek_UChar(c) == 0 ? " is empty." : ":" );
-
- while (peek_UChar(c) != 0) {
-
- DiCursor cur = get_AsciiZ(c);
- HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" );
- TRACE_D3(" %s\n", data_str);
-
- /* If data_str[0] is '/', then 'data' is an absolute path and we
- don't mess with it. Otherwise, construct the
- path 'compdir' ++ "/" ++ 'data'. */
-
- if (data_str[0] != '/'
- /* not an absolute path */
- && compdir
- /* actually got something sensible for compdir */
- && compdir_len)
- {
- SizeT len = compdir_len + 1 + VG_(strlen)(data_str);
- HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1);
-
- VG_(strcpy)(buf, compdir);
- VG_(strcat)(buf, "/");
- VG_(strcat)(buf, data_str);
-
- dirname = ML_(addStr)(di, buf, len);
- VG_(addToXA) (dirname_xa, &dirname);
- if (0) VG_(printf)("rel path %s\n", buf);
- ML_(dinfo_free)(buf);
- } else {
- /* just use 'data'. */
- dirname = ML_(addStr)(di,data_str,-1);
- VG_(addToXA) (dirname_xa, &dirname);
- if (0) VG_(printf)("abs path %s\n", data_str);
+
+ /* For version 5, the compdir is the first (zero) entry. */
+ if (version < 5)
+ VG_(addToXA) (dirname_xa, &dirname);
+
+ if (version < 5) {
+ TRACE_D3("The Directory Table%s\n",
+ peek_UChar(c) == 0 ? " is empty." : ":" );
+
+ while (peek_UChar(c) != 0) {
+
+ DiCursor cur = get_AsciiZ(c);
+ HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" );
+ TRACE_D3(" %s\n", data_str);
+
+ /* If data_str[0] is '/', then 'data' is an absolute path and we
+ don't mess with it. Otherwise, construct the
+ path 'compdir' ++ "/" ++ 'data'. */
+
+ if (data_str[0] != '/'
+ /* not an absolute path */
+ && compdir
+ /* actually got something sensible for compdir */
+ && compdir_len)
+ {
+ SizeT len = compdir_len + 1 + VG_(strlen)(data_str);
+ HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1);
+
+ VG_(strcpy)(buf, compdir);
+ VG_(strcat)(buf, "/");
+ VG_(strcat)(buf, data_str);
+
+ dirname = ML_(addStr)(di, buf, len);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("rel path %s\n", buf);
+ ML_(dinfo_free)(buf);
+ } else {
+ /* just use 'data'. */
+ dirname = ML_(addStr)(di,data_str,-1);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("abs path %s\n", data_str);
+ }
+
+ ML_(dinfo_free)(data_str);
+ }
+ } else {
+ UChar forms[256];
+ UChar p_ndx = 0;
+ UInt directories_count;
+ UChar directory_entry_format_count;
+ UInt n;
+ DiSlice debugstr_img = cc->escn_debug_str;
+ DiSlice debuglinestr_img = cc->escn_debug_line_str;
+
+ directory_entry_format_count = get_UChar(c);
+ for (n = 0; n < directory_entry_format_count; n++) {
+ UInt lnct = get_ULEB128(c);
+ UInt form = get_ULEB128(c);
+ if (lnct == DW_LNCT_path)
+ p_ndx = n;
+ forms[n] = form;
}
+ directories_count = get_ULEB128(c);
+ TRACE_D3("The Directory Table%s\n",
+ directories_count == 0 ? " is empty." : ":" );
+
+ for (n = 0; n < directories_count; n++) {
+ UInt f;
+ for (f = 0; f < directory_entry_format_count; f++) {
+ UInt form = forms[f];
+ if (f == p_ndx) {
+ HChar *data_str = get_line_str (di, cc->is_dw64, c, form,
+ debugstr_img,
+ debuglinestr_img);
+ TRACE_D3(" %s\n", data_str);
+
+ /* If data_str[0] is '/', then 'data' is an absolute path and we
+ don't mess with it. Otherwise, construct the
+ path 'compdir' ++ "/" ++ 'data'. */
+
+ if (data_str[0] != '/'
+ /* not an absolute path */
+ && compdir
+ /* actually got something sensible for compdir */
+ && compdir_len)
+ {
+ SizeT len = compdir_len + 1 + VG_(strlen)(data_str);
+ HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1);
+
+ VG_(strcpy)(buf, compdir);
+ VG_(strcat)(buf, "/");
+ VG_(strcat)(buf, data_str);
+
+ dirname = ML_(addStr)(di, buf, len);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("rel path %s\n", buf);
+ ML_(dinfo_free)(buf);
+ } else {
+ /* just use 'data'. */
+ dirname = ML_(addStr)(di,data_str,-1);
+ VG_(addToXA) (dirname_xa, &dirname);
+ if (0) VG_(printf)("abs path %s\n", data_str);
+ }
- ML_(dinfo_free)(data_str);
+ ML_(dinfo_free)(data_str);
+ } else {
+ skip_line_form (di, cc->is_dw64, c, form);
+ }
+ }
+ }
}
TRACE_D3 ("\n");
- if (get_UChar (c) != 0) {
+ if (version < 5 && get_UChar (c) != 0) {
ML_(symerr)(NULL, True,
"could not get NUL at end of DWARF directory table");
VG_(deleteXA)(dirname_xa);
@@ -1888,9 +2250,13 @@ void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table,
get_Initial_Length( &is_dw64, &c,
"read_filename_table: invalid initial-length field" );
version = get_UShort( &c );
- if (version != 2 && version != 3 && version != 4)
- cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
- "is currently supported.");
+ if (version != 2 && version != 3 && version != 4 && version != 5)
+ cc->barf("read_filename_table: Only DWARF version 2, 3, 4 and 5 "
+ "line info is currently supported.");
+ if (version >= 5) {
+ /* addrs_size = */ get_UChar( &c );
+ /* seg_size = */ get_UChar( &c );
+ }
/*header_length = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
/*minimum_instruction_length = */ get_UChar( &c );
if (version >= 4)
@@ -1903,30 +2269,77 @@ void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table,
for (i = 1; i < (Word)opcode_base; i++)
(void)get_UChar( &c );
- dirname_xa = read_dirname_xa(cc->di, compdir, &c, td3);
+ dirname_xa = read_dirname_xa(cc->di, version, compdir, &c, cc, td3);
/* Read and record the file names table */
vg_assert( VG_(sizeXA)( fndn_ix_Table ) == 0 );
- /* Add a dummy index-zero entry. DWARF3 numbers its files
- from 1, for some reason. */
- fndn_ix = ML_(addFnDn) ( cc->di, "<unknown_file>", NULL );
- VG_(addToXA)( fndn_ix_Table, &fndn_ix );
- while (peek_UChar(&c) != 0) {
- DiCursor cur = get_AsciiZ(&c);
- str = ML_(addStrFromCursor)( cc->di, cur );
- dir_xa_ix = get_ULEB128( &c );
- if (dirname_xa != NULL
- && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa))
- dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix );
- else
- dirname = NULL;
- fndn_ix = ML_(addFnDn)( cc->di, str, dirname);
- TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n",
- VG_(sizeXA)(fndn_ix_Table), fndn_ix,
- dirname, str);
+ if (version < 5) {
+ /* Add a dummy index-zero entry. DWARF3 numbers its files
+ from 1, for some reason. */
+ fndn_ix = ML_(addFnDn) ( cc->di, "<unknown_file>", NULL );
VG_(addToXA)( fndn_ix_Table, &fndn_ix );
- (void)get_ULEB128( &c ); /* skip last mod time */
- (void)get_ULEB128( &c ); /* file size */
+ while (peek_UChar(&c) != 0) {
+ DiCursor cur = get_AsciiZ(&c);
+ str = ML_(addStrFromCursor)( cc->di, cur );
+ dir_xa_ix = get_ULEB128( &c );
+ if (dirname_xa != NULL
+ && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa))
+ dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix );
+ else
+ dirname = NULL;
+ fndn_ix = ML_(addFnDn)( cc->di, str, dirname);
+ TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n",
+ VG_(sizeXA)(fndn_ix_Table), fndn_ix,
+ dirname, str);
+ VG_(addToXA)( fndn_ix_Table, &fndn_ix );
+ (void)get_ULEB128( &c ); /* skip last mod time */
+ (void)get_ULEB128( &c ); /* file size */
+ }
+ } else {
+ UChar forms[256];
+ UChar p_ndx = 0, d_ndx = 0;
+ UInt file_names_count;
+ UChar file_names_entry_format_count;
+ UInt n;
+ DiSlice debugstr_img = cc->escn_debug_str;
+ DiSlice debuglinestr_img = cc->escn_debug_line_str;
+ file_names_entry_format_count = get_UChar( &c );
+ for (n = 0; n < file_names_entry_format_count; n++) {
+ UInt lnct = get_ULEB128( &c );
+ UInt form = get_ULEB128( &c );
+ if (lnct == DW_LNCT_path)
+ p_ndx = n;
+ if (lnct == DW_LNCT_directory_index)
+ d_ndx = n;
+ forms[n] = form;
+ }
+ file_names_count = get_ULEB128( &c );
+ for (n = 0; n < file_names_count; n++) {
+ UInt f;
+ dir_xa_ix = 0;
+ str = NULL;
+ for (f = 0; f < file_names_entry_format_count; f++) {
+ UInt form = forms[f];
+ if (f == p_ndx)
+ str = get_line_str (cc->di, cc->is_dw64, &c, form,
+ debugstr_img, debuglinestr_img);
+ else if (n == d_ndx)
+ dir_xa_ix = get_line_ndx (cc->di, &c, form);
+ else
+ skip_line_form (cc->di, cc->is_dw64, &c, form);
+ }
+
+ if (dirname_xa != NULL
+ && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa))
+ dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix );
+ else
+ dirname = NULL;
+ fndn_ix = ML_(addFnDn)( cc->di, str, dirname);
+ TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n",
+ VG_(sizeXA)(fndn_ix_Table), fndn_ix,
+ dirname, str);
+ VG_(addToXA)( fndn_ix_Table, &fndn_ix );
+ }
}
/* We're done! The rest of it is not interesting. */
if (dirname_xa != NULL)
@@ -2011,11 +2424,12 @@ static void trace_DIE(
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
VG_(printf)(" %-18s: ", ML_(pp_DW_AT)(attr));
/* Get the form contents, so as to print them */
- get_Form_contents( &cts, cc, &c, True, form );
+ get_Form_contents( &cts, cc, &c, True, nf );
if (attr == DW_AT_sibling && cts.szB > 0) {
sibling = cts.u.val;
}
@@ -2094,9 +2508,10 @@ static void parse_var_DIE (
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_low_pc && cts.szB > 0) {
ip_lo = cts.u.val;
have_lo = True;
@@ -2196,9 +2611,10 @@ static void parse_var_DIE (
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_low_pc && cts.szB > 0) {
ip_lo = cts.u.val;
have_lo = True;
@@ -2282,9 +2698,10 @@ static void parse_var_DIE (
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
n_attrs++;
if (attr == DW_AT_name && cts.szB < 0) {
name = ML_(addStrFromCursor)( cc->di, cts.u.cur );
@@ -2646,9 +3063,10 @@ static const HChar* get_inlFnName (Int absori, const CUConst* cc, Bool td3)
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, &c, False/*td3*/, form );
+ get_Form_contents( &cts, cc, &c, False/*td3*/, nf );
if (attr == DW_AT_name) {
HChar *fnname;
if (cts.szB >= 0)
@@ -2720,9 +3138,10 @@ static Bool parse_inl_DIE (
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_low_pc && cts.szB > 0) {
ip_lo = cts.u.val;
have_lo = True;
@@ -2764,9 +3183,10 @@ static Bool parse_inl_DIE (
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_call_file && cts.szB > 0) {
Int ftabIx = (Int)cts.u.val;
if (ftabIx >= 1
@@ -3090,9 +3510,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr != DW_AT_language)
continue;
if (cts.szB <= 0)
@@ -3132,9 +3553,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
typeE.Te.TyBase.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3243,9 +3665,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_byte_size && cts.szB > 0) {
typeE.Te.TyPorR.szB = cts.u.val;
}
@@ -3275,9 +3698,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
typeE.Te.TyEnum.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3356,9 +3780,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
atomE.Te.Atom.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3411,9 +3836,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
typeE.Te.TyStOrUn.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3498,9 +3924,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
fieldE.Te.Field.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3585,9 +4012,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_type && cts.szB > 0) {
typeE.Te.TyArray.typeR
= cook_die_using_form( cc, (UWord)cts.u.val, form );
@@ -3626,9 +4054,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_lower_bound && cts.szB > 0
&& form_expected_for_bound (form)) {
lower = (Long)cts.u.val;
@@ -3714,9 +4143,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_name && cts.szB < 0) {
typeE.Te.TyTyDef.name
= ML_(cur_read_strdup)( cts.u.cur,
@@ -3764,9 +4194,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
while (True) {
DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name;
DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
+ const name_form *nf = &abbv->nf[nf_i];
nf_i++;
if (attr == 0 && form == 0) break;
- get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf );
if (attr == DW_AT_type && cts.szB > 0) {
typeE.Te.TyQual.typeR
= cook_die_using_form( cc, (UWord)cts.u.val, form );
@@ -4486,6 +4917,9 @@ static void trace_debug_abbrev (const DebugInfo* di,
while (True) {
ULong at_name = get_ULEB128( &abbv );
ULong at_form = get_ULEB128( &abbv );
+ if (at_form == DW_FORM_implicit_const) {
+ /* Long at_val = */ get_SLEB128 ( &abbv );
+ }
if (at_name == 0 && at_form == 0) break;
TRACE_D3(" %-18s %s\n",
ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
@@ -4502,9 +4936,10 @@ void new_dwarf3_reader_wrk (
DiSlice escn_debug_info, DiSlice escn_debug_types,
DiSlice escn_debug_abbv, DiSlice escn_debug_line,
DiSlice escn_debug_str, DiSlice escn_debug_ranges,
+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists,
DiSlice escn_debug_loc, DiSlice escn_debug_info_alt,
DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt,
- DiSlice escn_debug_str_alt
+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str
)
{
XArray* /* of TyEnt */ tyents = NULL;
@@ -4738,6 +5173,8 @@ void new_dwarf3_reader_wrk (
cc.escn_debug_str = pass == 0 ? escn_debug_str_alt
: escn_debug_str;
cc.escn_debug_ranges = escn_debug_ranges;
+ cc.escn_debug_rnglists = escn_debug_rnglists;
+ cc.escn_debug_loclists = escn_debug_loclists;
cc.escn_debug_loc = escn_debug_loc;
cc.escn_debug_line = pass == 0 ? escn_debug_line_alt
: escn_debug_line;
@@ -4746,6 +5183,7 @@ void new_dwarf3_reader_wrk (
cc.escn_debug_types = escn_debug_types;
cc.escn_debug_info_alt = escn_debug_info_alt;
cc.escn_debug_str_alt = escn_debug_str_alt;
+ cc.escn_debug_line_str = escn_debug_line_str;
cc.types_cuOff_bias = escn_debug_info.szB;
cc.alt_cuOff_bias = escn_debug_info.szB + escn_debug_types.szB;
cc.cu_start_offset = cu_start_offset;
@@ -5216,9 +5654,10 @@ ML_(new_dwarf3_reader) (
DiSlice escn_debug_info, DiSlice escn_debug_types,
DiSlice escn_debug_abbv, DiSlice escn_debug_line,
DiSlice escn_debug_str, DiSlice escn_debug_ranges,
+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists,
DiSlice escn_debug_loc, DiSlice escn_debug_info_alt,
DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt,
- DiSlice escn_debug_str_alt
+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str
)
{
volatile Int jumped;
@@ -5239,9 +5678,10 @@ ML_(new_dwarf3_reader) (
escn_debug_info, escn_debug_types,
escn_debug_abbv, escn_debug_line,
escn_debug_str, escn_debug_ranges,
+ escn_debug_rnglists, escn_debug_loclists,
escn_debug_loc, escn_debug_info_alt,
escn_debug_abbv_alt, escn_debug_line_alt,
- escn_debug_str_alt );
+ escn_debug_str_alt, escn_debug_line_str );
d3rd_jmpbuf_valid = False;
TRACE_D3("\n------ .debug_info reading was successful ------\n");
} else {
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index bc5a732d7..404034df0 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -2577,7 +2577,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4)
DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2)
DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2)
+ DiSlice debug_line_str_escn = DiSlice_INVALID; // .debug_line_str(dwarf5)
DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2)
+ DiSlice debug_rnglists_escn = DiSlice_INVALID; // .debug_rnglists(dwarf5)
+ DiSlice debug_loclists_escn = DiSlice_INVALID; // .debug_loclists(dwarf5)
DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2)
DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2)
DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt)
@@ -2683,10 +2686,22 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
if (!ML_(sli_is_valid)(debug_str_escn))
FIND(".zdebug_str", debug_str_escn)
+ FIND( ".debug_line_str", debug_line_str_escn)
+ if (!ML_(sli_is_valid)(debug_line_str_escn))
+ FIND(".zdebug_str", debug_line_str_escn)
+
FIND( ".debug_ranges", debug_ranges_escn)
if (!ML_(sli_is_valid)(debug_ranges_escn))
FIND(".zdebug_ranges", debug_ranges_escn)
+ FIND( ".debug_rnglists", debug_rnglists_escn)
+ if (!ML_(sli_is_valid)(debug_rnglists_escn))
+ FIND(".zdebug_rnglists", debug_rnglists_escn)
+
+ FIND( ".debug_loclists", debug_loclists_escn)
+ if (!ML_(sli_is_valid)(debug_loclists_escn))
+ FIND(".zdebug_loclists", debug_loclists_escn)
+
FIND( ".debug_loc", debug_loc_escn)
if (!ML_(sli_is_valid)(debug_loc_escn))
FIND(".zdebug_loc", debug_loc_escn)
@@ -2994,10 +3009,22 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
if (!ML_(sli_is_valid)(debug_str_escn))
FIND(need_dwarf2, ".zdebug_str", debug_str_escn)
+ FIND( need_dwarf2, ".debug_line_str", debug_line_str_escn)
+ if (!ML_(sli_is_valid)(debug_line_str_escn))
+ FIND(need_dwarf2, ".zdebug_line_str", debug_line_str_escn)
+
FIND( need_dwarf2, ".debug_ranges", debug_ranges_escn)
if (!ML_(sli_is_valid)(debug_ranges_escn))
FIND(need_dwarf2, ".zdebug_ranges", debug_ranges_escn)
+ FIND( need_dwarf2, ".debug_rnglists", debug_rnglists_escn)
+ if (!ML_(sli_is_valid)(debug_rnglists_escn))
+ FIND(need_dwarf2, ".zdebug_rnglists", debug_rnglists_escn)
+
+ FIND( need_dwarf2, ".debug_loclists", debug_loclists_escn)
+ if (!ML_(sli_is_valid)(debug_loclists_escn))
+ FIND(need_dwarf2, ".zdebug_loclists", debug_loclists_escn)
+
FIND( need_dwarf2, ".debug_loc", debug_loc_escn)
if (!ML_(sli_is_valid)(debug_loc_escn))
FIND(need_dwarf2, ".zdebug_loc", debug_loc_escn)
@@ -3231,7 +3258,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
debug_abbv_escn,
debug_line_escn,
debug_str_escn,
- debug_str_alt_escn );
+ debug_str_alt_escn,
+ debug_line_str_escn);
/* The new reader: read the DIEs in .debug_info to acquire
information on variable types and locations or inline info.
But only if the tool asks for it, or the user requests it on
@@ -3242,9 +3270,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
di, debug_info_escn, debug_types_escn,
debug_abbv_escn, debug_line_escn,
debug_str_escn, debug_ranges_escn,
+ debug_rnglists_escn, debug_loclists_escn,
debug_loc_escn, debug_info_alt_escn,
debug_abbv_alt_escn, debug_line_alt_escn,
- debug_str_alt_escn
+ debug_str_alt_escn, debug_line_str_escn
);
}
}
diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c
index f39ee006f..9153a74ca 100644
--- a/coregrind/m_debuginfo/readmacho.c
+++ b/coregrind/m_debuginfo/readmacho.c
@@ -1103,8 +1103,14 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di )
= getsectdata(dsli, "__DWARF", "__debug_line", NULL);
DiSlice debug_str_mscn
= getsectdata(dsli, "__DWARF", "__debug_str", NULL);
+ DiSlice debug_line_str_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_line_str", NULL);
DiSlice debug_ranges_mscn
= getsectdata(dsli, "__DWARF", "__debug_ranges", NULL);
+ DiSlice debug_rnglists_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_rnglists", NULL);
+ DiSlice debug_loclists_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_loclists", NULL);
DiSlice debug_loc_mscn
= getsectdata(dsli, "__DWARF", "__debug_loc", NULL);
@@ -1145,7 +1151,8 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di )
debug_abbv_mscn,
debug_line_mscn,
debug_str_mscn,
- DiSlice_INVALID /* ALT .debug_str */ );
+ DiSlice_INVALID, /* ALT .debug_str */
+ debug_line_str );
/* The new reader: read the DIEs in .debug_info to acquire
information on variable types and locations or inline info.
@@ -1160,11 +1167,14 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di )
debug_line_mscn,
debug_str_mscn,
debug_ranges_mscn,
+ debug_rnglists_mscn,
+ debug_loclists_mscn,
debug_loc_mscn,
DiSlice_INVALID, /* ALT .debug_info */
DiSlice_INVALID, /* ALT .debug_abbv */
DiSlice_INVALID, /* ALT .debug_line */
- DiSlice_INVALID /* ALT .debug_str */
+ DiSlice_INVALID, /* ALT .debug_str */
+ debug_line_str_mscn /* .debug_line_str */
);
}
}
--
2.18.4