Issue |
159978
|
Summary |
PDB named stream map forgets to mention niMac
|
Labels |
documentation,
debuginfo
|
Assignees |
|
Reporter |
nlguillemot
|
If I look at the named stream map from a real-world pdb in the debugger, I see the following data:
<!DOCTYPE html>
<HTML>
<head>
<title>Document</title></head>
<body>
<!--StartFragment-->
index | value
-- | --
[0x00000000] | 0x00000005
[0x00000001] | 0x0000000a
[0x00000002] | 0x00000001
[0x00000003] | 0x0000002f
[0x00000004] | 0x00000000
[0x00000005] | 0x0000002b
[0x00000006] | 0x0000031b
[0x00000007] | 0x0000001a
[0x00000008] | 0x00000319
[0x00000009] | 0x00000000
[0x0000000a] | 0x00000005
[0x0000000b] | 0x0000000a
[0x0000000c] | 0x00000006
[0x0000000d] | 0x00000013
[0x0000000e] | 0x00000007
[0x0000000f] | 0x00000000
[0x00000010] | 0x013351dc
<!--EndFragment-->
</body>
</HTML>
It begins with 5 which is the number of pairs in the map.
Then we see 10 for the capacity of the map (for the runtime data structure it originally came from, [not the stored data](https://github.com/llvm/llvm-project/issues/76602))
Then we see the present bit vector with 1 word, followed by that one word.
Then the deleted bit vector has 0 words, so we see the count 0, followed by no other words from it.
Then we see 5 pairs of uint32, for the map entries.
At the very end, after the named stream data, we can see the feature code 0x013351dc for PdbRaw_FeatureSig::VC140.
But in between the end of the pairs and the feature flag, there's one word that has the value 0. That is the issue for this bug.
Based on the Microsoft reference code I think this is the niMac field, used to incrementally generate indices for named streams. It happens to be zero in this case because the named stream map was created using a mode where the indices are assigned by a user-defined function.
```cpp
// create a name table with client defined name index generation
NMTNI(BOOL (*pfnNi_)(void*, OUT NI*), void* pfnNiArg_ = 0)
{
pfnNi = pfnNi_;
pfnNiArg = pfnNiArg_;
niMac = 0; // will not be used
mapSzoNi.setContext(&buf);
}
```
In the save code itself, you can see where the niMac is appended to the buffer.
```cpp
BOOL save(Buffer* pbuf) {
MTS_PROTECT(m_csReadWrite);
// optimization: since mapNiSzo is just the reverse map of mapSzoNi,
// we store only the latter
if (!buf.save(pbuf))
return FALSE;
traceOnly(CB cb0 = pbuf->Size());
if (!mapSzoNi.save(pbuf))
return FALSE;
traceOnly(CB cbMap = pbuf->Size() - cb0);
if (!pbuf->Append((PB)&niMac, sizeof niMac))
return FALSE;
trace((trSave, "NMTNI::save() cbBuf=%d cbMap=%d\n", buf.Size(), cbMap));
return TRUE;
}
```
In all PDB parsers (MSFT, LLVM, and Molecular Matters' [raw_pdb](https://github.com/MolecularMatters/raw_pdb)), it seems to me like the existence of this field is ignored. The parser just looks for feature flags and ignores anything that doesn't match. It just happens that the niMac field doesn't match the pattern for a feature flag, so it doesn't cause a false positive. In theory somebody could append an incredible number of named streams so that the niMac field looks like a feature flag. It's unlikely (impossible?) to happen in practice but I believe it is in fact a documentation bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs