-
-
Notifications
You must be signed in to change notification settings - Fork 264
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
Add option '-fvisibility=<hidden|default>' able to hide symbols not marked as 'export' on non-Windows targets. Resolves #2431 #2894
Conversation
…ort' on linux and OSX. Resolves ldc-developers#2431.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a test case, but otherwise LGTM.
dmd/globals.d
Outdated
| @@ -262,6 +262,9 @@ struct Param | |||
| bool fullyQualifiedObjectFiles; | |||
| bool cleanupObjectFiles; | |||
|
|
|||
| // Export only symbols marked as 'export' on linux and OSX | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also add a note that this is the default behaviour on windows
dmd/globals.h
Outdated
| @@ -240,6 +240,9 @@ struct Param | |||
| bool fullyQualifiedObjectFiles; | |||
| bool cleanupObjectFiles; | |||
|
|
|||
| // Export only symbols marked as 'export' on linux and OSX | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
driver/cl_options.cpp
Outdated
| @@ -81,6 +81,11 @@ static cl::opt<bool, true> | |||
| createSharedLib("shared", cl::desc("Create shared library (DLL)"), | |||
| cl::ZeroOrMore, cl::location(global.params.dll)); | |||
|
|
|||
| static cl::opt<bool, true> exportOnlyMarkedExport( | |||
| "export-marked-symbols", cl::ZeroOrMore, | |||
| cl::desc("Export only symbols marked as 'export' on linux and OSX"), | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description should say that it only affects non-Windows targets (as it's enforced for Windows, not just the default, and doesn't just apply to Linux and Mac).
driver/main.cpp
Outdated
| @@ -558,6 +558,11 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, | |||
|
|
|||
| global.params.hdrStripPlainFunctions = !opts::hdrKeepAllBodies; | |||
| global.params.disableRedZone = opts::disableRedZone(); | |||
|
|
|||
| // On windows this is already a default behavior | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit already the default behavior
dmd/globals.d
Outdated
| @@ -262,6 +262,9 @@ struct Param | |||
| bool fullyQualifiedObjectFiles; | |||
| bool cleanupObjectFiles; | |||
|
|
|||
| // Export only symbols marked as 'export' on linux and OSX | |||
| bool export_only_symbols_marked_export; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use lowerCamelCase such that it matches our coding style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not have the flag in the Param struct at all; it's a pure codegen flag and doesn't affect the frontend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if it is there it should be in version(IN_LLVM).
driver/main.cpp
Outdated
| @@ -558,6 +558,11 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, | |||
|
|
|||
| global.params.hdrStripPlainFunctions = !opts::hdrKeepAllBodies; | |||
| global.params.disableRedZone = opts::disableRedZone(); | |||
|
|
|||
| // On windows this is already a default behavior | |||
| if (global.params.isWindows) { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may bite us in the future. Better to have the option mean what the behaviour will look like to the user. If Windows already does this by default, we should not internally change this option to false (which would mean the opposite would happen!), but instead change the way this option is used to achieve that behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. I'd call it internally something like defaultToHiddenVisibility; the gcc/clang option is -fvisibility=hidden, so our cmdline option could be named similarly.
| // Hide non-exported symbols | ||
| if (global.params.export_only_symbols_marked_export && | ||
| !decl->isExport()) { | ||
| gvar->setVisibility(LLGlobalValue::HiddenVisibility); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is causing trouble on windows, then the check for windows should be here, instead of setting the option to false for Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use the DLL storage classes for Windows; I guess the visibility doesn't really matter.
|
This basic approach is more or less a port of the current Windows approach, i.e., allowing selective exports of functions and globals. It doesn't handle any of the special symbols (TypeInfos, vtables, init symbols...); only exporting those for aggregates marked with |
|
…port. State non-Windows targets instead of OSX and linux. Don't switch off the option on Windows, since it doesn't have effect anyway.
|
…portOnlySymbolsMarkedExport directly) Add tests for -export-marked-symbols switch.
| @@ -0,0 +1,13 @@ | |||
| // Test if -export-marked-symbols works with thin LTO | |||
|
|
|||
| // RUN: ldc2 %S/inputs/export_marked_symbols_thin_lto_lib.d -c -export-marked-symbols -of=%t1.o | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need a // REQUIRES: LTO and -flto=thin
| // RUN: ldc2 %s -betterC -shared -export-marked-symbols -of=lib%t.so | ||
| // RUN: nm lib%t.so | FileCheck %s | ||
|
|
||
| // UNSUPPORTED: Windows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can you move this to the top? It's how we do it in other test files (requirements first), and it took me a while to see that you disabled this test on Windows. thanks! (also in the other test file)
|
Thanks for figuring out the For Mac, |
| // CHECK: test__nonExportedFunDef | ||
| // CHECK: test__nonExportedVarDef | ||
| // CHECK-NOT: test__nonExportedFunDecl | ||
| // CHECK-NOT: test__nonExportedVarDecl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is that you're only checking that the 2 latter symbols don't exist in the nm output after test__nonExportedVarDef. I don't think replacing CHECK with CHECK-DAG helps in that case; see https://llvm.org/docs/CommandGuide/FileCheck.html.
But apparently nm sorts alphabetically by default, so the list here should too.
…dows object extensions.
|
Thx dude, lgtm now. There's only the bikeshedding about the name of the cmdline option - I'm still in favor of gcc/clang-compatible |
|
terminology-wise it is smartest to use what others know about. LLVM and C seem to call the attribute "hidden visibility", so that'd have my vote too. (Also for buildsystems, the more LDC looks like a C compiler, the better) edit: I think |
|
Sounds good. Would |
|
Something like: cl::opt<bool> defaultToHiddenVisibility(
"fvisibility", cl::ZeroOrMore, cl::desc("Default visibility of symbols (not relevant for Windows)"),
clEnumValues(
clEnumValN(false, "default", "Export all symbols"),
clEnumValN(true, "hidden", "Only export symbols marked with 'export'")
)); |
…bility'. Rename flag 'export-marked-symbols' to 'fvisibility' with 'default' and 'hidden' values.
|
Somehow clEnumValues doesn't work for opt |
|
[I added a fixup commit, |
|
@kinke What is the plan on this PR? |
|
It'll be part of v1.13, don't worry. ;) |
|
Very happy about this outcome :) |
|
@p0nce I am not sure it should work for non-shared binary, but if so we can made binary more small. |
#2431