From 9509f4e6578b78b6380a07c0b1c846b9c0d1682a Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Tue, 20 Sep 2022 10:44:45 +0300 Subject: [PATCH] [LLD][COFF] Improve symbol table info for import thunk Import thunks themselves contain a jump or branch, which is code by nature. Therefore the import thunk symbol should be marked as function type in the symbol table to help with debugging. The `__imp_` import symbol associated to the import thunk is also useful for debugging. However, when the import symbol isn't directly referenced outside of the import thunk, it doesn't normally get added to the symbol table. This change teaches LLD to add the import symbol explicitly. Reviewed By: mstorsjo Differential Revision: https://reviews.llvm.org/D134169 --- lld/COFF/Writer.cpp | 12 ++++++++++++ lld/test/COFF/symtab.test | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 0883841..b3761ba 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1179,6 +1179,10 @@ Optional Writer::createSymbol(Defined *def) { COFFSymbolRef ref = d->getCOFFSymbol(); sym.Type = ref.getType(); sym.StorageClass = ref.getStorageClass(); + } else if (def->kind() == Symbol::DefinedImportThunkKind) { + sym.Type = (IMAGE_SYM_DTYPE_FUNCTION << SCT_COMPLEX_TYPE_SHIFT) | + IMAGE_SYM_TYPE_NULL; + sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; } else { sym.Type = IMAGE_SYM_TYPE_NULL; sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; @@ -1225,6 +1229,14 @@ void Writer::createSymbolAndStringTable() { if (Optional sym = createSymbol(d)) outputSymtab.push_back(*sym); + + if (auto *dthunk = dyn_cast(d)) { + if (!dthunk->wrappedSym->writtenToSymtab) { + dthunk->wrappedSym->writtenToSymtab = true; + if (Optional sym = createSymbol(dthunk->wrappedSym)) + outputSymtab.push_back(*sym); + } + } } } } diff --git a/lld/test/COFF/symtab.test b/lld/test/COFF/symtab.test index 949e960..ccf26fd 100644 --- a/lld/test/COFF/symtab.test +++ b/lld/test/COFF/symtab.test @@ -15,6 +15,15 @@ # CHECK-NEXT: Value: 80 # CHECK-NEXT: Section: .text (1) # CHECK-NEXT: BaseType: Null (0x0) +# CHECK-NEXT: ComplexType: Function (0x2) +# CHECK-NEXT: StorageClass: External (0x2) +# CHECK-NEXT: AuxSymbolCount: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __imp_MessageBoxA +# CHECK-NEXT: Value: +# CHECK-NEXT: Section: .rdata (2) +# CHECK-NEXT: BaseType: Null (0x0) # CHECK-NEXT: ComplexType: Null (0x0) # CHECK-NEXT: StorageClass: External (0x2) # CHECK-NEXT: AuxSymbolCount: 0 @@ -24,6 +33,15 @@ # CHECK-NEXT: Value: 64 # CHECK-NEXT: Section: .text (1) # CHECK-NEXT: BaseType: Null (0x0) +# CHECK-NEXT: ComplexType: Function (0x2) +# CHECK-NEXT: StorageClass: External (0x2) +# CHECK-NEXT: AuxSymbolCount: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __imp_ExitProcess +# CHECK-NEXT: Value: +# CHECK-NEXT: Section: .rdata (2) +# CHECK-NEXT: BaseType: Null (0x0) # CHECK-NEXT: ComplexType: Null (0x0) # CHECK-NEXT: StorageClass: External (0x2) # CHECK-NEXT: AuxSymbolCount: 0 -- 2.7.4