[llvm-dwp] Retrieve the DWOID from the CU for the cu_index entry
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 4 Dec 2015 17:20:04 +0000 (17:20 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 4 Dec 2015 17:20:04 +0000 (17:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254731 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFFormValue.h
lib/DebugInfo/DWARF/DWARFFormValue.cpp
test/tools/llvm-dwp/X86/simple.test
tools/llvm-dwp/llvm-dwp.cpp

index 7ddcc0d..3c32a3e 100644 (file)
@@ -84,6 +84,9 @@ public:
                  const DWARFUnit *u) const;
   static bool skipValue(uint16_t form, DataExtractor debug_info_data,
                         uint32_t *offset_ptr, const DWARFUnit *u);
+  static bool skipValue(uint16_t form, DataExtractor debug_info_data,
+                        uint32_t *offset_ptr, uint16_t Version,
+                        uint8_t AddrSize);
 
   static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize,
                                              uint16_t Version);
index a11b00a..3dc5842 100644 (file)
@@ -261,6 +261,12 @@ DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr,
 bool
 DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
                           uint32_t *offset_ptr, const DWARFUnit *cu) {
+  return skipValue(form, debug_info_data, offset_ptr, cu->getVersion(),
+                   cu->getAddressByteSize());
+}
+bool DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
+                               uint32_t *offset_ptr, uint16_t Version,
+                               uint8_t AddrSize) {
   bool indirect = false;
   do {
     switch (form) {
@@ -295,10 +301,10 @@ DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data,
 
     // Compile unit address sized values
     case DW_FORM_addr:
-      *offset_ptr += cu->getAddressByteSize();
+      *offset_ptr += AddrSize;
       return true;
     case DW_FORM_ref_addr:
-      *offset_ptr += getRefAddrSize(cu->getAddressByteSize(), cu->getVersion());
+      *offset_ptr += getRefAddrSize(AddrSize, Version);
       return true;
 
     // 0 byte values - implied from the form.
index 6ee1969..1c7b104 100644 (file)
@@ -28,6 +28,7 @@ CHECK: .debug_info.dwo contents:
 CHECK: 0x00000000: Compile Unit: length = 0x00000025 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000029)
 CHECK: DW_TAG_compile_unit
 CHECK:   DW_AT_name {{.*}} "a.cpp"
+CHECK:   DW_AT_GNU_dwo_id {{.*}} ([[DWOA:.*]])
 CHECK:   DW_TAG_variable
 CHECK:     DW_AT_name {{.*}} "a"
 CHECK:   DW_TAG_structure_type
@@ -35,6 +36,7 @@ CHECK:     DW_AT_name {{.*}} "foo"
 
 CHECK: 0x00000029: Compile Unit: length = 0x00000031 version = 0x0004 abbr_offset = 0x0031 addr_size = 0x08 (next unit at 0x0000005e)
 CHECK:   DW_AT_name {{.*}} "b.cpp"
+CHECK:   DW_AT_GNU_dwo_id {{.*}} ([[DWOB:.*]])
 CHECK:   DW_TAG_structure_type
 CHECK:     DW_AT_name {{.*}} "bar"
 CHECK:   DW_TAG_subprogram
@@ -45,8 +47,8 @@ CHECK: .debug_cu_index contents:
 Ensure only the relevant/contained sections are included in the table:
 CHECK: Index Signature          INFO                     ABBREV                   STR_OFFSETS
 Don't bother checking the Signatures, they aren't correct yet.
-CHECK:                          [0x00000000, 0x00000029) [0x00000000, 0x00000031) [0x00000000, 0x00000010)
-CHECK:                          [0x00000029, 0x0000005e) [0x00000031, 0x00000075) [0x00000010, 0x00000024)
+CHECK:     1 [[DWOA]]           [0x00000000, 0x00000029) [0x00000000, 0x00000031) [0x00000000, 0x00000010)
+CHECK:     2 [[DWOB]]           [0x00000029, 0x0000005e) [0x00000031, 0x00000075) [0x00000010, 0x00000024)
 
 CHECK: .debug_str.dwo contents:
 CHECK: "clang version
index e6a90cf..b68ba43 100644 (file)
@@ -1,5 +1,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
@@ -82,6 +83,52 @@ writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &Strings,
   return std::error_code();
 }
 
+static uint32_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
+  uint64_t CurCode;
+  uint32_t Offset = 0;
+  DataExtractor AbbrevData(Abbrev, true, 0);
+  while ((CurCode = AbbrevData.getULEB128(&Offset)) != AbbrCode) {
+    // Tag
+    AbbrevData.getULEB128(&Offset);
+    // DW_CHILDREN
+    AbbrevData.getU8(&Offset);
+    // Attributes
+    while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
+      ;
+  }
+  return Offset;
+}
+
+static uint64_t getCUSignature(StringRef Abbrev, StringRef Info) {
+  uint32_t Offset = 0;
+  DataExtractor InfoData(Info, true, 0);
+  InfoData.getU32(&Offset); // Length
+  uint16_t Version = InfoData.getU16(&Offset);
+  InfoData.getU32(&Offset); // Abbrev offset (should be zero)
+  uint8_t AddrSize = InfoData.getU8(&Offset);
+
+  uint32_t AbbrCode = InfoData.getULEB128(&Offset);
+
+  DataExtractor AbbrevData(Abbrev, true, 0);
+  uint32_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
+  uint64_t Tag = AbbrevData.getULEB128(&AbbrevOffset);
+  (void)Tag;
+  // FIXME: Real error handling
+  assert(Tag == dwarf::DW_TAG_compile_unit);
+  // DW_CHILDREN
+  AbbrevData.getU8(&AbbrevOffset);
+  uint32_t Name;
+  uint32_t Form;
+  while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
+             (Form = AbbrevData.getULEB128(&AbbrevOffset)) &&
+         Name != dwarf::DW_AT_GNU_dwo_id) {
+    DWARFFormValue::skipValue(Form, InfoData, &Offset, Version, AddrSize);
+  }
+  // FIXME: Real error handling
+  assert(Name == dwarf::DW_AT_GNU_dwo_id);
+  return InfoData.getU64(&Offset);
+}
+
 static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
   const auto &MCOFI = *Out.getContext().getObjectFileInfo();
   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
