mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
Add support for export_dynamic cmdline option and behaviour.
This option matches the behaviour of ld64, that is it prevents globals from being dead stripped in executables and dylibs. Reviewed by Lang Hames Differential Revision: http://reviews.llvm.org/D16026 llvm-svn: 258554
This commit is contained in:
@@ -84,7 +84,8 @@ public:
|
||||
/// Initializes the context to sane default values given the specified output
|
||||
/// file type, arch, os, and minimum os version. This should be called before
|
||||
/// other setXXX() methods.
|
||||
void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion);
|
||||
void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion,
|
||||
bool exportDynamicSymbols);
|
||||
|
||||
void addPasses(PassManager &pm) override;
|
||||
bool validateImpl(raw_ostream &diagnostics) override;
|
||||
|
||||
@@ -385,9 +385,16 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
||||
// No min-os version on command line, check environment variables
|
||||
}
|
||||
|
||||
// Handle export_dynamic
|
||||
// FIXME: Should we warn when this applies to something other than a static
|
||||
// executable or dylib? Those are the only cases where this has an effect.
|
||||
// Note, this has to come before ctx.configure() so that we get the correct
|
||||
// value for _globalsAreDeadStripRoots.
|
||||
bool exportDynamicSymbols = parsedArgs.hasArg(OPT_export_dynamic);
|
||||
|
||||
// Now that there's enough information parsed in, let the linking context
|
||||
// set up default values.
|
||||
ctx.configure(fileType, arch, os, minOSVersion);
|
||||
ctx.configure(fileType, arch, os, minOSVersion, exportDynamicSymbols);
|
||||
|
||||
// Handle -e xxx
|
||||
if (llvm::opt::Arg *entry = parsedArgs.getLastArg(OPT_entry))
|
||||
|
||||
@@ -84,6 +84,9 @@ def stack_size : Separate<["-"], "stack_size">,
|
||||
HelpText<"Specifies the maximum stack size for the main thread in a program. "
|
||||
"Must be a page-size multiple. (default=8Mb)">,
|
||||
Group<grp_main>;
|
||||
def export_dynamic : Flag<["-"], "export_dynamic">,
|
||||
HelpText<"Preserves all global symbols in main executables during LTO">,
|
||||
Group<grp_main>;
|
||||
|
||||
// dylib executable options
|
||||
def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">;
|
||||
|
||||
@@ -155,7 +155,8 @@ MachOLinkingContext::MachOLinkingContext()
|
||||
MachOLinkingContext::~MachOLinkingContext() {}
|
||||
|
||||
void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
|
||||
uint32_t minOSVersion) {
|
||||
uint32_t minOSVersion,
|
||||
bool exportDynamicSymbols) {
|
||||
_outputMachOType = type;
|
||||
_arch = arch;
|
||||
_os = os;
|
||||
@@ -218,9 +219,10 @@ void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
|
||||
case OS::unknown:
|
||||
break;
|
||||
}
|
||||
setGlobalsAreDeadStripRoots(exportDynamicSymbols);
|
||||
break;
|
||||
case llvm::MachO::MH_DYLIB:
|
||||
setGlobalsAreDeadStripRoots(true);
|
||||
setGlobalsAreDeadStripRoots(exportDynamicSymbols);
|
||||
break;
|
||||
case llvm::MachO::MH_BUNDLE:
|
||||
break;
|
||||
|
||||
27
lld/test/mach-o/dead-strip-globals.yaml
Normal file
27
lld/test/mach-o/dead-strip-globals.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
# RUN: lld -flavor darwin -arch x86_64 -dead_strip -export_dynamic %s -dylib %p/Inputs/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s
|
||||
# RUN: lld -flavor darwin -arch x86_64 -export_dynamic -dead_strip %s -dylib %p/Inputs/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s
|
||||
# RUN: lld -flavor darwin -arch x86_64 -dead_strip %s -dylib %p/Inputs/libSystem.yaml -o %t2.dylib -print_atoms | FileCheck -check-prefix=CHECK2 %s
|
||||
|
||||
#
|
||||
# Test that -export_dynamic -dead-strip from removing globals.
|
||||
#
|
||||
|
||||
---
|
||||
defined-atoms:
|
||||
- name: def
|
||||
scope: global
|
||||
dead-strip: never
|
||||
- name: dead
|
||||
scope: global
|
||||
shared-library-atoms:
|
||||
- name: dyld_stub_binder
|
||||
load-name: /usr/lib/libSystem.B.dylib
|
||||
type: unknown
|
||||
...
|
||||
|
||||
# CHECK1: name: def
|
||||
# CHECK1: name: dead
|
||||
|
||||
# CHECK2: name: def
|
||||
# CHECK2-NOT: name: dead
|
||||
|
||||
@@ -84,9 +84,34 @@ TEST_F(DarwinLdParserTest, DeadStripRootsExe) {
|
||||
TEST_F(DarwinLdParserTest, DeadStripRootsDylib) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-dylib", "-dead_strip", "foo.o",
|
||||
nullptr));
|
||||
EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
|
||||
}
|
||||
|
||||
TEST_F(DarwinLdParserTest, DeadStripRootsRelocatable) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-r", "-dead_strip", "foo.o",
|
||||
nullptr));
|
||||
EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
|
||||
}
|
||||
|
||||
TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicExe) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-dead_strip",
|
||||
"-export_dynamic", "foo.o", nullptr));
|
||||
EXPECT_TRUE(_ctx.globalsAreDeadStripRoots());
|
||||
}
|
||||
|
||||
TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicDylib) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-dylib", "-dead_strip",
|
||||
"-export_dynamic", "foo.o",
|
||||
nullptr));
|
||||
EXPECT_TRUE(_ctx.globalsAreDeadStripRoots());
|
||||
}
|
||||
|
||||
TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicRelocatable) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "-r", "-dead_strip",
|
||||
"-export_dynamic", "foo.o", nullptr));
|
||||
EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
|
||||
}
|
||||
|
||||
TEST_F(DarwinLdParserTest, Arch) {
|
||||
EXPECT_TRUE(parse("ld", "-arch", "x86_64", "foo.o", nullptr));
|
||||
EXPECT_EQ(MachOLinkingContext::arch_x86_64, _ctx.arch());
|
||||
|
||||
Reference in New Issue
Block a user