grimar created this revision.
grimar added reviewers: LLDB, clayborg.
Herald added subscribers: JDevlieghere, aprantl.

LLDB does not support this DWARF5 form atm.
At least gcc emits it in some cases when doing optimization
for abbreviations.

As far I can tell, clang does not support it yet, though
the rest LLVM code already knows about it.

The patch adds the support.


https://reviews.llvm.org/D52689

Files:
  lit/Breakpoint/Inputs/implicit_const_form_support.yaml
  lit/Breakpoint/implicit_const_form_support.test
  source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
  source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
  source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
  source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.h

Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -56,7 +56,8 @@
   };
 
   DWARFFormValue();
-  DWARFFormValue(const DWARFUnit *cu, dw_form_t form);
+  DWARFFormValue(const DWARFUnit *cu, dw_form_t form,
+                 ValueType val = ValueType());
   const DWARFUnit *GetCompileUnit() const { return m_cu; }
   void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; }
   dw_form_t Form() const { return m_form; }
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -154,8 +154,9 @@
 
 DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
 
-DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
-    : m_cu(cu), m_form(form), m_value() {}
+DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form,
+                               ValueType val)
+    : m_cu(cu), m_form(form), m_value(val) {}
 
 void DWARFFormValue::Clear() {
   m_cu = nullptr;
@@ -165,6 +166,9 @@
 
 bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
                                   lldb::offset_t *offset_ptr) {
+  if (m_form == DW_FORM_implicit_const)
+    return true;
+
   bool indirect = false;
   bool is_block = false;
   m_value.data = NULL;
@@ -366,6 +370,7 @@
 
   // 0 bytes values (implied from DW_FORM)
   case DW_FORM_flag_present:
+  case DW_FORM_implicit_const:
     return true;
 
     // 1 byte values
@@ -822,6 +827,7 @@
     case DW_FORM_ref_sig8:
     case DW_FORM_GNU_str_index:
     case DW_FORM_GNU_addr_index:
+    case DW_FORM_implicit_const:
       return true;
     default:
       break;
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -174,6 +174,10 @@
               debug_info_data.GetU32(&offset);
             break;
 
+          case DW_FORM_implicit_const:
+            form_size = 0;
+            break;
+
           default:
             *offset_ptr = m_offset;
             return false;
@@ -287,6 +291,7 @@
 
               // 0 sized form
               case DW_FORM_flag_present:
+              case DW_FORM_implicit_const:
                 form_size = 0;
                 break;
 
@@ -378,6 +383,13 @@
   Dump(dwarf2Data, cu, s, recurse_depth);
 }
 
+static void setUnsignedOrSigned(int &dest, DWARFFormValue &val) {
+  if (val.Form() == DW_FORM_implicit_const)
+    dest = val.Signed();
+  else
+    dest = val.Unsigned();
+}
+
 //----------------------------------------------------------------------
 // GetDIENamesAndRanges
 //
@@ -420,11 +432,13 @@
     uint32_t i;
     dw_attr_t attr;
     dw_form_t form;
