@@ -761,12 +761,18 @@ llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t §) {
761
761
762
762
void ObjectFilePECOFF::ParseSymtab (Symtab &symtab) {
763
763
SectionList *sect_list = GetSectionList ();
764
- AppendFromExportTable (sect_list, symtab);
765
- AppendFromCOFFSymbolTable (sect_list, symtab);
764
+ rva_symbol_list_t sorted_exports = AppendFromExportTable (sect_list, symtab);
765
+ AppendFromCOFFSymbolTable (sect_list, symtab, sorted_exports );
766
766
}
767
767
768
- void ObjectFilePECOFF::AppendFromCOFFSymbolTable (SectionList *sect_list,
769
- Symtab &symtab) {
768
+ static bool RVASymbolListCompareRVA (const std::pair<uint32_t , uint32_t > &a,
769
+ const std::pair<uint32_t , uint32_t > &b) {
770
+ return a.first < b.first ;
771
+ }
772
+
773
+ void ObjectFilePECOFF::AppendFromCOFFSymbolTable (
774
+ SectionList *sect_list, Symtab &symtab,
775
+ const ObjectFilePECOFF::rva_symbol_list_t &sorted_exports) {
770
776
const uint32_t num_syms = m_binary->getNumberOfSymbols ();
771
777
if (num_syms == 0 )
772
778
return ;
@@ -795,22 +801,52 @@ void ObjectFilePECOFF::AppendFromCOFFSymbolTable(SectionList *sect_list,
795
801
if (section_number >= 1 ) {
796
802
symbol.GetAddressRef () = Address (
797
803
sect_list->FindSectionByID (section_number), coff_sym_ref.getValue ());
798
- symbol.SetType (MapSymbolType (coff_sym_ref.getType ()));
804
+ const auto symbol_type = MapSymbolType (coff_sym_ref.getType ());
805
+ symbol.SetType (symbol_type);
806
+
807
+ // Check for duplicate of exported symbols:
808
+ const uint32_t symbol_rva = symbol.GetAddressRef ().GetFileAddress () -
809
+ m_coff_header_opt.image_base ;
810
+ const auto &first_match = std::lower_bound (
811
+ sorted_exports.begin (), sorted_exports.end (),
812
+ std::make_pair (symbol_rva, 0 ), RVASymbolListCompareRVA);
813
+ for (auto it = first_match;
814
+ it != sorted_exports.end () && it->first == symbol_rva; ++it) {
815
+ Symbol *exported = symtab.SymbolAtIndex (it->second );
816
+ if (symbol_type != lldb::eSymbolTypeInvalid)
817
+ exported->SetType (symbol_type);
818
+ if (exported->GetMangled () == symbol.GetMangled ()) {
819
+ symbol.SetExternal (true );
820
+ // We don't want the symbol to be duplicated (e.g. when running
821
+ // `disas -n func`), but we also don't want to erase this entry (to
822
+ // preserve the original symbol order), so we mark it as additional.
823
+ symbol.SetType (lldb::eSymbolTypeAdditional);
824
+ } else {
825
+ // It is possible for a symbol to be exported in a different name
826
+ // from its original. In this case keep both entries so lookup using
827
+ // either names will work. If this symbol has an invalid type, replace
828
+ // it with the type from the export symbol.
829
+ if (symbol.GetType () == lldb::eSymbolTypeInvalid)
830
+ symbol.SetType (exported->GetType ());
831
+ }
832
+ }
799
833
}
800
834
symtab.AddSymbol (symbol);
801
835
}
802
836
}
803
837
804
- void ObjectFilePECOFF::AppendFromExportTable (SectionList *sect_list,
805
- Symtab &symtab) {
838
+ ObjectFilePECOFF::rva_symbol_list_t
839
+ ObjectFilePECOFF::AppendFromExportTable (SectionList *sect_list,
840
+ Symtab &symtab) {
806
841
const auto *export_table = m_binary->getExportTable ();
807
842
if (!export_table)
808
- return ;
843
+ return {} ;
809
844
const uint32_t num_syms = export_table->AddressTableEntries ;
810
845
if (num_syms == 0 )
811
- return ;
846
+ return {} ;
812
847
813
848
Log *log = GetLog (LLDBLog::Object);
849
+ rva_symbol_list_t export_list;
814
850
symtab.Reserve (symtab.GetNumSymbols () + num_syms);
815
851
// Read each export table entry, ordered by ordinal instead of by name.
816
852
for (const auto &entry : m_binary->export_directories ()) {
@@ -851,8 +887,12 @@ void ObjectFilePECOFF::AppendFromExportTable(SectionList *sect_list,
851
887
if (section_sp->GetPermissions () & ePermissionsExecutable)
852
888
symbol.SetType (lldb::eSymbolTypeCode);
853
889
symbol.SetExternal (true );
854
- symtab.AddSymbol (symbol);
890
+ uint32_t idx = symtab.AddSymbol (symbol);
891
+ export_list.push_back (std::make_pair (function_rva, idx));
855
892
}
893
+ std::stable_sort (export_list.begin (), export_list.end (),
894
+ RVASymbolListCompareRVA);
895
+ return export_list;
856
896
}
857
897
858
898
std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo () {
0 commit comments