alvinhochun created this revision.
alvinhochun added reviewers: labath, DavidSpickett, mstorsjo.
Herald added a subscriber: mgrang.
Herald added a project: All.
alvinhochun published this revision for review.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

If a symbol is the same as an export symbol, mark it as 'Additional' to
prevent the duplicated symbol from being repeated in some commands (e.g.
`disas -n func`). If the RVA is the same but exported with a different
name, only synchronize the symbol types.

Depends on D134265 <https://reviews.llvm.org/D134265>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134426

Files:
  lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
  lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
  lldb/test/Shell/ObjectFile/PECOFF/symbols-export-table.yaml

Index: lldb/test/Shell/ObjectFile/PECOFF/symbols-export-table.yaml
===================================================================
--- lldb/test/Shell/ObjectFile/PECOFF/symbols-export-table.yaml
+++ lldb/test/Shell/ObjectFile/PECOFF/symbols-export-table.yaml
@@ -6,20 +6,28 @@
 
 # CHECK:          UserID DSX Type    File Address/Value {{.*}} Size            Flags           Name
 # CHECK-NEXT:     ------
-# CHECK-NEXT:          1   X Code    0x0000000180001010        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportFunc
-# CHECK-NEXT:          2   X Data    0x0000000180003000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportInt
-# CHECK-NEXT: 4294967295     Code    0x0000000180001000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} entry
-# CHECK-NEXT: 4294967295     Code    0x0000000180001010        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportFunc
-# CHECK-NEXT: 4294967295     Invalid 0x0000000180003000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportInt
+# CHECK-NEXT:          1   X Code       0x0000000180001020        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportFnAlias
+# CHECK-NEXT:          2   X Code       0x0000000180001010        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportFunc
+# CHECK-NEXT:          3   X Data       0x0000000180003000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportInt
+# CHECK-NEXT:          4   X Data       0x0000000180003004        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportIntAlias
+# CHECK-NEXT: 4294967295     Code       0x0000000180001000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} entry
+# CHECK-NEXT: 4294967295   X Additional 0x0000000180001010        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportFunc
+# CHECK-NEXT: 4294967295     Code       0x0000000180001020        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} aliasFunc
+# CHECK-NEXT: 4294967295   X Additional 0x0000000180003000        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} exportInt
+# CHECK-NEXT: 4294967295     Data       0x0000000180003004        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} aliasInt
+# CHECK-NEXT: 4294967295     Invalid    0x0000000180003008        0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}} internalInt
 # CHECK-EMPTY:
 
 # Test file generated with:
 #   clang -O2 --target=x86_64-windows-gnu test.c -nostdlib -c -o test.obj
-#   lld-link -lldmingw -debug:symtab -dll -out:test.dll -entry:entry test.obj
+#   lld-link -lldmingw -debug:symtab -dll -out:test.dll -entry:entry -export:exportFnAlias=aliasFn -export:exportIntAlias=aliasInt test.obj
 # test.c:
 #   __attribute__((dllexport)) int exportInt;
+#   int internalInt;
+#   int aliasInt;
 #   void entry(void) {}
 #   __attribute__((dllexport)) void exportFunc(void) {}
+#   void aliasFunc(void) {}
 
 --- !COFF
 OptionalHeader:
@@ -41,7 +49,7 @@
   SizeOfHeapCommit: 4096
   ExportTable:
     RelativeVirtualAddress: 8224
-    Size:            107
+    Size:            156
 header:
   Machine:         IMAGE_FILE_MACHINE_AMD64
   Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ]
@@ -49,17 +57,17 @@
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     VirtualAddress:  4096
-    VirtualSize:     17
-    SectionData:     C36666666666662E0F1F840000000000C3
+    VirtualSize:     33
+    SectionData:     C36666666666662E0F1F840000000000C36666666666662E0F1F840000000000C3
   - Name:            .rdata
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
     VirtualAddress:  8192
-    VirtualSize:     139
-    SectionData:     FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF000000000000000000000000000000000000000048200000010000000200000002000000622000006A2000007220000073796D626F6C732D6578706F7274732E632E746D702E646C6C0010100000003000007620000081200000000001006578706F727446756E63006578706F7274496E7400
+    VirtualSize:     188
+    SectionData:     FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000004820000001000000040000000400000062200000722000008220000073796D626F6C732D6578706F7274732E632E746D702E646C6C00201000001010000000300000043000008A20000098200000A3200000AD20000000000100020003006578706F7274466E416C696173006578706F727446756E63006578706F7274496E74006578706F7274496E74416C69617300
   - Name:            .data
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
     VirtualAddress:  12288
-    VirtualSize:     4
+    VirtualSize:     12
     SectionData:     ''
 symbols:
   - Name:            entry
@@ -74,10 +82,28 @@
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            aliasFunc
+    Value:           32
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
   - Name:            exportInt
     Value:           0
     SectionNumber:   3
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            aliasInt
+    Value:           4
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            internalInt
+    Value:           8
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
 ...
Index: lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
===================================================================
--- lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -268,10 +268,12 @@
 
 private:
   bool CreateBinary();