+    DWARFFormValue::ValueType val;
     bool do_offset = false;
 
     for (i = 0; i < numAttributes; ++i) {
-      abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
-      DWARFFormValue form_value(cu, form);
+      abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form, &val);
+      DWARFFormValue form_value(cu, form, val);
+
       if (form_value.ExtractValue(debug_info_data, &offset)) {
         switch (attr) {
         case DW_AT_low_pc:
@@ -491,32 +505,32 @@
 
         case DW_AT_decl_file:
           if (decl_file == 0)
-            decl_file = form_value.Unsigned();
+            setUnsignedOrSigned(decl_file, form_value);
           break;
 
         case DW_AT_decl_line:
-          if (decl_line == 0)
-            decl_line = form_value.Unsigned();
+          if (decl_line != 0)
+            setUnsignedOrSigned(decl_line, form_value);
           break;
 
         case DW_AT_decl_column:
-          if (decl_column == 0)
-            decl_column = form_value.Unsigned();
+          if (decl_column != 0)
+            setUnsignedOrSigned(decl_column, form_value);
           break;
 
         case DW_AT_call_file:
-          if (call_file == 0)
-            call_file = form_value.Unsigned();
+          if (call_file != 0)
+            setUnsignedOrSigned(call_file, form_value);
           break;
 
         case DW_AT_call_line:
           if (call_line == 0)
-            call_line = form_value.Unsigned();
+            setUnsignedOrSigned(call_line, form_value);
           break;
 
         case DW_AT_call_column:
           if (call_column == 0)
-            call_column = form_value.Unsigned();
+            setUnsignedOrSigned(call_column, form_value);
           break;
 
         case DW_AT_frame_base:
Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -11,15 +11,17 @@
 #define SymbolFileDWARF_DWARFAttribute_h_
 
 #include "DWARFDefines.h"
+#include "DWARFFormValue.h"
 #include "llvm/ADT/SmallVector.h"
 #include <vector>
 
 class DWARFUnit;
-class DWARFFormValue;
 
 class DWARFAttribute {
 public:
-  DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {}
+  DWARFAttribute(dw_attr_t attr, dw_form_t form,
+                 DWARFFormValue::ValueType value)
+      : m_attr(attr), m_form(form), m_value(value) {}
 
   void set(dw_attr_t attr, dw_form_t form) {
     m_attr = attr;
@@ -29,9 +31,12 @@
   void set_form(dw_form_t form) { m_form = form; }
   dw_attr_t get_attr() const { return m_attr; }
   dw_form_t get_form() const { return m_form; }
-  void get(dw_attr_t &attr, dw_form_t &form) const {
+  void get(dw_attr_t &attr, dw_form_t &form,
+           DWARFFormValue::ValueType *val = nullptr) const {
     attr = m_attr;
     form = m_form;
+    if (val)
+      *val = m_value;
   }
   bool operator==(const DWARFAttribute &rhs) const {
     return m_attr == rhs.m_attr && m_form == rhs.m_form;
@@ -43,6 +48,7 @@
 protected:
   dw_attr_t m_attr;
   dw_form_t m_form;
+  DWARFFormValue::ValueType m_value;
 };
 
 class DWARFAttributes {
Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -26,10 +26,10 @@
   return UINT32_MAX;
 }
 
-void DWARFAttributes::Append(const DWARFUnit *cu,
-                             dw_offset_t attr_die_offset, dw_attr_t attr,
-                             dw_form_t form) {
-  AttributeValue attr_value = {cu, attr_die_offset, {attr, form}};
+void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
+                             dw_attr_t attr, dw_form_t form) {
+  AttributeValue attr_value = {
+      cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}};
   m_infos.push_back(attr_value);
 }
 
Index: source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -46,9 +46,10 @@
   }
 
   // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked()
-  void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr,
-                                      dw_form_t &form) const {
-    m_attributes[idx].get(attr, form);
+  void GetAttrAndFormByIndexUnchecked(
+      uint32_t idx, dw_attr_t &attr, dw_form_t &form,
+      DWARFFormValue::ValueType *val = nullptr) const {
+    m_attributes[idx].get(attr, form, val);
   }
   dw_form_t GetFormByIndexUnchecked(uint32_t idx) const {
     return m_attributes[idx].get_form();
Index: source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -41,9 +41,13 @@
     while (data.ValidOffset(*offset_ptr)) {
       dw_attr_t attr = data.GetULEB128(offset_ptr);
       dw_form_t form = data.GetULEB128(offset_ptr);
+      DWARFFormValue::ValueType val;
+
+      if (form == DW_FORM_implicit_const)
+        val.value.sval = data.GetULEB128(offset_ptr);
 
       if (attr && form)
-        m_attributes.push_back(DWARFAttribute(attr, form));
+        m_attributes.push_back(DWARFAttribute(attr, form, val));
       else
         break;
     }
Index: lit/Breakpoint/implicit_const_form_support.test
===================================================================
--- lit/Breakpoint/implicit_const_form_support.test
+++ lit/Breakpoint/implicit_const_form_support.test
@@ -0,0 +1,33 @@
+# RUN: yaml2obj %p/Inputs/implicit_const_form_support.yaml > %ttest
+# RUN: lldb-test breakpoints %ttest %s | FileCheck %s
+
+## The intention of the test is to check that DW_FORM_implicit_const
+## is supported and handled properly.
+
+## About implicit_const_form_support.yaml:
+## The following invocation and code were used to produce the binary
+## which was converted to yaml and reduced:
+## gcc version 8.0.1 20180319 (experimental) (GCC)
+##
+## g++ test.cpp -g -gdwarf-5 -o test
+##
+## // test.cpp
+## int foo1() {
+##  return 0;
+## }
+## 
+## int foo2() {
+##  return 0;
+## }
+## 
+## int main() {
+##  return foo1() + foo2();
+## }
+
+b foo1
+# CHECK-LABEL: b foo1
+# CHECK: Address: {{.*}}foo1() at test.cpp:2:9
+
+b foo2
+# CHECK-LABEL: b foo2
+# CHECK: Address: {{.*}}foo2() at test.cpp:6:9
Index: lit/Breakpoint/Inputs/implicit_const_form_support.yaml
===================================================================
--- lit/Breakpoint/Inputs/implicit_const_form_support.yaml
+++ lit/Breakpoint/Inputs/implicit_const_form_support.yaml
@@ -0,0 +1,41 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x00000000004004A0
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x00000000004004A0
+    AddressAlign:    0x0000000000000010
+    Content:         31ED4989D15E4889E24883E4F0505449C7C01006400048C7C1A005400048C7C77E054000E8B7FFFFFFF4660F1F440000B820204000483D202040007413B8000000004885C07409BF20204000FFE06690C30F1F440000662E0F1F840000000000BE202040004881EE2020400048C1FE034889F048C1E83F4801C648D1FE7411B8000000004885C07407BF20204000FFE0C30F1F440000662E0F1F840000000000803DD91A0000007517554889E5E87EFFFFFFC605C71A0000015DC30F1F440000C30F1F440000662E0F1F840000000000EB8EB800000000C3B800000000C3554889E5534883EC08E8E6FFFFFF89C3E8E5FFFFFF01D84883C4085B5DC30F1F4000415741564189FF415541544C8D251618000055488D2D16180000534989F64989D54C29E54883EC0848C1FD03E877FEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3
+  - Name:            .debug_frame
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000008
+    Content:         14000000FFFFFFFF03000178100C0708900100000000000014000000000000007205400000000000060000000000000014000000000000007805400000000000060000000000000034000000000000007E054000000000001E0000000000000004010000000E10860204030000000D060405000000830304140000000C070800
+  - Name:            .debug_info
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         900000000500010800000000023A00000021310000000000000072054000000000002A0000000000000000000000039A0000000109054C0000007E054000000000001E00000000000000019C040405696E7400012C000000059F0000004C00000078054000000000000600000000000000019C018C00000001910000004C00000072054000000000000600000000000000019C00
+  - Name:            .debug_abbrev
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         012E003F19030E3A21013B0B3921056E0E49131101120740187A190000021101250E130B030E1B0E1101120710170000032E003F19030E3A0B3B0B390B49131101120740187C1900000424000B0B3E0B0308000000
+  - Name:            .debug_aranges
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         2C00000002000000000008000000000072054000000000002A0000000000000000000000000000000000000000000000
+  - Name:            .debug_line
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         5600000002001F0000000101FB0E0D00010101010000000100000100746573742E6370700000000000050C000902720540000000000001050913050159050C22050913050159050C22050D9105167405175805012F0207000101
+  - Name:            .debug_str
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    Content:         2F686F6D652F756D622F74657374735F323031382F3130315F696D706C696369745F636F6E73742F6E657700666F6F3200746573742E63707000474E5520432B2B313420382E302E3120323031383033313920286578706572696D656E74616C29202D6D74756E653D67656E65726963202D6D617263683D7838362D3634202D67202D6764776172662D3500666F6F31005F5A34666F6F3176006D61696E005F5A34666F6F327600
+Symbols:
+...
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to