labath created this revision.
labath added reviewers: clayborg, amccarth, markmentovai, asmith.

D59433 <https://reviews.llvm.org/D59433> added code to swap bytes UUIDs coming 
from minidump files, but
only enabled it for apple platforms. Based on my research, I believe
this is the correct thing to do for windows as well, as the natural way
of printing U(G)UIDs on this platforms is to print the first three
components as (4 or 2)-byte integers printed in natural (big-endian)
order. This makes the UUID string coming out of lldb match the strings
produced by other windows tools.

The decision to byte-swap the age field is somewhat arbitrary, because
the age field is usually printed separately of the file GUID (and often
in decimal). However, for our purposes (telling whether two files are
identical), including it in the UUID is correct, and printing it in
big-endian makes the it easier to recognize the age value.

This also makes the UUIDs generated here (almost) match up with the
UUIDs computed for breakpad symbol files
(BreakpadRecords.cpp:parseModuleId), which already implemented the
byte-swapping. The "almost" is here because ObjectFileBreakpad does not
swap the age field, but I'll fix that in a follow-up.

There is no UUID support in ObjectFileCOFF at the moment, but ideally
the algorithms used here and in ObjectFileCOFF should be in sync so that
object file matching works correctly.


https://reviews.llvm.org/D60501

Files:
  
packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
  source/Plugins/Process/minidump/MinidumpParser.cpp
  source/Plugins/Process/minidump/MinidumpTypes.h

Index: source/Plugins/Process/minidump/MinidumpTypes.h
===================================================================
--- source/Plugins/Process/minidump/MinidumpTypes.h
+++ source/Plugins/Process/minidump/MinidumpTypes.h
@@ -44,7 +44,12 @@
 // Reference:
 // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
 struct CvRecordPdb70 {
-  uint8_t Uuid[16];
+  struct {
+    llvm::support::ulittle32_t Data1;
+    llvm::support::ulittle16_t Data2;
+    llvm::support::ulittle16_t Data3;
+    uint8_t Data4[8];
+  } Uuid;
   llvm::support::ulittle32_t Age;
   // char PDBFileName[];
 };
Index: source/Plugins/Process/minidump/MinidumpParser.cpp
===================================================================
--- source/Plugins/Process/minidump/MinidumpParser.cpp
+++ source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -66,40 +66,23 @@
     Status error = consumeObject(cv_record, pdb70_uuid);
     if (error.Fail())
       return UUID();
-    // If the age field is not zero, then include the entire pdb70_uuid struct
-    if (pdb70_uuid->Age != 0)
-      return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid));
-
-    // Many times UUIDs are all zeroes. This can cause more than one module
-    // to claim it has a valid UUID of all zeroes and causes the files to all
-    // merge into the first module that claims this valid zero UUID.
-    bool all_zeroes = true;
-    for (size_t i = 0; all_zeroes && i < sizeof(pdb70_uuid->Uuid); ++i)
-      all_zeroes = pdb70_uuid->Uuid[i] == 0;
-    if (all_zeroes)
-      return UUID();
-    
-    if (GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
-      // Breakpad incorrectly byte swaps the first 32 bit and next 2 16 bit
-      // values in the UUID field. Undo this so we can match things up
-      // with our symbol files
-      uint8_t apple_uuid[16];
-      // Byte swap the first 32 bits
-      apple_uuid[0] = pdb70_uuid->Uuid[3];
-      apple_uuid[1] = pdb70_uuid->Uuid[2];
-      apple_uuid[2] = pdb70_uuid->Uuid[1];
-      apple_uuid[3] = pdb70_uuid->Uuid[0];
-      // Byte swap the next 16 bit value
-      apple_uuid[4] = pdb70_uuid->Uuid[5];
-      apple_uuid[5] = pdb70_uuid->Uuid[4];
-      // Byte swap the next 16 bit value
-      apple_uuid[6] = pdb70_uuid->Uuid[7];
-      apple_uuid[7] = pdb70_uuid->Uuid[6];
-      for (size_t i = 8; i < sizeof(pdb70_uuid->Uuid); ++i)
-        apple_uuid[i] = pdb70_uuid->Uuid[i];
-      return UUID::fromData(apple_uuid, sizeof(apple_uuid));
+
+    CvRecordPdb70 swapped;
+    if (!GetArchitecture().GetTriple().isOSBinFormatELF()) {
+      // LLDB's UUID class treats the data as a sequence of bytes, but breakpad
+      // interprets it as a sequence of little-endian fields, which it converts
+      // to big-endian when converting to text. Swap the bytes to big endian so
+      // that the string representation comes out right.
+      swapped = *pdb70_uuid;
+      llvm::sys::swapByteOrder(swapped.Uuid.Data1);
+      llvm::sys::swapByteOrder(swapped.Uuid.Data2);
+      llvm::sys::swapByteOrder(swapped.Uuid.Data3);
+      llvm::sys::swapByteOrder(swapped.Age);
+      pdb70_uuid = &swapped;
     }
-    return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
+    if (pdb70_uuid->Age != 0)
+      return UUID::fromOptionalData(pdb70_uuid, sizeof(*pdb70_uuid));
+    return UUID::fromOptionalData(&pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
   } else if (cv_signature == CvSignature::ElfBuildId)
     return UUID::fromOptionalData(cv_record);
 
Index: packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
+++ packages/Python/lldbsuite/test/functionalities/postmortem/minidump/TestMiniDump.py
@@ -51,27 +51,27 @@
         expected_modules = [
             {
                 'filename' : r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug/fizzbuzz.exe",
-                'uuid' : '91B7450F-969A-F946-BF8F-2D6076EA421A-11000000',
+                'uuid' : '0F45B791-9A96-46F9-BF8F-2D6076EA421A-00000011',
             },
             {
                 'filename' : r"C:\Windows\SysWOW64/ntdll.dll",
-                'uuid' : '6A84B0BB-2C40-5240-A16B-67650BBFE6B0-02000000',
+                'uuid' : 'BBB0846A-402C-4052-A16B-67650BBFE6B0-00000002',
             },
             {
                 'filename' : r"C:\Windows\SysWOW64/kernel32.dll",
-                'uuid' : '1B7ECBE5-5E00-1341-AB98-98D6913B52D8-02000000',
+                'uuid' : 'E5CB7E1B-005E-4113-AB98-98D6913B52D8-00000002',
             },
             {
                 'filename' : r"C:\Windows\SysWOW64/KERNELBASE.dll",
-                'uuid' : '4152F90B-0DCB-D44B-AC5D-186A6452E522-01000000',
+                'uuid' : '0BF95241-CB0D-4BD4-AC5D-186A6452E522-00000001',
             },
             {
                 'filename' : r"C:\Windows\System32/MSVCP120D.dll",
-                'uuid' : '6E51053C-E757-EB40-8D3F-9722C5BD80DD-01000000',
+                'uuid' : '3C05516E-57E7-40EB-8D3F-9722C5BD80DD-00000001',
             },
             {
                 'filename' : r"C:\Windows\System32/MSVCR120D.dll",
-                'uuid' : '86FB8263-C446-4640-AE42-8D97B3F91FF2-01000000',
+                'uuid' : '6382FB86-46C4-4046-AE42-8D97B3F91FF2-00000001',
             },
         ]
         self.assertEqual(self.target.GetNumModules(), len(expected_modules))
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to