[PATCH] D41153: [XRay][compiler-rt] Coalesce calls to mprotect to reduce patching overhead
Dean Michael Berris via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 13 15:45:10 PST 2017
dberris added a comment.
In https://reviews.llvm.org/D41153#954307, @kpw wrote:
> Suggestion for future changes:
>
> 1. We could decouple mprotect and __xray_patch_function so that callers that want to mprotect once and then patch individual functions have their cake and eat it too.
Yeah, I'd like to think about that a little more. I suspect the call to mprotect is an implementation detail of patching/unpatching.
> 2. Should xray make an effort to restore the mprotect status of pages after it's done? Probably not worth the complexity.
I think we do that already, no? `MProtectHelper` already does that in the destructor, to make the pages read+execute only as opposed to read+write+execute.
> 3. If these regions never lose write permissions, why even call mprotect for unpatching?
They do, `MProtectHelper` does RAII on the mprotect status of pages. It does make the assumption that the pages being mprotected are r+x to begin with.
================
Comment at: compiler-rt/lib/xray/xray_flags.inc:22-23
XRAY_FLAG(const char *, xray_mode, "", "Mode to install by default.")
-
+XRAY_FLAG(uptr, xray_page_size_override, 0,
+ "Override the default page size for the system, in bytes.")
----------------
kpw wrote:
> It's a bit unfortunate that there is now an undocumented requirement that code #including this file must have already imported sanitizer_internal_defs.h.
>
> Perhaps you could add an #ifdef check for SANITIZER_DEFS_H or the uptr typedef itself with an #error assertion.
>
> Is uptr even the right type? Page size doesn't represent a pointer, it's more like a size_t (although we might have to use it as an offset and add it to an address).
Yeah, this file could only really be included from `xray_flags.h` and `xray_flags.cc` which should include the types. Fixed it from that side instead.
Unfortunately the flag parser doesn't support an overload for `size_t` reliably, and of the options we have there, `uptr` seems to fit the best.
================
Comment at: compiler-rt/lib/xray/xray_interface.cc:211-213
+ // and try to get as few calls to mprotect(...) as possible. We're assuming
+ // that all the sleds for the instrumentation map are contiguous as a single
+ // set of pages. When we do support dynamic shared object instrumentation,
----------------
kpw wrote:
> What evidence or reasoning leads us to conclude that this assumption holds (ignoring DSO)?
This is the convention used by ELF and thus the Linux kernel to map the `.text` segment as contiguous virtual memory. If this is somehow not true, then our calls to `mprotect` will fail (i.e. if `.text` was somehow further segmented or non-contiguous). Is there a way to somehow improve this comment to make that clearer?
================
Comment at: compiler-rt/lib/xray/xray_interface.cc:228
+
+ const size_t PageSize = flags()->xray_page_size_override > 0
+ ? flags()->xray_page_size_override
----------------
kpw wrote:
> Usage suggests defining the flag as size_t.
Unfortunately the flag parser may not know how to parse `size_t` but does know how to parse `uptr`.
================
Comment at: compiler-rt/lib/xray/xray_interface.cc:320
+static XRayPatchingStatus __xray_patch_helper(int32_t FuncId, bool Enable) {
+ XRaySledMap InstrMap;
----------------
kpw wrote:
> This function name is very non-descriptive.
>
> __mprotect_and_patch_function()?
Good point. I've moved this into the `__xray` namespace, put it in an anonymous namespace in there, and used a more descriptive name `mprotectAndPatchFunction`.
https://reviews.llvm.org/D41153
More information about the llvm-commits
mailing list