[DWARFLinker] Set size of location expression of DW_FORM_block1 properly.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Wed, 24 May 2023 13:38:44 +0000 (15:38 +0200)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Thu, 25 May 2023 12:10:26 +0000 (14:10 +0200)
This patch fixes the problem introduced by D147066. As D147066 may change
the contents of location expression, it started to calculate final attribute
size. This patch uses more correct way to calculate size: DIEValue::sizeOf().

Differential Revision: https://reviews.llvm.org/D151348

llvm/lib/DWARFLinker/DWARFLinker.cpp
llvm/test/tools/dsymutil/X86/location-expression.test [new file with mode: 0644]

index 894c4e5..af2e0db 100644 (file)
@@ -1278,13 +1278,7 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
   Attr = Loc ? static_cast<DIEValueList *>(Loc)
              : static_cast<DIEValueList *>(Block);
 
-  if (Loc)
-    Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
-                     dwarf::Form(AttrSpec.Form), Loc);
-  else
-    Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
-                     dwarf::Form(AttrSpec.Form), Block);
-
+  DWARFUnit &OrigUnit = Unit.getOrigUnit();
   // If the block is a DWARF Expression, clone it into the temporary
   // buffer using cloneExpression(), otherwise copy the data directly.
   SmallVector<uint8_t, 32> Buffer;
@@ -1292,7 +1286,6 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
   if (DWARFAttribute::mayHaveLocationExpr(AttrSpec.Attr) &&
       (Val.isFormClass(DWARFFormValue::FC_Block) ||
        Val.isFormClass(DWARFFormValue::FC_Exprloc))) {
-    DWARFUnit &OrigUnit = Unit.getOrigUnit();
     DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()),
                        IsLittleEndian, OrigUnit.getAddressByteSize());
     DWARFExpression Expr(Data, OrigUnit.getAddressByteSize(),
@@ -1313,8 +1306,24 @@ unsigned DWARFLinker::DIECloner::cloneBlockAttribute(
   else
     Block->setSize(Bytes.size());
 
-  Die.addValue(DIEAlloc, Value);
-  return getULEB128Size(Bytes.size()) + Bytes.size();
+  if (Loc)
+    Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
+                     dwarf::Form(AttrSpec.Form), Loc);
+  else {
+    // The expression location data might be updated and exceed the original
+    // size. Check whether the new data fits into the original form.
+    if ((AttrSpec.Form == dwarf::DW_FORM_block1 &&
+         (Bytes.size() > UINT8_MAX)) ||
+        (AttrSpec.Form == dwarf::DW_FORM_block2 &&
+         (Bytes.size() > UINT16_MAX)) ||
+        (AttrSpec.Form == dwarf::DW_FORM_block4 && (Bytes.size() > UINT32_MAX)))
+      AttrSpec.Form = dwarf::DW_FORM_block;
+
+    Value = DIEValue(dwarf::Attribute(AttrSpec.Attr),
+                     dwarf::Form(AttrSpec.Form), Block);
+  }
+
+  return Die.addValue(DIEAlloc, Value)->sizeOf(OrigUnit.getFormParams());
 }
 
 unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
