MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / parseCovMapFilenames

Function parseCovMapFilenames

src/Common/LLVMCoverageMapping.cpp:85–192  ·  view source on GitHub ↗

Parse all filename tables from the `__llvm_covmap` section. Each block starts with a 16-byte header followed by FilenamesSize bytes of compressed (or uncompressed) filename data. Header layout (all uint32_t, little-endian): NRecords (always 0 for LLVM coverage format V4+) FilenamesSize CoverageSize (always 0 for V4+) Version (3 = V4, 4 = V5, 5 = V6, …) The filename blob format (ULEB128

Source from the content-addressed store, hash-verified

83/// Uncompressed content for V5+ (i.e. format version 4+):
84/// For each filename: ULEB128 length followed by that many bytes
85std::vector<FilenameTable> parseCovMapFilenames(
86 const uint8_t * covmap_data,
87 size_t covmap_size)
88{
89 std::vector<FilenameTable> tables;
90
91 const uint8_t * p = covmap_data;
92 const uint8_t * const section_end = covmap_data + covmap_size;
93
94 while (p < section_end)
95 {
96 /// Align start of each block to 8 bytes within the section.
97 {
98 const uintptr_t off = static_cast<uintptr_t>(p - covmap_data);
99 if (off % 8 != 0)
100 p += 8 - (off % 8);
101 }
102 if (p + 16 > section_end)
103 break;
104
105 uint32_t n_records;
106 uint32_t filenames_size;
107 uint32_t coverage_size;
108 uint32_t version;
109 memcpy(&n_records, p, 4);
110 memcpy(&filenames_size, p + 4, 4);
111 memcpy(&coverage_size, p + 8, 4);
112 memcpy(&version, p + 12, 4);
113
114 p += 16;
115
116 if (p + filenames_size > section_end)
117 break;
118
119 const uint8_t * const fnames_start = p;
120 const uint8_t * const fnames_end = p + filenames_size;
121 p = fnames_end;
122
123 /// Compute MD5Hash of the raw filename blob — this is exactly what LLVM stores as FilenamesRef.
124 const uint64_t block_hash = computeMD5Hash(fnames_start, filenames_size);
125
126 /// Decode the filename blob.
127 const uint8_t * fp = fnames_start;
128 bool ok = true;
129
130 const uint64_t num_filenames = readULEB128(fp, fnames_end, ok);
131 const uint64_t uncompressed_len = readULEB128(fp, fnames_end, ok);
132 const uint64_t compressed_len = readULEB128(fp, fnames_end, ok);
133 if (!ok || num_filenames == 0)
134 continue;
135
136 /// Sanity-check the uncompressed size before allocating to avoid OOM on corrupt data.
137 /// 256 MB is a generous upper bound; also require it is not implausibly large
138 /// relative to the compressed/raw input (a 16× expansion factor is already very liberal).
139 static constexpr uint64_t kMaxUncompressedLen = 256u * 1024u * 1024u;
140 if (uncompressed_len > kMaxUncompressedLen
141 || uncompressed_len > static_cast<uint64_t>(filenames_size) * 16)
142 continue;

Callers 1

readLLVMCoverageMappingFunction · 0.85

Calls 12

memcpyFunction · 0.85
computeMD5HashFunction · 0.85
readULEB128Function · 0.85
uncompressFunction · 0.85
resizeMethod · 0.45
dataMethod · 0.45
assignMethod · 0.45
reserveMethod · 0.45
sizeMethod · 0.45
emplace_backMethod · 0.45
emptyMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected