Page MenuHomePhabricator

[IR][sanitizer] Set nounwind on module ctor/dtor, additionally set uwtable if -fasynchronous-unwind-tables
ClosedPublic

Authored by MaskRay on Apr 10 2021, 2:27 PM.

Details

Summary

On ELF targets, if a function has uwtable or personality, or does not have
nounwind (needsUnwindTableEntry), it marks that .eh_frame is needed in the module.

Then, a function gets .eh_frame if needsUnwindTableEntry or -g[123] is specified.
(i.e. If -g[123], every function gets .eh_frame.
This behavior is strange but that is the status quo on GCC and Clang.)

Let's take asan as an example. Other sanitizers are similar.
asan.module_[cd]tor has no attribute. needsUnwindTableEntry returns true,
so every function gets .eh_frame if -g[123] is specified.
This is the root cause that
-fno-exceptions -fno-asynchronous-unwind-tables -g produces .debug_frame
while
-fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address produces .eh_frame (buggy, should produce .debug_frame)

This patch

  • sets the nounwind attribute on sanitizer module ctor/dtor.
  • let Clang emit a module flag metadata "uwtable" for -fasynchronous-unwind-tables. If "uwtable" is set, sanitizer module ctor/dtor additionally get the uwtable attribute.

The "uwtable" mechanism is generic: synthesized functions not cloned/specialized
from existing ones should consider Function::createWithDefaultAttr instead of
Function::create if they want to get some default attributes which
have more of module semantics.

Other candidates: "frame-pointer" (https://github.com/ClangBuiltLinux/linux/issues/955
https://github.com/ClangBuiltLinux/linux/issues/1238), dso_local, etc.

Diff Detail

Event Timeline

MaskRay created this revision.Apr 10 2021, 2:27 PM
MaskRay requested review of this revision.Apr 10 2021, 2:27 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 10 2021, 2:27 PM

-fno-exceptions -fno-asynchronous-unwind-tables -g produces .debug_frame
while
-fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address produces .eh_frame.

Does this patch change that behavior?

MaskRay added a comment.EditedApr 12 2021, 1:27 PM

-fno-exceptions -fno-asynchronous-unwind-tables -g produces .debug_frame
while
-fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address produces .eh_frame.

Does this patch change that behavior?

Yes. I consider -fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address producing .eh_frame is a bug. This patch will fix it and match GCC.

-fsanitize=address can be replaced with many other instrumentations (-fsanitize=memory, -fprofile-arcs, -fsanitize-coverage=trace-pc-guard, ...)
This patch fixes the various sanitizers.

-fno-exceptions -fno-asynchronous-unwind-tables -g produces .debug_frame
while
-fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address produces .eh_frame.

Does this patch change that behavior?

Yes. I consider -fno-exceptions -fno-asynchronous-unwind-tables -g -fsanitize=address producing .eh_frame is a bug. This patch will fix it and match GCC.

SGTM; please make that clearer though in the description.

MaskRay edited the summary of this revision. (Show Details)Apr 12 2021, 2:15 PM
nickdesaulniers accepted this revision.Apr 12 2021, 2:37 PM
nickdesaulniers added inline comments.
llvm/include/llvm/IR/Function.h
156

Perhaps a comment that this "creates functions with module level attributes applied at the function level. Use this when synthesizing new functions that might have attributes that depend on module level attributes that would have been set by command line flags" or such.

This revision is now accepted and ready to land.Apr 12 2021, 2:37 PM

This touches sanitizers so hope #sanitizers folks can weigh in as well.

llvm/include/llvm/IR/Function.h
156

Thanks. This definitely deserves a comment. I will add when I update it:)

vitalybuka accepted this revision.Wed, Apr 21, 12:28 PM