summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2019-03-20 16:50:17 +0000
committerGreg Clayton <gclayton@apple.com>2019-03-20 16:50:17 +0000
commit621e8b438701e928b4f3ac9044c47925fe0e19f9 (patch)
tree93577931e8a995703e6b18cdbe48f4a91198e354 /lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
parenta2250e923b3926471c9dfdf163c4b134b0c2918a (diff)
downloadbcm5719-llvm-621e8b438701e928b4f3ac9044c47925fe0e19f9.tar.gz
bcm5719-llvm-621e8b438701e928b4f3ac9044c47925fe0e19f9.zip
Fix UUID decoding from minidump files
This patch fixes: UUIDs now don't include the age field from a PDB70 when the age is zero. Prior to this they would incorrectly contain the zero age which stopped us from being able to match up the UUID with real files. UUIDs for Apple targets get the first 32 bit value and next two 16 bit values swapped. Breakpad incorrectly swaps these values when it creates darwin minidump files, so this must be undone so we can match up symbol files with the minidump modules. UUIDs that are all zeroes are treated as invalid UUIDs. Breakpad will always save out a UUID, even if one wasn't available. This caused all files that have UUID values of zero to be uniqued to the first module that had a zero UUID. We now don't fill in the UUID if it is all zeroes. Added tests for PDB70 and ELF build ID based CvRecords. Differential Revision: https://reviews.llvm.org/D59433 llvm-svn: 356573
Diffstat (limited to 'lldb/source/Plugins/Process/minidump/MinidumpParser.cpp')
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.cpp47
1 files changed, 35 insertions, 12 deletions
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 0ec8ddcdcfb..884d7c9b0db 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -165,21 +165,44 @@ UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) {
static_cast<CvSignature>(static_cast<uint32_t>(*signature));
if (cv_signature == CvSignature::Pdb70) {
- // PDB70 record
const CvRecordPdb70 *pdb70_uuid = nullptr;
Status error = consumeObject(cv_record, pdb70_uuid);
- if (!error.Fail()) {
- auto arch = GetArchitecture();
- // For Apple targets we only need a 16 byte UUID so that we can match
- // the UUID in the Module to actual UUIDs from the built binaries. The
- // "Age" field is zero in breakpad minidump files for Apple targets, so
- // we restrict the UUID to the "Uuid" field so we have a UUID we can use
- // to match.
- if (arch.GetTriple().getVendor() == llvm::Triple::Apple)
- return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
- else
- return UUID::fromData(pdb70_uuid, sizeof(*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));
}
+ return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
} else if (cv_signature == CvSignature::ElfBuildId)
return UUID::fromData(cv_record);
OpenPOWER on IntegriCloud