diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 67 | 
1 files changed, 51 insertions, 16 deletions
| diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index e76b7a3..aaec160 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1130,7 +1130,35 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {    if (!section_list)      return; -  for (auto pid : m_index->publics().getPublicsTable()) { +  PublicSym32 last_sym; +  size_t last_sym_idx = 0; +  lldb::SectionSP section_sp; + +  // To estimate the size of a symbol, we use the difference to the next symbol. +  // If there's no next symbol or the section/segment changed, the symbol will +  // take the remaining space. The estimate can be too high in case there's +  // padding between symbols. This similar to the algorithm used by the DIA +  // SDK. +  auto finish_last_symbol = [&](const PublicSym32 *next) { +    if (!section_sp) +      return; +    Symbol *last = symtab.SymbolAtIndex(last_sym_idx); +    if (!last) +      return; + +    if (next && last_sym.Segment == next->Segment) { +      assert(last_sym.Offset <= next->Offset); +      last->SetByteSize(next->Offset - last_sym.Offset); +    } else { +      // the last symbol was the last in its section +      assert(section_sp->GetByteSize() >= last_sym.Offset); +      assert(!next || next->Segment > last_sym.Segment); +      last->SetByteSize(section_sp->GetByteSize() - last_sym.Offset); +    } +  }; + +  // The address map is sorted by the address of a symbol. +  for (auto pid : m_index->publics().getAddressMap()) {      PdbGlobalSymId global{pid, true};      CVSymbol sym = m_index->ReadSymbolRecord(global);      auto kind = sym.kind(); @@ -1138,8 +1166,11 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {        continue;      PublicSym32 pub =          llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym)); +    finish_last_symbol(&pub); + +    if (!section_sp || last_sym.Segment != pub.Segment) +      section_sp = section_list->FindSectionByID(pub.Segment); -    auto section_sp = section_list->FindSectionByID(pub.Segment);      if (!section_sp)        continue; @@ -1148,20 +1179,24 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {          (pub.Flags & PublicSymFlags::Code) != PublicSymFlags::None)        type = eSymbolTypeCode; -    symtab.AddSymbol(Symbol(/*symID=*/pid, -                            /*name=*/pub.Name, -                            /*type=*/type, -                            /*external=*/true, -                            /*is_debug=*/true, -                            /*is_trampoline=*/false, -                            /*is_artificial=*/false, -                            /*section_sp=*/section_sp, -                            /*value=*/pub.Offset, -                            /*size=*/0, -                            /*size_is_valid=*/false, -                            /*contains_linker_annotations=*/false, -                            /*flags=*/0)); -  } +    last_sym_idx = +        symtab.AddSymbol(Symbol(/*symID=*/pid, +                                /*name=*/pub.Name, +                                /*type=*/type, +                                /*external=*/true, +                                /*is_debug=*/true, +                                /*is_trampoline=*/false, +                                /*is_artificial=*/false, +                                /*section_sp=*/section_sp, +                                /*value=*/pub.Offset, +                                /*size=*/0, +                                /*size_is_valid=*/false, +                                /*contains_linker_annotations=*/false, +                                /*flags=*/0)); +    last_sym = pub; +  } + +  finish_last_symbol(nullptr);  }  size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { | 