@@ -104,7 +151,6 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
   StringMap<uint32_t> Strings;
   uint32_t StringOffset = 0;
 
-  uint64_t UnitIndex = 0;
   uint32_t ContributionOffsets[8] = {};
 
   for (const auto &Input : Inputs) {
@@ -114,10 +160,11 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
 
     IndexEntries.emplace_back();
     UnitIndexEntry &CurEntry = IndexEntries.back();
-    CurEntry.Signature = UnitIndex++;
 
     StringRef CurStrSection;
     StringRef CurStrOffsetSection;
+    StringRef InfoSection;
+    StringRef AbbrevSection;
 
     for (const auto &Section : ErrOrObj->getBinary()->sections()) {
       StringRef Name;
@@ -138,6 +185,14 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
         CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
         ContributionOffsets[Index] +=
             (CurEntry.Contributions[Index].Length = Contents.size());
+
+        if (Kind == DW_SECT_INFO) {
+          assert(InfoSection.empty());
+          InfoSection = Contents;
+        } else if (Kind == DW_SECT_ABBREV) {
+          assert(AbbrevSection.empty());
+          AbbrevSection = Contents;
+        }
       }
 
       MCSection *OutSection = SectionPair->second.first;
@@ -151,6 +206,10 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
       }
     }
 
+    assert(!AbbrevSection.empty());
+    assert(!InfoSection.empty());
+    CurEntry.Signature = getCUSignature(AbbrevSection, InfoSection);
+
     if (auto Err = writeStringsAndOffsets(Out, Strings, StringOffset,
                                           StrSection, StrOffsetSection,
                                           CurStrSection, CurStrOffsetSection))