@@ -1130,16 +1130,47 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
11301130 if (!section_list)
11311131 return ;
11321132
1133- for (auto pid : m_index->publics ().getPublicsTable ()) {
1133+ PublicSym32 last_sym;
1134+ size_t last_sym_idx = 0 ;
1135+ lldb::SectionSP section_sp;
1136+
1137+ // To estimate the size of a symbol, we use the difference to the next symbol.
1138+ // If there's no next symbol or the section/segment changed, the symbol will
1139+ // take the remaining space. The estimate can be too high in case there's
1140+ // padding between symbols. This similar to the algorithm used by the DIA
1141+ // SDK.
1142+ auto finish_last_symbol = [&](const PublicSym32 *next) {
1143+ if (!section_sp)
1144+ return ;
1145+ Symbol *last = symtab.SymbolAtIndex (last_sym_idx);
1146+ if (!last)
1147+ return ;
1148+
1149+ if (next && last_sym.Segment == next->Segment ) {
1150+ assert (last_sym.Offset <= next->Offset );
1151+ last->SetByteSize (next->Offset - last_sym.Offset );
1152+ } else {
1153+ // the last symbol was the last in its section
1154+ assert (section_sp->GetByteSize () >= last_sym.Offset );
1155+ assert (!next || next->Segment > last_sym.Segment );
1156+ last->SetByteSize (section_sp->GetByteSize () - last_sym.Offset );
1157+ }
1158+ };
1159+
1160+ // the address map is sorted by the address of a symbol
1161+ for (auto pid : m_index->publics ().getAddressMap ()) {
11341162 PdbGlobalSymId global{pid, true };
11351163 CVSymbol sym = m_index->ReadSymbolRecord (global);
11361164 auto kind = sym.kind ();
11371165 if (kind != S_PUB32)
11381166 continue ;
11391167 PublicSym32 pub =
11401168 llvm::cantFail (SymbolDeserializer::deserializeAs<PublicSym32>(sym));
1169+ finish_last_symbol (&pub);
1170+
1171+ if (!section_sp || last_sym.Segment != pub.Segment )
1172+ section_sp = section_list->FindSectionByID (pub.Segment );
11411173
1142- auto section_sp = section_list->FindSectionByID (pub.Segment );
11431174 if (!section_sp)
11441175 continue ;
11451176
@@ -1148,20 +1179,24 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {
11481179 (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)
11491180 type = eSymbolTypeCode;
11501181
1151- symtab.AddSymbol (Symbol (/* symID=*/ pid,
1152- /* name=*/ pub.Name ,
1153- /* type=*/ type,
1154- /* external=*/ true ,
1155- /* is_debug=*/ true ,
1156- /* is_trampoline=*/ false ,
1157- /* is_artificial=*/ false ,
1158- /* section_sp=*/ section_sp,
1159- /* value=*/ pub.Offset ,
1160- /* size=*/ 0 ,
1161- /* size_is_valid=*/ false ,
1162- /* contains_linker_annotations=*/ false ,
1163- /* flags=*/ 0 ));
1164- }
1182+ last_sym_idx =
1183+ symtab.AddSymbol (Symbol (/* symID=*/ pid,
1184+ /* name=*/ pub.Name ,
1185+ /* type=*/ type,
1186+ /* external=*/ true ,
1187+ /* is_debug=*/ true ,
1188+ /* is_trampoline=*/ false ,
1189+ /* is_artificial=*/ false ,
1190+ /* section_sp=*/ section_sp,
1191+ /* value=*/ pub.Offset ,
1192+ /* size=*/ 0 ,
1193+ /* size_is_valid=*/ false ,
1194+ /* contains_linker_annotations=*/ false ,
1195+ /* flags=*/ 0 ));
1196+ last_sym = pub;
1197+ }
1198+
1199+ finish_last_symbol (nullptr );
11651200}
11661201
11671202size_t SymbolFileNativePDB::ParseFunctions (CompileUnit &comp_unit) {
0 commit comments