Index: lld/COFF/Writer.cpp =================================================================== --- lld/COFF/Writer.cpp +++ lld/COFF/Writer.cpp @@ -120,7 +120,7 @@ void createSymbolAndStringTable(); void openFile(StringRef OutputPath); template void writeHeader(); - void fixSafeSEHSymbols(); + void createSEHTable(OutputSection *RData); void setSectionPermissions(); void writeSections(); void writeBuildId(); @@ -302,7 +302,6 @@ } else { writeHeader(); } - fixSafeSEHSymbols(); writeSections(); sortExceptionTable(); writeBuildId(); @@ -387,28 +386,7 @@ RData->addChunk(C); } - // Create SEH table. x86-only. - if (Config->Machine != I386) - return; - - std::set Handlers; - - for (ObjFile *File : ObjFile::Instances) { - if (!File->SEHCompat) - return; - for (Symbol *B : File->SEHandlers) { - // Make sure the handler is still live. Assume all handlers are regular - // symbols. - auto *D = dyn_cast(B); - if (D && D->getChunk()->isLive()) - Handlers.insert(D); - } - } - - if (!Handlers.empty()) { - SEHTable = make(Handlers); - RData->addChunk(SEHTable); - } + createSEHTable(RData); } // Create .idata section for the DLL-imported symbol table. @@ -798,9 +776,31 @@ "failed to open " + Path); } -void Writer::fixSafeSEHSymbols() { - if (!SEHTable) +void Writer::createSEHTable(OutputSection *RData) { + // Create SEH table. x86-only. + if (Config->Machine != I386) return; + + std::set Handlers; + + for (ObjFile *File : ObjFile::Instances) { + if (!File->SEHCompat) + return; + for (Symbol *B : File->SEHandlers) { + // Make sure the handler is still live. Assume all handlers are regular + // symbols. + auto *D = dyn_cast(B); + if (D && D->getChunk()->isLive()) + Handlers.insert(D); + } + } + + if (Handlers.empty()) + return; + + SEHTable = make(Handlers); + RData->addChunk(SEHTable); + // Replace the absolute table symbol with a synthetic symbol pointing to the // SEHTable chunk so that we can emit base relocations for it and resolve // section relative relocations. Index: lld/test/COFF/safeseh.s =================================================================== --- lld/test/COFF/safeseh.s +++ lld/test/COFF/safeseh.s @@ -1,9 +1,14 @@ # RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main -# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC +# RUN: llvm-readobj -coff-basereloc -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC # RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main -# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC +# RUN: llvm-readobj -coff-basereloc -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC +# __safe_se_handler_table needs to be relocated against ImageBase. +# check that the relocation is present. +# CHECK-NOGC: BaseReloc [ +# CHECK-NOGC: Entry { +# CHECK-NOGC: Type: HIGHLOW # CHECK-NOGC: LoadConfig [ # CHECK-NOGC: Size: 0x48 # CHECK-NOGC: SEHandlerTable: 0x401048 @@ -13,6 +18,10 @@ # CHECK-NOGC-NEXT: 0x402006 # CHECK-NOGC-NEXT: ] +# Without the SEH table, the address is absolute, so check that we do +# not have a relocation for it. +# CHECK-GC: BaseReloc [ +# CHECK-GC-NEXT: ] # CHECK-GC: LoadConfig [ # CHECK-GC: Size: 0x48 # CHECK-GC: SEHandlerTable: 0x0