mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-23 07:52:06 +00:00
[PECOFF] Implement /SAFESEH option.
LLD now prints an error message if /SAFESEH option is specified and one or more input files are not compatible with SEH. llvm-svn: 201900
This commit is contained in:
parent
27cfe10df8
commit
a5dc335574
@ -68,6 +68,7 @@ public:
|
||||
|
||||
error_code parse(StringMap &altNames);
|
||||
StringRef getLinkerDirectives() const { return _directives; }
|
||||
bool isCompatibleWithSEH() const { return _compatibleWithSEH; }
|
||||
|
||||
virtual const atom_collection<DefinedAtom> &defined() const {
|
||||
return _definedAtoms;
|
||||
@ -136,6 +137,9 @@ private:
|
||||
// The contents of .drectve section.
|
||||
StringRef _directives;
|
||||
|
||||
// True if the object has "@feat.00" symbol.
|
||||
bool _compatibleWithSEH;
|
||||
|
||||
// A map from symbol to its name. All symbols should be in this map except
|
||||
// unnamed ones.
|
||||
std::map<const coff_symbol *, StringRef> _symbolName;
|
||||
@ -317,10 +321,18 @@ error_code FileCOFF::readSymbolTable(vector<const coff_symbol *> &result) {
|
||||
"Cannot atomize IMAGE_SYM_DEBUG!");
|
||||
result.push_back(sym);
|
||||
|
||||
// Cache the name.
|
||||
StringRef name;
|
||||
if (error_code ec = _obj->getSymbolName(sym, name))
|
||||
return ec;
|
||||
|
||||
// Existence of the symbol @feat.00 indicates that object file is compatible
|
||||
// with Safe Exception Handling.
|
||||
if (name == "@feat.00") {
|
||||
_compatibleWithSEH = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cache the name.
|
||||
_symbolName[sym] = name;
|
||||
|
||||
// Symbol may be followed by auxiliary symbol table records. The aux
|
||||
@ -778,9 +790,8 @@ error_code FileCOFF::findSection(StringRef name, const coff_section *&result) {
|
||||
return error_code::success();
|
||||
}
|
||||
}
|
||||
// Section was not found, but it's not an error. This method returns an
|
||||
// error
|
||||
// only when there's a read error.
|
||||
// Section was not found, but it's not an error. This method returns
|
||||
// an error only when there's a read error.
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
@ -930,6 +941,7 @@ public:
|
||||
parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry ®istry,
|
||||
std::vector<std::unique_ptr<File>> &result) const {
|
||||
// Parse the memory buffer as PECOFF file.
|
||||
const char *mbName = mb->getBufferIdentifier();
|
||||
error_code ec;
|
||||
std::unique_ptr<FileCOFF> file(new FileCOFF(std::move(mb), ec));
|
||||
if (ec)
|
||||
@ -943,6 +955,14 @@ public:
|
||||
|
||||
if (error_code ec = file->parse(_context.alternateNames()))
|
||||
return ec;
|
||||
|
||||
// Check for /SAFESEH.
|
||||
if (_context.requireSEH() && !file->isCompatibleWithSEH()) {
|
||||
llvm::errs() << "/SAFESEH is specified, but " << mbName
|
||||
<< " is not compatible with SEH.\n";
|
||||
return llvm::object::object_error::parse_failed;
|
||||
}
|
||||
|
||||
result.push_back(std::move(file));
|
||||
return error_code::success();
|
||||
}
|
||||
|
9
lld/test/pecoff/safeseh.test
Normal file
9
lld/test/pecoff/safeseh.test
Normal file
@ -0,0 +1,9 @@
|
||||
# "hello.obj" does not have the symbol "@feat.00", so it's not
|
||||
# compatible with SEH.
|
||||
|
||||
# RUN: yaml2obj %p/Inputs/hello.obj.yaml > %t.obj
|
||||
# RUN: not lld -flavor link /safeseh /out:%t.exe /subsystem:console \
|
||||
# RUN: -- %t.obj 2> %t.err
|
||||
# RUN: FileCheck %s < %t.err
|
||||
|
||||
CHECK: /SAFESEH is specified, but {{.*}} is not compatible with SEH.
|
Loading…
Reference in New Issue
Block a user