Skip to content

[compiler-rt][Fuchsia] Change GetMaxUserVirtualAddress to invoke syscall #153309

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler-rt/lib/asan/asan_fuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ void EarlySanitizerInit() {}

namespace __asan {

// The system already set up the shadow memory for us.
// __sanitizer::GetMaxUserVirtualAddress has already been called by
// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cpp).
// Just do some additional sanity checks here.
void InitializeShadowMemory() {
// Explicitly setup shadow here right beforer any of the ShadowBounds members
// are used.
InitShadowBounds();

if (Verbosity())
PrintAddressSpaceLayout();

Expand Down
31 changes: 29 additions & 2 deletions compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "sanitizer_fuchsia.h"
#if SANITIZER_FUCHSIA

# include <limits.h>
# include <pthread.h>
# include <stdlib.h>
# include <unistd.h>
Expand Down Expand Up @@ -117,11 +118,37 @@ uptr GetMmapGranularity() { return _zx_system_get_page_size(); }

sanitizer_shadow_bounds_t ShadowBounds;

// Any sanitizer that utilizes shadow should explicitly call whenever it's
// appropriate for that sanitizer to reference shadow bounds. For ASan, this is
// done in `InitializeShadowMemory` and for HWASan, this is done in
// `InitShadow`.
void InitShadowBounds() { ShadowBounds = __sanitizer_shadow_bounds(); }

// TODO(leonardchan): It's not immediately clear from a user perspective if
// `GetMaxUserVirtualAddress` should be called exatly once on runtime startup
// or can be called multiple times. Currently it looks like most instances of
// `GetMaxUserVirtualAddress` are meant to be called once, but if someone
// decides to call this multiple times in the future, we should have a separate
// function that's ok to call multiple times. Ideally we would just invoke this
// syscall once. Also for Fuchsia, this syscall technically gets invoked twice
// since `__sanitizer_shadow_bounds` also invokes this syscall under the hood.
uptr GetMaxUserVirtualAddress() {
InitShadowBounds();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now what calls InitShadowBounds?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see it added above now for asan. As long as that is certainly early enough, this should be OK. It's far from obvious that this is the only place that needs to call this, however. Comments are appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments. This and hwasan are the only places that need this rn, but hwasan already calls this during its init path.

return ShadowBounds.memory_limit - 1;
zx_info_vmar_t info;
zx_status_t status = _zx_object_get_info(_zx_vmar_root_self(), ZX_INFO_VMAR,
&info, sizeof(info), NULL, NULL);
CHECK_EQ(status, ZX_OK);

// Find the top of the accessible address space.
uintptr_t top = info.base + info.len;

// Round it up to a power-of-two size. There may be some pages at
// the top that can't actually be mapped, but for purposes of the
// the shadow, we'll pretend they could be.
int bit = (sizeof(uintptr_t) * CHAR_BIT) - __builtin_clzl(top);
if (top != (uintptr_t)1 << bit)
top = (uintptr_t)1 << (bit + 1);

return top - 1;
}

uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); }
Expand Down
Loading