Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ld: support -dynamic_lookup_library #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/man/man1/ld.1
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ the dylib as an upward dependency.
.It Fl weak_library Ar path_to_library
This is the same as listing a file name path to a library on the link line except that it forces the
library and all references to it to be marked as weak imports.
.It Fl dynamic_lookup-l Ns Ar x
This is the same as the -lx but forces all symbols provided by the library to be marked as dynamic_lookup.
That is, the library is allowed to be missing at runtime, but the symbols provided by this library must
be available at runtime.
.It Fl dynamic_lookup_library Ar path_to_library
This is the same as listing a file name path to a library on the link line except that it forces all symbols
provided by the library to be marked as dynamic_lookup.
.It Fl L Ns dir
Add
.Ar dir
Expand Down Expand Up @@ -192,6 +199,9 @@ symbols are used from it. Thus, it can be used suppress warnings about unused d
This is the same as the -framework name[,suffix] but forces the framework and all
references to it to be marked as weak imports. Note: due to a clang optimizations, if functions
are not marked weak, the compiler will optimize out any checks if the function address is NULL.
.It Fl dynamic_lookup_framework Ar name[,suffix]
This is the same as the -framework name[,suffix] but forces all symbols provided by the framework
to be marked as dynamic_lookup.
.It Fl reexport_framework Ar name[,suffix]
This is the same as the -framework name[,suffix] but also specifies that the
all symbols in that framework should be available to clients linking to the library being created.
Expand Down
4 changes: 3 additions & 1 deletion src/ld/HeaderAndLoadCommands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,9 @@ uint8_t* HeaderAndLoadCommandsAtom<A>::copyDylibLoadCommand(uint8_t* p, const ld
warning("cannot weak upward link. Dropping weak for %s", dylib->installPath());
if ( weakLink && reExport )
warning("cannot weak re-export a dylib. Dropping weak for %s", dylib->installPath());
if ( reExport )
if ( dylib->forcedDynamicLookupLinked() )
return p;
else if ( reExport )
cmd->set_cmd(LC_REEXPORT_DYLIB);
else if ( upward )
cmd->set_cmd(LC_LOAD_UPWARD_DYLIB);
Expand Down
2 changes: 2 additions & 0 deletions src/ld/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,8 @@ ld::File* InputFiles::addDylib(ld::dylib::File* reader, const Options::FileInfo&
// store options about how dylib will be used in dylib itself
if ( info.options.fWeakImport )
reader->setForcedWeakLinked();
if ( info.options.fDynamicLookupImport )
reader->setForcedDynamicLookupLinked();
if ( info.options.fReExport )
reader->setWillBeReExported();
if ( info.options.fUpward ) {
Expand Down
28 changes: 28 additions & 0 deletions src/ld/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2140,6 +2140,9 @@ void Options::addLibrary(const FileInfo& info)
// if dylib is specified again but weak, record that it should be weak
if ( info.options.fWeakImport )
fit->options.fWeakImport = true;
// if dylib is specified again but dynamic_lookup, record that it should be dynamic_lookup
if ( info.options.fDynamicLookupImport )
fit->options.fDynamicLookupImport = true;
return;
}
}
Expand Down Expand Up @@ -2638,6 +2641,14 @@ void Options::parse(int argc, const char* argv[])
info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
addLibrary(info);
}
else if ( strncmp(arg, "-dynamic_lookup-l", 17) == 0 ) {
// SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
snapshotArgCount = 0;
FileInfo info = findLibrary(&arg[7]);
info.options.fDynamicLookupImport = true;
info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
addLibrary(info);
}
// Avoid lazy binding.
else if ( strcmp(arg, "-bind_at_load") == 0 ) {
fBindAtLoad = true;
Expand Down Expand Up @@ -2868,6 +2879,15 @@ void Options::parse(int argc, const char* argv[])
cannotBeUsedWithBitcode(arg);
warning("-lazy_library is deprecated, changing to regular link");
}
else if ( strcmp(arg, "-dynamic_lookup_library") == 0 ) {
// SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
snapshotArgCount = 0;
FileInfo info = findFile(argv[++i]);
info.options.fDynamicLookupImport = true;
info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
addLibrary(info);
cannotBeUsedWithBitcode(arg);
}
else if ( strcmp(arg, "-needed_library") == 0 ) {
snapshotArgCount = 0;
const char* path = checkForNullArgument(arg, argv[++i]);
Expand Down Expand Up @@ -2900,6 +2920,14 @@ void Options::parse(int argc, const char* argv[])
info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
addLibrary(info);
}
else if ( strcmp(arg, "-dynamic_lookup_framework") == 0 ) {
// SNAPSHOT FIXME: what should we do for link snapshots? (ignore for now)
snapshotArgCount = 0;
FileInfo info = findFramework(argv[++i]);
info.options.fDynamicLookupImport = true;
info.ordinal = ld::File::Ordinal::makeArgOrdinal((uint16_t)i);
addLibrary(info);
}
else if ( strcmp(arg, "-search_paths_first") == 0 ) {
// previously handled by buildSearchPaths()
}
Expand Down
3 changes: 2 additions & 1 deletion src/ld/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ class LibraryOptions
public:
LibraryOptions() : fWeakImport(false), fReExport(false), fBundleLoader(false),
fUpward(false), fIndirectDylib(false), fNeeded(false),
fForceLoad(false), fLoadHidden(false) {}
fDynamicLookupImport(false), fForceLoad(false), fLoadHidden(false) {}
// for dynamic libraries
bool fWeakImport;
bool fReExport;
bool fBundleLoader;
bool fUpward;
bool fIndirectDylib;
bool fNeeded;
bool fDynamicLookupImport;
// for static libraries
bool fForceLoad;
bool fLoadHidden;
Expand Down
4 changes: 4 additions & 0 deletions src/ld/OutputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4914,6 +4914,10 @@ int OutputFile::compressedOrdinalForAtom(const ld::Atom* target) const
// regular ordinal
const ld::dylib::File* dylib = dynamic_cast<const ld::dylib::File*>(target->file());
if ( dylib != NULL ) {
// Handle -dynamic_lookup_library
if ( dylib->forcedDynamicLookupLinked() )
return BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE. However, I suspect this is more geared towards the case where the symbols are actually in the main executable which is not the case for the libpython use case.


std::map<const ld::dylib::File*, int>::const_iterator pos = _dylibToOrdinal.find(dylib);
if ( pos != _dylibToOrdinal.end() )
return pos->second;
Expand Down
6 changes: 4 additions & 2 deletions src/ld/ld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ namespace dylib {
: ld::File(pth, modTime, ord, Dylib), _dylibInstallPath(NULL), _frameworkName(NULL),
_dylibTimeStamp(0), _dylibCurrentVersion(0), _dylibCompatibilityVersion(0),
_explicitlyLinked(false), _implicitlyLinked(false), _speculativelyLoaded(false),
_forcedWeakLinked(false), _needed(false), _reExported(false),
_forcedWeakLinked(false), _needed(false), _forcedDynamicLookupLinked(false), _reExported(false),
_upward(false), _dead(false) { }
const char* installPath() const { return _dylibInstallPath; }
const char* frameworkName() const { return _frameworkName; }
Expand All @@ -489,7 +489,8 @@ namespace dylib {
bool forcedWeakLinked() const { return _forcedWeakLinked; }
void setNeededDylib() { _needed = true; }
bool neededDylib() const { return _needed; }

void setForcedDynamicLookupLinked() { _forcedDynamicLookupLinked = true; }
bool forcedDynamicLookupLinked() const { return _forcedDynamicLookupLinked; }
void setWillBeReExported() { _reExported = true; }
bool willBeReExported() const { return _reExported; }
void setWillBeUpwardDylib() { _upward = true; }
Expand Down Expand Up @@ -525,6 +526,7 @@ namespace dylib {
bool _speculativelyLoaded;
bool _forcedWeakLinked;
bool _needed;
bool _forcedDynamicLookupLinked;
bool _reExported;
bool _upward;
bool _dead;
Expand Down