From 5989281cf3af52fc07ad458297e70f559db02de7 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Tue, 9 Oct 2018 21:19:03 +0000 Subject: [PATCH] [PDB] Fix another bug in globals stream name lookup. When we're on the last bucket the computation is tricky. We were failing when the last bucket contained multiple matches. Added a new test for this. llvm-svn: 344081 --- llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp | 24 +++++++----- .../DebugInfo/PDB/Inputs/global-name-lookup.cpp | 23 +++++++++++ .../DebugInfo/PDB/Inputs/global-name-lookup.pdb | Bin 0 -> 94208 bytes llvm/test/DebugInfo/PDB/pdbdump-global-lookup.test | 42 +++++++++++---------- 4 files changed, 60 insertions(+), 29 deletions(-) create mode 100644 llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.cpp create mode 100644 llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.pdb diff --git a/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp b/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp index b03c6c3..e363195 100644 --- a/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/GlobalsStream.cpp @@ -56,22 +56,28 @@ GlobalsStream::findRecordsByName(StringRef Name, if (CompressedBucketIndex == -1) return Result; - uint32_t ChainStartOffset = GlobalsTable.HashBuckets[CompressedBucketIndex]; - uint32_t NextChainOffset = GlobalsTable.HashBuckets.size() * 12; uint32_t LastBucketIndex = GlobalsTable.HashBuckets.size() - 1; - if (static_cast(CompressedBucketIndex) < LastBucketIndex) { - NextChainOffset = GlobalsTable.HashBuckets[CompressedBucketIndex + 1]; + uint32_t StartRecordIndex = + GlobalsTable.HashBuckets[CompressedBucketIndex] / 12; + uint32_t EndRecordIndex = 0; + if (LLVM_LIKELY(uint32_t(CompressedBucketIndex) < LastBucketIndex)) { + EndRecordIndex = GlobalsTable.HashBuckets[CompressedBucketIndex + 1]; + } else { + // If this is the last bucket, it consists of all hash records until the end + // of the HashRecords array. + EndRecordIndex = GlobalsTable.HashRecords.size() * 12; } - ChainStartOffset /= 12; - NextChainOffset /= 12; - while (ChainStartOffset < NextChainOffset) { - PSHashRecord PSH = GlobalsTable.HashRecords[ChainStartOffset]; + EndRecordIndex /= 12; + + assert(EndRecordIndex <= GlobalsTable.HashRecords.size()); + while (StartRecordIndex < EndRecordIndex) { + PSHashRecord PSH = GlobalsTable.HashRecords[StartRecordIndex]; uint32_t Off = PSH.Off - 1; codeview::CVSymbol Record = Symbols.readRecord(Off); if (codeview::getSymbolName(Record) == Name) Result.push_back(std::make_pair(Off, std::move(Record))); - ++ChainStartOffset; + ++StartRecordIndex; } return Result; } diff --git a/llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.cpp b/llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.cpp new file mode 100644 index 0000000..70c84eb --- /dev/null +++ b/llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.cpp @@ -0,0 +1,23 @@ +// Build with "cl.exe /Z7 /GR- /GS- -EHs-c- every-function.cpp /link /debug /nodefaultlib /incremental:no /entry:main" + +void __cdecl operator delete(void *, unsigned int) {} +void __cdecl operator delete(void *, unsigned __int64) {} + +// Note: It's important that this particular function hashes to a higher bucket +// number than any other function in the PDB. When changing this test, ensure +// that this requirement still holds. This is because we need to test lookup +// in the edge case where we try to look something up in the final bucket, which +// has special logic. +int OvlGlobalFn(int X) { return X + 42; } +int OvlGlobalFn(int X, int Y) { return X + Y + 42; } +int OvlGlobalFn(int X, int Y, int Z) { return X + Y + Z + 42; } + +static int StaticFn(int X) { + return X + 42; +} + +int main(int argc, char **argv) { + // Make sure they don't get optimized out. + int Result = OvlGlobalFn(argc) + OvlGlobalFn(argc, argc) + OvlGlobalFn(argc, argc, argc) + StaticFn(argc); + return Result; +} diff --git a/llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.pdb b/llvm/test/DebugInfo/PDB/Inputs/global-name-lookup.pdb new file mode 100644 index 0000000000000000000000000000000000000000..3e53d6cd1ec7783ea472b156b76f3519c5400a5e GIT binary patch literal 94208 zcmeI5U2Ggz702)F`rD3UyQ$k)QJK<|rYTaFNLIp*rNT}*V->OP^;Gt2G3J)Ma6e>{!jVh6dmx3aJP~ZU`s-!`EK{fyXow@dS zvu;S8xJ~%q`0Smz=iGD8{AL~b&fJgv*@>A#sc@|9@9f$6$Rqy#Lwo$eL~rk!rmkIw z3{smhF=Y2Z=6H_O8D#nt0TB=Z5fA|p5CIVo0TB=Z5fA|pxJ?MW`JZ_u5fA|p5CIVo z0TB=Z5fA|p5CIVofjgYQQ2e<&{0en>A|L`HAOa#F0wN#+A|L`HAOa#F0?p_8ydjQN zz&L*^$VjEe=5c%m=aqS@@j5s!AYNz8Eb>;<&=y#u6uzSR2P*V2=$laALwPyWF*n9D zHIce3TdI$lI_Nu4mu)%yQkys;q5oK05wW$vr;CMlP1b)y8;?1&p&92&A|L`HAOa#F z0wN#+A|L`HAOa$ArxW)Q`aV=nm$MUajPg7E9_so; zKmYKmrU?bGWoy}I4i zrH&F!7Y}T$EQ+diECM1R0wN#+A|L`HAOa#F0wN#+BJe39z;XTwv#p(-`SYeBj4b(? z;9w$`&QJL#GBc%YA@2_*dK10AF$1Qpo%*)|BV$j(V~z)4g1^dP0p>o_(H5!$qs7l8 z+ixq~I(QD@zg=A1SIt;=xa(4mhXiCxz8FB7{XT~fe-oM@Uycx3@ z7TZj5at2a#uLh2-7)2TUtf)=;9kYH~Bk>$rh{x%o@iYXJL(D_0943zGDB`$UJWy3j z%QE=3_0xGxJY;#T?r9qz84y{Jy!waVBSQf>`Zv6MmQXI_1*b#@M=W zpVBi^6T$bnA9g>nK8~XO$J#j;#WT>K2=ttX#j<9EzQ!1!4h4#T)_^!xRo^$~o(uAmK{4I!a;;dh_M>sW|He9q3tF?H_u zF>1$xF79d@8tw_| zyanAQNDUm)?=}ekAIm|ML_h>YKmaRk3pxzF z_?zE1=4hgvnPaD~(+sw|GMu8%5olN^#yT)&KOu>q#LQ&6oTk6Q_QSAc88QYKm5cd1H_8)V+hPUsq_&$u!2$V!X z1VlgtL_h>YKm?UjoaF1-^YRNRf+x2#A0Ph=2%)fCz|y2#A0Ph=2%O zL%@wQ=NNN4VKs)l;)TD@@#x{$ayus#1sMDt3=%-*QW8VM-NoDf+gdzmfu4*&Npq@!jkN0r84=E zf{MWt5zTUk(b~(|tY$f%3ET_W2;p-9t~J5rLz0k5$n%gNL6k&51VlgtL_h>YKm9lG6nn8jUMIkm6yl=$lRD_(;JSn zABCZ_4RnT^@*U1h7prW)*WEY%XeN_R6vm(ZAFb$fem?Nb>x!NSr7h+;JjbY(7*}-v z!|q=sF1uK(U6*s?_PTSn^i3Vh_d}AVH(9Cs0m|1cqx%`kzqyQ#`|%BhI%H<#?1mSa z*Wlk8+lXiPZ(tc?ZnR~wg)*+)5R}Ci${1%ucrlC2=I3MfPI(LWE3&O)_jDm&up2z4 z%9&C**xhj?f2@$ghKZ?>d~vp1s&YRQ6UCx2AHMhDdkkxUK}MWjyH{j27u=DN!P*N8 zb4DGcCVN%EG2JVPfCz|y2#A0Ph=2%)fCz|y2rLq4KG)~5Psz3a)+vp}WByw!-v4hv8HMlvH$s@YjK`?}#zURT75AJjUPad#)~kgsy3(F2 zXAITK8!O5&2Eex8f^xeG;QLoDJ0JADu(}?~8K;s6h=2%)fCz|y2#A0Ph=2%)fC&6Q z6Zkpa*AM>Mn5n;brZ?@Gb4{Kpju>-sSIiXu;hCv_8}ql_G1LBh-0c09F<&WRYKmqi@-ns)LPI*5`8h=2%) zfCz|y2#A0Ph=2%)fCz}d>Jhkm^_o&kA|L`HAOa#F0wN#+A|L`HAOa#F0-q3p{{k^I B=End4 literal 0 HcmV?d00001 diff --git a/llvm/test/DebugInfo/PDB/pdbdump-global-lookup.test b/llvm/test/DebugInfo/PDB/pdbdump-global-lookup.test index 18a6f18..7018fe0 100644 --- a/llvm/test/DebugInfo/PDB/pdbdump-global-lookup.test +++ b/llvm/test/DebugInfo/PDB/pdbdump-global-lookup.test @@ -1,30 +1,32 @@ ; RUN: llvm-pdbutil dump -globals \ -; RUN: -global-name="operator delete" \ ; RUN: -global-name=main \ +; RUN: -global-name="operator delete" \ ; RUN: -global-name=abcdefg \ -; RUN: %p/Inputs/every-function.pdb | FileCheck %s +; RUN: %p/Inputs/global-name-lookup.pdb | FileCheck %s -; This is a separate command line invocation because B::PureFunc -; is special. It's in the last hash bucket, so it exercises a special -; calculation path. -; RUN: llvm-pdbutil dump -globals -global-name=B::PureFunc \ -; RUN: %p/Inputs/symbolformat.pdb | FileCheck --check-prefix=PURE %s +; RUN: llvm-pdbutil dump -globals \ +; RUN: -global-name=OvlGlobalFn \ +; RUN: %p/Inputs/global-name-lookup.pdb | FileCheck --check-prefix=LASTBUCKET %s CHECK: Global Symbols CHECK-NEXT: ============================================================ -CHECK-NEXT: Global Name `operator delete` -CHECK-NEXT: 1516 | S_PROCREF [size = 32] `operator delete` -CHECK-NEXT: module = 1, sum name = 0, offset = 324 -CHECK-NEXT: 1484 | S_PROCREF [size = 32] `operator delete` -CHECK-NEXT: module = 1, sum name = 0, offset = 184 CHECK-NEXT: Global Name `main` -CHECK-NEXT: 2016 | S_PROCREF [size = 20] `main` -CHECK-NEXT: module = 1, sum name = 0, offset = 1952 +CHECK-NEXT: 344 | S_PROCREF [size = 20] `main` +CHECK-NEXT: module = 1, sum name = 0, offset = 780 +CHECK-NEXT: Global Name `operator delete` +CHECK-NEXT: 228 | S_PROCREF [size = 32] `operator delete` +CHECK-NEXT: module = 1, sum name = 0, offset = 200 +CHECK-NEXT: 196 | S_PROCREF [size = 32] `operator delete` +CHECK-NEXT: module = 1, sum name = 0, offset = 52 CHECK-NEXT: Global Name `abcdefg` -CHECK-NEXT: (no matching records found) +CHECK-NEXT: (no matching records found) -PURE: Global Symbols -PURE-NEXT: ============================================================ -PURE-NEXT: Global Name `B::PureFunc` -PURE-NEXT: 980 | S_PROCREF [size = 28] `B::PureFunc` -PURE-NEXT: module = 1, sum name = 0, offset = 800 +LASTBUCKET: Global Symbols +LASTBUCKET-NEXT: ============================================================ +LASTBUCKET-NEXT: Global Name `OvlGlobalFn` +LASTBUCKET-NEXT: 316 | S_PROCREF [size = 28] `OvlGlobalFn` +LASTBUCKET-NEXT: module = 1, sum name = 0, offset = 608 +LASTBUCKET-NEXT: 288 | S_PROCREF [size = 28] `OvlGlobalFn` +LASTBUCKET-NEXT: module = 1, sum name = 0, offset = 464 +LASTBUCKET-NEXT: 260 | S_PROCREF [size = 28] `OvlGlobalFn` +LASTBUCKET-NEXT: module = 1, sum name = 0, offset = 348 -- 2.7.4