diff --git a/llvm/test/tools/dsymutil/X86/location-expression.test b/llvm/test/tools/dsymutil/X86/location-expression.test
new file mode 100644 (file)
index 0000000..a991edb
--- /dev/null
@@ -0,0 +1,458 @@
+## This test checks that size of DW_AT_location attribute
+## of the DW_FORM_block1 form is correctly written to the
+## output.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo '---' > %t2.map
+# RUN: echo "triple:          'x86_64-apple-darwin'" >> %t2.map
+# RUN: echo 'objects:'  >> %t2.map
+# RUN: echo " -  filename: '%t.o'" >> %t2.map
+# RUN: echo '    symbols:' >> %t2.map
+# RUN: echo '      - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }' >> %t2.map
+# RUN: echo '...' >> %t2.map
+# RUN: dsymutil -y %t2.map -f -o - | llvm-dwarfdump -a --verbose - | FileCheck %s
+
+# CHECK: file format Mach-O 64-bit x86-64
+# CHECK: .debug_info contents:
+# CHECK: Compile Unit:
+# CHECK: DW_TAG_compile_unit
+# CHECK: DW_AT_name{{.*}}"CU1"
+# CHECK: 0x0000001b:   DW_TAG_variable
+# CHECK: DW_AT_name {{.*}}"var1"
+# CHECK: DW_AT_type {{.*}}"class1"
+# CHECK:   DW_AT_location [DW_FORM_block1]  (DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address)
+# CHECK: 0x000000ab:   DW_TAG_variable
+# CHECK: DW_AT_name {{.*}}"var2"
+# CHECK: DW_AT_type {{.*}}"class1"
+# CHECK:   DW_AT_location [DW_FORM_block]  (DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address, DW_OP_const8u 0x2000, DW_OP_form_tls_address)
+# CHECK: 0x00000146:   DW_TAG_variable
+# CHECK: DW_AT_name {{.*}}"var3"
+# CHECK: DW_AT_type {{.*}}"class1"
+#
+
+--- !mach-o
+FileHeader:
+  magic:      0xFEEDFACF
+  cputype:    0x01000007
+  cpusubtype: 0x00000003
+  filetype:   0x00000001
+  ncmds:      2
+  sizeofcmds: 376
+  flags:      0x00002000
+  reserved:   0x00000000
+LoadCommands:
+  - cmd:      LC_SEGMENT_64
+    cmdsize:  232
+    segname:  ''
+    vmaddr:   0x00
+    vmsize:   0x300
+    fileoff:  0x300
+    filesize: 0x300
+    maxprot:  7
+    initprot: 7
+    nsects:   2
+    flags:    0
+    Sections:
+      - sectname:  __debug_abbrev
+        segname:   __DWARF
+        addr:      0x000000000000000F
+        size:      0x38
+        offset:    0x00000380
+        align:     0
+        reloff:    0x00000000
+        nreloc:    0
+        flags:     0x02000000
+        reserved1: 0x00000000
+        reserved2: 0x00000000
+        reserved3: 0x00000000
+      - sectname:  __debug_info
+        segname:   __DWARF
+        addr:      0x000000000000100
+        size:      0x15e
+        offset:    0x00000410
+        align:     0
+        reloff:    0x00000600
+        nreloc:    1
+        flags:     0x02000000
+        reserved1: 0x00000000
+        reserved2: 0x00000000
+        reserved3: 0x00000000
+        relocations:
+          - address:         0x1FC
+            symbolnum:       1
+            pcrel:           true
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          0x700
+    nsyms:           2
+    stroff:          0x720
+    strsize:         10
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - '__Z3foov'
+    - ''
+DWARF:
+  debug_abbrev:
+    - Table:
+      - Tag:      DW_TAG_compile_unit
+        Children: DW_CHILDREN_yes
+        Attributes:
+          - Attribute: DW_AT_producer
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_language
+            Form:      DW_FORM_data2
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_class_type
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+      - Tag:      DW_TAG_variable
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_const_value
+            Form:      DW_FORM_data4
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+          - Attribute: DW_AT_location
+            Form:      DW_FORM_block1
+      - Tag:      DW_TAG_variable
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_const_value
+            Form:      DW_FORM_data4
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+          - Attribute: DW_AT_location
+            Form:      DW_FORM_block
+      - Tag:      DW_TAG_variable
+        Children: DW_CHILDREN_no
+        Attributes:
+          - Attribute: DW_AT_name
+            Form:      DW_FORM_string
+          - Attribute: DW_AT_const_value
+            Form:      DW_FORM_data4
+          - Attribute: DW_AT_type
+            Form:      DW_FORM_ref4
+  debug_info:
+    - Version: 4
+      Entries:
+        - AbbrCode: 1
+          Values:
+            - CStr: by_hand
+            - Value:  0x04
+            - CStr: CU1
+        - AbbrCode: 2
+          Values:
+            - CStr: class1
+        - AbbrCode: 3
+          Values:
+            - CStr: var1
+            - Value:  0x00000000
+            - Value:  0x0000001a
+            - BlockData:
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+        - AbbrCode: 4
+          Values:
+            - CStr: var2
+            - Value:  0x00000000
+            - Value:  0x0000001a
+            - BlockData:
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+                - 0x0e
+                - 0x00
+                - 0x20
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x00
+                - 0x9b
+        - AbbrCode: 5
+          Values:
+            - CStr: var3
+            - Value:  0x00000000
+            - Value:  0x0000001a
+        - AbbrCode: 0
+...