summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/COFF/Writer.cpp52
-rw-r--r--lld/test/COFF/safeseh.s13
2 files changed, 37 insertions, 28 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 781afee6ed4..5ffef21db74 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -120,7 +120,7 @@ private:
void createSymbolAndStringTable();
void openFile(StringRef OutputPath);
template <typename PEHeaderTy> void writeHeader();
- void fixSafeSEHSymbols();
+ void createSEHTable(OutputSection *RData);
void setSectionPermissions();
void writeSections();
void writeBuildId();
@@ -302,7 +302,6 @@ void Writer::run() {
} else {
writeHeader<pe32_header>();
}
- fixSafeSEHSymbols();
writeSections();
sortExceptionTable();
writeBuildId();
@@ -387,28 +386,7 @@ void Writer::createMiscChunks() {
RData->addChunk(C);
}
- // Create SEH table. x86-only.
- if (Config->Machine != I386)
- return;
-
- std::set<Defined *> 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<DefinedRegular>(B);
- if (D && D->getChunk()->isLive())
- Handlers.insert(D);
- }
- }
-
- if (!Handlers.empty()) {
- SEHTable = make<SEHTableChunk>(Handlers);
- RData->addChunk(SEHTable);
- }
+ createSEHTable(RData);
}
// Create .idata section for the DLL-imported symbol table.
@@ -798,9 +776,31 @@ void Writer::openFile(StringRef Path) {
"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<Defined *> 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<DefinedRegular>(B);
+ if (D && D->getChunk()->isLive())
+ Handlers.insert(D);
+ }
+ }
+
+ if (Handlers.empty())
+ return;
+
+ SEHTable = make<SEHTableChunk>(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.
diff --git a/lld/test/COFF/safeseh.s b/lld/test/COFF/safeseh.s
index 83c15afbf93..d8fea2e44ee 100644
--- a/lld/test/COFF/safeseh.s
+++ b/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
OpenPOWER on IntegriCloud