This is an archive of the discontinued LLVM Phabricator instance.

Enable weak hooks on darwin
ClosedPublic

Authored by fjricci on Dec 31 2016, 10:21 AM.

Details

Summary

By default, darwin requires a definition for weak interface functions at
link time. Adding the '-U' link flag with each weak function allows these
weak interface functions to be used without definitions, which mirrors
behavior on linux and windows.

Diff Detail

Repository
rL LLVM

Event Timeline

fjricci updated this revision to Diff 82775.Dec 31 2016, 10:21 AM
fjricci retitled this revision from to Enable weak hooks on darwin.
fjricci updated this object.
fjricci added reviewers: compnerd, eugenis.
fjricci added a subscriber: llvm-commits.
kubamracek edited edge metadata.Dec 31 2016, 10:51 AM

-undefined dynamic_lookup

This means the linker won't warn/error out on any undefined symbol. Sounds very dangerous to me and it's likely to cause a lot of development headaches.

Can we solve this in a different way? E.g. a macro that would expand to a empty function body on Darwin?

compnerd edited edge metadata.Dec 31 2016, 5:59 PM

Its actually not that dangerous, given that ELF by default does this for any dynamic linking. However, it is possible to be more granular and specify the symbols which are okay to be undefined using the -U <name> option to the linker. It is slightly nicer than the blanket approach, but at a higher maintainence cost (any time the sanitizers change the hooks, it would need to be updated. But, that doesnt seem too bad.

fjricci updated this revision to Diff 82794.Jan 1 2017, 6:23 PM
fjricci updated this object.
fjricci edited edge metadata.

Upload correct commit

fjricci added a comment.EditedJan 1 2017, 6:25 PM

Individually lists each undefined symbol as undefined in the linker invocation.

fjricci updated this revision to Diff 82805.Jan 2 2017, 8:18 AM

Enable on darwin

Looks better, but I'd rather see the list of weak symbols in each subdirectory (asan/, ubsan/, etc.), because each sanitizer has its own list. It looks wrong to list sanitizer-specific symbols in a global CMake file. Can this also be stored in a separate file and not directly in CMake (with a dependency on that file)?

Can we also make the Linux linker use this list? I only looked briefly at man ld, but it seems that --dynamic-list may achieve the same?

Overall, I support this change, but I want to avoid situations where a weak symbol is forgotten to be added to the list, and the Linux build will work fine, but Darwin will be broken.

Ish. Most linkers can read the arguments from a file. The GNU linker uses @file syntax as does link (Windows). ld64 can read a set of files to link via -file_list but not all the arguments AFAIK.

COFF does not allow any undefined symbols anyways, and this patch addresses MachO. On ELFish targets, -z defs will prevent undefined symbols even in DSOs, but I don't think that applies to STB_WEAK symbols.

FWIW, I think that getting the same behavior across the two is a bit beyond the scope of this change.

As far as I can tell, @compnerd is correct with respect to STB_WEAK symbols on Linux. I'll upload a refactored change targeting Darwin with the weak symbols pushed down into the sanitizer-specific directories.

fjricci updated this revision to Diff 83423.Jan 6 2017, 2:07 PM

Refactor symbols into text files only included in required link steps

This revision was automatically updated to reflect the committed changes.
fjricci reopened this revision.Jan 6 2017, 4:47 PM

Accidentally committed with another commit. Reverting.

kubamracek accepted this revision.Jan 6 2017, 4:51 PM
kubamracek edited edge metadata.

LGTM with a nit.

Note that D28359 was trying to solve a similar problem with weak linking on Windows, so maybe there are more changes coming, but this patch doesn't need to be blocked on that.

cmake/Modules/SanitizerUtils.cmake
53 ↗(On Diff #83423)

nit: add a comment saying that this is specific to Darwin/Mach-O

lib/sanitizer_common/sanitizer_internal_defs.h
35 ↗(On Diff #83423)

What about FreeBSD? Just curious.

This revision is now accepted and ready to land.Jan 6 2017, 4:51 PM
compnerd added inline comments.Jan 7 2017, 8:53 AM
lib/sanitizer_common/sanitizer_internal_defs.h
35 ↗(On Diff #83423)

I believe that FreeBSD uses ELF, so it should be able to support weak linkage. However, if its untested ...

fjricci added inline comments.Jan 7 2017, 10:22 AM
cmake/Modules/SanitizerUtils.cmake
53 ↗(On Diff #83423)

Will do before commit.

lib/sanitizer_common/sanitizer_internal_defs.h
35 ↗(On Diff #83423)

I don't have any way to run this on FreeBSD, so I'll leave this for future work.

fjricci updated this revision to Diff 83532.Jan 7 2017, 12:23 PM
fjricci edited edge metadata.

Adds undefined symbols to test cases as well

fjricci updated this revision to Diff 83534.Jan 7 2017, 12:25 PM

Also add function comment

I realized during testing that the symbols must also be added to some test cases directly. Re-uploaded with those changes, to give the opportunity for review before submitting.

fjricci updated this revision to Diff 83538.Jan 7 2017, 12:39 PM

Fix typo

There are still a few typos where LINK_FLAGS (with the underscore) is used.

Besides that, the patch looks good.

This revision was automatically updated to reflect the committed changes.