diff options
author | Bob Haarman <llvm@inglorion.net> | 2017-11-07 23:24:10 +0000 |
---|---|---|
committer | Bob Haarman <llvm@inglorion.net> | 2017-11-07 23:24:10 +0000 |
commit | 6c301b6eb1c393331ec38aee37b29cadae607723 (patch) | |
tree | b12580e9d7656c318036c42146c42952d5f3a9b3 | |
parent | 63efdd32dd1c8eb82eb6d812c0b145c052207a4b (diff) | |
download | bcm5719-llvm-6c301b6eb1c393331ec38aee37b29cadae607723.tar.gz bcm5719-llvm-6c301b6eb1c393331ec38aee37b29cadae607723.zip |
[coff] use relative instead of absolute __safe_se_handler_base when present
Summary:
__safe_se_handler_base should be either absolute 0 (when no SafeSEH
table is present), or relative to the image base (when the table is
present). An earlier change inadvertedly made the symbol absolute in
both cases, leading to the SafeSEH table not being locatble at run
time. This change fixes that and updates the safeseh test to check for
the presence of the relocation.
Reviewers: rnk, ruiu
Reviewed By: ruiu
Subscribers: ruiu, llvm-commits
Differential Revision: https://reviews.llvm.org/D39765
llvm-svn: 317635
-rw-r--r-- | lld/COFF/Writer.cpp | 52 | ||||
-rw-r--r-- | lld/test/COFF/safeseh.s | 13 |
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 |