The linux part is a bit ahead of time - the instrumentation code where this matters have not landed yet. But when it does, this would be the right condition, and for now ELF instrumentation simply ignores this setting.
Diff Detail
- Repository
- rL LLVM
Event Timeline
From a quick look at the code, it seems like -fno-data-sections on COFF would suppress GC of globals the same as on ELF. Is that true?
I think it would be better to move this logic to the driver and have it pass in an -mllvm flag. The sanitizer passes should really be taking no arguments in the constructor like the other passes, so I don't want us to add another argument here.
That seems like the opposite of the direction we've been moving, though. cl::opt flags can't appear twice, and this means one process can't do two asan compilations in two LLVMContexts in parallel with different settings.
lib/Driver/SanitizerArgs.cpp | ||
---|---|---|
636 ↗ | (On Diff #95254) | We can return true for COFF here. By adding a comdat during asan instrumentation, we effectively implement -fdata-sections ourselves. If the user really wanted -fno-data-sections for some reason, they're out of luck right now. |
lib/Driver/SanitizerArgs.cpp | ||
---|---|---|
636 ↗ | (On Diff #95254) | What do you mean by "out of luck", will it break compilation? |
lib/Driver/SanitizerArgs.cpp | ||
---|---|---|
636 ↗ | (On Diff #95254) | By "out of luck", I was thinking about users who might do crazy things like take label differences between globals and assume that they are laid out consecutively in the original source file order. I wasn't thinking about object file size. The size increase for COFF is probably comparable, so I guess I agree, this is reasonable behavior. I think Chromium explicitly passes /Gw, which is equivalent to -fdata-sections. We basically don't support non-integrated as on Windows at this point. We've extended the assembler a number of times already. |
Yes, but adding an argument is also the wrong direction. This information should really be passed either via the module (e.g. module flags or attributes) or the TargetMachine. If we aren't going to do that, we might as well pass it via -mllvm, as it is simpler.
I'm really just echoing what I thought was conventional wisdom. I think avoiding new cl::opts is something that @chandlerc cares more about. It's been said on llvm-dev that cl::opt should mostly be for debugging. We should be able to ship a production compiler that effectively compiles every cl::opt to its default value.
I don't see why constructor parameters are the wrong direction. It's already how ASan instrumentation takes every other global pass option. Only tsan uses -mllvm flags created by clang. If we aren't going to make ASan consistent, we should standardize on what we already have.
The ultimate solution would be a function attribute - if we want this thing to work correctly with LTO. But it sounds a bit like overkill, plus none of the settings it depends on (integrated-as, data-sections) work with LTO anway: the former is ignored and the second does not make sense.
I won't stand in the way here if others feel strongly that the flag should be passed via a constructor. It will just mean more work to be done if/when this flag is ever changed to be passed via some other mechanism, but that's a relatively minor detail.
I think the only functional change here is for COFF, so you can add a CodeGen test that checks that metadata globals are created only if -fdata-sections is passed.