Skip to content

Commit

Permalink
[coff] use relative instead of absolute __safe_se_handler_base when p…
Browse files Browse the repository at this point in the history
…resent

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
  • Loading branch information
inglorion committed Nov 7, 2017
1 parent 63efdd3 commit 6c301b6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 28 deletions.
52 changes: 26 additions & 26 deletions lld/COFF/Writer.cpp
Expand Up @@ -120,7 +120,7 @@ class Writer {
void createSymbolAndStringTable();
void openFile(StringRef OutputPath);
template <typename PEHeaderTy> void writeHeader();
void fixSafeSEHSymbols();
void createSEHTable(OutputSection *RData);
void setSectionPermissions();
void writeSections();
void writeBuildId();
Expand Down Expand Up @@ -302,7 +302,6 @@ void Writer::run() {
} else {
writeHeader<pe32_header>();
}
fixSafeSEHSymbols();
writeSections();
sortExceptionTable();
writeBuildId();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 11 additions & 2 deletions 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
Expand All @@ -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
Expand Down

0 comments on commit 6c301b6

Please sign in to comment.