+  typedef std::vector<std::pair<uint32_t, uint32_t>> rva_symbol_list_t;
   void AppendFromCOFFSymbolTable(lldb_private::SectionList *sect_list,
-                                 lldb_private::Symtab &symtab);
-  void AppendFromExportTable(lldb_private::SectionList *sect_list,
-                             lldb_private::Symtab &symtab);
+                                 lldb_private::Symtab &symtab,
+                                 const rva_symbol_list_t &sorted_exports);
+  rva_symbol_list_t AppendFromExportTable(lldb_private::SectionList *sect_list,
+                                          lldb_private::Symtab &symtab);
 
   dos_header_t m_dos_header;
   coff_header_t m_coff_header;
Index: lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -761,12 +761,18 @@
 
 void ObjectFilePECOFF::ParseSymtab(Symtab &symtab) {
   SectionList *sect_list = GetSectionList();
-  AppendFromExportTable(sect_list, symtab);
-  AppendFromCOFFSymbolTable(sect_list, symtab);
+  rva_symbol_list_t sorted_exports = AppendFromExportTable(sect_list, symtab);
+  AppendFromCOFFSymbolTable(sect_list, symtab, sorted_exports);
 }
 
-void ObjectFilePECOFF::AppendFromCOFFSymbolTable(SectionList *sect_list,
-                                                 Symtab &symtab) {
+static bool RVASymbolListCompareRVA(const std::pair<uint32_t, uint32_t> &a,
+                                    const std::pair<uint32_t, uint32_t> &b) {
+  return a.first < b.first;
+}
+
+void ObjectFilePECOFF::AppendFromCOFFSymbolTable(
+    SectionList *sect_list, Symtab &symtab,
+    const ObjectFilePECOFF::rva_symbol_list_t &sorted_exports) {
   const uint32_t num_syms = m_binary->getNumberOfSymbols();
   if (num_syms == 0)
     return;
@@ -795,22 +801,51 @@
     if (section_number >= 1) {
       symbol.GetAddressRef() = Address(
           sect_list->FindSectionByID(section_number), coff_sym_ref.getValue());
-      symbol.SetType(MapSymbolType(coff_sym_ref.getType()));
+      const auto symbol_type = MapSymbolType(coff_sym_ref.getType());
+      symbol.SetType(symbol_type);
+
+      // Check for duplicate of exported symbols:
+      const uint32_t symbol_rva = symbol.GetAddressRef().GetFileAddress() -
+                                  m_coff_header_opt.image_base;
+      const auto &first_match = std::lower_bound(
+          sorted_exports.begin(), sorted_exports.end(),
+          std::make_pair(symbol_rva, 0), RVASymbolListCompareRVA);
+      for (auto it = first_match;
+           it != sorted_exports.end() && it->first == symbol_rva; ++it) {
+        Symbol *exported = symtab.SymbolAtIndex(it->second);
+        if (symbol_type != lldb::eSymbolTypeInvalid)
+          exported->SetType(symbol_type);
+        if (exported->GetMangled() == symbol.GetMangled()) {
+          symbol.SetExternal(true);
+          // We don't want the symbol to be duplicated (e.g. when running
+          // `disas -n func`), but we also don't want to erase this entry (to
+          // preserve the original symbol order), so we mark it as additional.
+          symbol.SetType(lldb::eSymbolTypeAdditional);
+        } else {
+          // It is possible for a symbol to be exported in a different name
+          // from its original. In this case keep both entries so lookup using
+          // either names will work. Only synchronize the symbol type.
+          if (symbol.GetType() == lldb::eSymbolTypeInvalid)
+            symbol.SetType(exported->GetType());
+        }
+      }
     }
     symtab.AddSymbol(symbol);
   }
 }
 
-void ObjectFilePECOFF::AppendFromExportTable(SectionList *sect_list,
-                                             Symtab &symtab) {
+ObjectFilePECOFF::rva_symbol_list_t
+ObjectFilePECOFF::AppendFromExportTable(SectionList *sect_list,
+                                        Symtab &symtab) {
   const auto *export_table = m_binary->getExportTable();
   if (!export_table)
-    return;
+    return {};
   const uint32_t num_syms = export_table->AddressTableEntries;
   if (num_syms == 0)
-    return;
+    return {};
 
   Log *log = GetLog(LLDBLog::Object);
+  rva_symbol_list_t export_list;
   symtab.Reserve(symtab.GetNumSymbols() + num_syms);
   // Read each export table entry, ordered by ordinal instead of by name.
   for (const auto &entry : m_binary->export_directories()) {
@@ -851,8 +886,11 @@
       if (section_sp->GetPermissions() & ePermissionsExecutable)
         symbol.SetType(lldb::eSymbolTypeCode);
     symbol.SetExternal(true);
-    symtab.AddSymbol(symbol);
+    uint32_t idx = symtab.AddSymbol(symbol);
+    export_list.push_back(std::make_pair(function_rva, idx));
   }
+  std::sort(export_list.begin(), export_list.end(), RVASymbolListCompareRVA);
+  return export_list;
 }
 
 std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo() {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to