[lld] r347820 - [ELF] --gdb-index: use lower_bound to compute relative CU index in the object file

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 28 16:17:00 PST 2018


Author: maskray
Date: Wed Nov 28 16:17:00 2018
New Revision: 347820

URL: http://llvm.org/viewvc/llvm-project?rev=347820&view=rev
Log:
[ELF] --gdb-index: use lower_bound to compute relative CU index in the object file

Summary:
This reinstates what I originally intended to do in D54361.
It removes the assumption that .debug_gnu_pubnames has increasing CuOffset.

Now we do better than gold here: when .debug_gnu_pubnames contains
multiple sets, gold would think every set has the same CU index as the
first set (incorrect).

Reviewed By: ruiu

Reviewers: ruiu, dblaikie, espindola

Subscribers: emaste, arichardson, arphaman, llvm-commits

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

Modified:
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/test/ELF/gdb-index-multiple-cu.s

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=347820&r1=347819&r2=347820&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Nov 28 16:17:00 2018
@@ -2434,16 +2434,17 @@ readPubNamesAndTypes(const LLDDwarfObj<E
   std::vector<GdbIndexSection::NameAttrEntry> Ret;
   for (const DWARFSection *Pub : {&PubNames, &PubTypes}) {
     DWARFDebugPubTable Table(Obj, *Pub, Config->IsLE, true);
-    uint32_t I = 0;
     for (const DWARFDebugPubTable::Set &Set : Table.getData()) {
       // The value written into the constant pool is Kind << 24 | CuIndex. As we
       // don't know how many compilation units precede this object to compute
       // CuIndex, we compute (Kind << 24 | CuIndexInThisObject) instead, and add
       // the number of preceding compilation units later.
-      //
-      // We assume both CUs[*].CuOff and Set.Offset are increasing.
-      while (I < CUs.size() && CUs[I].CuOffset < Set.Offset)
-        ++I;
+      uint32_t I =
+          lower_bound(CUs, Set.Offset,
+                      [](GdbIndexSection::CuEntry CU, uint32_t Offset) {
+                        return CU.CuOffset < Offset;
+                      }) -
+          CUs.begin();
       for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
         Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)},
                        (Ent.Descriptor.toBits() << 24) | I});

Modified: lld/trunk/test/ELF/gdb-index-multiple-cu.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gdb-index-multiple-cu.s?rev=347820&r1=347819&r2=347820&view=diff
==============================================================================
--- lld/trunk/test/ELF/gdb-index-multiple-cu.s (original)
+++ lld/trunk/test/ELF/gdb-index-multiple-cu.s Wed Nov 28 16:17:00 2018
@@ -3,20 +3,27 @@
 # RUN: ld.lld --gdb-index %t.o -o %t
 # RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s
 
-# Attributes << 24 | CuIndex = 48 << 24 | 1 = 0x30000001
-# CHECK: Constant pool
-# CHECK-NEXT: 0(0x0): 0x30000001
+# CuIndexAndAttrs of _start:
+#   Attributes << 24 | CuIndex = 48 << 24 | 0 = 0x30000000
+# CuIndexAndAttrs of foo:
+#   Attributes << 24 | CuIndex = 48 << 24 | 1 = 0x30000001
+# CHECK:      Symbol table
+# CHECK-DAG:      String name: _start, CU vector index: 0
+# CHECK-DAG:      String name: foo, CU vector index: 1
+# CHECK:      Constant pool
+# CHECK-NEXT:   0(0x0): 0x30000000
+# CHECK-NEXT:   1(0x8): 0x30000001
 
-.globl _start
+.globl _start, foo
 _start:
-	ret
+foo:
 
 .section .debug_abbrev,"", at progbits
 	.byte	1              # Abbreviation Code
 	.byte	17             # DW_TAG_compile_unit
 	.byte	1              # DW_CHILDREN_yes
 	.ascii	"\264B"        # DW_AT_GNU_pubnames
-	.byte	12             # DW_FORM_flag
+	.byte	25             # DW_FORM_flag_present
 	.byte	0              # EOM(1)
 	.byte	0              # EOM(2)
 	.byte	2              # Abbreviation Code
@@ -34,8 +41,11 @@ _start:
 	.short	4              # DWARF version number
 	.long	0              # Offset Into Abbrev. Section
 	.byte	4              # Address Size
+.Ldie0:
 	.byte	1              # Abbrev [1] DW_TAG_compile_unit
-	.byte	0              # DW_AT_GNU_pubnames
+	.byte	2              # Abbrev [2] DW_TAG_subprogram
+	.asciz	"_start"       # DW_AT_name
+	.byte	0
 	.byte	0
 .Lcu_end0:
 .Lcu_begin1:
@@ -43,23 +53,36 @@ _start:
 	.short	4              # DWARF version number
 	.long	0              # Offset Into Abbrev. Section
 	.byte	4              # Address Size
-.Ldie:
+.Ldie1:
 	.byte	1              # Abbrev [1] DW_TAG_compile_unit
-	.byte	1              # DW_AT_GNU_pubnames
 	.byte	2              # Abbrev [2] DW_TAG_subprogram
-	.asciz	"_start"       # DW_AT_name
+	.asciz	"foo"          # DW_AT_name
 	.byte	0
 .Lcu_end1:
 
-# .debug_gnu_pubnames has just one set, associated with .Lcu_begin1 (CuIndex: 1)
+# Swap sets to test the case where pubnames are in a
+# different order than the CUs they refer to.
 .section .debug_gnu_pubnames,"", at progbits
-	.long	.LpubNames_end1-.LpubNames_begin1
+	# CuIndex: 1
+	.long	.LpubNames_end1 - .LpubNames_begin1
 .LpubNames_begin1:
 	.short	2              # Version
 	.long	.Lcu_begin1    # CU Offset
 	.long	.Lcu_end1 - .Lcu_begin1
-	.long	.Ldie - .Lcu_begin1
+	.long	.Ldie1 - .Lcu_begin1
 	.byte	48             # Attributes: FUNCTION, EXTERNAL
-	.asciz	"_start"       # External Name
+	.asciz	"foo"          # External Name
 	.long	0
 .LpubNames_end1:
+
+	# CuIndex: 0
+	.long	.LpubNames_end0 - .LpubNames_begin0
+.LpubNames_begin0:
+	.short	2              # Version
+	.long	.Lcu_begin0    # CU Offset
+	.long	.Lcu_end0 - .Lcu_begin0
+	.long	.Ldie0 - .Lcu_begin0
+	.byte	48             # Attributes: FUNCTION, EXTERNAL
+	.asciz	"_start"       # External Name
+	.long	0
+.LpubNames_end0:




More information about the llvm-commits mailing list