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