forked from OSchip/llvm-project
[mach-o] Add support for -pie and -no_pie
There is a bit (MH_PIE) in the flags field of the mach_header which tells the kernel is a program was built position independent (for ASLR). The linker automatically attempts to build programs PIE if they are built for a recent OS version. But the -pie and -no_pie options override that default behavior. llvm-svn: 217408
This commit is contained in:
parent
513e8a911f
commit
b7035ae367
|
@ -104,6 +104,8 @@ public:
|
|||
const StringRefVector &frameworkDirs() const { return _frameworkDirs; }
|
||||
void setSysLibRoots(const StringRefVector &paths);
|
||||
const StringRefVector &sysLibRoots() const { return _syslibRoots; }
|
||||
bool PIE() const { return _pie; }
|
||||
void setPIE(bool pie) { _pie = pie; }
|
||||
|
||||
/// \brief Checks whether a given path on the filesystem exists.
|
||||
///
|
||||
|
@ -266,6 +268,7 @@ private:
|
|||
HeaderFileType _outputMachOType; // e.g MH_EXECUTE
|
||||
bool _outputMachOTypeStatic; // Disambiguate static vs dynamic prog
|
||||
bool _doNothing; // for -help and -v which just print info
|
||||
bool _pie;
|
||||
Arch _arch;
|
||||
OS _os;
|
||||
uint32_t _osMinVersion;
|
||||
|
|
|
@ -544,6 +544,52 @@ bool DarwinLdDriver::parse(int argc, const char *argv[],
|
|||
}
|
||||
}
|
||||
|
||||
// Handle -pie or -no_pie
|
||||
if (llvm::opt::Arg *pie = parsedArgs->getLastArg(OPT_pie, OPT_no_pie)) {
|
||||
switch (ctx.outputMachOType()) {
|
||||
case llvm::MachO::MH_EXECUTE:
|
||||
switch (ctx.os()) {
|
||||
case MachOLinkingContext::OS::macOSX:
|
||||
if ((minOSVersion < 0x000A0500) &&
|
||||
(pie->getOption().getID() == OPT_pie)) {
|
||||
diagnostics << "-pie can only be used when targeting "
|
||||
"Mac OS X 10.5 or later\n";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case MachOLinkingContext::OS::iOS:
|
||||
if ((minOSVersion < 0x00040200) &&
|
||||
(pie->getOption().getID() == OPT_pie)) {
|
||||
diagnostics << "-pie can only be used when targeting "
|
||||
"iOS 4.2 or later\n";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case MachOLinkingContext::OS::iOS_simulator:
|
||||
if (pie->getOption().getID() == OPT_no_pie)
|
||||
diagnostics << "iOS simulator programs must be built PIE\n";
|
||||
return false;
|
||||
break;
|
||||
case MachOLinkingContext::OS::unknown:
|
||||
break;
|
||||
}
|
||||
ctx.setPIE(pie->getOption().getID() == OPT_pie);
|
||||
break;
|
||||
case llvm::MachO::MH_PRELOAD:
|
||||
break;
|
||||
case llvm::MachO::MH_DYLIB:
|
||||
case llvm::MachO::MH_BUNDLE:
|
||||
diagnostics << "warning: " << pie->getSpelling() << " being ignored. "
|
||||
<< "It is only used when linking main executables\n";
|
||||
break;
|
||||
default:
|
||||
diagnostics << pie->getSpelling()
|
||||
<< " can only used when linking main executables\n";
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle input files
|
||||
for (auto &arg : *parsedArgs) {
|
||||
ErrorOr<StringRef> resolvedPath = StringRef();
|
||||
|
|
|
@ -55,6 +55,12 @@ def grp_main : OptionGroup<"opts">, HelpText<"MAIN EXECUTABLE OPTIONS">;
|
|||
def entry : Separate<["-"], "e">,
|
||||
MetaVarName<"<entry-name>">,
|
||||
HelpText<"entry symbol name">,Group<grp_main>;
|
||||
def pie : Flag<["-"], "pie">,
|
||||
HelpText<"Create Position Independent Executable (for ASLR)">,
|
||||
Group<grp_main>;
|
||||
def no_pie : Flag<["-"], "no_pie">,
|
||||
HelpText<"Do not create Position Independent Executable">,
|
||||
Group<grp_main>;
|
||||
|
||||
// dylib executable options
|
||||
def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">;
|
||||
|
|
|
@ -132,7 +132,8 @@ bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
|
|||
|
||||
MachOLinkingContext::MachOLinkingContext()
|
||||
: _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false),
|
||||
_doNothing(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
|
||||
_doNothing(false), _pie(false),
|
||||
_arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0),
|
||||
_pageZeroSize(0), _pageSize(4096), _compatibilityVersion(0),
|
||||
_currentVersion(0), _deadStrippableDylib(false), _printAtoms(false),
|
||||
_testingFileUsage(false), _keepPrivateExterns(false),
|
||||
|
@ -165,6 +166,22 @@ void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
|
|||
_pageZeroSize = 0x1000;
|
||||
}
|
||||
|
||||
// Make PIE by default when targetting newer OSs.
|
||||
switch (os) {
|
||||
case OS::macOSX:
|
||||
if (minOSVersion >= 0x000A0700) // MacOSX 10.7
|
||||
_pie = true;
|
||||
break;
|
||||
case OS::iOS:
|
||||
if (minOSVersion >= 0x00040300) // iOS 4.3
|
||||
_pie = true;
|
||||
break;
|
||||
case OS::iOS_simulator:
|
||||
_pie = true;
|
||||
break;
|
||||
case OS::unknown:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case llvm::MachO::MH_DYLIB:
|
||||
_globalsAreDeadStripRoots = true;
|
||||
|
|
|
@ -1120,7 +1120,10 @@ uint32_t Util::fileFlags() {
|
|||
if (_context.outputMachOType() == MH_OBJECT) {
|
||||
return MH_SUBSECTIONS_VIA_SYMBOLS;
|
||||
} else {
|
||||
return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL;
|
||||
if ((_context.outputMachOType() == MH_EXECUTE) && _context.PIE())
|
||||
return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL | MH_PIE;
|
||||
else
|
||||
return MH_DYLDLINK | MH_NOUNDEFS | MH_TWOLEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t && \
|
||||
# RUN: llvm-objdump -macho -private-headers %t | FileCheck %s
|
||||
#
|
||||
# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -pie -o %t\
|
||||
# RUN: && llvm-objdump -macho -private-headers %t | FileCheck %s
|
||||
#
|
||||
# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -no_pie -o %t\
|
||||
# RUN: && llvm-objdump -macho -private-headers %t \
|
||||
# RUN: | FileCheck --check-prefix=CHECK_NO_PIE %s
|
||||
#
|
||||
# Test various PIE options.
|
||||
#
|
||||
|
||||
--- !mach-o
|
||||
arch: x86_64
|
||||
file-type: MH_OBJECT
|
||||
flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
|
||||
has-UUID: false
|
||||
OS: unknown
|
||||
sections:
|
||||
- segment: __TEXT
|
||||
section: __text
|
||||
type: S_REGULAR
|
||||
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
|
||||
address: 0x0000000000000000
|
||||
content: [ 0xC3 ]
|
||||
global-symbols:
|
||||
- name: _main
|
||||
type: N_SECT
|
||||
scope: [ N_EXT ]
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
|
||||
--- !mach-o
|
||||
arch: x86_64
|
||||
file-type: MH_DYLIB
|
||||
install-name: /usr/lib/libSystem.B.dylib
|
||||
exports:
|
||||
- name: dyld_stub_binder
|
||||
|
||||
...
|
||||
|
||||
# CHECK: MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE
|
||||
# CHECK_NO_PIE-NOT: MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE
|
Loading…
Reference in New Issue